diff options
author | Subrata Banik <subrata.banik@intel.com> | 2021-10-26 20:46:21 +0530 |
---|---|---|
committer | Subrata Banik <subrata.banik@intel.com> | 2021-11-11 09:10:10 +0000 |
commit | 6de8b424824069345714001766b389f0b992df8e (patch) | |
tree | ff3b4a308ce58213e068e7709584b3fdb04b98f5 /src/device/dram | |
parent | 9a3bde0581a574956dd57ca24683c41ac7e0edfc (diff) |
arch/x86: Refactor the SMBIOS type 17 write function
List of changes:
1. Create Module Type macros as per Memory Type
(i.e. DDR2/DDR3/DDR4/DDR5/LPDDR4/LPDDR5) and fix compilation
issue due to renaming of existing macros due to scoping the Memory
Type.
2. Use dedicated Memory Type and Module type for `Form Factor`
and `TypeDetail` conversion using `get_spd_info()` function.
3. Create a new API (convert_form_factor_to_module_type()) for
`Form Factor` to 'Module type' conversion as per `Memory Type`.
4. Add new argument as `Memory Type` to
smbios_form_factor_to_spd_mod_type() so that it can internally
call convert_form_factor_to_module_type() for `Module Type`
conversion.
5. Update `test_smbios_form_factor_to_spd_mod_type()` to
accommodate different memory types.
6. Skip fixed module type to form factor conversion using DDR2 SPD4
specification (inside dimm_info_fill()).
Refer to datasheet SPD4.1.2.M-1 for LPDDRx and SPD4.1.2.L-3 for DDRx.
BUG=b:194659789
TEST=Refer to dmidecode -t 17 output as below:
Without this code change:
Handle 0x0012, DMI type 17, 40 bytes
Memory Device
Array Handle: 0x000A
Error Information Handle: Not Provided
Total Width: 16 bits
Data Width: 16 bits
Size: 2048 MB
Form Factor: Unknown
....
With this code change:
Handle 0x0012, DMI type 17, 40 bytes
Memory Device
Array Handle: 0x000A
Error Information Handle: Not Provided
Total Width: 16 bits
Data Width: 16 bits
Size: 2048 MB
Form Factor: Row Of Chips
....
Change-Id: Ia337ac8f50b61ae78d86a07c7a86aa9c248bad50
Signed-off-by: Subrata Banik <subrata.banik@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/56628
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Jakub Czapiga <jacz@semihalf.com>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Diffstat (limited to 'src/device/dram')
-rw-r--r-- | src/device/dram/ddr3.c | 10 | ||||
-rw-r--r-- | src/device/dram/ddr4.c | 8 | ||||
-rw-r--r-- | src/device/dram/spd.c | 217 |
3 files changed, 226 insertions, 9 deletions
diff --git a/src/device/dram/ddr3.c b/src/device/dram/ddr3.c index 0a32d02de9..b99730d45b 100644 --- a/src/device/dram/ddr3.c +++ b/src/device/dram/ddr3.c @@ -545,19 +545,19 @@ enum cb_err spd_add_smbios17(const u8 channel, const u8 slot, switch (info->dimm_type) { case SPD_DDR3_DIMM_TYPE_SO_DIMM: - dimm->mod_type = SPD_SODIMM; + dimm->mod_type = DDR3_SPD_SODIMM; break; case SPD_DDR3_DIMM_TYPE_72B_SO_CDIMM: - dimm->mod_type = SPD_72B_SO_CDIMM; + dimm->mod_type = DDR3_SPD_72B_SO_CDIMM; break; case SPD_DDR3_DIMM_TYPE_72B_SO_RDIMM: - dimm->mod_type = SPD_72B_SO_RDIMM; + dimm->mod_type = DDR3_SPD_72B_SO_RDIMM; break; case SPD_DDR3_DIMM_TYPE_UDIMM: - dimm->mod_type = SPD_UDIMM; + dimm->mod_type = DDR3_SPD_UDIMM; break; case SPD_DDR3_DIMM_TYPE_RDIMM: - dimm->mod_type = SPD_RDIMM; + dimm->mod_type = DDR3_SPD_RDIMM; break; case SPD_DDR3_DIMM_TYPE_UNDEFINED: default: diff --git a/src/device/dram/ddr4.c b/src/device/dram/ddr4.c index c5a8d13f53..eea5f0af56 100644 --- a/src/device/dram/ddr4.c +++ b/src/device/dram/ddr4.c @@ -299,16 +299,16 @@ enum cb_err spd_add_smbios17_ddr4(const u8 channel, const u8 slot, const u16 sel switch (info->dimm_type) { case SPD_DDR4_DIMM_TYPE_SO_DIMM: - dimm->mod_type = SPD_SODIMM; + dimm->mod_type = DDR4_SPD_SODIMM; break; case SPD_DDR4_DIMM_TYPE_72B_SO_RDIMM: - dimm->mod_type = SPD_72B_SO_RDIMM; + dimm->mod_type = DDR4_SPD_72B_SO_RDIMM; break; case SPD_DDR4_DIMM_TYPE_UDIMM: - dimm->mod_type = SPD_UDIMM; + dimm->mod_type = DDR4_SPD_UDIMM; break; case SPD_DDR4_DIMM_TYPE_RDIMM: - dimm->mod_type = SPD_RDIMM; + dimm->mod_type = DDR4_SPD_RDIMM; break; default: dimm->mod_type = SPD_UNDEFINED; diff --git a/src/device/dram/spd.c b/src/device/dram/spd.c index 0b2dd49eee..11808e2cf3 100644 --- a/src/device/dram/spd.c +++ b/src/device/dram/spd.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include <device/dram/spd.h> +#include <spd.h> const char *spd_manufacturer_name(const uint16_t mod_id) { @@ -38,3 +39,219 @@ const char *spd_manufacturer_name(const uint16_t mod_id) return NULL; } } + +static void convert_default_module_type_to_spd_info(struct spd_info *info) +{ + info->form_factor = MEMORY_FORMFACTOR_UNKNOWN; + info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN; +} + +static void convert_ddr2_module_type_to_spd_info(enum ddr2_module_type module_type, + struct spd_info *info) +{ + switch (module_type) { + case DDR2_SPD_RDIMM: + case DDR2_SPD_MINI_RDIMM: + info->form_factor = MEMORY_FORMFACTOR_RIMM; + info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED; + break; + case DDR2_SPD_UDIMM: + case DDR2_SPD_MINI_UDIMM: + info->form_factor = MEMORY_FORMFACTOR_DIMM; + info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED; + break; + case DDR2_SPD_MICRO_DIMM: + info->form_factor = MEMORY_FORMFACTOR_DIMM; + info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN; + break; + case DDR2_SPD_SODIMM: + info->form_factor = MEMORY_FORMFACTOR_SODIMM; + info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN; + break; + default: + convert_default_module_type_to_spd_info(info); + break; + } +} + +static void convert_ddr3_module_type_to_spd_info(enum ddr3_module_type module_type, + struct spd_info *info) +{ + switch (module_type) { + case DDR3_SPD_RDIMM: + case DDR3_SPD_MINI_RDIMM: + info->form_factor = MEMORY_FORMFACTOR_RIMM; + info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED; + break; + case DDR3_SPD_UDIMM: + case DDR3_SPD_MINI_UDIMM: + info->form_factor = MEMORY_FORMFACTOR_DIMM; + info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED; + break; + case DDR3_SPD_MICRO_DIMM: + info->form_factor = MEMORY_FORMFACTOR_DIMM; + info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN; + break; + case DDR3_SPD_SODIMM: + case DDR3_SPD_72B_SO_UDIMM: + info->form_factor = MEMORY_FORMFACTOR_SODIMM; + info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN; + break; + default: + convert_default_module_type_to_spd_info(info); + break; + } +} + +static void convert_ddr4_module_type_to_spd_info(enum ddr4_module_type module_type, + struct spd_info *info) +{ + switch (module_type) { + case DDR4_SPD_RDIMM: + case DDR4_SPD_MINI_RDIMM: + info->form_factor = MEMORY_FORMFACTOR_RIMM; + info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED; + break; + case DDR4_SPD_UDIMM: + case DDR4_SPD_MINI_UDIMM: + info->form_factor = MEMORY_FORMFACTOR_DIMM; + info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED; + break; + case DDR4_SPD_SODIMM: + case DDR4_SPD_72B_SO_UDIMM: + info->form_factor = MEMORY_FORMFACTOR_SODIMM; + info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN; + break; + default: + convert_default_module_type_to_spd_info(info); + break; + } +} + +static void convert_ddr5_module_type_to_spd_info(enum ddr5_module_type module_type, + struct spd_info *info) +{ + switch (module_type) { + case DDR5_SPD_RDIMM: + case DDR5_SPD_MINI_RDIMM: + info->form_factor = MEMORY_FORMFACTOR_RIMM; + info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED; + break; + case DDR5_SPD_UDIMM: + case DDR5_SPD_MINI_UDIMM: + info->form_factor = MEMORY_FORMFACTOR_DIMM; + info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED; + break; + case DDR5_SPD_SODIMM: + case DDR5_SPD_72B_SO_UDIMM: + info->form_factor = MEMORY_FORMFACTOR_SODIMM; + info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN; + break; + case DDR5_SPD_2DPC: + info->form_factor = MEMORY_FORMFACTOR_PROPRIETARY_CARD; + info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN; + break; + default: + convert_default_module_type_to_spd_info(info); + break; + } +} + +static void convert_lpx_module_type_to_spd_info(enum lpx_module_type module_type, + struct spd_info *info) +{ + switch (module_type) { + case LPX_SPD_NONDIMM: + info->form_factor = MEMORY_FORMFACTOR_ROC; + info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN; + break; + default: + convert_default_module_type_to_spd_info(info); + break; + } +} + +void get_spd_info(smbios_memory_type memory_type, uint8_t module_type, struct spd_info *info) +{ + switch (memory_type) { + case MEMORY_TYPE_DDR2: + convert_ddr2_module_type_to_spd_info(module_type, info); + break; + case MEMORY_TYPE_DDR3: + convert_ddr3_module_type_to_spd_info(module_type, info); + break; + case MEMORY_TYPE_DDR4: + convert_ddr4_module_type_to_spd_info(module_type, info); + break; + case MEMORY_TYPE_DDR5: + convert_ddr5_module_type_to_spd_info(module_type, info); + break; + case MEMORY_TYPE_LPDDR3: + case MEMORY_TYPE_LPDDR4: + case MEMORY_TYPE_LPDDR5: + convert_lpx_module_type_to_spd_info(module_type, info); + break; + default: + convert_default_module_type_to_spd_info(info); + break; + } +} + +static uint8_t convert_default_form_factor_to_module_type(void) +{ + return SPD_UNDEFINED; +} + +static uint8_t convert_ddrx_form_factor_to_module_type(smbios_memory_type memory_type, + smbios_memory_form_factor form_factor) +{ + uint8_t module_type; + + switch (form_factor) { + case MEMORY_FORMFACTOR_DIMM: + return DDR2_SPD_UDIMM; + case MEMORY_FORMFACTOR_RIMM: + return DDR2_SPD_RDIMM; + case MEMORY_FORMFACTOR_SODIMM: + module_type = (memory_type == MEMORY_TYPE_DDR2) ? DDR2_SPD_SODIMM + : DDR3_SPD_SODIMM; + return module_type; + default: + return convert_default_form_factor_to_module_type(); + } +} + +static uint8_t convert_lpx_form_factor_to_module_type(smbios_memory_form_factor form_factor) +{ + switch (form_factor) { + case MEMORY_FORMFACTOR_ROC: + return LPX_SPD_NONDIMM; + default: + return convert_default_form_factor_to_module_type(); + } +} + +uint8_t convert_form_factor_to_module_type(smbios_memory_type memory_type, + smbios_memory_form_factor form_factor) +{ + uint8_t module_type; + + switch (memory_type) { + case MEMORY_TYPE_DDR2: + case MEMORY_TYPE_DDR3: + case MEMORY_TYPE_DDR4: + case MEMORY_TYPE_DDR5: + module_type = convert_ddrx_form_factor_to_module_type(memory_type, form_factor); + break; + case MEMORY_TYPE_LPDDR3: + case MEMORY_TYPE_LPDDR4: + case MEMORY_TYPE_LPDDR5: + module_type = convert_lpx_form_factor_to_module_type(form_factor); + break; + default: + module_type = convert_default_form_factor_to_module_type(); + break; + } + + return module_type; +} |