|
@@ -10,17 +10,52 @@
|
|
|
**/
|
|
|
|
|
|
#include <PiDxe.h>
|
|
|
+#include <IndustryStandard/SdramSpdDdr4.h>
|
|
|
#include <IndustryStandard/SmBios.h>
|
|
|
#include <Library/BaseLib.h>
|
|
|
#include <Library/BaseMemoryLib.h>
|
|
|
#include <Library/DebugLib.h>
|
|
|
#include <Library/HobLib.h>
|
|
|
#include <Library/MemoryAllocationLib.h>
|
|
|
+#include <Library/PrintLib.h>
|
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
|
#include <Protocol/Smbios.h>
|
|
|
|
|
|
STATIC EFI_SMBIOS_PROTOCOL *mSmbios;
|
|
|
|
|
|
+#define SPD4_MEM_BUS_WIDTH_8BIT (0x00)
|
|
|
+#define SPD4_MEM_BUS_WIDTH_16BIT (BIT0)
|
|
|
+#define SPD4_MEM_BUS_WIDTH_32BIT (BIT1)
|
|
|
+#define SPD4_MEM_BUS_WIDTH_64BIT (BIT0 | BIT1)
|
|
|
+
|
|
|
+#define SPD4_MEM_DEV_WIDTH_4BIT (0x00)
|
|
|
+#define SPD4_MEM_DEV_WIDTH_8BIT (BIT0)
|
|
|
+#define SPD4_MEM_DEV_WIDTH_16BIT (BIT1)
|
|
|
+#define SPD4_MEM_DEV_WIDTH_32BIT (BIT0 | BIT1)
|
|
|
+
|
|
|
+#define SPD4_DDR4_SDRAM_TYPE (0x0C)
|
|
|
+
|
|
|
+#define SPD4_MEM_MODULE_TYPE_RDIMM (0x01)
|
|
|
+#define SPD4_MEM_MODULE_TYPE_UDIMM (0x02)
|
|
|
+#define SPD4_MEM_MODULE_TYPE_SODIMM (0x03)
|
|
|
+
|
|
|
+#define TYPE17_DEVICE_LOCATOR_LEN (8 + 1)
|
|
|
+#define TYPE17_BANK_LOCATOR_LEN (20 + 1)
|
|
|
+#define TYPE17_MANUFACTURER_NAME_LEN (30 + 1)
|
|
|
+#define TYPE17_SERIAL_NUMBER_LEN (16 + 1)
|
|
|
+#define TYPE17_ASSETTAG_LEN (16 + 1)
|
|
|
+#define TYPE17_MODULE_PART_NUMBER_LEN (20 + 1)
|
|
|
+#define TYPE17_FIRMWARE_VERSION_LEN (8 + 1)
|
|
|
+
|
|
|
+#define TYPE17_STRINGS_MAX_LEN (TYPE17_DEVICE_LOCATOR_LEN + \
|
|
|
+ TYPE17_BANK_LOCATOR_LEN + \
|
|
|
+ TYPE17_MANUFACTURER_NAME_LEN + \
|
|
|
+ TYPE17_SERIAL_NUMBER_LEN + \
|
|
|
+ TYPE17_ASSETTAG_LEN + \
|
|
|
+ TYPE17_MODULE_PART_NUMBER_LEN + \
|
|
|
+ TYPE17_FIRMWARE_VERSION_LEN + \
|
|
|
+ 1/* null SMBIOS_TABLE_STRING terminator */ )
|
|
|
+
|
|
|
//
|
|
|
// Type definition and contents of the default SMBIOS table.
|
|
|
// This table covers only the minimum structures required by
|
|
@@ -69,7 +104,7 @@ typedef struct {
|
|
|
|
|
|
typedef struct {
|
|
|
SMBIOS_TABLE_TYPE17 Base;
|
|
|
- CHAR8 Strings[];
|
|
|
+ CHAR8 Strings[TYPE17_STRINGS_MAX_LEN];
|
|
|
} ARM_TYPE17;
|
|
|
|
|
|
typedef struct {
|
|
@@ -94,6 +129,69 @@ enum {
|
|
|
SMBIOS_HANDLE_MEMORY,
|
|
|
};
|
|
|
|
|
|
+struct JEP106_MANUFACTURER_TABLE {
|
|
|
+ UINT16 ManufacturerId;
|
|
|
+ CHAR8 ManufacturerName[TYPE17_MANUFACTURER_NAME_LEN];
|
|
|
+};
|
|
|
+
|
|
|
+STATIC CONST struct JEP106_MANUFACTURER_TABLE Manufacturer[] = {
|
|
|
+ {0x0010, "NEC\0"},
|
|
|
+ {0x002C, "Micron Technology\0"},
|
|
|
+ {0x003D, "Tektronix\0"},
|
|
|
+ {0x0097, "Texas Instruments\0"},
|
|
|
+ {0x00AD, "SK Hynix\0"},
|
|
|
+ {0x00B3, "IDT\0"},
|
|
|
+ {0x00C1, "Infineon\0"},
|
|
|
+ {0x00CE, "Samsung\0"},
|
|
|
+ {0x00DA, "Winbond Electronic\0"},
|
|
|
+ {0x014F, "Transcend Information\0"},
|
|
|
+ {0x0194, "Smart Modular\0"},
|
|
|
+ {0x0198, "Kingston\0"},
|
|
|
+ {0x02C8, "Agilent Technologies\0"},
|
|
|
+ {0x02FE, "Elpida\0"},
|
|
|
+ {0x030B, "Nanya Technology\0"},
|
|
|
+ {0x0443, "Ramaxel Technology\0"},
|
|
|
+ {0x04B3, "Inphi Corporation\0"},
|
|
|
+ {0x04C8, "Powerchip Semiconductor\0"},
|
|
|
+ {0x0551, "Qimonda\0"},
|
|
|
+ {0x0557, "AENEON\0"},
|
|
|
+ {0x059B, "Crucial Technology\0"},
|
|
|
+ {0xFFFF, "Unknown\0"}
|
|
|
+};
|
|
|
+
|
|
|
+enum SPD4_SDRAM_CAPACITY {
|
|
|
+ SPD4_SDRAM_CAPACITY_256MBIT = 0,
|
|
|
+ SPD4_SDRAM_CAPACITY_512MBIT,
|
|
|
+ SPD4_SDRAM_CAPACITY_1GBIT,
|
|
|
+ SPD4_SDRAM_CAPACITY_2GBIT,
|
|
|
+ SPD4_SDRAM_CAPACITY_4GBIT,
|
|
|
+ SPD4_SDRAM_CAPACITY_8GBIT,
|
|
|
+ SPD4_SDRAM_CAPACITY_16GBIT,
|
|
|
+ SPD4_SDRAM_CAPACITY_32GBIT,
|
|
|
+ SPD4_SDRAM_CAPACITY_12GBIT,
|
|
|
+ SPD4_SDRAM_CAPACITY_24GBIT,
|
|
|
+ SPD4_SDRAM_CAPACITY_INVALID = 0xFF,
|
|
|
+};
|
|
|
+
|
|
|
+struct SPD4_SDRAM_CAPACITY_TABLE {
|
|
|
+ enum SPD4_SDRAM_CAPACITY Capacity;
|
|
|
+ UINT16 SizeMbit;
|
|
|
+};
|
|
|
+
|
|
|
+STATIC CONST struct SPD4_SDRAM_CAPACITY_TABLE CapacityTable[] = {
|
|
|
+ {SPD4_SDRAM_CAPACITY_256MBIT, 256 },
|
|
|
+ {SPD4_SDRAM_CAPACITY_512MBIT, 512 },
|
|
|
+ {SPD4_SDRAM_CAPACITY_1GBIT, (1 * 1024) },
|
|
|
+ {SPD4_SDRAM_CAPACITY_2GBIT, (2 * 1024) },
|
|
|
+ {SPD4_SDRAM_CAPACITY_4GBIT, (4 * 1024) },
|
|
|
+ {SPD4_SDRAM_CAPACITY_8GBIT, (8 * 1024) },
|
|
|
+ {SPD4_SDRAM_CAPACITY_16GBIT, (16 * 1024)},
|
|
|
+ {SPD4_SDRAM_CAPACITY_32GBIT, (32 * 1024)},
|
|
|
+ {SPD4_SDRAM_CAPACITY_12GBIT, (12 * 1024)},
|
|
|
+ {SPD4_SDRAM_CAPACITY_24GBIT, (24 * 1024)},
|
|
|
+ {SPD4_SDRAM_CAPACITY_INVALID, 0 },
|
|
|
+};
|
|
|
+
|
|
|
// BIOS information (section 7.1)
|
|
|
STATIC CONST ARM_TYPE0 mArmDefaultType0 = {
|
|
|
{
|
|
@@ -394,123 +492,6 @@ STATIC CONST ARM_TYPE16 mArmDefaultType16 = {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-// Memory device
|
|
|
-STATIC CONST ARM_TYPE17 mArmDefaultType17_1 = {
|
|
|
- {
|
|
|
- { // SMBIOS_STRUCTURE Hdr
|
|
|
- EFI_SMBIOS_TYPE_MEMORY_DEVICE,
|
|
|
- sizeof (SMBIOS_TABLE_TYPE17),
|
|
|
- SMBIOS_HANDLE_PI_RESERVED,
|
|
|
- },
|
|
|
- SMBIOS_HANDLE_MEMORY, // array to which this module belongs
|
|
|
- 0xFFFE, // no errors
|
|
|
- 72, // single DIMM with ECC
|
|
|
- 64, // data width of this device (64-bits)
|
|
|
- 0xFFFF, // size unknown
|
|
|
- 0x09, // DIMM
|
|
|
- 1, // part of a set
|
|
|
- 1, // device locator
|
|
|
- 0, // bank locator
|
|
|
- MemoryTypeDdr4, // DDR4
|
|
|
- {}, // type detail
|
|
|
- 0, // ? MHz
|
|
|
- 0, // manufacturer
|
|
|
- 0, // serial
|
|
|
- 0, // asset tag
|
|
|
- 0, // part number
|
|
|
- 0, // rank
|
|
|
- }, {
|
|
|
- "DIMM1\0"
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-STATIC CONST ARM_TYPE17 mArmDefaultType17_2 = {
|
|
|
- {
|
|
|
- { // SMBIOS_STRUCTURE Hdr
|
|
|
- EFI_SMBIOS_TYPE_MEMORY_DEVICE,
|
|
|
- sizeof (SMBIOS_TABLE_TYPE17),
|
|
|
- SMBIOS_HANDLE_PI_RESERVED,
|
|
|
- },
|
|
|
- SMBIOS_HANDLE_MEMORY, // array to which this module belongs
|
|
|
- 0xFFFE, // no errors
|
|
|
- 72, // single DIMM with ECC
|
|
|
- 64, // data width of this device (64-bits)
|
|
|
- 0xFFFF, // size unknown
|
|
|
- 0x09, // DIMM
|
|
|
- 1, // part of a set
|
|
|
- 1, // device locator
|
|
|
- 0, // bank locator
|
|
|
- MemoryTypeDdr4, // DDR4
|
|
|
- {}, // type detail
|
|
|
- 0, // ? MHz
|
|
|
- 0, // manufacturer
|
|
|
- 0, // serial
|
|
|
- 0, // asset tag
|
|
|
- 0, // part number
|
|
|
- 0, // rank
|
|
|
- }, {
|
|
|
- "DIMM2\0"
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-STATIC CONST ARM_TYPE17 mArmDefaultType17_3 = {
|
|
|
- {
|
|
|
- { // SMBIOS_STRUCTURE Hdr
|
|
|
- EFI_SMBIOS_TYPE_MEMORY_DEVICE,
|
|
|
- sizeof (SMBIOS_TABLE_TYPE17),
|
|
|
- SMBIOS_HANDLE_PI_RESERVED,
|
|
|
- },
|
|
|
- SMBIOS_HANDLE_MEMORY, // array to which this module belongs
|
|
|
- 0xFFFE, // no errors
|
|
|
- 72, // single DIMM with ECC
|
|
|
- 64, // data width of this device (64-bits)
|
|
|
- 0xFFFF, // size unknown
|
|
|
- 0x09, // DIMM
|
|
|
- 1, // part of a set
|
|
|
- 1, // device locator
|
|
|
- 0, // bank locator
|
|
|
- MemoryTypeDdr4, // DDR4
|
|
|
- {}, // type detail
|
|
|
- 0, // ? MHz
|
|
|
- 0, // manufacturer
|
|
|
- 0, // serial
|
|
|
- 0, // asset tag
|
|
|
- 0, // part number
|
|
|
- 0, // rank
|
|
|
- }, {
|
|
|
- "DIMM3\0"
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-STATIC CONST ARM_TYPE17 mArmDefaultType17_4 = {
|
|
|
- {
|
|
|
- { // SMBIOS_STRUCTURE Hdr
|
|
|
- EFI_SMBIOS_TYPE_MEMORY_DEVICE,
|
|
|
- sizeof (SMBIOS_TABLE_TYPE17),
|
|
|
- SMBIOS_HANDLE_PI_RESERVED,
|
|
|
- },
|
|
|
- SMBIOS_HANDLE_MEMORY, // array to which this module belongs
|
|
|
- 0xFFFE, // no errors
|
|
|
- 72, // single DIMM with ECC
|
|
|
- 64, // data width of this device (64-bits)
|
|
|
- 0xFFFF, // size unknown
|
|
|
- 0x09, // DIMM
|
|
|
- 1, // part of a set
|
|
|
- 1, // device locator
|
|
|
- 0, // bank locator
|
|
|
- MemoryTypeDdr4, // DDR4
|
|
|
- {}, // type detail
|
|
|
- 0, // ? MHz
|
|
|
- 0, // manufacturer
|
|
|
- 0, // serial
|
|
|
- 0, // asset tag
|
|
|
- 0, // part number
|
|
|
- 0, // rank
|
|
|
- }, {
|
|
|
- "DIMM4\0"
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
// Memory array mapped address, this structure
|
|
|
// is overridden by InstallMemoryStructure
|
|
|
STATIC CONST ARM_TYPE19 mArmDefaultType19 = {
|
|
@@ -559,13 +540,330 @@ STATIC SMBIOS_STRUCTURE * CONST FixedTables[] = {
|
|
|
(SMBIOS_STRUCTURE *)&mArmDefaultType9_1.Base.Hdr,
|
|
|
(SMBIOS_STRUCTURE *)&mArmDefaultType9_2.Base.Hdr,
|
|
|
(SMBIOS_STRUCTURE *)&mArmDefaultType16.Base.Hdr,
|
|
|
- (SMBIOS_STRUCTURE *)&mArmDefaultType17_1.Base.Hdr,
|
|
|
- (SMBIOS_STRUCTURE *)&mArmDefaultType17_2.Base.Hdr,
|
|
|
- (SMBIOS_STRUCTURE *)&mArmDefaultType17_3.Base.Hdr,
|
|
|
- (SMBIOS_STRUCTURE *)&mArmDefaultType17_4.Base.Hdr,
|
|
|
(SMBIOS_STRUCTURE *)&mArmDefaultType32.Base.Hdr,
|
|
|
};
|
|
|
|
|
|
+STATIC
|
|
|
+UINT16
|
|
|
+GetPrimaryBusWidth (
|
|
|
+ IN UINT8 SpdPrimaryBusWidth
|
|
|
+ )
|
|
|
+{
|
|
|
+ UINT16 PrimaryBusWidth;
|
|
|
+
|
|
|
+ switch (SpdPrimaryBusWidth) {
|
|
|
+ case SPD4_MEM_BUS_WIDTH_8BIT:
|
|
|
+ PrimaryBusWidth = 8;
|
|
|
+ break;
|
|
|
+ case SPD4_MEM_BUS_WIDTH_16BIT:
|
|
|
+ PrimaryBusWidth = 16;
|
|
|
+ break;
|
|
|
+ case SPD4_MEM_BUS_WIDTH_32BIT:
|
|
|
+ PrimaryBusWidth = 32;
|
|
|
+ break;
|
|
|
+ case SPD4_MEM_BUS_WIDTH_64BIT:
|
|
|
+ PrimaryBusWidth = 64;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ PrimaryBusWidth = 0xFFFF;
|
|
|
+ ASSERT(FALSE);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return PrimaryBusWidth;
|
|
|
+}
|
|
|
+
|
|
|
+STATIC
|
|
|
+UINT16
|
|
|
+GetSdramDeviceWidth (
|
|
|
+ IN UINT8 SpdSdramDeviceWidth
|
|
|
+ )
|
|
|
+{
|
|
|
+ UINT16 SdramDeviceWidth;
|
|
|
+
|
|
|
+ switch (SpdSdramDeviceWidth) {
|
|
|
+ case SPD4_MEM_DEV_WIDTH_4BIT:
|
|
|
+ SdramDeviceWidth = 4;
|
|
|
+ break;
|
|
|
+ case SPD4_MEM_DEV_WIDTH_8BIT:
|
|
|
+ SdramDeviceWidth = 8;
|
|
|
+ break;
|
|
|
+ case SPD4_MEM_DEV_WIDTH_16BIT:
|
|
|
+ SdramDeviceWidth = 16;
|
|
|
+ break;
|
|
|
+ case SPD4_MEM_DEV_WIDTH_32BIT:
|
|
|
+ SdramDeviceWidth = 32;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ SdramDeviceWidth = 0;
|
|
|
+ ASSERT(FALSE);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return SdramDeviceWidth;
|
|
|
+}
|
|
|
+
|
|
|
+STATIC
|
|
|
+UINT16
|
|
|
+CalculateModuleDramCapacityMB (
|
|
|
+ IN SPD4_BASE_SECTION *Spd4Base
|
|
|
+ )
|
|
|
+{
|
|
|
+ UINT32 SdramCapacityMbit;
|
|
|
+ UINT16 PrimaryBusWidth;
|
|
|
+ UINT8 SdramDeviceWidth;
|
|
|
+ UINT8 SdramDeviceWidthShiftNum;
|
|
|
+ UINT8 RankCount;
|
|
|
+ UINT16 DramSize;
|
|
|
+ UINT32 Index;
|
|
|
+
|
|
|
+ SdramCapacityMbit = 0;
|
|
|
+
|
|
|
+ for (Index = 0; CapacityTable[Index].Capacity != SPD4_SDRAM_CAPACITY_INVALID; Index++) {
|
|
|
+ if (Spd4Base->SdramDensityAndBanks.Bits.Density == CapacityTable[Index].Capacity) {
|
|
|
+ SdramCapacityMbit = CapacityTable[Index].SizeMbit;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ PrimaryBusWidth = GetPrimaryBusWidth (Spd4Base->ModuleMemoryBusWidth.Bits.PrimaryBusWidth);
|
|
|
+ SdramDeviceWidth = GetSdramDeviceWidth (Spd4Base->ModuleOrganization.Bits.SdramDeviceWidth);
|
|
|
+ RankCount = Spd4Base->ModuleOrganization.Bits.RankCount + 1;
|
|
|
+
|
|
|
+ if ((SdramCapacityMbit == 0) || (PrimaryBusWidth == 0xFFFF) ||
|
|
|
+ (SdramDeviceWidth == 0) || RankCount == 0) {
|
|
|
+ DEBUG ((DEBUG_ERROR, "Calculate DRAM size failed. Cap:%d, BusWidth:%d, "
|
|
|
+ "DevWidth:%d, Rank:%d\n", SdramCapacityMbit,
|
|
|
+ PrimaryBusWidth, SdramDeviceWidth, RankCount));
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ //Total[MB] = SDRAM Capacity[Mb] / 8 * Primary Bus Width /
|
|
|
+ // SDRAM Width * Logical Ranks per DIMM
|
|
|
+ //
|
|
|
+ switch (SdramDeviceWidth) {
|
|
|
+ case 4:
|
|
|
+ SdramDeviceWidthShiftNum = 2;
|
|
|
+ break;
|
|
|
+ case 8:
|
|
|
+ SdramDeviceWidthShiftNum = 3;
|
|
|
+ break;
|
|
|
+ case 16:
|
|
|
+ SdramDeviceWidthShiftNum = 4;
|
|
|
+ break;
|
|
|
+ case 32:
|
|
|
+ SdramDeviceWidthShiftNum = 5;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ SdramDeviceWidthShiftNum = 0;
|
|
|
+ ASSERT(FALSE);
|
|
|
+ break;
|
|
|
+ };
|
|
|
+ DramSize = (((SdramCapacityMbit >> 3) * PrimaryBusWidth) >> SdramDeviceWidthShiftNum) * RankCount;
|
|
|
+
|
|
|
+ return DramSize;
|
|
|
+}
|
|
|
+
|
|
|
+STATIC
|
|
|
+VOID
|
|
|
+GetManufacturerName (
|
|
|
+ IN UINT16 SpdManufacturerId,
|
|
|
+ OUT CHAR8 *ManufacturerStr
|
|
|
+ )
|
|
|
+{
|
|
|
+ UINT16 ManufacturerId;
|
|
|
+ UINT32 Index;
|
|
|
+ RETURN_STATUS RetStatus;
|
|
|
+
|
|
|
+ ManufacturerId = SwapBytes16 (SpdManufacturerId);
|
|
|
+ ManufacturerId &= 0x7FFF; // ignore odd parity bit
|
|
|
+
|
|
|
+ for (Index = 0; Manufacturer[Index].ManufacturerId != 0xFFFF; Index++) {
|
|
|
+ if (ManufacturerId == Manufacturer[Index].ManufacturerId) {
|
|
|
+ RetStatus = AsciiStrCpyS (ManufacturerStr, TYPE17_MANUFACTURER_NAME_LEN,
|
|
|
+ Manufacturer[Index].ManufacturerName);
|
|
|
+ ASSERT_RETURN_ERROR (RetStatus);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ RetStatus = AsciiStrCpyS (ManufacturerStr, TYPE17_MANUFACTURER_NAME_LEN,
|
|
|
+ Manufacturer[Index].ManufacturerName);
|
|
|
+ ASSERT_RETURN_ERROR (RetStatus);
|
|
|
+}
|
|
|
+
|
|
|
+STATIC
|
|
|
+BOOLEAN
|
|
|
+IsValidSPD (
|
|
|
+ IN SPD4_BASE_SECTION *Spd4Base
|
|
|
+ )
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Developerbox only supports DDR4.
|
|
|
+ // If the device type is not DDR4 SDRAM, the SPD is invalid
|
|
|
+ //
|
|
|
+ if (Spd4Base->DramDeviceType.Bits.Type == SPD4_DDR4_SDRAM_TYPE) {
|
|
|
+ return TRUE;
|
|
|
+ } else {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+STATIC
|
|
|
+EFI_STATUS
|
|
|
+InstallMemoryDeviceStructure (
|
|
|
+ VOID
|
|
|
+ )
|
|
|
+{
|
|
|
+ EFI_SMBIOS_HANDLE SmbiosHandle;
|
|
|
+ ARM_TYPE17 *Descriptor;
|
|
|
+ SPD_DDR4 *Spd;
|
|
|
+ UINT8 Slot;
|
|
|
+ CHAR8 *StringPtr;
|
|
|
+
|
|
|
+ CHAR8 DeviceLocatorStr[TYPE17_DEVICE_LOCATOR_LEN];
|
|
|
+ CHAR8 BankLocatorStr[TYPE17_BANK_LOCATOR_LEN];
|
|
|
+ CHAR8 ManufacturerStr[TYPE17_MANUFACTURER_NAME_LEN];
|
|
|
+ CHAR8 SerialNumberStr[TYPE17_SERIAL_NUMBER_LEN];
|
|
|
+ CHAR8 PartNumberStr[TYPE17_MODULE_PART_NUMBER_LEN];
|
|
|
+ CHAR8 FirmwareVersionStr[TYPE17_FIRMWARE_VERSION_LEN];
|
|
|
+
|
|
|
+ Descriptor = AllocateZeroPool(sizeof (ARM_TYPE17));
|
|
|
+ if (Descriptor == NULL) {
|
|
|
+ return EFI_OUT_OF_RESOURCES;
|
|
|
+ }
|
|
|
+
|
|
|
+ Spd = (SPD_DDR4 *) FixedPcdGet32 (PcdStoredSpdDDR4Address);
|
|
|
+
|
|
|
+ for (Slot = 0; Slot < 4; Slot++, Spd++) {
|
|
|
+ SetMem (Descriptor, sizeof (ARM_TYPE17), 0);
|
|
|
+ // fill fixed parameters
|
|
|
+ Descriptor->Base.Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE;
|
|
|
+ Descriptor->Base.Hdr.Length = sizeof (SMBIOS_TABLE_TYPE17);
|
|
|
+ Descriptor->Base.Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED;
|
|
|
+ Descriptor->Base.MemoryArrayHandle = SMBIOS_HANDLE_MEMORY;
|
|
|
+ Descriptor->Base.MemoryErrorInformationHandle = 0xFFFE;
|
|
|
+ Descriptor->Base.ExtendedSize = 0;
|
|
|
+ Descriptor->Base.ExtendedSpeed = 0;
|
|
|
+ Descriptor->Base.ExtendedConfiguredMemorySpeed = 0;
|
|
|
+ Descriptor->Base.MemoryOperatingModeCapability.Bits.VolatileMemory = 1;
|
|
|
+ Descriptor->Base.DeviceSet = 1;
|
|
|
+ Descriptor->Base.MemoryType = MemoryTypeDdr4;
|
|
|
+ Descriptor->Base.DeviceLocator = 1;
|
|
|
+ Descriptor->Base.BankLocator = 2;
|
|
|
+
|
|
|
+ AsciiSPrint (DeviceLocatorStr, sizeof(DeviceLocatorStr), "DIMM %d\0", (Slot + 1));
|
|
|
+ AsciiSPrint (BankLocatorStr, sizeof(BankLocatorStr), "CHANNEL %d SLOT %d\0", (Slot / 2), (Slot % 2));
|
|
|
+
|
|
|
+ StringPtr = Descriptor->Strings;
|
|
|
+ AsciiStrnCpyS (StringPtr, TYPE17_DEVICE_LOCATOR_LEN, DeviceLocatorStr,
|
|
|
+ TYPE17_DEVICE_LOCATOR_LEN - 1);
|
|
|
+ StringPtr += AsciiStrSize (StringPtr);
|
|
|
+ AsciiStrnCpyS (StringPtr, TYPE17_BANK_LOCATOR_LEN, BankLocatorStr,
|
|
|
+ TYPE17_BANK_LOCATOR_LEN - 1);
|
|
|
+ StringPtr += AsciiStrSize (StringPtr);
|
|
|
+
|
|
|
+ if (IsValidSPD ((SPD4_BASE_SECTION *)Spd)) {
|
|
|
+ Descriptor->Base.Manufacturer = 3;
|
|
|
+ Descriptor->Base.SerialNumber = 4;
|
|
|
+ Descriptor->Base.AssetTag = 5;
|
|
|
+ Descriptor->Base.PartNumber = 6;
|
|
|
+ Descriptor->Base.FirmwareVersion = 7;
|
|
|
+
|
|
|
+ Descriptor->Base.TotalWidth = Descriptor->Base.DataWidth =
|
|
|
+ GetPrimaryBusWidth (Spd->Base.ModuleMemoryBusWidth.Bits.PrimaryBusWidth);
|
|
|
+ if (Spd->Base.ModuleMemoryBusWidth.Bits.BusWidthExtension) {
|
|
|
+ if (Descriptor->Base.TotalWidth != 0xFFFF) {
|
|
|
+ Descriptor->Base.TotalWidth += 8;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Descriptor->Base.Size = CalculateModuleDramCapacityMB ((SPD4_BASE_SECTION *)Spd);
|
|
|
+
|
|
|
+ switch (Spd->Base.ModuleType.Bits.ModuleType) {
|
|
|
+ case SPD4_MEM_MODULE_TYPE_RDIMM:
|
|
|
+ Descriptor->Base.FormFactor = 0x09;
|
|
|
+ Descriptor->Base.TypeDetail.Registered = 1;
|
|
|
+ Descriptor->Base.TypeDetail.Unbuffered = 0;
|
|
|
+ break;
|
|
|
+ case SPD4_MEM_MODULE_TYPE_UDIMM:
|
|
|
+ Descriptor->Base.FormFactor = 0x09;
|
|
|
+ Descriptor->Base.TypeDetail.Registered = 0;
|
|
|
+ Descriptor->Base.TypeDetail.Unbuffered = 1;
|
|
|
+ break;
|
|
|
+ case SPD4_MEM_MODULE_TYPE_SODIMM:
|
|
|
+ Descriptor->Base.FormFactor = 0x0D;
|
|
|
+ Descriptor->Base.TypeDetail.Registered = 0;
|
|
|
+ Descriptor->Base.TypeDetail.Unbuffered = 1;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ Descriptor->Base.FormFactor = 0x01;
|
|
|
+ Descriptor->Base.TypeDetail.Registered = 0;
|
|
|
+ Descriptor->Base.TypeDetail.Unbuffered = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ Descriptor->Base.Attributes = Spd->Base.ModuleOrganization.Bits.RankCount + 1;
|
|
|
+ Descriptor->Base.Speed = 2133;
|
|
|
+ Descriptor->Base.ConfiguredMemoryClockSpeed = 2133;
|
|
|
+ Descriptor->Base.MinimumVoltage = 1200;
|
|
|
+ Descriptor->Base.MaximumVoltage = 1200;
|
|
|
+ Descriptor->Base.ConfiguredVoltage = 1200;
|
|
|
+ Descriptor->Base.MemoryTechnology = MemoryTechnologyDram;
|
|
|
+ Descriptor->Base.ModuleManufacturerID = Spd->ManufactureInfo.ModuleId.IdCode.Data;
|
|
|
+
|
|
|
+ GetManufacturerName (Spd->ManufactureInfo.ModuleId.IdCode.Data, ManufacturerStr);
|
|
|
+ AsciiSPrint (SerialNumberStr, TYPE17_SERIAL_NUMBER_LEN, "0x%08X\0",
|
|
|
+ SwapBytes32(Spd->ManufactureInfo.ModuleId.SerialNumber.Data));
|
|
|
+ //
|
|
|
+ // Module part number is not null terminated string in SPD DDR4,
|
|
|
+ // unused digits are coded as ASCII blanks(0x20).
|
|
|
+ //
|
|
|
+ ZeroMem(PartNumberStr, TYPE17_MODULE_PART_NUMBER_LEN);
|
|
|
+ CopyMem (PartNumberStr,
|
|
|
+ (CHAR8 *)Spd->ManufactureInfo.ModulePartNumber.ModulePartNumber,
|
|
|
+ TYPE17_MODULE_PART_NUMBER_LEN - 1);
|
|
|
+
|
|
|
+ AsciiSPrint (FirmwareVersionStr, sizeof(FirmwareVersionStr), "%d\0", FixedPcdGet32 (PcdFirmwareRevision));
|
|
|
+
|
|
|
+ AsciiStrnCpyS (StringPtr, TYPE17_MANUFACTURER_NAME_LEN, ManufacturerStr,
|
|
|
+ TYPE17_MANUFACTURER_NAME_LEN - 1);
|
|
|
+ StringPtr += AsciiStrSize (StringPtr);
|
|
|
+ AsciiStrnCpyS (StringPtr, TYPE17_SERIAL_NUMBER_LEN, SerialNumberStr,
|
|
|
+ TYPE17_SERIAL_NUMBER_LEN - 1);
|
|
|
+ StringPtr += AsciiStrSize (StringPtr);
|
|
|
+ AsciiStrnCpyS (StringPtr, TYPE17_ASSETTAG_LEN, "-\0",
|
|
|
+ TYPE17_ASSETTAG_LEN - 1);
|
|
|
+ StringPtr += AsciiStrSize (StringPtr);
|
|
|
+ AsciiStrnCpyS (StringPtr, TYPE17_MODULE_PART_NUMBER_LEN, PartNumberStr,
|
|
|
+ TYPE17_MODULE_PART_NUMBER_LEN - 1);
|
|
|
+ StringPtr += AsciiStrSize (StringPtr);
|
|
|
+ AsciiStrnCpyS (StringPtr, TYPE17_FIRMWARE_VERSION_LEN, FirmwareVersionStr,
|
|
|
+ TYPE17_FIRMWARE_VERSION_LEN - 1);
|
|
|
+ } else {
|
|
|
+ Descriptor->Base.TotalWidth = 0xFFFF;
|
|
|
+ Descriptor->Base.DataWidth = 0xFFFF;
|
|
|
+ Descriptor->Base.Size = 0;
|
|
|
+ Descriptor->Base.FormFactor = 0x09;
|
|
|
+ Descriptor->Base.DeviceSet = 1;
|
|
|
+ Descriptor->Base.Attributes = 0;
|
|
|
+ Descriptor->Base.Speed = 0;
|
|
|
+ Descriptor->Base.ConfiguredMemoryClockSpeed = 0;
|
|
|
+ Descriptor->Base.MinimumVoltage = 0;
|
|
|
+ Descriptor->Base.MaximumVoltage = 0;
|
|
|
+ Descriptor->Base.ConfiguredVoltage = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ SmbiosHandle = Descriptor->Base.Hdr.Handle;
|
|
|
+ mSmbios->Add (mSmbios, NULL, &SmbiosHandle, &Descriptor->Base.Hdr);
|
|
|
+ }
|
|
|
+
|
|
|
+ FreePool (Descriptor);
|
|
|
+
|
|
|
+ return EFI_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
STATIC
|
|
|
EFI_STATUS
|
|
|
InstallMemoryStructure (
|
|
@@ -587,6 +885,7 @@ InstallMemoryStructure (
|
|
|
return mSmbios->Add (mSmbios, NULL, &SmbiosHandle, &Descriptor->Base.Hdr);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
STATIC
|
|
|
VOID
|
|
|
InstallAllStructures (
|
|
@@ -608,6 +907,16 @@ InstallAllStructures (
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ //
|
|
|
+ // SPD_DDR4 data is stored in Non Secure SRAM by SCP-firmware.
|
|
|
+ // Install Type17 record by analyzing SPD_DDR4 information.
|
|
|
+ //
|
|
|
+ Status = InstallMemoryDeviceStructure();
|
|
|
+ if (EFI_ERROR(Status)) {
|
|
|
+ DEBUG ((DEBUG_WARN, "%a: failed to add SMBIOS type 17 table - %r\n",
|
|
|
+ __FUNCTION__, Status));
|
|
|
+ }
|
|
|
+
|
|
|
for (Hob.Raw = GetHobList ();
|
|
|
!END_OF_HOB_LIST (Hob);
|
|
|
Hob.Raw = GET_NEXT_HOB (Hob)) {
|