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>
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) *