VirtualBox

Changeset 7099 in vbox for trunk


Ignore:
Timestamp:
Feb 22, 2008 2:05:36 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
28344
Message:

Use CMOS to store hard disk geometry for more than 4 disks

Location:
trunk/src/VBox/Devices/PC
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/BIOS/logo.c

    r6879 r7099  
    621621
    622622        if (device_position / 2)
     623            printf("Secondary ");
     624        else
    623625            printf("Primary ");
    624         else
    625             printf("Secondary ");
    626626
    627627        if (device_position % 2)
  • trunk/src/VBox/Devices/PC/BIOS/rombios.c

    r6879 r7099  
    24422442              chsgeo_base = 0x70;
    24432443              break;
     2444          case 4:
     2445              chsgeo_base = 0x40;
     2446              break;
     2447          case 5:
     2448              chsgeo_base = 0x48;
     2449              break;
     2450          case 6:
     2451              chsgeo_base = 0x50;
     2452              break;
     2453          case 7:
     2454              chsgeo_base = 0x58;
     2455              break;
    24442456          default:
    24452457              chsgeo_base = 0;
     
    24532465      else
    24542466      {
    2455           Bit32u temp_sectors = sectors;
    2456 
    2457           //FIXME: only valid for LBA translation
    2458           lspt = 63;
    2459           temp_sectors /= 63;
    2460           lheads = temp_sectors / 1024;
    2461           if (lheads>128) lheads = 255;
    2462           else if (lheads>64) lheads = 128;
    2463           else if (lheads>32) lheads = 64;
    2464           else if (lheads>16) lheads = 32;
    2465           else lheads=16;
    2466           lcylinders = temp_sectors / lheads;
    2467 
    2468           // clip to 1024 cylinders
    2469           if (lcylinders > 1024) lcylinders=1024;
    2470 
    2471 #if 0
    24722467          lcylinders = 0;
    24732468          lheads = 0;
    24742469          lspt = 0;
    2475 #endif
    24762470      }
    24772471      BX_INFO("ata%d-%d: PCHS=%u/%d/%d LCHS=%u/%u/%u\n", channel, slave, cylinders, heads, spt, lcylinders, lheads, lspt);
  • trunk/src/VBox/Devices/PC/DevPcBios.cpp

    r7072 r7099  
    3636#include "DevPcBios.h"
    3737
     38
     39/*
     40 * The BIOS uses a CMOS to store configuration data.
     41 * It is currently used as followed:
     42 *
     43 *     Base memory:
     44 *          0x15
     45 *          0x16
     46 *     Extended memory:
     47 *          0x17
     48 *          0x18
     49 *          0x30
     50 *          0x31
     51 *     Amount of memory above 16M:
     52 *          0x34
     53 *          0x35
     54 *     Boot device (BOCHS bios specific):
     55 *          0x3d
     56 *          0x38
     57 *          0x3c
     58 *     PXE debug:
     59 *          0x3f
     60 *     Floppy drive type:
     61 *          0x10
     62 *     Equipment byte:
     63 *          0x14
     64 *     First HDD:
     65 *          0x19
     66 *          0x1e - 0x25
     67 *     Second HDD:
     68 *          0x1a
     69 *          0x26 - 0x2d
     70 *     Third HDD:
     71 *          0x67 - 0x6e
     72 *     Fourth HDD:
     73 *          0x70 - 0x77
     74 *     Extended:
     75 *          0x12
     76 *     First Sata HDD:
     77 *          0x40 - 0x47
     78 *     Second Sata HDD:
     79 *          0x48 - 0x4f
     80 *     Third Sata HDD:
     81 *          0x50 - 0x57
     82 *     Fourth Sata HDD:
     83 *          0x58 - 0x5f
     84 */
    3885
    3986/*******************************************************************************
     
    71118    /** Harddisk device. */
    72119    char           *pszHDDevice;
     120    /** Sata harddisk device. */
     121    char           *pszSataDevice;
     122    /** LUN of the four harddisks which are emulated as IDE. */
     123    uint32_t        iSataHDLUN[4];
    73124    /** Bios message buffer. */
    74125    char            szMsg[256];
     
    362413}
    363414
     415/**
     416 * Set logical CHS geometry for a hard disk
     417 *
     418 * @returns VBox status code.
     419 * @param   pBase         Base interface for the device.
     420 * @param   pHardDisk     The hard disk.
     421 * @param   pLCHSGeometry Where to store the geometry settings.
     422 */
     423static int setLogicalDiskGeometry(PPDMIBASE pBase, PPDMIBLOCKBIOS pHardDisk, PPDMMEDIAGEOMETRY pLCHSGeometry)
     424{
     425    PDMMEDIAGEOMETRY LCHSGeometry;
     426    int rc = VINF_SUCCESS;
     427
     428    rc = pHardDisk->pfnGetLCHSGeometry(pHardDisk, &LCHSGeometry);
     429    if (   rc == VERR_PDM_GEOMETRY_NOT_SET
     430        || LCHSGeometry.cCylinders == 0
     431        || LCHSGeometry.cCylinders > 1024
     432        || LCHSGeometry.cHeads == 0
     433        || LCHSGeometry.cHeads > 255
     434        || LCHSGeometry.cSectors == 0
     435        || LCHSGeometry.cSectors > 63)
     436    {
     437        PPDMIBLOCK pBlock;
     438        pBlock = (PPDMIBLOCK)pBase->pfnQueryInterface(pBase, PDMINTERFACE_BLOCK);
     439        /* No LCHS geometry, autodetect and set. */
     440        rc = biosGuessDiskLCHS(pBlock, &LCHSGeometry);
     441        if (VBOX_FAILURE(rc))
     442        {
     443            /* Try if PCHS geometry works, otherwise fall back. */
     444            rc = pHardDisk->pfnGetPCHSGeometry(pHardDisk, &LCHSGeometry);
     445        }
     446        if (   VBOX_FAILURE(rc)
     447            || LCHSGeometry.cCylinders == 0
     448            || LCHSGeometry.cCylinders > 1024
     449            || LCHSGeometry.cHeads == 0
     450            || LCHSGeometry.cHeads > 16
     451            || LCHSGeometry.cSectors == 0
     452            || LCHSGeometry.cSectors > 63)
     453        {
     454            uint64_t cSectors = pBlock->pfnGetSize(pBlock) / 512;
     455            if (cSectors / 16 / 63 <= 1024)
     456            {
     457                LCHSGeometry.cCylinders = RT_MAX(cSectors / 16 / 63, 1);
     458                LCHSGeometry.cHeads = 16;
     459            }
     460            else if (cSectors / 32 / 63 <= 1024)
     461            {
     462                LCHSGeometry.cCylinders = RT_MAX(cSectors / 32 / 63, 1);
     463                LCHSGeometry.cHeads = 32;
     464            }
     465            else if (cSectors / 64 / 63 <= 1024)
     466            {
     467                LCHSGeometry.cCylinders = cSectors / 64 / 63;
     468                LCHSGeometry.cHeads = 64;
     469            }
     470            else if (cSectors / 128 / 63 <= 1024)
     471            {
     472                LCHSGeometry.cCylinders = cSectors / 128 / 63;
     473                LCHSGeometry.cHeads = 128;
     474            }
     475            else
     476            {
     477                LCHSGeometry.cCylinders = RT_MIN(cSectors / 255 / 63, 1024);
     478                LCHSGeometry.cHeads = 255;
     479            }
     480            LCHSGeometry.cSectors = 63;
     481
     482        }
     483        rc = pHardDisk->pfnSetLCHSGeometry(pHardDisk, &LCHSGeometry);
     484        if (rc == VERR_VDI_IMAGE_READ_ONLY)
     485        {
     486            LogRel(("DevPcBios: ATA failed to update LCHS geometry\n"));
     487            rc = VINF_SUCCESS;
     488        }
     489    }
     490
     491    *pLCHSGeometry = LCHSGeometry;
     492
     493    return rc;
     494}
    364495
    365496/**
     
    517648        {
    518649            PDMMEDIAGEOMETRY LCHSGeometry;
    519             int rc = apHDs[i]->pfnGetLCHSGeometry(apHDs[i], &LCHSGeometry);
    520             if (   rc == VERR_PDM_GEOMETRY_NOT_SET
    521                 || LCHSGeometry.cCylinders == 0
    522                 || LCHSGeometry.cCylinders > 1024
    523                 || LCHSGeometry.cHeads == 0
    524                 || LCHSGeometry.cHeads > 255
    525                 || LCHSGeometry.cSectors == 0
    526                 || LCHSGeometry.cSectors > 63)
    527             {
    528                 PPDMIBLOCK pBlock;
    529                 pBlock = (PPDMIBLOCK)pBase->pfnQueryInterface(pBase, PDMINTERFACE_BLOCK);
    530                 /* No LCHS geometry, autodetect and set. */
    531                 rc = biosGuessDiskLCHS(pBlock, &LCHSGeometry);
    532                 if (VBOX_FAILURE(rc))
    533                 {
    534                     /* Try if PCHS geometry works, otherwise fall back. */
    535                     rc = apHDs[i]->pfnGetPCHSGeometry(apHDs[i], &LCHSGeometry);
    536                 }
    537                 if (   VBOX_FAILURE(rc)
    538                     || LCHSGeometry.cCylinders == 0
    539                     || LCHSGeometry.cCylinders > 1024
    540                     || LCHSGeometry.cHeads == 0
    541                     || LCHSGeometry.cHeads > 16
    542                     || LCHSGeometry.cSectors == 0
    543                     || LCHSGeometry.cSectors > 63)
    544                 {
    545                     uint64_t cSectors = pBlock->pfnGetSize(pBlock) / 512;
    546                     if (cSectors / 16 / 63 <= 1024)
    547                     {
    548                         LCHSGeometry.cCylinders = RT_MAX(cSectors / 16 / 63, 1);
    549                         LCHSGeometry.cHeads = 16;
    550                     }
    551                     else if (cSectors / 32 / 63 <= 1024)
    552                     {
    553                         LCHSGeometry.cCylinders = RT_MAX(cSectors / 32 / 63, 1);
    554                         LCHSGeometry.cHeads = 32;
    555                     }
    556                     else if (cSectors / 64 / 63 <= 1024)
    557                     {
    558                         LCHSGeometry.cCylinders = cSectors / 64 / 63;
    559                         LCHSGeometry.cHeads = 64;
    560                     }
    561                     else if (cSectors / 128 / 63 <= 1024)
    562                     {
    563                         LCHSGeometry.cCylinders = cSectors / 128 / 63;
    564                         LCHSGeometry.cHeads = 128;
    565                     }
    566                     else
    567                     {
    568                         LCHSGeometry.cCylinders = RT_MIN(cSectors / 255 / 63, 1024);
    569                         LCHSGeometry.cHeads = 255;
    570                     }
    571                     LCHSGeometry.cSectors = 63;
    572 
    573                 }
    574                 rc = apHDs[i]->pfnSetLCHSGeometry(apHDs[i], &LCHSGeometry);
    575                 if (rc == VERR_VDI_IMAGE_READ_ONLY)
    576                 {
    577                     LogRel(("DevPcBios: ATA LUN#%d: failed to update LCHS geometry\n", i));
    578                     rc = VINF_SUCCESS;
    579                 }
    580                 AssertRC(rc);
    581             }
     650            int rc = setLogicalDiskGeometry(pBase, apHDs[i], &LCHSGeometry);
     651            AssertRC(rc);
     652
    582653            if (i < 4)
    583654            {
     
    615686    u32 = (apHDs[0] ? 0xf0 : 0) | (apHDs[1] ? 0x0f : 0);
    616687    pcbiosCmosWrite(pDevIns, 0x12, u32);
     688
     689    /*
     690     * Sata Harddisks.
     691     */
     692    if (pData->pszSataDevice)
     693    {
     694        for (i = 0; i < ELEMENTS(apHDs); i++)
     695        {
     696            PPDMIBASE pBase;
     697            int rc = PDMR3QueryLun(pVM, pData->pszSataDevice, 0, pData->iSataHDLUN[i], &pBase);
     698            if (VBOX_SUCCESS(rc))
     699                apHDs[i] = (PPDMIBLOCKBIOS)pBase->pfnQueryInterface(pBase, PDMINTERFACE_BLOCK_BIOS);
     700            if (   apHDs[i]
     701                && (   apHDs[i]->pfnGetType(apHDs[i]) != PDMBLOCKTYPE_HARD_DISK
     702                    || !apHDs[i]->pfnIsVisible(apHDs[i])))
     703                apHDs[i] = NULL;
     704            if (apHDs[i])
     705            {
     706                PDMMEDIAGEOMETRY LCHSGeometry;
     707                int rc = setLogicalDiskGeometry(pBase, apHDs[i], &LCHSGeometry);
     708                AssertRC(rc);
     709
     710                if (i < 4)
     711                {
     712                    /* Award BIOS extended drive types for first to fourth disk.
     713                     * Used by the BIOS for setting the logical geometry. */
     714                    int offInfo;
     715                    switch (i)
     716                    {
     717                        case 0:
     718                            offInfo = 0x40;
     719                            break;
     720                        case 1:
     721                            offInfo = 0x48;
     722                            break;
     723                        case 2:
     724                            offInfo = 0x50;
     725                            break;
     726                        case 3:
     727                        default:
     728                            offInfo = 0x58;
     729                            break;
     730                    }
     731                    pcbiosCmosInitHardDisk(pDevIns, 0x00, offInfo,
     732                                           &LCHSGeometry);
     733                }
     734                LogRel(("DevPcBios: SATA LUN#%d LCHS=%u/%u/%u\n", i, LCHSGeometry.cCylinders, LCHSGeometry.cHeads, LCHSGeometry.cSectors));
     735            }
     736        }
     737    }
    617738
    618739    LogFlow(("%s: returns VINF_SUCCESS\n", __FUNCTION__));
     
    12911412                              "RamSize\0"
    12921413                              "HardDiskDevice\0"
     1414                              "SataHardDiskDevice\0"
     1415                              "SataPrimaryMasterLUN\0"
     1416                              "SataPrimarySlaveLUN\0"
     1417                              "SataSecondaryMasterLUN\0"
     1418                              "SataSecondarySlaveLUN\0"
    12931419                              "FloppyDevice\0"
    12941420                              "FadeIn\0"
     
    13461472                                N_("Configuration error: Querying \"FloppyDevice\" as a string failed"));
    13471473
     1474    rc = CFGMR3QueryStringAlloc(pCfgHandle, "SataHardDiskDevice", &pData->pszSataDevice);
     1475    if (rc == VERR_CFGM_VALUE_NOT_FOUND)
     1476        pData->pszSataDevice = NULL;
     1477    else if (VBOX_FAILURE(rc))
     1478        return PDMDEV_SET_ERROR(pDevIns, rc,
     1479                                N_("Configuration error: Querying \"SataHardDiskDevice\" as a string failed"));
     1480
     1481    if (pData->pszSataDevice)
     1482    {
     1483        static const char * const s_apszSataDisks[] =
     1484            { "SataPrimaryMasterLUN", "SataPrimarySlaveLUN", "SataSecondaryMasterLUN", "SataSecondarySlaveLUN" };
     1485        Assert(ELEMENTS(s_apszSataDisks) == ELEMENTS(pData->iSataHDLUN));
     1486        for (i = 0; i < ELEMENTS(pData->iSataHDLUN); i++)
     1487        {
     1488            rc = CFGMR3QueryU32(pCfgHandle, s_apszSataDisks[i], &pData->iSataHDLUN[i]);
     1489            if (rc == VERR_CFGM_VALUE_NOT_FOUND)
     1490                pData->iSataHDLUN[i] = i;
     1491            else if (VBOX_FAILURE(rc))
     1492                return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
     1493                                           N_("Configuration error: Querying \"%s\" as a string failed"), s_apszSataDisks);
     1494        }
     1495    }
    13481496    /*
    13491497     * Register I/O Ports and PC BIOS.
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette