All of lore.kernel.org
 help / color / mirror / Atom feed
From: Heiko Schocher <hs@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 15/16] [PATCH] mgcoge, mgsuvd: added support for the IVM EEprom.
Date: Wed, 15 Oct 2008 09:41:00 +0200	[thread overview]
Message-ID: <48F59E8C.9060101@denx.de> (raw)

The EEprom contains some Manufacturerinformation,
which are read from u-boot at boot time, and saved
in same hush shell variables.

Signed-off-by: Heiko Schocher <hs@denx.de>
---
 board/keymile/common/common.c |  287 +++++++++++++++++++++++++++++++++++++++++
 board/keymile/mgcoge/mgcoge.c |    7 +
 board/keymile/mgsuvd/mgsuvd.c |    8 +
 include/configs/mgcoge.h      |    6 +
 include/configs/mgsuvd.h      |    6 +
 5 files changed, 314 insertions(+), 0 deletions(-)

diff --git a/board/keymile/common/common.c b/board/keymile/common/common.c
index 13b80fe..ccf76ca 100644
--- a/board/keymile/common/common.c
+++ b/board/keymile/common/common.c
@@ -25,6 +25,7 @@
 #include <mpc8260.h>
 #include <ioports.h>
 #include <malloc.h>
+#include <hush.h>

 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
 #include <libfdt.h>
@@ -36,6 +37,292 @@

 extern int i2c_soft_read_pin (void);

+int ivm_calc_crc (unsigned char *buf, int len)
+{
+	const unsigned short crc_tab[16] = {
+		0x0000, 0xCC01, 0xD801, 0x1400,
+		0xF001, 0x3C00, 0x2800, 0xE401,
+		0xA001, 0x6C00, 0x7800, 0xB401,
+		0x5000, 0x9C01, 0x8801, 0x4400};
+
+	unsigned short crc     = 0;   /* final result */
+	unsigned short r1      = 0;   /* temp */
+	unsigned char  byte    = 0;   /* input buffer */
+	int	i;
+
+	/* calculate CRC from array data */
+	for (i = 0; i < len; i++) {
+		byte = buf[i];
+
+		/* lower 4 bits */
+		r1 = crc_tab[crc & 0xF];
+		crc = ((crc) >> 4) & 0x0FFF;
+		crc = crc ^ r1 ^ crc_tab[byte & 0xF];
+
+		/* upper 4 bits */
+		r1 = crc_tab[crc & 0xF];
+		crc = (crc >> 4) & 0x0FFF;
+		crc = crc ^ r1 ^ crc_tab[(byte >> 4) & 0xF];
+	}
+	return crc;
+}
+
+static int  ivm_set_value (char *name, char *value)
+{
+	char tempbuf[256];
+
+	if (value != NULL) {
+		sprintf (tempbuf, "%s=%s", name, value);
+		return set_local_var (tempbuf, 0);
+	} else {
+		unset_local_var (name);
+	}
+	return 0;
+}
+
+static int ivm_get_value (unsigned char *buf, int len, char *name, int off,
+				int check)
+{
+	unsigned short	val;
+	unsigned char	valbuf[30];
+
+	if ((buf[off + 0] != buf[off + 2]) &&
+	    (buf[off + 2] != buf[off + 4])) {
+		printf ("%s Error corrupted %s\n", __FUNCTION__, name);
+		val = -1;
+	} else {
+		val = buf[off + 0] + (buf[off + 1] << 8);
+		if ((val == 0) && (check == 1))
+			val = -1;
+	}
+	sprintf ((char *)valbuf, "%x", val);
+	ivm_set_value (name, (char *)valbuf);
+	return val;
+}
+
+#define INVENTORYBLOCKSIZE	0x100
+#define INVENTORYDATAADDRESS	0x21
+#define INVENTORYDATASIZE	(INVENTORYBLOCKSIZE - INVENTORYDATAADDRESS - 3)
+
+#define IVM_POS_SHORT_TEXT		0
+#define IVM_POS_MANU_ID			1
+#define IVM_POS_MANU_SERIAL		2
+#define IVM_POS_PART_NUMBER		3
+#define IVM_POS_BUILD_STATE		4
+#define IVM_POS_SUPPLIER_PART_NUMBER	5
+#define IVM_POS_DELIVERY_DATE		6
+#define IVM_POS_SUPPLIER_BUILD_STATE	7
+#define IVM_POS_CUSTOMER_ID		8
+#define IVM_POS_CUSTOMER_PROD_ID	9
+#define IVM_POS_HISTORY			10
+#define IVM_POS_SYMBOL_ONLY		11
+
+static char convert_char (char c)
+{
+	return (c < ' ' || c > '~') ? '.' : c;
+}
+
+static int ivm_findinventorystring (int type,
+					unsigned char* const string,
+					unsigned long maxlen,
+					unsigned char *buf)
+{
+	int xcode = 0;
+	unsigned long cr = 0;
+	unsigned long addr = INVENTORYDATAADDRESS;
+	unsigned long size = 0;
+	unsigned long nr = type;
+	int stop = 0; 	/* stop on semicolon */
+
+	memset(string, '\0', maxlen);
+	switch (type) {
+		case IVM_POS_SYMBOL_ONLY:
+			nr = 0;
+			stop= 1;
+		break;
+		default:
+			nr = type;
+			stop = 0;
+	}
+
+	/* Look for the requested number of CR. */
+	while ((cr != nr) && (addr < INVENTORYDATASIZE)) {
+		if ((buf[addr] == '\r')) {
+			cr++;
+		}
+		addr++;
+	}
+
+	/* the expected number of CR was found until the end of the IVM
+	 *  content --> fill string */
+	if (addr < INVENTORYDATASIZE) {
+		/* Copy the IVM string in the corresponding string */
+		for (; (buf[addr] != '\r')			&&
+			((buf[addr] != ';') ||  (!stop))	&&
+			(size < (maxlen - 1)			&&
+			(addr < INVENTORYDATASIZE)); addr++)
+		{
+			size += sprintf((char *)string + size, "%c",
+						convert_char (buf[addr]));
+		}
+
+		/* copy phase is done: check if everything is ok. If not,
+		 * the inventory data is most probably corrupted: tell
+		 * the world there is a problem! */
+		if (addr == INVENTORYDATASIZE) {
+			xcode = -1;
+			printf ("Error end of string not found\n");
+		} else if ((size >= (maxlen - 1)) &&
+			   (buf[addr] != '\r')) {
+			xcode = -1;
+			printf ("string too long till next CR\n");
+		}
+	} else {
+		/* some CR are missing...
+		 * the inventory data is most probably corrupted */
+		xcode = -1;
+		printf ("not enough cr found\n");
+	}
+	return xcode;
+}
+
+#define GET_STRING(name, which, len) \
+	if (ivm_findinventorystring (which, valbuf, len, buf) == 0) { \
+		ivm_set_value (name, (char *)valbuf); \
+	}
+
+static int ivm_check_crc (unsigned char *buf, int block)
+{
+	unsigned long	crc;
+	unsigned long	crceeprom;
+
+	crc = ivm_calc_crc (buf, CFG_IVM_EEPROM_PAGE_LEN - 2);
+	crceeprom = (buf[CFG_IVM_EEPROM_PAGE_LEN - 1] + \
+			buf[CFG_IVM_EEPROM_PAGE_LEN - 2] * 256);
+	if (crc != crceeprom) {
+		printf ("Error CRC Block: %d EEprom: calculated: %lx EEprom: %lx\n",
+			block, crc, crceeprom);
+		return -1;
+	}
+	return 0;
+}
+
+static int ivm_analyze_block2 (unsigned char *buf, int len)
+{
+	unsigned char	valbuf[CFG_IVM_EEPROM_PAGE_LEN];
+	unsigned long	count;
+
+	/* IVM_MacAddress */
+	sprintf ((char *)valbuf, "%02X:%02X:%02X:%02X:%02X:%02X",
+			buf[1],
+			buf[2],
+			buf[3],
+			buf[4],
+			buf[5],
+			buf[6]);	
+	ivm_set_value ("IVM_MacAddress", (char *)valbuf);
+	if (getenv ("ethaddr") == NULL)
+		setenv ((char *)"ethaddr", (char *)valbuf);
+	/* IVM_MacCount */
+	count = (buf[10] << 24) +
+		   (buf[11] << 16) +
+		   (buf[12] << 8)  +
+		    buf[13];
+	if (count == 0xffffffff)
+		count = 1;
+	sprintf ((char *)valbuf, "%lx", count);
+	ivm_set_value ("IVM_MacCount", (char *)valbuf);
+	return 0;
+}
+
+int ivm_analyze_eeprom (unsigned char *buf, int len)
+{
+	unsigned short	val;
+	unsigned char	valbuf[CFG_IVM_EEPROM_PAGE_LEN];
+	unsigned char	*tmp;
+
+	if (ivm_check_crc (buf, 0) != 0)
+		return -1;
+
+	ivm_get_value (buf, CFG_IVM_EEPROM_PAGE_LEN, "IVM_BoardId", 0, 1);
+	val = ivm_get_value (buf, CFG_IVM_EEPROM_PAGE_LEN, "IVM_HWKey", 6, 1);
+	if (val != 0xffff) {
+		sprintf ((char *)valbuf, "%x", ((val /100) % 10));
+		ivm_set_value ("IVM_HWVariant", (char *)valbuf);
+		sprintf ((char *)valbuf, "%x", (val % 100));
+		ivm_set_value ("IVM_HWVersion", (char *)valbuf);
+	}
+	ivm_get_value (buf, CFG_IVM_EEPROM_PAGE_LEN, "IVM_Functions", 12, 0);
+
+	GET_STRING("IVM_Symbol", IVM_POS_SYMBOL_ONLY, 8)
+	GET_STRING("IVM_DeviceName", IVM_POS_SHORT_TEXT, 64)
+	tmp = (unsigned char *) getenv("IVM_DeviceName");
+	if (tmp) {
+		int	len = strlen ((char *)tmp);
+		int	i = 0;
+
+		while (i < len) {
+			if (tmp[i] == ';') {
+				ivm_set_value ("IVM_ShortText", (char *)&tmp[i + 1]);
+				break;
+			}
+			i++;
+		}
+		if (i >= len)
+			ivm_set_value ("IVM_ShortText", NULL);
+	} else {
+		ivm_set_value ("IVM_ShortText", NULL);
+	}
+	GET_STRING("IVM_ManufacturerID", IVM_POS_MANU_ID, 32)
+	GET_STRING("IVM_ManufacturerSerialNumber", IVM_POS_MANU_SERIAL, 20)
+	GET_STRING("IVM_ManufacturerPartNumber", IVM_POS_PART_NUMBER, 32)
+	GET_STRING("IVM_ManufacturerBuildState", IVM_POS_BUILD_STATE, 32)
+	GET_STRING("IVM_SupplierPartNumber", IVM_POS_SUPPLIER_PART_NUMBER, 32)
+	GET_STRING("IVM_DelieveryDate", IVM_POS_DELIVERY_DATE, 32)
+	GET_STRING("IVM_SupplierBuildState", IVM_POS_SUPPLIER_BUILD_STATE, 32)
+	GET_STRING("IVM_CustomerID", IVM_POS_CUSTOMER_ID, 32)
+	GET_STRING("IVM_CustomerProductID", IVM_POS_CUSTOMER_PROD_ID, 32)
+
+	if (ivm_check_crc (&buf[CFG_IVM_EEPROM_PAGE_LEN * 2], 2) != 0)
+		return -2;
+	ivm_analyze_block2 (&buf[CFG_IVM_EEPROM_PAGE_LEN * 2], CFG_IVM_EEPROM_PAGE_LEN);
+
+	return 0;
+}
+
+int ivm_read_eeprom (void)
+{
+	I2C_MUX_DEVICE *dev = NULL;
+	uchar i2c_buffer[CFG_IVM_EEPROM_MAX_LEN];
+	uchar	*buf;
+	unsigned dev_addr = CFG_IVM_EEPROM_ADR;
+
+	/* First init the Bus, select the Bus */
+#if defined(CFG_I2C_IVM_BUS)
+	dev = i2c_mux_ident_muxstring ((uchar *)CFG_I2C_IVM_BUS);
+#else
+	buf = (unsigned char *) getenv ("EEprom_ivm");
+	if (buf != NULL)
+		dev = i2c_mux_ident_muxstring (buf);
+#endif
+	if (dev == NULL) {
+		printf ("Error couldnt add Bus for IVM\n");
+		return -1;
+	}
+	i2c_set_bus_num (dev->busid);
+
+	buf = (unsigned char *) getenv ("EEprom_ivm_addr");
+	if (buf != NULL)
+		dev_addr = simple_strtoul ((char *)buf, NULL, 16);
+
+	if (eeprom_read (dev_addr, 0, i2c_buffer, CFG_IVM_EEPROM_MAX_LEN) != 0) {
+		printf ("Error reading EEprom\n");
+		return -2;
+	}
+	
+	return ivm_analyze_eeprom (i2c_buffer, CFG_IVM_EEPROM_MAX_LEN);
+}
+
 #if defined(CFG_I2C_INIT_BOARD)
 #define DELAY_ABORT_SEQ		62
 #define DELAY_HALF_PERIOD	(500 / (CFG_I2C_SPEED / 1000))
diff --git a/board/keymile/mgcoge/mgcoge.c b/board/keymile/mgcoge/mgcoge.c
index d3e46f5..31703ab 100644
--- a/board/keymile/mgcoge/mgcoge.c
+++ b/board/keymile/mgcoge/mgcoge.c
@@ -34,6 +34,7 @@
 #include <i2c.h>
 #endif

+extern int ivm_read_eeprom (void);
 /*
  * I/O Port configuration table
  *
@@ -299,6 +300,12 @@ int board_early_init_r (void)
 	return 0;
 }

+int hush_init_var (void)
+{
+	ivm_read_eeprom ();
+	return 0;
+}
+
 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
 /*
  * update "memory" property in the blob
diff --git a/board/keymile/mgsuvd/mgsuvd.c b/board/keymile/mgsuvd/mgsuvd.c
index 62df832..265dfe8 100644
--- a/board/keymile/mgsuvd/mgsuvd.c
+++ b/board/keymile/mgsuvd/mgsuvd.c
@@ -32,6 +32,8 @@
 #include <libfdt.h>
 #endif

+extern int ivm_read_eeprom (void);
+
 DECLARE_GLOBAL_DATA_PTR;

 const uint sdram_table[] =
@@ -145,6 +147,12 @@ int board_early_init_r(void)
 	return 0;
 }

+int hush_init_var (void)
+{
+	ivm_read_eeprom ();
+	return 0;
+}
+
 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
 /*
  * update "memory" property in the blob
diff --git a/include/configs/mgcoge.h b/include/configs/mgcoge.h
index 6564c15..cdbfd67 100644
--- a/include/configs/mgcoge.h
+++ b/include/configs/mgcoge.h
@@ -134,6 +134,7 @@
 #define CFG_PROMPT_HUSH_PS2	"> "
 #define CFG_LONGHELP			/* undef to save memory	    */
 #define CFG_PROMPT		"=> "	/* Monitor Command Prompt   */
+#define CONFIG_HUSH_INIT_VAR	1
 #if defined(CONFIG_CMD_KGDB)
 #define CFG_CBSIZE		1024	/* Console I/O Buffer Size  */
 #else
@@ -212,6 +213,11 @@
 #define CFG_EEPROM_PAGE_WRITE_BITS 3
 #define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10

+/* Support the IVM EEprom */
+#define	CFG_IVM_EEPROM_ADR	0x50
+#define CFG_IVM_EEPROM_MAX_LEN	0x400
+#define CFG_IVM_EEPROM_PAGE_LEN	0x100
+
 /* I2C SYSMON (LM75, AD7414 is almost compatible)			*/
 #define CONFIG_DTT_LM75		1	/* ON Semi's LM75		*/
 #define CONFIG_DTT_SENSORS	{0}	/* Sensor addresses		*/
diff --git a/include/configs/mgsuvd.h b/include/configs/mgsuvd.h
index e2a7c07..eda71c0 100644
--- a/include/configs/mgsuvd.h
+++ b/include/configs/mgsuvd.h
@@ -129,6 +129,7 @@
 #define CFG_HUSH_PARSER		1	/* Use the HUSH parser		*/
 #ifdef	CFG_HUSH_PARSER
 #define	CFG_PROMPT_HUSH_PS2	"> "
+#define CONFIG_HUSH_INIT_VAR	1
 #endif

 #if defined(CONFIG_CMD_KGDB)
@@ -383,6 +384,11 @@
 #define CFG_EEPROM_PAGE_WRITE_BITS 3
 #define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10

+/* Support the IVM EEprom */
+#define	CFG_IVM_EEPROM_ADR	0x50
+#define CFG_IVM_EEPROM_MAX_LEN	0x400
+#define CFG_IVM_EEPROM_PAGE_LEN	0x100
+
 /* I2C SYSMON (LM75, AD7414 is almost compatible)			*/
 #define CONFIG_DTT_LM75		1	/* ON Semi's LM75		*/
 #define CONFIG_DTT_SENSORS	{0, 2, 4, 6}	/* Sensor addresses		*/
-- 
1.5.6.1

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

                 reply	other threads:[~2008-10-15  7:41 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48F59E8C.9060101@denx.de \
    --to=hs@denx.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.