VirtualBox

儲存庫 vbox 的更動 50091


忽略:
時間撮記:
2014-1-17 下午12:06:45 (11 年 以前)
作者:
vboxsync
訊息:

BIOS: If available, store logical geometry of SCSI disk in CMOS and use it.

位置:
trunk/src/VBox/Devices/PC
檔案:
修改 2 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Devices/PC/BIOS/scsi.c

    r48123 r50091  
    411411                uint16_t    heads, sectors_per_track;
    412412                uint8_t     hdcount;
     413                uint8_t     cmos_base;
    413414
    414415                /* Issue a read capacity command now. */
     
    440441                }
    441442
    442                 /* We need to calculate the geometry for the disk. From
    443                  * the BusLogic driver in the Linux kernel.
    444                 */
    445                 if (sectors >= (uint32_t)4 * 1024 * 1024)
     443                devcount_scsi = bios_dsk->scsi_devcount;
     444
     445                /* Get logical CHS geometry. */
     446                switch (devcount_scsi)
    446447                {
    447                     heads = 255;
    448                     sectors_per_track = 63;
     448                    case 0:
     449                        cmos_base = 0x90;
     450                        break;
     451                    case 1:
     452                        cmos_base = 0x98;
     453                        break;
     454                    case 2:
     455                        cmos_base = 0xA0;
     456                        break;
     457                    case 3:
     458                        cmos_base = 0xA8;
     459                        break;
     460                    default:
     461                        cmos_base = 0;
    449462                }
    450                 else if (sectors >= (uint32_t)2 * 1024 * 1024)
     463
     464                if (cmos_base && inb_cmos(cmos_base + 7))
    451465                {
    452                     heads = 128;
    453                     sectors_per_track = 32;
     466                    /* If provided, grab the logical geometry from CMOS. */
     467                    cylinders         = inb_cmos(cmos_base + 0) + (inb_cmos(cmos_base + 1) << 8);
     468                    heads             = inb_cmos(cmos_base + 2);
     469                    sectors_per_track = inb_cmos(cmos_base + 7);
    454470                }
    455471                else
    456472                {
    457                     heads = 64;
    458                     sectors_per_track = 32;
     473                    /* Calculate default logical geometry. NB: Very different
     474                     * from default ATA/SATA logical geometry!
     475                     */
     476                    if (sectors >= (uint32_t)4 * 1024 * 1024)
     477                    {
     478                        heads = 255;
     479                        sectors_per_track = 63;
     480                    }
     481                    else if (sectors >= (uint32_t)2 * 1024 * 1024)
     482                    {
     483                        heads = 128;
     484                        sectors_per_track = 32;
     485                    }
     486                    else
     487                    {
     488                        heads = 64;
     489                        sectors_per_track = 32;
     490                    }
     491                    cylinders = (uint32_t)(sectors / (heads * sectors_per_track));
    459492                }
    460                 cylinders = (uint32_t)(sectors / (heads * sectors_per_track));
    461                 devcount_scsi = bios_dsk->scsi_devcount;
    462493
    463494                /* Calculate index into the generic disk table. */
  • trunk/src/VBox/Devices/PC/DevPcBios.cpp

    r48947 r50091  
    107107    Second to third net boot devices:
    108108         0x84 - 0x89
     109    First SCSI HDD:
     110         0x90 - 0x97
     111    Second SCSI HDD:
     112         0x98 - 0x9f
     113    Third SCSI HDD:
     114         0xa0 - 0xa7
     115    Fourth SCSI HDD:
     116         0xa8 - 0xaf
     117
    109118@endverbatim
    110119 *
     
    152161    /** Sata harddisk device. */
    153162    char           *pszSataDevice;
    154     /** LUN of the four harddisks which are emulated as IDE. */
     163    /** LUNs of the four BIOS-accessible SATA disks. */
    155164    uint32_t        iSataHDLUN[4];
     165    /** SCSI harddisk device. */
     166    char           *pszScsiDevice;
     167    /** LUNs of the four BIOS-accessible SCSI disks. */
     168    uint32_t        iScsiHDLUN[4];
    156169    /** Bios message buffer. */
    157170    char            szMsg[256];
     
    462475
    463476/**
     477 * Get logical CHS geometry for a hard disk, intended for SCSI/SAS drives
     478 * with no physical geometry.
     479 *
     480 * @returns VBox status code.
     481 * @param   pHardDisk     The hard disk.
     482 * @param   pLCHSGeometry Where to store the geometry settings.
     483 */
     484static int getLogicalDiskGeometry(PPDMIBLOCKBIOS pHardDisk, PPDMMEDIAGEOMETRY pLCHSGeometry)
     485{
     486    PDMMEDIAGEOMETRY LCHSGeometry;
     487    int rc = VINF_SUCCESS;
     488
     489    rc = pHardDisk->pfnGetLCHSGeometry(pHardDisk, &LCHSGeometry);
     490    if (   rc == VERR_PDM_GEOMETRY_NOT_SET
     491        || LCHSGeometry.cCylinders == 0
     492        || LCHSGeometry.cHeads == 0
     493        || LCHSGeometry.cHeads > 255
     494        || LCHSGeometry.cSectors == 0
     495        || LCHSGeometry.cSectors > 63)
     496    {
     497        /* Unlike the ATA case, if the image does not provide valid logical
     498         * geometry, we leave things alone and let the BIOS decide what the
     499         * logical geometry should be.
     500         */
     501        rc = VERR_PDM_GEOMETRY_NOT_SET;
     502    }
     503    else
     504        *pLCHSGeometry = LCHSGeometry;
     505
     506    return rc;
     507}
     508
     509
     510/**
    464511 * Get BIOS boot code from enmBootDevice in order
    465512 *
     
    628675
    629676    /*
    630      * Harddisks.
     677     * IDE harddisks.
    631678     */
    632679    for (i = 0; i < RT_ELEMENTS(apHDs); i++)
     
    683730
    684731    /*
    685      * Sata Harddisks.
     732     * SATA harddisks.
    686733     */
    687734    if (pThis->pszSataDevice)
    688735    {
    689         /* Clear pointers to IDE controller. */
     736        /* Clear pointers to the block devices. */
    690737        for (i = 0; i < RT_ELEMENTS(apHDs); i++)
    691738            apHDs[i] = NULL;
     
    736783    }
    737784
     785    /*
     786     * SCSI harddisks. Not handled quite the same as SATA.
     787     */
     788    if (pThis->pszScsiDevice)
     789    {
     790        /* Clear pointers to the block devices. */
     791        for (i = 0; i < RT_ELEMENTS(apHDs); i++)
     792            apHDs[i] = NULL;
     793
     794        for (i = 0; i < RT_ELEMENTS(apHDs); i++)
     795        {
     796            PPDMIBASE pBase;
     797            int rc = PDMR3QueryLun(pUVM, pThis->pszScsiDevice, 0, pThis->iScsiHDLUN[i], &pBase);
     798            if (RT_SUCCESS(rc))
     799                apHDs[i] = PDMIBASE_QUERY_INTERFACE(pBase, PDMIBLOCKBIOS);
     800            if (   apHDs[i]
     801                && (   apHDs[i]->pfnGetType(apHDs[i]) != PDMBLOCKTYPE_HARD_DISK
     802                    || !apHDs[i]->pfnIsVisible(apHDs[i])))
     803                apHDs[i] = NULL;
     804            if (apHDs[i])
     805            {
     806                PDMMEDIAGEOMETRY LCHSGeometry;
     807                rc = getLogicalDiskGeometry(apHDs[i], &LCHSGeometry);
     808
     809                if (i < 4 && RT_SUCCESS(rc))
     810                {
     811                    /* Extended drive information (for SCSI disks).
     812                     * Used by the BIOS for setting the logical geometry, but
     813                     * only if the image provided valid data.
     814                     */
     815                    int offInfo;
     816                    switch (i)
     817                    {
     818                        case 0:
     819                            offInfo = 0x90;
     820                            break;
     821                        case 1:
     822                            offInfo = 0x98;
     823                            break;
     824                        case 2:
     825                            offInfo = 0xa0;
     826                            break;
     827                        case 3:
     828                        default:
     829                            offInfo = 0xa8;
     830                            break;
     831                    }
     832                    pcbiosCmosInitHardDisk(pDevIns, 0x00, offInfo, &LCHSGeometry);
     833                    LogRel(("DevPcBios: SCSI LUN#%d LCHS=%u/%u/%u\n", i, LCHSGeometry.cCylinders, LCHSGeometry.cHeads, LCHSGeometry.cSectors));
     834                }
     835                else
     836                    LogRel(("DevPcBios: SCSI LUN#%d LCHS not provided\n", i));
     837            }
     838        }
     839    }
     840
    738841    /* Calculate and store AT-style CMOS checksum. */
    739842    uint16_t    cksum = 0;
     
    847950        MMR3HeapFree(pThis->pszSataDevice);
    848951        pThis->pszSataDevice = NULL;
     952    }
     953
     954    if (pThis->pszScsiDevice)
     955    {
     956        MMR3HeapFree(pThis->pszScsiDevice);
     957        pThis->pszScsiDevice = NULL;
    849958    }
    850959
     
    9181027                              "SataLUN3\0"
    9191028                              "SataLUN4\0"
     1029                              "ScsiHardDiskDevice\0"
     1030                              "ScsiLUN1\0"
     1031                              "ScsiLUN2\0"
     1032                              "ScsiLUN3\0"
     1033                              "ScsiLUN4\0"
    9201034                              "FloppyDevice\0"
    9211035                              "DelayBoot\0"
     
    10411155        }
    10421156    }
     1157
     1158    /* Repeat the exercise for SCSI drives. */
     1159    rc = CFGMR3QueryStringAlloc(pCfg, "ScsiHardDiskDevice", &pThis->pszScsiDevice);
     1160    if (rc == VERR_CFGM_VALUE_NOT_FOUND)
     1161        pThis->pszScsiDevice = NULL;
     1162    else if (RT_FAILURE(rc))
     1163        return PDMDEV_SET_ERROR(pDevIns, rc,
     1164                                N_("Configuration error: Querying \"ScsiHardDiskDevice\" as a string failed"));
     1165
     1166    if (pThis->pszScsiDevice)
     1167    {
     1168        static const char * const s_apszScsiDisks[] =
     1169            { "ScsiLUN1", "ScsiLUN2", "ScsiLUN3", "ScsiLUN4" };
     1170        Assert(RT_ELEMENTS(s_apszScsiDisks) == RT_ELEMENTS(pThis->iScsiHDLUN));
     1171        for (unsigned i = 0; i < RT_ELEMENTS(pThis->iScsiHDLUN); i++)
     1172        {
     1173            rc = CFGMR3QueryU32(pCfg, s_apszScsiDisks[i], &pThis->iScsiHDLUN[i]);
     1174            if (rc == VERR_CFGM_VALUE_NOT_FOUND)
     1175                pThis->iScsiHDLUN[i] = i;
     1176            else if (RT_FAILURE(rc))
     1177                return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
     1178                                           N_("Configuration error: Querying \"%s\" as a string failed"), s_apszScsiDisks);
     1179        }
     1180    }
     1181
     1182
    10431183    /*
    10441184     * Register I/O Ports and PC BIOS.
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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