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>
This commit is contained in:
committed by
Patrick Georgi
parent
69ff428159
commit
6724ba4f04
@ -445,8 +445,7 @@ static int get_socket_type(void)
|
|||||||
|
|
||||||
unsigned int __weak smbios_memory_error_correction_type(struct memory_info *meminfo)
|
unsigned int __weak smbios_memory_error_correction_type(struct memory_info *meminfo)
|
||||||
{
|
{
|
||||||
return meminfo->ecc_capable ?
|
return meminfo->ecc_type;
|
||||||
MEMORY_ARRAY_ECC_SINGLE_BIT : MEMORY_ARRAY_ECC_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int __weak smbios_processor_external_clock(void)
|
unsigned int __weak smbios_processor_external_clock(void)
|
||||||
|
@ -96,8 +96,11 @@ struct dimm_info {
|
|||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct memory_info {
|
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 */
|
/* Maximum capacity the DRAM controller/mainboard supports */
|
||||||
uint32_t max_capacity_mib;
|
uint32_t max_capacity_mib;
|
||||||
/* Maximum number of DIMMs the DRAM controller/mainboard supports */
|
/* Maximum number of DIMMs the DRAM controller/mainboard supports */
|
||||||
|
@ -167,9 +167,9 @@ void sdram_initialize(struct pei_data *pei_data)
|
|||||||
report_memory_config();
|
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)
|
static uint16_t nb_slots_per_channel(const uint32_t capid0_a)
|
||||||
@ -256,7 +256,7 @@ void setup_sdram_meminfo(struct pei_data *pei_data)
|
|||||||
|
|
||||||
const uint16_t channels = nb_number_of_channels(capid0_a);
|
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->max_capacity_mib = channels * nb_max_chan_capacity_mib(capid0_a);
|
||||||
mem_info->number_of_devices = channels * nb_slots_per_channel(capid0_a);
|
mem_info->number_of_devices = channels * nb_slots_per_channel(capid0_a);
|
||||||
}
|
}
|
||||||
|
@ -53,9 +53,9 @@ static void disable_channel(ramctr_timing *ctrl, int channel)
|
|||||||
memset(&ctrl->info.dimm[channel][0], 0, sizeof(ctrl->info.dimm[0]));
|
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)
|
static uint16_t nb_slots_per_channel(const uint32_t capid0_a)
|
||||||
@ -114,7 +114,7 @@ static void setup_sdram_meminfo(ramctr_timing *ctrl)
|
|||||||
|
|
||||||
const uint16_t channels = nb_number_of_channels(capid0_a);
|
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->max_capacity_mib = channels * nb_max_chan_capacity_mib(capid0_a);
|
||||||
m->number_of_devices = channels * nb_slots_per_channel(capid0_a);
|
m->number_of_devices = channels * nb_slots_per_channel(capid0_a);
|
||||||
}
|
}
|
||||||
|
@ -48,9 +48,9 @@ __weak uint32_t soc_systemagent_max_chan_capacity_mib(u8 capid0_a_ddrsz)
|
|||||||
return 32768; /* 32 GiB per channel */
|
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)
|
static size_t sa_slots_per_channel(const uint32_t capid0_a)
|
||||||
@ -73,7 +73,7 @@ static void sa_soc_systemagent_init(struct device *dev)
|
|||||||
|
|
||||||
const uint32_t capid0_a = pci_read_config32(dev, CAPID0_A);
|
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)) *
|
m->max_capacity_mib = soc_systemagent_max_chan_capacity_mib(CAPID_DDRSZ(capid0_a)) *
|
||||||
sa_number_of_channels(capid0_a);
|
sa_number_of_channels(capid0_a);
|
||||||
m->number_of_devices = sa_slots_per_channel(capid0_a) *
|
m->number_of_devices = sa_slots_per_channel(capid0_a) *
|
||||||
|
Reference in New Issue
Block a user