mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
547 lines
15 KiB
C
547 lines
15 KiB
C
/** @file
|
|
Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved.
|
|
|
|
All rights reserved.
|
|
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
**/
|
|
|
|
#include <Uefi.h>
|
|
|
|
#include <Protocol/PciRootBridgeIo.h>
|
|
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/OcCpuLib.h>
|
|
#include <Library/OcMiscLib.h>
|
|
#include <Library/OcSmbiosLib.h>
|
|
#include <Library/PrintLib.h>
|
|
#include <Library/UefiLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
|
|
|
#include "SmbiosInternal.h"
|
|
#include "DebugSmbios.h"
|
|
|
|
EFI_STATUS
|
|
SmbiosExtendTable (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN UINT32 Size
|
|
)
|
|
{
|
|
UINT32 TableSize;
|
|
UINT32 RequestedSize;
|
|
UINT8 *NewTable;
|
|
|
|
//
|
|
// Always requrest 2 more bytes, so that the table can be terminated.
|
|
//
|
|
Size += SMBIOS_STRUCTURE_TERMINATOR_SIZE;
|
|
|
|
if (Table->Table == NULL) {
|
|
TableSize = 0;
|
|
} else {
|
|
TableSize = (UINT32)((UINT8 *)Table->CurrentStrPtr - Table->Table);
|
|
}
|
|
|
|
//
|
|
// We are not allowed to allocate more than we can write.
|
|
//
|
|
RequestedSize = TableSize + Size;
|
|
if (RequestedSize > SMBIOS_TABLE_MAX_LENGTH) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// Skip reallocation if region fits.
|
|
//
|
|
if (RequestedSize <= Table->AllocatedTableSize) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
RequestedSize = ALIGN_VALUE (RequestedSize, EFI_PAGE_SIZE);
|
|
if (RequestedSize > ALIGN_VALUE (SMBIOS_TABLE_MAX_LENGTH, EFI_PAGE_SIZE)) {
|
|
RequestedSize = ALIGN_VALUE (SMBIOS_TABLE_MAX_LENGTH, EFI_PAGE_SIZE);
|
|
}
|
|
|
|
NewTable = ReallocatePool (TableSize, RequestedSize, Table->Table);
|
|
if (NewTable == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// Guarantee zero fill for the table.
|
|
//
|
|
ZeroMem (NewTable + TableSize, RequestedSize - TableSize);
|
|
|
|
Table->CurrentPtr.Raw = NewTable + (Table->CurrentPtr.Raw - Table->Table);
|
|
Table->CurrentStrPtr = (CHAR8 *)NewTable + TableSize;
|
|
Table->Table = NewTable;
|
|
Table->AllocatedTableSize = RequestedSize;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
UINT8
|
|
SmbiosOverrideString (
|
|
IN OC_SMBIOS_TABLE *Table,
|
|
IN CONST CHAR8 *Override OPTIONAL,
|
|
IN UINT8 *Index
|
|
)
|
|
{
|
|
UINT32 Length;
|
|
|
|
//
|
|
// No override.
|
|
//
|
|
if (Override == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
Length = (UINT32)AsciiStrLen (Override);
|
|
|
|
//
|
|
// Truncate to fit but do not error.
|
|
//
|
|
if (Length > SMBIOS_STRING_MAX_LENGTH) {
|
|
Length = SMBIOS_STRING_MAX_LENGTH;
|
|
DEBUG ((DEBUG_INFO, "OCMB: SMBIOS truncating '%a' to %u bytes\n", Override, Length));
|
|
}
|
|
|
|
while (Length > 0 && Override[Length - 1] == ' ') {
|
|
Length--;
|
|
}
|
|
|
|
if (Length == 0) {
|
|
return 0;
|
|
}
|
|
|
|
if (EFI_ERROR (SmbiosExtendTable (Table, Length + 1))) {
|
|
DEBUG ((DEBUG_WARN, "OCSMB: SMBIOS failed to write '%a' with %u byte extension\n", Override, Length + 1));
|
|
return 0;
|
|
}
|
|
|
|
return SmbiosSetString (&Table->CurrentStrPtr, Override, Length, Index);
|
|
}
|
|
|
|
STATIC
|
|
EFI_STATUS
|
|
SmbiosAssignStructHandle (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN UINT32 Type,
|
|
IN UINT16 Index
|
|
)
|
|
{
|
|
//
|
|
// Support select tables to have more than 1 entry.
|
|
//
|
|
if ( (Type == SMBIOS_TYPE_PROCESSOR_INFORMATION)
|
|
|| (Type == SMBIOS_TYPE_CACHE_INFORMATION)
|
|
|| (Type == SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION)
|
|
|| (Type == SMBIOS_TYPE_SYSTEM_SLOTS)
|
|
|| (Type == SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY)
|
|
|| (Type == SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS)
|
|
|| (Type == SMBIOS_TYPE_MEMORY_DEVICE)
|
|
|| (Type == SMBIOS_TYPE_MEMORY_DEVICE_MAPPED_ADDRESS))
|
|
{
|
|
Table->CurrentPtr.Standard.Hdr->Handle = Table->Handle++;
|
|
return EFI_SUCCESS;
|
|
} else if (Index != 1) {
|
|
ASSERT (FALSE);
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
switch (Type) {
|
|
case SMBIOS_TYPE_BIOS_INFORMATION:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosBiosInformationHandle;
|
|
break;
|
|
case SMBIOS_TYPE_SYSTEM_INFORMATION:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosSystemInformationHandle;
|
|
break;
|
|
case SMBIOS_TYPE_BASEBOARD_INFORMATION:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosBaseboardInformationHandle;
|
|
break;
|
|
case SMBIOS_TYPE_SYSTEM_ENCLOSURE:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosSystemEnclosureHandle;
|
|
break;
|
|
case SMBIOS_TYPE_MEMORY_CONTROLLER_INFORMATION:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosMemoryControllerInformationHandle;
|
|
break;
|
|
case SMBIOS_TYPE_MEMORY_MODULE_INFORMATON:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosMemoryModuleInformatonHandle;
|
|
break;
|
|
case SMBIOS_TYPE_ONBOARD_DEVICE_INFORMATION:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosOnboardDeviceInformationHandle;
|
|
break;
|
|
case SMBIOS_TYPE_OEM_STRINGS:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosOemStringsHandle;
|
|
break;
|
|
case SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosSystemConfigurationOptionsHandle;
|
|
break;
|
|
case SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosBiosLanguageInformationHandle;
|
|
break;
|
|
case SMBIOS_TYPE_GROUP_ASSOCIATIONS:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosGroupAssociationsHandle;
|
|
break;
|
|
case SMBIOS_TYPE_SYSTEM_EVENT_LOG:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosSystemEventLogHandle;
|
|
break;
|
|
case SMBIOS_TYPE_32BIT_MEMORY_ERROR_INFORMATION:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbios32BitMemoryErrorInformationHandle;
|
|
break;
|
|
case SMBIOS_TYPE_BUILT_IN_POINTING_DEVICE:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosBuiltInPointingDeviceHandle;
|
|
break;
|
|
case SMBIOS_TYPE_PORTABLE_BATTERY:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosPortableBatteryHandle;
|
|
break;
|
|
case SMBIOS_TYPE_SYSTEM_RESET:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosSystemResetHandle;
|
|
break;
|
|
case SMBIOS_TYPE_HARDWARE_SECURITY:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosHardwareSecurityHandle;
|
|
break;
|
|
case SMBIOS_TYPE_SYSTEM_POWER_CONTROLS:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosSystemPowerControlsHandle;
|
|
break;
|
|
case SMBIOS_TYPE_VOLTAGE_PROBE:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosVoltageProbeHandle;
|
|
break;
|
|
case SMBIOS_TYPE_COOLING_DEVICE:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosCoolingDeviceHandle;
|
|
break;
|
|
case SMBIOS_TYPE_TEMPERATURE_PROBE:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosTemperatureProbeHandle;
|
|
break;
|
|
case SMBIOS_TYPE_ELECTRICAL_CURRENT_PROBE:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosElectricalCurrentProbeHandle;
|
|
break;
|
|
case SMBIOS_TYPE_OUT_OF_BAND_REMOTE_ACCESS:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosOutOfBandRemoteAccessHandle;
|
|
break;
|
|
case SMBIOS_TYPE_BOOT_INTEGRITY_SERVICE:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosBootIntegrityServiceHandle;
|
|
break;
|
|
case SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosSystemBootInformationHandle;
|
|
break;
|
|
case SMBIOS_TYPE_64BIT_MEMORY_ERROR_INFORMATION:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbios64BitMemoryErrorInformationHandle;
|
|
break;
|
|
case SMBIOS_TYPE_MANAGEMENT_DEVICE:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosManagementDeviceHandle;
|
|
break;
|
|
case SMBIOS_TYPE_MANAGEMENT_DEVICE_COMPONENT:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosManagementDeviceComponentHandle;
|
|
break;
|
|
case SMBIOS_TYPE_MANAGEMENT_DEVICE_THRESHOLD_DATA:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosManagementDeviceThresholdDataHandle;
|
|
break;
|
|
case SMBIOS_TYPE_MEMORY_CHANNEL:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosMemoryChannelHandle;
|
|
break;
|
|
case SMBIOS_TYPE_IPMI_DEVICE_INFORMATION:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosIpmiDeviceInformationHandle;
|
|
break;
|
|
case SMBIOS_TYPE_SYSTEM_POWER_SUPPLY:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosSystemPowerSupplyHandle;
|
|
break;
|
|
case SMBIOS_TYPE_ADDITIONAL_INFORMATION:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosAdditionalInformationHandle;
|
|
break;
|
|
case SMBIOS_TYPE_ONBOARD_DEVICES_EXTENDED_INFORMATION:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosOnboardDevicesExtendedInformationHandle;
|
|
break;
|
|
case SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosManagementControllerHostInterfaceHandle;
|
|
break;
|
|
case SMBIOS_TYPE_TPM_DEVICE:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosTpmDeviceHandle;
|
|
break;
|
|
case SMBIOS_TYPE_INACTIVE:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosInactiveHandle;
|
|
break;
|
|
case SMBIOS_TYPE_END_OF_TABLE:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcSmbiosEndOfTableHandle;
|
|
break;
|
|
case APPLE_SMBIOS_TYPE_FIRMWARE_INFORMATION:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcAppleSmbiosFirmwareInformationHandle;
|
|
break;
|
|
case APPLE_SMBIOS_TYPE_MEMORY_SPD_DATA:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcAppleSmbiosMemorySpdDataHandle;
|
|
break;
|
|
case APPLE_SMBIOS_TYPE_PROCESSOR_TYPE:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcAppleSmbiosProcessorTypeHandle;
|
|
break;
|
|
case APPLE_SMBIOS_TYPE_PROCESSOR_BUS_SPEED:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcAppleSmbiosProcessorBusSpeedHandle;
|
|
break;
|
|
case APPLE_SMBIOS_TYPE_PLATFORM_FEATURE:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcAppleSmbiosPlatformFeatureHandle;
|
|
break;
|
|
case APPLE_SMBIOS_TYPE_SMC_INFORMATION:
|
|
Table->CurrentPtr.Standard.Hdr->Handle = OcAppleSmbiosSmcInformationHandle;
|
|
break;
|
|
default:
|
|
ASSERT (FALSE);
|
|
Table->CurrentPtr.Standard.Hdr->Handle = Table->Handle++;
|
|
break;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
SmbiosInitialiseStruct (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN SMBIOS_TYPE Type,
|
|
IN UINT8 MinLength,
|
|
IN UINT16 Index
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = SmbiosExtendTable (Table, MinLength);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_WARN, "OCSMB: Failed to extend SMBIOS for table %u - %r\n", Type, Status));
|
|
return Status;
|
|
}
|
|
|
|
Table->CurrentPtr.Standard.Hdr->Type = Type;
|
|
Table->CurrentPtr.Standard.Hdr->Length = MinLength;
|
|
Status = SmbiosAssignStructHandle (Table, Type, Index);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Table->CurrentStrPtr = (CHAR8 *)Table->CurrentPtr.Standard.Raw + MinLength;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
VOID
|
|
SmbiosFinaliseStruct (
|
|
IN OUT OC_SMBIOS_TABLE *Table
|
|
)
|
|
{
|
|
DEBUG_CODE_BEGIN ();
|
|
SmbiosDebugAnyStructure (Table->CurrentPtr);
|
|
DEBUG_CODE_END ();
|
|
|
|
if (Table->CurrentPtr.Standard.Hdr->Length > Table->MaxStructureSize) {
|
|
Table->MaxStructureSize = Table->CurrentPtr.Standard.Hdr->Length;
|
|
}
|
|
|
|
Table->CurrentPtr.Raw += Table->CurrentPtr.Standard.Hdr->Length;
|
|
|
|
Table->NumberOfStructures++;
|
|
|
|
//
|
|
// SMBIOS spec requires 2 terminator bytes after structures without strings and 1 byte otherwise.
|
|
// We allocate 2 extra bytes (SMBIOS_STRUCTURE_TERMINATOR_SIZE), and end up using one or two here.
|
|
//
|
|
if (Table->CurrentStrPtr != (CHAR8 *)Table->CurrentPtr.Raw) {
|
|
Table->CurrentStrPtr++;
|
|
Table->CurrentPtr.Raw = (UINT8 *)Table->CurrentStrPtr;
|
|
} else {
|
|
Table->CurrentStrPtr += 2;
|
|
Table->CurrentPtr.Raw += 2;
|
|
}
|
|
}
|
|
|
|
CHAR8 *
|
|
SmbiosGetString (
|
|
IN APPLE_SMBIOS_STRUCTURE_POINTER SmbiosTable,
|
|
IN SMBIOS_TABLE_STRING String
|
|
)
|
|
{
|
|
UINT8 *Walker;
|
|
UINT8 Index;
|
|
|
|
if (String == 0) {
|
|
return NULL;
|
|
}
|
|
|
|
Walker = SmbiosTable.Raw + SmbiosTable.Standard.Hdr->Length;
|
|
|
|
for (Index = 1; Index != String; Index++) {
|
|
while (*Walker != 0) {
|
|
Walker++;
|
|
}
|
|
|
|
Walker++;
|
|
|
|
//
|
|
// Double NULL termination means end of table.
|
|
//
|
|
if (*Walker == 0) {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
return (CHAR8 *)Walker;
|
|
}
|
|
|
|
UINT8
|
|
SmbiosSetString (
|
|
IN OUT CHAR8 **Buffer,
|
|
IN CONST CHAR8 *String,
|
|
IN UINT32 Length,
|
|
IN OUT UINT8 *Index
|
|
)
|
|
{
|
|
ASSERT (Buffer != NULL);
|
|
ASSERT (String != NULL);
|
|
ASSERT (Index != NULL);
|
|
ASSERT (Length > 0);
|
|
|
|
CopyMem (*Buffer, String, Length);
|
|
*Buffer += Length + 1;
|
|
(*Index)++;
|
|
|
|
return *Index;
|
|
}
|
|
|
|
UINT32
|
|
SmbiosGetStructureLength (
|
|
IN APPLE_SMBIOS_STRUCTURE_POINTER SmbiosTable,
|
|
IN UINT32 SmbiosTableSize
|
|
)
|
|
{
|
|
UINT32 Length;
|
|
UINT8 *Walker;
|
|
|
|
Length = SmbiosTable.Standard.Hdr->Length;
|
|
if (Length > SmbiosTableSize) {
|
|
return 0;
|
|
}
|
|
|
|
SmbiosTable.Raw += Length;
|
|
SmbiosTableSize -= Length;
|
|
Walker = SmbiosTable.Raw;
|
|
while (SmbiosTableSize >= SMBIOS_STRUCTURE_TERMINATOR_SIZE) {
|
|
if ((Walker[0] == 0) && (Walker[1] == 0)) {
|
|
return Length + (UINT32)(Walker - SmbiosTable.Raw) + SMBIOS_STRUCTURE_TERMINATOR_SIZE;
|
|
}
|
|
|
|
Walker++;
|
|
SmbiosTableSize--;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
APPLE_SMBIOS_STRUCTURE_POINTER
|
|
SmbiosGetStructureOfType (
|
|
IN APPLE_SMBIOS_STRUCTURE_POINTER SmbiosTable,
|
|
IN UINT32 SmbiosTableSize,
|
|
IN SMBIOS_TYPE Type,
|
|
IN UINT16 Index
|
|
)
|
|
{
|
|
UINT16 SmbiosTypeIndex;
|
|
UINT32 Length;
|
|
|
|
SmbiosTypeIndex = 1;
|
|
|
|
while (SmbiosTableSize >= sizeof (SMBIOS_STRUCTURE)) {
|
|
//
|
|
// Perform basic size sanity check.
|
|
//
|
|
Length = SmbiosGetStructureLength (SmbiosTable, SmbiosTableSize);
|
|
if (Length == 0) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// We found the right table.
|
|
//
|
|
if ((SmbiosTypeIndex == Index) && (SmbiosTable.Standard.Hdr->Type == Type)) {
|
|
return SmbiosTable;
|
|
}
|
|
|
|
//
|
|
// Abort on EOT.
|
|
//
|
|
if (SmbiosTable.Standard.Hdr->Type == SMBIOS_TYPE_END_OF_TABLE) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Skip extra tables of this type until we reach requested number.
|
|
//
|
|
if (SmbiosTable.Standard.Hdr->Type == Type) {
|
|
SmbiosTypeIndex++;
|
|
//
|
|
// Unsigned wraparound, we have more than MAX_UINT16 tables of this kind.
|
|
//
|
|
if (SmbiosTypeIndex == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
SmbiosTable.Raw += Length;
|
|
SmbiosTableSize -= Length;
|
|
}
|
|
|
|
SmbiosTable.Raw = NULL;
|
|
return SmbiosTable;
|
|
}
|
|
|
|
UINT16
|
|
SmbiosGetStructureCount (
|
|
IN APPLE_SMBIOS_STRUCTURE_POINTER SmbiosTable,
|
|
IN UINT32 SmbiosTableSize,
|
|
IN SMBIOS_TYPE Type
|
|
)
|
|
{
|
|
UINT16 Count;
|
|
UINT32 Length;
|
|
|
|
Count = 0;
|
|
|
|
while (SmbiosTableSize >= sizeof (SMBIOS_STRUCTURE)) {
|
|
//
|
|
// Perform basic size sanity check.
|
|
//
|
|
Length = SmbiosGetStructureLength (SmbiosTable, SmbiosTableSize);
|
|
if (Length == 0) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// We found the right table.
|
|
//
|
|
if (SmbiosTable.Standard.Hdr->Type == Type) {
|
|
Count++;
|
|
//
|
|
// Unsigned wraparound, we have more than MAX_UINT16 tables of this kind.
|
|
//
|
|
if (Count == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Abort on EOT.
|
|
//
|
|
if (SmbiosTable.Standard.Hdr->Type == SMBIOS_TYPE_END_OF_TABLE) {
|
|
break;
|
|
}
|
|
|
|
SmbiosTable.Raw += Length;
|
|
SmbiosTableSize -= Length;
|
|
}
|
|
|
|
return Count;
|
|
}
|