[coreboot-gerrit] New patch to review for coreboot: 2450436 lenovo/x201 & x230: Read serial number, UUID and P/N from EEPROM.

Vladimir Serbinenko (phcoder@gmail.com) gerrit at coreboot.org
Tue Jan 21 15:10:00 CET 2014


Vladimir Serbinenko (phcoder at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4770

-gerrit

commit 245043688edfab74c74462edb30975953e216376
Author: Vladimir Serbinenko <phcoder at gmail.com>
Date:   Tue Jan 21 11:19:45 2014 +0100

    lenovo/x201 & x230: Read serial number, UUID and P/N from EEPROM.
    
    This info is stored on AT24RF08 chip acessible through SMBUS.
    
    Change-Id: I40b052f14fc733d4cc9b0c08bedc5597d8b474cb
    Signed-off-by: Vladimir Serbinenko <phcoder at gmail.com>
---
 src/mainboard/lenovo/x201/mainboard.c | 79 +++++++++++++++++++++++++++++++++++
 src/mainboard/lenovo/x230/mainboard.c | 79 +++++++++++++++++++++++++++++++++++
 2 files changed, 158 insertions(+)

diff --git a/src/mainboard/lenovo/x201/mainboard.c b/src/mainboard/lenovo/x201/mainboard.c
index 6321777..8a2d926 100644
--- a/src/mainboard/lenovo/x201/mainboard.c
+++ b/src/mainboard/lenovo/x201/mainboard.c
@@ -34,6 +34,7 @@
 #include <ec/lenovo/h8/h8.h>
 #include <northbridge/intel/nehalem/nehalem.h>
 #include <southbridge/intel/bd82x6x/pch.h>
+#include <southbridge/intel/bd82x6x/smbus.h>
 
 #include <pc80/mc146818rtc.h>
 #include "dock.h"
@@ -89,9 +90,87 @@ static int int15_handler(void)
 
 const char *smbios_mainboard_version(void)
 {
+	/* Is available from SMBUS as well but why read it if we know
+	   what we'll find?  */
 	return "Lenovo X201";
 }
 
+static void smbus_read_string(u8 addr, u8 start, u8 len, char *result)
+{
+	int i;
+
+	for (i = 0; i < len; i++) {
+		int t = do_smbus_read_byte(SMBUS_IO_BASE, addr, start + i);
+		if (t < 0x20 || t > 0x7f) {
+			memcpy(result, "*INVALID*", sizeof ("*INVALID*"));
+			return;
+		}
+		result[i] = t;
+	}
+}
+
+const char *smbios_mainboard_serial_number(void)
+{
+	static char result[12];
+	static int already_read;
+
+	if (already_read)
+		return result;
+
+	memset(result, 0, sizeof (result));
+
+	smbus_read_string(0x54, 0x2e, 7, result);
+	already_read = 1;
+	return result;
+}
+
+const char *smbios_mainboard_product_name(void)
+{
+	static char result[12];
+	static int already_read;
+
+	if (already_read)
+		return result;
+	memset (result, 0, sizeof (result));
+
+	smbus_read_string(0x54, 0x27, 7, result);
+
+	already_read = 1;
+	return result;
+}
+
+void smbios_mainboard_set_uuid(u8 *uuid)
+{
+	static char result[16];
+	unsigned i;
+	static int already_read;
+	const int remap[16] = {
+		/* UUID byteswap.  */
+		3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15
+	};
+
+
+	if (already_read) {
+		memcpy (uuid, result, 16);
+		return;
+	}
+
+	memset (result, 0, sizeof (result));
+
+	for (i = 0; i < 16; i++) {
+		int t = do_smbus_read_byte(SMBUS_IO_BASE, 0x56, 0x12 + i);
+		if (t < 0) {
+			memset (result, 0, sizeof (result));
+			break;
+		}
+		result[remap[i]] = t;
+	}
+
+	already_read = 1;
+
+	memcpy (uuid, result, 16);
+}
+
 static void mainboard_enable(device_t dev)
 {
 	device_t dev0;
diff --git a/src/mainboard/lenovo/x230/mainboard.c b/src/mainboard/lenovo/x230/mainboard.c
index 91965b6..22afce4 100644
--- a/src/mainboard/lenovo/x230/mainboard.c
+++ b/src/mainboard/lenovo/x230/mainboard.c
@@ -34,6 +34,7 @@
 #include <boot/coreboot_tables.h>
 #include "hda_verb.h"
 #include <southbridge/intel/bd82x6x/pch.h>
+#include <southbridge/intel/bd82x6x/smbus.h>
 #include <smbios.h>
 #include <device/pci.h>
 #include <cbfs.h>
@@ -132,9 +133,87 @@ static int int15_handler(void)
 
 const char *smbios_mainboard_version(void)
 {
+	/* Is available from SMBUS as well but why read it if we know
+	   what we'll find?  */
 	return "ThinkPad X230";
 }
 
+static void smbus_read_string(u8 addr, u8 start, u8 len, char *result)
+{
+	int i;
+
+	for (i = 0; i < len; i++) {
+		int t = do_smbus_read_byte(SMBUS_IO_BASE, addr, start + i);
+		if (t < 0x20 || t > 0x7f) {
+			memcpy(result, "*INVALID*", sizeof ("*INVALID*"));
+			return;
+		}
+		result[i] = t;
+	}
+}
+
+const char *smbios_mainboard_serial_number(void)
+{
+	static char result[12];
+	static int already_read;
+
+	if (already_read)
+		return result;
+
+	memset(result, 0, sizeof (result));
+
+	smbus_read_string(0x54, 0x2e, 7, result);
+	already_read = 1;
+	return result;
+}
+
+const char *smbios_mainboard_product_name(void)
+{
+	static char result[12];
+	static int already_read;
+
+	if (already_read)
+		return result;
+	memset (result, 0, sizeof (result));
+
+	smbus_read_string(0x54, 0x27, 7, result);
+
+	already_read = 1;
+	return result;
+}
+
+void smbios_mainboard_set_uuid(u8 *uuid)
+{
+	static char result[16];
+	unsigned i;
+	static int already_read;
+	const int remap[16] = {
+		/* UUID byteswap.  */
+		3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15
+	};
+
+
+	if (already_read) {
+		memcpy (uuid, result, 16);
+		return;
+	}
+
+	memset (result, 0, sizeof (result));
+
+	for (i = 0; i < 16; i++) {
+		int t = do_smbus_read_byte(SMBUS_IO_BASE, 0x56, 0x12 + i);
+		if (t < 0) {
+			memset (result, 0, sizeof (result));
+			break;
+		}
+		result[remap[i]] = t;
+	}
+
+	already_read = 1;
+
+	memcpy (uuid, result, 16);
+}
+
 /* Audio Setup */
 
 extern const u32 *cim_verb_data;



More information about the coreboot-gerrit mailing list