Richard Spiegel has uploaded this change for review. ( https://review.coreboot.org/23644
Change subject: soc/amd/common/block/pi/amd_init_late.c: Transfer memory info to cbmem ......................................................................
soc/amd/common/block/pi/amd_init_late.c: Transfer memory info to cbmem
SMBIOS structure type 17 is not being generated because memory info is not being stored to cbmem. This has to happen after AGESA AmdInitLate has run, but before the structure is released. There's a need to convert format between AGESA generated info, and what is required in cbmem.
BUG=b:65403853 TEST=build and run kahlee, verify if SMBIOS structure type 17 is being generated, and if associated strings are what should be expected.
Change-Id: I151a8f1348c9bafceb38bab1f79d3002c5f6b31b Signed-off-by: Richard Spiegel richard.spiegel@silverbackltd.com --- M src/soc/amd/common/block/pi/amd_late_init.c 1 file changed, 97 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/44/23644/1
diff --git a/src/soc/amd/common/block/pi/amd_late_init.c b/src/soc/amd/common/block/pi/amd_late_init.c index 3eb3674..499931a 100644 --- a/src/soc/amd/common/block/pi/amd_late_init.c +++ b/src/soc/amd/common/block/pi/amd_late_init.c @@ -19,16 +19,113 @@ #include <device/device.h> #include <device/pci_def.h> #include <device/pci_ops.h> +#include <cbmem.h> +#include <memory_info.h>
#include <amdblocks/agesawrapper.h> #include <amdblocks/agesawrapper_call.h>
+/* + * Description Copies a string from origin to destine. However, destine buffer + * can sometimes be smaller than the string in origin. This procedure makes + * sure that at least the last characters are copied. + * + * origin pointer to origing of string. + * destin pointer to final string. + * o_size size of origin buffer. + * d_size size of destin buffer. + */ +static void string_end(char *origin, char *destin, uint8_t o_size, + uint8_t d_size) +{ + uint8_t size, i, j; + char *optr, *dptr; + + optr = origin; + dptr = destin; + if (o_size > d_size) { + /* Find the actual string size */ + i = 0; + for (j = 0; j < o_size; j++) { + if (*optr == 0) + break; + optr++; + i++; + } + i++; /* include terminator in string size */ + if (i < d_size) { + /* actual string smaller than destin buffer */ + optr = origin; + size = o_size; + } else { + /* String equal or greater than destin buffer */ + for (j = 1; j < d_size; j++) + optr--; + size = d_size; + } + } else { + size = o_size; + } + for (i = 0; i < size; i++) + dptr[i] = optr[i]; +} + +static void transfer_memory_info(TYPE17_DMI_INFO *dmi17, + struct dimm_info *dimm) +{ + dimm->dimm_size = dmi17->ExtSize; + dimm->ddr_type = dmi17->MemoryType; + dimm->ddr_frequency = dmi17->Speed; + dimm->rank_per_dimm = dmi17->Attributes; + dimm->mod_id = dmi17->DeviceLocator[5] & 0x0f; + dimm->mod_type = dmi17->MemoryType; + dimm->bus_width = dmi17->DataWidth; + dimm->bank_locator = 0; + string_end(dmi17->SerialNumber, (char *)&dimm->serial, 9, 5); + dimm->module_part_number[0] = 0x4e; /* NA */ + dimm->module_part_number[1] = 0x41; + dimm->module_part_number[2] = 0; +} + +static void prepare_dmi_17(void) +{ + DMI_INFO *DmiTable; + TYPE17_DMI_INFO *address; + struct memory_info *mem_info; + struct dimm_info *dimm; + uint8_t i, j; /* i for channel, j for dimm */ + int dimm_cnt = 0; + + mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(struct memory_info)); + if (!mem_info) { + printk(BIOS_DEBUG, "Failed to add memory info to CBMEM.\n"); + return; + } + memset(mem_info, 0, sizeof(struct memory_info)); + + DmiTable = agesawrapper_getlateinitptr(PICK_DMI); + for (i = 0; i < MAX_CHANNELS_PER_SOCKET; i++) { + for (j = 0; j < MAX_DIMMS_PER_CHANNEL; j++) { + address = &DmiTable->T17[0][i][j]; + if (address->Handle > 0) { + dimm = &mem_info->dimm[dimm_cnt]; + dimm->channel_num = i; + dimm->dimm_num = j; + transfer_memory_info(address, dimm); + dimm_cnt++; + } + } + } + mem_info->dimm_cnt = dimm_cnt; +} + static void agesawrapper_post_device(void *unused) { if (acpi_is_wakeup_s3()) return;
do_agesawrapper(agesawrapper_amdinitlate, "amdinitlate"); + prepare_dmi_17();
if (!acpi_s3_resume_allowed()) return;