Changeset 39372 in vbox for trunk/src/VBox/Devices/PC/BIOS-new
- Timestamp:
- Nov 18, 2011 4:50:34 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 74968
- Location:
- trunk/src/VBox/Devices/PC/BIOS-new
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/BIOS-new/ahci.c
r39366 r39372 15 15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. 16 16 */ 17 /**18 * Parts are based on the int13_harddisk code in rombios.c19 */20 17 21 18 //@todo!!!! save/restore high bits of EAX/ECX and whatever else may be needed. … … 30 27 31 28 #define VBOX_AHCI_DEBUG 1 32 #define VBOX_AHCI_INT13_DEBUG 033 29 34 30 #if VBOX_AHCI_DEBUG … … 38 34 #endif 39 35 40 #if VBOX_AHCI_INT13_DEBUG41 # define VBOXAHCI_INT13_DEBUG(...) BX_INFO(__VA_ARGS__)42 #else43 # define VBOXAHCI_INT13_DEBUG(...)44 #endif45 46 #define AHCI_MAX_STORAGE_DEVICES 447 48 36 /* Number of S/G table entries in EDDS. */ 49 37 #define NUM_EDDS_SG 16 50 38 51 52 /**53 * AHCI device data.54 */55 typedef struct56 {57 uint8_t type; // Detected type of ata (ata/atapi/none/unknown/scsi)58 uint8_t device; // Detected type of attached devices (hd/cd/none)59 uint8_t removable; // Removable device flag60 uint8_t lock; // Locks for removable devices61 uint16_t blksize; // block size62 chs_t lchs; // Logical CHS63 chs_t pchs; // Physical CHS64 uint32_t cSectors; // Total sectors count65 uint8_t port; // Port this device is on.66 } ahci_device_t;67 39 68 40 /** … … 106 78 uint16_t iobase; 107 79 /** Current port which uses the memory to communicate with the controller. */ 108 uint8_t port; 109 /** AHCI device information. */ 110 ahci_device_t aDevices[AHCI_MAX_STORAGE_DEVICES]; 111 /** Index of the next unoccupied device slot. */ 112 uint8_t cDevices; 113 /** Map between (bios hd id - 0x80) and ahci devices. */ 114 uint8_t cHardDisks; 115 uint8_t aHdIdMap[AHCI_MAX_STORAGE_DEVICES]; 116 /** Map between (bios cd id - 0xE0) and ahci_devices. */ 117 uint8_t cCdDrives; 118 uint8_t aCdIdMap[AHCI_MAX_STORAGE_DEVICES]; 119 /** Number of harddisks detected before the AHCI driver started detection. */ 120 uint8_t cHardDisksOld; 121 /** int13 handler to call if given device is not from AHCI. */ 122 uint16_t pfnInt13Old; 80 uint8_t cur_port; 123 81 /** VDS EDDS DMA buffer descriptor structure. */ 124 82 vds_edds edds; … … 275 233 ahci_t __far *ahci = ahci_seg :> 0; 276 234 277 u8Port = ahci-> port;235 u8Port = ahci->cur_port; 278 236 279 237 if (u8Port != 0xff) … … 376 334 ahci_t __far *ahci = ahci_seg :> 0; 377 335 378 u8Port = ahci-> port;336 u8Port = ahci->cur_port; 379 337 380 338 if (u8Port != 0xff) … … 408 366 VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_IE, 0); 409 367 410 ahci-> port = 0xff;368 ahci->cur_port = 0xff; 411 369 } 412 370 } … … 459 417 VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_SERR, 0xffffffff); 460 418 461 ahci->port = u8Port; 462 } 463 464 /** 465 * Write data to the device. 466 */ 467 static void ahci_cmd_data_out(uint16_t ahci_seg, uint16_t u16IoBase, uint8_t u8Port, uint8_t u8Cmd, uint32_t u32Lba, uint16_t u16Sectors, uint16_t SegData, uint16_t OffData) 468 { 469 uint8_t u8CylLow, u8CylHigh, u8Device, u8Sect, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp; 470 471 u8SectCount = (uint8_t)(u16Sectors & 0xff); 472 u8SectCountExp = (uint8_t)((u16Sectors >> 8) & 0xff);; 473 u8Sect = (uint8_t)(u32Lba & 0xff); 474 u8SectExp = (uint8_t)((u32Lba >> 24) & 0xff); 475 u8CylLow = (uint8_t)((u32Lba >> 8) & 0xff); 419 ahci->cur_port = u8Port; 420 } 421 422 /** 423 * Read sectors from an attached AHCI device. 424 * 425 * @returns status code. 426 * @param bios_dsk Pointer to disk request packet (in the 427 * EBDA). 428 */ 429 int ahci_read_sectors(bio_dsk_t __far *bios_dsk) 430 { 431 uint32_t lba; 432 void __far *buffer; 433 uint16_t n_sect; 434 uint16_t ahci_seg; 435 uint16_t io_base; 436 uint16_t device_id; 437 uint8_t port; 438 uint8_t u8CylLow, u8CylHigh, u8Device, u8Sect, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp; 439 440 device_id = bios_dsk->drqp.dev_id - BX_MAX_ATA_DEVICES - BX_MAX_SCSI_DEVICES; 441 if (device_id > BX_MAX_AHCI_DEVICES) 442 BX_PANIC("ahci_read_sectors: device_id out of range %d\n", device_id); 443 444 ahci_seg = bios_dsk->ahci_seg; 445 io_base = read_word(ahci_seg, (uint16_t)&AhciData->iobase); 446 port = bios_dsk->ahcidev[device_id].port; 447 448 lba = bios_dsk->drqp.lba; 449 buffer = bios_dsk->drqp.buffer; 450 n_sect = bios_dsk->drqp.nsect; 451 452 u8SectCount = (uint8_t)(n_sect & 0xff); 453 u8SectCountExp = (uint8_t)((n_sect >> 8) & 0xff); 454 u8Sect = (uint8_t)(lba & 0xff); 455 u8SectExp = (uint8_t)((lba >> 24) & 0xff); 456 u8CylLow = (uint8_t)((lba >> 8) & 0xff); 476 457 u8CylLowExp = 0; 477 u8CylHigh = (uint8_t)(( u32Lba >> 16) & 0xff);458 u8CylHigh = (uint8_t)((lba >> 16) & 0xff); 478 459 u8CylHighExp = 0; 460 479 461 u8Device = (1 << 6); /* LBA access */ 480 462 463 ahci_port_init(ahci_seg, io_base, port); 464 ahci_cmd_data(ahci_seg, io_base, AHCI_CMD_READ_DMA_EXT, 0, u8Device, u8CylHigh, u8CylLow, 465 u8Sect, 0, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, 466 u8SectCountExp, buffer, n_sect * 512, 0); 467 #ifdef DMA_WORKAROUND 468 rep_movsw(buffer, buffer, n_sect * 512 / 2); 469 #endif 470 return 0; //@todo!! 471 } 472 473 /** 474 * Write sectors to an attached AHCI device. 475 * 476 * @returns status code. 477 * @param bios_dsk Pointer to disk request packet (in the 478 * EBDA). 479 */ 480 int ahci_write_sectors(bio_dsk_t __far *bios_dsk) 481 { 482 uint32_t lba; 483 void __far *buffer; 484 uint16_t n_sect; 485 uint16_t ahci_seg; 486 uint16_t io_base; 487 uint16_t device_id; 488 uint8_t port; 489 uint8_t u8CylLow, u8CylHigh, u8Device, u8Sect, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp; 490 491 device_id = bios_dsk->drqp.dev_id - BX_MAX_ATA_DEVICES - BX_MAX_SCSI_DEVICES; 492 if (device_id > BX_MAX_AHCI_DEVICES) 493 BX_PANIC("ahci_write_sectors: device_id out of range %d\n", device_id); 494 495 ahci_seg = bios_dsk->ahci_seg; 496 io_base = read_word(ahci_seg, (uint16_t)&AhciData->iobase); 497 port = bios_dsk->ahcidev[device_id].port; 498 499 lba = bios_dsk->drqp.lba; 500 buffer = bios_dsk->drqp.buffer; 501 n_sect = bios_dsk->drqp.nsect; 502 503 u8SectCount = (uint8_t)(n_sect & 0xff); 504 u8SectCountExp = (uint8_t)((n_sect >> 8) & 0xff); 505 u8Sect = (uint8_t)(lba & 0xff); 506 u8SectExp = (uint8_t)((lba >> 24) & 0xff); 507 u8CylLow = (uint8_t)((lba >> 8) & 0xff); 508 u8CylLowExp = 0; 509 u8CylHigh = (uint8_t)((lba >> 16) & 0xff); 510 u8CylHighExp = 0; 511 512 u8Device = (1 << 6); /* LBA access */ 513 514 ahci_port_init(ahci_seg, io_base, port); 515 ahci_cmd_data(ahci_seg, io_base, AHCI_CMD_WRITE_DMA_EXT, 0, u8Device, u8CylHigh, u8CylLow, 516 u8Sect, 0, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, 517 u8SectCountExp, buffer, n_sect * 512, 0); 518 return 0; //@todo!! 519 } 520 521 static void ahci_port_detect_device(uint16_t ahci_seg, uint16_t u16IoBase, uint8_t u8Port) 522 { 523 uint32_t val; 524 bio_dsk_t __far *bios_dsk; 525 481 526 ahci_port_init(ahci_seg, u16IoBase, u8Port); 482 ahci_cmd_data(ahci_seg, u16IoBase, u8Cmd, 0, u8Device, u8CylHigh, u8CylLow, 483 u8Sect,0, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, 484 u8SectCountExp, SegData :> OffData, u16Sectors * 512, 1); 485 } 486 487 488 /** 489 * Read data from the device. 490 */ 491 static void ahci_cmd_data_in(uint16_t ahci_seg, uint16_t u16IoBase, uint8_t u8Port, uint8_t u8Cmd, 492 uint32_t u32Lba, uint16_t u16Sectors, uint16_t SegData, uint16_t OffData) 493 { 494 uint8_t u8CylLow, u8CylHigh, u8Device, u8Sect, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp; 495 496 u8SectCount = (uint8_t)(u16Sectors & 0xff); 497 u8SectCountExp = (uint8_t)((u16Sectors >> 8) & 0xff);; 498 u8Sect = (uint8_t)(u32Lba & 0xff); 499 u8SectExp = (uint8_t)((u32Lba >> 24) & 0xff); 500 u8CylLow = (uint8_t)((u32Lba >> 8) & 0xff); 501 u8CylLowExp = 0; 502 u8CylHigh = (uint8_t)((u32Lba >> 16) & 0xff); 503 u8CylHighExp = 0; 504 505 u8Device = (1 << 6); /* LBA access */ 506 507 ahci_port_init(ahci_seg, u16IoBase, u8Port); 508 ahci_cmd_data(ahci_seg, u16IoBase, u8Cmd, 0, u8Device, u8CylHigh, u8CylLow, 509 u8Sect, 0, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, 510 u8SectCountExp, SegData :> OffData, u16Sectors * 512, 0); 511 #ifdef DMA_WORKAROUND 512 rep_movsw(SegData :> OffData, SegData :> OffData, u16Sectors * 512 / 2); 513 #endif 514 } 515 516 static void ahci_port_detect_device(uint16_t ahci_seg, uint16_t u16IoBase, uint8_t u8Port) 517 { 518 uint32_t val; 519 520 ahci_port_init(ahci_seg, u16IoBase, u8Port); 527 528 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk; 521 529 522 530 /* Reset connection. */ … … 532 540 if (ahci_ctrl_extract_bits(val, 0xfL, 0) == 0x3L) 533 541 { 534 uint8_t idxDevice; 535 536 idxDevice = read_byte(ahci_seg, (uint16_t)&AhciData->cDevices); 542 uint8_t hdcount, hdcount_ahci, hd_index; 543 544 hdcount_ahci = bios_dsk->ahci_hdcount; 545 537 546 VBOXAHCI_DEBUG("AHCI: Device detected on port %d\n", u8Port); 538 547 539 if ( idxDevice < AHCI_MAX_STORAGE_DEVICES)548 if (hdcount_ahci < BX_MAX_AHCI_DEVICES) 540 549 { 541 550 /* Device detected, enable FIS receive. */ … … 547 556 if (val == 0x101L) 548 557 { 549 uint8_t idxHdCurr;550 558 uint32_t cSectors; 551 559 uint8_t abBuffer[0x0200]; 552 560 uint8_t fRemovable; 553 561 uint16_t cCylinders, cHeads, cSectorsPerTrack; 554 uint8_t cHardDisksOld;555 562 uint8_t idxCmosChsBase; 556 563 557 idxHdCurr = read_byte(ahci_seg, (uint16_t)&AhciData->cHardDisks);558 564 VBOXAHCI_DEBUG("AHCI: Detected hard disk\n"); 559 565 … … 561 567 ahci_cmd_data(ahci_seg, u16IoBase, ATA_CMD_IDENTIFY_DEVICE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &abBuffer, sizeof(abBuffer), 0); 562 568 563 write_byte(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].port, u8Port); 569 /* Calculate index into the generic disk table. */ 570 hd_index = hdcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES; 564 571 565 572 fRemovable = *(abBuffer+0) & 0x80 ? 1 : 0; … … 575 582 VBOXAHCI_DEBUG("AHCI: %ld sectors\n", cSectors); 576 583 577 write_byte(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].device,ATA_DEVICE_HD); 578 write_byte(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].removable, fRemovable); 579 write_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].blksize, 512); 580 write_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].pchs.heads, cHeads); 581 write_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].pchs.cylinders, cCylinders); 582 write_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].pchs.spt, cSectorsPerTrack); 583 write_dword(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].cSectors, cSectors); 584 bios_dsk->ahcidev[hdcount_ahci].port = u8Port; 585 bios_dsk->devices[hd_index].type = ATA_TYPE_AHCI; 586 bios_dsk->devices[hd_index].device = ATA_DEVICE_HD; 587 bios_dsk->devices[hd_index].removable = fRemovable; 588 bios_dsk->devices[hd_index].lock = 0; 589 bios_dsk->devices[hd_index].blksize = 512; 590 bios_dsk->devices[hd_index].translation = ATA_TRANSLATION_LBA; 591 bios_dsk->devices[hd_index].sectors = cSectors; 592 593 bios_dsk->devices[hd_index].pchs.heads = cHeads; 594 bios_dsk->devices[hd_index].pchs.cylinders = cCylinders; 595 bios_dsk->devices[hd_index].pchs.spt = cSectorsPerTrack; 584 596 585 597 /* Get logical CHS geometry. */ 586 switch ( idxDevice)598 switch (hdcount_ahci) 587 599 { 588 600 case 0: … … 614 626 } 615 627 VBOXAHCI_DEBUG("AHCI: Dev %d LCHS=%d/%d/%d\n", 616 idxDevice, cCylinders, cHeads, cSectorsPerTrack); 617 write_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.heads, cHeads); 618 write_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.cylinders, cCylinders); 619 write_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.spt, cSectorsPerTrack); 620 621 write_byte(ahci_seg, (uint16_t)&AhciData->aHdIdMap[idxHdCurr], idxDevice); 622 idxHdCurr++; 623 write_byte(ahci_seg, (uint16_t)&AhciData->cHardDisks, idxHdCurr); 628 hdcount_ahci, cCylinders, cHeads, cSectorsPerTrack); 629 630 bios_dsk->devices[hd_index].lchs.heads = cHeads; 631 bios_dsk->devices[hd_index].lchs.cylinders = cCylinders; 632 bios_dsk->devices[hd_index].lchs.spt = cSectorsPerTrack; 633 634 /* Store the id of the disk in the ata hdidmap. */ 635 hdcount = bios_dsk->hdcount; 636 bios_dsk->hdidmap[hdcount] = hdcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES; 637 hdcount++; 638 bios_dsk->hdcount = hdcount; 624 639 625 640 /* Update hdcount in the BDA. */ 626 cHardDisksOld = read_byte(0x40, 0x75); 627 cHardDisksOld++; 628 write_byte(0x40, 0x75, cHardDisksOld); 641 hdcount = read_byte(0x40, 0x75); 642 hdcount++; 643 write_byte(0x40, 0x75, hdcount); 644 629 645 } 630 646 else if (val == 0xeb140101) … … 635 651 VBOXAHCI_DEBUG("AHCI: Ignoring unknown device\n"); 636 652 637 idxDevice++;638 write_byte(ahci_seg, (uint16_t)&AhciData->cDevices, idxDevice);653 hdcount_ahci++; 654 bios_dsk->ahci_hdcount = hdcount_ahci; 639 655 } 640 656 else … … 643 659 } 644 660 645 #define SET_DISK_RET_STATUS(status) write_byte(0x0040, 0x0074, status) 646 647 /** 648 * Int 13 handler. 649 */ 650 void BIOSCALL ahci_int13(volatile uint16_t RET, volatile uint16_t ES, volatile uint16_t DS, volatile uint16_t DI, 651 volatile uint16_t SI, volatile uint16_t BP, volatile uint16_t SP, volatile uint16_t BX, 652 volatile uint16_t DX, volatile uint16_t CX, volatile uint16_t AX, volatile uint16_t IPIRET, 653 volatile uint16_t CSIRET, volatile uint16_t FLAGSIRET, volatile uint16_t IP, 654 volatile uint16_t CS, volatile uint16_t FLAGS) 655 { 656 uint16_t ebda_seg; 657 uint16_t ahci_seg, u16IoBase; 658 uint8_t idxDevice; 659 uint8_t old_disks; 660 uint8_t u8Port; 661 662 uint32_t lba; 663 uint16_t cylinder, head, sector; 664 uint16_t segment, offset; 665 uint16_t npc, nph, npspt, nlc, nlh, nlspt; 666 uint16_t count; 667 // uint16_t size; 668 uint8_t status; 669 670 VBOXAHCI_INT13_DEBUG("ahci_int13 AX=%x CX=%x DX=%x BX=%x ES=%x SP=%x BP=%x SI=%x DI=%x IP=%x CS=%x FLAGS=%x\n", 671 AX, CX, DX, BX, ES, SP, BP, SI, DI, IP, CS, FLAGS); 672 673 ebda_seg = read_word(0x0040, 0x000E); 674 ahci_seg = read_word(ebda_seg, (uint16_t)&EbdaData->ahci_seg); 675 u16IoBase = read_word(ahci_seg, (uint16_t)&AhciData->iobase); 676 old_disks = read_byte(ahci_seg, (uint16_t)&AhciData->cHardDisksOld); 677 VBOXAHCI_INT13_DEBUG("ahci_int13: ahci_seg=%x u16IoBase=%x old_disks=%d\n", ahci_seg, u16IoBase, old_disks); 678 679 /* Check if the device is controlled by us first. */ 680 if ( (GET_DL() < 0x80) 681 || (GET_DL() < 0x80 + old_disks) 682 || ((GET_DL() & 0xe0) != 0x80) /* No CD-ROM drives supported for now */) 683 { 684 VBOXAHCI_INT13_DEBUG("ahci_int13: device not controlled by us, forwarding to old handler (%d)\n", old_disks); 685 /* Fill the iret frame to jump to the old handler. */ 686 IPIRET = read_word(ahci_seg, (uint16_t)&AhciData->pfnInt13Old); 687 CSIRET = 0xf000; 688 FLAGSIRET = FLAGS; 689 RET = 1; 690 return; 691 } 692 693 //@todo: pre-init aHdIdMap! 694 idxDevice = read_byte(ahci_seg, (uint16_t)&AhciData->aHdIdMap[GET_DL() - 0x80 - old_disks]); 695 696 if (idxDevice >= AHCI_MAX_STORAGE_DEVICES) 697 { 698 VBOXAHCI_INT13_DEBUG("ahci_int13: function %02x, unmapped device for ELDL=%02x\n", GET_AH(), GET_DL()); 699 goto ahci_int13_fail; 700 } 701 702 u8Port = read_byte(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].port); 703 704 switch (GET_AH()) 705 { 706 case 0x00: /* disk controller reset */ 707 { 708 /** @todo: not really important I think. */ 709 goto ahci_int13_success; 710 break; 711 } 712 case 0x01: /* read disk status */ 713 { 714 status = read_byte(0x0040, 0x0074); 715 SET_AH(status); 716 SET_DISK_RET_STATUS(0); 717 /* set CF if error status read */ 718 if (status) 719 goto ahci_int13_fail_nostatus; 720 else 721 goto ahci_int13_success_noah; 722 break; 723 } 724 case 0x02: // read disk sectors 725 case 0x03: // write disk sectors 726 case 0x04: // verify disk sectors 727 { 728 count = GET_AL(); 729 cylinder = GET_CH(); 730 cylinder |= ( ((uint16_t) GET_CL()) << 2) & 0x300; 731 sector = (GET_CL() & 0x3f); 732 head = GET_DH(); 733 734 segment = ES; 735 offset = BX; 736 737 if ((count > 128) || (count == 0)) 738 { 739 BX_INFO("ahci_int13: function %02x, count out of range!\n",GET_AH()); 740 goto ahci_int13_fail; 741 } 742 743 nlc = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.cylinders); 744 nlh = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.heads); 745 nlspt = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.spt); 746 747 // sanity check on cyl heads, sec 748 if( (cylinder >= nlc) || (head >= nlh) || (sector > nlspt )) 749 { 750 BX_INFO("ahci_int13: function %02x, disk %02x, idx %02x, parameters out of range %04x/%04x/%04x!\n", 751 GET_AH(), GET_DL(), idxDevice, cylinder, head, sector); 752 goto ahci_int13_fail; 753 } 754 755 // FIXME verify 756 if ( GET_AH() == 0x04 ) 757 goto ahci_int13_success; 758 759 lba = ((((uint32_t)cylinder * (uint32_t)nlh) + (uint32_t)head) * (uint32_t)nlspt) + (uint32_t)sector - 1; 760 761 status = 0; 762 if ( GET_AH() == 0x02 ) 763 ahci_cmd_data_in(ahci_seg, u16IoBase, u8Port, AHCI_CMD_READ_DMA_EXT, lba, count, segment, offset); 764 else 765 ahci_cmd_data_out(ahci_seg, u16IoBase, u8Port, AHCI_CMD_WRITE_DMA_EXT, lba, count, segment, offset); 766 767 // Set nb of sector transferred 768 SET_AL(read_word(ebda_seg, (uint16_t)&EbdaData->bdisk.drqp.trsfsectors)); 769 770 if (status != 0) 771 { 772 BX_INFO("ahci_int13: function %02x, error %02x !\n",GET_AH(),status); 773 SET_AH(0x0c); 774 goto ahci_int13_fail_noah; 775 } 776 777 goto ahci_int13_success; 778 break; 779 } 780 case 0x05: /* format disk track */ 781 BX_INFO("format disk track called\n"); 782 goto ahci_int13_success; 783 break; 784 case 0x08: /* read disk drive parameters */ 785 { 786 // Get logical geometry from table 787 nlc = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.cylinders); 788 nlh = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.heads); 789 nlspt = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.spt); 790 791 count = read_byte(ahci_seg, (uint16_t)&AhciData->cHardDisks); /** @todo correct? */ 792 /* Maximum cylinder number is just one less than the number of cylinders. */ 793 nlc = nlc - 1; /* 0 based , last sector not used */ 794 SET_AL(0); 795 SET_CH(nlc & 0xff); 796 SET_CL(((nlc >> 2) & 0xc0) | (nlspt & 0x3f)); 797 SET_DH(nlh - 1); 798 SET_DL(count); /* FIXME returns 0, 1, or n hard drives */ 799 // FIXME should set ES & DI 800 goto ahci_int13_success; 801 break; 802 } 803 case 0x10: /* check drive ready */ 804 { 805 /** @todo */ 806 goto ahci_int13_success; 807 break; 808 } 809 case 0x15: /* read disk drive size */ 810 { 811 // Get physical geometry from table 812 npc = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].pchs.cylinders); 813 nph = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].pchs.heads); 814 npspt = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].pchs.spt); 815 816 // Compute sector count seen by int13 817 lba = (uint32_t)npc * (uint32_t)nph * (uint32_t)npspt; 818 CX = lba >> 16; 819 DX = lba & 0xffff; 820 821 SET_AH(3); // hard disk accessible 822 goto ahci_int13_success_noah; 823 break; 824 } 825 #if 0 826 case 0x41: // IBM/MS installation check 827 { 828 BX=0xaa55; // install check 829 SET_AH(0x30); // EDD 3.0 830 CX=0x0007; // ext disk access and edd, removable supported 831 goto ahci_int13_success_noah; 832 break; 833 } 834 case 0x42: // IBM/MS extended read 835 case 0x43: // IBM/MS extended write 836 case 0x44: // IBM/MS verify 837 case 0x47: // IBM/MS extended seek 838 { 839 count=read_word(DS, SI+(uint16_t)&Int13Ext->count); 840 segment=read_word(DS, SI+(uint16_t)&Int13Ext->segment); 841 offset=read_word(DS, SI+(uint16_t)&Int13Ext->offset); 842 843 // Can't use 64 bits lba 844 lba=read_dword(DS, SI+(uint16_t)&Int13Ext->lba2); 845 if (lba != 0L) 846 { 847 BX_PANIC("ahci_int13: function %02x. Can't use 64bits lba\n",GET_AH()); 848 goto ahci_int13_fail; 849 } 850 851 // Get 32 bits lba and check 852 lba=read_dword(DS, SI+(uint16_t)&Int13Ext->lba1); 853 854 if (lba >= read_word(ahci_seg, &AhciData->aDevices[idxDevice].cSectors) ) 855 { 856 BX_INFO("ahci_int13: function %02x. LBA out of range\n",GET_AH()); 857 goto ahci_int13_fail; 858 } 859 860 // If verify or seek 861 if (( GET_AH() == 0x44 ) || ( GET_AH() == 0x47 )) 862 goto ahci_int13_success; 863 864 // Execute the command 865 if ( GET_AH() == 0x42 ) 866 { 867 ... 868 } 869 else 870 { 871 ... 872 } 873 874 count=read_word(ebda_seg, &EbdaData->bdisk.drqp.trsfsectors); 875 write_word(DS, SI+(uint16_t)&Int13Ext->count, count); 876 877 if (status != 0) 878 { 879 BX_INFO("ahci_int13: function %02x, error %02x !\n",GET_AH(),status); 880 SET_AH(0x0c); 881 goto ahci_int13_fail_noah; 882 } 883 goto ahci_int13_success; 884 break; 885 } 886 case 0x45: // IBM/MS lock/unlock drive 887 case 0x49: // IBM/MS extended media change 888 goto ahci_int13_success; // Always success for HD 889 break; 890 case 0x46: // IBM/MS eject media 891 SET_AH(0xb2); // Volume Not Removable 892 goto ahci_int13_fail_noah; // Always fail for HD 893 break; 894 895 case 0x48: // IBM/MS get drive parameters 896 size=read_word(DS,SI+(uint16_t)&Int13DPT->size); 897 898 // Buffer is too small 899 if(size < 0x1a) 900 goto ahci_int13_fail; 901 902 // EDD 1.x 903 if(size >= 0x1a) 904 { 905 uint16_t blksize; 906 907 npc = read_word(ahci_seg, &AhciData->aDevices[idxDevice].pchs.cylinders); 908 nph = read_word(ahci_seg, &AhciData->aDevices[idxDevice].pchs.heads); 909 npspt = read_word(ahci_seg, &AhciData->aDevices[idxDevice].pchs.spt); 910 lba = read_dword(ahci_seg, &AhciData->aDevices[idxDevice].cSectors); 911 blksize = read_word(ahci_seg, &AhciData->aDevices[idxDevice].blksize); 912 913 write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x1a); 914 write_word(DS, SI+(uint16_t)&Int13DPT->infos, 0x02); // geometry is valid 915 write_dword(DS, SI+(uint16_t)&Int13DPT->cylinders, (uint32_t)npc); 916 write_dword(DS, SI+(uint16_t)&Int13DPT->heads, (uint32_t)nph); 917 write_dword(DS, SI+(uint16_t)&Int13DPT->spt, (uint32_t)npspt); 918 write_dword(DS, SI+(uint16_t)&Int13DPT->sector_count1, lba); // FIXME should be Bit64 919 write_dword(DS, SI+(uint16_t)&Int13DPT->sector_count2, 0L); 920 write_word(DS, SI+(uint16_t)&Int13DPT->blksize, blksize); 921 } 922 923 #if 0 /* Disable EDD 2.X and 3.x for now, don't know if it is required by any OS loader yet */ 924 // EDD 2.x 925 if(size >= 0x1e) 926 { 927 uint8_t channel, dev, irq, mode, checksum, i, translation; 928 uint16_t iobase1, iobase2, options; 929 930 translation = ATA_TRANSLATION_LBA; 931 932 write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x1e); 933 934 write_word(DS, SI+(uint16_t)&Int13DPT->dpte_segment, ebda_seg); 935 write_word(DS, SI+(uint16_t)&Int13DPT->dpte_offset, &EbdaData->bdisk.dpte); 936 937 // Fill in dpte 938 channel = device / 2; 939 iobase1 = read_word(ebda_seg, &EbdaData->bdisk.channels[channel].iobase1); 940 iobase2 = read_word(ebda_seg, &EbdaData->bdisk.channels[channel].iobase2); 941 irq = read_byte(ebda_seg, &EbdaData->bdisk.channels[channel].irq); 942 mode = read_byte(ebda_seg, &EbdaData->bdisk.devices[device].mode); 943 translation = read_byte(ebda_seg, &EbdaData->bdisk.devices[device].translation); 944 945 options = (translation==ATA_TRANSLATION_NONE?0:1<<3); // chs translation 946 options |= (1<<4); // lba translation 947 options |= (mode==ATA_MODE_PIO32?1:0<<7); 948 options |= (translation==ATA_TRANSLATION_LBA?1:0<<9); 949 options |= (translation==ATA_TRANSLATION_RECHS?3:0<<9); 950 951 write_word(ebda_seg, &EbdaData->bdisk.dpte.iobase1, iobase1); 952 write_word(ebda_seg, &EbdaData->bdisk.dpte.iobase2, iobase2); 953 //write_byte(ebda_seg, &EbdaData->bdisk.dpte.prefix, (0xe | /*(device % 2))<<4*/ ); 954 write_byte(ebda_seg, &EbdaData->bdisk.dpte.unused, 0xcb ); 955 write_byte(ebda_seg, &EbdaData->bdisk.dpte.irq, irq ); 956 write_byte(ebda_seg, &EbdaData->bdisk.dpte.blkcount, 1 ); 957 write_byte(ebda_seg, &EbdaData->bdisk.dpte.dma, 0 ); 958 write_byte(ebda_seg, &EbdaData->bdisk.dpte.pio, 0 ); 959 write_word(ebda_seg, &EbdaData->bdisk.dpte.options, options); 960 write_word(ebda_seg, &EbdaData->bdisk.dpte.reserved, 0); 961 write_byte(ebda_seg, &EbdaData->bdisk.dpte.revision, 0x11); 962 963 checksum=0; 964 for (i=0; i<15; i++) 965 checksum+=read_byte(ebda_seg, (&EbdaData->bdisk.dpte) + i); 966 967 checksum = -checksum; 968 write_byte(ebda_seg, &EbdaData->bdisk.dpte.checksum, checksum); 969 } 970 971 // EDD 3.x 972 if(size >= 0x42) 973 { 974 uint8_t channel, iface, checksum, i; 975 uint16_t iobase1; 976 977 channel = device / 2; 978 iface = read_byte(ebda_seg, &EbdaData->bdisk.channels[channel].iface); 979 iobase1 = read_word(ebda_seg, &EbdaData->bdisk.channels[channel].iobase1); 980 981 write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x42); 982 write_word(DS, SI+(uint16_t)&Int13DPT->key, 0xbedd); 983 write_byte(DS, SI+(uint16_t)&Int13DPT->dpi_length, 0x24); 984 write_byte(DS, SI+(uint16_t)&Int13DPT->reserved1, 0); 985 write_word(DS, SI+(uint16_t)&Int13DPT->reserved2, 0); 986 987 if (iface==ATA_IFACE_ISA) { 988 write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[0], 'I'); 989 write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[1], 'S'); 990 write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[2], 'A'); 991 write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[3], 0); 992 } 993 else { 994 // FIXME PCI 995 } 996 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[0], 'A'); 997 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[1], 'T'); 998 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[2], 'A'); 999 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[3], 0); 1000 1001 if (iface==ATA_IFACE_ISA) { 1002 write_word(DS, SI+(uint16_t)&Int13DPT->iface_path[0], iobase1); 1003 write_word(DS, SI+(uint16_t)&Int13DPT->iface_path[2], 0); 1004 write_dword(DS, SI+(uint16_t)&Int13DPT->iface_path[4], 0L); 1005 } 1006 else { 1007 // FIXME PCI 1008 } 1009 //write_byte(DS, SI+(uint16_t)&Int13DPT->device_path[0], device%2); 1010 write_byte(DS, SI+(uint16_t)&Int13DPT->device_path[1], 0); 1011 write_word(DS, SI+(uint16_t)&Int13DPT->device_path[2], 0); 1012 write_dword(DS, SI+(uint16_t)&Int13DPT->device_path[4], 0L); 1013 1014 checksum=0; 1015 for (i=30; i<64; i++) checksum+=read_byte(DS, SI + i); 1016 checksum = -checksum; 1017 write_byte(DS, SI+(uint16_t)&Int13DPT->checksum, checksum); 1018 } 1019 #endif 1020 goto ahci_int13_success; 1021 break; 1022 case 0x4e: // // IBM/MS set hardware configuration 1023 // DMA, prefetch, PIO maximum not supported 1024 switch (GET_AL()) 1025 { 1026 case 0x01: 1027 case 0x03: 1028 case 0x04: 1029 case 0x06: 1030 goto ahci_int13_success; 1031 break; 1032 default : 1033 goto ahci_int13_fail; 1034 } 1035 break; 1036 #endif 1037 case 0x09: /* initialize drive parameters */ 1038 case 0x0c: /* seek to specified cylinder */ 1039 case 0x0d: /* alternate disk reset */ 1040 case 0x11: /* recalibrate */ 1041 case 0x14: /* controller internal diagnostic */ 1042 BX_INFO("ahci_int13: function %02xh unimplemented, returns success\n", GET_AH()); 1043 goto ahci_int13_success; 1044 break; 1045 1046 case 0x0a: /* read disk sectors with ECC */ 1047 case 0x0b: /* write disk sectors with ECC */ 1048 case 0x18: // set media type for format 1049 case 0x50: // IBM/MS send packet command 1050 default: 1051 BX_INFO("ahci_int13: function %02xh unsupported, returns fail\n", GET_AH()); 1052 goto ahci_int13_fail; 1053 break; 1054 } 1055 1056 //@todo: this is really badly written, reuse the code more! 1057 ahci_int13_fail: 1058 SET_AH(0x01); // defaults to invalid function in AH or invalid parameter 1059 ahci_int13_fail_noah: 1060 SET_DISK_RET_STATUS(GET_AH()); 1061 ahci_int13_fail_nostatus: 1062 VBOXAHCI_INT13_DEBUG("ahci_int13: done, AH=%02x\n", GET_AH()); 1063 SET_CF(); // error occurred 1064 return; 1065 1066 ahci_int13_success: 1067 SET_AH(0x00); // no error 1068 ahci_int13_success_noah: 1069 SET_DISK_RET_STATUS(0x00); 1070 VBOXAHCI_INT13_DEBUG("ahci_int13: done, AH=%02x\n", GET_AH()); 1071 CLEAR_CF(); // no error 1072 return; 1073 } 1074 1075 #undef SET_DISK_RET_STATUS 1076 1077 /* Defined in assembler code. */ 1078 extern void ahci_int13_handler(void); 1079 #pragma aux ahci_int13_handler "*"; 1080 1081 /** 1082 * Install the in13 interrupt handler 1083 * preserving the previous one. 1084 */ 1085 static void ahci_install_int_handler(uint16_t ahci_seg) 1086 { 1087 1088 uint16_t pfnInt13Old; 1089 1090 VBOXAHCI_DEBUG("AHCI: Hooking int 13h vector\n"); 1091 1092 /* Read the old interrupt handler. */ 1093 pfnInt13Old = read_word(0x0000, 0x0013*4); 1094 write_word(ahci_seg, (uint16_t)&AhciData->pfnInt13Old, pfnInt13Old); 1095 1096 /* Set our own */ 1097 write_word(0x0000, 0x0013*4, (uint16_t)ahci_int13_handler); 1098 } 1099 1100 /** 1101 * Allocates 1K from the base memory. 661 /** 662 * Allocates 1K of conventional memory. 1102 663 */ 1103 664 static uint16_t ahci_mem_alloc(void) … … 1146 707 } 1147 708 VBOXAHCI_DEBUG("AHCI: ahci_seg=%04x, size=%04x, pointer at EBDA:%04x (EBDA size=%04x)\n", 1148 ahci_seg, sizeof(ahci_t), (uint16_t)&EbdaData->ahci_seg, sizeof(ebda_data_t)); 1149 1150 write_word(ebda_seg, (uint16_t)&EbdaData->ahci_seg, ahci_seg); 1151 write_byte(ahci_seg, (uint16_t)&AhciData->port, 0xff); 709 ahci_seg, sizeof(ahci_t), (uint16_t)&EbdaData->bdisk.ahci_seg, sizeof(ebda_data_t)); 710 711 write_word(ebda_seg, (uint16_t)&EbdaData->bdisk.ahci_seg, ahci_seg); 712 write_byte(ebda_seg, (uint16_t)&EbdaData->bdisk.ahci_hdcount, 0); 713 write_byte(ahci_seg, (uint16_t)&AhciData->cur_port, 0xff); 1152 714 write_word(ahci_seg, (uint16_t)&AhciData->iobase, u16IoBase); 1153 write_byte(ahci_seg, (uint16_t)&AhciData->cHardDisksOld, read_byte(0x40, 0x75));1154 715 1155 716 /* Reset the controller. */ … … 1178 739 } 1179 740 i++; 1180 }1181 1182 if (read_byte(ahci_seg, (uint16_t)&AhciData->cDevices) > 0)1183 {1184 /*1185 * Init completed and there is at least one device present.1186 * Install our int13 handler.1187 */1188 ahci_install_int_handler(ahci_seg);1189 741 } 1190 742 -
trunk/src/VBox/Devices/PC/BIOS-new/ata.h
r39366 r39372 43 43 #define ATA_DATA_IN 0x01 44 44 #define ATA_DATA_OUT 0x02 45 46 #define ATA_TRANSLATION_NONE 047 #define ATA_TRANSLATION_LBA 148 #define ATA_TRANSLATION_LARGE 249 #define ATA_TRANSLATION_RECHS 350 45 51 46 #define ATA_IFACE_NONE 0x00 -
trunk/src/VBox/Devices/PC/BIOS-new/disk.c
r39366 r39372 168 168 if ( GET_AH() == 0x02 ) 169 169 { 170 #ifdef VBOX_WITH_AHCI 171 if (VBOX_IS_AHCI_DEVICE(device)) 172 status = ahci_read_sectors(bios_dsk); 173 else 174 #endif 170 175 #ifdef VBOX_WITH_SCSI 171 176 if (VBOX_IS_SCSI_DEVICE(device)) … … 175 180 status = ata_read_sectors(bios_dsk); 176 181 } else { 182 #ifdef VBOX_WITH_AHCI 183 if (VBOX_IS_AHCI_DEVICE(device)) 184 status = ahci_write_sectors(bios_dsk); 185 else 186 #endif 177 187 #ifdef VBOX_WITH_SCSI 178 188 if (VBOX_IS_SCSI_DEVICE(device)) … … 370 380 // Execute the command 371 381 if ( GET_AH() == 0x42 ) { 382 #ifdef VBOX_WITH_AHCI 383 if (VBOX_IS_AHCI_DEVICE(device)) 384 status = ahci_read_sectors(bios_dsk); 385 else 386 #endif 372 387 #ifdef VBOX_WITH_SCSI 373 388 if (VBOX_IS_SCSI_DEVICE(device)) … … 377 392 status = ata_read_sectors(bios_dsk); 378 393 } else { 394 #ifdef VBOX_WITH_AHCI 395 if (VBOX_IS_AHCI_DEVICE(device)) 396 status = ahci_write_sectors(bios_dsk); 397 else 398 #endif 379 399 #ifdef VBOX_WITH_SCSI 380 400 if (VBOX_IS_SCSI_DEVICE(device)) -
trunk/src/VBox/Devices/PC/BIOS-new/ebda.h
r39366 r39372 50 50 51 51 #ifdef VBOX_WITH_SCSI 52 /* Enough for now */ 53 # define BX_MAX_SCSI_DEVICES 4 54 # define BX_MAX_STORAGE_DEVICES (BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES) 55 56 /* A SCSI device starts always at BX_MAX_ATA_DEVICES. */ 57 # define VBOX_IS_SCSI_DEVICE(device_id) (device_id >= BX_MAX_ATA_DEVICES) 58 # define VBOX_GET_SCSI_DEVICE(device_id) (device_id - BX_MAX_ATA_DEVICES) 52 /* Enough for now */ 53 #define BX_MAX_SCSI_DEVICES 4 54 /* A SCSI device starts always at BX_MAX_ATA_DEVICES. */ 55 #define VBOX_IS_SCSI_DEVICE(device_id) (device_id >= BX_MAX_ATA_DEVICES) 56 #define VBOX_GET_SCSI_DEVICE(device_id) (device_id - BX_MAX_ATA_DEVICES) 59 57 #else 60 # define BX_MAX_STORAGE_DEVICES BX_MAX_ATA_DEVICES 61 #endif 58 #define BX_MAX_SCSI_DEVICES 0 59 #endif 60 61 #ifdef VBOX_WITH_AHCI 62 /* Four should be enough for now */ 63 #define BX_MAX_AHCI_DEVICES 4 64 65 /* An AHCI device starts always at BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES. */ 66 #define VBOX_IS_AHCI_DEVICE(device_id) (device_id >= (BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES)) 67 #define VBOX_GET_AHCI_DEVICE(device_id) (device_id - (BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES)) 68 #else 69 #define BX_MAX_AHCI_DEVICES 0 70 #endif 71 72 #define BX_MAX_STORAGE_DEVICES (BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES + BX_MAX_AHCI_DEVICES) 62 73 63 74 /* Generic storage device types. Bit of a misnomer! */ … … 67 78 #define ATA_TYPE_ATAPI 0x03 68 79 #define ATA_TYPE_SCSI 0x04 // SCSI disk 80 #define ATA_TYPE_AHCI 0x05 // SATA disk 69 81 70 82 #define ATA_DEVICE_NONE 0x00 … … 72 84 #define ATA_DEVICE_CDROM 0x05 73 85 86 #define ATA_TRANSLATION_NONE 0 87 #define ATA_TRANSLATION_LBA 1 88 #define ATA_TRANSLATION_LARGE 2 89 #define ATA_TRANSLATION_RECHS 3 74 90 75 91 #if 1 //BX_USE_ATADRV … … 146 162 #endif 147 163 164 #ifdef VBOX_WITH_AHCI 165 166 /* AHCI specific device information. */ 167 typedef struct { 168 uint8_t port; /* SATA port. */ 169 } ahci_dev_t; 170 171 #endif 172 148 173 /* Generic disk information. */ 149 174 typedef struct { … … 152 177 uint8_t removable; /* Removable device flag. */ 153 178 uint8_t lock; /* Lock count for removable devices. */ 179 //@todo: ATA specific - move? 154 180 uint8_t mode; /* Transfer mode: PIO 16/32 bits - IRQ - ISADMA - PCIDMA. */ 155 181 uint8_t translation; /* Type of geometry translation. */ … … 182 208 disk_req_t drqp; /* Disk request packet. */ 183 209 184 /* ATA bus-specific device information. */185 ata_chan_t channels[BX_MAX_ATA_INTERFACES];186 187 210 /* Bus-independent disk device information. */ 188 disk_dev_t devices[BX_MAX_ ATA_DEVICES + BX_MAX_SCSI_DEVICES];189 190 uint8_t hdcount; /* Number of ATAdisks. */191 /* Map between (BIOS disk ID - 0x80) and ATA/SCSI disks. */211 disk_dev_t devices[BX_MAX_STORAGE_DEVICES]; 212 213 uint8_t hdcount; /* Total number of BIOS disks. */ 214 /* Map between (BIOS disk ID - 0x80) and ATA/SCSI/AHCI disks. */ 192 215 uint8_t hdidmap[BX_MAX_STORAGE_DEVICES]; 193 216 … … 195 218 /* Map between (BIOS CD-ROM ID - 0xE0) and ATA channels. */ 196 219 uint8_t cdidmap[BX_MAX_STORAGE_DEVICES]; 220 221 /* ATA bus-specific device information. */ 222 ata_chan_t channels[BX_MAX_ATA_INTERFACES]; 197 223 198 224 #ifdef VBOX_WITH_SCSI … … 201 227 uint8_t scsi_hdcount; /* Number of SCSI disks. */ 202 228 #endif 229 230 #ifdef VBOX_WITH_AHCI 231 /* SATA (AHCI) bus-specific device information. */ 232 ahci_dev_t ahcidev[BX_MAX_AHCI_DEVICES]; 233 uint8_t ahci_hdcount; /* Number of SATA disks. */ 234 uint16_t ahci_seg; /* Segment of AHCI data block. */ 235 #endif 236 203 237 dpte_t dpte; /* Buffer for building a DPTE. */ 204 238 } bio_dsk_t; … … 233 267 fdpt_t fdpt1; 234 268 235 #if 0236 269 uint8_t filler2[0xC4]; 237 #else238 uint8_t filler2[0xC2];239 uint16_t ahci_seg;240 #endif241 270 242 271 bio_dsk_t bdisk; /* Disk driver data (ATA/SCSI/AHCI). */ … … 244 273 #if BX_ELTORITO_BOOT 245 274 cdemu_t cdemu; /* El Torito floppy/HD emulation data. */ 246 #endif247 248 #ifdef VBOX_WITH_BIOS_AHCI249 // ahci_t ahci;250 // uint16_t ahci_seg; //@todo: Someone is trashing the data here!?!251 275 #endif 252 276 … … 262 286 #define EbdaData ((ebda_data_t *) 0) 263 287 288 /* Note: Using fastcall reduces stack usage a little. */ 289 int __fastcall ata_read_sectors(bio_dsk_t __far *bios_dsk); 290 int __fastcall ata_write_sectors(bio_dsk_t __far *bios_dsk); 291 264 292 int __fastcall scsi_read_sectors(bio_dsk_t __far *bios_dsk); 265 293 int __fastcall scsi_write_sectors(bio_dsk_t __far *bios_dsk); 266 294 267 int __fastcall a ta_read_sectors(bio_dsk_t __far *bios_dsk);268 int __fastcall a ta_write_sectors(bio_dsk_t __far *bios_dsk);295 int __fastcall ahci_read_sectors(bio_dsk_t __far *bios_dsk); 296 int __fastcall ahci_write_sectors(bio_dsk_t __far *bios_dsk); 269 297 270 298 // @todo: put this elsewhere (and change/eliminate?) -
trunk/src/VBox/Devices/PC/BIOS-new/makefile
r39346 r39372 16 16 CFLAGS = -q -0 -wx -zu -s -oas -d1+ -ms 17 17 DEFS = -DVBOX -DVBOX_LANBOOT_SEG=0xE200 -DVBOX_VERSION_STRING=$(QUOTE)0.9$(QUOTE) & 18 -DVBOX_WITH_SCSI -DVBOX_WITH_ BIOS_AHCI18 -DVBOX_WITH_SCSI -DVBOX_WITH_AHCI 19 19 20 20 AFLAGS = -q -0 -wx -
trunk/src/VBox/Devices/PC/BIOS-new/orgs.asm
r39109 r39372 100 100 extrn _cdemu_isactive:near 101 101 extrn _cdemu_emulated_drive:near 102 extrn _ahci_int13:near103 102 extrn _int13_harddisk:near 104 103 extrn _int13_harddisk_ext:near … … 155 154 public hard_drive_post 156 155 public int13_legacy 157 public ahci_int13_handler158 156 public int70_handler 159 157 public int75_handler … … 453 451 endif 454 452 455 ;; floppy setup 456 call floppy_post 457 458 ;; hard drive setup 459 call hard_drive_post 460 461 C_SETUP ; in case assembly code changed things 462 ifdef VBOX_WITH_BIOS_AHCI 453 ifdef VBOX_WITH_AHCI 463 454 ; AHCI driver setup 464 455 call _ahci_init 465 456 endif 466 457 458 ;; floppy setup 459 call floppy_post 460 461 ;; hard drive setup 462 call hard_drive_post 463 464 C_SETUP ; in case assembly code changed things 467 465 call _print_bios_banner 468 466 … … 1490 1488 include pirq.inc 1491 1489 1492 ifdef VBOX_WITH_BIOS_AHCI1493 1494 ahci_int13_handler:1495 ;; allocate space for IRET frame used to call old INT 13h1496 push ax1497 push ax1498 push ax1499 1500 pusha1501 push ds1502 push es1503 push 0 ; Room for return value (default 0)1504 C_SETUP1505 call _ahci_int131506 pop ax1507 pop es1508 pop ds1509 cmp ax, 0 ; Check if interrupt was handled1510 je ahci_int13_out1511 1512 popa ; Restore caller's registers1513 iret ; Call old handler1514 1515 ahci_int13_out:1516 popa1517 add sp, 6 ; Remove the IRET frame1518 iret1519 1520 endif1521 1490 1522 1491 ;; -------------------------------------------------------- -
trunk/src/VBox/Devices/PC/BIOS-new/scsi.c
r39366 r39372 21 21 #include "inlines.h" 22 22 #include "ebda.h" 23 #include "ata.h"24 23 25 24 … … 339 338 bios_dsk->devices[hd_index].removable = 0; 340 339 bios_dsk->devices[hd_index].lock = 0; 341 bios_dsk->devices[hd_index].mode = ATA_MODE_PIO16;342 340 bios_dsk->devices[hd_index].blksize = sector_size; 343 341 bios_dsk->devices[hd_index].translation = ATA_TRANSLATION_LBA;
Note:
See TracChangeset
for help on using the changeset viewer.