nb/amd/mct_ddr3: Report correct DIMM size in SMBIOS structure

The existing DIMM size calculation for DDR3 was incorrect.  Use
the recommended calculation from the DDR3 SPD specification.

Change-Id: Id6a39e2b38b5d9f483341ebef8f2960ae52bda6c
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
Reviewed-on: https://review.coreboot.org/14739
Tested-by: build bot (Jenkins)
Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com>
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
Timothy Pearson 2016-05-07 17:26:40 -05:00
parent 251ce85b58
commit 84da72c988
3 changed files with 22 additions and 3 deletions

View File

@ -1199,12 +1199,27 @@ static int amdfam10_get_smbios_data17(int* count, int handle, int parent_handle,
* Primary data width * 2^(#rows) * 2^(#cols) * #banks * #ranks * Primary data width * 2^(#rows) * 2^(#cols) * #banks * #ranks
*/ */
uint8_t width, rows, cols, banks, ranks; uint8_t width, rows, cols, banks, ranks;
width = 8; uint64_t chip_size;
uint32_t chip_width;
rows = mem_info->dct_stat[node].DimmRows[slot]; rows = mem_info->dct_stat[node].DimmRows[slot];
cols = mem_info->dct_stat[node].DimmCols[slot]; cols = mem_info->dct_stat[node].DimmCols[slot];
ranks = mem_info->dct_stat[node].DimmRanks[slot]; ranks = mem_info->dct_stat[node].DimmRanks[slot];
banks = mem_info->dct_stat[node].DimmBanks[slot]; banks = mem_info->dct_stat[node].DimmBanks[slot];
uint64_t dimm_size_bytes = width * (1ULL << rows) * (1ULL << cols) * banks * ranks; #if IS_ENABLED(CONFIG_DIMM_DDR3)
chip_size = mem_info->dct_stat[node].DimmChipSize[slot];
chip_width = mem_info->dct_stat[node].DimmChipWidth[slot];
#else
chip_size = 0;
chip_width = 0;
#endif
uint64_t dimm_size_bytes;
if (IS_ENABLED(CONFIG_DIMM_DDR3)) {
width = mem_info->dct_stat[node].DimmWidth[slot];
dimm_size_bytes = ((width / chip_width) * chip_size * ranks) / 8;
} else {
width = 8;
dimm_size_bytes = width * (1ULL << rows) * (1ULL << cols) * banks * ranks;
}
memset(t, 0, sizeof(struct smbios_type17)); memset(t, 0, sizeof(struct smbios_type17));
t->type = SMBIOS_MEMORY_DEVICE; t->type = SMBIOS_MEMORY_DEVICE;
@ -1213,7 +1228,7 @@ static int amdfam10_get_smbios_data17(int* count, int handle, int parent_handle,
t->length = sizeof(struct smbios_type17) - 2; t->length = sizeof(struct smbios_type17) - 2;
if (dimm_size_bytes > 0x800000000) { if (dimm_size_bytes > 0x800000000) {
t->size = 0x7FFF; t->size = 0x7FFF;
t->extended_size = dimm_size_bytes; t->extended_size = dimm_size_bytes >> 16;
} else { } else {
t->size = dimm_size_bytes / (1024*1024); t->size = dimm_size_bytes / (1024*1024);
t->size &= (~0x8000); /* size specified in megabytes */ t->size &= (~0x8000); /* size specified in megabytes */

View File

@ -5706,6 +5706,8 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat,
pDCTstat->DimmRanks[i] = ((pDCTstat->spd_data.spd_bytes[i][SPD_Organization] & 0x38) >> 3) + 1; pDCTstat->DimmRanks[i] = ((pDCTstat->spd_data.spd_bytes[i][SPD_Organization] & 0x38) >> 3) + 1;
pDCTstat->DimmBanks[i] = 1ULL << (((pDCTstat->spd_data.spd_bytes[i][SPD_Density] & 0x70) >> 4) + 3); pDCTstat->DimmBanks[i] = 1ULL << (((pDCTstat->spd_data.spd_bytes[i][SPD_Density] & 0x70) >> 4) + 3);
pDCTstat->DimmWidth[i] = 1ULL << ((pDCTstat->spd_data.spd_bytes[i][SPD_BusWidth] & 0x7) + 3); pDCTstat->DimmWidth[i] = 1ULL << ((pDCTstat->spd_data.spd_bytes[i][SPD_BusWidth] & 0x7) + 3);
pDCTstat->DimmChipSize[i] = 1ULL << ((pDCTstat->spd_data.spd_bytes[i][SPD_Density] & 0xf) + 28);
pDCTstat->DimmChipWidth[i] = 1ULL << ((pDCTstat->spd_data.spd_bytes[i][SPD_Organization] & 0x7) + 2);
} }
/* Check supported voltage(s) */ /* Check supported voltage(s) */
pDCTstat->DimmSupportedVoltages[i] = pDCTstat->spd_data.spd_bytes[i][SPD_Voltage] & 0x7; pDCTstat->DimmSupportedVoltages[i] = pDCTstat->spd_data.spd_bytes[i][SPD_Voltage] & 0x7;

View File

@ -621,6 +621,8 @@ struct DCTStatStruc { /* A per Node structure*/
uint8_t DimmRanks[MAX_DIMMS_SUPPORTED]; uint8_t DimmRanks[MAX_DIMMS_SUPPORTED];
uint8_t DimmBanks[MAX_DIMMS_SUPPORTED]; uint8_t DimmBanks[MAX_DIMMS_SUPPORTED];
uint8_t DimmWidth[MAX_DIMMS_SUPPORTED]; uint8_t DimmWidth[MAX_DIMMS_SUPPORTED];
uint64_t DimmChipSize[MAX_DIMMS_SUPPORTED];
uint32_t DimmChipWidth[MAX_DIMMS_SUPPORTED];
uint8_t DimmRegistered[MAX_DIMMS_SUPPORTED]; uint8_t DimmRegistered[MAX_DIMMS_SUPPORTED];
uint8_t DimmLoadReduced[MAX_DIMMS_SUPPORTED]; uint8_t DimmLoadReduced[MAX_DIMMS_SUPPORTED];