Changeset 104194 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Apr 5, 2024 2:39:02 PM (10 months ago)
- Location:
- trunk/src/VBox/Devices/PC/BIOS
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/BIOS/ata.c
r104067 r104194 131 131 132 132 // --------------------------------------------------------------------------- 133 // ATA/ATAPI driver : initialize device parameters (CHS geometry) 134 // --------------------------------------------------------------------------- 135 uint16_t ata_set_params(bio_dsk_t __far *bios_dsk, uint8_t device) 136 { 137 uint16_t iobase1, iobase2; 138 uint8_t lheads, lsectors; 139 uint8_t pheads, psectors; 140 uint8_t status; 141 142 psectors = bios_dsk->devices[device].pchs.spt; 143 pheads = bios_dsk->devices[device].pchs.heads - 1; 144 145 lsectors = bios_dsk->devices[device].lchs.spt; 146 lheads = bios_dsk->devices[device].lchs.heads - 1; 147 148 if ((psectors == lsectors) && (pheads == lheads)) { 149 // If LCHS == PCHS, we can save ourselves the bother 150 // because INITIALIZE DEVICE PARAMETERS won't change anything. 151 return 0; 152 } 153 154 iobase1 = bios_dsk->channels[device / 2].iobase1; 155 iobase2 = bios_dsk->channels[device / 2].iobase2; 156 157 status = inb(iobase1 + ATA_CB_STAT); 158 if (status & ATA_CB_STAT_BSY) 159 { 160 BX_DEBUG_ATA("%s: disk busy\n", __func__); 161 return 1; 162 } 163 164 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); 165 outb(iobase1 + ATA_CB_FR, 0x00); 166 outb(iobase1 + ATA_CB_SC, lsectors); 167 outb(iobase1 + ATA_CB_DH, ((device & 1) ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | lheads ); 168 outb(iobase1 + ATA_CB_CMD, ATA_CMD_INITIALIZE_DEVICE_PARAMETERS); 169 170 int_enable(); // enable higher priority interrupts 171 172 while (1) { 173 status = inb(iobase1 + ATA_CB_STAT); 174 if ( !(status & ATA_CB_STAT_BSY) ) 175 break; 176 } 177 178 // Enable interrupts 179 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15); 180 return 0; 181 } 182 183 184 // --------------------------------------------------------------------------- 133 185 // ATA/ATAPI driver : software reset 134 186 // --------------------------------------------------------------------------- 135 187 // ATA-3 136 188 // 8.2.1 Software reset - Device 0 189 // NB: If two hard disks are installed on a single channel, *both* are reset 190 // by setting the SRST bit. 137 191 138 192 void ata_reset(uint16_t device) 139 193 { 140 194 uint16_t iobase1, iobase2; 141 uint8_t channel, s lave, sn, sc;195 uint8_t channel, sn, sc; 142 196 uint16_t max; 143 197 uint16_t pdelay; … … 146 200 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk; 147 201 channel = device / 2; 148 slave = device %2;202 device = channel * 2; 149 203 150 204 iobase1 = bios_dsk->channels[channel].iobase1; … … 179 233 } 180 234 181 if (bios_dsk->devices[device].type != DSK_TYPE_NONE) { 182 // 8.2.1 (g) -- check for sc==sn==0x01 183 // select device 184 outb(iobase1+ATA_CB_DH, slave?ATA_CB_DH_DEV1:ATA_CB_DH_DEV0); 185 sc = inb(iobase1+ATA_CB_SC); 186 sn = inb(iobase1+ATA_CB_SN); 187 188 if ( (sc==0x01) && (sn==0x01) ) { 189 // 8.2.1 (i) -- wait for DRDY 190 max = 0x10; /* Speed up for virtual drives. Disks are immediately ready, CDs never */ 191 while(--max>0) { 192 uint8_t status = inb(iobase1+ATA_CB_STAT); 193 if ((status & ATA_CB_STAT_RDY) != 0) 194 break; 235 for ( ; (device & ~1) == (channel * 2); ++device) { 236 if (bios_dsk->devices[device].type == DSK_TYPE_ATA) { 237 // 8.2.1 (g) -- check for sc==sn==0x01 238 // select device 239 outb(iobase1+ATA_CB_DH, (device & 1) ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0); 240 sc = inb(iobase1+ATA_CB_SC); 241 sn = inb(iobase1+ATA_CB_SN); 242 243 if ( (sc==0x01) && (sn==0x01) ) { 244 // 8.2.1 (i) -- wait for DRDY 245 max = 0x10; /* Speed up for virtual drives. Disks are immediately ready, CDs never */ 246 while(--max>0) { 247 uint8_t status = inb(iobase1+ATA_CB_STAT); 248 if ((status & ATA_CB_STAT_RDY) != 0) 249 break; 250 } 251 ata_set_params(bios_dsk, device); 195 252 } 196 253 } … … 673 730 } 674 731 } 732 733 // Set the right CHS geometry if needed 734 ata_set_params(bios_dsk, device); 675 735 676 736 // fill hdidmap -
trunk/src/VBox/Devices/PC/BIOS/disk.c
r98103 r104194 314 314 315 315 case 0x00: /* disk controller reset */ 316 #ifdef VBOX_WITH_SCSI 317 /* SCSI controller does not need a reset. */ 318 if (!VBOX_IS_SCSI_DEVICE(device)) 319 #endif 320 ata_reset (device); 316 /* For ATA drives only. NB: This resets both drives on a channel. */ 317 if (VBOX_IS_ATA_DEVICE(device)) 318 ata_reset(device); 321 319 goto int13_success; 322 320 break; -
trunk/src/VBox/Devices/PC/BIOS/ebda.h
r104142 r104194 77 77 #define BX_USE_ATADRV 1 78 78 #define BX_ELTORITO_BOOT 1 79 80 #define VBOX_IS_ATA_DEVICE(device_id) (device_id < BX_MAX_ATA_DEVICES) 79 81 80 82 #ifdef VBOX_WITH_SCSI -
trunk/src/VBox/Devices/PC/BIOS/notes.txt
r100483 r104194 76 76 at least in protected mode, assumes that those vectors must point into 77 77 the F000h segment. 78 79 - NetWare 2.0a INSTALL and VREPAIR utilities run in real mode but have their 80 own ATA disk driver. Like NetWare itself, the utilities obtain drive 81 geometry from the FDPT, but unlike NetWare, they assume that the drive 82 already had the correct geometry set during POST and that INT 13h/00h 83 will keep it in place by executing INITIALIZE DRIVE PARAMETERS. 84 NB: The BIOS itself always uses LBA and thus does not depend on the 85 drive's current CHS geometry at all. 78 86 79 87 - Windows NT (including XP) uses INT 13h/08h to obtain the DPT for each floppy
Note:
See TracChangeset
for help on using the changeset viewer.