blob: 2a847330aa0fbf659ff03650c3ac2b4d496f1883 [file] [log] [blame]
/** @file
Routines that support Memory SubClass data records translation.
Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "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;
}