summaryrefslogtreecommitdiffstats
path: root/EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/MemoryConv.c
diff options
context:
space:
mode:
Diffstat (limited to 'EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/MemoryConv.c')
-rw-r--r--EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/MemoryConv.c1089
1 files changed, 1089 insertions, 0 deletions
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;
+}