Changeset 104194 in vbox for trunk/src/VBox/Devices/PC/BIOS/ata.c
- Timestamp:
- Apr 5, 2024 2:39:02 PM (10 months ago)
- File:
-
- 1 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
Note:
See TracChangeset
for help on using the changeset viewer.