Changeset 24706 in vbox for trunk/src/VBox/Devices/PC
- Timestamp:
- Nov 16, 2009 5:57:20 PM (15 years ago)
- Location:
- trunk/src/VBox/Devices/PC
- Files:
-
- 2 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevPcBios.cpp
r24194 r24706 41 41 #include "../Builtins2.h" 42 42 #include "DevPcBios.h" 43 #include "DevFwCommon.h" 43 44 44 45 … … 169 170 } DEVPCBIOS, *PDEVPCBIOS; 170 171 171 #pragma pack(1)172 173 /** DMI header */174 typedef struct DMIHDR175 {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 DMIBIOSINF184 {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 DMISYSTEMINF203 {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 DMICHASSIS218 {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 DMIPROCESSORINF240 {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 DMIOEMSTRINGS270 {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 MPSFLOATPTR280 {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 MPSCFGTBLHEADER292 {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 MPSPROCENTRY311 {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 MPSBUSENTRY324 {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 MPSIOAPICENTRY333 {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 MPSIOINTERRUPTENTRY344 {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 357 172 358 173 /* Attempt to guess the LCHS disk geometry from the MS-DOS master boot … … 920 735 } 921 736 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 DmiUuid931 * 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 = 01058 /* 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_CHASSIS1100 pChassis->header.u8Type = 3; /* System Enclosure or Chassis */1101 #else1102 pChassis->header.u8Type = 0x7e; /* inactive */1103 #endif1104 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 01116 /* 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 # endif1123 *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_OEMSTRINGS1131 pOEMStrings->header.u8Type = 0xb; /* OEM Strings */1132 #else1133 pOEMStrings->header.u8Type = 0x7e; /* inactive */1134 #endif1135 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 SETSTRING1158 #undef READCFGSTR1159 #undef READCFGINT1160 #undef CHECKSIZE1161 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 data1186 * @param len size of data1187 */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 Scope1202 * ...1203 * The hardware required to implement the MP specification is kept to a1204 * minimum, as follows:1205 * * One or more processors that are Intel architecture instruction set1206 * compatible, such as the CPUs in the Intel486 or Pentium processor1207 * family.1208 * * One or more APICs, such as the Intel 82489DX Advanced Programmable1209 * Interrupt Controller or the integrated APIC, such as that on the1210 * Intel Pentium 735\90 and 815\100 processors, together with a discrete1211 * I/O APIC unit.''1212 * and later:1213 * ``4.3.3 I/O APIC Entries1214 * 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 the1217 * operating system should not attempt to access1218 * 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 provide1252 * 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 1328 737 /** 1329 738 * Reset notification. … … 1338 747 1339 748 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); 1341 750 1342 751 /* … … 1620 1029 uuid.Gen.u16TimeMid = RT_H2BE_U16(uuid.Gen.u16TimeMid); 1621 1030 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); 1623 1032 if (RT_FAILURE(rc)) 1624 1033 return rc; 1625 1034 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); 1627 1036 1628 1037 rc = PDMDevHlpROMRegister(pDevIns, VBOX_DMI_TABLE_BASE, _4K, pThis->au8DMIPage, -
trunk/src/VBox/Devices/PC/DevPcBios.h
r21874 r24706 7 7 * Copyright (C) 2006-2007 Sun Microsystems, Inc. 8 8 * 9 * This file is part of VirtualBox Open Source Edit ion (OSE), as9 * This file is part of VirtualBox Open Source Edit2ion (OSE), as 10 10 * available from http://www.virtualbox.org. This file is free software; 11 11 * you can redistribute it and/or modify it under the terms of the GNU … … 29 29 #define VBOX_DMI_TABLE_SIZE 0x100 30 30 31 32 /** @def VBOX_MPS_TABLE_BASE33 *34 * Must be located in the same page as the DMI table.35 */36 #define VBOX_MPS_TABLE_BASE 0xe110037 38 #define VBOX_SMBIOS_MAJOR_VER 239 #define VBOX_SMBIOS_MINOR_VER 540 #define VBOX_SMBIOS_MAXSS 0xff /* Not very accurate */41 42 43 31 /** @def VBOX_VMI_BIOS_BASE 44 32 * … … 53 41 #define VBOX_LANBOOT_SEG 0xe200 54 42 43 #define VBOX_SMBIOS_MAJOR_VER 2 44 #define VBOX_SMBIOS_MINOR_VER 5 45 #define VBOX_SMBIOS_MAXSS 0xff /* Not very accurate */ 46 55 47 #endif 56
Note:
See TracChangeset
for help on using the changeset viewer.