VirtualBox

Changeset 24706 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 16, 2009 5:57:20 PM (15 years ago)
Author:
vboxsync
Message:

EFI: ACPI work

Location:
trunk/src/VBox
Files:
2 added
5 edited

Legend:

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

    r23400 r24706  
    4848#include "../Builtins.h"
    4949#include "../Builtins2.h"
     50#include "../PC/DevFwCommon.h"
    5051
    5152/* EFI includes */
     
    100101
    101102    uint64_t cbRamHole;
     103
     104    /** The DMI tables. */
     105    uint8_t         au8DMIPage[0x1000];
     106
     107    /** I/O-APIC enabled? */
     108    uint8_t         u8IOAPIC;
    102109} DEVEFI;
    103110typedef DEVEFI *PDEVEFI;
     
    839846                              "RamSize\0"
    840847                              "RamHoleSize\0"
    841                               "NumCPUs\0"))
     848                              "NumCPUs\0"
     849                              "UUID\0"
     850                              "IOAPIC\0"
     851                              "DmiBIOSVendor\0"
     852                              "DmiBIOSVersion\0"
     853                              "DmiBIOSReleaseDate\0"
     854                              "DmiBIOSReleaseMajor\0"
     855                              "DmiBIOSReleaseMinor\0"
     856                              "DmiBIOSFirmwareMajor\0"
     857                              "DmiBIOSFirmwareMinor\0"
     858                              "DmiSystemFamily\0"
     859                              "DmiSystemProduct\0"
     860                              "DmiSystemSerial\0"
     861                              "DmiSystemUuid\0"
     862                              "DmiSystemVendor\0"
     863                              "DmiSystemVersion\0"
     864                              "DmiChassisVendor\0"
     865                              "DmiChassisVersion\0"
     866                              "DmiChassisSerial\0"
     867                              "DmiChassisAssetTag\0"
     868#ifdef VBOX_WITH_DMI_OEMSTRINGS
     869                              "DmiOEMVBoxVer\0"
     870                              "DmiOEMVBoxRev\0"
     871#endif
     872                              ))
    842873        return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
    843874                                N_("Configuration error: Invalid config value(s) for the EFI device"));
     875
     876    rc = CFGMR3QueryU8Def(pCfgHandle, "IOAPIC", &pThis->u8IOAPIC, 1);
     877    if (RT_FAILURE (rc))
     878        return PDMDEV_SET_ERROR(pDevIns, rc,
     879                                N_("Configuration error: Failed to read \"IOAPIC\""));
     880
     881    /*
     882     * Query the machine's UUID for SMBIOS/DMI use.
     883     */
     884    RTUUID  uuid;
     885    rc = CFGMR3QueryBytes(pCfgHandle, "UUID", &uuid, sizeof(uuid));
     886    if (RT_FAILURE(rc))
     887        return PDMDEV_SET_ERROR(pDevIns, rc,
     888                                N_("Configuration error: Querying \"UUID\" failed"));
     889
     890    /* Convert the UUID to network byte order. Not entirely straightforward as parts are MSB already... */
     891    uuid.Gen.u32TimeLow = RT_H2BE_U32(uuid.Gen.u32TimeLow);
     892    uuid.Gen.u16TimeMid = RT_H2BE_U16(uuid.Gen.u16TimeMid);
     893    uuid.Gen.u16TimeHiAndVersion = RT_H2BE_U16(uuid.Gen.u16TimeHiAndVersion);
     894    rc = sharedfwPlantDMITable(pDevIns, pThis->au8DMIPage, VBOX_DMI_TABLE_SIZE, &uuid, pCfgHandle);
     895    if (RT_FAILURE(rc))
     896        return rc;
     897    if (pThis->u8IOAPIC)
     898        sharedfwPlantMpsTable(pDevIns, pThis->au8DMIPage + VBOX_DMI_TABLE_SIZE, pThis->cCpus);
     899
     900    rc = PDMDevHlpROMRegister(pDevIns, VBOX_DMI_TABLE_BASE, _4K, pThis->au8DMIPage,
     901                              PGMPHYS_ROM_FLAGS_PERMANENT_BINARY, "DMI tables");
     902    if (RT_FAILURE(rc))
     903        return rc;
    844904
    845905    /* RAM sizes */
  • trunk/src/VBox/Devices/Makefile.kmk

    r23659 r24706  
    291291        PC/DevRTC.cpp \
    292292        PC/DevPcBios.cpp \
     293        PC/DevFwCommon.cpp \
    293294        PC/DevPcArch.c \
    294295        VMMDev/VMMDev.cpp \
  • trunk/src/VBox/Devices/PC/DevPcBios.cpp

    r24194 r24706  
    4141#include "../Builtins2.h"
    4242#include "DevPcBios.h"
     43#include "DevFwCommon.h"
    4344
    4445
     
    169170} DEVPCBIOS, *PDEVPCBIOS;
    170171
    171 #pragma pack(1)
    172 
    173 /** DMI header */
    174 typedef struct DMIHDR
    175 {
    176     uint8_t         u8Type;
    177     uint8_t         u8Length;
    178     uint16_t        u16Handle;
    179 } *PDMIHDR;
    180 AssertCompileSize(DMIHDR, 4);
    181 
    182 /** DMI BIOS information (Type 0) */
    183 typedef struct DMIBIOSINF
    184 {
    185     DMIHDR          header;
    186     uint8_t         u8Vendor;
    187     uint8_t         u8Version;
    188     uint16_t        u16Start;
    189     uint8_t         u8Release;
    190     uint8_t         u8ROMSize;
    191     uint64_t        u64Characteristics;
    192     uint8_t         u8CharacteristicsByte1;
    193     uint8_t         u8CharacteristicsByte2;
    194     uint8_t         u8ReleaseMajor;
    195     uint8_t         u8ReleaseMinor;
    196     uint8_t         u8FirmwareMajor;
    197     uint8_t         u8FirmwareMinor;
    198 } *PDMIBIOSINF;
    199 AssertCompileSize(DMIBIOSINF, 0x18);
    200 
    201 /** DMI system information (Type 1) */
    202 typedef struct DMISYSTEMINF
    203 {
    204     DMIHDR          header;
    205     uint8_t         u8Manufacturer;
    206     uint8_t         u8ProductName;
    207     uint8_t         u8Version;
    208     uint8_t         u8SerialNumber;
    209     uint8_t         au8Uuid[16];
    210     uint8_t         u8WakeupType;
    211     uint8_t         u8SKUNumber;
    212     uint8_t         u8Family;
    213 } *PDMISYSTEMINF;
    214 AssertCompileSize(DMISYSTEMINF, 0x1b);
    215 
    216 /** DMI system enclosure or chassis type (Type 3) */
    217 typedef struct DMICHASSIS
    218 {
    219     DMIHDR          header;
    220     uint8_t         u8Manufacturer;
    221     uint8_t         u8Type;
    222     uint8_t         u8Version;
    223     uint8_t         u8SerialNumber;
    224     uint8_t         u8AssetTag;
    225     uint8_t         u8BootupState;
    226     uint8_t         u8PowerSupplyState;
    227     uint8_t         u8ThermalState;
    228     uint8_t         u8SecurityStatus;
    229     /* v2.3+, currently not supported */
    230     uint32_t        u32OEMdefined;
    231     uint8_t         u8Height;
    232     uint8_t         u8NumPowerChords;
    233     uint8_t         u8ContElems;
    234     uint8_t         u8ContElemRecLen;
    235 } *PDMICHASSIS;
    236 AssertCompileSize(DMICHASSIS, 0x15);
    237 
    238 /** DMI processor information (Type 4) */
    239 typedef struct DMIPROCESSORINF
    240 {
    241     DMIHDR          header;
    242     uint8_t         u8SocketDesignation;
    243     uint8_t         u8ProcessorType;
    244     uint8_t         u8ProcessorFamily;
    245     uint8_t         u8ProcessorManufacturer;
    246     uint64_t        u64ProcessorIdentification;
    247     uint8_t         u8ProcessorVersion;
    248     uint8_t         u8Voltage;
    249     uint16_t        u16ExternalClock;
    250     uint16_t        u16MaxSpeed;
    251     uint16_t        u16CurrentSpeed;
    252     uint8_t         u8Status;
    253     uint8_t         u8ProcessorUpgrade;
    254     uint16_t        u16L1CacheHandle;
    255     uint16_t        u16L2CacheHandle;
    256     uint16_t        u16L3CacheHandle;
    257     uint8_t         u8SerialNumber;
    258     uint8_t         u8AssetTag;
    259     uint8_t         u8PartNumber;
    260     uint8_t         u8CoreCount;
    261     uint8_t         u8CoreEnabled;
    262     uint8_t         u8ThreadCount;
    263     uint16_t        u16ProcessorCharacteristics;
    264     uint16_t        u16ProcessorFamily2;
    265 } *PDMIPROCESSORINF;
    266 AssertCompileSize(DMIPROCESSORINF, 0x2a);
    267 
    268 /** DMI OEM strings (Type 11) */
    269 typedef struct DMIOEMSTRINGS
    270 {
    271     DMIHDR          header;
    272     uint8_t         u8Count;
    273     uint8_t         u8VBoxVersion;
    274     uint8_t         u8VBoxRevision;
    275 } *PDMIOEMSTRINGS;
    276 AssertCompileSize(DMIOEMSTRINGS, 0x7);
    277 
    278 /** MPS floating pointer structure */
    279 typedef struct MPSFLOATPTR
    280 {
    281     uint8_t         au8Signature[4];
    282     uint32_t        u32MPSAddr;
    283     uint8_t         u8Length;
    284     uint8_t         u8SpecRev;
    285     uint8_t         u8Checksum;
    286     uint8_t         au8Feature[5];
    287 } *PMPSFLOATPTR;
    288 AssertCompileSize(MPSFLOATPTR, 16);
    289 
    290 /** MPS config table header */
    291 typedef struct MPSCFGTBLHEADER
    292 {
    293     uint8_t         au8Signature[4];
    294     uint16_t        u16Length;
    295     uint8_t         u8SpecRev;
    296     uint8_t         u8Checksum;
    297     uint8_t         au8OemId[8];
    298     uint8_t         au8ProductId[12];
    299     uint32_t        u32OemTablePtr;
    300     uint16_t        u16OemTableSize;
    301     uint16_t        u16EntryCount;
    302     uint32_t        u32AddrLocalApic;
    303     uint16_t        u16ExtTableLength;
    304     uint8_t         u8ExtTableChecksxum;
    305     uint8_t         u8Reserved;
    306 } *PMPSCFGTBLHEADER;
    307 AssertCompileSize(MPSCFGTBLHEADER, 0x2c);
    308 
    309 /** MPS processor entry */
    310 typedef struct MPSPROCENTRY
    311 {
    312     uint8_t         u8EntryType;
    313     uint8_t         u8LocalApicId;
    314     uint8_t         u8LocalApicVersion;
    315     uint8_t         u8CPUFlags;
    316     uint32_t        u32CPUSignature;
    317     uint32_t        u32CPUFeatureFlags;
    318     uint32_t        u32Reserved[2];
    319 } *PMPSPROCENTRY;
    320 AssertCompileSize(MPSPROCENTRY, 20);
    321 
    322 /** MPS bus entry */
    323 typedef struct MPSBUSENTRY
    324 {
    325     uint8_t         u8EntryType;
    326     uint8_t         u8BusId;
    327     uint8_t         au8BusTypeStr[6];
    328 } *PMPSBUSENTRY;
    329 AssertCompileSize(MPSBUSENTRY, 8);
    330 
    331 /** MPS I/O-APIC entry */
    332 typedef struct MPSIOAPICENTRY
    333 {
    334     uint8_t         u8EntryType;
    335     uint8_t         u8Id;
    336     uint8_t         u8Version;
    337     uint8_t         u8Flags;
    338     uint32_t        u32Addr;
    339 } *PMPSIOAPICENTRY;
    340 AssertCompileSize(MPSIOAPICENTRY, 8);
    341 
    342 /** MPS I/O-Interrupt entry */
    343 typedef struct MPSIOINTERRUPTENTRY
    344 {
    345     uint8_t         u8EntryType;
    346     uint8_t         u8Type;
    347     uint16_t        u16Flags;
    348     uint8_t         u8SrcBusId;
    349     uint8_t         u8SrcBusIrq;
    350     uint8_t         u8DstIOAPICId;
    351     uint8_t         u8DstIOAPICInt;
    352 } *PMPSIOIRQENTRY;
    353 AssertCompileSize(MPSIOINTERRUPTENTRY, 8);
    354 
    355 #pragma pack()
    356 
    357172
    358173/* Attempt to guess the LCHS disk geometry from the MS-DOS master boot
     
    920735}
    921736
    922 
    923 /**
    924  * Construct the DMI table.
    925  *
    926  * @returns VBox status code.
    927  * @param   pDevIns     The device instance.
    928  * @param   pTable      Where to create the DMI table.
    929  * @param   cbMax       The max size of the DMI table.
    930  * @param   pUuid       Pointer to the UUID to use if the DmiUuid
    931  *                      configuration string isn't present.
    932  * @param   pCfgHandle  The handle to our config node.
    933  */
    934 static int pcbiosPlantDMITable(PPDMDEVINS pDevIns, uint8_t *pTable, unsigned cbMax, PRTUUID pUuid, PCFGMNODE pCfgHandle)
    935 {
    936     char *pszStr = (char *)pTable;
    937     int iStrNr;
    938     int rc;
    939     char *pszDmiBIOSVendor, *pszDmiBIOSVersion, *pszDmiBIOSReleaseDate;
    940     int  iDmiBIOSReleaseMajor, iDmiBIOSReleaseMinor, iDmiBIOSFirmwareMajor, iDmiBIOSFirmwareMinor;
    941     char *pszDmiSystemVendor, *pszDmiSystemProduct, *pszDmiSystemVersion, *pszDmiSystemSerial, *pszDmiSystemUuid, *pszDmiSystemFamily;
    942     char *pszDmiChassisVendor, *pszDmiChassisVersion, *pszDmiChassisSerial, *pszDmiChassisAssetTag;
    943     char *pszDmiOEMVBoxVer, *pszDmiOEMVBoxRev;
    944 
    945 #define CHECKSIZE(want) \
    946     do { \
    947         size_t _max = (size_t)(pszStr + want - (char *)pTable) + 5; /* +1 for strtab terminator +4 for end-of-table entry */ \
    948         if (_max > cbMax) \
    949         { \
    950             return PDMDevHlpVMSetError(pDevIns, VERR_TOO_MUCH_DATA, RT_SRC_POS, \
    951                    N_("One of the DMI strings is too long. Check all bios/Dmi* configuration entries. At least %zu bytes are needed but there is no space for more than %d bytes"), _max, cbMax); \
    952         } \
    953     } while (0)
    954 #define SETSTRING(memb, str) \
    955     do { \
    956         if (!str[0]) \
    957             memb = 0; /* empty string */ \
    958         else \
    959         { \
    960             memb = iStrNr++; \
    961             size_t _len = strlen(str) + 1; \
    962             CHECKSIZE(_len); \
    963             memcpy(pszStr, str, _len); \
    964             pszStr += _len; \
    965         } \
    966     } while (0)
    967 #define READCFGSTR(name, variable, default_value) \
    968     do { \
    969         rc = CFGMR3QueryStringAlloc(pCfgHandle, name, & variable); \
    970         if (rc == VERR_CFGM_VALUE_NOT_FOUND) \
    971             variable = MMR3HeapStrDup(PDMDevHlpGetVM(pDevIns), MM_TAG_CFGM, default_value); \
    972         else if (RT_FAILURE(rc)) \
    973             return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, \
    974                     N_("Configuration error: Querying \"" name "\" as a string failed")); \
    975         else if (!strcmp(variable, "<EMPTY>")) \
    976             variable[0] = '\0'; \
    977     } while (0)
    978 #define READCFGINT(name, variable, default_value) \
    979     do { \
    980         rc = CFGMR3QueryS32(pCfgHandle, name, & variable); \
    981         if (rc == VERR_CFGM_VALUE_NOT_FOUND) \
    982             variable = default_value; \
    983         else if (RT_FAILURE(rc)) \
    984             return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, \
    985                     N_("Configuration error: Querying \"" name "\" as a Int failed")); \
    986     } while (0)
    987 
    988 
    989     /*
    990      * Don't change this information otherwise Windows guests will demand re-activation!
    991      */
    992     READCFGSTR("DmiBIOSVendor",        pszDmiBIOSVendor,      "innotek GmbH");
    993     READCFGSTR("DmiBIOSVersion",       pszDmiBIOSVersion,     "VirtualBox");
    994     READCFGSTR("DmiBIOSReleaseDate",   pszDmiBIOSReleaseDate, "12/01/2006");
    995     READCFGINT("DmiBIOSReleaseMajor",  iDmiBIOSReleaseMajor,   0);
    996     READCFGINT("DmiBIOSReleaseMinor",  iDmiBIOSReleaseMinor,   0);
    997     READCFGINT("DmiBIOSFirmwareMajor", iDmiBIOSFirmwareMajor,  0);
    998     READCFGINT("DmiBIOSFirmwareMinor", iDmiBIOSFirmwareMinor,  0);
    999     READCFGSTR("DmiSystemVendor",      pszDmiSystemVendor,    "innotek GmbH");
    1000     READCFGSTR("DmiSystemProduct",     pszDmiSystemProduct,   "VirtualBox");
    1001     READCFGSTR("DmiSystemVersion",     pszDmiSystemVersion,   "1.2");
    1002     READCFGSTR("DmiSystemSerial",      pszDmiSystemSerial,    "0");
    1003     rc = CFGMR3QueryStringAlloc(pCfgHandle, "DmiSystemUuid", &pszDmiSystemUuid);
    1004     if (rc == VERR_CFGM_VALUE_NOT_FOUND)
    1005         pszDmiSystemUuid = NULL;
    1006     else if (RT_FAILURE(rc))
    1007         return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
    1008                                    N_("Configuration error: Querying \"DmiUuid\" as a string failed"));
    1009     READCFGSTR("DmiSystemFamily",      pszDmiSystemFamily,    "Virtual Machine");
    1010     READCFGSTR("DmiChassisVendor",     pszDmiChassisVendor,   "Sun Microsystems, Inc.");
    1011     READCFGSTR("DmiChassisVersion",    pszDmiChassisVersion,  ""); /* default not specified */
    1012     READCFGSTR("DmiChassisSerial",     pszDmiChassisSerial,   ""); /* default not specified */
    1013     READCFGSTR("DmiChassisAssetTag",   pszDmiChassisAssetTag, ""); /* default not specified */
    1014 
    1015     /* DMI BIOS information (Type 0) */
    1016     PDMIBIOSINF pBIOSInf         = (PDMIBIOSINF)pszStr;
    1017     CHECKSIZE(sizeof(*pBIOSInf));
    1018 
    1019     pszStr                       = (char *)&pBIOSInf->u8ReleaseMajor;
    1020     pBIOSInf->header.u8Length    = RT_OFFSETOF(DMIBIOSINF, u8ReleaseMajor);
    1021 
    1022     /* don't set these fields by default for legacy compatibility */
    1023     if (iDmiBIOSReleaseMajor != 0 || iDmiBIOSReleaseMinor != 0)
    1024     {
    1025         pszStr = (char *)&pBIOSInf->u8FirmwareMajor;
    1026         pBIOSInf->header.u8Length = RT_OFFSETOF(DMIBIOSINF, u8FirmwareMajor);
    1027         pBIOSInf->u8ReleaseMajor  = iDmiBIOSReleaseMajor;
    1028         pBIOSInf->u8ReleaseMinor  = iDmiBIOSReleaseMinor;
    1029         if (iDmiBIOSFirmwareMajor != 0 || iDmiBIOSFirmwareMinor != 0)
    1030         {
    1031             pszStr = (char *)(pBIOSInf + 1);
    1032             pBIOSInf->header.u8Length = sizeof(DMIBIOSINF);
    1033             pBIOSInf->u8FirmwareMajor = iDmiBIOSFirmwareMajor;
    1034             pBIOSInf->u8FirmwareMinor = iDmiBIOSFirmwareMinor;
    1035         }
    1036     }
    1037 
    1038     iStrNr                       = 1;
    1039     pBIOSInf->header.u8Type      = 0; /* BIOS Information */
    1040     pBIOSInf->header.u16Handle   = 0x0000;
    1041     SETSTRING(pBIOSInf->u8Vendor,  pszDmiBIOSVendor);
    1042     SETSTRING(pBIOSInf->u8Version, pszDmiBIOSVersion);
    1043     pBIOSInf->u16Start           = 0xE000;
    1044     SETSTRING(pBIOSInf->u8Release, pszDmiBIOSReleaseDate);
    1045     pBIOSInf->u8ROMSize          = 1; /* 128K */
    1046     pBIOSInf->u64Characteristics = RT_BIT(4)   /* ISA is supported */
    1047                                  | RT_BIT(7)   /* PCI is supported */
    1048                                  | RT_BIT(15)  /* Boot from CD is supported */
    1049                                  | RT_BIT(16)  /* Selectable Boot is supported */
    1050                                  | RT_BIT(27)  /* Int 9h, 8042 Keyboard services supported */
    1051                                  | RT_BIT(30)  /* Int 10h, CGA/Mono Video Services supported */
    1052                                  /* any more?? */
    1053                                  ;
    1054     pBIOSInf->u8CharacteristicsByte1 = RT_BIT(0)   /* ACPI is supported */
    1055                                      /* any more?? */
    1056                                      ;
    1057     pBIOSInf->u8CharacteristicsByte2 = 0
    1058                                      /* any more?? */
    1059                                      ;
    1060     *pszStr++                    = '\0';
    1061 
    1062     /* DMI system information (Type 1) */
    1063     PDMISYSTEMINF pSystemInf     = (PDMISYSTEMINF)pszStr;
    1064     CHECKSIZE(sizeof(*pSystemInf));
    1065     pszStr                       = (char *)(pSystemInf + 1);
    1066     iStrNr                       = 1;
    1067     pSystemInf->header.u8Type    = 1; /* System Information */
    1068     pSystemInf->header.u8Length  = sizeof(*pSystemInf);
    1069     pSystemInf->header.u16Handle = 0x0001;
    1070     SETSTRING(pSystemInf->u8Manufacturer, pszDmiSystemVendor);
    1071     SETSTRING(pSystemInf->u8ProductName,  pszDmiSystemProduct);
    1072     SETSTRING(pSystemInf->u8Version,      pszDmiSystemVersion);
    1073     SETSTRING(pSystemInf->u8SerialNumber, pszDmiSystemSerial);
    1074 
    1075     RTUUID uuid;
    1076     if (pszDmiSystemUuid)
    1077     {
    1078         int rc = RTUuidFromStr(&uuid, pszDmiSystemUuid);
    1079         if (RT_FAILURE(rc))
    1080             return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
    1081                                        N_("Invalid UUID for DMI tables specified"));
    1082         uuid.Gen.u32TimeLow = RT_H2BE_U32(uuid.Gen.u32TimeLow);
    1083         uuid.Gen.u16TimeMid = RT_H2BE_U16(uuid.Gen.u16TimeMid);
    1084         uuid.Gen.u16TimeHiAndVersion = RT_H2BE_U16(uuid.Gen.u16TimeHiAndVersion);
    1085         pUuid = &uuid;
    1086     }
    1087     memcpy(pSystemInf->au8Uuid, pUuid, sizeof(RTUUID));
    1088 
    1089     pSystemInf->u8WakeupType     = 6; /* Power Switch */
    1090     pSystemInf->u8SKUNumber      = 0;
    1091     SETSTRING(pSystemInf->u8Family, pszDmiSystemFamily);
    1092     *pszStr++                    = '\0';
    1093 
    1094     /* DMI System Enclosure or Chassis (Type 3) */
    1095     PDMICHASSIS pChassis         = (PDMICHASSIS)pszStr;
    1096     CHECKSIZE(sizeof(*pChassis));
    1097     pszStr                       = (char*)&pChassis->u32OEMdefined;
    1098     iStrNr                       = 1;
    1099 #ifdef VBOX_WITH_DMI_CHASSIS
    1100     pChassis->header.u8Type      = 3; /* System Enclosure or Chassis */
    1101 #else
    1102     pChassis->header.u8Type      = 0x7e; /* inactive */
    1103 #endif
    1104     pChassis->header.u8Length    = RT_OFFSETOF(DMICHASSIS, u32OEMdefined);
    1105     pChassis->header.u16Handle   = 0x0003;
    1106     SETSTRING(pChassis->u8Manufacturer, pszDmiChassisVendor);
    1107     pChassis->u8Type             = 0x01; /* ''other'', no chassis lock present */
    1108     SETSTRING(pChassis->u8Version, pszDmiChassisVersion);
    1109     SETSTRING(pChassis->u8SerialNumber, pszDmiChassisSerial);
    1110     SETSTRING(pChassis->u8AssetTag, pszDmiChassisAssetTag);
    1111     pChassis->u8BootupState      = 0x03; /* safe */
    1112     pChassis->u8PowerSupplyState = 0x03; /* safe */
    1113     pChassis->u8ThermalState     = 0x03; /* safe */
    1114     pChassis->u8SecurityStatus   = 0x03; /* none XXX */
    1115 # if 0
    1116     /* v2.3+, currently not supported */
    1117     pChassis->u32OEMdefined      = 0;
    1118     pChassis->u8Height           = 0; /* unspecified */
    1119     pChassis->u8NumPowerChords   = 0; /* unspecified */
    1120     pChassis->u8ContElems        = 0; /* no contained elements */
    1121     pChassis->u8ContElemRecLen   = 0; /* no contained elements */
    1122 # endif
    1123     *pszStr++                    = '\0';
    1124 
    1125     /* DMI OEM strings */
    1126     PDMIOEMSTRINGS pOEMStrings    = (PDMIOEMSTRINGS)pszStr;
    1127     CHECKSIZE(sizeof(*pOEMStrings));
    1128     pszStr                        = (char *)(pOEMStrings + 1);
    1129     iStrNr                        = 1;
    1130 #ifdef VBOX_WITH_DMI_OEMSTRINGS
    1131     pOEMStrings->header.u8Type    = 0xb; /* OEM Strings */
    1132 #else
    1133     pOEMStrings->header.u8Type    = 0x7e; /* inactive */
    1134 #endif
    1135     pOEMStrings->header.u8Length  = sizeof(*pOEMStrings);
    1136     pOEMStrings->header.u16Handle = 0x0002;
    1137     pOEMStrings->u8Count          = 2;
    1138 
    1139     char szTmp[64];
    1140     RTStrPrintf(szTmp, sizeof(szTmp), "vboxVer_%u.%u.%u",
    1141                 RTBldCfgVersionMajor(), RTBldCfgVersionMinor(), RTBldCfgVersionBuild());
    1142     READCFGSTR("DmiOEMVBoxVer", pszDmiOEMVBoxVer, szTmp);
    1143     RTStrPrintf(szTmp, sizeof(szTmp), "vboxRev_%u", RTBldCfgRevision());
    1144     READCFGSTR("DmiOEMVBoxRev", pszDmiOEMVBoxRev, szTmp);
    1145     SETSTRING(pOEMStrings->u8VBoxVersion, pszDmiOEMVBoxVer);
    1146     SETSTRING(pOEMStrings->u8VBoxRevision, pszDmiOEMVBoxRev);
    1147     *pszStr++                    = '\0';
    1148 
    1149     /* End-of-table marker - includes padding to account for fixed table size. */
    1150     PDMIHDR pEndOfTable          = (PDMIHDR)pszStr;
    1151     pEndOfTable->u8Type          = 0x7f;
    1152     pEndOfTable->u8Length        = cbMax - ((char *)pszStr - (char *)pTable) - 2;
    1153     pEndOfTable->u16Handle       = 0xFEFF;
    1154 
    1155     /* If more fields are added here, fix the size check in SETSTRING */
    1156 
    1157 #undef SETSTRING
    1158 #undef READCFGSTR
    1159 #undef READCFGINT
    1160 #undef CHECKSIZE
    1161 
    1162     MMR3HeapFree(pszDmiBIOSVendor);
    1163     MMR3HeapFree(pszDmiBIOSVersion);
    1164     MMR3HeapFree(pszDmiBIOSReleaseDate);
    1165     MMR3HeapFree(pszDmiSystemVendor);
    1166     MMR3HeapFree(pszDmiSystemProduct);
    1167     MMR3HeapFree(pszDmiSystemVersion);
    1168     MMR3HeapFree(pszDmiSystemSerial);
    1169     MMR3HeapFree(pszDmiSystemUuid);
    1170     MMR3HeapFree(pszDmiSystemFamily);
    1171     MMR3HeapFree(pszDmiChassisVendor);
    1172     MMR3HeapFree(pszDmiChassisVersion);
    1173     MMR3HeapFree(pszDmiChassisSerial);
    1174     MMR3HeapFree(pszDmiChassisAssetTag);
    1175     MMR3HeapFree(pszDmiOEMVBoxVer);
    1176     MMR3HeapFree(pszDmiOEMVBoxRev);
    1177 
    1178     return VINF_SUCCESS;
    1179 }
    1180 AssertCompile(VBOX_DMI_TABLE_ENTR == 5);
    1181 
    1182 /**
    1183  * Calculate a simple checksum for the MPS table.
    1184  *
    1185  * @param   data            data
    1186  * @param   len             size of data
    1187  */
    1188 static uint8_t pcbiosChecksum(const uint8_t * const au8Data, uint32_t u32Length)
    1189 {
    1190     uint8_t u8Sum = 0;
    1191     for (size_t i = 0; i < u32Length; ++i)
    1192         u8Sum += au8Data[i];
    1193     return -u8Sum;
    1194 }
    1195 
    1196 
    1197 /**
    1198  * Construct the MPS table. Only applicable if IOAPIC is active!
    1199  *
    1200  * See ``MultiProcessor Specificatiton Version 1.4 (May 1997)'':
    1201  *   ``1.3 Scope
    1202  *     ...
    1203  *     The hardware required to implement the MP specification is kept to a
    1204  *     minimum, as follows:
    1205  *     * One or more processors that are Intel architecture instruction set
    1206  *       compatible, such as the CPUs in the Intel486 or Pentium processor
    1207  *       family.
    1208  *     * One or more APICs, such as the Intel 82489DX Advanced Programmable
    1209  *       Interrupt Controller or the integrated APIC, such as that on the
    1210  *       Intel Pentium 735\90 and 815\100 processors, together with a discrete
    1211  *       I/O APIC unit.''
    1212  * and later:
    1213  *   ``4.3.3 I/O APIC Entries
    1214  *     The configuration table contains one or more entries for I/O APICs.
    1215  *     ...
    1216  *     I/O APIC FLAGS: EN 3:0 1 If zero, this I/O APIC is unusable, and the
    1217  *                              operating system should not attempt to access
    1218  *                              this I/O APIC.
    1219  *                              At least one I/O APIC must be enabled.''
    1220  *
    1221  * @param   pDevIns    The device instance data.
    1222  * @param   addr       physical address in guest memory.
    1223  */
    1224 static void pcbiosPlantMpsTable(PPDMDEVINS pDevIns, uint8_t *pTable, uint16_t numCpus)
    1225 {
    1226     /* configuration table */
    1227     PMPSCFGTBLHEADER pCfgTab      = (MPSCFGTBLHEADER*)pTable;
    1228     memcpy(pCfgTab->au8Signature, "PCMP", 4);
    1229     pCfgTab->u8SpecRev             =  4;    /* 1.4 */
    1230     memcpy(pCfgTab->au8OemId, "VBOXCPU ", 8);
    1231     memcpy(pCfgTab->au8ProductId, "VirtualBox  ", 12);
    1232     pCfgTab->u32OemTablePtr        =  0;
    1233     pCfgTab->u16OemTableSize       =  0;
    1234     pCfgTab->u16EntryCount         =  numCpus /* Processors */
    1235                                    +  1 /* ISA Bus */
    1236                                    +  1 /* I/O-APIC */
    1237                                    + 16 /* Interrupts */;
    1238     pCfgTab->u32AddrLocalApic      = 0xfee00000;
    1239     pCfgTab->u16ExtTableLength     =  0;
    1240     pCfgTab->u8ExtTableChecksxum   =  0;
    1241     pCfgTab->u8Reserved            =  0;
    1242 
    1243     uint32_t u32Eax, u32Ebx, u32Ecx, u32Edx;
    1244     uint32_t u32CPUSignature = 0x0520; /* default: Pentium 100 */
    1245     uint32_t u32FeatureFlags = 0x0001; /* default: FPU */
    1246     PDMDevHlpGetCpuId(pDevIns, 0, &u32Eax, &u32Ebx, &u32Ecx, &u32Edx);
    1247     if (u32Eax >= 1)
    1248     {
    1249         PDMDevHlpGetCpuId(pDevIns, 1, &u32Eax, &u32Ebx, &u32Ecx, &u32Edx);
    1250         u32CPUSignature = u32Eax & 0xfff;
    1251         /* Local APIC will be enabled later so override it here. Since we provide
    1252          * an MP table we have an IOAPIC and therefore a Local APIC. */
    1253         u32FeatureFlags = u32Edx | X86_CPUID_FEATURE_EDX_APIC;
    1254     }
    1255     /* Construct MPS table for each VCPU. */
    1256     PMPSPROCENTRY pProcEntry = (PMPSPROCENTRY)(pCfgTab+1);
    1257     for (int i = 0; i<numCpus; i++)
    1258     {
    1259         pProcEntry->u8EntryType        = 0; /* processor entry */
    1260         pProcEntry->u8LocalApicId      = i;
    1261         pProcEntry->u8LocalApicVersion = 0x11;
    1262         pProcEntry->u8CPUFlags         = (i == 0 ? 2 /* bootstrap processor */ : 0 /* application processor */) | 1 /* enabled */;
    1263         pProcEntry->u32CPUSignature    = u32CPUSignature;
    1264         pProcEntry->u32CPUFeatureFlags = u32FeatureFlags;
    1265         pProcEntry->u32Reserved[0]     =
    1266         pProcEntry->u32Reserved[1]     = 0;
    1267         pProcEntry++;
    1268     }
    1269 
    1270     /* ISA bus */
    1271     PMPSBUSENTRY pBusEntry         = (PMPSBUSENTRY)(pProcEntry+1);
    1272     pBusEntry->u8EntryType         = 1; /* bus entry */
    1273     pBusEntry->u8BusId             = 0; /* this ID is referenced by the interrupt entries */
    1274     memcpy(pBusEntry->au8BusTypeStr, "ISA   ", 6);
    1275 
    1276     /* PCI bus? */
    1277 
    1278     /* I/O-APIC.
    1279      * MP spec: "The configuration table contains one or more entries for I/O APICs.
    1280      *           ... At least one I/O APIC must be enabled." */
    1281     PMPSIOAPICENTRY pIOAPICEntry   = (PMPSIOAPICENTRY)(pBusEntry+1);
    1282     uint16_t apicId = numCpus;
    1283     pIOAPICEntry->u8EntryType      = 2; /* I/O-APIC entry */
    1284     pIOAPICEntry->u8Id             = apicId; /* this ID is referenced by the interrupt entries */
    1285     pIOAPICEntry->u8Version        = 0x11;
    1286     pIOAPICEntry->u8Flags          = 1 /* enable */;
    1287     pIOAPICEntry->u32Addr          = 0xfec00000;
    1288 
    1289     PMPSIOIRQENTRY pIrqEntry       = (PMPSIOIRQENTRY)(pIOAPICEntry+1);
    1290     for (int i = 0; i < 16; i++, pIrqEntry++)
    1291     {
    1292         pIrqEntry->u8EntryType     = 3; /* I/O interrupt entry */
    1293         pIrqEntry->u8Type          = 0; /* INT, vectored interrupt */
    1294         pIrqEntry->u16Flags        = 0; /* polarity of APIC I/O input signal = conforms to bus,
    1295                                            trigger mode = conforms to bus */
    1296         pIrqEntry->u8SrcBusId      = 0; /* ISA bus */
    1297         pIrqEntry->u8SrcBusIrq     = i;
    1298         pIrqEntry->u8DstIOAPICId   = apicId;
    1299         pIrqEntry->u8DstIOAPICInt  = i;
    1300     }
    1301 
    1302     pCfgTab->u16Length             = (uint8_t*)pIrqEntry - pTable;
    1303     pCfgTab->u8Checksum            = pcbiosChecksum(pTable, pCfgTab->u16Length);
    1304 
    1305     AssertMsg(pCfgTab->u16Length < 0x1000 - 0x100,
    1306               ("VBOX_MPS_TABLE_SIZE=%d, maximum allowed size is %d",
    1307               pCfgTab->u16Length, 0x1000-0x100));
    1308 
    1309     MPSFLOATPTR floatPtr;
    1310     floatPtr.au8Signature[0]       = '_';
    1311     floatPtr.au8Signature[1]       = 'M';
    1312     floatPtr.au8Signature[2]       = 'P';
    1313     floatPtr.au8Signature[3]       = '_';
    1314     floatPtr.u32MPSAddr            = VBOX_MPS_TABLE_BASE;
    1315     floatPtr.u8Length              = 1; /* structure size in paragraphs */
    1316     floatPtr.u8SpecRev             = 4; /* MPS revision 1.4 */
    1317     floatPtr.u8Checksum            = 0;
    1318     floatPtr.au8Feature[0]         = 0;
    1319     floatPtr.au8Feature[1]         = 0;
    1320     floatPtr.au8Feature[2]         = 0;
    1321     floatPtr.au8Feature[3]         = 0;
    1322     floatPtr.au8Feature[4]         = 0;
    1323     floatPtr.u8Checksum            = pcbiosChecksum((uint8_t*)&floatPtr, 16);
    1324     PDMDevHlpPhysWrite (pDevIns, 0x9fff0, &floatPtr, 16);
    1325 }
    1326 
    1327 
    1328737/**
    1329738 * Reset notification.
     
    1338747
    1339748    if (pThis->u8IOAPIC)
    1340         pcbiosPlantMpsTable(pDevIns, pThis->au8DMIPage + VBOX_DMI_TABLE_SIZE, pThis->cCpus);
     749        sharedfwPlantMpsTable(pDevIns, pThis->au8DMIPage + VBOX_DMI_TABLE_SIZE, pThis->cCpus);
    1341750
    1342751    /*
     
    16201029    uuid.Gen.u16TimeMid = RT_H2BE_U16(uuid.Gen.u16TimeMid);
    16211030    uuid.Gen.u16TimeHiAndVersion = RT_H2BE_U16(uuid.Gen.u16TimeHiAndVersion);
    1622     rc = pcbiosPlantDMITable(pDevIns, pThis->au8DMIPage, VBOX_DMI_TABLE_SIZE, &uuid, pCfgHandle);
     1031    rc = sharedfwPlantDMITable(pDevIns, pThis->au8DMIPage, VBOX_DMI_TABLE_SIZE, &uuid, pCfgHandle);
    16231032    if (RT_FAILURE(rc))
    16241033        return rc;
    16251034    if (pThis->u8IOAPIC)
    1626         pcbiosPlantMpsTable(pDevIns, pThis->au8DMIPage + VBOX_DMI_TABLE_SIZE, pThis->cCpus);
     1035        sharedfwPlantMpsTable(pDevIns, pThis->au8DMIPage + VBOX_DMI_TABLE_SIZE, pThis->cCpus);
    16271036
    16281037    rc = PDMDevHlpROMRegister(pDevIns, VBOX_DMI_TABLE_BASE, _4K, pThis->au8DMIPage,
  • trunk/src/VBox/Devices/PC/DevPcBios.h

    r21874 r24706  
    77 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
    88 *
    9  * This file is part of VirtualBox Open Source Edition (OSE), as
     9 * This file is part of VirtualBox Open Source Edit2ion (OSE), as
    1010 * available from http://www.virtualbox.org. This file is free software;
    1111 * you can redistribute it and/or modify it under the terms of the GNU
     
    2929#define VBOX_DMI_TABLE_SIZE          0x100
    3030
    31 
    32 /** @def VBOX_MPS_TABLE_BASE
    33  *
    34  * Must be located in the same page as the DMI table.
    35  */
    36 #define VBOX_MPS_TABLE_BASE          0xe1100
    37 
    38 #define VBOX_SMBIOS_MAJOR_VER        2
    39 #define VBOX_SMBIOS_MINOR_VER        5
    40 #define VBOX_SMBIOS_MAXSS            0xff   /* Not very accurate */
    41 
    42 
    4331/** @def VBOX_VMI_BIOS_BASE
    4432 *
     
    5341#define VBOX_LANBOOT_SEG             0xe200
    5442
     43#define VBOX_SMBIOS_MAJOR_VER        2
     44#define VBOX_SMBIOS_MINOR_VER        5
     45#define VBOX_SMBIOS_MAXSS            0xff   /* Not very accurate */
     46
    5547#endif
    56 
  • trunk/src/VBox/Main/ConsoleImpl2.cpp

    r24603 r24706  
    839839        rc = CFGMR3InsertInteger(pCfg,  "NumCPUs",          cCpus);                 RC_CHECK();
    840840        rc = CFGMR3InsertString(pCfg,   "EfiRom",           efiRomFile.raw());      RC_CHECK();
     841        rc = CFGMR3InsertInteger(pCfg,  "IOAPIC",               fIOAPIC);           RC_CHECK();
     842        rc = CFGMR3InsertBytes(pCfg,    "UUID", &HardwareUuid,sizeof(HardwareUuid));RC_CHECK();
    841843    }
    842844
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