summaryrefslogtreecommitdiff
path: root/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk
diff options
context:
space:
mode:
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>2009-12-30 06:42:12 +0000
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>2009-12-30 06:42:12 +0000
commitcde64255132b46dde9090220f7e622eb9abd9003 (patch)
treee584038ee5b337258b08ebbddf94198868a176db /EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk
parent3bfa77f0f6dc52dc867318b86ddd23bcf504818f (diff)
downloadedk2-platforms-cde64255132b46dde9090220f7e622eb9abd9003.tar.xz
Rename DataHubSmBiosRecordsOnPiSmBiosThunk to PiSmbiosRecordOnDataHubSmbiosRecordThunk to avoid confusion. This thunk is used to filter all smbios related records from datahub and translate these records to SMBIOS record which is added into SMBIOS database via EFI_SMBIOS_PROTOCOL.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9646 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk')
-rw-r--r--EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/ConvLib.c786
-rw-r--r--EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/ConvTable.c1235
-rw-r--r--EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/MemoryConv.c1089
-rw-r--r--EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/MiscConv.c2444
-rw-r--r--EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/PiSmbiosRecordOnDataHubSmbiosRecordThunk.inf75
-rw-r--r--EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/ProcessorConv.c164
-rw-r--r--EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/Thunk.c160
-rw-r--r--EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/Thunk.h842
-rw-r--r--EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/Translate.c591
9 files changed, 7386 insertions, 0 deletions
diff --git a/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/ConvLib.c b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/ConvLib.c
new file mode 100644
index 0000000000..fac1fb7b58
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/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 NewBufferSize 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 == NULL) {
+ 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/PiSmbiosRecordOnDataHubSmbiosRecordThunk/ConvTable.c b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/ConvTable.c
new file mode 100644
index 0000000000..28097482ad
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/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/PiSmbiosRecordOnDataHubSmbiosRecordThunk/MemoryConv.c b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/MemoryConv.c
new file mode 100644
index 0000000000..9200738ee3
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/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) {
+ 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/PiSmbiosRecordOnDataHubSmbiosRecordThunk/MiscConv.c b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/MiscConv.c
new file mode 100644
index 0000000000..3ffbbe5195
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/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/PiSmbiosRecordOnDataHubSmbiosRecordThunk/PiSmbiosRecordOnDataHubSmbiosRecordThunk.inf b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/PiSmbiosRecordOnDataHubSmbiosRecordThunk.inf
new file mode 100644
index 0000000000..782d64aaa5
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/PiSmbiosRecordOnDataHubSmbiosRecordThunk.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/PiSmbiosRecordOnDataHubSmbiosRecordThunk/ProcessorConv.c b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/ProcessorConv.c
new file mode 100644
index 0000000000..5bd32070c7
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/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/PiSmbiosRecordOnDataHubSmbiosRecordThunk/Thunk.c b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/Thunk.c
new file mode 100644
index 0000000000..797f8036a3
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/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/PiSmbiosRecordOnDataHubSmbiosRecordThunk/Thunk.h b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/Thunk.h
new file mode 100644
index 0000000000..2069fa962a
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/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 NewBufferSize 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/PiSmbiosRecordOnDataHubSmbiosRecordThunk/Translate.c b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/Translate.c
new file mode 100644
index 0000000000..3230d96576
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/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 == NULL) {
+ 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 == NULL) {
+ //
+ // 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 == NULL) {
+ //
+ // 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 == NULL) {
+ //
+ // 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;
+}