meta-digi/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0005-dump-v1-boot-structure...

196 lines
6.5 KiB
Diff

From: Hector Palacios <hector.palacios@digi.com>
Date: Tue, 15 Oct 2013 18:58:11 +0200
Subject: dump v1 boot structures
The kobs-ng that we received from Freescale did not support reading the
boot structures on the mx28. It could write them, but the function that
reads them was never updated to handle the updated structures used by
the mx28. This change adds basic support for reading these structures,
enough so that the dump command works.
(forward ported from kobs-ng-10.12.01 to kobs-ng-3.0.35_4.1.0)
Signed-off-by: Hector Palacios <hector.palacios@digi.com>
Reviewed-by: Robert Hodaszi <robert.hodaszi@digi.com>
---
src/main.c | 5 ++-
src/mtd.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
src/mtd.h | 1 +
3 files changed, 131 insertions(+), 4 deletions(-)
diff --git a/src/main.c b/src/main.c
index 82b6f9e..70517b0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -152,7 +152,10 @@ int dump_main(int argc, char **argv)
if (flags & F_VERBOSE)
mtd_dump(md);
- r = mtd_load_all_boot_structures(md);
+ if (ROM_Version_1 == plat_config_data->m_u32RomVer)
+ r = mtd_load_v1_boot_structures(md);
+ else
+ r = mtd_load_all_boot_structures(md);
if (r != 0) {
fprintf(stderr, "Unable to load boot structures\n");
exit(5);
diff --git a/src/mtd.c b/src/mtd.c
index f9e60a3..9ea92ad 100644
--- a/src/mtd.c
+++ b/src/mtd.c
@@ -975,6 +975,130 @@ void dump(const void *data, int size)
printf("\n");
}
+/*
+ * This function is a hack written by Digi because the original code from
+ * Freescale did not supporting reading the bootlet structures at all.
+ * This function reads the search areas for a given BCB. It will read the first
+ * search area and use it if the read succeeds. If the read fails, then it will
+ * try again with the second search area.
+ *
+ * md A pointer to the current struct mtd_data.
+ * bcb_name A pointer to a human-readable string that indicates what kind of
+ * BCB we're reading. This string will only be used in log messages.
+ * ofs1 If there is one chips, the index of the search area to read
+ * ofs2
+ * ofs_mchip If there are multiple chips, the index of the search area to read
+ * on both chips.
+ * end The number of consecutive search areas to be read.
+ * size The size of the BCB data to be read.
+ * ecc Indicates whether or not to use hardware ECC.
+ */
+int mtd_read_bcb(struct mtd_data *md, char *bcb_name,
+ loff_t ofs1, loff_t ofs2, loff_t ofs_mchip,
+ loff_t end, size_t size, int ecc)
+{
+ int chip;
+ loff_t end_index, search_area_indices[2], o;
+ int r;
+ int i;
+ int j;
+ unsigned stride_size_in_bytes;
+ unsigned search_area_size_in_strides;
+ unsigned search_area_size_in_bytes;
+
+ /* Compute some important facts about geometry */
+ if (plat_config_data->m_u32RomVer == ROM_Version_2) {
+ stride_size_in_bytes = mtd_erasesize(md);
+ search_area_size_in_strides = 4;
+ search_area_size_in_bytes = search_area_size_in_strides * stride_size_in_bytes;
+ } else {
+ stride_size_in_bytes = PAGES_PER_STRIDE * mtd_writesize(md);
+ search_area_size_in_strides = 1 << md->cfg.search_exponent;
+ search_area_size_in_bytes = search_area_size_in_strides * stride_size_in_bytes;
+ }
+
+ /*
+ * Check whether there are multiple chips and set up the two search area
+ * indices accordingly.
+ */
+ if (multichip(md))
+ search_area_indices[0] = search_area_indices[1] = ofs_mchip;
+ else {
+ search_area_indices[0] = ofs1;
+ search_area_indices[1] = ofs2;
+ }
+
+ /* Loop over search areas for this BCB. */
+ for (i = 0; i < 2; i++) {
+ /*
+ * Compute the search area index that marks the end of the
+ * writing on this chip.
+ */
+ end_index = search_area_indices[i] + end;
+
+ /* Figure out which chip we're writing */
+ chip = multichip(md) ? i : 0;
+
+ /* Loop over consecutive search areas to write. */
+ for (; search_area_indices[i] < end_index; search_area_indices[i]++) {
+ /*
+ * Compute the byte offset of the beginning of this
+ * search area
+ */
+ o = search_area_indices[i] * search_area_size_in_bytes;
+
+ /* Loop over strides in this search area. */
+ for (j = 0; j < search_area_size_in_strides; j++, o += stride_size_in_bytes) {
+ /*
+ * If we're crossing into a new block, erase it
+ * first.
+ */
+
+ /* Write the page */
+ vp(md, "mtd: Reading %s%d @%d:0x%llx(%x)\n",
+ bcb_name, j, chip, o, size);
+
+ r = mtd_read_page(md, chip, o, ecc);
+ if (r != size) {
+ fprintf(stderr, "\n%s r = 0x%8.8X, size = 0x%8.8X\n", __func__, r, size);
+ fprintf(stderr, "mtd: Failed to read %s @%d: 0x%llx (%d)\n",
+ bcb_name, chip, o, r);
+ } else
+ break;
+ }
+ }
+ }
+
+ return !(r == size);
+}
+
+/*
+ * This function is a hack by Digi, written because the original code from
+ * Freescale did not support reading the v1 boot structures at all. Do not
+ * use the results from this function for anything other than browsing the
+ * boot structures.
+ */
+int mtd_load_v1_boot_structures(struct mtd_data *md)
+{
+ int err = 0;
+
+ /* read the FCB search area */
+ err = mtd_read_bcb(md, "FCB", 0, 0, 0, 1,
+ mtd_writesize(md) + mtd_oobsize(md), false);
+ memcpy(&md->fcb, md->buf, sizeof(md->fcb));
+
+ /* read the DBBT search area */
+ err |= mtd_read_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true);
+ memcpy(&md->dbbt28, md->buf, sizeof(md->dbbt28));
+
+ if ((err != 0) ||
+ (md->dbbt28.m_u32FingerPrint != DBBT_FINGERPRINT2)) {
+ err = -1;
+ }
+
+ return err;
+}
+
void *mtd_load_boot_structure(struct mtd_data *md, int chip, loff_t *ofsp, loff_t end,
uint32_t magic1, uint32_t magic2, uint32_t magic3, int use_ecc,
int magic_offset)
@@ -1083,9 +1207,8 @@ int mtd_load_all_boot_structures(struct mtd_data *md)
md->curr_ncb = NULL;
md->ncb_version = ncb_get_version(buf, &md->curr_ncb);
- if (md->flags & F_VERBOSE)
- printf("mtd: found NCB%d candidate version %d @%d:0x%llx\n",
- i, md->ncb_version, chip, ofs);
+ vp(md, "mtd: found NCB%d candidate version %d @%d:0x%llx\n",
+ i, md->ncb_version, chip, ofs);
if (md->ncb_version >= 0)
break;
diff --git a/src/mtd.h b/src/mtd.h
index bf6e53d..18e4d70 100644
--- a/src/mtd.h
+++ b/src/mtd.h
@@ -276,6 +276,7 @@ void *mtd_load_boot_structure(struct mtd_data *md, int chip, loff_t *ofsp, loff_
uint32_t magic1, uint32_t magic2, uint32_t magic3, int use_ecc,
int magic_offset);
int mtd_load_all_boot_structures(struct mtd_data *md);
+int mtd_load_v1_boot_structures(struct mtd_data *md);
int mtd_dump_structure(struct mtd_data *md);
int v0_rom_mtd_init(struct mtd_data *md, FILE *fp);