Patrick Georgi has submitted this change. ( https://review.coreboot.org/c/coreboot/+/50178 )
Change subject: memory_info.h: Store SMBIOS error correction type ......................................................................
memory_info.h: Store SMBIOS error correction type
There are platforms that support error correction types other than single-bit ECC. Extend meminfo to accomodate additional ECC types.
It is assumed that `struct memory_info` is packed to save space. Thus, use `uint8_t` instead of an enum type (which are usually 4 bytes wide).
Change-Id: I863f8e34c84841d931dfb8d7067af0f12a437e36 Signed-off-by: Angel Pons th3fanbus@gmail.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/50178 Reviewed-by: Nico Huber nico.h@gmx.de Reviewed-by: Paul Menzel paulepanter@users.sourceforge.net Reviewed-by: Patrick Rudolph patrick.rudolph@9elements.com Tested-by: build bot (Jenkins) no-reply@coreboot.org --- M src/arch/x86/smbios.c M src/include/memory_info.h M src/northbridge/intel/haswell/raminit.c M src/northbridge/intel/sandybridge/raminit.c M src/soc/intel/common/block/systemagent/systemagent.c 5 files changed, 15 insertions(+), 13 deletions(-)
Approvals: build bot (Jenkins): Verified Nico Huber: Looks good to me, approved Paul Menzel: Looks good to me, but someone else must approve Patrick Rudolph: Looks good to me, but someone else must approve
diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c index 4c20d52..bd7f422 100644 --- a/src/arch/x86/smbios.c +++ b/src/arch/x86/smbios.c @@ -445,8 +445,7 @@
unsigned int __weak smbios_memory_error_correction_type(struct memory_info *meminfo) { - return meminfo->ecc_capable ? - MEMORY_ARRAY_ECC_SINGLE_BIT : MEMORY_ARRAY_ECC_NONE; + return meminfo->ecc_type; }
unsigned int __weak smbios_processor_external_clock(void) diff --git a/src/include/memory_info.h b/src/include/memory_info.h index 1ba7329..fed5bbe 100644 --- a/src/include/memory_info.h +++ b/src/include/memory_info.h @@ -96,8 +96,11 @@ } __packed;
struct memory_info { - /* controller specific */ - bool ecc_capable; + /* + * SMBIOS error correction type. + * See the smbios.h smbios_memory_array_ecc enum. + */ + uint8_t ecc_type; /* Maximum capacity the DRAM controller/mainboard supports */ uint32_t max_capacity_mib; /* Maximum number of DIMMs the DRAM controller/mainboard supports */ diff --git a/src/northbridge/intel/haswell/raminit.c b/src/northbridge/intel/haswell/raminit.c index 96e6a2a..58ac8a0 100644 --- a/src/northbridge/intel/haswell/raminit.c +++ b/src/northbridge/intel/haswell/raminit.c @@ -167,9 +167,9 @@ report_memory_config(); }
-static bool nb_supports_ecc(const uint32_t capid0_a) +static uint8_t nb_get_ecc_type(const uint32_t capid0_a) { - return !(capid0_a & CAPID_ECCDIS); + return capid0_a & CAPID_ECCDIS ? MEMORY_ARRAY_ECC_NONE : MEMORY_ARRAY_ECC_SINGLE_BIT; }
static uint16_t nb_slots_per_channel(const uint32_t capid0_a) @@ -256,7 +256,7 @@
const uint16_t channels = nb_number_of_channels(capid0_a);
- mem_info->ecc_capable = nb_supports_ecc(capid0_a); + mem_info->ecc_type = nb_get_ecc_type(capid0_a); mem_info->max_capacity_mib = channels * nb_max_chan_capacity_mib(capid0_a); mem_info->number_of_devices = channels * nb_slots_per_channel(capid0_a); } diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c index 0dcd952..47cd7de 100644 --- a/src/northbridge/intel/sandybridge/raminit.c +++ b/src/northbridge/intel/sandybridge/raminit.c @@ -53,9 +53,9 @@ memset(&ctrl->info.dimm[channel][0], 0, sizeof(ctrl->info.dimm[0])); }
-static bool nb_supports_ecc(const uint32_t capid0_a) +static uint8_t nb_get_ecc_type(const uint32_t capid0_a) { - return !(capid0_a & CAPID_ECCDIS); + return capid0_a & CAPID_ECCDIS ? MEMORY_ARRAY_ECC_NONE : MEMORY_ARRAY_ECC_SINGLE_BIT; }
static uint16_t nb_slots_per_channel(const uint32_t capid0_a) @@ -114,7 +114,7 @@
const uint16_t channels = nb_number_of_channels(capid0_a);
- m->ecc_capable = nb_supports_ecc(capid0_a); + m->ecc_type = nb_get_ecc_type(capid0_a); m->max_capacity_mib = channels * nb_max_chan_capacity_mib(capid0_a); m->number_of_devices = channels * nb_slots_per_channel(capid0_a); } diff --git a/src/soc/intel/common/block/systemagent/systemagent.c b/src/soc/intel/common/block/systemagent/systemagent.c index ec26fce..7d42fe1 100644 --- a/src/soc/intel/common/block/systemagent/systemagent.c +++ b/src/soc/intel/common/block/systemagent/systemagent.c @@ -48,9 +48,9 @@ return 32768; /* 32 GiB per channel */ }
-static bool sa_supports_ecc(const uint32_t capid0_a) +static uint8_t sa_get_ecc_type(const uint32_t capid0_a) { - return !(capid0_a & CAPID_ECCDIS); + return capid0_a & CAPID_ECCDIS ? MEMORY_ARRAY_ECC_NONE : MEMORY_ARRAY_ECC_SINGLE_BIT; }
static size_t sa_slots_per_channel(const uint32_t capid0_a) @@ -73,7 +73,7 @@
const uint32_t capid0_a = pci_read_config32(dev, CAPID0_A);
- m->ecc_capable = sa_supports_ecc(capid0_a); + m->ecc_type = sa_get_ecc_type(capid0_a); m->max_capacity_mib = soc_systemagent_max_chan_capacity_mib(CAPID_DDRSZ(capid0_a)) * sa_number_of_channels(capid0_a); m->number_of_devices = sa_slots_per_channel(capid0_a) *