/** This function gets system guid and serial number from the smbios table. @param SystemGuid The pointer of returned system guid. @param SystemSerialNumber The pointer of returned system serial number. @retval EFI_SUCCESS Successfully get the system guid and system serial number. @retval EFI_NOT_FOUND Not find the SMBIOS table. **/ EFI_STATUS GetSmbiosSystemGuidAndSerialNumber ( IN EFI_GUID *SystemGuid, OUT CHAR8 **SystemSerialNumber ) { EFI_STATUS Status; SMBIOS_TABLE_ENTRY_POINT *SmbiosTable; SMBIOS_STRUCTURE_POINTER Smbios; SMBIOS_STRUCTURE_POINTER SmbiosEnd; UINT16 Index; Status = EfiGetSystemConfigurationTable (&gEfiSmbiosTableGuid, (VOID **) &SmbiosTable); if (EFI_ERROR (Status)) { return EFI_NOT_FOUND; } ASSERT (SmbiosTable != NULL); Smbios.Hdr = (SMBIOS_STRUCTURE *) (UINTN) SmbiosTable->TableAddress; SmbiosEnd.Raw = (UINT8 *) (UINTN) (SmbiosTable->TableAddress + SmbiosTable->TableLength); for (Index = 0; Index < SmbiosTable->TableLength; Index++) { if (Smbios.Hdr->Type == 1) { if (Smbios.Hdr->Length < 0x19) { // // Older version did not support Guid and Serial number // continue; } // // SMBIOS tables are byte packed so we need to do a byte copy to // prevend alignment faults on Itanium-based platform. // CopyMem (SystemGuid, &Smbios.Type1->Uuid, sizeof (EFI_GUID)); *SystemSerialNumber = GetSmbiosString (&Smbios, Smbios.Type1->SerialNumber); return EFI_SUCCESS; } // // Make Smbios point to the next record // GetSmbiosString (&Smbios, 0); if (Smbios.Raw >= SmbiosEnd.Raw) { // // SMBIOS 2.1 incorrectly stated the length of SmbiosTable as 0x1e. // given this we must double check against the length of the structure. // return EFI_SUCCESS; } } return EFI_SUCCESS; }
PLOOKUP_ENTRY GetVirtualizationPlatform() { DWORD i = 0; DWORD dwVirtPlatform = VIRT_PLATFORM_NONE; PSMBIOS_STRUCT_HEADER sysTable = GetNextStructureOfType(NULL, SMB_TABLE_SYSTEM); LPTSTR szManufacturer = NULL; LPTSTR szProduct = NULL; // Return cached result if (NULL != VIRT_PLATFORM) return VIRT_PLATFORM; // Validate SMBIOS data if (NULL == sysTable) { SetError(ERR_CRIT, 0, _T("Unable to determine Virtualization status from SBMIOS System Table (Type %u)"), SMB_TABLE_SYSTEM); VIRT_PLATFORM = &VIRT_UNKNOWN; return VIRT_PLATFORM; } // Default to physical VIRT_PLATFORM = &VIRT_PHYSICAL; // Search for platform names in SMBIOS System Manufacturer and Product strings szManufacturer = GetSmbiosString(sysTable, BYTE_AT_OFFSET(sysTable, 0x04)); szProduct = GetSmbiosString(sysTable, BYTE_AT_OFFSET(sysTable, 0x05)); for (i = 0; i < ARRAYSIZE(VIRT_VENDORS); i++) { if (NULL != wcsistr(szManufacturer, VIRT_VENDORS[i].Code) || NULL != wcsstr(szProduct, VIRT_VENDORS[i].Code)) { VIRT_PLATFORM = &VIRT_VENDORS[i]; break; } } LocalFree(szManufacturer); LocalFree(szProduct); return VIRT_PLATFORM; }
VOID InstallProcessorSmbios ( IN VOID *Smbios ) { SMBIOS_STRUCTURE_POINTER SmbiosTable; CHAR8 *AString; CHAR16 *UString; STRING_REF Token; // // Processor info (TYPE 4) // SmbiosTable = GetSmbiosTableFromType ((SMBIOS_TABLE_ENTRY_POINT *)Smbios, 4, 0); if (SmbiosTable.Raw == NULL) { DEBUG ((EFI_D_ERROR, "SmbiosTable: Type 4 (Processor Info) not found!\n")); return ; } // // Log Smbios Record Type4 // LogSmbiosData(gSmbios,(UINT8*)SmbiosTable.Type4); // // Set ProcessorVersion string // AString = GetSmbiosString (SmbiosTable, SmbiosTable.Type4->ProcessorVersion); UString = AllocateZeroPool ((AsciiStrLen(AString) + 1) * sizeof(CHAR16)); ASSERT (UString != NULL); AsciiStrToUnicodeStr (AString, UString); Token = HiiSetString (gStringHandle, 0, UString, NULL); if (Token == 0) { gBS->FreePool (UString); return ; } gBS->FreePool (UString); return ; }
VOID InstallMiscSmbios ( IN VOID *Smbios ) { SMBIOS_STRUCTURE_POINTER SmbiosTable; CHAR8 *AString; CHAR16 *UString; STRING_REF Token; // // BIOS information (TYPE 0) // SmbiosTable = GetSmbiosTableFromType ((SMBIOS_TABLE_ENTRY_POINT *)Smbios, 0, 0); if (SmbiosTable.Raw == NULL) { DEBUG ((EFI_D_ERROR, "SmbiosTable: Type 0 (BIOS Information) not found!\n")); return ; } // // Record Type 2 // AString = GetSmbiosString (SmbiosTable, SmbiosTable.Type0->BiosVersion); UString = AllocateZeroPool ((AsciiStrLen(AString) + 1) * sizeof(CHAR16) + sizeof(FIRMWARE_BIOS_VERSIONE)); ASSERT (UString != NULL); CopyMem (UString, FIRMWARE_BIOS_VERSIONE, sizeof(FIRMWARE_BIOS_VERSIONE)); AsciiStrToUnicodeStr (AString, UString + sizeof(FIRMWARE_BIOS_VERSIONE) / sizeof(CHAR16) - 1); Token = HiiSetString (gStringHandle, 0, UString, NULL); if (Token == 0) { gBS->FreePool (UString); return ; } gBS->FreePool (UString); // // Log Smios Type 0 // LogSmbiosData(gSmbios, (UINT8*)SmbiosTable.Type0); // // System information (TYPE 1) // SmbiosTable = GetSmbiosTableFromType ((SMBIOS_TABLE_ENTRY_POINT *)Smbios, 1, 0); if (SmbiosTable.Raw == NULL) { DEBUG ((EFI_D_ERROR, "SmbiosTable: Type 1 (System Information) not found!\n")); return ; } // // Record Type 3 // AString = GetSmbiosString (SmbiosTable, SmbiosTable.Type1->ProductName); UString = AllocateZeroPool ((AsciiStrLen(AString) + 1) * sizeof(CHAR16) + sizeof(FIRMWARE_PRODUCT_NAME)); ASSERT (UString != NULL); CopyMem (UString, FIRMWARE_PRODUCT_NAME, sizeof(FIRMWARE_PRODUCT_NAME)); AsciiStrToUnicodeStr (AString, UString + sizeof(FIRMWARE_PRODUCT_NAME) / sizeof(CHAR16) - 1); Token = HiiSetString (gStringHandle, 0, UString, NULL); if (Token == 0) { gBS->FreePool (UString); return ; } gBS->FreePool (UString); // // Log Smbios Type 1 // LogSmbiosData(gSmbios, (UINT8*)SmbiosTable.Type1); return ; }
// SMBIOS Table Type 16 Physical Memory Array PNODE EnumMemorySockets() { PNODE parentNode = NULL; PNODE node = NULL; PNODE devicesNode = NULL; PNODE deviceNode = NULL; PRAW_SMBIOS_DATA smbios = GetSmbiosData(); PSMBIOS_STRUCT_HEADER header = NULL; PSMBIOS_STRUCT_HEADER memHeader = NULL; PBYTE cursor = NULL; PBYTE memCursor = NULL; LPTSTR unicode = NULL; TCHAR buffer[MAX_PATH + 1]; DWORD i; WORD wbuffer = 0; DWORD dwBuffer = 0; QWORD totalArrayMb = 0; QWORD totalSystemMb = 0; BOOL isVirt = IsVirtualized(); // v2.1+ (Use Table Type 5 Memory Controller for < v2.1) if (smbios->SMBIOSMajorVersion < 2 || (smbios->SMBIOSMajorVersion == 2 && smbios->SMBIOSMinorVersion < 1)) return parentNode; parentNode = node_alloc(_T("Memory"), NFLG_TABLE); while (NULL != (header = GetNextStructureOfType(header, SMB_TABLE_MEM_ARRAY))) { cursor = (PBYTE)header; node = node_append_new(parentNode, _T("Array"), NFLG_TABLE_ROW); // 0x04 Location node_att_set(node, _T("Location"), SAFE_INDEX(MEM_ARRAY_LOCATION, BYTE_AT_OFFSET(header, 0x04)), 0); // 0x05 Use node_att_set(node, _T("Use"), SAFE_INDEX(MEM_ARRAY_USE, BYTE_AT_OFFSET(header, 0x05)), 0); // 0x06 Error Checking node_att_set(node, _T("ErrorChecking"), SAFE_INDEX(MEM_ARRAY_EC_TYPE, BYTE_AT_OFFSET(header, 0x06)), 0); // 0x07 Maximum Capacity (KB) dwBuffer = DWORD_AT_OFFSET(header, 0x07); if (dwBuffer != 0x80000000) { swprintf(buffer, _T("%u"), dwBuffer); node_att_set(node, _T("MaxCapacityKb"), buffer, NAFLG_FMT_KBYTES); swprintf(buffer, _T("%u"), dwBuffer / 1024); node_att_set(node, _T("MaxCapacityMb"), buffer, NAFLG_FMT_MBYTES); swprintf(buffer, _T("%u"), dwBuffer / 1048576); node_att_set(node, _T("MaxCapacityGb"), buffer, NAFLG_FMT_GBYTES); } // 0x0D Number of memory devices swprintf(buffer, _T("%u"), BYTE_AT_OFFSET(header, 0x0D)); node_att_set(node, _T("SocketCount"), buffer, NAFLG_FMT_NUMERIC); // 7.18 Memory Devices (Type 17) devicesNode = node_append_new(node, _T("Modules"), NFLG_TABLE); while (NULL != (memHeader = GetNextStructureOfType(memHeader, SMB_TABLE_MEM_DEVICE))) { memCursor = (PBYTE)memHeader; // 0x04 Memory Array Handle // Ensure array handle matches the parent handle if (header->Handle != WORD_AT_OFFSET(memHeader, 0x04)) continue; // Skip empty slots if (isVirt && 0 == WORD_AT_OFFSET(memHeader, 0x0C)) continue; deviceNode = node_append_new(devicesNode, _T("Module"), NFLG_TABLE_ROW); // 0x08 Total Width wbuffer = WORD_AT_OFFSET(memHeader, 0x08); if (0xFFFF != wbuffer) { swprintf(buffer, _T("%u"), wbuffer); node_att_set(deviceNode, _T("TotalWidth"), buffer, NAFLG_FMT_NUMERIC); } // 0x0A Data Width wbuffer = WORD_AT_OFFSET(memHeader, 0x0A); if (0xFFFF != wbuffer) { swprintf(buffer, _T("%u"), wbuffer); node_att_set(deviceNode, _T("DataWidth"), buffer, NAFLG_FMT_NUMERIC); } // 0x0C Size wbuffer = WORD_AT_OFFSET(memHeader, 0x0C); if (wbuffer & 0x8000) { // Size is in KB wbuffer &= ~0x8000; swprintf(buffer, _T("%u"), wbuffer); node_att_set(deviceNode, _T("Size"), buffer, NAFLG_FMT_KBYTES); } else { // Size is in MB. Scale down to bytes swprintf(buffer, _T("%llu"), (QWORD)wbuffer * 1048576LL); node_att_set(deviceNode, _T("SizeBytes"), buffer, NAFLG_FMT_BYTES); swprintf(buffer, _T("%u"), wbuffer); node_att_set(deviceNode, _T("SizeMb"), buffer, NAFLG_FMT_MBYTES); totalArrayMb += wbuffer; if (wbuffer > 1024) { swprintf(buffer, _T("%u"), wbuffer / 1024); node_att_set(deviceNode, _T("SizeGb"), buffer, NAFLG_FMT_GBYTES); } } // 0x0E Form Factor node_att_set(deviceNode, _T("FormFactor"), SAFE_INDEX(MEM_FORM_FACTOR, BYTE_AT_OFFSET(memHeader, 0x0E)), 0); // 0x0F Device Set wbuffer = BYTE_AT_OFFSET(memHeader, 0x0F); if (0xFF != wbuffer && 0x00 != wbuffer) { swprintf(buffer, _T("0x%X"), wbuffer); node_att_set(deviceNode, _T("DeviceSet"), buffer, NAFLG_FMT_HEX); } // 0x10 Device Locator node_att_set(deviceNode, _T("DeviceLocator"), GetSmbiosString(memHeader, BYTE_AT_OFFSET(memHeader, 0x10)), 0); // 0x11 Device Locator node_att_set(deviceNode, _T("BankLocator"), GetSmbiosString(memHeader, BYTE_AT_OFFSET(memHeader, 0x11)), 0); // 0x12 Memory Type node_att_set(deviceNode, _T("Type"), SAFE_INDEX(MEM_TYPE, BYTE_AT_OFFSET(memHeader, 0x012)), 0); // 0x13 Type Detail unicode = NULL; for (i = 0; i < ARRAYSIZE(MEM_TYPE_DETAIL); i++) { if (CHECK_BIT(WORD_AT_OFFSET(memHeader, 0x13), i)) { AppendMultiString(&unicode, MEM_TYPE_DETAIL[i]); } } node_att_set_multi(deviceNode, _T("TypeDetails"), unicode, 0); LocalFree(unicode); //v 2.3+ if (2 < smbios->SMBIOSMajorVersion || (2 == smbios->SMBIOSMajorVersion && 3 <= smbios->SMBIOSMinorVersion)) { // 0x15 Speed Mhz swprintf(buffer, _T("%u"), WORD_AT_OFFSET(memHeader, 0x15)); node_att_set(deviceNode, _T("SpeedMhz"), buffer, NAFLG_FMT_NUMERIC); // 0x17 Manufacturer node_att_set(deviceNode, _T("Manufacturer"), GetSmbiosString(memHeader, BYTE_AT_OFFSET(memHeader, 0x17)), 0); // 0x18 Serial Number node_att_set(deviceNode, _T("SerialNumber"), GetSmbiosString(memHeader, BYTE_AT_OFFSET(memHeader, 0x18)), 0); // 0x19 Asset Tag node_att_set(deviceNode, _T("AssetTag"), GetSmbiosString(memHeader, BYTE_AT_OFFSET(memHeader, 0x19)), 0); // 0x1A Part Number node_att_set(deviceNode, _T("PartNumber"), GetSmbiosString(memHeader, BYTE_AT_OFFSET(memHeader, 0x1A)), 0); } } // Total array size totalSystemMb += totalArrayMb; swprintf(buffer, _T("%llu"), totalArrayMb); node_att_set(node, _T("TotalInstalledMb"), buffer, NAFLG_FMT_MBYTES); } // Total system size swprintf(buffer, _T("%llu"), totalSystemMb); node_att_set(parentNode, _T("TotalInstalledMb"), buffer, NAFLG_FMT_MBYTES); return parentNode; }