VirtualBox

Changeset 40277 in vbox


Ignore:
Timestamp:
Feb 28, 2012 2:10:07 PM (13 years ago)
Author:
vboxsync
Message:

DevPcBios: always copy the BIOS to RAM and patch the DMI table field length after planting the DMI table

Location:
trunk/src/VBox/Devices
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/DevEFI.cpp

    r39707 r40277  
    11991199    /*
    12001200     * Plant DMI and MPS tables
    1201      */
    1202     rc = FwCommonPlantDMITable(pDevIns, pThis->au8DMIPage,
    1203                                VBOX_DMI_TABLE_SIZE, &pThis->aUuid, pDevIns->pCfg, pThis->cCpus);
     1201     * XXX I wonder if we really need these tables as there is no SMBIOS header...
     1202     */
     1203    uint16_t cbDmiTablesDummy;
     1204    rc = FwCommonPlantDMITable(pDevIns, pThis->au8DMIPage, VBOX_DMI_TABLE_SIZE, &pThis->aUuid,
     1205                               pDevIns->pCfg, pThis->cCpus, &cbDmiTablesDummy);
    12041206    AssertRCReturn(rc, rc);
    12051207    if (pThis->u8IOAPIC)
  • trunk/src/VBox/Devices/PC/DevFwCommon.cpp

    r40019 r40277  
    417417 * @param   pCfg                The handle to our config node.
    418418 */
    419 int FwCommonPlantDMITable(PPDMDEVINS pDevIns, uint8_t *pTable, unsigned cbMax, PCRTUUID pUuid, PCFGMNODE pCfg, uint16_t cCpus)
     419int FwCommonPlantDMITable(PPDMDEVINS pDevIns, uint8_t *pTable, unsigned cbMax, PCRTUUID pUuid, PCFGMNODE pCfg, uint16_t cCpus, uint16_t *pcbDmiTables)
    420420{
    421421#define CHECKSIZE(cbWant) \
     
    875875        /* End-of-table marker - includes padding to account for fixed table size. */
    876876        PDMIHDR pEndOfTable          = (PDMIHDR)pszStr;
     877        pszStr                       = (char *)(pEndOfTable + 1);
    877878        pEndOfTable->u8Type          = 0x7f;
    878         uint32_t cbEof = cbMax - ((uintptr_t)pszStr - (uintptr_t)pTable) - 2;
    879         if (cbEof > 255)
    880             return PDMDevHlpVMSetError(pDevIns, VERR_TOO_MUCH_DATA, RT_SRC_POS, \
    881                                        N_("DMI table has the wrong length (%u bytes left for the EOF marker). One of the DMI strings is too long. Check all bios/Dmi* configuration entries"), cbEof); \
    882         pEndOfTable->u8Length        = cbEof;
     879
     880        pEndOfTable->u8Length        = sizeof(*pEndOfTable);
    883881        pEndOfTable->u16Handle       = 0xFEFF;
     882        *pcbDmiTables = ((uintptr_t)pszStr - (uintptr_t)pTable) + 2;
    884883
    885884        /* If more fields are added here, fix the size check in READCFGSTR */
  • trunk/src/VBox/Devices/PC/DevFwCommon.h

    r39707 r40277  
    2828
    2929/* Plant DMI table */
    30 int FwCommonPlantDMITable(PPDMDEVINS pDevIns, uint8_t *pTable, unsigned cbMax, PCRTUUID pUuid, PCFGMNODE pCfg, uint16_t cCpus);
     30int FwCommonPlantDMITable(PPDMDEVINS pDevIns, uint8_t *pTable, unsigned cbMax, PCRTUUID pUuid, PCFGMNODE pCfg, uint16_t cCpus, uint16_t *pcbDmiTables);
    3131void FwCommonPlantSmbiosAndDmiHdrs(PPDMDEVINS pDevIns);
    3232
  • trunk/src/VBox/Devices/PC/DevPcBios.cpp

    r40019 r40277  
    924924static DECLCALLBACK(int)  pcbiosConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
    925925{
    926     unsigned    i;
    927926    PDEVPCBIOS  pThis = PDMINS_2_DATA(pDevIns, PDEVPCBIOS);
    928927    int         rc;
     
    10311030    static const char * const s_apszBootDevices[] = { "BootDevice0", "BootDevice1", "BootDevice2", "BootDevice3" };
    10321031    Assert(RT_ELEMENTS(s_apszBootDevices) == RT_ELEMENTS(pThis->aenmBootDevice));
    1033     for (i = 0; i < RT_ELEMENTS(pThis->aenmBootDevice); i++)
     1032    for (unsigned i = 0; i < RT_ELEMENTS(pThis->aenmBootDevice); i++)
    10341033    {
    10351034        rc = pcbiosBootFromCfg(pDevIns, pCfg, s_apszBootDevices[i], &pThis->aenmBootDevice[i]);
     
    10601059            { "SataPrimaryMasterLUN", "SataPrimarySlaveLUN", "SataSecondaryMasterLUN", "SataSecondarySlaveLUN" };
    10611060        Assert(RT_ELEMENTS(s_apszSataDisks) == RT_ELEMENTS(pThis->iSataHDLUN));
    1062         for (i = 0; i < RT_ELEMENTS(pThis->iSataHDLUN); i++)
     1061        for (unsigned i = 0; i < RT_ELEMENTS(pThis->iSataHDLUN); i++)
    10631062        {
    10641063            rc = CFGMR3QueryU32(pCfg, s_apszSataDisks[i], &pThis->iSataHDLUN[i]);
     
    10831082
    10841083    /*
    1085      * Query the machine's UUID for SMBIOS/DMI use.
    1086      */
    1087     RTUUID  uuid;
    1088     rc = CFGMR3QueryBytes(pCfg, "UUID", &uuid, sizeof(uuid));
    1089     if (RT_FAILURE(rc))
    1090         return PDMDEV_SET_ERROR(pDevIns, rc,
    1091                                 N_("Configuration error: Querying \"UUID\" failed"));
    1092 
    1093 
    1094     /* Convert the UUID to network byte order. Not entirely straightforward as parts are MSB already... */
    1095     uuid.Gen.u32TimeLow = RT_H2BE_U32(uuid.Gen.u32TimeLow);
    1096     uuid.Gen.u16TimeMid = RT_H2BE_U16(uuid.Gen.u16TimeMid);
    1097     uuid.Gen.u16TimeHiAndVersion = RT_H2BE_U16(uuid.Gen.u16TimeHiAndVersion);
    1098     rc = FwCommonPlantDMITable(pDevIns, pThis->au8DMIPage,
    1099                                VBOX_DMI_TABLE_SIZE, &uuid, pCfg, pThis->cCpus);
    1100     if (RT_FAILURE(rc))
    1101         return rc;
    1102     if (pThis->u8IOAPIC)
    1103         FwCommonPlantMpsTable(pDevIns, pThis->au8DMIPage + VBOX_DMI_TABLE_SIZE,
    1104                               _4K - VBOX_DMI_TABLE_SIZE, pThis->cCpus);
    1105 
    1106     rc = PDMDevHlpROMRegister(pDevIns, VBOX_DMI_TABLE_BASE, _4K, pThis->au8DMIPage, _4K,
    1107                               PGMPHYS_ROM_FLAGS_PERMANENT_BINARY, "DMI tables");
    1108     if (RT_FAILURE(rc))
    1109         return rc;
    1110 
    1111     /*
    11121084     * Read the PXE debug logging option.
    11131085     */
     
    11411113
    11421114        Assert(pCfgNetBoot);
    1143         for (i = 0; i < NET_BOOT_DEVS; ++i)
     1115        for (unsigned i = 0; i < NET_BOOT_DEVS; ++i)
    11441116        {
    11451117            szIndex[0] = '0' + i;
     
    12411213            }
    12421214            else
    1243                 rc = PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, N_("Failed to query the system BIOS file size ('%s')"),
     1215                rc = PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
     1216                                         N_("Failed to query the system BIOS file size ('%s')"),
    12441217                                         pThis->pszPcBiosFile);
    12451218            RTFileClose(hFilePcBios);
    12461219        }
    12471220        else
    1248             rc = PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, N_("Failed to open system BIOS file '%s'"), pThis->pszPcBiosFile);
     1221            rc = PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
     1222                                     N_("Failed to open system BIOS file '%s'"), pThis->pszPcBiosFile);
    12491223        if (RT_FAILURE(rc))
    12501224            return rc;
    12511225
    1252         pu8PcBiosBinary = pThis->pu8PcBios;
    1253         cbPcBiosBinary  = pThis->cbPcBios;
    12541226        LogRel(("Using BIOS ROM '%s' with a size of %#x bytes\n", pThis->pszPcBiosFile, pThis->cbPcBios));
    12551227    }
     
    12591231         * Use the embedded BIOS ROM image.
    12601232         */
    1261         pu8PcBiosBinary = g_abPcBiosBinary;
    1262         cbPcBiosBinary  = g_cbPcBiosBinary;
    1263     }
     1233        pThis->pu8PcBios = (uint8_t *)PDMDevHlpMMHeapAlloc(pDevIns, g_cbPcBiosBinary);
     1234        if (pThis->pu8PcBios)
     1235        {
     1236            pThis->cbPcBios = g_cbPcBiosBinary;
     1237            memcpy(pThis->pu8PcBios, g_abPcBiosBinary, pThis->cbPcBios);
     1238        }
     1239        else
     1240            return PDMDevHlpVMSetError(pDevIns, VERR_NO_MEMORY, RT_SRC_POS,
     1241                                       N_("Failed to allocate %#x bytes for loading the embedded BIOS image"),
     1242                                       g_cbPcBiosBinary);
     1243    }
     1244    pu8PcBiosBinary = pThis->pu8PcBios;
     1245    cbPcBiosBinary  = pThis->cbPcBios;
     1246
     1247    /*
     1248     * Query the machine's UUID for SMBIOS/DMI use.
     1249     */
     1250    RTUUID  uuid;
     1251    rc = CFGMR3QueryBytes(pCfg, "UUID", &uuid, sizeof(uuid));
     1252    if (RT_FAILURE(rc))
     1253        return PDMDEV_SET_ERROR(pDevIns, rc,
     1254                                N_("Configuration error: Querying \"UUID\" failed"));
     1255
     1256    /* Convert the UUID to network byte order. Not entirely straightforward as parts are MSB already... */
     1257    uuid.Gen.u32TimeLow = RT_H2BE_U32(uuid.Gen.u32TimeLow);
     1258    uuid.Gen.u16TimeMid = RT_H2BE_U16(uuid.Gen.u16TimeMid);
     1259    uuid.Gen.u16TimeHiAndVersion = RT_H2BE_U16(uuid.Gen.u16TimeHiAndVersion);
     1260    uint16_t cbDmiTables = 0;
     1261    rc = FwCommonPlantDMITable(pDevIns, pThis->au8DMIPage, VBOX_DMI_TABLE_SIZE,
     1262                               &uuid, pCfg, pThis->cCpus, &cbDmiTables);
     1263    if (RT_FAILURE(rc))
     1264        return rc;
     1265
     1266    /* If the DMI table is located at the expected place, patch the DMI table length and the checksum. */
     1267    if (   pThis->pu8PcBios[VBOX_DMI_TABLE_OFFSET + 0x00] == '_'
     1268        && pThis->pu8PcBios[VBOX_DMI_TABLE_OFFSET + 0x01] == 'D'
     1269        && pThis->pu8PcBios[VBOX_DMI_TABLE_OFFSET + 0x02] == 'M'
     1270        && pThis->pu8PcBios[VBOX_DMI_TABLE_OFFSET + 0x03] == 'I'
     1271        && pThis->pu8PcBios[VBOX_DMI_TABLE_OFFSET + 0x04] == '_')
     1272    {
     1273        *(uint16_t*)&pThis->pu8PcBios[VBOX_DMI_TABLE_OFFSET + 0x06] = cbDmiTables;
     1274        uint8_t u8Sum = 0;
     1275        for (unsigned i = 0; i < pThis->cbPcBios; i++)
     1276            if (i != VBOX_DMI_TABLE_OFFSET + 0x05)
     1277                u8Sum += pThis->pu8PcBios[i];
     1278        pThis->pu8PcBios[VBOX_DMI_TABLE_OFFSET + 0x05] = -u8Sum;
     1279    }
     1280
     1281    if (pThis->u8IOAPIC)
     1282        FwCommonPlantMpsTable(pDevIns, pThis->au8DMIPage + VBOX_DMI_TABLE_SIZE,
     1283                              _4K - VBOX_DMI_TABLE_SIZE, pThis->cCpus);
     1284
     1285    rc = PDMDevHlpROMRegister(pDevIns, VBOX_DMI_TABLE_BASE, _4K, pThis->au8DMIPage, _4K,
     1286                              PGMPHYS_ROM_FLAGS_PERMANENT_BINARY, "DMI tables");
     1287    if (RT_FAILURE(rc))
     1288        return rc;
    12641289
    12651290    /*
  • trunk/src/VBox/Devices/PC/DevPcBios.h

    r40019 r40277  
    2828 */
    2929#define VBOX_DMI_TABLE_ENTR         9
     30#define VBOX_DMI_TABLE_OFFSET       0xff40
    3031
    3132/** def VBOX_DMI_TABLE_SIZE
    3233 *
    33  * Must not be bigger than the minimal size of the DMI tables + 255 because
    34  * the length field of the the DMI end-of-table marker is 8 bits only. And
    35  * the size should be at least 16-byte aligned for a proper alignment of
     34 * The size should be at least 16-byte aligned for a proper alignment of
    3635 * the MPS table.
    3736 */
    38 #define VBOX_DMI_TABLE_SIZE         512
     37#define VBOX_DMI_TABLE_SIZE         768
    3938
    4039
Note: See TracChangeset for help on using the changeset viewer.

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