summaryrefslogtreecommitdiff
path: root/EdkCompatibilityPkg
diff options
context:
space:
mode:
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>2009-12-28 05:03:49 +0000
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>2009-12-28 05:03:49 +0000
commit024b10295d8f5fe4d9e5466086d9e26469341323 (patch)
treec840ecb42ad3a41bcc17905726b5cdc5ccecd0e4 /EdkCompatibilityPkg
parent1d7dfebf3862a53e087e08c3e2e82c03ba4f4503 (diff)
downloadedk2-024b10295d8f5fe4d9e5466086d9e26469341323.zip
edk2-024b10295d8f5fe4d9e5466086d9e26469341323.tar.gz
edk2-024b10295d8f5fe4d9e5466086d9e26469341323.tar.bz2
Add a thunk driver to translate framework DataHub's smbios related record to PI SMBIOS's record via EFI_SMBIOS_PROTOCOL defined in PI 1.2 specification.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9619 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkCompatibilityPkg')
-rw-r--r--EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/ConvLib.c786
-rw-r--r--EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/ConvTable.c1235
-rw-r--r--EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/DataHubSmBiosRecordsOnPiSmBiosThunk.inf75
-rw-r--r--EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/MemoryConv.c1089
-rw-r--r--EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/MiscConv.c2444
-rw-r--r--EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/ProcessorConv.c164
-rw-r--r--EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/Thunk.c160
-rw-r--r--EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/Thunk.h842
-rw-r--r--EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/Translate.c591
-rw-r--r--EdkCompatibilityPkg/EdkCompatibilityPkg.dsc1
10 files changed, 7387 insertions, 0 deletions
diff --git a/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/ConvLib.c b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/ConvLib.c
new file mode 100644
index 0000000..56df30c
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/ConvLib.c
@@ -0,0 +1,786 @@
+/**@file
+ Common filling functions used in translating Datahub's record
+ to PI SMBIOS's record.
+
+Copyright (c) 2009, Intel Corporation
+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 "Thunk.h"
+
+/**
+ Field Filling Function for Cache SubClass record type 5&6 -- Cache SRAM type.
+ Offset is mandatory
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldCacheType5 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_CACHE_SRAM_TYPE_DATA SramData;
+ UINT32 Temp;
+
+ SramData = *(EFI_CACHE_SRAM_TYPE_DATA*)RecordData;
+
+ //
+ // Swap two fields because of inconsistency between smbios and datahub specs
+ //
+ Temp = SramData.Asynchronous;
+ SramData.Asynchronous = SramData.Synchronous;
+ SramData.Synchronous = Temp;
+
+ //
+ // Truncate the data to word
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + Offset,
+ (EFI_CACHE_SRAM_TYPE_DATA *) &SramData,
+ 2
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Cache SubClass record type 10 -- Cache Config.
+ Offset is mandatory
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldCacheType10 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+
+ UINT16 CacheConfig;
+
+ CopyMem (&CacheConfig, RecordData, 2);
+
+ if ((CacheConfig & 0x07) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Truncate the data to 2 bytes and make cache level zero-based.
+ //
+ CacheConfig--;
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + Offset,
+ &CacheConfig,
+ 2
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Enlarge the structure buffer of a structure node in SMBIOS database.
+ The function maybe lead the structure pointer for SMBIOS record changed.
+
+ @param StructureNode The structure node whose structure buffer is to be enlarged.
+ @param NewLength The new length of SMBIOS record which does not include unformat area.
+ @param OldBufferSize The old size of SMBIOS record buffer.
+ @param NewSize The new size is targeted for enlarged.
+
+ @retval EFI_OUT_OF_RESOURCES No more memory to allocate new record
+ @retval EFI_SUCCESS Success to enlarge the record buffer size.
+**/
+EFI_STATUS
+SmbiosEnlargeStructureBuffer (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ UINT8 NewLength,
+ UINTN OldBufferSize,
+ UINTN NewBufferSize
+ )
+{
+ EFI_SMBIOS_TABLE_HEADER *NewRecord;
+ EFI_SMBIOS_PROTOCOL *Smbios;
+ EFI_STATUS Status;
+ UINT8 CountOfString;
+
+ NewRecord = NULL;
+ Smbios = GetSmbiosProtocol();
+ ASSERT (Smbios != NULL);
+
+ NewRecord = (EFI_SMBIOS_TABLE_HEADER*) AllocateZeroPool (NewBufferSize);
+ if (NewRecord == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem (NewRecord, StructureNode->Structure, OldBufferSize);
+
+
+ Status = Smbios->Remove (Smbios, StructureNode->SmbiosHandle);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // try to use original handle to enlarge the buffer.
+ //
+ NewRecord->Length = NewLength;
+ Status = Smbios->Add (Smbios, NULL, &StructureNode->SmbiosHandle, NewRecord);
+ ASSERT_EFI_ERROR (Status);
+ FreePool (NewRecord);
+
+ StructureNode->Structure = GetSmbiosBufferFromHandle (
+ StructureNode->SmbiosHandle,
+ StructureNode->SmbiosType,
+ NULL
+ );
+ GetSmbiosStructureSize (
+ StructureNode->Structure,
+ &StructureNode->StructureSize,
+ &CountOfString
+ );
+ return EFI_SUCCESS;
+}
+
+/**
+ Fill a standard Smbios string field.
+
+ This function will convert the unicode string to single byte chars, and only
+ English language is supported.
+ This function changes the Structure pointer value of the structure node,
+ which should be noted by Caller.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_INVALID_PARAMETER RecordDataSize is too larger
+ @retval EFI_OUT_OF_RESOURCES No memory to allocate new buffer for string
+ @retval EFI_SUCCESS Sucess append string for a SMBIOS record.
+**/
+EFI_STATUS
+SmbiosFldString (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_STATUS Status;
+ UINT16 *Data;
+ CHAR8 AsciiData[SMBIOS_STRING_MAX_LENGTH];
+ UINT8 CountOfStrings;
+ UINTN OrigStringNumber;
+ EFI_SMBIOS_PROTOCOL *Smbios;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ UINT32 OrigStructureSize;
+ UINTN NewStructureSize;
+ EFI_SMBIOS_TABLE_HEADER *NewRecord;
+ UINT32 StringLength;
+
+ Status = EFI_SUCCESS;
+ OrigStringNumber = 0;
+ OrigStructureSize = 0;
+
+ //
+ // if we have a NULL token,
+ //
+ if (0 == *((STRING_REF *) RecordData)) {
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = 0;
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Get the String from the Hii Database
+ //
+ Data = HiiGetPackageString (
+ &(StructureNode->ProducerName),
+ *((EFI_STRING_ID *) RecordData),
+ NULL
+ );
+ if (Data == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ StringLength = (UINT32)StrLen (Data);
+ //
+ // Count the string size including the terminating 0.
+ //
+ if (StringLength == 0) {
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = 0;
+ FreePool (Data);
+ return EFI_SUCCESS;
+ }
+
+ if (StringLength > SMBIOS_STRING_MAX_LENGTH) {
+ //
+ // Too long a string
+ //
+ FreePool (Data);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Smbios = GetSmbiosProtocol();
+ ASSERT (Smbios != NULL);
+
+ //
+ // Convert Unicode string to Ascii string which only supported by SMBIOS.
+ //
+ ZeroMem (AsciiData, SMBIOS_STRING_MAX_LENGTH);
+ UnicodeStrToAsciiStr (Data, AsciiData);
+
+ //
+ // if the field at offset is already filled with some value,
+ // find out the string it points to
+ //
+ OrigStringNumber = *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset);
+ if (OrigStringNumber != 0) {
+ DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Update %dth string for type[%d],offset[0x%x],handle[0x%x] to [%s]\n",
+ OrigStringNumber, StructureNode->SmbiosType, Offset, StructureNode->SmbiosHandle, AsciiData));
+
+ //
+ // If original string number is not zero, just update string
+ //
+ Status = Smbios->UpdateString (Smbios, &StructureNode->SmbiosHandle, &OrigStringNumber, AsciiData);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Fail to update %dth string in offset 0x%x for handle:0x%x type:0x%x\n",
+ OrigStringNumber, Offset, StructureNode->SmbiosHandle, StructureNode->SmbiosType));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+ } else {
+ //
+ // If the string has not been filled in SMBIOS database, remove it and add again
+ // with string appended.
+ //
+ Status = GetSmbiosStructureSize (StructureNode->Structure, &OrigStructureSize, &CountOfStrings);
+ ASSERT_EFI_ERROR (Status);
+
+ if (CountOfStrings == 0) {
+ NewStructureSize = OrigStructureSize + StringLength;
+ } else {
+ NewStructureSize = OrigStructureSize + StringLength + 1;
+ }
+
+ NewRecord = AllocateZeroPool (NewStructureSize);
+ if (NewRecord == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem (NewRecord, StructureNode->Structure, OrigStructureSize);
+
+ //
+ // Copy new string into tail of original SMBIOS record buffer.
+ //
+ if (CountOfStrings == 0) {
+ AsciiStrCpy ((CHAR8 *)NewRecord + OrigStructureSize - 2, AsciiData);
+ } else {
+ AsciiStrCpy ((CHAR8 *)NewRecord + OrigStructureSize - 1, AsciiData);
+ }
+ DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Type(%d) offset(0x%x) StringNumber:%d\n",
+ StructureNode->SmbiosType, Offset, CountOfStrings + 1));
+ //
+ // Update string reference number
+ //
+ *(UINT8 *) ((UINT8 *) NewRecord + Offset) = (UINT8) (CountOfStrings + 1);
+ SmbiosHandle = StructureNode->SmbiosHandle;
+
+ //
+ // Remove original SMBIOS record and add new one
+ //
+ Status = Smbios->Remove (Smbios, StructureNode->SmbiosHandle);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Add new SMBIOS record
+ //
+ Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, NewRecord);
+ ASSERT_EFI_ERROR (Status);
+
+ StructureNode->SmbiosHandle = SmbiosHandle;
+
+ FreePool (NewRecord);
+ }
+
+ //
+ // The SMBIOS record buffer maybe re-allocated in SMBIOS database,
+ // so update cached buffer pointer in DataHub structure list.
+ //
+ StructureNode->Structure = GetSmbiosBufferFromHandle (
+ StructureNode->SmbiosHandle,
+ StructureNode->SmbiosType,
+ NULL
+ );
+ ASSERT (StructureNode->Structure != NULL);
+
+ //
+ // The string update action maybe lead the record is re-allocated in SMBIOS database
+ // so update cached record pointer
+ //
+ Status = GetSmbiosStructureSize (StructureNode->Structure, &StructureNode->StructureSize, &CountOfStrings);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Find a handle that matches the Link Data and the target Smbios type.
+
+ @param TargetType the Smbios type
+ @param SubClass the SubClass
+ @param LinkData Specifies Instance, SubInstance and ProducerName
+ @param Handle the HandleNum found
+
+ @retval EFI_NOT_FOUND Can not find the record according to handle
+ @retval EFI_SUCCESS Success to find the handle
+**/
+EFI_STATUS
+SmbiosFindHandle (
+ IN UINT8 TargetType,
+ IN EFI_GUID *SubClass,
+ IN EFI_INTER_LINK_DATA *LinkData,
+ IN OUT UINT16 *HandleNum
+ )
+{
+ LIST_ENTRY *Link;
+ SMBIOS_STRUCTURE_NODE *StructureNode;
+
+ StructureNode = NULL;
+
+ //
+ // Find out the matching handle
+ //
+ for (Link = mStructureList.ForwardLink; Link != &mStructureList; Link = Link->ForwardLink) {
+ StructureNode = CR (Link, SMBIOS_STRUCTURE_NODE, Link, SMBIOS_STRUCTURE_NODE_SIGNATURE);
+ if (StructureNode->Structure->Type == TargetType &&
+ CompareGuid (&(StructureNode->SubClass), SubClass) &&
+ StructureNode->Instance == LinkData->Instance &&
+ StructureNode->SubInstance == LinkData->SubInstance
+ ) {
+ break;
+ }
+ }
+
+ if (Link == &mStructureList) {
+ return EFI_NOT_FOUND;
+ } else {
+ *HandleNum = StructureNode->Structure->Handle;
+ return EFI_SUCCESS;
+ }
+}
+
+/**
+ Fill the inter link field for a SMBIOS recorder.
+
+ Some SMBIOS recorder need to reference the handle of another SMBIOS record. But
+ maybe another SMBIOS record has not been added, so put the InterLink request into
+ a linked list and the interlink will be fixedup when a new SMBIOS record is added.
+
+ @param StructureNode Point to SMBIOS_STRUCTURE_NODE which reference another record's handle
+ @param LinkSmbiosNodeOffset The offset in this record for holding the handle of another SMBIOS record
+ @param LinkSmbiosType The type of SMBIOS record want to be linked.
+ @param InterLink Point to EFI_INTER_LINK_DATA will be put linked list.
+ @param SubClassGuid The guid of subclass for linked SMBIOS record.
+
+ @retval EFI_SUCESS The linked record is found and no need fixup in future.
+ @retval !EFI_SUCESS The linked record can not be found and InterLink is put a fixing-p linked list.
+**/
+EFI_STATUS
+SmbiosFldInterLink (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT16 LinkSmbiosNodeOffset,
+ IN UINT8 LinkSmbiosType,
+ IN EFI_INTER_LINK_DATA *InterLink,
+ IN EFI_GUID *SubClassGuid
+ )
+{
+ EFI_STATUS Status;
+ SMBIOS_LINK_DATA_FIXUP_NODE *LinkDataFixupNode;
+ UINT16 StructureHandle;
+
+ Status = EFI_SUCCESS;
+ LinkDataFixupNode = NULL;
+
+ Status = SmbiosFindHandle (
+ LinkSmbiosType, // Smbios type
+ SubClassGuid,
+ InterLink,
+ &StructureHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Set the handle
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + LinkSmbiosNodeOffset,
+ &StructureHandle,
+ sizeof (EFI_SMBIOS_HANDLE)
+ );
+ } else {
+ //
+ // Hang this in the link data fixup node
+ //
+ LinkDataFixupNode = AllocateZeroPool (sizeof (SMBIOS_LINK_DATA_FIXUP_NODE));
+ if (!LinkDataFixupNode) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ LinkDataFixupNode->Signature = SMBIOS_LINK_DATA_FIXUP_NODE_SIGNATURE;
+ LinkDataFixupNode->Offset = LinkSmbiosNodeOffset;
+ LinkDataFixupNode->TargetType = LinkSmbiosType;
+ CopyMem (
+ &LinkDataFixupNode->SubClass,
+ SubClassGuid,
+ sizeof (EFI_GUID)
+ );
+ CopyMem (
+ &LinkDataFixupNode->LinkData,
+ InterLink,
+ sizeof (EFI_INTER_LINK_DATA)
+ );
+ InsertTailList (
+ &StructureNode->LinkDataFixup,
+ &(LinkDataFixupNode->Link)
+ );
+ }
+
+ return Status;
+}
+
+/**
+ Field Filling Function. Transform an EFI_EXP_BASE10_DATA to a word, with 'Mega'
+ as the unit.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_INVALID_PARAMETER RecordDataSize is invalid.
+ @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.
+**/
+EFI_STATUS
+SmbiosFldBase10ToWordWithMega (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_EXP_BASE10_DATA *Base10Data;
+ INT16 Value;
+ INT16 Exponent;
+
+ if (RecordDataSize != sizeof (EFI_EXP_BASE10_DATA)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Base10Data = RecordData;
+ Value = Base10Data->Value;
+ Exponent = Base10Data->Exponent;
+
+ Exponent -= 6;
+ while (Exponent != 0) {
+ if (Exponent > 0) {
+ Value = (INT16) (Value * 10);
+ Exponent--;
+ } else {
+ Value = (INT16) (Value / 10);
+ Exponent++;
+ }
+ }
+
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + Offset,
+ &Value,
+ 2
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a word, with 'Kilo'
+ as the unit. Granularity implemented for Cache Size.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_INVALID_PARAMETER RecordDataSize is invalid.
+ @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.
+**/
+EFI_STATUS
+SmbiosFldBase2ToWordWithKilo (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_EXP_BASE2_DATA *Base2Data;
+ UINT32 Value;
+ UINT16 Exponent;
+
+ if (RecordDataSize != sizeof (EFI_EXP_BASE2_DATA)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Base2Data = RecordData;
+ Value = Base2Data->Value;
+ Exponent = Base2Data->Exponent;
+
+ Exponent -= 10;
+ Value <<= Exponent;
+
+ //
+ // Implement cache size granularity
+ //
+ if(Value >= 0x8000) {
+ Value >>= 6;
+ Value |= 0x8000;
+ }
+
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + Offset,
+ &Value,
+ 2
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with '64k'
+ as the unit.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_INVALID_PARAMETER RecordDataSize is invalid.
+ @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.
+**/
+EFI_STATUS
+SmbiosFldBase2ToByteWith64K (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_EXP_BASE2_DATA *Base2Data;
+ UINT16 Value;
+ UINT16 Exponent;
+
+ if (RecordDataSize != sizeof (EFI_EXP_BASE2_DATA)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Base2Data = RecordData;
+ Value = Base2Data->Value;
+ Exponent = Base2Data->Exponent;
+ Exponent -= 16;
+ Value <<= Exponent;
+
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + Offset,
+ &Value,
+ 1
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a word, with 10exp-9
+ as the unit.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_INVALID_PARAMETER RecordDataSize is invalid.
+ @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.
+**/
+EFI_STATUS
+SmbiosFldBase10ToByteWithNano (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_EXP_BASE10_DATA *Base10Data;
+ INT16 Value;
+ INT16 Exponent;
+
+ if (RecordDataSize != sizeof (EFI_EXP_BASE2_DATA)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Base10Data = RecordData;
+ Value = Base10Data->Value;
+ Exponent = Base10Data->Exponent;
+
+ Exponent += 9;
+ while (Exponent != 0) {
+ if (Exponent > 0) {
+ Value = (INT16) (Value * 10);
+ Exponent--;
+ } else {
+ Value = (INT16) (Value / 10);
+ Exponent++;
+ }
+ }
+
+ * (UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = (UINT8) Value;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function: truncate record data to byte and fill in the
+ field as indicated by Offset.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_INVALID_PARAMETER RecordDataSize is invalid.
+ @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.
+**/
+EFI_STATUS
+SmbiosFldTruncateToByte (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Truncate the data to 8 bits
+ //
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = (UINT8) (*(UINT8 *) RecordData);
+
+ return Status;
+}
+
+/**
+ Field Filling Function: truncate record data to byte and fill in the
+ field as indicated by Offset.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_INVALID_PARAMETER RecordDataSize is invalid.
+ @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.
+**/
+EFI_STATUS
+SmbiosFldTruncateToWord (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Truncate the data to 8 bits
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + Offset,
+ RecordData,
+ 2
+ );
+
+ return Status;
+}
+
+/**
+ Check if OEM structure has included 2 trailing 0s in data record.
+
+ @param RecordData Point to record data will be checked.
+ @param RecordDataSize The size of record data.
+
+ @retval 0 2 trailing 0s exist in unformatted section
+ @retval 1 1 trailing 0 exists at the end of unformatted section
+ @retval -1 There is no 0 at the end of unformatted section
+**/
+INT8
+SmbiosCheckTrailingZero (
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ SMBIOS_STRUCTURE *Smbios;
+ CHAR8 *Start;
+ CHAR8 *End;
+
+ Smbios = (SMBIOS_STRUCTURE *) RecordData;
+
+ //
+ // Skip over formatted section
+ //
+ Start = (CHAR8 *) ((UINT8 *) Smbios + Smbios->Length);
+ End = (CHAR8 *) RecordData + RecordDataSize;
+
+ //
+ // Unformatted section exists
+ //
+ while (Start < End - 1) {
+ //
+ // Avoid unaligned issue on IPF
+ //
+ if ((*Start == 0) && (*(Start + 1) == 0)) {
+ //
+ // 2 trailing 0s exist in unformatted section
+ //
+ return 0;
+ }
+ Start++;
+ }
+
+ if (Start == End - 1) {
+ //
+ // Check if there has been already 1 trailing 0
+ //
+ if (*Start == 0) {
+ return 1;
+ }
+ }
+
+ //
+ // There is no 0 at the end of unformatted section
+ //
+ return -1;
+}
diff --git a/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/ConvTable.c b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/ConvTable.c
new file mode 100644
index 0000000..2809748
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/ConvTable.c
@@ -0,0 +1,1235 @@
+/** @file
+ The conversion table that guides the generation of the Smbios struture list.
+
+Copyright (c) 2009, Intel Corporation
+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 "Thunk.h"
+
+///
+/// The minimal length includes last two zero bytes.
+///
+SMBIOS_TYPE_INFO_TABLE_ENTRY mTypeInfoTable[] = {
+ //
+ // Type 0: Bios Information
+ //
+ {
+ 0,
+ 0x1a,
+ TRUE,
+ FALSE
+ }, // size includes wo extension bytes
+ //
+ // Type 1: System Information
+ //
+ {
+ 1,
+ 0x1d,
+ TRUE,
+ FALSE
+ },
+ //
+ // Type 2: Base Board Information
+ //
+ {
+ 2,
+ 0x12,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 3: System Enclosure or Chassis
+ //
+ {
+ 3,
+ 0x17, // 0x13 covers till OEM-defined, not right
+ TRUE,
+ FALSE
+ },
+ //
+ // Type 4: Processor
+ //
+ {
+ 4,
+ 0x25,
+ TRUE,
+ FALSE
+ },
+ //
+ // Type 5: Memory Controller
+ //
+ {
+ 5,
+ 0x12,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 6: Memory
+ //
+ {
+ 6,
+ 0x0E,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 7: Cache
+ //
+ {
+ 7,
+ 0x15,
+ TRUE,
+ FALSE
+ },
+ //
+ // Type 8: Port Connector Information
+ //
+ {
+ 8,
+ 0x0B,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 9: System Slots
+ //
+ {
+ 9,
+ 0x0f,
+ TRUE,
+ FALSE
+ },
+ //
+ // Type 10: On Board Device Information
+ //
+ {
+ 10,
+ 0x8,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 11: OEM Strings
+ //
+ {
+ 11,
+ 0x7,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 12: System Configuration Options
+ //
+ {
+ 12,
+ 0x7,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 13: BIOS Language Information
+ //
+ {
+ 13,
+ 0x18,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 15: System Event Log
+ //
+ {
+ 15,
+ 0x19,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 16: Physical Memory Array
+ //
+ {
+ 16,
+ 0x11,
+ TRUE,
+ FALSE
+ },
+ //
+ // Type 17: Memory Device
+ //
+ {
+ 17,
+ 0x1d,
+ TRUE,
+ FALSE
+ },
+ //
+ // Type 18: 32 bit Memory Error Information
+ //
+ {
+ 18,
+ 0x19,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 19: Memory Array Mapped Address
+ //
+ {
+ 19,
+ 0x11,
+ TRUE,
+ FALSE
+ },
+ //
+ // Type 20: Memory Device Mapped Address
+ //
+ {
+ 20,
+ 0x15,
+ TRUE,
+ FALSE
+ },
+ //
+ // Type 21: Pointing Device
+ //
+ {
+ 21,
+ 0x9,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 22: Portable Battery
+ //
+ {
+ 22,
+ 0x1c,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 23: System Reset
+ //
+ {
+ 23,
+ 0x0f,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 24: Hardware Security
+ //
+ {
+ 24,
+ 0x07,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 25: System Power Controls
+ //
+ {
+ 25,
+ 0x0b,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 26: Voltage Probe
+ //
+ {
+ 26,
+ 0x18,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 27: Cooling Device
+ //
+ {
+ 27,
+ 0x10,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 28: Temperature Probe
+ //
+ {
+ 28,
+ 0x18,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 29: Electrical Current Probe
+ //
+ {
+ 29,
+ 0x18,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 30: Out-of-Band Remote Access
+ //
+ {
+ 30,
+ 0x08,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 31: BIS Entry Point
+ //
+ {
+ 31,
+ 0x1c,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 32: System Boot Information
+ //
+ {
+ 32,
+ 0x16,
+ TRUE,
+ FALSE
+ },
+ //
+ // Type 33: 64 bit Memory Error Information
+ //
+ {
+ 33,
+ 0x21,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 34: Management Device
+ //
+ {
+ 34,
+ 0x0d,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 36: Management Device Threshold
+ //
+ {
+ 36,
+ 0x12,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 37: Memory Channel
+ //
+ {
+ 37,
+ 0x0c,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 38: IPMI device info
+ //
+ {
+ 38,
+ 0x12,
+ TRUE,
+ FALSE
+ },
+ //
+ // Type 39: Power supply
+ //
+ {
+ 39,
+ 0x18,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 0x80-0xFF: OEM type
+ //
+ {
+ 0x80,
+ 0x6,
+ FALSE,
+ FALSE
+ },
+ //
+ // Type 127: End of Table
+ //
+ {
+ 127,
+ 0x6,
+ FALSE,
+ FALSE
+ },
+ //
+ // Terminator
+ //
+ {
+ 0,
+ 0
+ }
+};
+
+SMBIOS_CONVERSION_TABLE_ENTRY mConversionTable[] = {
+
+ {
+ //
+ // Processor Sub Class -- Record Type 1: Frequency
+ //
+ EFI_PROCESSOR_SUBCLASS_GUID,
+ ProcessorCoreFrequencyRecordType,
+ 4,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x16,
+ SmbiosFldBase10ToWordWithMega
+ },
+
+ {
+ //
+ // Processor SubClass -- Record Type 2: Bus Frequency
+ //
+ EFI_PROCESSOR_SUBCLASS_GUID,
+ ProcessorFsbFrequencyRecordType,
+ 4,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x12,
+ SmbiosFldBase10ToWordWithMega
+ },
+
+ {
+ //
+ // Processor SubClass -- Record Type 3: Version
+ //
+ EFI_PROCESSOR_SUBCLASS_GUID,
+ ProcessorVersionRecordType,
+ 4,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x10,
+ SmbiosFldString
+ },
+
+ {
+ //
+ // Processor SubClass -- Record Type 4: Manufacturor
+ //
+ EFI_PROCESSOR_SUBCLASS_GUID,
+ ProcessorManufacturerRecordType,
+ 4,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x7,
+ SmbiosFldString
+ },
+
+ {
+ //
+ // Processor SubClass -- Record Type 5: Serial Number
+ //
+ EFI_PROCESSOR_SUBCLASS_GUID,
+ ProcessorSerialNumberRecordType,
+ 4,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x20,
+ SmbiosFldString
+ },
+
+ {
+ //
+ // Processor SubClass -- Record Type 6: ID
+ //
+ EFI_PROCESSOR_SUBCLASS_GUID,
+ ProcessorIdRecordType,
+ 4,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x08,
+ SmbiosFldProcessorType6
+ },
+
+ {
+ //
+ // Processor SubClass -- Record Type 7: Type
+ //
+ EFI_PROCESSOR_SUBCLASS_GUID,
+ ProcessorTypeRecordType,
+ 4,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x05,
+ SmbiosFldTruncateToByte
+ },
+
+ {
+ //
+ // Processor SubClass -- Record Type 8: Family
+ //
+ EFI_PROCESSOR_SUBCLASS_GUID,
+ ProcessorFamilyRecordType,
+ 4,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x06,
+ SmbiosFldTruncateToByte
+ },
+
+ {
+ //
+ // Processor SubClass -- Record Type 9: Voltage
+ //
+ EFI_PROCESSOR_SUBCLASS_GUID,
+ ProcessorVoltageRecordType,
+ 4,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x11,
+ SmbiosFldProcessorType9
+ },
+
+ {
+ //
+ // Processor SubClass -- Record Type 14: Status
+ //
+ EFI_PROCESSOR_SUBCLASS_GUID,
+ ProcessorStatusRecordType,
+ 4,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x18,
+ SmbiosFldTruncateToByte
+ },
+
+ {
+ //
+ // Processor SubClass -- Record Type 15: Socket Type
+ //
+ EFI_PROCESSOR_SUBCLASS_GUID,
+ ProcessorSocketTypeRecordType,
+ 4,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x19,
+ SmbiosFldTruncateToByte
+ },
+
+ {
+ //
+ // Processor SubClass -- Record Type 16: Socket Name
+ //
+ EFI_PROCESSOR_SUBCLASS_GUID,
+ ProcessorSocketNameRecordType,
+ 4,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x04,
+ SmbiosFldString
+ },
+
+ {
+ //
+ // Processor SubClass -- Record Type 17: Cache Associtation
+ //
+ EFI_PROCESSOR_SUBCLASS_GUID,
+ CacheAssociationRecordType,
+ 4,
+ BY_SUBCLASS_INSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_WHOLE_DATA_RECORD,
+ 0,
+ SmbiosFldProcessorType17
+ },
+
+ {
+ //
+ // Processor Sub Class -- Record Type 18: MaxFrequency
+ //
+ EFI_PROCESSOR_SUBCLASS_GUID,
+ ProcessorMaxCoreFrequencyRecordType,
+ 4,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x14,
+ SmbiosFldBase10ToWordWithMega
+ },
+
+ {
+ //
+ // Processor SubClass -- Record Type 19: Asset Tag
+ //
+ EFI_PROCESSOR_SUBCLASS_GUID,
+ ProcessorAssetTagRecordType,
+ 4,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x21,
+ SmbiosFldString
+ },
+
+ {
+ //
+ // Cache SubClass -- Record Type 1: Size
+ //
+ EFI_CACHE_SUBCLASS_GUID,
+ CacheSizeRecordType,
+ 7,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x09,
+ SmbiosFldBase2ToWordWithKilo
+ },
+
+ {
+ //
+ // Cache SubClass -- Record Type 2: Max Size
+ //
+ EFI_CACHE_SUBCLASS_GUID,
+ MaximumSizeCacheRecordType,
+ 7,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x07,
+ SmbiosFldBase2ToWordWithKilo
+ },
+
+ {
+ //
+ // Cache SubClass -- Record Type 3: Speed
+ //
+ EFI_CACHE_SUBCLASS_GUID,
+ CacheSpeedRecordType,
+ 7,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x0f,
+ SmbiosFldBase10ToByteWithNano
+ },
+
+ {
+ //
+ // Cache SubClass -- Record Type 4: Socket
+ //
+ EFI_CACHE_SUBCLASS_GUID,
+ CacheSocketRecordType,
+ 7,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x04,
+ SmbiosFldString
+ },
+
+ {
+ //
+ // Cache SubClass -- Record Type 5: Supported SRAM type
+ //
+ EFI_CACHE_SUBCLASS_GUID,
+ CacheSramTypeRecordType,
+ 7,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x0b,
+ SmbiosFldCacheType5 // Asynchronous and Synchronous are reversed
+ },
+
+ {
+ //
+ // Cache SubClass -- Record Type 6: Installed SRAM type
+ //
+ EFI_CACHE_SUBCLASS_GUID,
+ CacheInstalledSramTypeRecordType,
+ 7,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x0d,
+ SmbiosFldCacheType5
+ },
+
+ {
+ //
+ // Cache SubClass -- Record Type 7: error correction type
+ //
+ EFI_CACHE_SUBCLASS_GUID,
+ CacheErrorTypeRecordType,
+ 7,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x10,
+ SmbiosFldTruncateToByte
+ },
+
+ {
+ //
+ // Cache SubClass -- Record Type 8: cache type
+ //
+ EFI_CACHE_SUBCLASS_GUID,
+ CacheTypeRecordType,
+ 7,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x11,
+ SmbiosFldTruncateToByte
+ },
+
+ {
+ //
+ // Cache SubClass -- Record Type 9: Associativity
+ //
+ EFI_CACHE_SUBCLASS_GUID,
+ CacheAssociativityRecordType,
+ 7,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x12,
+ SmbiosFldTruncateToByte
+ },
+
+ {
+ //
+ // Cache SubClass -- Record Type 10: Cache configuration
+ //
+ EFI_CACHE_SUBCLASS_GUID,
+ CacheConfigRecordType,
+ 7,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ 0x05,
+ SmbiosFldCacheType10
+ },
+
+ {
+ //
+ // Memory SubClass -- Record Type 2: Physical Memory Array
+ //
+ EFI_MEMORY_SUBCLASS_GUID,
+ EFI_MEMORY_ARRAY_LOCATION_RECORD_NUMBER,
+ 16,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMemoryType2
+ },
+
+ {
+ //
+ // Memory SubClass -- Record Type 3: Memory Device to SMBIOS type 6
+ //
+ EFI_MEMORY_SUBCLASS_GUID,
+ EFI_MEMORY_ARRAY_LINK_RECORD_NUMBER,
+ 6,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldSMBIOSType6
+ },
+
+ {
+ //
+ // Memory SubClass -- Record Type 3: Memory Device to SMBIOS type 17
+ //
+ EFI_MEMORY_SUBCLASS_GUID,
+ EFI_MEMORY_ARRAY_LINK_RECORD_NUMBER,
+ 17,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMemoryType3
+ },
+
+ {
+ //
+ // Memory SubClass -- Record Type 4: Memory Array Mapped Address
+ //
+ EFI_MEMORY_SUBCLASS_GUID,
+ EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER,
+ 19,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMemoryType4
+ },
+
+ {
+ //
+ // Memory SubClass -- Record Type 5: Memory Device Mapped Address
+ //
+ EFI_MEMORY_SUBCLASS_GUID,
+ EFI_MEMORY_DEVICE_START_ADDRESS_RECORD_NUMBER,
+ 20,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMemoryType5
+ },
+
+ {
+ //
+ // Memory SubClass -- Record Type 6: Memory Channel Type
+ //
+ EFI_MEMORY_SUBCLASS_GUID,
+ EFI_MEMORY_CHANNEL_TYPE_RECORD_NUMBER,
+ 37,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMemoryType6
+ },
+
+ {
+ //
+ // Memory SubClass -- Record Type 7: Memory Channel Device
+ //
+ EFI_MEMORY_SUBCLASS_GUID,
+ EFI_MEMORY_CHANNEL_DEVICE_RECORD_NUMBER,
+ 37,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMemoryType7
+ },
+
+ {
+ //
+ // Memory SubClass -- Record Type 8: Memory Controller information
+ //
+ EFI_MEMORY_SUBCLASS_GUID,
+ EFI_MEMORY_CONTROLLER_INFORMATION_RECORD_NUMBER,
+ 5,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMemoryType8
+ },
+
+ {
+ //
+ // Memory SubClass -- Record Type 9: Memory 32 Bit Error Information
+ //
+ EFI_MEMORY_SUBCLASS_GUID,
+ EFI_MEMORY_32BIT_ERROR_INFORMATION_RECORD_NUMBER,
+ 18,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMemoryType9
+ },
+
+ {
+ //
+ // Memory SubClass -- Record Type 10: Memory 64 Bit Error Information
+ //
+ EFI_MEMORY_SUBCLASS_GUID,
+ EFI_MEMORY_64BIT_ERROR_INFORMATION_RECORD_NUMBER,
+ 33,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMemoryType10
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 2: Bios Information (SMBIOS Type 0)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_BIOS_VENDOR_RECORD_NUMBER, // 0,
+ 0, // smbios Type 0
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType0
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 3: System Information (SMBIOS Type 1)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER, // 1,
+ 1,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType1
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 4: Base Board Manufacturer (SMBIOS Type 2)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_BASE_BOARD_MANUFACTURER_RECORD_NUMBER, // 2,
+ 2, // SMBIOS Type 2
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType2
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 5: System Enclosure or Chassis (SMBIOS Type 3)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_CHASSIS_MANUFACTURER_RECORD_NUMBER, // 3,
+ 3,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType3
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 6: Port Connector (SMBIOS Type 8)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_RECORD_NUMBER, // 8,
+ 8,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType8
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 7: System Slots (SMBIOS Type 9)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_SYSTEM_SLOT_DESIGNATION_RECORD_NUMBER, // 9,
+ 9,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType9
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 8: Onboard Device (SMBIOS Type 10)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_ONBOARD_DEVICE_RECORD_NUMBER, // 10,
+ 10,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType10
+ },
+
+ {
+ //
+ // Misc Subclass -- Record Type 9: OEM strings (SMBIOS Type 11)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_OEM_STRING_RECORD_NUMBER, // 11,
+ 11,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType11
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0A: System Options (SMBIOS Type 12)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_SYSTEM_OPTION_STRING_RECORD_NUMBER, // 12,
+ 12,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType12
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0B: Number of Installable Languages (SMBIOS Type 13)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES_RECORD_NUMBER, // 13,
+ 13,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType13
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0C: Installable Languages (SMBIOS Type 13)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_SYSTEM_LANGUAGE_STRING_RECORD_NUMBER, // 13,
+ 13,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType14
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 20: System Event Log (SMBIOS Type 15)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_SYSTEM_EVENT_LOG_RECORD_NUMBER, // 15,
+ 15,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType15
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0F: Pointing Device (SMBIOS Type 21)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_POINTING_DEVICE_TYPE_RECORD_NUMBER, // 21,
+ 21,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType21
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 10: Portable Battery (SMBIOS Type 22)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_PORTABLE_BATTERY_RECORD_NUMBER, // 22,
+ 22,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType22
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0x11: Reset Capabilities (SMBIOS Type 23)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_RESET_CAPABILITIES_RECORD_NUMBER, // 23,
+ 23,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType23
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0x12: Hardware Security (SMBIOS Type 24)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_HARDWARE_SECURITY_SETTINGS_DATA_RECORD_NUMBER, // 24,
+ 24,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType24
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0x13: System Power Controls (SMBIOS Type 25)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_SCHEDULED_POWER_ON_MONTH_RECORD_NUMBER, // 25,
+ 25,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType25
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0x14: System Power Controls (SMBIOS Type 26)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_VOLTAGE_PROBE_DESCRIPTION_RECORD_NUMBER, // 26,
+ 26,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType26
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0x15: Cooling Device (SMBIOS Type 27)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_COOLING_DEVICE_TEMP_LINK_RECORD_NUMBER, // 27,
+ 27,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType27
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0x16: Temperature Probe (SMBIOS Type 28)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_TEMPERATURE_PROBE_DESCRIPTION_RECORD_NUMBER, // 28,
+ 28,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType28
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0x17: Electrical Current Probe (SMBIOS Type 29)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_ELECTRICAL_CURRENT_PROBE_DESCRIPTION_RECORD_NUMBER, // 29,
+ 29,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType29
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0x18: Temperature Probe (SMBIOS Type 30)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_REMOTE_ACCESS_MANUFACTURER_DESCRIPTION_RECORD_NUMBER, // 30,
+ 30,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType30
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0x1A: Boot Information (SMBIOS Type 32)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_BOOT_INFORMATION_STATUS_RECORD_NUMBER, // 32,
+ 32,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType32
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0x1B: Management Device (SMBIOS Type 34)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_MANAGEMENT_DEVICE_DESCRIPTION_RECORD_NUMBER, // 34,
+ 34,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType34
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0x21: Management Device Threshold (SMBIOS Type 36)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_MANAGEMENT_DEVICE_THRESHOLD_RECORD_NUMBER, // 36,
+ 36,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType36
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0x1D: Boot Information (SMBIOS Type 38)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_IPMI_INTERFACE_TYPE_RECORD_NUMBER, // 38,
+ 38,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType38
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0x1E: Power supply (SMBIOS Type 39)
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_SYSTEM_POWER_SUPPLY_RECORD_NUMBER, // 39,
+ 39,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType39
+ },
+
+ {
+ //
+ // Misc SubClass -- Record Type 0x80-0xFF: OEM type
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ EFI_MISC_SMBIOS_STRUCT_ENCAP_RECORD_NUMBER, // 0x80,
+ 0x80,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscTypeOEM
+ },
+
+ {
+ //
+ // End-of-Table -- Record Type 127
+ //
+ EFI_MISC_SUBCLASS_GUID,
+ 127,
+ 127,
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_FUNCTION,
+ 0,
+ SmbiosFldMiscType127
+ },
+ //
+ // Table Terminator
+ //
+ {
+ {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}},
+ 0,
+ 0,
+ (SMBIOS_STRUCTURE_LOCATING_METHOD) 0,
+ (SMBIOS_FIELD_FILLING_METHOD) 0,
+ 0,
+ 0
+ }
+};
diff --git a/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/DataHubSmBiosRecordsOnPiSmBiosThunk.inf b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/DataHubSmBiosRecordsOnPiSmBiosThunk.inf
new file mode 100644
index 0000000..782d64a
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/DataHubSmBiosRecordsOnPiSmBiosThunk.inf
@@ -0,0 +1,75 @@
+#/** @file
+# This thunk driver register a filter for DataHub protocol, once a data hub record
+# is added via EFI_DATA_HUB_PROTOCOL->LogData(), this filter will be invoked to
+# translate the datahub's record to SMBIOS record.
+#
+# Copyright (c) 2009, Intel Corporation
+#
+# 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.
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Datahub2SmbiosThunk
+ FILE_GUID = 9F8B12CF-E796-408f-9D59-3ACDDC0AFBE3
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ EDK_RELEASE_VERSION = 0x00020000
+ EFI_SPECIFICATION_VERSION = 0x00020000
+
+ ENTRY_POINT = ThunkEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources.common]
+ Thunk.c
+ Thunk.h
+ Translate.c
+ ConvLib.c
+ ConvTable.c
+ ProcessorConv.c
+ MemoryConv.c
+ MiscConv.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ EdkCompatibilityPkg/EdkCompatibilityPkg.dec
+
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ UefiDriverEntryPoint
+ BaseMemoryLib
+ HiiLib
+ DebugLib
+ BaseLib
+ PcdLib
+
+[Protocols]
+ gEfiDataHubProtocolGuid ## CONSUMES
+ gEfiSmbiosProtocolGuid ## CONSUMES
+
+[Guids]
+ gEfiMemorySubClassGuid ## CONSUMES
+ gEfiMiscSubClassGuid ## CONSUMES
+ gEfiCacheSubClassGuid ## CONSUMES
+
+[FeaturePcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport
+
+[Depex]
+ gEfiDataHubProtocolGuid AND gEfiSmbiosProtocolGuid \ No newline at end of file
diff --git a/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/MemoryConv.c b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/MemoryConv.c
new file mode 100644
index 0000000..20cd71a
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/MemoryConv.c
@@ -0,0 +1,1089 @@
+/** @file
+ Routines that support Memory SubClass data records translation.
+
+Copyright (c) 2009, Intel Corporation
+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 "Thunk.h"
+
+/**
+ Field Filling Function for Memory SubClass record type 2 -- Physical Memory
+ Array.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMemoryType2 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_MEMORY_ARRAY_LOCATION_DATA *PhyMemArray;
+ FRAMEWORK_MEMORY_ARRAY_LOCATION_DATA *FrameworkPhyMemArray;
+ UINT32 MemoryCapacity;
+ UINT16 NumberMemoryDevices;
+ UINT16 Test16;
+
+ Status = EFI_SUCCESS;
+ PhyMemArray = (EFI_MEMORY_ARRAY_LOCATION_DATA *) RecordData;
+ FrameworkPhyMemArray = (FRAMEWORK_MEMORY_ARRAY_LOCATION_DATA *) RecordData;
+
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE16, Location)) = (UINT8) (PhyMemArray->MemoryArrayLocation);
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE16, Use)) = (UINT8) (PhyMemArray->MemoryArrayUse);
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE16, MemoryErrorCorrection)) = (UINT8) (PhyMemArray->MemoryErrorCorrection);
+
+ if (!FeaturePcdGet(PcdFrameworkCompatibilitySupport)) {
+ MemoryCapacity = (UINT32) (((UINTN) PhyMemArray->MaximumMemoryCapacity.Value) << PhyMemArray->MaximumMemoryCapacity.Exponent);
+ NumberMemoryDevices = PhyMemArray->NumberMemoryDevices;
+ } else {
+ //
+ // Support EDk/Framework defined Data strucutre.
+ //
+ MemoryCapacity = FrameworkPhyMemArray->MaximumMemoryCapacity;
+ NumberMemoryDevices = FrameworkPhyMemArray->NumberMemoryDevices;
+ }
+
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE16, MaximumCapacity),
+ &MemoryCapacity,
+ 4
+ );
+
+ Test16 = 0xfffe;
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE16, MemoryErrorInformationHandle),
+ &Test16,
+ 2
+ );
+
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE16, NumberOfMemoryDevices),
+ &NumberMemoryDevices,
+ 2
+ );
+
+ return Status;
+}
+
+/**
+ Field Filling Function for Memory SubClass record type 3 -
+ - Memory Device: SMBIOS Type 17
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMemoryType3 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MEMORY_ARRAY_LINK_DATA *MemDevice;
+ FRAMEWORK_MEMORY_ARRAY_LINK_DATA *FrameworkMemDevice;
+ UINT64 MemoryDeviceSize;
+ BOOLEAN MemoryDeviceSizeUnitMega;
+ UINT16 MemoryDeviceSpeed;
+ UINT16 MemoryDeviceExponent;
+ UINT16 Test16;
+
+ MemDevice = (EFI_MEMORY_ARRAY_LINK_DATA *) RecordData;
+ FrameworkMemDevice = (FRAMEWORK_MEMORY_ARRAY_LINK_DATA *) RecordData;
+ MemoryDeviceSpeed = 0;
+ MemoryDeviceExponent = 0;
+
+ //
+ // Memory Device Locator
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE17, DeviceLocator),
+ &(MemDevice->MemoryDeviceLocator),
+ sizeof (STRING_REF)
+ );
+
+ //
+ // Memory Bank Locator
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE17, BankLocator),
+ &(MemDevice->MemoryBankLocator),
+ sizeof (STRING_REF)
+ );
+
+ //
+ // Memory Manufacturer
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE17, Manufacturer),
+ &(MemDevice->MemoryManufacturer),
+ sizeof (STRING_REF)
+ );
+
+ //
+ // Memory Serial Number
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE17, SerialNumber),
+ &(MemDevice->MemorySerialNumber),
+ sizeof (STRING_REF)
+ );
+
+ //
+ // Memory Asset Tag
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE17, AssetTag),
+ &(MemDevice->MemoryAssetTag),
+ sizeof (STRING_REF)
+ );
+
+ //
+ // Memory Part Number
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE17, PartNumber),
+ &(MemDevice->MemoryPartNumber),
+ sizeof (STRING_REF)
+ );
+
+ //
+ // Memory Array Link
+ //
+ SmbiosFldInterLink (
+ StructureNode,
+ (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE17, MemoryArrayHandle),
+ 16, // SMBIOS type 16
+ &MemDevice->MemoryArrayLink,
+ &gEfiMemorySubClassGuid
+ );
+
+ //
+ // Set Memory Error Information Handle to Not supported
+ //
+ Test16 = 0xfffe;
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE17, MemoryErrorInformationHandle),
+ &Test16,
+ sizeof (EFI_SMBIOS_HANDLE)
+ );
+
+ //
+ // Total width
+ //
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, TotalWidth),
+ &MemDevice->MemoryTotalWidth,
+ 2
+ );
+
+ //
+ // Data Width
+ //
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, DataWidth),
+ &MemDevice->MemoryDataWidth,
+ 2
+ );
+
+ //
+ // Device Size
+ //
+ if (!FeaturePcdGet(PcdFrameworkCompatibilitySupport)) {
+ //
+ // Form Factor
+ //
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, FormFactor),
+ &MemDevice->MemoryFormFactor,
+ 1
+ );
+
+ //
+ // Device Set
+ //
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, DeviceSet),
+ &MemDevice->MemoryDeviceSet,
+ 1
+ );
+
+ //
+ // Type
+ //
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, MemoryType),
+ &MemDevice->MemoryType,
+ 1
+ );
+
+ //
+ // Type Detail
+ //
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, TypeDetail),
+ &MemDevice->MemoryTypeDetail,
+ 2
+ );
+
+ //
+ // Speed
+ //
+ MemoryDeviceSpeed = MemDevice->MemorySpeed.Value;
+ MemoryDeviceExponent = MemDevice->MemorySpeed.Exponent;
+ while (MemoryDeviceExponent-- > 0) {
+ MemoryDeviceSpeed = (UINT16) (MemoryDeviceSpeed * 10);
+ }
+
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, Speed),
+ &MemoryDeviceSpeed,
+ 2
+ );
+
+ MemoryDeviceSize = (UINT64) (((UINTN) MemDevice->MemoryDeviceSize.Value) << MemDevice->MemoryDeviceSize.Exponent);
+ } else {
+ //
+ // Form Factor
+ //
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, FormFactor),
+ &FrameworkMemDevice->MemoryFormFactor,
+ 1
+ );
+
+ //
+ // Device Set
+ //
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, DeviceSet),
+ &FrameworkMemDevice->MemoryDeviceSet,
+ 1
+ );
+
+ //
+ // Type
+ //
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, MemoryType),
+ &FrameworkMemDevice->MemoryType,
+ 1
+ );
+
+ //
+ // Type Detail
+ //
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, TypeDetail),
+ &FrameworkMemDevice->MemoryTypeDetail,
+ 2
+ );
+
+ //
+ // Speed
+ //
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, Speed),
+ &FrameworkMemDevice->MemorySpeed,
+ 2
+ );
+
+ MemoryDeviceSize = FrameworkMemDevice->MemoryDeviceSize;
+ }
+
+ MemoryDeviceSizeUnitMega = FALSE;
+ MemoryDeviceSize = RShiftU64 (MemoryDeviceSize, 10);
+ //
+ // kilo as unit
+ //
+ if (MemoryDeviceSize > 0xffff) {
+ MemoryDeviceSize = RShiftU64 (MemoryDeviceSize, 10);
+ //
+ // Mega as unit
+ //
+ MemoryDeviceSizeUnitMega = TRUE;
+ }
+
+ MemoryDeviceSize = MemoryDeviceSize & 0x7fff;
+ if (MemoryDeviceSize != 0 && MemoryDeviceSizeUnitMega == FALSE) {
+ MemoryDeviceSize |= 0x8000;
+ }
+
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, Size),
+ &MemoryDeviceSize,
+ 2
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Memory SubClass record type 3 -
+ - Memory Device: SMBIOS Type 6
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldSMBIOSType6 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MEMORY_ARRAY_LINK_DATA *MemDevice;
+ UINT64 MemoryDeviceSize;
+ UINT8 MemSize;
+ UINT16 MemType;
+ UINT8 MemSpeed;
+ FRAMEWORK_MEMORY_ARRAY_LINK_DATA *FrameworkMemDevice;
+ UINT16 MemoryDeviceSpeed;
+ UINT16 MemoryDeviceExponent;
+
+ MemDevice = (EFI_MEMORY_ARRAY_LINK_DATA *) RecordData;
+ FrameworkMemDevice = (FRAMEWORK_MEMORY_ARRAY_LINK_DATA *) RecordData;
+ MemoryDeviceExponent = 0;
+
+ //
+ // Memory Device Locator
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE6, SocketDesignation),
+ &(MemDevice->MemoryDeviceLocator),
+ 2
+ );
+
+ if (!FeaturePcdGet(PcdFrameworkCompatibilitySupport)) {
+ MemoryDeviceSpeed = MemDevice->MemorySpeed.Value;
+ MemoryDeviceExponent = MemDevice->MemorySpeed.Exponent;
+ while (MemoryDeviceExponent-- > 0) {
+ MemoryDeviceSpeed = (UINT16) (MemoryDeviceSpeed * 10);
+ }
+ MemoryDeviceSize = (UINT64) (((UINTN) MemDevice->MemoryDeviceSize.Value) << MemDevice->MemoryDeviceSize.Exponent);
+ } else {
+ //
+ // Support EDk/Framework defined Data strucutre.
+ //
+ MemoryDeviceSpeed = FrameworkMemDevice->MemorySpeed;
+ MemoryDeviceSize = FrameworkMemDevice->MemoryDeviceSize;
+ }
+
+ if (MemoryDeviceSpeed == 0) {
+ MemSpeed = 0;
+ } else {
+ //
+ // Memory speed is in ns unit
+ //
+ MemSpeed = (UINT8)(1000 / MemoryDeviceSpeed);
+ }
+
+ CopyMem (
+ (UINT8*)StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE6, CurrentSpeed),
+ &MemSpeed,
+ 1
+ );
+
+
+ //
+ // Device Size
+ //
+ MemSize = 0;
+ if (MemoryDeviceSize == 0) {
+ MemSize = 0x7F;
+ } else {
+ MemoryDeviceSize = RShiftU64 (MemoryDeviceSize, 21);
+ while (MemoryDeviceSize != 0) {
+ MemSize++;
+ MemoryDeviceSize = RShiftU64(MemoryDeviceSize,1);
+ }
+ }
+
+ CopyMem (
+ (UINT8*)StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE6, InstalledSize),
+ &MemSize,
+ 1
+ );
+
+ CopyMem (
+ (UINT8*)StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE6, EnabledSize),
+ &MemSize,
+ 1
+ );
+
+ //
+ // According SMBIOS SPEC Type 6 definition
+ //
+ MemType = 0;
+ if (!FeaturePcdGet(PcdFrameworkCompatibilitySupport)) {
+ if (MemDevice->MemoryFormFactor == EfiMemoryFormFactorDimm ||
+ MemDevice->MemoryFormFactor == EfiMemoryFormFactorFbDimm) {
+ MemType |= 1<<8;
+ }
+
+ if (MemDevice->MemoryFormFactor == EfiMemoryFormFactorSimm) {
+ MemType |= 1<<7;
+ }
+
+ if (MemDevice->MemoryType == EfiMemoryTypeSdram) {
+ MemType |= 1<<10;
+ }
+
+ if (MemDevice->MemoryTypeDetail.Edo == 1) {
+ MemType |= 1<<4;
+ }
+
+ if (MemDevice->MemoryTypeDetail.FastPaged == 1) {
+ MemType |= 1<<3;
+ }
+ } else {
+ //
+ // Support EDk/Framework defined Data strucutre.
+ //
+ if (FrameworkMemDevice->MemoryFormFactor == EfiMemoryFormFactorDimm ||
+ FrameworkMemDevice->MemoryFormFactor == EfiMemoryFormFactorFbDimm) {
+ MemType |= 1<<8;
+ }
+
+ if (FrameworkMemDevice->MemoryFormFactor == EfiMemoryFormFactorSimm) {
+ MemType |= 1<<7;
+ }
+
+ if (FrameworkMemDevice->MemoryType == EfiMemoryTypeSdram) {
+ MemType |= 1<<10;
+ }
+
+ if (FrameworkMemDevice->MemoryTypeDetail.Edo == 1) {
+ MemType |= 1<<4;
+ }
+
+ if (FrameworkMemDevice->MemoryTypeDetail.FastPaged == 1) {
+ MemType |= 1<<3;
+ }
+ }
+ //
+ // Form Factor
+ //
+ CopyMem (
+ (UINT8*)StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE6, CurrentMemoryType),
+ &MemType,
+ 2
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Memory SubClass record type 4
+ -- Memory Array Mapped Address: SMBIOS Type 19
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMemoryType4 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MEMORY_ARRAY_START_ADDRESS_DATA *Masa;
+ EFI_PHYSICAL_ADDRESS TempData;
+
+ Masa = (EFI_MEMORY_ARRAY_START_ADDRESS_DATA *) RecordData;
+
+ //
+ // Starting Address
+ //
+ TempData = RShiftU64 (Masa->MemoryArrayStartAddress, 10);
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE19, StartingAddress),
+ &TempData,
+ 4
+ );
+
+ //
+ // Ending Address
+ //
+ TempData = RShiftU64 (Masa->MemoryArrayEndAddress, 10);
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE19, EndingAddress),
+ &TempData,
+ 4
+ );
+
+ //
+ // Partition Width
+ //
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE19, PartitionWidth),
+ &Masa->MemoryArrayPartitionWidth,
+ 1
+ );
+
+ //
+ // Physical Memory Array Link
+ //
+ return SmbiosFldInterLink (
+ StructureNode,
+ (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE19, MemoryArrayHandle),
+ 16, // SMBIOS type 16
+ &Masa->PhysicalMemoryArrayLink,
+ &gEfiMemorySubClassGuid
+ );
+
+}
+
+/**
+ Field Filling Function for Memory SubClass record type 5
+ -- Memory Device Mapped Address: SMBIOS Type 20
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMemoryType5 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MEMORY_DEVICE_START_ADDRESS_DATA *Mdsa;
+ EFI_PHYSICAL_ADDRESS TempData;
+
+ Mdsa = (EFI_MEMORY_DEVICE_START_ADDRESS_DATA *) RecordData;
+
+ //
+ // Starting Address
+ //
+ TempData = RShiftU64 (Mdsa->MemoryDeviceStartAddress, 10);
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE20, StartingAddress),
+ &TempData,
+ 4
+ );
+
+ //
+ // Ending Address
+ //
+ TempData = RShiftU64 (Mdsa->MemoryDeviceEndAddress, 10);
+ CopyMem (
+ (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE20, EndingAddress),
+ &TempData,
+ 4
+ );
+
+ //
+ // Memory Device Link
+ //
+ SmbiosFldInterLink (
+ StructureNode,
+ (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE20, MemoryDeviceHandle),
+ 17, // SMBIOS type 17
+ &Mdsa->PhysicalMemoryDeviceLink,
+ &gEfiMemorySubClassGuid
+ );
+
+ //
+ // Memory Array Mapped Address Link
+ //
+ SmbiosFldInterLink (
+ StructureNode,
+ (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE20, MemoryArrayMappedAddressHandle),
+ 19, // SMBIOS type 19
+ &Mdsa->PhysicalMemoryArrayLink,
+ &gEfiMemorySubClassGuid
+ );
+
+ //
+ // Memory Device Partition Row Position
+ //
+ *(UINT8 *) ((UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE20, PartitionRowPosition)) = (UINT8) Mdsa->MemoryDevicePartitionRowPosition;
+
+ //
+ // Memory Device Interleave Position
+ //
+ *(UINT8 *) ((UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE20, InterleavePosition)) = (UINT8) Mdsa->MemoryDeviceInterleavePosition;
+
+ //
+ // Memory Device Interleave Data Depth
+ //
+ *(UINT8 *) ((UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE20, InterleavedDataDepth)) = (UINT8) Mdsa->MemoryDeviceInterleaveDataDepth;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Memory SubClass record type 6
+ -- Memory Channel Type: SMBIOS Type 37
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMemoryType6 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MEMORY_CHANNEL_TYPE_DATA *McTa;
+ EFI_STATUS Status;
+
+ McTa = (EFI_MEMORY_CHANNEL_TYPE_DATA *) RecordData;
+
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE37, ChannelType)) = (UINT8) (McTa->MemoryChannelType);
+
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE37, MaximumChannelLoad)) = (UINT8) (McTa->MemoryChannelMaximumLoad);
+
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE37, MemoryDeviceCount)) = (UINT8) (McTa->MemoryChannelDeviceCount);
+
+ //
+ // Update the length field
+ // Multiple device loads are filled through SmbiosFldMemoryType7
+ //
+ StructureNode->Structure->Length = (UINT8)(StructureNode->Structure->Length +
+ sizeof(MEMORY_DEVICE) * McTa->MemoryChannelDeviceCount);
+ Status = SmbiosEnlargeStructureBuffer(
+ StructureNode,
+ StructureNode->Structure->Length,
+ StructureNode->StructureSize,
+ StructureNode->StructureSize + sizeof(MEMORY_DEVICE) * McTa->MemoryChannelDeviceCount
+ );
+ return Status;
+}
+
+/**
+ Field Filling Function for Memory SubClass record type 7
+ -- Memory Channel Device: SMBIOS Type 37
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMemoryType7 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MEMORY_CHANNEL_DEVICE_DATA *Mcdd;
+ UINTN DeviceLoadOffset;
+ UINTN DeviceLoadHandleOffset;
+
+ Mcdd = (EFI_MEMORY_CHANNEL_DEVICE_DATA *) RecordData;
+
+ if (Mcdd->DeviceId < 1) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DeviceLoadOffset = OFFSET_OF (SMBIOS_TABLE_TYPE37, MemoryDevice[0]) + 3 * (Mcdd->DeviceId - 1);
+ DeviceLoadHandleOffset = OFFSET_OF (SMBIOS_TABLE_TYPE37, MemoryDevice[1]) + 3 * (Mcdd->DeviceId - 1);
+
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + DeviceLoadOffset) = (UINT8) (Mcdd->MemoryChannelDeviceLoad);
+
+ //
+ // Memory Device Handle Link
+ //
+ return SmbiosFldInterLink (
+ StructureNode,
+ (UINT16) DeviceLoadHandleOffset,
+ 17, // Smbios type 17 -- Physical Memory Device
+ &Mcdd->DeviceLink,
+ &gEfiMemorySubClassGuid
+ );
+
+}
+
+/**
+ Field Filling Function for Memory SubClass record type 8
+ -- Memory Controller information: SMBIOS Type 5
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMemoryType8 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MEMORY_CONTROLLER_INFORMATION_DATA *MemoryController;
+ UINT32 NewMinimalSize;
+ UINT16 Count;
+ EFI_INTER_LINK_DATA *Link;
+ EFI_STATUS Status;
+
+ NewMinimalSize = 0;
+
+ //
+ // There is an update from EFI_MEMORY_CONTROLLER_INFORMATION to
+ // EFI_MEMORY_CONTROLLER_INFORMATION_DATA. Multiple MemoryModuleConfig
+ // handles are filled.
+ //
+ MemoryController = (EFI_MEMORY_CONTROLLER_INFORMATION_DATA *)RecordData;
+
+ //
+ // ErrorDetectingMethod
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, ErrDetectMethod),
+ &MemoryController->ErrorDetectingMethod,
+ 1
+ );
+
+ //
+ // ErrorCorrectingCapability
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, ErrCorrectCapability),
+ &MemoryController->ErrorCorrectingCapability,
+ 1
+ );
+
+ //
+ // MemorySupportedInterleave
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, SupportInterleave),
+ &MemoryController->MemorySupportedInterleave,
+ 1
+ );
+
+ //
+ // MemoryCurrentInterleave
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, CurrentInterleave),
+ &MemoryController->MemoryCurrentInterleave,
+ 1
+ );
+
+ //
+ // MaxMemoryModuleSize
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, MaxMemoryModuleSize),
+ &MemoryController->MaxMemoryModuleSize,
+ 1
+ );
+
+ //
+ // MemorySpeedType
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, SupportSpeed),
+ &MemoryController->MemorySpeedType,
+ 2
+ );
+
+ //
+ // MemorySupportedType
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, SupportMemoryType),
+ &MemoryController->MemorySupportedType,
+ 2
+ );
+
+ //
+ // MemoryModuleVoltage
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, MemoryModuleVoltage),
+ &MemoryController->MemoryModuleVoltage,
+ 1
+ );
+
+ //
+ // NumberofMemorySlot
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, AssociatedMemorySlotNum),
+ &MemoryController->NumberofMemorySlot,
+ 1
+ );
+
+ if (MemoryController->NumberofMemorySlot == 0) {
+ //
+ // EnabledCorrectingCapability
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, MemoryModuleConfigHandles),
+ &MemoryController->EnabledCorrectingCapability,
+ 1
+ );
+ } else {
+ //
+ // Memory module configuration handles exist
+ // we should enlarge smbios entry buffer from minimal size
+ //
+ NewMinimalSize = (MemoryController->NumberofMemorySlot) * sizeof(UINT16) + StructureNode->StructureSize;
+ StructureNode->Structure->Length = (UINT8) (NewMinimalSize - 2);
+ Status = SmbiosEnlargeStructureBuffer (StructureNode, StructureNode->Structure->Length, StructureNode->StructureSize, NewMinimalSize);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // MemoryModuleConfigHandles
+ //
+ for (Count = 0, Link = MemoryController->MemoryModuleConfig;
+ Count < MemoryController->NumberofMemorySlot;
+ Count++, Link++) {
+ SmbiosFldInterLink (
+ StructureNode,
+ (UINT16) (OFFSET_OF (SMBIOS_TABLE_TYPE5, MemoryModuleConfigHandles) + Count * sizeof(UINT16)),
+ 6, // SMBIOS type 6
+ Link,
+ &gEfiMemorySubClassGuid
+ );
+ }
+
+ //
+ // EnabledCorrectingCapability
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, MemoryModuleConfigHandles) + (MemoryController->NumberofMemorySlot) * sizeof(UINT16),
+ &MemoryController->EnabledCorrectingCapability,
+ 1
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Memory SubClass record type
+ -- Memory 32 Bit Error Information: SMBIOS Type 18
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMemoryType9 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MEMORY_32BIT_ERROR_INFORMATION *MemoryInfo;
+
+ MemoryInfo = (EFI_MEMORY_32BIT_ERROR_INFORMATION *)RecordData;
+
+ //
+ // MemoryErrorType
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE18, ErrorType),
+ &MemoryInfo->MemoryErrorType,
+ 1
+ );
+
+ //
+ // MemoryErrorGranularity
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE18, ErrorGranularity),
+ &MemoryInfo->MemoryErrorGranularity,
+ 1
+ );
+
+ //
+ // MemoryErrorOperation
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE18, ErrorOperation),
+ &MemoryInfo->MemoryErrorOperation,
+ 1
+ );
+
+ //
+ // VendorSyndrome
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE18, VendorSyndrome),
+ &MemoryInfo->VendorSyndrome,
+ 4
+ );
+
+ //
+ // MemoryArrayErrorAddress
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE18, MemoryArrayErrorAddress),
+ &MemoryInfo->MemoryArrayErrorAddress,
+ 4
+ );
+
+ //
+ // DeviceErrorAddress
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE18, DeviceErrorAddress),
+ &MemoryInfo->DeviceErrorAddress,
+ 4
+ );
+
+ //
+ // DeviceErrorResolution
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE18, ErrorResolution),
+ &MemoryInfo->DeviceErrorResolution,
+ 4
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Memory SubClass record type
+ -- Memory 64 Bit Error Information: SMBIOS Type 33
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMemoryType10 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MEMORY_64BIT_ERROR_INFORMATION *MemoryInfo;
+
+ MemoryInfo = (EFI_MEMORY_64BIT_ERROR_INFORMATION *)RecordData;
+
+ //
+ // MemoryErrorType
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE33, ErrorType),
+ &MemoryInfo->MemoryErrorType,
+ 1
+ );
+
+ //
+ // MemoryErrorGranularity
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE33, ErrorGranularity),
+ &MemoryInfo->MemoryErrorGranularity,
+ 1
+ );
+
+ //
+ // MemoryErrorOperation
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE33, ErrorOperation),
+ &MemoryInfo->MemoryErrorOperation,
+ 1
+ );
+
+ //
+ // VendorSyndrome
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE33, VendorSyndrome),
+ &MemoryInfo->VendorSyndrome,
+ 4
+ );
+
+ //
+ // MemoryArrayErrorAddress
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE33, MemoryArrayErrorAddress),
+ &MemoryInfo->MemoryArrayErrorAddress,
+ 8
+ );
+
+ //
+ // DeviceErrorAddress
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE33, DeviceErrorAddress),
+ &MemoryInfo->DeviceErrorAddress,
+ 8
+ );
+
+ //
+ // DeviceErrorResolution
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE33, ErrorResolution),
+ &MemoryInfo->DeviceErrorResolution,
+ 4
+ );
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/MiscConv.c b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/MiscConv.c
new file mode 100644
index 0000000..3ffbbe5
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/MiscConv.c
@@ -0,0 +1,2444 @@
+/** @file
+ Routines that support Misc SubClass data records translation.
+
+Copyright (c) 2009, Intel Corporation
+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 "Thunk.h"
+
+/**
+ Field Filling Function for Misc SubClass record type 0 -- Bios Information.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType0 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_MISC_BIOS_VENDOR_DATA *BiosInfo;
+
+ Status = EFI_SUCCESS;
+ BiosInfo = NULL;
+
+ BiosInfo = (EFI_MISC_BIOS_VENDOR_DATA *) RecordData;
+
+ //
+ // Bios Vendor
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE0, Vendor),
+ &(BiosInfo->BiosVendor),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // Bios Version
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE0, BiosVersion),
+ &(BiosInfo->BiosVersion),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // Bios Release Date
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE0, BiosReleaseDate),
+ &(BiosInfo->BiosReleaseDate),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // Bios Starting Address Segment
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE0, BiosSegment),
+ &BiosInfo->BiosStartingAddress,
+ 2
+ );
+
+ //
+ // Bios Physical device size
+ //
+ SmbiosFldBase2ToByteWith64K (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE0, BiosSize),
+ &BiosInfo->BiosPhysicalDeviceSize,
+ sizeof (EFI_EXP_BASE2_DATA)
+ );
+ (*(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE0, BiosSize)))--;
+
+ //
+ // Bios Characteristics
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE0, BiosCharacteristics),
+ &BiosInfo->BiosCharacteristics1,
+ 4
+ );
+
+ //
+ // Bios Characteristics higher four bytes
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE0, BiosCharacteristics) + 4,
+ &BiosInfo->BiosCharacteristics2,
+ 4
+ );
+
+ //
+ // Bios Characteristics Extension1/2
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE0, BIOSCharacteristicsExtensionBytes),
+ (UINT8 *) &BiosInfo->BiosCharacteristics1 + 4,
+ 2
+ );
+
+ //
+ // System BIOS Major Release
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE0, SystemBiosMajorRelease),
+ (UINT8 *) &BiosInfo->BiosMajorRelease,
+ 1
+ );
+
+ //
+ // System BIOS Minor Release
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE0, SystemBiosMinorRelease),
+ (UINT8 *) &BiosInfo->BiosMinorRelease,
+ 1
+ );
+
+ //
+ // Embedded Controller Firmware Major Release
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE0, EmbeddedControllerFirmwareMajorRelease),
+ (UINT8 *) &BiosInfo->BiosEmbeddedFirmwareMajorRelease,
+ 1
+ );
+
+ //
+ // Embedded Controller Firmware Minor Release
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE0, EmbeddedControllerFirmwareMinorRelease),
+ (UINT8 *) &BiosInfo->BiosEmbeddedFirmwareMinorRelease,
+ 1
+ );
+
+ return Status;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 1 -- System Information.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType1 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_MISC_SYSTEM_MANUFACTURER_DATA *SystemInfo;
+
+ Status = EFI_SUCCESS;
+ SystemInfo = NULL;
+
+ SystemInfo = (EFI_MISC_SYSTEM_MANUFACTURER_DATA *) RecordData;
+
+ //
+ // System Manufacturer
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE1, Manufacturer),
+ &(SystemInfo->SystemManufacturer),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // System Product Name
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE1, ProductName),
+ &(SystemInfo->SystemProductName),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // System Version
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE1, Version),
+ &(SystemInfo->SystemVersion),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // System Serial Number
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE1, SerialNumber),
+ &(SystemInfo->SystemSerialNumber),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // Uuid
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE1, Uuid),
+ &SystemInfo->SystemUuid,
+ 16
+ );
+
+ //
+ // Wakeup Type
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE1, WakeUpType),
+ &SystemInfo->SystemWakeupType,
+ 1
+ );
+
+ //
+ // System SKU Number
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE1, SKUNumber),
+ &(SystemInfo->SystemSKUNumber),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // System Family
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE1, Family),
+ &(SystemInfo->SystemFamily),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ return Status;
+}
+
+/**
+ Field Filling Function for record type 2 -- Base Board Manufacture.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType2 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_MISC_BASE_BOARD_MANUFACTURER_DATA *Bbm;
+ Status = EFI_SUCCESS;
+ Bbm = (EFI_MISC_BASE_BOARD_MANUFACTURER_DATA *) RecordData;
+
+ //
+ // Manufacturer
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE2, Manufacturer),
+ &(Bbm->BaseBoardManufacturer),
+ 2
+ );
+
+ //
+ // Product
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE2, ProductName),
+ &(Bbm->BaseBoardProductName),
+ 2
+ );
+
+ //
+ // Version
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE2, Version),
+ &(Bbm->BaseBoardVersion),
+ 2
+ );
+
+ //
+ // Serial Number
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE2, SerialNumber),
+ &(Bbm->BaseBoardSerialNumber),
+ 2
+ );
+
+ //
+ // Asset Tag
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE2, AssetTag),
+ &(Bbm->BaseBoardAssetTag),
+ 2
+ );
+
+ //
+ // Location in Chassis
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE2, LocationInChassis),
+ &(Bbm->BaseBoardChassisLocation),
+ 2
+ );
+
+ //
+ // Feature Flags
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE2, FeatureFlag),
+ &Bbm->BaseBoardFeatureFlags,
+ 1
+ );
+
+ //
+ // Board Type
+ //
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE2, BoardType)) = (UINT8) Bbm->BaseBoardType;
+
+ //
+ // Chassis Handle
+ //
+ SmbiosFldInterLink (
+ StructureNode,
+ (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE2, ChassisHandle),
+ 3, // SMBIOS type 3 - System Enclosure or Chassis
+ &Bbm->BaseBoardChassisLink,
+ &gEfiMiscSubClassGuid
+ );
+
+ //
+ // Number of Contained Object Handles
+ //
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE2, NumberOfContainedObjectHandles)) = (UINT8) Bbm->BaseBoardNumberLinks;
+
+ return Status;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 3 -
+ - System Enclosure or Chassis.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType3 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_MISC_CHASSIS_MANUFACTURER_DATA *Ec;
+ EFI_MISC_ELEMENTS *Element;
+ UINT16 Index;
+ UINT8 ContainedElementType;
+ Status = EFI_SUCCESS;
+ Ec = (EFI_MISC_CHASSIS_MANUFACTURER_DATA *) RecordData;
+
+ //
+ // Chassis Type
+ //
+ *(UINT8*)((UINT8 *) (StructureNode->Structure) +
+ OFFSET_OF (SMBIOS_TABLE_TYPE3, Type))
+ = (UINT8) (Ec->ChassisType.ChassisType | Ec->ChassisType.ChassisLockPresent << 7);
+
+
+ //
+ // Chassis Bootup State
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE3, BootupState),
+ &Ec->ChassisBootupState,
+ 1
+ );
+
+ //
+ // Chassis Power Supply State
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE3, PowerSupplyState),
+ &Ec->ChassisPowerSupplyState,
+ 1
+ );
+
+ //
+ // Chassis Thermal State
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE3, ThermalState),
+ &Ec->ChassisThermalState,
+ 1
+ );
+
+ //
+ // Chassis Security State
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE3, SecurityStatus),
+ &Ec->ChassisSecurityState,
+ 1
+ );
+
+ //
+ // Chassis Oem Defined
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE3, OemDefined),
+ &Ec->ChassisOemDefined,
+ 4
+ );
+
+ //
+ // Chassis Height
+ //
+ *(UINT8*)((UINT8*)(StructureNode->Structure) +
+ OFFSET_OF (SMBIOS_TABLE_TYPE3, Height))
+ = (UINT8)Ec->ChassisHeight;
+
+ //
+ // Chassis Number Power Cords
+ //
+ *(UINT8*)((UINT8*)(StructureNode->Structure) +
+ OFFSET_OF (SMBIOS_TABLE_TYPE3, NumberofPowerCords))
+ = (UINT8)Ec->ChassisNumberPowerCords;
+
+ //
+ // Chassis Element Count
+ //
+ *(UINT8*)((UINT8*)(StructureNode->Structure) +
+ OFFSET_OF (SMBIOS_TABLE_TYPE3, ContainedElementCount))
+ = (UINT8)Ec->ChassisElementCount;
+
+ if( Ec->ChassisElementCount ) {
+ //
+ // Element Record Length
+ // Current solution covers first 3 bytes; user can extend to meet its requirements.
+ //
+ *(UINT8*)((UINT8*)(StructureNode->Structure) +
+ OFFSET_OF (SMBIOS_TABLE_TYPE3, ContainedElementRecordLength))
+ = (UINT8)sizeof(CONTAINED_ELEMENT);
+
+ //
+ // Update the structure's length and StructureSize
+ //
+ StructureNode->Structure->Length = (UINT8)(StructureNode->Structure->Length +
+ Ec->ChassisElementCount * sizeof(CONTAINED_ELEMENT));
+ Status = SmbiosEnlargeStructureBuffer (
+ StructureNode,
+ StructureNode->Structure->Length,
+ StructureNode->StructureSize,
+ StructureNode->StructureSize + Ec->ChassisElementCount * sizeof(CONTAINED_ELEMENT)
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Contained Elements
+ //
+ for (Index=0, Element = &Ec->ChassisElements;
+ Index < Ec->ChassisElementCount;
+ Index += 1, Element ++) {
+
+ //
+ // ContainedElementType
+ //
+ ContainedElementType = (UINT8)((Element->ChassisElementType.RecordType == 1)
+ ? (UINT8)(Element->ChassisElementType.RecordType << 7 | Element->ChassisElementType.Type)
+ : (UINT8)(Element->ChassisBaseBoard));
+ *(UINT8*)((UINT8*)(StructureNode->Structure) +
+ OFFSET_OF (SMBIOS_TABLE_TYPE3, ContainedElements) +
+ Index * sizeof(CONTAINED_ELEMENT) +
+ OFFSET_OF(CONTAINED_ELEMENT,ContainedElementType))
+ = ContainedElementType;
+
+ //
+ // ContainedElementMinimum
+ //
+ *(UINT8*)((UINT8*)(StructureNode->Structure) +
+ OFFSET_OF (SMBIOS_TABLE_TYPE3, ContainedElements) +
+ Index * sizeof(CONTAINED_ELEMENT) +
+ OFFSET_OF(CONTAINED_ELEMENT,ContainedElementMinimum))
+ = (UINT8)Element->ChassisElementMinimum;
+
+ //
+ // ContainedElementMaximum
+ //
+ *(UINT8*)((UINT8*)(StructureNode->Structure) +
+ OFFSET_OF (SMBIOS_TABLE_TYPE3, ContainedElements) +
+ Index * sizeof(CONTAINED_ELEMENT) +
+ OFFSET_OF(CONTAINED_ELEMENT,ContainedElementMaximum))
+ = (UINT8)Element->ChassisElementMaximum;
+ }
+ }
+
+ //
+ // Move the filling of following four String fields after Contained Elements
+ // because they would break SMBIOS table.
+ // Chassis Manufacturer
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE3, Manufacturer),
+ &(Ec->ChassisManufacturer),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // Chassis Version
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE3, Version),
+ &(Ec->ChassisVersion),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // Chassis Serial Number
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE3, SerialNumber),
+ &(Ec->ChassisSerialNumber),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // Chassis Asset Tag
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE3, AssetTag),
+ &(Ec->ChassisAssetTag),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ return Status;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 8 -- Port Connector.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType8 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *Picd;
+
+ Status = EFI_SUCCESS;
+ Picd = (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *) RecordData;
+
+ //
+ // Internal Connector Designator
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE8, InternalReferenceDesignator),
+ &(Picd->PortInternalConnectorDesignator),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // Internal Connector Type
+ //
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE8, InternalConnectorType)) = (UINT8) Picd->PortInternalConnectorType;
+
+ //
+ // External Connector Designator
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE8, ExternalReferenceDesignator),
+ &(Picd->PortExternalConnectorDesignator),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // Internal Connector Type
+ //
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE8, ExternalConnectorType)) = (UINT8) Picd->PortExternalConnectorType;
+
+ //
+ // Internal Connector Type
+ //
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE8, PortType)) = (UINT8) Picd->PortType;
+
+ return Status;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 9 -- System slot.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType9 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA *Slot;
+
+ Status = EFI_SUCCESS;
+ Slot = (EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA *) RecordData;
+
+ //
+ // Slot Designation
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE9, SlotDesignation),
+ &(Slot->SlotDesignation),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // Slot Type
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE9, SlotType),
+ &Slot->SlotType,
+ 1
+ );
+
+ //
+ // Slot Data Bus Width
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE9, SlotDataBusWidth),
+ &Slot->SlotDataBusWidth,
+ 1
+ );
+
+ //
+ // Slot Usage
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE9, CurrentUsage),
+ &Slot->SlotUsage,
+ 1
+ );
+
+ //
+ // Slot Length
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE9, SlotLength),
+ &Slot->SlotLength,
+ 1
+ );
+
+ //
+ // Slot Id
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE9, SlotID),
+ &Slot->SlotId,
+ 2
+ );
+
+ //
+ // Slot Characteristics
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE9, SlotCharacteristics1),
+ &Slot->SlotCharacteristics,
+ 2
+ );
+
+ return Status;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 10 - Onboard Device.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType10 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_MISC_ONBOARD_DEVICE_DATA *OnboardDevice;
+ UINTN NumberOfDevices;
+ UINTN Index;
+ UINT8 StatusAndType;
+
+ Status = EFI_SUCCESS;
+ OnboardDevice = (EFI_MISC_ONBOARD_DEVICE_DATA *) RecordData;
+
+ NumberOfDevices = (StructureNode->Structure->Length - 4) / 2;
+ for (Index = 0; Index < NumberOfDevices; Index += 1) {
+ //
+ // OnBoard Device Description
+ //
+ SmbiosFldString (
+ StructureNode,
+ (UINT32) (OFFSET_OF (SMBIOS_TABLE_TYPE10, Device) + 1 + (2 * Index)),
+ &(OnboardDevice->OnBoardDeviceDescription),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // Status & Type: Bit 7 Devicen Status, Bits 6:0 Type of Device
+ //
+ StatusAndType = (UINT8) OnboardDevice->OnBoardDeviceStatus.DeviceType;
+ if (OnboardDevice->OnBoardDeviceStatus.DeviceEnabled != 0) {
+ StatusAndType |= 0x80;
+ } else {
+ StatusAndType &= 0x7F;
+ }
+
+ * (UINT8 *) ((UINT8 *) (StructureNode->Structure) + (OFFSET_OF (SMBIOS_TABLE_TYPE10, Device) + (2 * Index))) = StatusAndType;
+ }
+
+ return Status;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 11 - OEM Strings.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType11 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_OEM_STRING_DATA *OemString;
+
+ OemString = (EFI_MISC_OEM_STRING_DATA *)RecordData;
+ //
+ // OEM String data
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE11, StringCount),
+ &(OemString->OemStringRef[0]),
+ 2
+ );
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 12 - System Options.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType12 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_MISC_SYSTEM_OPTION_STRING_DATA *Sos;
+ UINTN NumberOfInstallableLanguages;
+ UINTN Index;
+
+ Status = EFI_SUCCESS;
+ Sos = (EFI_MISC_SYSTEM_OPTION_STRING_DATA *) RecordData;
+
+ //
+ // As MiscDataHub spec defines,
+ // NumberOfInstallableLanguages should retrieve from Type 13.
+ //
+ NumberOfInstallableLanguages = (StructureNode->Structure->Length - 4);
+ for (Index = 0; Index < NumberOfInstallableLanguages; Index += 1) {
+ //
+ // OnBoard Device Description
+ //
+ SmbiosFldString (
+ StructureNode,
+ (UINT32) (OFFSET_OF (SMBIOS_TABLE_TYPE12, StringCount) + (Index)),
+ &(Sos->SystemOptionStringRef[Index]),
+ 2
+ );
+ }
+
+ return Status;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 13 - BIOS Language.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType13 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES_DATA *InstallableLanguage;
+
+ InstallableLanguage = (EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES_DATA *) RecordData;
+
+ //
+ // Number Of Installable Languages
+ //
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE13, InstallableLanguages)) = (UINT8) (InstallableLanguage->NumberOfInstallableLanguages);
+
+ //
+ // Language Flags
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE13, Flags),
+ &InstallableLanguage->LanguageFlags,
+ 1
+ );
+
+ //
+ // Current Language Number
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE13, CurrentLanguages),
+ &(InstallableLanguage->CurrentLanguageNumber),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 14 - System Language String
+ Current solution assumes that EFI_MISC_SYSTEM_LANGUAGE_STRINGs are logged with
+ their LanguageId having ascending orders.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType14 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ UINT16 CurrentLanguageNumber;
+ EFI_MISC_SYSTEM_LANGUAGE_STRING *LanguageString;
+
+ LanguageString = (EFI_MISC_SYSTEM_LANGUAGE_STRING *) RecordData;
+
+ //
+ // Backup CurrentLanguage
+ //
+ CopyMem (
+ &CurrentLanguageNumber,
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE13, CurrentLanguages),
+ 1
+ );
+
+ //
+ // Clear the field so that SmbiosFldString can be reused
+ //
+ *(UINT8 *)((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE13, CurrentLanguages)) = 0;
+
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE13, CurrentLanguages),
+ &(LanguageString->SystemLanguageString),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // Restore CurrentLanguage
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE13, CurrentLanguages),
+ &CurrentLanguageNumber,
+ 1
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 15 -- System Event Log.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType15 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_MISC_SYSTEM_EVENT_LOG_DATA *SystemEventLog;
+
+ Status = EFI_SUCCESS;
+ SystemEventLog = NULL;
+
+ SystemEventLog = (EFI_MISC_SYSTEM_EVENT_LOG_DATA *) RecordData;
+
+ //
+ // Log Area Length
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE15, LogAreaLength),
+ &(SystemEventLog->LogAreaLength),
+ 2
+ );
+
+ //
+ // Log Header Start Offset
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE15, LogHeaderStartOffset),
+ &(SystemEventLog->LogHeaderStartOffset),
+ 2
+ );
+
+ //
+ // Log Data Start Offset
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE15, LogDataStartOffset),
+ &(SystemEventLog->LogDataStartOffset),
+ 2
+ );
+
+ //
+ // Access Method
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE15, AccessMethod),
+ &(SystemEventLog->AccessMethod),
+ 1
+ );
+
+ //
+ // Log Status
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE15, LogStatus),
+ &(SystemEventLog->LogStatus),
+ 1
+ );
+
+ //
+ // Log Change Token
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE15, LogChangeToken),
+ &(SystemEventLog->LogChangeToken),
+ 4
+ );
+
+ //
+ // Access Method Address
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE15, AccessMethodAddress),
+ &(SystemEventLog->AccessMethodAddress),
+ 4
+ );
+
+ //
+ // Log Header Format
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE15, LogHeaderFormat),
+ &(SystemEventLog->LogHeaderFormat),
+ 1
+ );
+
+ //
+ // Number of Supported Log Type Descriptors
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE15, NumberOfSupportedLogTypeDescriptors),
+ &(SystemEventLog->NumberOfSupportedLogType),
+ 1
+ );
+
+ //
+ // Length of each Log Type Descriptor
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE15, LengthOfLogTypeDescriptor),
+ &(SystemEventLog->LengthOfLogDescriptor),
+ 1
+ );
+
+ return Status;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 21 - Pointing Device.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType21 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_POINTING_DEVICE_TYPE_DATA *PointingDeviceData;
+
+ PointingDeviceData = (EFI_MISC_POINTING_DEVICE_TYPE_DATA *) RecordData;
+
+ //
+ // Pointing Device Type
+ //
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE21, Type)) = (UINT8) (PointingDeviceData->PointingDeviceType);
+
+ //
+ // Pointing Device Interface
+ //
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE21, Interface)) = (UINT8) (PointingDeviceData->PointingDeviceInterface);
+
+ //
+ // Number Pointing Device Buttons
+ //
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE21, NumberOfButtons)) = (UINT8) (PointingDeviceData->NumberPointingDeviceButtons);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 22 - Portable Battery.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType22 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_PORTABLE_BATTERY *PortableBattery;
+ STRING_REF Chemistry;
+ PortableBattery = (EFI_MISC_PORTABLE_BATTERY *)RecordData;
+
+ //
+ // Location
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE22, Location),
+ &(PortableBattery->Location),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // Manufacturer
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE22, Manufacturer),
+ &(PortableBattery->Manufacturer),
+ 2
+ );
+
+ //
+ // ManufactureDate
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE22, ManufactureDate),
+ &(PortableBattery->ManufactureDate),
+ 2
+ );
+
+ //
+ // SerialNumber
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE22, SerialNumber),
+ &(PortableBattery->SerialNumber),
+ 2
+ );
+
+ //
+ // DeviceName
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE22, DeviceName),
+ &(PortableBattery->DeviceName),
+ 2
+ );
+
+ //
+ // DeviceChemistry
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE22, DeviceChemistry),
+ &PortableBattery->DeviceChemistry,
+ 1
+ );
+
+ //
+ // DesignCapacity
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE22, DeviceCapacity),
+ &PortableBattery->DesignCapacity,
+ 2
+ );
+
+ //
+ // DesignVoltage
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE22, DesignVoltage),
+ &PortableBattery->DesignVoltage,
+ 2
+ );
+
+ //
+ // SBDSVersionNumber
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE22, SBDSVersionNumber),
+ &(PortableBattery->SBDSVersionNumber),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // MaximumError
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE22, MaximumErrorInBatteryData),
+ &PortableBattery->MaximumError,
+ 1
+ );
+
+ //
+ // SBDSSerialNumber
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE22, SBDSSerialNumber),
+ &PortableBattery->SBDSSerialNumber,
+ 2
+ );
+
+ //
+ // SBDSManufactureDate
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE22, SBDSManufactureDate),
+ &PortableBattery->SBDSManufactureDate,
+ 2
+ );
+
+ //
+ // Avoid alignment issue on IPF
+ //
+ CopyMem (
+ &Chemistry,
+ &PortableBattery->SBDSDeviceChemistry,
+ 2
+ );
+
+ //
+ // SBDSDeviceChemistry
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE22, SBDSDeviceChemistry),
+ &Chemistry,
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // DesignCapacityMultiplier
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE22, DesignCapacityMultiplier),
+ &PortableBattery->DesignCapacityMultiplier,
+ 1
+ );
+
+ //
+ // OEMSpecific
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE22, OEMSpecific),
+ &PortableBattery->OEMSpecific,
+ 4
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 23 - System Reset.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType23 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_RESET_CAPABILITIES_DATA *SystemResetData;
+
+ SystemResetData = (EFI_MISC_RESET_CAPABILITIES_DATA *) RecordData;
+
+ //
+ // Reset Capabilities
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE23, Capabilities),
+ &(SystemResetData->ResetCapabilities),
+ 1
+ );
+
+ //
+ // Reset Count
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE23, ResetCount),
+ &(SystemResetData->ResetCount),
+ 2
+ );
+
+ //
+ // Reset Limit
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE23, ResetLimit),
+ &(SystemResetData->ResetLimit),
+ 2
+ );
+
+ //
+ // Reset Timer Interval
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE23, TimerInterval),
+ &(SystemResetData->ResetTimerInterval),
+ 2
+ );
+
+ //
+ // Reset Timeout
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE23, Timeout),
+ &(SystemResetData->ResetTimeout),
+ 2
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 24 - Hardware Security.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType24 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_HARDWARE_SECURITY_SETTINGS_DATA *HardwareSecurity;
+
+ HardwareSecurity = (EFI_MISC_HARDWARE_SECURITY_SETTINGS_DATA *)RecordData;
+
+ //
+ // Hardware Security Settings
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE24, HardwareSecuritySettings),
+ &HardwareSecurity->HardwareSecuritySettings,
+ 1
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 25 - System Power Controls.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType25 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_SCHEDULED_POWER_ON_MONTH *PowerOnMonth;
+
+ PowerOnMonth = (EFI_MISC_SCHEDULED_POWER_ON_MONTH *)RecordData;
+
+ //
+ // ScheduledPoweronMonth
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE25, NextScheduledPowerOnMonth),
+ &PowerOnMonth->ScheduledPoweronMonth,
+ 1
+ );
+
+ //
+ // ScheduledPoweronDayOfMonth
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE25, NextScheduledPowerOnDayOfMonth),
+ &PowerOnMonth->ScheduledPoweronDayOfMonth,
+ 1
+ );
+
+ //
+ // ScheduledPoweronHour
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE25, NextScheduledPowerOnHour),
+ &PowerOnMonth->ScheduledPoweronHour,
+ 1
+ );
+
+ //
+ // ScheduledPoweronMinute
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE25, NextScheduledPowerOnMinute),
+ &PowerOnMonth->ScheduledPoweronMinute,
+ 1
+ );
+
+ //
+ // ScheduledPoweronSecond
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE25, NextScheduledPowerOnSecond),
+ &PowerOnMonth->ScheduledPoweronSecond,
+ 1
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 26 - Voltage Probe.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType26 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_VOLTAGE_PROBE_DESCRIPTION *VoltageProbe;
+
+ VoltageProbe = (EFI_MISC_VOLTAGE_PROBE_DESCRIPTION *)RecordData;
+
+ //
+ // VoltageProbe Description
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE26, Description),
+ &(VoltageProbe->VoltageProbeDescription),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // VoltageProbeLocation
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE26, LocationAndStatus),
+ &VoltageProbe->VoltageProbeLocation,
+ 1
+ );
+
+ //
+ // VoltageProbeMaximumValue
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE26, MaximumValue),
+ &VoltageProbe->VoltageProbeMaximumValue,
+ 2
+ );
+
+ //
+ // VoltageProbeMinimumValue
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE26, MinimumValue),
+ &VoltageProbe->VoltageProbeMinimumValue,
+ 2
+ );
+
+ //
+ // VoltageProbeResolution
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE26, Resolution),
+ &VoltageProbe->VoltageProbeResolution,
+ 2
+ );
+
+ //
+ // VoltageProbeTolerance
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE26, Tolerance),
+ &VoltageProbe->VoltageProbeTolerance,
+ 2
+ );
+
+ //
+ // VoltageProbeAccuracy
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE26, Accuracy),
+ &VoltageProbe->VoltageProbeAccuracy,
+ 2
+ );
+
+ //
+ // VoltageProbeNominalValue
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE26, NominalValue),
+ &VoltageProbe->VoltageProbeNominalValue,
+ 2
+ );
+
+ //
+ // VoltageProbeOemDefined
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE26, OEMDefined),
+ &VoltageProbe->VoltageProbeOemDefined,
+ 4
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 27 - Cooling Device.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType27 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_COOLING_DEVICE_TEMP_LINK *CoolingDevice;
+
+ CoolingDevice = (EFI_MISC_COOLING_DEVICE_TEMP_LINK *)RecordData;
+
+ //
+ // Device Type
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE27, DeviceTypeAndStatus),
+ &CoolingDevice->CoolingDeviceType,
+ 1
+ );
+
+ //
+ // Temperature Probe
+ //
+ SmbiosFldInterLink (
+ StructureNode,
+ (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE27, TemperatureProbeHandle),
+ 28, // SMBIOS type 28 - Temperature Probe
+ &CoolingDevice->CoolingDeviceTemperatureLink,
+ &gEfiMiscSubClassGuid
+ );
+
+ //
+ // CoolingDeviceUnitGroup
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE27, CoolingUnitGroup),
+ &CoolingDevice->CoolingDeviceUnitGroup,
+ 1
+ );
+
+ //
+ // CoolingDeviceUnitGroup
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE27, OEMDefined),
+ &CoolingDevice->CoolingDeviceOemDefined,
+ 4
+ );
+
+ //
+ // CoolingDeviceNominalSpeed
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE27, NominalSpeed),
+ &CoolingDevice->CoolingDeviceNominalSpeed,
+ 2
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 28 -- Temperature Probe.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType28 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_TEMPERATURE_PROBE_DESCRIPTION *TemperatureProbe;
+
+ TemperatureProbe = (EFI_MISC_TEMPERATURE_PROBE_DESCRIPTION *)RecordData;
+
+ //
+ // TemperatureProbeDescription
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE28, Description),
+ &(TemperatureProbe->TemperatureProbeDescription),
+ 2
+ );
+
+ //
+ // TemperatureProbeLocation
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE28, LocationAndStatus),
+ &TemperatureProbe->TemperatureProbeLocation,
+ 1
+ );
+
+ //
+ // TemperatureProbeMaximumValue
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE28, MaximumValue),
+ &TemperatureProbe->TemperatureProbeMaximumValue,
+ 2
+ );
+
+ //
+ // TemperatureProbeMinimumValue
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE28, MinimumValue),
+ &TemperatureProbe->TemperatureProbeMinimumValue,
+ 2
+ );
+
+ //
+ // TemperatureProbeResolution
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE28, Resolution),
+ &TemperatureProbe->TemperatureProbeResolution,
+ 2
+ );
+
+
+ //
+ // TemperatureProbeTolerance
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE28, Tolerance),
+ &TemperatureProbe->TemperatureProbeTolerance,
+ 2
+ );
+
+ //
+ // TemperatureProbeAccuracy
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE28, Accuracy),
+ &TemperatureProbe->TemperatureProbeAccuracy,
+ 2
+ );
+
+ //
+ // TemperatureProbeNominalValue
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE28, NominalValue),
+ &TemperatureProbe->TemperatureProbeNominalValue,
+ 2
+ );
+
+ //
+ // TemperatureProbeOemDefined
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE28, OEMDefined),
+ &TemperatureProbe->TemperatureProbeOemDefined,
+ 4
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 29 -- Electrical Current Probe.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType29 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_ELECTRICAL_CURRENT_PROBE_DESCRIPTION *ElectricalProbe;
+
+ ElectricalProbe = (EFI_MISC_ELECTRICAL_CURRENT_PROBE_DESCRIPTION *)RecordData;
+
+ //
+ // ElectricalCurrentProbeDescription
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE29, Description),
+ &(ElectricalProbe->ElectricalCurrentProbeDescription),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // ElectricalCurrentProbeLocation
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE29, LocationAndStatus),
+ &ElectricalProbe->ElectricalCurrentProbeLocation,
+ 1
+ );
+
+ //
+ // ElectricalCurrentProbeMaximumValue
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE29, MaximumValue),
+ &ElectricalProbe->ElectricalCurrentProbeMaximumValue,
+ 2
+ );
+
+ //
+ // ElectricalCurrentProbeMinimumValue
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE29, MinimumValue),
+ &ElectricalProbe->ElectricalCurrentProbeMinimumValue,
+ 2
+ );
+
+ //
+ // ElectricalCurrentProbeResolution
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE29, Resolution),
+ &ElectricalProbe->ElectricalCurrentProbeResolution,
+ 2
+ );
+
+ //
+ // ElectricalCurrentProbeTolerance
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE29, Tolerance),
+ &ElectricalProbe->ElectricalCurrentProbeTolerance,
+ 2
+ );
+
+ //
+ // ElectricalCurrentProbeAccuracy
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE29, Accuracy),
+ &ElectricalProbe->ElectricalCurrentProbeAccuracy,
+ 2
+ );
+ //
+ // ElectricalCurrentProbeNominalValue
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE29, NominalValue),
+ &ElectricalProbe->ElectricalCurrentProbeNominalValue,
+ 2
+ );
+
+ //
+ // ElectricalCurrentProbeOemDefined
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE29, OEMDefined),
+ &ElectricalProbe->ElectricalCurrentProbeOemDefined,
+ 4
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 30 -- Out-of-Band Remote Access.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType30 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_REMOTE_ACCESS_MANUFACTURER_DESCRIPTION *RemoteData;
+
+ RemoteData = (EFI_MISC_REMOTE_ACCESS_MANUFACTURER_DESCRIPTION *)RecordData;
+
+ //
+ // ManufacturerNameDescription
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE30, ManufacturerName),
+ &(RemoteData->RemoteAccessManufacturerNameDescription),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // RemoteAccessConnections
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE30, Connections),
+ &RemoteData->RemoteAccessConnections,
+ 1
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 32 -- System Boot Information.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType32 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_MISC_BOOT_INFORMATION_STATUS_DATA *BootInfo;
+
+ Status = EFI_SUCCESS;
+ BootInfo = (EFI_MISC_BOOT_INFORMATION_STATUS_DATA *) RecordData;
+
+ //
+ // Set reserved bytes
+ //
+ ZeroMem ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE32, Reserved), 6);
+
+ //
+ // Set BootInformation Status
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE32, BootStatus),
+ &BootInfo->BootInformationStatus,
+ 1
+ );
+
+ //
+ // Set Additional Data
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE32, BootStatus) + 1,
+ &BootInfo->BootInformationData,
+ 9
+ );
+
+ return Status;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 34 -- Management Device.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType34 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_MANAGEMENT_DEVICE_DESCRIPTION *ManagementDevice;
+
+ ManagementDevice = (EFI_MISC_MANAGEMENT_DEVICE_DESCRIPTION *)RecordData;
+
+ //
+ // ManagementDeviceDescription
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE34, Description),
+ &(ManagementDevice->ManagementDeviceDescription),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // ManagementDeviceType
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE34, Type),
+ &ManagementDevice->ManagementDeviceType,
+ 1
+ );
+
+ //
+ // ManagementDeviceAddress
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE34, Address),
+ &ManagementDevice->ManagementDeviceAddress,
+ 4
+ );
+
+ //
+ // ManagementDeviceAddressType
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE34, AddressType),
+ &ManagementDevice->ManagementDeviceAddressType,
+ 1
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 36 -- Management Device Threshold.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType36 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_MANAGEMENT_DEVICE_THRESHOLD *DeviceThreshold;
+
+ DeviceThreshold = (EFI_MISC_MANAGEMENT_DEVICE_THRESHOLD *)RecordData;
+
+ //
+ // LowerThresNonCritical
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE36, LowerThresholdNonCritical),
+ &DeviceThreshold->LowerThresNonCritical,
+ 2
+ );
+
+ //
+ // UpperThresNonCritical
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE36, UpperThresholdNonCritical),
+ &DeviceThreshold->UpperThresNonCritical,
+ 2
+ );
+
+ //
+ // LowerThresCritical
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE36, LowerThresholdCritical),
+ &DeviceThreshold->LowerThresCritical,
+ 2
+ );
+
+ //
+ // UpperThresCritical
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE36, UpperThresholdCritical),
+ &DeviceThreshold->UpperThresCritical,
+ 2
+ );
+
+ //
+ // LowerThresNonRecover
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE36, LowerThresholdNonRecoverable),
+ &DeviceThreshold->LowerThresNonRecover,
+ 2
+ );
+
+ //
+ // UpperThresNonRecover
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE36, UpperThresholdNonRecoverable),
+ &DeviceThreshold->UpperThresNonRecover,
+ 2
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 38 -- IPMI device info.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType38 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_IPMI_INTERFACE_TYPE_DATA *IpmiInfo;
+
+ IpmiInfo = (EFI_MISC_IPMI_INTERFACE_TYPE_DATA *) RecordData;
+
+ //
+ // Interface Type
+ //
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE38, InterfaceType)) = (UINT8) (IpmiInfo->IpmiInterfaceType);
+
+ //
+ // IPMI specification revision
+ //
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE38, IPMISpecificationRevision)) =
+ (UINT8) ((IpmiInfo->IpmiSpecificationRevision.IpmiSpecLeastSignificantDigit) + \
+ (IpmiInfo->IpmiSpecificationRevision.IpmiSpecMostSignificantDigit << 4));
+
+ //
+ // I2C slave address
+ //
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE38, I2CSlaveAddress)) = (UINT8) (IpmiInfo->IpmiI2CSlaveAddress);
+
+ //
+ // NV storage device address
+ //
+ *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE38, NVStorageDeviceAddress)) = (UINT8) (IpmiInfo->IpmiNvDeviceAddress);
+
+ //
+ // Base address
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE38, BaseAddress),
+ &IpmiInfo->IpmiBaseAddress,
+ 8
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 39 -- Power supply.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType39 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_MISC_SYSTEM_POWER_SUPPLY *PowerSupply;
+
+ PowerSupply = (EFI_MISC_SYSTEM_POWER_SUPPLY *)RecordData;
+
+ //
+ // PowerUnitGroup
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE39, PowerUnitGroup),
+ &PowerSupply->PowerUnitGroup,
+ 1
+ );
+
+ //
+ // PowerSupplyLocation
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE39, Location),
+ &(PowerSupply->PowerSupplyLocation),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // PowerSupplyDeviceName
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE39, DeviceName),
+ &(PowerSupply->PowerSupplyDeviceName),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // PowerSupplyManufacturer
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE39, Manufacturer),
+ &(PowerSupply->PowerSupplyManufacturer),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // PowerSupplySerialNumber
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE39, SerialNumber),
+ &(PowerSupply->PowerSupplySerialNumber),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // PowerSupplyAssetTagNumber
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE39, AssetTagNumber),
+ &(PowerSupply->PowerSupplyAssetTagNumber),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // PowerSupplyModelPartNumber
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE39, ModelPartNumber),
+ &(PowerSupply->PowerSupplyModelPartNumber),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // PowerSupplyRevisionLevel
+ //
+ SmbiosFldString (
+ StructureNode,
+ OFFSET_OF (SMBIOS_TABLE_TYPE39, RevisionLevel),
+ &(PowerSupply->PowerSupplyRevisionLevel),
+ 2 // 64 * sizeof(CHAR16)
+ );
+
+ //
+ // PowerSupplyMaxPowerCapacity
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE39, MaxPowerCapacity),
+ &PowerSupply->PowerSupplyMaxPowerCapacity,
+ 2
+ );
+
+ //
+ // PowerSupplyCharacteristics
+ //
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE39, PowerSupplyCharacteristics),
+ &PowerSupply->PowerSupplyCharacteristics,
+ 2
+ );
+
+ //
+ // PowerSupplyInputVoltageProbeLink
+ //
+ SmbiosFldInterLink (
+ StructureNode,
+ (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE39, InputVoltageProbeHandle),
+ 26, // SMBIOS type 26 - Voltage Probe
+ &PowerSupply->PowerSupplyInputVoltageProbeLink,
+ &gEfiMiscSubClassGuid
+ );
+
+ //
+ // PowerSupplyCoolingDeviceLink
+ //
+ SmbiosFldInterLink (
+ StructureNode,
+ (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE39, CoolingDeviceHandle),
+ 27, // SMBIOS type 27 - Cooling Device
+ &PowerSupply->PowerSupplyCoolingDeviceLink,
+ &gEfiMiscSubClassGuid
+ );
+
+ //
+ // PowerSupplyInputCurrentProbeLink
+ //
+ SmbiosFldInterLink (
+ StructureNode,
+ (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE39, InputCurrentProbeHandle),
+ 29, // SMBIOS type 29 - Electrical Current Probe
+ &PowerSupply->PowerSupplyInputCurrentProbeLink,
+ &gEfiMiscSubClassGuid
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 0x80-0xFF -- OEM.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscTypeOEM (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *NewRecordData;
+ UINT32 IncrementDataSize;
+ UINT16 Handle;
+ INT8 Result;
+ UINT32 StructureSize;
+ UINT8 CountOfString;
+
+ Status = EFI_SUCCESS;
+ NewRecordData = NULL;
+
+ //
+ // Check if OEM structure has included 2 trailing 0s in data record, if not,
+ // we append them at the end to ensure OEM structure is always correct with 2 trailing 0s.
+ //
+ Result = SmbiosCheckTrailingZero (RecordData, RecordDataSize);
+
+ if (Result != 0) {
+ DEBUG ((EFI_D_ERROR, "OEM SMBIOS type %x is not valid!!\n", ((SMBIOS_STRUCTURE *) RecordData) -> Type));
+ if (Result == -1) {
+ //
+ // No 2 trailing 0s exist
+ //
+ DEBUG ((EFI_D_ERROR, "OEM SMBIOS type has NO 2 trailing 0s!!\n"));
+ IncrementDataSize = 2;
+ } else {
+ //
+ // Only 1 trailing 0 exist at the end
+ //
+ DEBUG ((EFI_D_ERROR, "OEM SMBIOS type has only 1 trailing 0!!\n"));
+ IncrementDataSize = 1;
+ }
+ NewRecordData = AllocateZeroPool (RecordDataSize + IncrementDataSize);
+ ASSERT (NewRecordData != NULL);
+ CopyMem (NewRecordData, RecordData, RecordDataSize);
+ RecordData = NewRecordData;
+ RecordDataSize += IncrementDataSize;
+ }
+
+ Status = GetSmbiosStructureSize (StructureNode->Structure, &StructureSize, &CountOfString);
+ ASSERT_EFI_ERROR (Status);
+
+ if (StructureSize < RecordDataSize) {
+ Status = SmbiosEnlargeStructureBuffer (
+ StructureNode,
+ ((EFI_SMBIOS_TABLE_HEADER *)RecordData)->Length,
+ StructureSize,
+ RecordDataSize
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Copy the entire data (including the Smbios structure header),
+ // but preserve the handle that is already allocated.
+ //
+ Handle = StructureNode->Structure->Handle;
+ CopyMem (
+ StructureNode->Structure,
+ RecordData,
+ RecordDataSize
+ );
+ StructureNode->Structure->Handle = Handle;
+ StructureNode->StructureSize = RecordDataSize;
+
+ if (NewRecordData != NULL) {
+ FreePool (NewRecordData);
+ }
+
+ return Status;
+}
+
+/**
+ Field Filling Function for Misc SubClass record type 127 - End-of-Table.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldMiscType127 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ return EFI_SUCCESS;
+}
diff --git a/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/ProcessorConv.c b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/ProcessorConv.c
new file mode 100644
index 0000000..5bd3207
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/ProcessorConv.c
@@ -0,0 +1,164 @@
+/** @file
+ Routines that support Processor SubClass data records translation.
+
+Copyright (c) 2009, Intel Corporation
+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 "Thunk.h"
+
+/**
+ Field Filling Function for Processor SubClass record type 17 -- Cache association.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldProcessorType17 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_SUBCLASS_TYPE1_HEADER *DataHeader;
+ EFI_INTER_LINK_DATA *LinkData;
+ UINT16 FieldOffset;
+ UINT8 *Pointer;
+
+ DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) RecordData;
+ LinkData = (EFI_INTER_LINK_DATA *) (DataHeader + 1);
+ if (RecordDataSize != sizeof (EFI_INTER_LINK_DATA) + sizeof (EFI_SUBCLASS_TYPE1_HEADER)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Determine the cache level
+ //
+ Pointer = (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE4, L1CacheHandle);
+ if ((*Pointer == 0) && (*(Pointer + 1) == 0)) {
+ SetMem ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE4, L1CacheHandle), 2, 0xFF);
+ }
+
+ Pointer = (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE4, L2CacheHandle);
+ if ((*Pointer == 0) && (*(Pointer + 1) == 0)) {
+ SetMem ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE4, L2CacheHandle), 2, 0xFF);
+ }
+
+ Pointer = (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE4, L3CacheHandle);
+ if ((*Pointer == 0) && (*(Pointer + 1) == 0)) {
+ SetMem ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE4, L3CacheHandle), 2, 0xFF);
+ }
+
+ if (LinkData->SubInstance == 1) {
+ FieldOffset = (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE4, L1CacheHandle);
+ } else if (LinkData->SubInstance == 2) {
+ FieldOffset = (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE4, L2CacheHandle);
+ } else if (LinkData->SubInstance == 3) {
+ FieldOffset = (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE4, L3CacheHandle);
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return SmbiosFldInterLink (
+ StructureNode,
+ FieldOffset,
+ 7, // Smbios type 7 -- Cache Information
+ LinkData,
+ &gEfiCacheSubClassGuid // gProcessorSubClassName
+ );
+}
+
+/**
+ Field Filling Function for Processor SubClass record type 6 -- ProcessorID.
+ Offset is mandatory.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldProcessorType6 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_PROCESSOR_ID_DATA *ProcessorIdData;
+
+ ProcessorIdData = RecordData;
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + Offset,
+ &(ProcessorIdData->Signature),
+ 4
+ );
+
+ CopyMem (
+ (UINT8 *) (StructureNode->Structure) + Offset + 4,
+ &(ProcessorIdData->FeatureFlags),
+ 4
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function for Processor SubClass record type 9 -- Voltage.
+ Offset is mandatory.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.
+**/
+EFI_STATUS
+SmbiosFldProcessorType9 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+{
+ EFI_EXP_BASE10_DATA *Base10Data;
+ INT16 Value;
+ INT16 Exponent;
+
+ if (RecordDataSize != sizeof (EFI_EXP_BASE10_DATA)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Base10Data = RecordData;
+ Value = Base10Data->Value;
+ Exponent = Base10Data->Exponent;
+
+ Exponent += 1;
+ while (Exponent != 0) {
+ if (Exponent > 0) {
+ Value = (INT16) (Value * 10);
+ Exponent--;
+ } else {
+ Value = (INT16) (Value / 10);
+ Exponent++;
+ }
+ }
+
+ * (UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = (UINT8) (Value | BIT7);
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/Thunk.c b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/Thunk.c
new file mode 100644
index 0000000..797f803
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/Thunk.c
@@ -0,0 +1,160 @@
+/** @file
+ Thunk driver's entry that install filter for DataRecord.
+
+Copyright (c) 2009 Intel Corporation. <BR>
+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 "Thunk.h"
+
+//
+// Global variables
+//
+LIST_ENTRY mStructureList;
+
+/**
+ Entry Point of thunk driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Pointer to EFI system table.
+
+ @retval EFI_SUCCESS The event handlers were registered.
+ @retval EFI_DEVICE_ERROR Failed to register the event handlers
+**/
+EFI_STATUS
+EFIAPI
+ThunkEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_DATA_HUB_PROTOCOL *DataHub;
+ EFI_EVENT FilterEvent;
+
+ Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID**) &DataHub);
+ ASSERT_EFI_ERROR (Status);
+ ASSERT (DataHub != NULL);
+
+ InitializeListHead (&mStructureList);
+
+ //
+ // Register SmBios Data Filter Function.
+ // This function is notified at TPL_CALLBACK.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ SmbiosDataFilter,
+ NULL,
+ &FilterEvent
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = DataHub->RegisterFilterDriver (
+ DataHub,
+ FilterEvent,
+ TPL_APPLICATION,
+ EFI_DATA_RECORD_CLASS_DATA,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->CloseEvent (FilterEvent);
+ return Status;
+ }
+
+ return Status;
+
+}
+
+/**
+ Smbios data filter function. This function is invoked when there is data records
+ available in the Data Hub.
+
+ @param Event The event that is signaled.
+ @param Context not used here.
+**/
+VOID
+EFIAPI
+SmbiosDataFilter (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_DATA_HUB_PROTOCOL *DataHub;
+ EFI_HANDLE DataHubHandle;
+ UINTN HandleSize;
+ UINT64 MonotonicCount;
+ EFI_DATA_RECORD_HEADER *Record;
+
+ Status = EFI_SUCCESS;
+ DataHub = NULL;
+
+ //
+ // Get the Data Hub Protocol. Assume only one instance
+ // of Data Hub Protocol is availabe in the system.
+ //
+ HandleSize = sizeof (EFI_HANDLE);
+
+ Status = gBS->LocateHandle (
+ ByProtocol,
+ &gEfiDataHubProtocolGuid,
+ NULL,
+ &HandleSize,
+ &DataHubHandle
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Status = gBS->HandleProtocol (
+ DataHubHandle,
+ &gEfiDataHubProtocolGuid,
+ (VOID **) &DataHub
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ //
+ // Get all available data records from data hub
+ //
+ MonotonicCount = 0;
+ Record = NULL;
+
+ do {
+
+ Status = DataHub->GetNextRecord (
+ DataHub,
+ &MonotonicCount,
+ &Event,
+ &Record
+ );
+
+ if (!EFI_ERROR (Status)) {
+ if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
+
+ //
+ // It's of expected Data Type. Process it.
+ //
+ SmbiosProcessDataRecord (Record);
+ }
+ }
+ } while (!EFI_ERROR (Status) && (MonotonicCount != 0));
+
+Done:
+
+ return ;
+
+}
diff --git a/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/Thunk.h b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/Thunk.h
new file mode 100644
index 0000000..cb375b0
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/Thunk.h
@@ -0,0 +1,842 @@
+/** @file
+ The common header file for the thunk driver.
+
+Copyright (c) 2009 Intel Corporation. <BR>
+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.
+
+**/
+
+#ifndef _DATAHUB_TO_SMBIOS_THUNK_
+#define _DATAHUB_TO_SMBIOS_THUNK_
+
+#include <FrameworkDxe.h>
+#include <IndustryStandard/SmBios.h>
+
+#include <Guid/EventGroup.h>
+#include <Guid/SmBios.h>
+#include <Protocol/DataHub.h>
+#include <Guid/DataHubRecords.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/Smbios.h>
+
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/HiiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+//
+// Conversion Table that describes the translation method for
+// Data Hub Data Records of certain SubClass and RecordNumber
+//
+typedef enum {
+ BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER,
+ BY_SUBCLASS_INSTANCE_PRODUCER,
+ MAX_LOCATING_METHOD
+} SMBIOS_STRUCTURE_LOCATING_METHOD;
+
+typedef enum {
+ RECORD_DATA_UNCHANGED_OFFSET_SPECIFIED,
+ BY_FUNCTION_WITH_OFFSET_SPECIFIED,
+ BY_FUNCTION,
+ BY_FUNCTION_WITH_WHOLE_DATA_RECORD,
+ MAX_FIELD_FILLING_METHOD
+} SMBIOS_FIELD_FILLING_METHOD;
+
+typedef struct _SMBIOS_STRUCTURE_NODE SMBIOS_STRUCTURE_NODE;
+
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Handle;
+ UINT8 Tailing[2];
+} EFI_SMBIOS_TABLE_TYPE127;
+
+typedef
+EFI_STATUS
+(*SMBIOS_FIELD_FILLING_FUNCTION) (
+ IN OUT SMBIOS_STRUCTURE_NODE * StructureNode,
+ IN UINT32 Offset OPTIONAL,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ );
+
+typedef struct {
+ //
+ // Data Hub Data Record's SubClass and RecordNumber
+ //
+ EFI_GUID SubClass;
+ UINT32 RecordType;
+
+ //
+ // Translation method applied
+ //
+ UINT8 SmbiosType;
+ SMBIOS_STRUCTURE_LOCATING_METHOD StructureLocatingMethod;
+ SMBIOS_FIELD_FILLING_METHOD FieldFillingMethod;
+ UINT32 FieldOffset;
+ SMBIOS_FIELD_FILLING_FUNCTION FieldFillingFunction;
+
+} SMBIOS_CONVERSION_TABLE_ENTRY;
+
+//
+// SMBIOS_LINK_DATA_FIXUP nodes indicate the Link fields that
+// need to be fixed up when creating the resulting Smbios image.
+//
+#define SMBIOS_LINK_DATA_FIXUP_NODE_SIGNATURE SIGNATURE_32 ('S', 'm', 'l', 'n')
+
+typedef struct {
+
+ UINT32 Signature;
+ LIST_ENTRY Link;
+
+ UINT32 Offset;
+ UINT8 TargetType;
+ EFI_GUID SubClass;
+ EFI_INTER_LINK_DATA LinkData;
+
+} SMBIOS_LINK_DATA_FIXUP_NODE;
+
+//
+// The global Structure List node.
+// The Structure List is populated as more and more
+// Structures (of various types) are discovered and inserted.
+// The nodes in the Structure List will be concatenated
+// to form the ultimate SMBIOS table.
+//
+#define SMBIOS_STRUCTURE_NODE_SIGNATURE SIGNATURE_32 ('S', 'm', 'b', 's')
+
+struct _SMBIOS_STRUCTURE_NODE {
+
+ UINT32 Signature;
+ LIST_ENTRY Link;
+
+ //
+ // Tags
+ //
+ EFI_GUID SubClass;
+ UINT16 Instance;
+ UINT16 SubInstance;
+ EFI_GUID ProducerName;
+
+ //
+ // the Smbios structure
+ //
+ UINT32 StructureSize; // Actual structure size including strings
+
+ EFI_SMBIOS_TABLE_HEADER *Structure;
+
+
+ EFI_SMBIOS_HANDLE SmbiosHandle; // Smbios Handle in SMBIOS database.
+
+ EFI_SMBIOS_TYPE SmbiosType;
+
+ LIST_ENTRY LinkDataFixup;
+
+};
+
+//
+// Smbios type info table. Indicates minimum length
+// for each Smbios type as the indicator of the initial size of buffer
+// allocated for the structure instance of a specific type.
+//
+typedef struct {
+
+ UINT8 Type;
+ UINT8 MinLength; // Minimal structure size including
+ // TWO trailing bytes of 0x00
+ //
+ BOOLEAN IsRequired; // Required structure type defined by Smbios Spec
+ BOOLEAN IsCreated; // Created in this run
+} SMBIOS_TYPE_INFO_TABLE_ENTRY;
+
+//
+// EDK framwork Memory Data hub definition to support EDK/Framework driver.
+//
+typedef struct {
+ STRING_REF MemoryDeviceLocator;
+ STRING_REF MemoryBankLocator;
+ STRING_REF MemoryManufacturer;
+ STRING_REF MemorySerialNumber;
+ STRING_REF MemoryAssetTag;
+ STRING_REF MemoryPartNumber;
+ EFI_INTER_LINK_DATA MemoryArrayLink;
+ EFI_INTER_LINK_DATA MemorySubArrayLink;
+ UINT16 MemoryTotalWidth;
+ UINT16 MemoryDataWidth;
+ UINT64 MemoryDeviceSize;
+ EFI_MEMORY_FORM_FACTOR MemoryFormFactor;
+ UINT8 MemoryDeviceSet;
+ EFI_MEMORY_ARRAY_TYPE MemoryType;
+ EFI_MEMORY_TYPE_DETAIL MemoryTypeDetail;
+ UINT16 MemorySpeed;
+ EFI_MEMORY_STATE MemoryState;
+ UINT8 MemoryAttributes;
+} FRAMEWORK_MEMORY_ARRAY_LINK_DATA;
+
+typedef struct {
+ EFI_MEMORY_ARRAY_LOCATION MemoryArrayLocation;
+ EFI_MEMORY_ARRAY_USE MemoryArrayUse;
+ EFI_MEMORY_ERROR_CORRECTION MemoryErrorCorrection;
+ UINT32 MaximumMemoryCapacity;
+ UINT16 NumberMemoryDevices;
+} FRAMEWORK_MEMORY_ARRAY_LOCATION_DATA;
+
+//
+// Global variables
+//
+extern SMBIOS_CONVERSION_TABLE_ENTRY mConversionTable[];
+extern SMBIOS_TYPE_INFO_TABLE_ENTRY mTypeInfoTable[];
+extern LIST_ENTRY mStructureList;
+
+//
+// Function Prototypes
+//
+/**
+ Smbios data filter function. This function is invoked when there is data records
+ available in the Data Hub.
+
+ @param Event The event that is signaled.
+ @param Context not used here.
+**/
+VOID
+EFIAPI
+SmbiosDataFilter (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+//
+// Function prototypes
+//
+/**
+ Process a datahub's record and find corresponding translation way to translate
+ to SMBIOS record.
+
+ @param Record Point to datahub record.
+**/
+VOID
+SmbiosProcessDataRecord (
+ IN EFI_DATA_RECORD_HEADER *Record
+ )
+;
+
+/**
+ Calculate the minimal length for a SMBIOS type. This length maybe not equal
+ to sizeof (SMBIOS_RECORD_STRUCTURE), but defined in conformance chapter in SMBIOS specification.
+
+ @param Type SMBIOS's type.
+
+ @return the minimal length of a smbios record.
+**/
+UINT32
+SmbiosGetTypeMinimalLength (
+ IN UINT8 Type
+ )
+;
+
+/**
+ Enlarge the structure buffer of a structure node in SMBIOS database.
+ The function maybe lead the structure pointer for SMBIOS record changed.
+
+ @param StructureNode The structure node whose structure buffer is to be enlarged.
+ @param NewLength The new length of SMBIOS record which does not include unformat area.
+ @param OldBufferSize The old size of SMBIOS record buffer.
+ @param NewSize The new size is targeted for enlarged.
+
+ @retval EFI_OUT_OF_RESOURCES No more memory to allocate new record
+ @retval EFI_SUCCESS Success to enlarge the record buffer size.
+**/
+EFI_STATUS
+SmbiosEnlargeStructureBuffer (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ UINT8 NewLength,
+ UINTN OldBufferSize,
+ UINTN NewBufferSize
+ );
+
+/**
+ Field Filling Function. Fill a standard Smbios string field.
+ Convert the unicode string to single byte chars.
+ Only English language is supported.
+
+ This function changes the Structure pointer value of the structure node,
+ which should be noted by Caller.
+
+ @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
+ @param Offset Offset of SMBIOS record which RecordData will be filled.
+ @param RecordData RecordData buffer will be filled.
+ @param RecordDataSize The size of RecordData buffer.
+
+ @retval EFI_INVALID_PARAMETER RecordDataSize is too larger
+ @retval EFI_OUT_OF_RESOURCES No memory to allocate new buffer for string
+ @retval EFI_SUCCESS Sucess append string for a SMBIOS record.
+**/
+EFI_STATUS
+SmbiosFldString (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+/**
+ Fill the inter link field for a SMBIOS recorder.
+
+ Some SMBIOS recorder need to reference the handle of another SMBIOS record. But
+ maybe another SMBIOS record has not been added, so put the InterLink request into
+ a linked list and the interlink will be fixedup when a new SMBIOS record is added.
+
+ @param StructureNode Point to SMBIOS_STRUCTURE_NODE which reference another record's handle
+ @param LinkSmbiosNodeOffset The offset in this record for holding the handle of another SMBIOS record
+ @param LinkSmbiosType The type of SMBIOS record want to be linked.
+ @param InterLink Point to EFI_INTER_LINK_DATA will be put linked list.
+ @param SubClassGuid The guid of subclass for linked SMBIOS record.
+
+ @retval EFI_SUCESS The linked record is found and no need fixup in future.
+ @retval !EFI_SUCESS The linked record can not be found and InterLink is put a fixing-p linked list.
+**/
+EFI_STATUS
+SmbiosFldInterLink (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT16 LinkSmbiosNodeOffset,
+ IN UINT8 LinkSmbiosType,
+ IN EFI_INTER_LINK_DATA *InterLink,
+ IN EFI_GUID *SubClassGuid
+ )
+;
+
+/**
+ Find a handle that matches the Link Data and the target Smbios type.
+
+ @param TargetType the Smbios type
+ @param SubClass the SubClass
+ @param LinkData Specifies Instance, SubInstance and ProducerName
+ @param Handle the HandleNum found
+
+ @retval EFI_NOT_FOUND Can not find the record according to handle
+ @retval EFI_SUCCESS Success to find the handle
+**/
+EFI_STATUS
+SmbiosFindHandle (
+ IN UINT8 TargetType,
+ IN EFI_GUID *SubClass,
+ IN EFI_INTER_LINK_DATA *LinkData,
+ IN OUT UINT16 *HandleNum
+ )
+;
+
+EFI_STATUS
+SmbiosFldBase10ToWordWithMega (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldBase2ToWordWithKilo (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldTruncateToByte (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldProcessorType6 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldProcessorType9 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldProcessorType17 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldBase10ToByteWithNano (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldTruncateToWord (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldCacheType10 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+INT8
+SmbiosCheckTrailingZero (
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldCacheType5 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMemoryType2 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMemoryType3 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMemoryType4 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMemoryType5 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMemoryType6 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMemoryType7 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMemoryType8 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMemoryType9 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMemoryType10 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType0 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldBase2ToByteWith64K (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType1 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType2 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType3 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType8 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType9 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType10 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType11 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType12 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType13 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType14 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType15 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType21 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+
+EFI_STATUS
+SmbiosFldMiscType32 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType38 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ );
+
+EFI_STATUS
+SmbiosFldMiscTypeOEM (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldSMBIOSType6 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType22 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType22 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType23 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType24 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType25 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType26 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType27 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType28 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType29 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType30 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType34 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType36 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType38 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType39 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosFldMiscType127 (
+ IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
+ IN UINT32 Offset,
+ IN VOID *RecordData,
+ IN UINT32 RecordDataSize
+ )
+;
+
+EFI_STATUS
+SmbiosProtocolCreateRecord (
+ IN EFI_HANDLE ProducerHandle, OPTIONAL
+ IN SMBIOS_STRUCTURE_NODE *StructureNode
+ );
+
+EFI_SMBIOS_PROTOCOL*
+GetSmbiosProtocol (
+ VOID
+ );
+
+EFI_SMBIOS_TABLE_HEADER*
+GetSmbiosBufferFromHandle (
+ IN EFI_SMBIOS_HANDLE Handle,
+ IN EFI_SMBIOS_TYPE Type,
+ IN EFI_HANDLE ProducerHandle OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+GetSmbiosStructureSize (
+ IN EFI_SMBIOS_TABLE_HEADER *Head,
+ OUT UINT32 *Size,
+ OUT UINT8 *NumberOfStrings
+ );
+
+#endif
diff --git a/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/Translate.c b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/Translate.c
new file mode 100644
index 0000000..9912db8
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/Translate.c
@@ -0,0 +1,591 @@
+/**@file
+ Translate the DataHub records via EFI_DATA_HUB_PROTOCOL to Smbios recorders
+ via EFI_SMBIOS_PROTOCOL.
+
+Copyright (c) 2009, Intel Corporation
+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 "Thunk.h"
+
+EFI_GUID ZeroGuid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
+EFI_SMBIOS_PROTOCOL *mSmbiosProtocol = NULL;
+
+/**
+ Release the structure Node.
+
+ @param StructureNode Point to SMBIOS_STRUCTURE_NODE which will be removed.
+**/
+VOID
+ReleaseStructureNode (
+ SMBIOS_STRUCTURE_NODE *StructureNode
+ )
+{
+ EFI_SMBIOS_PROTOCOL *Smbios;
+
+ RemoveEntryList (&(StructureNode->Link));
+ Smbios = GetSmbiosProtocol();
+ ASSERT (Smbios != NULL);
+ Smbios->Remove (Smbios, StructureNode->SmbiosHandle);
+ gBS->FreePool (StructureNode);
+}
+
+/**
+ Process a datahub's record and find corresponding translation way to translate
+ to SMBIOS record.
+
+ @param Record Point to datahub record.
+**/
+VOID
+SmbiosProcessDataRecord (
+ IN EFI_DATA_RECORD_HEADER *Record
+ )
+{
+ EFI_DATA_RECORD_HEADER *RecordHeader;
+ EFI_SUBCLASS_TYPE1_HEADER *DataHeader;
+ UINTN Index;
+ SMBIOS_CONVERSION_TABLE_ENTRY *Conversion;
+ UINT8 *SrcData;
+ UINTN SrcDataSize;
+ LIST_ENTRY *Link;
+ SMBIOS_STRUCTURE_NODE *StructureNode;
+ BOOLEAN StructureCreated;
+ EFI_STATUS Status;
+
+ Conversion = NULL;
+ StructureNode = NULL;
+ StructureCreated = FALSE;
+ RecordHeader = Record;
+ DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);
+ SrcData = (UINT8 *) (DataHeader + 1);
+ SrcDataSize = RecordHeader->RecordSize - RecordHeader->HeaderSize - sizeof (EFI_SUBCLASS_TYPE1_HEADER);
+
+ if (DataHeader->HeaderSize != sizeof (EFI_SUBCLASS_TYPE1_HEADER) ||
+ DataHeader->Instance == EFI_SUBCLASS_INSTANCE_RESERVED ||
+ DataHeader->SubInstance == EFI_SUBCLASS_INSTANCE_RESERVED
+ ) {
+ //
+ // Invalid Data Record
+ //
+ goto Done;
+ }
+
+ Index = 0;
+ while(TRUE) {
+ //
+ // Find a matching entry in the conversion table for this
+ // (SubClass, RecordNumber) pair
+ //
+ for (; !CompareGuid (&(mConversionTable[Index].SubClass), &ZeroGuid); Index++) {
+ if (CompareGuid (
+ &(mConversionTable[Index].SubClass),
+ &(RecordHeader->DataRecordGuid)
+ )) {
+ if (mConversionTable[Index].RecordType == DataHeader->RecordType) {
+ break;
+ }
+ }
+ }
+
+ if (CompareGuid (&(mConversionTable[Index].SubClass), &ZeroGuid)) {
+ //
+ // We cannot find a matching entry in conversion table,
+ // this means this data record cannot be used for SMBIOS.
+ // Just skip it.
+ //
+ goto Done;
+ }
+
+ Conversion = &mConversionTable[Index++];
+
+ //
+ // Find corresponding structure in the Structure List
+ //
+ for (Link = mStructureList.ForwardLink; Link != &mStructureList; Link = Link->ForwardLink) {
+
+ StructureNode = CR (
+ Link,
+ SMBIOS_STRUCTURE_NODE,
+ Link,
+ SMBIOS_STRUCTURE_NODE_SIGNATURE
+ );
+
+ if (Conversion->StructureLocatingMethod == BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER) {
+ //
+ // Look at SubClass, Instance, SubInstance and ProducerName for a matching
+ // node
+ //
+ if (CompareGuid (&(StructureNode->SubClass), &(RecordHeader->DataRecordGuid)) &&
+ StructureNode->Instance == DataHeader->Instance &&
+ StructureNode->SubInstance == DataHeader->SubInstance &&
+ CompareGuid (&(StructureNode->ProducerName), &(RecordHeader->ProducerName))
+ ) {
+ if (Conversion->SmbiosType >= 0X80) {
+ if (StructureNode->SmbiosType == ((SMBIOS_STRUCTURE_HDR *) SrcData)->Type) {
+ break;
+ }
+ } else if (StructureNode->SmbiosType == Conversion->SmbiosType) {
+ break;
+ }
+ }
+
+ } else if (Conversion->StructureLocatingMethod == BY_SUBCLASS_INSTANCE_PRODUCER) {
+ //
+ // Look at SubClass, Instance and ProducerName for a matching node
+ //
+ if (CompareGuid (&(StructureNode->SubClass), &(RecordHeader->DataRecordGuid)) &&
+ StructureNode->Instance == DataHeader->Instance &&
+ CompareGuid (&(StructureNode->ProducerName), &(RecordHeader->ProducerName))
+ ) {
+ if (Conversion->SmbiosType >= 0X80) {
+ if (StructureNode->SmbiosType == ((SMBIOS_STRUCTURE_HDR *) SrcData)->Type) {
+ break;
+ }
+ } else if (StructureNode->SmbiosType == Conversion->SmbiosType) {
+ break;
+ }
+ }
+
+ } else {
+ //
+ // Invalid conversion table entry
+ //
+ goto Done;
+ }
+ }
+
+ if (Link == &mStructureList) {
+
+ //
+ // Not found, create a new structure
+ //
+ StructureNode = AllocateZeroPool (sizeof (SMBIOS_STRUCTURE_NODE));
+
+ if (!StructureNode) {
+ goto Done;
+ }
+
+ if (Conversion->StructureLocatingMethod == BY_SUBCLASS_INSTANCE_SUBINSTANCE_PRODUCER) {
+ //
+ // Fill in SubClass, Instance, SubInstance and ProducerName
+ //
+ CopyMem (&(StructureNode->SubClass), &(RecordHeader->DataRecordGuid), sizeof (EFI_GUID));
+ StructureNode->Instance = DataHeader->Instance;
+ StructureNode->SubInstance = DataHeader->SubInstance;
+ CopyMem (&(StructureNode->ProducerName), &(RecordHeader->ProducerName), sizeof (EFI_GUID));
+
+ } else if (Conversion->StructureLocatingMethod == BY_SUBCLASS_INSTANCE_PRODUCER) {
+ //
+ // Fill in at SubClass, Instance and ProducerName, mark SubInstance as Non
+ // Applicable
+ //
+ CopyMem (&(StructureNode->SubClass), &(RecordHeader->DataRecordGuid), sizeof (EFI_GUID));
+ StructureNode->Instance = DataHeader->Instance;
+ StructureNode->SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;
+ CopyMem (&(StructureNode->ProducerName), &(RecordHeader->ProducerName), sizeof (EFI_GUID));
+
+ }
+ //
+ // Allocate the structure instance
+ //
+ StructureNode->StructureSize = SmbiosGetTypeMinimalLength (Conversion->SmbiosType);
+ StructureNode->SmbiosType = Conversion->SmbiosType;
+
+ //
+ // StructureSize include the TWO trailing zero byte.
+ //
+ if (StructureNode->StructureSize < (sizeof(SMBIOS_STRUCTURE) + 2)) {
+ //
+ // Invalid Type
+ //
+ gBS->FreePool (StructureNode);
+ goto Done;
+ }
+
+ StructureNode->SmbiosType = Conversion->SmbiosType;
+ StructureNode->SmbiosHandle = 0;
+ Status = SmbiosProtocolCreateRecord (
+ NULL,
+ StructureNode
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ //
+ // Temporary cache the structrue pointer to Smbios database.
+ //
+ StructureNode->Structure = GetSmbiosBufferFromHandle (StructureNode->SmbiosHandle, StructureNode->SmbiosType, NULL);
+
+ InitializeListHead (&StructureNode->LinkDataFixup);
+
+ //
+ // Insert the Structure Node into the Strucutre List
+ //
+ StructureNode->Signature = SMBIOS_STRUCTURE_NODE_SIGNATURE;
+ InsertTailList (&mStructureList, &(StructureNode->Link));
+
+ StructureCreated = TRUE;
+
+ }
+
+
+ //
+ // Re-calculate the structure pointer to Smbios database.
+ //
+ StructureNode->Structure = GetSmbiosBufferFromHandle (StructureNode->SmbiosHandle, StructureNode->SmbiosType, NULL);
+
+ //
+ // Fill the Structure's field corresponding to this data record
+ //
+ if (Conversion->FieldFillingMethod == RECORD_DATA_UNCHANGED_OFFSET_SPECIFIED) {
+ //
+ // Field data is just the record data without transforming and
+ // offset is specified directly in the conversion table entry
+ //
+ if (Conversion->FieldOffset + SrcDataSize > StructureNode->Structure->Length) {
+ //
+ // Invalid Conversion Table Entry
+ //
+ if (StructureCreated) {
+ ReleaseStructureNode (StructureNode);
+ }
+
+ goto Done;
+ }
+
+ CopyMem ((UINT8 *) (StructureNode->Structure) + Conversion->FieldOffset, SrcData, SrcDataSize);
+
+ } else if (Conversion->FieldFillingMethod == BY_FUNCTION_WITH_OFFSET_SPECIFIED) {
+ //
+ // Field offfset is specified in the conversion table entry, but
+ // record data needs to be transformed to be filled into the field,
+ // so let the FieldFillingFunction do it.
+ //
+ if (!(Conversion->FieldFillingFunction)) {
+ //
+ // Invalid Conversion Table Entry
+ //
+ if (StructureCreated) {
+ ReleaseStructureNode (StructureNode);
+ }
+
+ goto Done;
+ }
+
+ Status = Conversion->FieldFillingFunction (
+ StructureNode,
+ Conversion->FieldOffset,
+ SrcData,
+ (UINT32) SrcDataSize
+ );
+ if (EFI_ERROR (Status)) {
+ if (StructureCreated) {
+ ReleaseStructureNode (StructureNode);
+ }
+
+ goto Done;
+ }
+ } else if (Conversion->FieldFillingMethod == BY_FUNCTION) {
+ //
+ // Both field offset and field content are determined by
+ // FieldFillingFunction
+ //
+ if (!(Conversion->FieldFillingFunction)) {
+ //
+ // Invalid Conversion Table Entry
+ //
+ if (StructureCreated) {
+ ReleaseStructureNode (StructureNode);
+ }
+
+ goto Done;
+ }
+
+ Status = Conversion->FieldFillingFunction (
+ StructureNode,
+ 0,
+ SrcData,
+ (UINT32) SrcDataSize
+ );
+ if (EFI_ERROR (Status)) {
+ if (StructureCreated) {
+ ReleaseStructureNode (StructureNode);
+ }
+
+ goto Done;
+ }
+ } else if (Conversion->FieldFillingMethod == BY_FUNCTION_WITH_WHOLE_DATA_RECORD) {
+ //
+ // Both field offset and field content are determined by
+ // FieldFillingFunction and the function accepts the whole data record
+ // including the data header
+ //
+ if (!(Conversion->FieldFillingFunction)) {
+ //
+ // Invalid Conversion Table Entry
+ //
+ if (StructureCreated) {
+ ReleaseStructureNode (StructureNode);
+ }
+
+ goto Done;
+ }
+
+ Status = Conversion->FieldFillingFunction (
+ StructureNode,
+ 0,
+ DataHeader,
+ RecordHeader->RecordSize - RecordHeader->HeaderSize
+ );
+ if (EFI_ERROR (Status)) {
+ if (StructureCreated) {
+ ReleaseStructureNode (StructureNode);
+ }
+
+ goto Done;
+ }
+ } else {
+ //
+ // Invalid Conversion Table Entry
+ //
+ if (StructureCreated) {
+ ReleaseStructureNode (StructureNode);
+ }
+
+ goto Done;
+ }
+ }
+Done:
+ return ;
+}
+
+/**
+ Calculate the minimal length for a SMBIOS type. This length maybe not equal
+ to sizeof (SMBIOS_RECORD_STRUCTURE), but defined in conformance chapter in SMBIOS specification.
+
+ @param Type SMBIOS's type.
+
+ @return the minimal length of a smbios record.
+**/
+UINT32
+SmbiosGetTypeMinimalLength (
+ IN UINT8 Type
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; mTypeInfoTable[Index].MinLength != 0; Index++) {
+ if (mTypeInfoTable[Index].Type == Type) {
+ return mTypeInfoTable[Index].MinLength;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ Get pointer of EFI_SMBIOS_PROTOCOL.
+
+ @return pointer of EFI_SMBIOS_PROTOCOL.
+**/
+EFI_SMBIOS_PROTOCOL*
+GetSmbiosProtocol(
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ if (mSmbiosProtocol == NULL) {
+ Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID*) &mSmbiosProtocol);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ ASSERT (mSmbiosProtocol != NULL);
+ return mSmbiosProtocol;
+}
+
+/**
+ Create a blank smbios record. The datahub record is only a field of smbios record.
+ So before fill any field from datahub's record. A blank smbios record need to be
+ created.
+
+ @param ProducerHandle The produce handle for a datahub record
+ @param StructureNode Point to SMBIOS_STRUCTURE_NODE
+
+ @retval EFI_OUT_OF_RESOURCES Fail to allocate memory for new blank SMBIOS record.
+ @retval EFI_SUCCESS Success to create blank smbios record.
+**/
+EFI_STATUS
+SmbiosProtocolCreateRecord (
+ IN EFI_HANDLE ProducerHandle, OPTIONAL
+ IN SMBIOS_STRUCTURE_NODE *StructureNode
+ )
+{
+ EFI_SMBIOS_PROTOCOL *Smbios;
+ EFI_SMBIOS_TABLE_HEADER *BlankRecord;
+ EFI_STATUS Status;
+ SMBIOS_STRUCTURE_NODE *RefStructureNode;
+ LIST_ENTRY *Link;
+ LIST_ENTRY *Link1;
+ LIST_ENTRY *Link2;
+ SMBIOS_LINK_DATA_FIXUP_NODE *LinkDataFixupNode;
+ UINT8 *BufferPointer;
+
+ Smbios = GetSmbiosProtocol();
+ ASSERT (Smbios != NULL);
+
+ //
+ // Prepare a blank smbios record.
+ //
+ BlankRecord = (EFI_SMBIOS_TABLE_HEADER*) AllocateZeroPool (StructureNode->StructureSize);
+ if (BlankRecord == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ BlankRecord->Type = StructureNode->SmbiosType;
+ BlankRecord->Length = (UINT8) (StructureNode->StructureSize - 2);
+
+ //
+ // Add blank record into SMBIOS database.
+ //
+ Status = Smbios->Add (Smbios, NULL, &StructureNode->SmbiosHandle, BlankRecord);
+ FreePool (BlankRecord);
+
+ //
+ // Fix up the InterLink node for new added smbios record if some other
+ // existing smbios record want to link this new record's handle.
+ //
+ for (Link = mStructureList.ForwardLink; Link != &mStructureList; Link = Link->ForwardLink) {
+ RefStructureNode = CR (Link, SMBIOS_STRUCTURE_NODE, Link, SMBIOS_STRUCTURE_NODE_SIGNATURE);
+ for (Link1 = RefStructureNode->LinkDataFixup.ForwardLink; Link1 != &RefStructureNode->LinkDataFixup;) {
+ LinkDataFixupNode = CR (Link1, SMBIOS_LINK_DATA_FIXUP_NODE, Link, SMBIOS_LINK_DATA_FIXUP_NODE_SIGNATURE);
+ Link2 = Link1;
+ Link1 = Link1->ForwardLink;
+
+ if ((StructureNode->SmbiosType != LinkDataFixupNode->TargetType) ||
+ !(CompareGuid (&StructureNode->SubClass, &LinkDataFixupNode->SubClass)) ||
+ (StructureNode->Instance != LinkDataFixupNode->LinkData.Instance) ||
+ (StructureNode->SubInstance != LinkDataFixupNode->LinkData.SubInstance)) {
+ continue;
+ }
+
+ //
+ // Fill the field with the handle found
+ //
+ BufferPointer = (UINT8 *) (RefStructureNode->Structure) + LinkDataFixupNode->Offset;
+ *BufferPointer = (UINT8) (StructureNode->SmbiosHandle & 0xFF);
+ *(BufferPointer + 1) = (UINT8) ((StructureNode->SmbiosHandle >> 8) & 0xFF);
+ BufferPointer = NULL;
+
+ RemoveEntryList (Link2);
+ FreePool (LinkDataFixupNode);
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Get pointer of a SMBIOS record's buffer according to its handle.
+
+ @param Handle The handle of SMBIOS record want to be searched.
+ @param Type The type of SMBIOS record want to be searched.
+ @param ProducerHandle The producer handle of SMBIOS record.
+
+ @return EFI_SMBIOS_TABLE_HEADER Point to a SMBIOS record's buffer.
+**/
+EFI_SMBIOS_TABLE_HEADER*
+GetSmbiosBufferFromHandle (
+ IN EFI_SMBIOS_HANDLE Handle,
+ IN EFI_SMBIOS_TYPE Type,
+ IN EFI_HANDLE ProducerHandle OPTIONAL
+ )
+{
+ EFI_SMBIOS_PROTOCOL* Smbios;
+ EFI_SMBIOS_HANDLE SearchingHandle;
+ EFI_SMBIOS_TABLE_HEADER *RecordInSmbiosDatabase;
+ EFI_STATUS Status;
+
+ SearchingHandle = 0;
+ Smbios = GetSmbiosProtocol();
+ ASSERT (Smbios != NULL);
+
+ do {
+ Status = Smbios->GetNext (Smbios, &SearchingHandle, &Type, &RecordInSmbiosDatabase, NULL);
+ } while ((SearchingHandle != Handle) && (Status != EFI_NOT_FOUND));
+
+ return RecordInSmbiosDatabase;
+}
+
+/**
+
+ 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 Size The returned size.
+ @param NumberOfStrings The returned number of optional strings that follow the formatted structure.
+
+ @retval EFI_SUCCESS Size retured in Size.
+ @retval EFI_INVALID_PARAMETER Input smbios structure mal-formed or Size is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetSmbiosStructureSize (
+ IN EFI_SMBIOS_TABLE_HEADER *Head,
+ OUT UINT32 *Size,
+ OUT UINT8 *NumberOfStrings
+ )
+{
+ UINT32 FullSize;
+ UINT8 StrLen;
+ INT8* CharInStr;
+
+ if (Size == NULL || NumberOfStrings == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FullSize = Head->Length;
+ CharInStr = (INT8*)Head + Head->Length;
+ *Size = FullSize;
+ *NumberOfStrings = 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 < SMBIOS_STRING_MAX_LENGTH; StrLen++) {
+ if (*(CharInStr+StrLen) == 0) {
+ break;
+ }
+ }
+
+ if (StrLen == SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // forward the pointer
+ //
+ CharInStr += StrLen;
+ *Size += StrLen;
+ *NumberOfStrings += 1;
+
+ }
+
+ //
+ // count ending two zeros.
+ //
+ *Size += 2;
+ return EFI_SUCCESS;
+}
diff --git a/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc b/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc
index 1e6b405..ec1a62b 100644
--- a/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc
+++ b/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc
@@ -243,6 +243,7 @@ define GCC_MACRO = -DEFI_SPECIFICATION_VERSION=0x00020000 -DPI_S
EdkCompatibilityPkg/Compatibility/UcOnUc2Thunk/UcOnUc2Thunk.inf
EdkCompatibilityPkg/Compatibility/PrintThunk/PrintThunk.inf
EdkCompatibilityPkg/Compatibility/LegacyRegion2OnLegacyRegionThunk/LegacyRegion2OnLegacyRegionThunk.inf
+ EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/DataHubSmBiosRecordsOnPiSmBiosThunk.inf
EdkCompatibilityPkg/Compatibility/CpuIo2OnCpuIoThunk/CpuIo2OnCpuIoThunk.inf
#