Changeset 39560 in vbox
- Timestamp:
- Dec 8, 2011 4:41:37 PM (13 years ago)
- Location:
- trunk/src/VBox/Devices/PC/BIOS-new
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/BIOS-new/ahci.c
r39375 r39560 64 64 * Must be aligned on 128 byte boundary. 65 65 */ 66 uint8_t abCmd[0x80]; 66 uint8_t abCmd[0x40]; 67 /** The ATAPI command region. 68 * Located 40h bytes after the beginning of the CFIS (Command FIS). 69 */ 70 uint8_t abAcmd[0x20]; 71 /** Align the PRDT structure on a 128 byte boundary. */ 72 uint8_t abAlignment2[0x20]; 67 73 /** Physical Region Descriptor Table (PRDT) array. In other 68 74 * words, a scatter/gather descriptor list. … … 155 161 156 162 #define ATA_CMD_IDENTIFY_DEVICE 0xEC 163 #define ATA_CMD_IDENTIFY_PACKET 0xA1 164 #define ATA_CMD_PACKET 0xA0 157 165 #define AHCI_CMD_READ_DMA_EXT 0x25 158 166 #define AHCI_CMD_WRITE_DMA_EXT 0x35 … … 239 247 /* Prepare the command header. */ 240 248 ahci->aCmdHdr[0] = RT_BIT_32(16) | RT_BIT_32(7) | val; 241 ahci->aCmdHdr[1] = cbData;249 ahci->aCmdHdr[1] = 0; //cbData; //@todo: Is this really an input parameter? 242 250 ahci->aCmdHdr[2] = ahci_addr_to_phys(&ahci->abCmd[0]); 243 251 … … 277 285 ahci_t __far *ahci = bios_dsk->ahci_seg :> 0; 278 286 uint16_t n_sect = bios_dsk->drqp.nsect; 287 uint16_t sectsz = bios_dsk->drqp.sect_sz; 279 288 280 289 _fmemset(&ahci->abCmd[0], 0, sizeof(ahci->abCmd)); … … 301 310 /* Lock memory needed for DMA. */ 302 311 ahci->edds.num_avail = NUM_EDDS_SG; 303 vds_build_sg_list(&ahci->edds, bios_dsk->drqp.buffer, n_sect * 512);312 vds_build_sg_list(&ahci->edds, bios_dsk->drqp.buffer, (uint32_t)n_sect * sectsz); 304 313 305 314 /* Set up the PRDT. */ … … 307 316 ahci->aPrdt[0].len = ahci->edds.u.sg[0].size - 1; 308 317 309 /* Build variable part first of command dword . */318 /* Build variable part first of command dword (reuses 'cmd'). */ 310 319 if (cmd == AHCI_CMD_WRITE_DMA_EXT) 311 cmd = RT_BIT_32(6); 312 else 320 cmd = RT_BIT_32(6); /* Indicate write to device. */ 321 else if (cmd == ATA_CMD_PACKET) { 322 cmd |= RT_BIT_32(5); /* Indicate ATAPI command. */ 323 ahci->abCmd[3] |= 1; /* DMA transfers. */ 324 } else 313 325 cmd = 0; 314 326 315 // if (fAtapi) 316 // cmd |= RT_BIT_32(5); 317 318 cmd |= 5; /* Five dwords. */ 319 320 ahci_port_cmd_sync(ahci, cmd, n_sect * 512); 327 cmd |= 5; /* Five DWORDs. */ 328 329 ahci_port_cmd_sync(ahci, cmd, n_sect * sectsz); 321 330 322 331 /* Unlock the buffer again. */ … … 427 436 device_id = bios_dsk->drqp.dev_id - BX_MAX_ATA_DEVICES - BX_MAX_SCSI_DEVICES; 428 437 if (device_id > BX_MAX_AHCI_DEVICES) 429 BX_PANIC("ahci_read_sectors: device_id out of range %d\n", device_id); 438 BX_PANIC("%s: device_id out of range %d\n", __func__, device_id); 439 440 VBOXAHCI_DEBUG("%s: %u sectors @ LBA %lu, device %d, port %d\n", __func__, 441 bios_dsk->drqp.nsect, bios_dsk->drqp.lba, device_id, 442 bios_dsk->ahcidev[device_id].port); 430 443 431 444 ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port); … … 450 463 device_id = bios_dsk->drqp.dev_id - BX_MAX_ATA_DEVICES - BX_MAX_SCSI_DEVICES; 451 464 if (device_id > BX_MAX_AHCI_DEVICES) 452 BX_PANIC("ahci_write_sectors: device_id out of range %d\n", device_id); 465 BX_PANIC("%s: device_id out of range %d\n", __func__, device_id); 466 467 VBOXAHCI_DEBUG("%s: %u sectors @ LBA %lu, device %d, port %d\n", __func__, 468 bios_dsk->drqp.nsect, bios_dsk->drqp.lba, device_id, 469 bios_dsk->ahcidev[device_id].port); 453 470 454 471 ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port); 455 472 ahci_cmd_data(bios_dsk, AHCI_CMD_WRITE_DMA_EXT); 456 473 return 0; //@todo!! 474 } 475 476 //@todo: move 477 #define ATA_DATA_NO 0x00 478 #define ATA_DATA_IN 0x01 479 #define ATA_DATA_OUT 0x02 480 481 uint16_t ahci_cmd_packet(uint16_t device_id, uint8_t cmdlen, char __far *cmdbuf, 482 uint16_t header, uint32_t length, uint8_t inout, char __far *buffer) 483 { 484 bio_dsk_t __far *bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk; 485 ahci_t __far *ahci = bios_dsk->ahci_seg :> 0; 486 487 /* Data out is currently not supported. */ 488 if (inout == ATA_DATA_OUT) { 489 BX_INFO("%s: DATA_OUT not supported yet\n", __func__); 490 return 1; 491 } 492 493 /* The header length must be even. */ 494 if (header & 1) { 495 VBOXAHCI_DEBUG("%s: header must be even (%04x)\n", __func__, header); 496 return 1; 497 } 498 499 /* Convert to AHCI specific device number. */ 500 device_id = device_id - BX_MAX_ATA_DEVICES - BX_MAX_SCSI_DEVICES; 501 502 VBOXAHCI_DEBUG("%s: reading %lu bytes, header %u, device %d, port %d\n", __func__, 503 length, header, device_id, bios_dsk->ahcidev[device_id].port); 504 505 bios_dsk->drqp.lba = (uint32_t)length << 8; //@todo: xfer length limit 506 bios_dsk->drqp.buffer = buffer; 507 bios_dsk->drqp.nsect = length / 2048; 508 bios_dsk->drqp.sect_sz = 2048; 509 510 ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port); 511 512 /* Copy the ATAPI command where the HBA can fetch it. */ 513 _fmemcpy(ahci->abAcmd, cmdbuf, cmdlen); 514 515 /* Reset transferred counts. */ 516 // @todo: clear in calling code? 517 bios_dsk->drqp.trsfsectors = 0; 518 bios_dsk->drqp.trsfbytes = 0; 519 520 ahci_cmd_data(bios_dsk, ATA_CMD_PACKET); 521 VBOXAHCI_DEBUG("%s: transferred %lu bytes\n", __func__, ahci->aCmdHdr[1]); 522 #ifdef DMA_WORKAROUND 523 rep_movsw(bios_dsk->drqp.buffer, bios_dsk->drqp.buffer, bios_dsk->drqp.nsect * 2048 / 2); 524 #endif 525 bios_dsk->drqp.trsfbytes = ahci->aCmdHdr[1]; 526 return ahci->aCmdHdr[1] == 0 ? 4 : 0; 527 // return 0; //@todo!! 457 528 } 458 529 … … 478 549 if (ahci_ctrl_extract_bits(val, 0xfL, 0) == 0x3) 479 550 { 480 uint8_t hdcount, hdcount_ahci, hd_index; 481 482 hdcount_ahci = bios_dsk->ahci_hdcount; 551 uint8_t abBuffer[0x0200]; 552 uint8_t hdcount, devcount_ahci, hd_index; 553 uint8_t cdcount; 554 uint8_t removable; 555 556 devcount_ahci = bios_dsk->ahci_devcnt; 483 557 484 558 VBOXAHCI_DEBUG("AHCI: Device detected on port %d\n", u8Port); 485 559 486 if (hdcount_ahci < BX_MAX_AHCI_DEVICES) 560 //@todo: Merge common HD/CDROM detection code 561 if (devcount_ahci < BX_MAX_AHCI_DEVICES) 487 562 { 488 563 /* Device detected, enable FIS receive. */ … … 495 570 { 496 571 uint32_t cSectors; 497 uint8_t abBuffer[0x0200];498 uint8_t fRemovable;499 572 uint16_t cCylinders, cHeads, cSectorsPerTrack; 500 573 uint8_t idxCmosChsBase; … … 503 576 504 577 /* Identify device. */ 505 bios_dsk->drqp.lba = 0; 506 bios_dsk->drqp.buffer = &abBuffer; 507 bios_dsk->drqp.nsect = 1; 578 bios_dsk->drqp.lba = 0; 579 bios_dsk->drqp.buffer = &abBuffer; 580 bios_dsk->drqp.nsect = 1; 581 bios_dsk->drqp.sect_sz = 512; 508 582 ahci_cmd_data(bios_dsk, ATA_CMD_IDENTIFY_DEVICE); 509 583 510 /* Calculate index into the generic d isktable. */511 hd_index = hdcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES;512 513 fRemovable= *(abBuffer+0) & 0x80 ? 1 : 0;584 /* Calculate index into the generic device table. */ 585 hd_index = devcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES; 586 587 removable = *(abBuffer+0) & 0x80 ? 1 : 0; 514 588 cCylinders = *(uint16_t *)(abBuffer+(1*2)); // word 1 515 589 cHeads = *(uint16_t *)(abBuffer+(3*2)); // word 3 … … 523 597 VBOXAHCI_DEBUG("AHCI: %ld sectors\n", cSectors); 524 598 525 bios_dsk->ahcidev[ hdcount_ahci].port = u8Port;599 bios_dsk->ahcidev[devcount_ahci].port = u8Port; 526 600 bios_dsk->devices[hd_index].type = ATA_TYPE_AHCI; 527 601 bios_dsk->devices[hd_index].device = ATA_DEVICE_HD; 528 bios_dsk->devices[hd_index].removable = fRemovable;602 bios_dsk->devices[hd_index].removable = removable; 529 603 bios_dsk->devices[hd_index].lock = 0; 530 604 bios_dsk->devices[hd_index].blksize = 512; … … 537 611 538 612 /* Get logical CHS geometry. */ 539 switch ( hdcount_ahci)613 switch (devcount_ahci) 540 614 { 541 615 case 0: … … 567 641 } 568 642 VBOXAHCI_DEBUG("AHCI: Dev %d LCHS=%d/%d/%d\n", 569 hdcount_ahci, cCylinders, cHeads, cSectorsPerTrack);643 devcount_ahci, cCylinders, cHeads, cSectorsPerTrack); 570 644 571 645 bios_dsk->devices[hd_index].lchs.heads = cHeads; … … 573 647 bios_dsk->devices[hd_index].lchs.spt = cSectorsPerTrack; 574 648 575 /* Store the id of the disk in the atahdidmap. */649 /* Store the ID of the disk in the BIOS hdidmap. */ 576 650 hdcount = bios_dsk->hdcount; 577 bios_dsk->hdidmap[hdcount] = hdcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES;651 bios_dsk->hdidmap[hdcount] = devcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES; 578 652 hdcount++; 579 653 bios_dsk->hdcount = hdcount; … … 582 656 hdcount = read_byte(0x40, 0x75); 583 657 hdcount++; 584 write_byte(0x40, 0x75, hdcount); 585 658 write_byte(0x40, 0x75, hdcount); 586 659 } 587 660 else if (val == 0xeb140101) 588 661 { 589 662 VBOXAHCI_DEBUG("AHCI: Detected ATAPI device\n"); 663 664 /* Identify packet device. */ 665 bios_dsk->drqp.lba = 0; 666 bios_dsk->drqp.buffer = &abBuffer; 667 bios_dsk->drqp.nsect = 1; 668 bios_dsk->drqp.sect_sz = 512; 669 ahci_cmd_data(bios_dsk, ATA_CMD_IDENTIFY_PACKET); 670 671 /* Calculate index into the generic device table. */ 672 hd_index = devcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES; 673 674 removable = *(abBuffer+0) & 0x80 ? 1 : 0; 675 676 bios_dsk->ahcidev[devcount_ahci].port = u8Port; 677 bios_dsk->devices[hd_index].type = ATA_TYPE_AHCI; 678 bios_dsk->devices[hd_index].device = ATA_DEVICE_CDROM; 679 bios_dsk->devices[hd_index].removable = removable; 680 bios_dsk->devices[hd_index].blksize = 2048; 681 682 /* Store the ID of the device in the BIOS cdidmap. */ 683 cdcount = bios_dsk->cdcount; 684 bios_dsk->cdidmap[cdcount] = devcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES; 685 cdcount++; 686 bios_dsk->cdcount = cdcount; 590 687 } 591 688 else 592 689 VBOXAHCI_DEBUG("AHCI: Ignoring unknown device\n"); 593 690 594 hdcount_ahci++;595 bios_dsk->ahci_ hdcount = hdcount_ahci;691 devcount_ahci++; 692 bios_dsk->ahci_devcnt = devcount_ahci; 596 693 } 597 694 else … … 651 748 652 749 write_word(ebda_seg, (uint16_t)&EbdaData->bdisk.ahci_seg, ahci_seg); 653 write_byte(ebda_seg, (uint16_t)&EbdaData->bdisk.ahci_ hdcount, 0);750 write_byte(ebda_seg, (uint16_t)&EbdaData->bdisk.ahci_devcnt, 0); 654 751 write_byte(ahci_seg, (uint16_t)&AhciData->cur_port, 0xff); 655 752 write_word(ahci_seg, (uint16_t)&AhciData->iobase, io_base); -
trunk/src/VBox/Devices/PC/BIOS-new/ata.c
r39366 r39560 586 586 bios_dsk->drqp.dev_id = device; 587 587 588 if (ata_cmd_data_in(bios_dsk, ATA_CMD_IDENTIFY_ DEVICE_PACKET, 1) != 0)588 if (ata_cmd_data_in(bios_dsk, ATA_CMD_IDENTIFY_PACKET, 1) != 0) 589 589 BX_PANIC("ata-detect: Failed to detect ATAPI device\n"); 590 590 … … 1128 1128 // End of ATA/ATAPI Driver 1129 1129 // --------------------------------------------------------------------------- 1130 1131 uint16_t atapi_is_cdrom(uint8_t device)1132 {1133 bio_dsk_t __far *bios_dsk;1134 1135 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;1136 1137 if (device >= BX_MAX_ATA_DEVICES)1138 return 0;1139 1140 if (bios_dsk->devices[device].type != ATA_TYPE_ATAPI)1141 return 0;1142 1143 if (bios_dsk->devices[device].device != ATA_DEVICE_CDROM)1144 return 0;1145 1146 return 1;1147 }1148 1149 // ---------------------------------------------------------------------------1150 // End of ATA/ATAPI generic functions1151 // --------------------------------------------------------------------------- -
trunk/src/VBox/Devices/PC/BIOS-new/ata.h
r39372 r39560 128 128 #define ATA_CMD_FORMAT_TRACK 0x50 129 129 #define ATA_CMD_IDENTIFY_DEVICE 0xEC 130 #define ATA_CMD_IDENTIFY_DEVICE_PACKET 0xA1 131 #define ATA_CMD_IDENTIFY_PACKET_DEVICE 0xA1 130 #define ATA_CMD_IDENTIFY_PACKET 0xA1 132 131 #define ATA_CMD_IDLE1 0xE3 133 132 #define ATA_CMD_IDLE2 0x97 … … 204 203 #define Int13DPT ((dpt_t *) 0) 205 204 206 207 205 extern void ata_reset(uint16_t device); 208 extern uint16_t atapi_is_cdrom(uint8_t device);209 extern uint16_t ata_cmd_packet(uint16_t device, uint8_t cmdlen,210 char __far *cmdbuf, uint16_t header,211 uint32_t length, uint8_t inout,212 char __far *buffer); -
trunk/src/VBox/Devices/PC/BIOS-new/disk.c
r39375 r39560 161 161 bios_dsk->drqp.buffer = MK_FP(ES, BX); 162 162 bios_dsk->drqp.nsect = count; 163 bios_dsk->drqp.sect_sz = 512; //@todo: device specific? 163 164 bios_dsk->drqp.cylinder = cylinder; 164 165 bios_dsk->drqp.head = head; … … 373 374 374 375 /* Pass request information to low level disk code. */ 375 bios_dsk->drqp.lba = lba; 376 bios_dsk->drqp.buffer = MK_FP(segment, offset); 377 bios_dsk->drqp.nsect = count; 378 bios_dsk->drqp.sector = 0; /* Indicate LBA. */ 376 bios_dsk->drqp.lba = lba; 377 bios_dsk->drqp.buffer = MK_FP(segment, offset); 378 bios_dsk->drqp.nsect = count; 379 bios_dsk->drqp.sect_sz = 512; //@todo: device specific? 380 bios_dsk->drqp.sector = 0; /* Indicate LBA. */ 379 381 380 382 // Execute the command -
trunk/src/VBox/Devices/PC/BIOS-new/ebda.h
r39372 r39560 195 195 uint8_t dev_id; /* Device ID; index into devices array. */ 196 196 uint16_t nsect; /* Number of sectors to be transferred. */ 197 uint16_t sect_sz; /* Size of a sector in bytes. */ 197 198 uint16_t cylinder; /* Starting cylinder (CHS only). */ 198 199 uint16_t head; /* Starting head (CHS only). */ … … 216 217 217 218 uint8_t cdcount; /* Number of CD-ROMs. */ 218 /* Map between (BIOS CD-ROM ID - 0xE0) and ATA channels. */219 /* Map between (BIOS CD-ROM ID - 0xE0) and ATA/SCSI/AHCI devices. */ 219 220 uint8_t cdidmap[BX_MAX_STORAGE_DEVICES]; 220 221 … … 231 232 /* SATA (AHCI) bus-specific device information. */ 232 233 ahci_dev_t ahcidev[BX_MAX_AHCI_DEVICES]; 233 uint8_t ahci_ hdcount; /* Number of SATA disks. */234 uint8_t ahci_devcnt; /* Number of SATA devices. */ 234 235 uint16_t ahci_seg; /* Segment of AHCI data block. */ 235 236 #endif … … 296 297 int __fastcall ahci_write_sectors(bio_dsk_t __far *bios_dsk); 297 298 299 300 uint16_t ahci_cmd_packet(uint16_t device_id, uint8_t cmdlen, char __far *cmdbuf, 301 uint16_t header, uint32_t length, uint8_t inout, char __far *buffer); 302 303 uint16_t ata_cmd_packet(uint16_t device, uint8_t cmdlen, char __far *cmdbuf, 304 uint16_t header, uint32_t length, uint8_t inout, char __far *buffer); 305 298 306 // @todo: put this elsewhere (and change/eliminate?) 299 307 #define SET_DISK_RET_STATUS(status) write_byte(0x0040, 0x0074, status) -
trunk/src/VBox/Devices/PC/BIOS-new/eltorito.c
r39355 r39560 189 189 // --------------------------------------------------------------------------- 190 190 191 /* Utility routine to check if a device is a CD-ROM. */ 192 //@todo: this function is kinda useless as the ATAPI type check is obsolete. 193 static uint16_t device_is_cdrom(uint8_t device) 194 { 195 bio_dsk_t __far *bios_dsk; 196 197 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk; 198 199 if (device >= BX_MAX_STORAGE_DEVICES) 200 return 0; 201 202 // if (bios_dsk->devices[device].type != ATA_TYPE_ATAPI) 203 // return 0; 204 205 if (bios_dsk->devices[device].device != ATA_DEVICE_CDROM) 206 return 0; 207 208 return 1; 209 } 210 211 // --------------------------------------------------------------------------- 212 // End of ATA/ATAPI generic functions 213 // --------------------------------------------------------------------------- 191 214 static const char isotag[]="CD001"; 192 215 static const char eltorito[]="EL TORITO SPECIFICATION"; … … 207 230 cdemu = ebda_seg :> &EbdaData->cdemu; 208 231 209 / / Find out the first cdrom210 for (device =0; device<BX_MAX_ATA_DEVICES;device++) {211 if ( atapi_is_cdrom(device))232 /* Find the first CD-ROM. */ 233 for (device = 0; device < BX_MAX_STORAGE_DEVICES; ++device) { 234 if (device_is_cdrom(device)) 212 235 break; 213 236 } 214 237 215 // if not found 216 if(device >= BX_MAX_ATA_DEVICES) return 2; 217 218 // Read the Boot Record Volume Descriptor 219 _fmemset(&atacmd,0,12); 220 atacmd[0]=0x28; // READ command 221 atacmd[7]=(0x01 & 0xff00) >> 8; // Sectors 222 atacmd[8]=(0x01 & 0x00ff); // Sectors 223 atacmd[2]=(0x11 & 0xff000000) >> 24; // LBA 224 atacmd[3]=(0x11 & 0x00ff0000) >> 16; 225 atacmd[4]=(0x11 & 0x0000ff00) >> 8; 226 atacmd[5]=(0x11 & 0x000000ff); 227 228 for (read_try = 0; read_try <= 4; read_try++) 238 /* Fail if not found. */ 239 if (device >= BX_MAX_STORAGE_DEVICES) 240 return 2; 241 242 /* Read the Boot Record Volume Descriptor (BRVD). */ 243 _fmemset(&atacmd, 0, 12); 244 //@todo: use some sane byte swapping routines here 245 atacmd[0] = 0x28; // READ command 246 atacmd[7] = (0x01 & 0xff00) >> 8; // Sectors 247 atacmd[8] = (0x01 & 0x00ff); // Sectors 248 atacmd[2] = (0x11 & 0xff000000) >> 24; // LBA 249 atacmd[3] = (0x11 & 0x00ff0000) >> 16; 250 atacmd[4] = (0x11 & 0x0000ff00) >> 8; 251 atacmd[5] = (0x11 & 0x000000ff); 252 253 for (read_try = 0; read_try <= 4; ++read_try) 229 254 { 230 error = ata_cmd_packet(device, 12, &atacmd, 0, 2048L, ATA_DATA_IN, &buffer); 255 //@todo: Use indirect calls instead? 256 if (device > BX_MAX_ATA_DEVICES) 257 error = ahci_cmd_packet(device, 12, &atacmd, 0, 2048L, ATA_DATA_IN, &buffer); 258 else 259 error = ata_cmd_packet(device, 12, &atacmd, 0, 2048L, ATA_DATA_IN, &buffer); 231 260 if (!error) 232 261 break; … … 235 264 return 3; 236 265 237 / / Validity checks238 if (buffer[0]!=0)266 /* Check for a valid BRVD. */ 267 if (buffer[0] != 0) 239 268 return 4; 240 for(i=0;i<5;i++){ 241 if(buffer[1+i] != isotag[i]) 269 //@todo: what's wrong with memcmp()? 270 for (i = 0; i < 5; ++i) { 271 if (buffer[1+i] != isotag[i]) 242 272 return 5; 243 273 } 244 for (i=0;i<23;i++)245 if (buffer[7+i] != eltorito[i])274 for (i = 0; i < 23; ++i) 275 if (buffer[7+i] != eltorito[i]) 246 276 return 6; 247 277 248 278 //@todo: this swaps the LBA back and forth for no good reason??! 249 279 // ok, now we calculate the Boot catalog address 250 lba =buffer[0x4A]*0x1000000UL+buffer[0x49]*0x10000UL+buffer[0x48]*0x100UL+buffer[0x47];280 lba = buffer[0x4A]*0x1000000UL + buffer[0x49]*0x10000UL + buffer[0x48]*0x100UL + buffer[0x47]; 251 281 BX_DEBUG_ELTORITO("BRVD at LBA %lx\n", lba); 252 282 253 / / And we read the Boot Catalog283 /* Now we read the Boot Catalog. */ 254 284 _fmemset(&atacmd,0,12); 255 atacmd[0]=0x28; // READ command 256 atacmd[7]=(0x01 & 0xff00) >> 8; // Sectors 257 atacmd[8]=(0x01 & 0x00ff); // Sectors 258 atacmd[2]=(lba & 0xff000000) >> 24; // LBA 259 atacmd[3]=(lba & 0x00ff0000) >> 16; 260 atacmd[4]=(lba & 0x0000ff00) >> 8; 261 atacmd[5]=(lba & 0x000000ff); 262 if((error = ata_cmd_packet(device, 12, &atacmd, 0, 2048L, ATA_DATA_IN, &buffer)) != 0) 285 //@todo: use some sane byte swapping routines here 286 atacmd[0] = 0x28; // READ command 287 atacmd[7] = (0x01 & 0xff00) >> 8; // Sectors 288 atacmd[8] = (0x01 & 0x00ff); // Sectors 289 atacmd[2] = (lba & 0xff000000) >> 24; // LBA 290 atacmd[3] = (lba & 0x00ff0000) >> 16; 291 atacmd[4] = (lba & 0x0000ff00) >> 8; 292 atacmd[5] = (lba & 0x000000ff); 293 294 if (device > BX_MAX_ATA_DEVICES) 295 error = ahci_cmd_packet(device, 12, &atacmd, 0, 2048L, ATA_DATA_IN, &buffer); 296 else 297 error = ata_cmd_packet(device, 12, &atacmd, 0, 2048L, ATA_DATA_IN, &buffer); 298 299 if (error != 0) 263 300 return 7; 264 301 265 / / Validation entry266 if (buffer[0x00]!=0x01)302 /* Check if the Boot Catalog looks valid. */ 303 if (buffer[0x00] != 0x01) 267 304 return 8; // Header 268 if (buffer[0x01]!=0x00)305 if (buffer[0x01] != 0x00) 269 306 return 9; // Platform 270 if (buffer[0x1E]!=0x55)307 if (buffer[0x1E] != 0x55) 271 308 return 10; // key 1 272 if (buffer[0x1F]!=0xAA)309 if (buffer[0x1F] != 0xAA) 273 310 return 10; // key 2 274 311 275 312 // Initial/Default Entry 276 if (buffer[0x20]!=0x88)313 if (buffer[0x20] != 0x88) 277 314 return 11; // Bootable 278 315 279 316 BX_DEBUG_ELTORITO("Emulate drive %x\n", buffer[0x21]); 280 317 cdemu->media = buffer[0x21]; 281 if (buffer[0x21]==0){318 if (buffer[0x21] == 0) { 282 319 // FIXME ElTorito Hardcoded. cdrom is hardcoded as device 0xE0. 283 320 // Win2000 cd boot needs to know it booted from cd 284 321 cdemu->emulated_drive = 0xE0; 285 322 } 286 else if (buffer[0x21]<4)323 else if (buffer[0x21] < 4) 287 324 cdemu->emulated_drive = 0x00; 288 325 else … … 305 342 cdemu->ilba = lba; 306 343 307 // And we read the image in memory 308 _fmemset(&atacmd,0,12); 309 atacmd[0]=0x28; // READ command 310 atacmd[7]=((1+(nbsectors-1)/4) & 0xff00) >> 8; // Sectors 311 atacmd[8]=((1+(nbsectors-1)/4) & 0x00ff); // Sectors 312 atacmd[2]=(lba & 0xff000000) >> 24; // LBA 313 atacmd[3]=(lba & 0x00ff0000) >> 16; 314 atacmd[4]=(lba & 0x0000ff00) >> 8; 315 atacmd[5]=(lba & 0x000000ff); 316 if((error = ata_cmd_packet(device, 12, &atacmd, 0, nbsectors*512L, ATA_DATA_IN, MK_FP(boot_segment,0))) != 0) 344 /* Read the image into memory. */ 345 _fmemset(&atacmd, 0, 12); 346 atacmd[0] = 0x28; // READ command 347 atacmd[7] = ((1+(nbsectors-1)/4) & 0xff00) >> 8;// Sectors 348 atacmd[8] = ((1+(nbsectors-1)/4) & 0x00ff); // Sectors 349 atacmd[2] = (lba & 0xff000000) >> 24; // LBA 350 atacmd[3] = (lba & 0x00ff0000) >> 16; 351 atacmd[4] = (lba & 0x0000ff00) >> 8; 352 atacmd[5] = (lba & 0x000000ff); 353 354 if (device > BX_MAX_ATA_DEVICES) 355 error = ahci_cmd_packet(device, 12, &atacmd, 0, nbsectors*512L, ATA_DATA_IN, MK_FP(boot_segment,0)); 356 else 357 error = ata_cmd_packet(device, 12, &atacmd, 0, nbsectors*512L, ATA_DATA_IN, MK_FP(boot_segment,0)); 358 if (error != 0) 317 359 return 12; 318 360 319 361 // Remember the media type 320 switch (cdemu->media) {362 switch (cdemu->media) { 321 363 case 0x01: // 1.2M floppy 322 364 cdemu->vdevice.spt = 15; … … 341 383 } 342 384 343 if (cdemu->media != 0) {344 / / Increase bios installed hardware number of devices345 if (cdemu->emulated_drive == 0x00)385 if (cdemu->media != 0) { 386 /* Increase BIOS installed number of drives (floppy or fixed). */ 387 if (cdemu->emulated_drive == 0x00) 346 388 write_byte(0x40,0x10,read_byte(0x40,0x10)|0x41); 347 389 else … … 351 393 352 394 // everything is ok, so from now on, the emulation is active 353 if (cdemu->media !=0 )395 if (cdemu->media !=0 ) 354 396 cdemu->active = 0x01; 355 397 … … 391 433 392 434 /* basic checks : emulation should be active, dl should equal the emulated drive */ 393 if( (cdemu->active ==0 ) 394 || (cdemu->emulated_drive != GET_DL())) { 435 if (!cdemu->active || (cdemu->emulated_drive != GET_DL())) { 395 436 BX_INFO("%s: function %02x, emulation not active for DL= %02x\n", __func__, GET_AH(), GET_DL()); 396 437 goto int13_fail; … … 475 516 elba = (uint32_t)(vlba+nbsectors-1)/4; 476 517 477 _fmemset(&atacmd,0,12); 478 atacmd[0]=0x28; // READ command 479 atacmd[7]=((uint16_t)(elba-slba+1) & 0xff00) >> 8; // Sectors 480 atacmd[8]=((uint16_t)(elba-slba+1) & 0x00ff); // Sectors 481 atacmd[2]=(ilba+slba & 0xff000000) >> 24; // LBA 482 atacmd[3]=(ilba+slba & 0x00ff0000) >> 16; 483 atacmd[4]=(ilba+slba & 0x0000ff00) >> 8; 484 atacmd[5]=(ilba+slba & 0x000000ff); 485 if((status = ata_cmd_packet(device, 12, &atacmd, before*512, nbsectors*512L, ATA_DATA_IN, MK_FP(segment,offset))) != 0) { 518 _fmemset(&atacmd, 0, 12); 519 //@todo: use some sane byte swapping routines here 520 atacmd[0] = 0x28; // READ command 521 atacmd[7] = ((uint16_t)(elba-slba+1) & 0xff00) >> 8;// Sectors 522 atacmd[8] = ((uint16_t)(elba-slba+1) & 0x00ff); // Sectors 523 atacmd[2] = (ilba+slba & 0xff000000) >> 24; // LBA 524 atacmd[3] = (ilba+slba & 0x00ff0000) >> 16; 525 atacmd[4] = (ilba+slba & 0x0000ff00) >> 8; 526 atacmd[5] = (ilba+slba & 0x000000ff); 527 528 if (device > BX_MAX_ATA_DEVICES) 529 status = ahci_cmd_packet(device, 12, &atacmd, before*512, nbsectors*512L, ATA_DATA_IN, MK_FP(segment,offset)); 530 else 531 status = ata_cmd_packet(device, 12, &atacmd, before*512, nbsectors*512L, ATA_DATA_IN, MK_FP(segment,offset)); 532 533 if (status != 0) { 486 534 BX_INFO("%s: function %02x, error %02x !\n", __func__, GET_AH(), status); 487 535 SET_AH(0x02); … … 506 554 // FIXME ElTorito Harddisk. should send the HD count 507 555 508 switch (cdemu->media) {556 switch (cdemu->media) { 509 557 case 0x01: SET_BL( 0x02 ); break; 510 558 case 0x02: SET_BL( 0x04 ); break; … … 572 620 uint32_t lba; 573 621 uint16_t count, segment, offset, size; 574 bio_dsk_t __far * ata;575 576 ata= ebda_seg :> &EbdaData->bdisk;622 bio_dsk_t __far *bios_dsk; 623 624 bios_dsk = ebda_seg :> &EbdaData->bdisk; 577 625 578 626 … … 582 630 583 631 /* basic check : device should be 0xE0+ */ 584 if( (GET_ELDL() < 0xE0) || (GET_ELDL() >= 0xE0 +BX_MAX_ATA_DEVICES) ) {632 if( (GET_ELDL() < 0xE0) || (GET_ELDL() >= 0xE0 + BX_MAX_STORAGE_DEVICES) ) { 585 633 BX_DEBUG("%s: function %02x, ELDL out of range %02x\n", __func__, GET_AH(), GET_ELDL()); 586 634 goto int13_fail; … … 588 636 589 637 // Get the ata channel 590 device = ata->cdidmap[GET_ELDL()-0xE0];638 device = bios_dsk->cdidmap[GET_ELDL()-0xE0]; 591 639 592 640 /* basic check : device has to be valid */ 593 if (device >= BX_MAX_ ATA_DEVICES) {641 if (device >= BX_MAX_STORAGE_DEVICES) { 594 642 BX_DEBUG("%s: function %02x, unmapped device for ELDL=%02x\n", __func__, GET_AH(), GET_ELDL()); 595 643 goto int13_fail; 596 644 } 597 645 598 switch (GET_AH()) {646 switch (GET_AH()) { 599 647 600 648 // all those functions return SUCCESS … … 607 655 case 0x14: /* controller internal diagnostic */ 608 656 case 0x16: /* detect disk change */ 609 goto int13_success;610 break;657 goto int13_success; 658 break; 611 659 612 660 // all those functions return disk write-protected … … 614 662 case 0x05: /* format disk track */ 615 663 case 0x43: // IBM/MS extended write 616 SET_AH(0x03);617 goto int13_fail_noah;618 break;664 SET_AH(0x03); 665 goto int13_fail_noah; 666 break; 619 667 620 668 case 0x01: /* read disk status */ 621 status = read_byte(0x0040, 0x0074); 622 SET_AH(status); 623 SET_DISK_RET_STATUS(0); 624 625 /* set CF if error status read */ 626 if (status) goto int13_fail_nostatus; 627 else goto int13_success_noah; 628 break; 669 status = read_byte(0x0040, 0x0074); 670 SET_AH(status); 671 SET_DISK_RET_STATUS(0); 672 673 /* set CF if error status read */ 674 if (status) 675 goto int13_fail_nostatus; 676 else 677 goto int13_success_noah; 678 break; 629 679 630 680 case 0x15: /* read disk drive size */ 631 SET_AH(0x02);632 goto int13_fail_noah;633 break;681 SET_AH(0x02); 682 goto int13_fail_noah; 683 break; 634 684 635 685 case 0x41: // IBM/MS installation check 636 BX=0xaa55;// install check637 SET_AH(0x30);// EDD 2.1638 CX=0x0007;// ext disk access, removable and edd639 goto int13_success_noah;640 break;686 BX = 0xaa55; // install check 687 SET_AH(0x30); // EDD 2.1 688 CX = 0x0007; // ext disk access, removable and edd 689 goto int13_success_noah; 690 break; 641 691 642 692 case 0x42: // IBM/MS extended read … … 644 694 case 0x47: // IBM/MS extended seek 645 695 646 count=read_word(DS, SI+(uint16_t)&Int13Ext->count); 647 segment=read_word(DS, SI+(uint16_t)&Int13Ext->segment); 648 offset=read_word(DS, SI+(uint16_t)&Int13Ext->offset); 649 650 // Can't use 64 bits lba 651 lba=read_dword(DS, SI+(uint16_t)&Int13Ext->lba2); 652 if (lba != 0L) { 653 BX_PANIC("%s: function %02x. Can't use 64bits lba\n", __func__,GET_AH()); 654 goto int13_fail; 655 } 656 657 // Get 32 bits lba 658 lba=read_dword(DS, SI+(uint16_t)&Int13Ext->lba1); 659 660 // If verify or seek 661 if (( GET_AH() == 0x44 ) || ( GET_AH() == 0x47 )) 696 count = read_word(DS, SI+(uint16_t)&Int13Ext->count); 697 segment = read_word(DS, SI+(uint16_t)&Int13Ext->segment); 698 offset = read_word(DS, SI+(uint16_t)&Int13Ext->offset); 699 700 // Can't use 64 bits lba 701 lba = read_dword(DS, SI+(uint16_t)&Int13Ext->lba2); 702 if (lba != 0L) { 703 BX_PANIC("%s: function %02x. Can't use 64bits lba\n", __func__, GET_AH()); 704 goto int13_fail; 705 } 706 707 // Get 32 bits lba 708 lba = read_dword(DS, SI+(uint16_t)&Int13Ext->lba1); 709 710 // If verify or seek 711 if (( GET_AH() == 0x44 ) || ( GET_AH() == 0x47 )) 712 goto int13_success; 713 714 BX_INFO("%s: read %u sectors @ LBA %lu to %04X:%04X\n", 715 __func__, count, lba, segment, offset); 716 717 _fmemset(&atacmd, 0, 12); 718 //@todo: use some sane byte swapping routines here 719 atacmd[0] = 0x28; // READ command 720 atacmd[7] = (count & 0xff00) >> 8; // Sectors 721 atacmd[8] = (count & 0x00ff); // Sectors 722 atacmd[2] = (lba & 0xff000000) >> 24; // LBA 723 atacmd[3] = (lba & 0x00ff0000) >> 16; 724 atacmd[4] = (lba & 0x0000ff00) >> 8; 725 atacmd[5] = (lba & 0x000000ff); 726 727 if (device > BX_MAX_ATA_DEVICES) 728 status = ahci_cmd_packet(device, 12, &atacmd, 0, count*2048L, ATA_DATA_IN, MK_FP(segment,offset)); 729 else 730 status = ata_cmd_packet(device, 12, &atacmd, 0, count*2048L, ATA_DATA_IN, MK_FP(segment,offset)); 731 732 count = (uint16_t)(bios_dsk->drqp.trsfbytes >> 11); 733 write_word(DS, SI+(uint16_t)&Int13Ext->count, count); 734 735 if (status != 0) { 736 BX_INFO("%s: function %02x, status %02x !\n", __func__, GET_AH(), status); 737 SET_AH(0x0c); 738 goto int13_fail_noah; 739 } 740 662 741 goto int13_success; 663 664 _fmemset(&atacmd,0,12); 665 atacmd[0]=0x28; // READ command 666 atacmd[7]=(count & 0xff00) >> 8; // Sectors 667 atacmd[8]=(count & 0x00ff); // Sectors 668 atacmd[2]=(lba & 0xff000000) >> 24; // LBA 669 atacmd[3]=(lba & 0x00ff0000) >> 16; 670 atacmd[4]=(lba & 0x0000ff00) >> 8; 671 atacmd[5]=(lba & 0x000000ff); 672 status = ata_cmd_packet(device, 12, &atacmd, 0, count*2048L, ATA_DATA_IN, MK_FP(segment,offset)); 673 674 count = (uint16_t)(ata->drqp.trsfbytes >> 11); 675 write_word(DS, SI+(uint16_t)&Int13Ext->count, count); 676 677 if (status != 0) { 678 BX_INFO("%s: function %02x, status %02x !\n", __func__, GET_AH(), status); 679 SET_AH(0x0c); 680 goto int13_fail_noah; 681 } 682 683 goto int13_success; 684 break; 742 break; 685 743 686 744 case 0x45: // IBM/MS lock/unlock drive 687 if (GET_AL() > 2) goto int13_fail; 688 689 locks = ata->devices[device].lock; 690 691 switch (GET_AL()) { 745 if (GET_AL() > 2) 746 goto int13_fail; 747 748 locks = bios_dsk->devices[device].lock; 749 750 switch (GET_AL()) { 692 751 case 0 : // lock 693 if (locks == 0xff) { 694 SET_AH(0xb4); 752 if (locks == 0xff) { 753 SET_AH(0xb4); 754 SET_AL(1); 755 goto int13_fail_noah; 756 } 757 bios_dsk->devices[device].lock = ++locks; 695 758 SET_AL(1); 759 break; 760 case 1 : // unlock 761 if (locks == 0x00) { 762 SET_AH(0xb0); 763 SET_AL(0); 764 goto int13_fail_noah; 765 } 766 bios_dsk->devices[device].lock = --locks; 767 SET_AL(locks==0?0:1); 768 break; 769 case 2 : // status 770 SET_AL(locks==0?0:1); 771 break; 772 } 773 goto int13_success; 774 break; 775 776 case 0x46: // IBM/MS eject media 777 locks = bios_dsk->devices[device].lock; 778 779 if (locks != 0) { 780 SET_AH(0xb1); // media locked 696 781 goto int13_fail_noah; 697 } 698 ata->devices[device].lock = ++locks; 699 SET_AL(1); 700 break; 701 case 1 : // unlock 702 if (locks == 0x00) { 703 SET_AH(0xb0); 704 SET_AL(0); 705 goto int13_fail_noah; 706 } 707 ata->devices[device].lock = --locks; 708 SET_AL(locks==0?0:1); 709 break; 710 case 2 : // status 711 SET_AL(locks==0?0:1); 712 break; 713 } 714 goto int13_success; 715 break; 716 717 case 0x46: // IBM/MS eject media 718 locks = ata->devices[device].lock; 719 720 if (locks != 0) { 721 SET_AH(0xb1); // media locked 722 goto int13_fail_noah; 723 } 724 // FIXME should handle 0x31 no media in device 725 // FIXME should handle 0xb5 valid request failed 782 } 783 // FIXME should handle 0x31 no media in device 784 // FIXME should handle 0xb5 valid request failed 726 785 727 786 #if 0 //@todo: implement! 728 // Call removable media eject729 ASM_START787 // Call removable media eject 788 ASM_START 730 789 push bp 731 790 mov bp, sp … … 738 797 int13_cdrom_rme_end: 739 798 pop bp 740 ASM_END799 ASM_END 741 800 #endif 742 801 743 if (status != 0) {744 SET_AH(0xb1); // media locked745 goto int13_fail_noah;746 }747 748 goto int13_success;749 break;802 if (status != 0) { 803 SET_AH(0xb1); // media locked 804 goto int13_fail_noah; 805 } 806 807 goto int13_success; 808 break; 750 809 751 810 case 0x48: // IBM/MS get drive parameters 752 size = read_word(DS,SI+(uint16_t)&Int13Ext->size); 753 754 // Buffer is too small 755 if(size < 0x1a) 756 goto int13_fail; 757 758 // EDD 1.x 759 if(size >= 0x1a) { 760 uint16_t blksize; 761 762 blksize = ata->devices[device].blksize; 763 764 write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x1a); 765 write_word(DS, SI+(uint16_t)&Int13DPT->infos, 0x74); // removable, media change, lockable, max values 766 write_dword(DS, SI+(uint16_t)&Int13DPT->cylinders, 0xffffffff); 767 write_dword(DS, SI+(uint16_t)&Int13DPT->heads, 0xffffffff); 768 write_dword(DS, SI+(uint16_t)&Int13DPT->spt, 0xffffffff); 769 write_dword(DS, SI+(uint16_t)&Int13DPT->sector_count1, 0xffffffff); // FIXME should be Bit64 770 write_dword(DS, SI+(uint16_t)&Int13DPT->sector_count2, 0xffffffff); 771 write_word(DS, SI+(uint16_t)&Int13DPT->blksize, blksize); 772 } 773 774 // EDD 2.x 775 if(size >= 0x1e) { 776 uint8_t channel, irq, mode, checksum, i; 777 uint16_t iobase1, iobase2, options; 778 779 write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x1e); 780 781 write_word(DS, SI+(uint16_t)&Int13DPT->dpte_segment, ebda_seg); 782 write_word(DS, SI+(uint16_t)&Int13DPT->dpte_offset, (uint16_t)&EbdaData->bdisk.dpte); 783 784 // Fill in dpte 785 channel = device / 2; 786 iobase1 = ata->channels[channel].iobase1; 787 iobase2 = ata->channels[channel].iobase2; 788 irq = ata->channels[channel].irq; 789 mode = ata->devices[device].mode; 790 791 // FIXME atapi device 792 options = (1<<4); // lba translation 793 options |= (1<<5); // removable device 794 options |= (1<<6); // atapi device 795 options |= (mode==ATA_MODE_PIO32?1:0<<7); 796 797 ata->dpte.iobase1 = iobase1; 798 ata->dpte.iobase2 = iobase2; 799 ata->dpte.prefix = (0xe | (device % 2))<<4; 800 ata->dpte.unused = 0xcb; 801 ata->dpte.irq = irq; 802 ata->dpte.blkcount = 1 ; 803 ata->dpte.dma = 0; 804 ata->dpte.pio = 0; 805 ata->dpte.options = options; 806 ata->dpte.reserved = 0; 807 ata->dpte.revision = 0x11; 808 809 checksum=0; 810 for (i=0; i<15; i++) 811 checksum += read_byte(ebda_seg, (uint16_t)&EbdaData->bdisk.dpte + i); 812 checksum = -checksum; 813 ata->dpte.checksum = checksum; 814 } 815 816 // EDD 3.x 817 if(size >= 0x42) { 818 uint8_t channel, iface, checksum, i; 819 uint16_t iobase1; 820 821 channel = device / 2; 822 iface = ata->channels[channel].iface; 823 iobase1 = ata->channels[channel].iobase1; 824 825 write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x42); 826 write_word(DS, SI+(uint16_t)&Int13DPT->key, 0xbedd); 827 write_byte(DS, SI+(uint16_t)&Int13DPT->dpi_length, 0x24); 828 write_byte(DS, SI+(uint16_t)&Int13DPT->reserved1, 0); 829 write_word(DS, SI+(uint16_t)&Int13DPT->reserved2, 0); 830 831 if (iface==ATA_IFACE_ISA) { 832 write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[0], 'I'); 833 write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[1], 'S'); 834 write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[2], 'A'); 835 write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[3], 0); 836 } 837 else { 838 // FIXME PCI 839 } 840 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[0], 'A'); 841 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[1], 'T'); 842 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[2], 'A'); 843 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[3], 0); 844 845 if (iface==ATA_IFACE_ISA) { 846 write_word(DS, SI+(uint16_t)&Int13DPT->iface_path[0], iobase1); 847 write_word(DS, SI+(uint16_t)&Int13DPT->iface_path[2], 0); 848 write_dword(DS, SI+(uint16_t)&Int13DPT->iface_path[4], 0L); 849 } 850 else { 851 // FIXME PCI 852 } 853 write_byte(DS, SI+(uint16_t)&Int13DPT->device_path[0], device%2); 854 write_byte(DS, SI+(uint16_t)&Int13DPT->device_path[1], 0); 855 write_word(DS, SI+(uint16_t)&Int13DPT->device_path[2], 0); 856 write_dword(DS, SI+(uint16_t)&Int13DPT->device_path[4], 0L); 857 858 checksum=0; 859 for (i=30; i<64; i++) checksum+=read_byte(DS, SI + i); 860 checksum = -checksum; 861 write_byte(DS, SI+(uint16_t)&Int13DPT->checksum, checksum); 862 } 863 864 goto int13_success; 865 break; 811 size = read_word(DS,SI+(uint16_t)&Int13Ext->size); 812 813 // Buffer is too small 814 if(size < 0x1a) 815 goto int13_fail; 816 817 // EDD 1.x 818 if(size >= 0x1a) { 819 uint16_t blksize; 820 821 blksize = bios_dsk->devices[device].blksize; 822 823 write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x1a); 824 write_word(DS, SI+(uint16_t)&Int13DPT->infos, 0x74); // removable, media change, lockable, max values 825 write_dword(DS, SI+(uint16_t)&Int13DPT->cylinders, 0xffffffff); 826 write_dword(DS, SI+(uint16_t)&Int13DPT->heads, 0xffffffff); 827 write_dword(DS, SI+(uint16_t)&Int13DPT->spt, 0xffffffff); 828 write_dword(DS, SI+(uint16_t)&Int13DPT->sector_count1, 0xffffffff); // FIXME should be Bit64 829 write_dword(DS, SI+(uint16_t)&Int13DPT->sector_count2, 0xffffffff); 830 write_word(DS, SI+(uint16_t)&Int13DPT->blksize, blksize); 831 } 832 833 // EDD 2.x 834 if(size >= 0x1e) { 835 uint8_t channel, irq, mode, checksum, i; 836 uint16_t iobase1, iobase2, options; 837 838 write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x1e); 839 840 write_word(DS, SI+(uint16_t)&Int13DPT->dpte_segment, ebda_seg); 841 write_word(DS, SI+(uint16_t)&Int13DPT->dpte_offset, (uint16_t)&EbdaData->bdisk.dpte); 842 843 // Fill in dpte 844 channel = device / 2; 845 iobase1 = bios_dsk->channels[channel].iobase1; 846 iobase2 = bios_dsk->channels[channel].iobase2; 847 irq = bios_dsk->channels[channel].irq; 848 mode = bios_dsk->devices[device].mode; 849 850 // FIXME atapi device 851 options = (1<<4); // lba translation 852 options |= (1<<5); // removable device 853 options |= (1<<6); // atapi device 854 options |= (mode==ATA_MODE_PIO32?1:0<<7); 855 856 bios_dsk->dpte.iobase1 = iobase1; 857 bios_dsk->dpte.iobase2 = iobase2; 858 bios_dsk->dpte.prefix = (0xe | (device % 2))<<4; 859 bios_dsk->dpte.unused = 0xcb; 860 bios_dsk->dpte.irq = irq; 861 bios_dsk->dpte.blkcount = 1 ; 862 bios_dsk->dpte.dma = 0; 863 bios_dsk->dpte.pio = 0; 864 bios_dsk->dpte.options = options; 865 bios_dsk->dpte.reserved = 0; 866 bios_dsk->dpte.revision = 0x11; 867 868 checksum = 0; 869 for (i=0; i<15; i++) 870 checksum += read_byte(ebda_seg, (uint16_t)&EbdaData->bdisk.dpte + i); 871 checksum = -checksum; 872 bios_dsk->dpte.checksum = checksum; 873 } 874 875 // EDD 3.x 876 if(size >= 0x42) { 877 uint8_t channel, iface, checksum, i; 878 uint16_t iobase1; 879 880 channel = device / 2; 881 iface = bios_dsk->channels[channel].iface; 882 iobase1 = bios_dsk->channels[channel].iobase1; 883 884 write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x42); 885 write_word(DS, SI+(uint16_t)&Int13DPT->key, 0xbedd); 886 write_byte(DS, SI+(uint16_t)&Int13DPT->dpi_length, 0x24); 887 write_byte(DS, SI+(uint16_t)&Int13DPT->reserved1, 0); 888 write_word(DS, SI+(uint16_t)&Int13DPT->reserved2, 0); 889 890 if (iface == ATA_IFACE_ISA) { 891 write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[0], 'I'); 892 write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[1], 'S'); 893 write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[2], 'A'); 894 write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[3], 0); 895 } 896 else { 897 // FIXME PCI 898 } 899 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[0], 'A'); 900 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[1], 'T'); 901 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[2], 'A'); 902 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[3], 0); 903 904 if (iface==ATA_IFACE_ISA) { 905 write_word(DS, SI+(uint16_t)&Int13DPT->iface_path[0], iobase1); 906 write_word(DS, SI+(uint16_t)&Int13DPT->iface_path[2], 0); 907 write_dword(DS, SI+(uint16_t)&Int13DPT->iface_path[4], 0L); 908 } 909 else { 910 // FIXME PCI 911 } 912 write_byte(DS, SI+(uint16_t)&Int13DPT->device_path[0], device%2); 913 write_byte(DS, SI+(uint16_t)&Int13DPT->device_path[1], 0); 914 write_word(DS, SI+(uint16_t)&Int13DPT->device_path[2], 0); 915 write_dword(DS, SI+(uint16_t)&Int13DPT->device_path[4], 0L); 916 917 checksum = 0; 918 for (i=30; i<64; i++) 919 checksum+=read_byte(DS, SI + i); 920 checksum = -checksum; 921 write_byte(DS, SI+(uint16_t)&Int13DPT->checksum, checksum); 922 } 923 924 goto int13_success; 925 break; 866 926 867 927 case 0x49: // IBM/MS extended media change 868 // always send changed ??869 SET_AH(06);870 goto int13_fail_nostatus;871 break;928 // always send changed ?? 929 SET_AH(06); 930 goto int13_fail_nostatus; 931 break; 872 932 873 933 case 0x4e: // // IBM/MS set hardware configuration 874 // DMA, prefetch, PIO maximum not supported875 switch (GET_AL()) {934 // DMA, prefetch, PIO maximum not supported 935 switch (GET_AL()) { 876 936 case 0x01: 877 937 case 0x03: 878 938 case 0x04: 879 939 case 0x06: 880 goto int13_success;881 break;940 goto int13_success; 941 break; 882 942 default : 883 goto int13_fail;884 } 885 break;943 goto int13_fail; 944 } 945 break; 886 946 887 947 // all those functions return unimplemented … … 894 954 case 0x50: // ? - send packet command 895 955 default: 896 BX_INFO("%s: unsupported AH=%02x\n", __func__, GET_AH());897 goto int13_fail;898 break;956 BX_INFO("%s: unsupported AH=%02x\n", __func__, GET_AH()); 957 goto int13_fail; 958 break; 899 959 } 900 960
Note:
See TracChangeset
for help on using the changeset viewer.