audk/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c

647 lines
23 KiB
C

/** @file
This driver measures SMBIOS table to TPM.
Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
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 <PiDxe.h>
#include <Protocol/Smbios.h>
#include <IndustryStandard/SmBios.h>
#include <IndustryStandard/UefiTcgPlatform.h>
#include <Guid/EventGroup.h>
#include <Guid/SmBios.h>
#include <Library/DebugLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/TpmMeasurementLib.h>
#define FIELD_SIZE_OF(TYPE, Field) ((UINTN)sizeof(((TYPE *)0)->Field))
typedef struct {
UINT8 Type;
UINTN Offset;
UINTN Size;
UINT32 Flags;
} SMBIOS_FILTER_TABLE;
#define SMBIOS_FILTER_TABLE_FLAG_IS_STRING BIT0
typedef struct {
UINT8 Type;
SMBIOS_FILTER_TABLE *Filter; // NULL means all fields
UINTN FilterCount;
} SMBIOS_FILTER_STRUCT;
//
// Platform Specific Policy
//
SMBIOS_FILTER_TABLE mSmbiosFilterType1BlackList[] = {
{0x01, OFFSET_OF(SMBIOS_TABLE_TYPE1, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE1, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},
{0x01, OFFSET_OF(SMBIOS_TABLE_TYPE1, Uuid), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE1, Uuid), 0},
{0x01, OFFSET_OF(SMBIOS_TABLE_TYPE1, WakeUpType), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE1, WakeUpType), 0},
};
SMBIOS_FILTER_TABLE mSmbiosFilterType2BlackList[] = {
{0x02, OFFSET_OF(SMBIOS_TABLE_TYPE2, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE2, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},
{0x02, OFFSET_OF(SMBIOS_TABLE_TYPE2, LocationInChassis), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE2, LocationInChassis), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},
};
SMBIOS_FILTER_TABLE mSmbiosFilterType3BlackList[] = {
{0x03, OFFSET_OF(SMBIOS_TABLE_TYPE3, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE3, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},
{0x03, OFFSET_OF(SMBIOS_TABLE_TYPE3, AssetTag), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE3, AssetTag), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},
};
SMBIOS_FILTER_TABLE mSmbiosFilterType4BlackList[] = {
{0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},
{0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, AssetTag), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, AssetTag), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},
{0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, PartNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, PartNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},
{0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, CoreCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, CoreCount), 0},
{0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount), 0},
{0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, ThreadCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, ThreadCount), 0},
{0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, CoreCount2), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, CoreCount2), 0},
{0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount2), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount2), 0},
{0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, ThreadCount2), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, ThreadCount2), 0},
};
SMBIOS_FILTER_TABLE mSmbiosFilterType17BlackList[] = {
{0x11, OFFSET_OF(SMBIOS_TABLE_TYPE17, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE17, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},
{0x11, OFFSET_OF(SMBIOS_TABLE_TYPE17, AssetTag), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE17, AssetTag), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},
{0x11, OFFSET_OF(SMBIOS_TABLE_TYPE17, PartNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE17, PartNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},
};
SMBIOS_FILTER_TABLE mSmbiosFilterType22BlackList[] = {
{0x16, OFFSET_OF(SMBIOS_TABLE_TYPE22, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE22, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},
{0x16, OFFSET_OF(SMBIOS_TABLE_TYPE22, SBDSSerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE22, SBDSSerialNumber), 0},
{0x16, OFFSET_OF(SMBIOS_TABLE_TYPE22, SBDSManufactureDate), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE22, SBDSManufactureDate), 0},
};
SMBIOS_FILTER_TABLE mSmbiosFilterType23BlackList[] = {
{0x17, OFFSET_OF(SMBIOS_TABLE_TYPE23, ResetCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE23, ResetCount), 0},
};
SMBIOS_FILTER_TABLE mSmbiosFilterType27BlackList[] = {
{0x1B, OFFSET_OF(SMBIOS_TABLE_TYPE27, NominalSpeed), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE27, NominalSpeed), 0},
};
SMBIOS_FILTER_TABLE mSmbiosFilterType39BlackList[] = {
{0x27, OFFSET_OF(SMBIOS_TABLE_TYPE39, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE39, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},
{0x27, OFFSET_OF(SMBIOS_TABLE_TYPE39, AssetTagNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE39, AssetTagNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},
{0x27, OFFSET_OF(SMBIOS_TABLE_TYPE39, ModelPartNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE39, ModelPartNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},
};
SMBIOS_FILTER_STRUCT mSmbiosFilterStandardTableBlackList[] = {
{0x01, mSmbiosFilterType1BlackList, sizeof(mSmbiosFilterType1BlackList)/sizeof(mSmbiosFilterType1BlackList[0])},
{0x02, mSmbiosFilterType2BlackList, sizeof(mSmbiosFilterType2BlackList)/sizeof(mSmbiosFilterType2BlackList[0])},
{0x03, mSmbiosFilterType3BlackList, sizeof(mSmbiosFilterType3BlackList)/sizeof(mSmbiosFilterType3BlackList[0])},
{0x04, mSmbiosFilterType4BlackList, sizeof(mSmbiosFilterType4BlackList)/sizeof(mSmbiosFilterType4BlackList[0])},
{0x0B, NULL, 0},
{0x0F, NULL, 0},
{0x11, mSmbiosFilterType17BlackList, sizeof(mSmbiosFilterType17BlackList)/sizeof(mSmbiosFilterType17BlackList[0])},
{0x12, NULL, 0},
{0x16, mSmbiosFilterType22BlackList, sizeof(mSmbiosFilterType22BlackList)/sizeof(mSmbiosFilterType22BlackList[0])},
{0x17, mSmbiosFilterType23BlackList, sizeof(mSmbiosFilterType23BlackList)/sizeof(mSmbiosFilterType23BlackList[0])},
{0x1B, mSmbiosFilterType27BlackList, sizeof(mSmbiosFilterType27BlackList)/sizeof(mSmbiosFilterType27BlackList[0])},
{0x1F, NULL, 0},
{0x21, NULL, 0},
{0x27, mSmbiosFilterType39BlackList, sizeof(mSmbiosFilterType39BlackList)/sizeof(mSmbiosFilterType39BlackList[0])},
};
EFI_SMBIOS_PROTOCOL *mSmbios;
UINTN mMaxLen;
/**
This function dump raw data.
@param Data raw data
@param Size raw data size
**/
VOID
InternalDumpData (
IN UINT8 *Data,
IN UINTN Size
)
{
UINTN Index;
for (Index = 0; Index < Size; Index++) {
DEBUG ((EFI_D_VERBOSE, "%02x", (UINTN)Data[Index]));
}
}
/**
This function dump raw data with colume format.
@param Data raw data
@param Size raw data size
**/
VOID
InternalDumpHex (
IN UINT8 *Data,
IN UINTN Size
)
{
UINTN Index;
UINTN Count;
UINTN Left;
#define COLUME_SIZE (16 * 2)
Count = Size / COLUME_SIZE;
Left = Size % COLUME_SIZE;
for (Index = 0; Index < Count; Index++) {
DEBUG ((EFI_D_VERBOSE, "%04x: ", Index * COLUME_SIZE));
InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);
DEBUG ((EFI_D_VERBOSE, "\n"));
}
if (Left != 0) {
DEBUG ((EFI_D_VERBOSE, "%04x: ", Index * COLUME_SIZE));
InternalDumpData (Data + Index * COLUME_SIZE, Left);
DEBUG ((EFI_D_VERBOSE, "\n"));
}
}
/**
This function get filter structure by SMBIOS type.
@param Type SMBIOS type
**/
SMBIOS_FILTER_STRUCT *
GetFilterStructByType (
IN UINT8 Type
)
{
UINTN Index;
for (Index = 0; Index < sizeof(mSmbiosFilterStandardTableBlackList)/sizeof(mSmbiosFilterStandardTableBlackList[0]); Index++) {
if (mSmbiosFilterStandardTableBlackList[Index].Type == Type) {
return &mSmbiosFilterStandardTableBlackList[Index];
}
}
return NULL;
}
/**
This function get SMBIOS string in SMBIOS table.
@param Head SMBIOS table head
@param StringId SMBIOS string ID
@param StringLen length of SMBIOS string
@return SMBIOS string data
**/
CHAR8 *
GetSmbiosStringById (
IN EFI_SMBIOS_TABLE_HEADER *Head,
IN SMBIOS_TABLE_STRING StringId,
OUT UINTN *StringLen
)
{
UINTN Size;
UINTN StrLen;
CHAR8 *CharInStr;
UINTN StringsNumber;
CHAR8 *String;
CharInStr = (CHAR8 *)Head + Head->Length;
Size = Head->Length;
StringsNumber = 0;
StrLen = 0;
//
// look for the two consecutive zeros, check the string limit by the way.
//
String = NULL;
while (*CharInStr != 0 || *(CharInStr+1) != 0) {
if (*CharInStr == 0) {
Size += 1;
CharInStr++;
}
String = CharInStr;
for (StrLen = 0 ; StrLen < mMaxLen; StrLen++) {
if (*(CharInStr+StrLen) == 0) {
break;
}
}
*StringLen = StrLen;
if (StrLen == mMaxLen) {
return NULL;
}
//
// forward the pointer
//
CharInStr += StrLen;
Size += StrLen;
StringsNumber += 1;
if (StringsNumber == StringId) {
break;
}
}
return String;
}
/**
This function update SMBIOS table based on policy.
@param TableEntry SMBIOS table
@param TableEntrySize SMBIOS table size
**/
VOID
FilterSmbiosEntry (
IN OUT VOID *TableEntry,
IN UINTN TableEntrySize
)
{
SMBIOS_FILTER_STRUCT *FilterStruct;
SMBIOS_FILTER_TABLE *Filter;
UINTN Index;
SMBIOS_TABLE_STRING StringId;
CHAR8 *String;
UINTN StringLen;
DEBUG ((EFI_D_INFO, "Smbios Table (Type - %d):\n", ((SMBIOS_STRUCTURE *)TableEntry)->Type));
DEBUG_CODE (InternalDumpHex (TableEntry, TableEntrySize););
//
// Skip measurement for OEM types.
//
if (((SMBIOS_STRUCTURE *)TableEntry)->Type >= SMBIOS_OEM_BEGIN) {
// zero all table fields, except header
ZeroMem ((UINT8 *)TableEntry + sizeof(SMBIOS_STRUCTURE), TableEntrySize - sizeof(SMBIOS_STRUCTURE));
} else {
FilterStruct = GetFilterStructByType (((SMBIOS_STRUCTURE *)TableEntry)->Type);
if (FilterStruct != NULL) {
if (FilterStruct->Filter == NULL || FilterStruct->FilterCount == 0) {
// zero all table fields, except header
ZeroMem ((UINT8 *)TableEntry + sizeof(SMBIOS_STRUCTURE), TableEntrySize - sizeof(SMBIOS_STRUCTURE));
} else {
Filter = FilterStruct->Filter;
for (Index = 0; Index < FilterStruct->FilterCount; Index++) {
if (((SMBIOS_STRUCTURE *) TableEntry)->Length >= (Filter[Index].Offset + Filter[Index].Size)) {
//
// The field is present in the SMBIOS entry.
//
if ((Filter[Index].Flags & SMBIOS_FILTER_TABLE_FLAG_IS_STRING) != 0) {
CopyMem (&StringId, (UINT8 *)TableEntry + Filter[Index].Offset, sizeof(StringId));
if (StringId != 0) {
// set ' ' for string field
String = GetSmbiosStringById (TableEntry, StringId, &StringLen);
ASSERT (String != NULL);
//DEBUG ((EFI_D_INFO,"StrId(0x%x)-%a(%d)\n", StringId, String, StringLen));
SetMem (String, StringLen, ' ');
}
}
// zero non-string field
ZeroMem ((UINT8 *)TableEntry + Filter[Index].Offset, Filter[Index].Size);
}
}
}
}
}
DEBUG ((EFI_D_INFO, "Filter Smbios Table (Type - %d):\n", ((SMBIOS_STRUCTURE *)TableEntry)->Type));
DEBUG_CODE (InternalDumpHex (TableEntry, TableEntrySize););
}
/**
Get the full size of SMBIOS structure including optional strings that follow the formatted structure.
@param Head Pointer to the beginning of SMBIOS structure.
@param NumberOfStrings The returned number of optional strings that follow the formatted structure.
@return Size The returned size.
**/
UINTN
GetSmbiosStructureSize (
IN EFI_SMBIOS_TABLE_HEADER *Head,
OUT UINTN *NumberOfStrings
)
{
UINTN Size;
UINTN StrLen;
CHAR8 *CharInStr;
UINTN StringsNumber;
CharInStr = (CHAR8 *)Head + Head->Length;
Size = Head->Length;
StringsNumber = 0;
StrLen = 0;
//
// look for the two consecutive zeros, check the string limit by the way.
//
while (*CharInStr != 0 || *(CharInStr+1) != 0) {
if (*CharInStr == 0) {
Size += 1;
CharInStr++;
}
for (StrLen = 0 ; StrLen < mMaxLen; StrLen++) {
if (*(CharInStr+StrLen) == 0) {
break;
}
}
if (StrLen == mMaxLen) {
return 0;
}
//
// forward the pointer
//
CharInStr += StrLen;
Size += StrLen;
StringsNumber += 1;
}
//
// count ending two zeros.
//
Size += 2;
if (NumberOfStrings != NULL) {
*NumberOfStrings = StringsNumber;
}
return Size;
}
/**
This function returns full SMBIOS table length.
@param TableAddress SMBIOS table based address
@param TableMaximumSize Maximum size of SMBIOS table
@return SMBIOS table length
**/
UINTN
GetSmbiosTableLength (
IN VOID *TableAddress,
IN UINTN TableMaximumSize
)
{
VOID *TableEntry;
VOID *TableAddressEnd;
UINTN TableEntryLength;
TableAddressEnd = (VOID *)((UINTN)TableAddress + TableMaximumSize);
TableEntry = TableAddress;
while (TableEntry < TableAddressEnd) {
TableEntryLength = GetSmbiosStructureSize (TableEntry, NULL);
if (TableEntryLength == 0) {
break;
}
if (((SMBIOS_STRUCTURE *)TableEntry)->Type == 127) {
TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);
break;
}
TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);
}
return ((UINTN)TableEntry - (UINTN)TableAddress);
}
/**
This function updatess full SMBIOS table length.
@param TableAddress SMBIOS table based address
@param TableLength SMBIOS table length
**/
VOID
FilterSmbiosTable (
IN OUT VOID *TableAddress,
IN UINTN TableLength
)
{
VOID *TableAddressEnd;
VOID *TableEntry;
UINTN TableEntryLength;
TableEntry = TableAddress;
TableAddressEnd = (VOID *)((UINTN)TableAddress + TableLength);
while ((UINTN)TableEntry < (UINTN)TableAddressEnd) {
TableEntryLength = GetSmbiosStructureSize (TableEntry, NULL);
if (TableEntryLength == 0) {
break;
}
FilterSmbiosEntry (TableEntry, TableEntryLength);
TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);
}
}
/**
Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1].
@param[in] Event Event whose notification function is being invoked.
@param[in] Context Pointer to the notification function's context.
**/
VOID
EFIAPI
MeasureSmbiosTable (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
EFI_HANDOFF_TABLE_POINTERS HandoffTables;
SMBIOS_TABLE_ENTRY_POINT *SmbiosTable;
SMBIOS_TABLE_3_0_ENTRY_POINT *Smbios3Table;
VOID *SmbiosTableAddress;
VOID *TableAddress;
UINTN TableLength;
SmbiosTable = NULL;
Smbios3Table = NULL;
SmbiosTableAddress = NULL;
TableLength = 0;
if (mSmbios->MajorVersion >= 3) {
Status = EfiGetSystemConfigurationTable (
&gEfiSmbios3TableGuid,
(VOID **) &Smbios3Table
);
if (!EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, "Smbios3Table:\n"));
DEBUG ((EFI_D_INFO, " AnchorString - '%c%c%c%c%c'\n",
Smbios3Table->AnchorString[0],
Smbios3Table->AnchorString[1],
Smbios3Table->AnchorString[2],
Smbios3Table->AnchorString[3],
Smbios3Table->AnchorString[4]
));
DEBUG ((EFI_D_INFO, " EntryPointStructureChecksum - 0x%02x\n", Smbios3Table->EntryPointStructureChecksum));
DEBUG ((EFI_D_INFO, " EntryPointLength - 0x%02x\n", Smbios3Table->EntryPointLength));
DEBUG ((EFI_D_INFO, " MajorVersion - 0x%02x\n", Smbios3Table->MajorVersion));
DEBUG ((EFI_D_INFO, " MinorVersion - 0x%02x\n", Smbios3Table->MinorVersion));
DEBUG ((EFI_D_INFO, " DocRev - 0x%02x\n", Smbios3Table->DocRev));
DEBUG ((EFI_D_INFO, " EntryPointRevision - 0x%02x\n", Smbios3Table->EntryPointRevision));
DEBUG ((EFI_D_INFO, " TableMaximumSize - 0x%08x\n", Smbios3Table->TableMaximumSize));
DEBUG ((EFI_D_INFO, " TableAddress - 0x%016lx\n", Smbios3Table->TableAddress));
}
}
if (Smbios3Table == NULL) {
Status = EfiGetSystemConfigurationTable (
&gEfiSmbiosTableGuid,
(VOID **) &SmbiosTable
);
if (!EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, "SmbiosTable:\n"));
DEBUG ((EFI_D_INFO, " AnchorString - '%c%c%c%c'\n",
SmbiosTable->AnchorString[0],
SmbiosTable->AnchorString[1],
SmbiosTable->AnchorString[2],
SmbiosTable->AnchorString[3]
));
DEBUG ((EFI_D_INFO, " EntryPointStructureChecksum - 0x%02x\n", SmbiosTable->EntryPointStructureChecksum));
DEBUG ((EFI_D_INFO, " EntryPointLength - 0x%02x\n", SmbiosTable->EntryPointLength));
DEBUG ((EFI_D_INFO, " MajorVersion - 0x%02x\n", SmbiosTable->MajorVersion));
DEBUG ((EFI_D_INFO, " MinorVersion - 0x%02x\n", SmbiosTable->MinorVersion));
DEBUG ((EFI_D_INFO, " MaxStructureSize - 0x%08x\n", SmbiosTable->MaxStructureSize));
DEBUG ((EFI_D_INFO, " EntryPointRevision - 0x%02x\n", SmbiosTable->EntryPointRevision));
DEBUG ((EFI_D_INFO, " FormattedArea - '%c%c%c%c%c'\n",
SmbiosTable->FormattedArea[0],
SmbiosTable->FormattedArea[1],
SmbiosTable->FormattedArea[2],
SmbiosTable->FormattedArea[3],
SmbiosTable->FormattedArea[4]
));
DEBUG ((EFI_D_INFO, " IntermediateAnchorString - '%c%c%c%c%c'\n",
SmbiosTable->IntermediateAnchorString[0],
SmbiosTable->IntermediateAnchorString[1],
SmbiosTable->IntermediateAnchorString[2],
SmbiosTable->IntermediateAnchorString[3],
SmbiosTable->IntermediateAnchorString[4]
));
DEBUG ((EFI_D_INFO, " IntermediateChecksum - 0x%02x\n", SmbiosTable->IntermediateChecksum));
DEBUG ((EFI_D_INFO, " TableLength - 0x%04x\n", SmbiosTable->TableLength));
DEBUG ((EFI_D_INFO, " TableAddress - 0x%08x\n", SmbiosTable->TableAddress));
DEBUG ((EFI_D_INFO, " NumberOfSmbiosStructures - 0x%04x\n", SmbiosTable->NumberOfSmbiosStructures));
DEBUG ((EFI_D_INFO, " SmbiosBcdRevision - 0x%02x\n", SmbiosTable->SmbiosBcdRevision));
}
}
if (Smbios3Table != NULL) {
SmbiosTableAddress = (VOID *)(UINTN)Smbios3Table->TableAddress;
TableLength = GetSmbiosTableLength (SmbiosTableAddress, Smbios3Table->TableMaximumSize);
} else if (SmbiosTable != NULL) {
SmbiosTableAddress = (VOID *)(UINTN)SmbiosTable->TableAddress;
TableLength = SmbiosTable->TableLength;
}
if (SmbiosTableAddress != NULL) {
DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTableAddress));
DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", TableLength));
DEBUG_CODE (InternalDumpHex ((UINT8 *)(UINTN)SmbiosTableAddress, TableLength););
TableAddress = AllocateCopyPool ((UINTN)TableLength, (VOID *)(UINTN)SmbiosTableAddress);
if (TableAddress == NULL) {
return ;
}
FilterSmbiosTable (TableAddress, TableLength);
DEBUG ((DEBUG_INFO, "The final Smbios Table starts at: 0x%x\n", TableAddress));
DEBUG ((DEBUG_INFO, "The final Smbios Table size: 0x%x\n", TableLength));
DEBUG_CODE (InternalDumpHex (TableAddress, TableLength););
HandoffTables.NumberOfTables = 1;
if (Smbios3Table != NULL) {
CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gEfiSmbios3TableGuid);
HandoffTables.TableEntry[0].VendorTable = Smbios3Table;
} else {
CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gEfiSmbiosTableGuid);
HandoffTables.TableEntry[0].VendorTable = SmbiosTable;
}
Status = TpmMeasureAndLogData (
1, // PCRIndex
EV_EFI_HANDOFF_TABLES, // EventType
&HandoffTables, // EventLog
sizeof (HandoffTables), // LogLen
TableAddress, // HashData
TableLength // HashDataLen
);
if (EFI_ERROR (Status)) {
return ;
}
}
return ;
}
/**
Driver to produce Smbios measurement.
@param ImageHandle Module's image handle
@param SystemTable Pointer of EFI_SYSTEM_TABLE
@return Status returned from EfiCreateEventReadyToBootEx().
**/
EFI_STATUS
EFIAPI
SmbiosMeasurementDriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_EVENT Event;
Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &mSmbios);
ASSERT_EFI_ERROR (Status);
DEBUG ((DEBUG_INFO, "The Smbios Table Version: %x.%x\n", mSmbios->MajorVersion, mSmbios->MinorVersion));
if (mSmbios->MajorVersion < 2 || (mSmbios->MajorVersion == 2 && mSmbios->MinorVersion < 7)){
mMaxLen = SMBIOS_STRING_MAX_LENGTH;
} else if (mSmbios->MajorVersion < 3) {
//
// Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string.
// However, the length of the entire structure table (including all strings) must be reported
// in the Structure Table Length field of the SMBIOS Structure Table Entry Point,
// which is a WORD field limited to 65,535 bytes.
//
mMaxLen = SMBIOS_TABLE_MAX_LENGTH;
} else {
//
// SMBIOS 3.0 defines the Structure table maximum size as DWORD field limited to 0xFFFFFFFF bytes.
// Locate the end of string as long as possible.
//
mMaxLen = SMBIOS_3_0_TABLE_MAX_LENGTH;
}
//
// Measure Smbios tables
//
Status = EfiCreateEventReadyToBootEx (
TPL_CALLBACK,
MeasureSmbiosTable,
NULL,
&Event
);
return Status;
}