VirtualBox

Changeset 24706 in vbox for trunk/src/VBox/Devices/PC


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

EFI: ACPI work

Location:
trunk/src/VBox/Devices/PC
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • 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 
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