From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pg1-f179.google.com (mail-pg1-f179.google.com [209.85.215.179]) by mx.groups.io with SMTP id smtpd.web12.73624.1638261437626455600 for ; Tue, 30 Nov 2021 00:37:17 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@linaro.org header.s=google header.b=vzRUqIPy; spf=pass (domain: linaro.org, ip: 209.85.215.179, mailfrom: masahisa.kojima@linaro.org) Received: by mail-pg1-f179.google.com with SMTP id s137so19032527pgs.5 for ; Tue, 30 Nov 2021 00:37:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=iZl9dayAkrwcqw1gPiRi5qSbdC0HI+r5UiFtgZtS0Gs=; b=vzRUqIPyNPwhDeFamHJJyeJcFSCzX7XaandqWPp3labYseJ2O8OMr//Qoe3OgDAoiQ DnVc58zfHbEOFoBygJxk74ThHPsqnr6W6oWyqlpjwHY8/cvlwHgRopxqabyov69GSkAm NKk/YWVaHs9klbm5zXyKy9Ru7rd2HakOuP3AtsZPTPT9+tnVLv0D31xtCujhRUdqB502 qmBxOe/beRZSIbA7SBsOLWQmxapDYNBHxIxHpZzyE1seidzKV4YwGyO6vwJAPi+hQ2Uy 3eDdyWAnoiKSsejrhlsq4AbCcJckE3tcVc7d/ttoypT5RPdAYsZRq5P4dn7ErNHA/Y6k HIRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=iZl9dayAkrwcqw1gPiRi5qSbdC0HI+r5UiFtgZtS0Gs=; b=l/CtkRwBLY3C/IOP4j3mH6jlYspe2W6/jRxmtE1lRaGYaOuPO6bwGaY2OsVcDROlES 1wApnG4MA6akjutWdaePH04G0FgNQ3DQ2RCzRPHOWXaOBYhPS9n9ul0dY3IpRlakVYSV cRLFT7/nnvpx4zCzdCk6WS5JAPdU0Jp8e67aAiCfqMH9lL6m2VOEAfYlS0SOQVFr0R/q cNb7g7peaBRrpHksejtOHfD2wtvsA8OTo56yzAogUhFZAyYEJP+gBwsxmadSNtWithp0 nZ+M5y2RlCGRm+aXbck0kDyii85nsfGJIGfg5A5H4AoVfUNX5QMmmwxQG7/GK8Ml9FFV TkIw== X-Gm-Message-State: AOAM5310zKv0TWyE1pZJ6pu/N5mlgpRfM63KAC7RmmqmMVcgjo1ANnsC 2DCTyE00Bbu7GMObFy+aSlgU39k9aowfIQ== X-Google-Smtp-Source: ABdhPJxb6NPYz7L7POujYE7GvyZDWqPFjwKfwhNgYDmeuuur/1R4bqUTLecA+XI08CEdwZUemsHTcQ== X-Received: by 2002:a63:7e0d:: with SMTP id z13mr27450641pgc.349.1638261436988; Tue, 30 Nov 2021 00:37:16 -0800 (PST) Return-Path: Received: from localhost.localdomain ([2400:2411:502:a100:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id g17sm20617624pfv.136.2021.11.30.00.37.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Nov 2021 00:37:16 -0800 (PST) From: "Masahisa Kojima" To: devel@edk2.groups.io Cc: sakamoto.kazuhiko@socionext.com, Masahisa Kojima , Ard Biesheuvel , Leif Lindholm , Masami Hiramatsu Subject: [PATCH edk2-platforms 1/1] Platform/Socionext/DeveloperBox: add SMBIOS type 17 table Date: Tue, 30 Nov 2021 17:41:03 +0900 Message-Id: <20211130084103.830-1-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit This commit adds the SMBIOS type 17 table support for Developerbox. The SPD can be accessed only from the SCP through I2C bus, so this commit expects that SCP-firmware reads the SPD and stores it in the non-secure SRAM. This commit also reduces the edk2 stack size to allocate the space for storing SPD. It requires 2KB, 512bytes * 4 DIMMs. Cc: Ard Biesheuvel Cc: Leif Lindholm Cc: Masami Hiramatsu Signed-off-by: Masahisa Kojima --- Silicon/Socionext/SynQuacer/SynQuacer.dec | 3 + Platform/Socionext/DeveloperBox/DeveloperBox.dsc.inc | 2 +- Platform/Socionext/DeveloperBox/DeveloperBox.dsc | 3 + Platform/Socionext/DeveloperBox/SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 2 + Platform/Socionext/DeveloperBox/SmbiosPlatformDxe/SmbiosPlatformDxe.c | 553 +++++++++++++++----- 5 files changed, 440 insertions(+), 123 deletions(-) diff --git a/Silicon/Socionext/SynQuacer/SynQuacer.dec b/Silicon/Socionext/SynQuacer/SynQuacer.dec index e7197e231991..401ac4e78d65 100644 --- a/Silicon/Socionext/SynQuacer/SynQuacer.dec +++ b/Silicon/Socionext/SynQuacer/SynQuacer.dec @@ -43,6 +43,9 @@ [PcdsFixedAtBuild] # for capsule update gSynQuacerTokenSpaceGuid.PcdLowestSupportedFirmwareVersion|1|UINT32|0x00000009 + # for SMBIOS Type17 + gSynQuacerTokenSpaceGuid.PcdStoredSpdDDR4Address|0|UINT32|0x0000000A + [PcdsPatchableInModule, PcdsDynamic] # Enable both RC #0 and RC #1 by default gSynQuacerTokenSpaceGuid.PcdPcieEnableMask|0x3|UINT8|0x00000007 diff --git a/Platform/Socionext/DeveloperBox/DeveloperBox.dsc.inc b/Platform/Socionext/DeveloperBox/DeveloperBox.dsc.inc index 0a364bc45746..c034c0a32cfd 100644 --- a/Platform/Socionext/DeveloperBox/DeveloperBox.dsc.inc +++ b/Platform/Socionext/DeveloperBox/DeveloperBox.dsc.inc @@ -147,7 +147,7 @@ [PcdsFixedAtBuild.common] # non-secure SRAM gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x2E000000 - gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0xFFC0 + gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0xF000 gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|24 diff --git a/Platform/Socionext/DeveloperBox/DeveloperBox.dsc b/Platform/Socionext/DeveloperBox/DeveloperBox.dsc index 9af262a2d149..8419c89318fb 100644 --- a/Platform/Socionext/DeveloperBox/DeveloperBox.dsc +++ b/Platform/Socionext/DeveloperBox/DeveloperBox.dsc @@ -185,6 +185,9 @@ [PcdsFixedAtBuild] gSynQuacerTokenSpaceGuid.PcdDramInfoBase|0x2E00FFC0 + # SCP-firmware stored SPD DDR4 data in non-secure SRAM + gSynQuacerTokenSpaceGuid.PcdStoredSpdDDR4Address|0x2E00F000 + # # 96boards mezzanine support # diff --git a/Platform/Socionext/DeveloperBox/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/Platform/Socionext/DeveloperBox/SmbiosPlatformDxe/SmbiosPlatformDxe.inf index e711cbf6dce7..e0079a18b3c5 100644 --- a/Platform/Socionext/DeveloperBox/SmbiosPlatformDxe/SmbiosPlatformDxe.inf +++ b/Platform/Socionext/DeveloperBox/SmbiosPlatformDxe/SmbiosPlatformDxe.inf @@ -21,6 +21,7 @@ [Packages] ArmPkg/ArmPkg.dec MdeModulePkg/MdeModulePkg.dec MdePkg/MdePkg.dec + Silicon/Socionext/SynQuacer/SynQuacer.dec [LibraryClasses] BaseMemoryLib @@ -34,6 +35,7 @@ [LibraryClasses] [FixedPcd] gArmTokenSpaceGuid.PcdFdSize gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareRevision + gSynQuacerTokenSpaceGuid.PcdStoredSpdDDR4Address [Protocols] gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED diff --git a/Platform/Socionext/DeveloperBox/SmbiosPlatformDxe/SmbiosPlatformDxe.c b/Platform/Socionext/DeveloperBox/SmbiosPlatformDxe/SmbiosPlatformDxe.c index 6227b7787707..f071aa01594d 100644 --- a/Platform/Socionext/DeveloperBox/SmbiosPlatformDxe/SmbiosPlatformDxe.c +++ b/Platform/Socionext/DeveloperBox/SmbiosPlatformDxe/SmbiosPlatformDxe.c @@ -10,17 +10,52 @@ **/ #include +#include #include #include #include #include #include #include +#include #include #include 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)) { -- 2.17.1