summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaul E Rangel <rrangel@chromium.org>2018-04-11 10:58:14 -0600
committerMartin Roth <martinroth@google.com>2018-04-12 15:21:45 +0000
commit99f54a60bf27dc8f31d79a30f09f94b83856ef00 (patch)
tree9771ccf627da39acd4e7c7bc4c78b2d8c893389e
parente96df83583d94ab8cddaa9f8ed8977067336712a (diff)
include/memory_info.h: Change serial number field from 5 bytes to 4
dimm_info.serial had a strange contract. The SPD spec defines a 4 byte serial number. dimm_info.serial required a 4 character ascii string with a null terminator. This change makes the serial field so it matches the SPD spec. smbios.c will then translate the byte array into hex and set it on the smbios table. There were only two callers that set the serial number: * haswell/raminit.c: already does a memcpy(serial, spd->serial, 4), so it already matches the new contract. * amd_late_init.c: Previously copied the last 4 characters. Requires decoding the serial number into a byte array. google/cyan/spd/spd.c: This could be updated to pass the serial number, but it uses a hard coded spd.bin. Testing this on grunt, dmidecode now shows the full serial number: Serial Number: 00000000 BUG=b:65403853 TEST=tested on grunt Change-Id: Ifc58ad9ea4cdd2abe06a170a39b1f32680e7b299 Signed-off-by: Raul E Rangel <rrangel@chromium.org> Reviewed-on: https://review.coreboot.org/25343 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r--src/arch/x86/smbios.c21
-rw-r--r--src/include/memory_info.h8
-rw-r--r--src/soc/amd/common/block/pi/amd_late_init.c26
3 files changed, 24 insertions, 31 deletions
diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c
index 7e776373c4..bb4bc1abd1 100644
--- a/src/arch/x86/smbios.c
+++ b/src/arch/x86/smbios.c
@@ -254,6 +254,19 @@ static void smbios_fill_dimm_part_number(const char *part_number,
}
}
+/* Encodes the SPD serial number into hex */
+static void smbios_fill_dimm_serial_number(const struct dimm_info *dimm,
+ struct smbios_type17 *t)
+{
+ char serial[9];
+
+ snprintf(serial, sizeof(serial), "%02hhx%02hhx%02hhx%02hhx",
+ dimm->serial[0], dimm->serial[1], dimm->serial[2],
+ dimm->serial[3]);
+
+ t->serial_number = smbios_add_string(t->eos, serial);
+}
+
static int create_smbios_type17_for_dimm(struct dimm_info *dimm,
unsigned long *current, int *handle)
{
@@ -293,13 +306,7 @@ static int create_smbios_type17_for_dimm(struct dimm_info *dimm,
}
smbios_fill_dimm_manufacturer_from_id(dimm->mod_id, t);
- /* put '\0' in the end of data */
- dimm->serial[DIMM_INFO_SERIAL_SIZE - 1] = '\0';
- if (dimm->serial[0] == 0)
- t->serial_number = smbios_add_string(t->eos, "None");
- else
- t->serial_number = smbios_add_string(t->eos,
- (const char *)dimm->serial);
+ smbios_fill_dimm_serial_number(dimm, t);
snprintf(locator, sizeof(locator), "Channel-%d-DIMM-%d",
dimm->channel_num, dimm->dimm_num);
diff --git a/src/include/memory_info.h b/src/include/memory_info.h
index 4613015d75..d26d7890bd 100644
--- a/src/include/memory_info.h
+++ b/src/include/memory_info.h
@@ -19,7 +19,7 @@
#include <stdint.h>
#include <compiler.h>
-#define DIMM_INFO_SERIAL_SIZE 5
+#define DIMM_INFO_SERIAL_SIZE 4
#define DIMM_INFO_PART_NUMBER_SIZE 19
#define DIMM_INFO_TOTAL 8 /* Maximum num of dimm is 8 */
@@ -46,11 +46,7 @@ struct dimm_info {
uint8_t dimm_num;
uint8_t bank_locator;
/*
- * The last byte is '\0' for the end of string.
- *
- * Even though the SPD spec defines this field as a byte array the value
- * is passed directly to SMBIOS as a string, and thus must be printable
- * ASCII.
+ * SPD serial number.
*/
uint8_t serial[DIMM_INFO_SERIAL_SIZE];
/*
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 b0064a2f40..b410602694 100644
--- a/src/soc/amd/common/block/pi/amd_late_init.c
+++ b/src/soc/amd/common/block/pi/amd_late_init.c
@@ -22,6 +22,7 @@
#include <device/pci_ops.h>
#include <dimm_info_util.h>
#include <memory_info.h>
+#include <lib.h>
#include <amdblocks/agesawrapper.h>
#include <amdblocks/agesawrapper_call.h>
@@ -29,23 +30,10 @@
/**
* Populate dimm_info using AGESA TYPE17_DMI_INFO.
*/
-static void transfer_memory_info(const TYPE17_DMI_INFO *dmi17,
+static void transfer_memory_info(TYPE17_DMI_INFO *dmi17,
struct dimm_info *dimm)
{
- size_t len, destlen;
- uint32_t offset;
-
-
- len = strnlen(dmi17->SerialNumber, sizeof(dmi17->SerialNumber)) + 1;
- destlen = sizeof(dimm->serial);
-
- if (len > destlen) {
- offset = len - destlen;
- len = destlen;
- } else
- offset = 0;
-
- strncpy((char *)dimm->serial, &dmi17->SerialNumber[offset], len);
+ hexstrtobin(dmi17->SerialNumber, dimm->serial, sizeof(dimm->serial));
dimm->dimm_size =
smbios_memory_size_to_mib(dmi17->MemorySize, dmi17->ExtSize);
@@ -90,7 +78,7 @@ static void print_dimm_info(const struct dimm_info *dimm)
" mod_id: %hu\n"
" mod_type: 0x%hhx\n"
" bus_width: %hhu\n"
- " serial(%zu): %s\n"
+ " serial: %02hhx%02hhx%02hhx%02hhx\n"
" module_part_number(%zu): %s\n",
dimm->dimm_size,
dimm->ddr_type,
@@ -102,8 +90,10 @@ static void print_dimm_info(const struct dimm_info *dimm)
dimm->mod_id,
dimm->mod_type,
dimm->bus_width,
- strlen((char *) dimm->serial),
- (char *) dimm->serial,
+ dimm->serial[0],
+ dimm->serial[1],
+ dimm->serial[2],
+ dimm->serial[3],
strlen((char *) dimm->module_part_number),
(char *) dimm->module_part_number
);