Richard Spiegel has uploaded this change for review. ( https://review.coreboot.org/23825
Change subject: soc/amd/common/block/pi/amd_late_init.c: Fix part number ......................................................................
soc/amd/common/block/pi/amd_late_init.c: Fix part number
Some DIMMs have invalid strings when it comes to part number (bytes 0x149-0x15c). It should be ASCIIZ with unused space filled with white spaces (ASCII 0x20). Byte 20 should be 0, all others should be ASCII. Create a test that detects invalid strings and replace them with "NA", while truncating valid strings to 18 characters (dimm->module_part_number has 19 bytes and byte 19 has to be 0).
BUG=b:73122207 TEST=Build, boot and record serial output for kahlee while injecting different strings to dmi17->PartNumber. Use code to examine SMBIOS, while testing different valid and invalid strings, testing corner cases. Remove string injection before committing.
Change-Id: I427262873f9ec80f459245e5f509e28a68de3074 Signed-off-by: Richard Spiegel richard.spiegel@silverbackltd.com --- M src/soc/amd/common/block/pi/amd_late_init.c 1 file changed, 35 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/25/23825/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 68f15ed..66684af 100644 --- a/src/soc/amd/common/block/pi/amd_late_init.c +++ b/src/soc/amd/common/block/pi/amd_late_init.c @@ -25,6 +25,35 @@ #include <amdblocks/agesawrapper.h> #include <amdblocks/agesawrapper_call.h>
+static int validate_part_number(char *buffer) +{ + int valid, space, i; + char ch; + + valid = 0; /* valid until proven invalid */ + space = 0; + for (i = 0; i < 19; i++) { + ch = buffer[i]; + if (ch < 0x20) + valid = -1; + if (ch == 0x20) + space++; + if (ch > 0x20) { + if (space > 1) + valid = -1; + else + space = 0; + } + } + /* + * dimm->module_part_number is 19 bytes, with last byte 0. + * dmi17->PartNumber is 21 bytes with last byte 0. So truncate + * string just in case it's valid. + */ + buffer[18] = 0; + return valid; +} + static void transfer_memory_info(TYPE17_DMI_INFO *dmi17, struct dimm_info *dimm) { size_t len, destlen; @@ -49,8 +78,12 @@ dimm->bus_width = dmi17->DataWidth; dimm->mod_id = dmi17->ManufacturerIdCode; dimm->bank_locator = 0; - strncpy((char *)dimm->module_part_number, "NA", - sizeof(dimm->module_part_number)); + if (validate_part_number(dmi17->PartNumber)) + strncpy((char *)dimm->module_part_number, "NA", + sizeof(dimm->module_part_number)); + else + strncpy((char *)dimm->module_part_number, dmi17->PartNumber, + sizeof(dimm->module_part_number)); }
static void prepare_dmi_17(void *unused)