Changeset 100443 in vbox for trunk/src/VBox
- Timestamp:
- Jul 8, 2023 2:14:42 PM (17 months ago)
- Location:
- trunk/src/VBox/Devices/PC
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/BIOS/ata.c
r98103 r100443 659 659 sum = -sum; 660 660 fdpt->csum = sum; 661 662 /* Read the drive type from the CMOS. If it is one of the old 663 * IBM compatible drive types (rather than Type 47 or so), point 664 * INT 41h/46h at the drive table in ROM. 665 * This is required for some old guests which look at INT 41h/46h, 666 * but either insist that it point to a high segment (NetWare 2.x) 667 * or wipe out all RAM (286 XENIX 2.1.3/2.2.1). 668 */ 669 i = inb_cmos(0x12); 670 i >>= ((1 - device) * 4); 671 i &= 0x0f; 672 if (i == 0xf) 673 i = inb_cmos(0x19 + device); 674 675 if (i <= 23) { // Should be in sync with DevPcBios.cpp 676 fdpt = MK_FP(0xF000, 0xE401); 677 fdpt += i - 1; 678 *int_vec = fdpt; 679 } 661 680 } 662 681 -
trunk/src/VBox/Devices/PC/DevPcBios.cpp
r98103 r100443 595 595 596 596 597 /* Several common PC/AT BIOS drive types. Corresponds to IBM BIOS drive tables. */ 598 PDMMEDIAGEOMETRY aGeomPCAT[] = { 599 /* cyls heads sectors */ 600 { 0, 0, 0 }, /* Type 0 is not used */ 601 { 306, 4, 17 }, /* Type 1, 10MB */ 602 { 615, 4, 17 }, /* Type 2, 20MB */ 603 { 615, 6, 17 }, /* Type 3, 30MB */ 604 { 940, 8, 17 }, /* Type 4, 62MB */ 605 { 940, 6, 17 }, /* Type 5, 47MB */ 606 { 615, 4, 17 }, /* Type 6, 20MB (different WPCOMP from Type 2) */ 607 { 462, 8, 17 }, /* Type 7, 30MB */ 608 { 733, 5, 17 }, /* Type 8, 30MB */ 609 { 900, 15, 17 }, /* Type 9, 117MB */ 610 611 { 820, 3, 17 }, /* Type 10, 21MB */ 612 { 855, 5, 17 }, /* Type 11, 37MB */ 613 { 855, 7, 17 }, /* Type 12, 52MB */ 614 { 306, 8, 17 }, /* Type 13, 21MB */ 615 { 733, 7, 17 }, /* Type 14, 45MB */ 616 { 0, 0, 0 }, /* Type 15 is not used */ 617 { 612, 4, 17 }, /* Type 16, 21MB */ 618 { 977, 5, 17 }, /* Type 17, 43MB */ 619 { 977, 7, 17 }, /* Type 18, 60MB */ 620 { 1024, 7, 17 }, /* Type 19, 62MB */ 621 622 { 733, 5, 17 }, /* Type 20, 32MB */ 623 { 733, 7, 17 }, /* Type 21, 45MB */ 624 { 733, 5, 17 }, /* Type 22, 32MB */ 625 { 306, 4, 17 }, /* Type 23, 10MB */ 626 }; 627 628 /** 629 * Attempts to initialize CMOS data for a hard disk matching one of 630 * the PC/AT BIOS types. Only applicable to the first two drives. 631 * Returns true if drive is one of the few recognized types. 632 */ 633 static bool pcbiosCmosTryPCATHardDisk(PPDMDEVINS pDevIns, int drive, PCPDMMEDIAGEOMETRY pLCHSGeometry) 634 { 635 int type; 636 int typeLow; 637 bool fCompatGeom = false; 638 639 Assert((drive == 0) || (drive == 1)); 640 641 /* See if drive geometry is one of the ancient PC/AT BIOS types. */ 642 for (type = 0; type < RT_ELEMENTS(aGeomPCAT); ++type) { 643 if ( (aGeomPCAT[type].cCylinders == pLCHSGeometry->cCylinders) 644 && (aGeomPCAT[type].cHeads == pLCHSGeometry->cHeads ) 645 && (aGeomPCAT[type].cSectors == pLCHSGeometry->cSectors )) { 646 LogRel(("PcBios: Recognized ATA hard disk %d as PC/AT BIOS type %d\n", drive, type)); 647 fCompatGeom = true; 648 break; 649 } 650 } 651 652 if (fCompatGeom) { 653 uint32_t u32; 654 655 /* For types below 15, the type is in CMOS byte 0x12. 656 * NB: The type for drive 0 is in the high nibble, drive 1 657 * is in the low nibble. 658 * For drive types above 15, CMOS byte 0x12 is set to 15 659 * and actual drive type is in byte 0x19 (drive 0) or 660 * byte 0x1a (drive 1). 661 */ 662 typeLow = type < 15 ? type : 15; 663 664 /* Always update CMOS byte 0x12. */ 665 u32 = pcbiosCmosRead(pDevIns, 0x12); 666 u32 &= 0x0f << (4 * drive); 667 u32 |= typeLow << (4 - 4 * drive); 668 pcbiosCmosWrite(pDevIns, 0x12, u32); 669 670 /* For higher drive types, also update CMOS byte 0x19/0x1a. */ 671 if (type > 15) { 672 u32 = type; 673 pcbiosCmosWrite(pDevIns, 0x19 + drive, u32); 674 } 675 } 676 677 return fCompatGeom; 678 } 679 680 597 681 /** 598 682 * Initializes the CMOS data for one harddisk. … … 601 685 { 602 686 Log2(("%s: offInfo=%#x: LCHS=%d/%d/%d\n", __FUNCTION__, offInfo, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors)); 603 if (offType) 687 if (offType) { 688 uint32_t u32; 689 int drive; 690 691 Assert(offType == 0x1a || offType == 0x19); 692 drive = offType == 0x19 ? 0 : 1; 693 694 /* Update CMOS byte 12h. It will always be set to type 0fh for this disk. */ 695 u32 = pcbiosCmosRead(pDevIns, 0x12); 696 u32 &= 0x0f << (4 * drive); 697 u32 |= 0x0f << (4 - 4 * drive); 698 pcbiosCmosWrite(pDevIns, 0x12, u32); 699 700 /* Now write the extended drive type at offset 19h or 1Ah. */ 604 701 pcbiosCmosWrite(pDevIns, offType, 47); 702 } 605 703 /* Cylinders low */ 606 704 pcbiosCmosWrite(pDevIns, offInfo + 0, RT_MIN(pLCHSGeometry->cCylinders, 1024) & 0xff); … … 951 1049 break; 952 1050 } 953 pcbiosCmosInitHardDisk(pDevIns, offType, offInfo, 954 &LCHSGeometry); 1051 pcbiosCmosInitHardDisk(pDevIns, offType, offInfo, &LCHSGeometry); 1052 if (i < 2) 1053 pcbiosCmosTryPCATHardDisk(pDevIns, i, &LCHSGeometry); 955 1054 } 956 1055 LogRel(("PcBios: ATA LUN#%d LCHS=%u/%u/%u\n", i, LCHSGeometry.cCylinders, LCHSGeometry.cHeads, LCHSGeometry.cSectors)); 957 1056 } 958 1057 } 959 960 /* 0Fh means extended and points to 19h, 1Ah */961 u32 = (apHDs[0] ? 0xf0 : 0) | (apHDs[1] ? 0x0f : 0);962 pcbiosCmosWrite(pDevIns, 0x12, u32);963 1058 964 1059 /*
Note:
See TracChangeset
for help on using the changeset viewer.