summaryrefslogtreecommitdiff
path: root/board/ti/logic/prod-id/startup.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/ti/logic/prod-id/startup.c')
-rw-r--r--board/ti/logic/prod-id/startup.c124
1 files changed, 89 insertions, 35 deletions
diff --git a/board/ti/logic/prod-id/startup.c b/board/ti/logic/prod-id/startup.c
index 73dd74069d..d87836ccd1 100644
--- a/board/ti/logic/prod-id/startup.c
+++ b/board/ti/logic/prod-id/startup.c
@@ -19,7 +19,7 @@ struct __attribute__ ((packed)) id_checksums {
unsigned short data;
} ;
-int id_startup(struct id_data *data)
+static int _id_startup(struct id_data *data, int first_run)
{
int i, err;
struct id_cookie cookie;
@@ -28,68 +28,74 @@ int id_startup(struct id_data *data)
unsigned short xsum;
struct id_header hdr;
struct id_checksums xsums;
- unsigned char *mem_ptr = data->mem_ptr;
-
- /* Clear out data->mem_ptr since we want all the fetches to come
- * from the AT24 chip. Once we've validated the CRCs, restore
- * data->mem_ptr to allow id_fetch_byte to read from data->mem_ptr
- * instead of the AT24 chip. Should speed up accesses dramatically */
- data->mem_ptr = NULL;
+ unsigned char *mem_ptr;
+ unsigned char *cache_ptr;
+
+ if (first_run) {
+ cache_ptr = data->mem_ptr;
+ data->mem_ptr = NULL;
+ mem_ptr = NULL;
+ } else {
+ cache_ptr = NULL;
+ mem_ptr = data->mem_ptr;
+ }
+
+ id_dbg_printf("%s: first_run %d cach_ptr %p mem_ptr %p\n", __FUNCTION__, first_run, cache_ptr, mem_ptr);
memset(&cookie, 0, sizeof(cookie));
/* Data starts with the header, should be 'LpId' */
for (i=0; i<4; ++i) {
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
hdr.signature[i] = byte;
cookie.offset++;
if (err != ID_EOK) {
- id_printf("%s[%u]\n", __FILE__, __LINE__);
+ id_dbg_printf("%s[%u]\n", __FILE__, __LINE__);
goto err_ret;
}
if (hdr.signature[i] != header_tag[i]) {
- id_printf("%s[%u]\n", __FILE__, __LINE__);
+ id_dbg_printf("%s[%u]\n", __FILE__, __LINE__);
err = ID_ENODEV;
goto err_ret;
}
}
/* First LE 8-bit value is ID format version */
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
hdr.id_fmt_ver = byte;
cookie.offset++;
/* Second LE 8-bit value is currently not used */
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
hdr.unused0 = byte;
cookie.offset++;
/* Next LE 16-bit value is length of data */
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
hdr.data_length = byte;
cookie.offset++;
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
hdr.data_length |= byte << 8;
cookie.offset++;
/* Next LE 16-bit value is xsum of header */
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
xsums.header = byte;
cookie.offset++;
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
xsums.header |= byte << 8;
@@ -102,20 +108,20 @@ int id_startup(struct id_data *data)
crc_15_step(&xsum, p[i]);
if (xsum != xsums.header) {
- id_printf("%s[%u] xsum: 0x%04x, xsums.header: 0x%04x\n",
+ id_dbg_printf("%s[%u] xsum: 0x%04x, xsums.header: 0x%04x\n",
__FILE__, __LINE__, xsum, xsums.header);
err = -ID_EL2NSYNC;
goto err_ret;
}
/* Next LE 16-bit value is xsum of data */
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
xsums.data = byte;
cookie.offset++;
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
xsums.data |= byte << 8;
@@ -123,42 +129,57 @@ int id_startup(struct id_data *data)
/* Checksum the data (next id_len bytes), must match xsums.data */
xsum = 0;
- for (i = 0; i < hdr.data_length; ++i) {
- byte = id_fetch_byte(NULL, cookie.offset + i, &err);
- if (mem_ptr)
- mem_ptr[cookie.offset + i] = byte;
+ id_dbg_printf("%s: mem_ptr %p\n", __FUNCTION__, mem_ptr);
+ if (mem_ptr) {
+ id_fetch_bytes(mem_ptr+cookie.offset, cookie.offset, hdr.data_length, &err);
if (err != ID_EOK) {
- id_printf("%s[%u]\n", __FILE__, __LINE__);
- goto err_ret;
+ id_error("%s:%d err %d", __FUNCTION__, __LINE__, err);
+ goto hard_way;
+ }
+ for (i = 0; i < hdr.data_length; ++i) {
+ crc_15_step(&xsum, mem_ptr[cookie.offset + i]);
+ }
+ } else {
+ hard_way:
+ for (i = 0; i < hdr.data_length; ++i) {
+ byte = id_fetch_byte(cache_ptr, cookie.offset + i, &err);
+ if (mem_ptr)
+ mem_ptr[cookie.offset + i] = byte;
+ if (err != ID_EOK) {
+ id_dbg_printf("%s[%u]\n", __FILE__, __LINE__);
+ goto err_ret;
+ }
+ crc_15_step(&xsum, byte);
}
- crc_15_step(&xsum, byte);
}
if (xsum != xsums.data) {
- id_printf("%s[%u] xsum: 0x%04x, xsums.data: 0x%04x\n",
+ id_dbg_printf("%s[%u] xsum: 0x%04x, xsums.data: 0x%04x\n",
__FILE__, __LINE__, xsum, xsums.data);
err = -ID_EL2NSYNC;
goto err_ret;
}
+
/* offset is now at the first byte of the root dictionary which
contains its span */
data->root_offset = cookie.offset;
+ cookie.mem_ptr = cache_ptr;
data->root_size = extract_unsigned_pnum(&cookie, 5, &err);
if (err != ID_EOK) {
- id_printf("%s[%u]\n", __FILE__, __LINE__);
+ id_dbg_printf("%s[%u]\n", __FILE__, __LINE__);
goto err_ret;
}
- data->root_size += cookie.offset - data->root_offset;
-
-#if 0
- id_printf("Data format version: %u\n", hdr.id_fmt_ver);
-#endif
-
/* Restore data->mem_ptr to allow id_fetch_byte to read
* from the cached data instead of the AT24 chip */
data->mem_ptr = mem_ptr;
+ id_dbg_printf("%s:%d root_size (old %u) now %u + %u\n", __FUNCTION__, __LINE__,
+ data->root_size, cookie.offset, data->root_offset);
+ data->root_size += cookie.offset - data->root_offset;
+
+ id_dbg_printf("Data format version: %u\n", hdr.id_fmt_ver);
+
return ID_EOK;
err_ret:
@@ -170,6 +191,39 @@ err_ret:
return err;
}
+int id_startup(struct id_data *data, int (*setup_id_chip)(void), int (*shutdown_id_chip)(void))
+{
+ int ret, ret2;
+ void *mem_ptr = data->mem_ptr;
+
+ /* See if product ID already exists in SRAM (i.e. from x-loader) */
+ if (data->mem_ptr) {
+ ret = _id_startup(data, 1);
+ data->mem_ptr = mem_ptr;
+ if (!ret) {
+ id_printf("Found new Product ID data at %p\n", mem_ptr);
+ return ret;
+ }
+ }
+
+ /* No ID data in SRAM, setup the ID chip and read for real */
+ ret = (*setup_id_chip)();
+ if (ret) {
+ id_error("%s: setup_id_chip failed!", __FUNCTION__);
+ return ret;
+ }
+ ret = _id_startup(data, 0);
+ if (!ret)
+ id_printf("Cache new Product ID data from AT24 to %p\n", mem_ptr);
+ ret2 = (*shutdown_id_chip)();
+ if (ret2)
+ id_error("%s: shutdown_id_chip failed!", __FUNCTION__);
+
+ if (!ret && ret2)
+ ret = ret2;
+
+ return ret;
+}
/*
* Reset the cookie to cover the whole root dictionary
*/