meta-digi-arm: add patches for kobs-ng version 3.0.35-4.1.0

This set of patches are forward port of patches for old version
10.12.01 and to make it work with v3.10 kernel.

Signed-off-by: Hector Palacios <hector.palacios@digi.com>
Reviewed-by: Javier Viguera <javier.viguera@digi.com>

https://jira.digi.com/browse/DEL-797
This commit is contained in:
Hector Palacios 2013-10-18 13:12:05 +02:00
parent bbebf6acf8
commit 03848a9fd3
5 changed files with 951 additions and 0 deletions

View File

@ -0,0 +1,170 @@
From: Hector Palacios <hector.palacios@digi.com>
Date: Fri, 18 Oct 2013 10:10:37 +0200
Subject: cleanup ROM version detection code and add cpx2 support
The original code flow was difficult to understand.
Now there is a main if-elseif to check for 'Hardware' or 'Revision'
strings from cpuinfo.
On the 'Hardware' section we first check if it is a CPX2, or else we
will parse the MX-- number to get the CPU model.
On the 'Revision' section we base on the revision number to get the
CPU model or, if unset (like when Linux is booted directly), we'll
rely on the previous hw_system_rev calculated before.
Signed-off-by: Hector Palacios <hector.palacios@digi.com>
Reviewed-by: Robert Hodaszi <robert.hodaszi@digi.com>
---
src/plat_boot_config.c | 119 ++++++++++++++++++++++++++-----------------------
1 file changed, 63 insertions(+), 56 deletions(-)
diff --git a/src/plat_boot_config.c b/src/plat_boot_config.c
index 76e65c8..e3bf242 100644
--- a/src/plat_boot_config.c
+++ b/src/plat_boot_config.c
@@ -109,10 +109,11 @@ int discover_boot_rom_version(void)
{
FILE *cpuinfo;
char line_buffer[100];
- static char *banner = "Revision";
+ static char *banner_rev = "Revision";
static char *banner_hw = "Hardware";
+ static char *banner_digi_x2 = "Hardware\t: Digi ConnectPort X2";
char *rev;
- int system_rev, hw_system_rev = 0;
+ int system_rev = 0, hw_system_rev = 0;
cpuinfo = fopen("/proc/cpuinfo", "r");
if (!cpuinfo) {
@@ -125,15 +126,20 @@ int discover_boot_rom_version(void)
if (!fgets(line_buffer, sizeof(line_buffer), cpuinfo))
break;
- /* Check if it's revision line */
- if (strncmp(line_buffer, banner, strlen(banner))) {
- /*
- * Why use the `Hardware` to parse the system type ?
- * [1] If boot linux kernel directly from SD card not by uboot,
- * the `Revision` will be zero.
- * [2] The code does not change the old logic.
- */
- if (!strncmp(line_buffer, banner_hw, strlen(banner))) {
+ /* Check if it's hardware line... */
+ /*
+ * Why use the `Hardware` to parse the system type ?
+ * [1] If boot linux kernel directly from SD card not by uboot,
+ * the `Revision` will be zero.
+ * [2] The code does not change the old logic.
+ */
+ if (!strncmp(line_buffer, banner_hw, strlen(banner_hw))) {
+ if (!strncmp(line_buffer, banner_digi_x2,
+ strlen(banner_digi_x2))) {
+ /* The cpx2 is an i.MX28 */
+ hw_system_rev = MX28;
+ }
+ else {
rev = strstr(line_buffer, "MX");
if (rev) {
char tmp[3] = {};
@@ -143,56 +149,57 @@ int discover_boot_rom_version(void)
hw_system_rev = strtoul(tmp, NULL, 16);
}
}
- continue;
}
+ /* ... or Revision line */
+ else if (!strncmp(line_buffer, banner_rev, strlen(banner_rev))) {
+ rev = index(line_buffer, ':');
+ if (rev != NULL) {
+ rev++;
+ system_rev = strtoul(rev, NULL, 16);
+ system_rev = mxc_cpu(system_rev);
+ if (!system_rev)
+ system_rev = hw_system_rev;
+
+ switch (system_rev) {
+ case MX23:
+ plat_config_data = &mx23_boot_config;
+ break;
+
+ case MX28:
+ plat_config_data = &mx28_boot_config;
+ break;
+
+ case MX53:
+ if (mxc_cpu_is_rev(system_rev, CHIP_REV_2_0) < 0)
+ plat_config_data = &mx53to1_boot_config;
+ else
+ plat_config_data = &mx53to2_boot_config;
+ break;
+
+ case MX50:
+ plat_config_data = &mx50_boot_config;
+ break;
+
+ case MX6:
+ case MX6Q:
+ case MX6DL:
+ plat_config_data = &mx6q_boot_config;
+ break;
+
+ default:
+ fprintf(stderr, "Couldn't find Boot ROM version\n");
+ break;
+ }
- rev = index(line_buffer, ':');
- if (rev != NULL) {
- rev++;
- system_rev = strtoul(rev, NULL, 16);
- system_rev = mxc_cpu(system_rev);
- if (!system_rev)
- system_rev = hw_system_rev;
-
- switch (system_rev) {
- case MX23:
- plat_config_data = &mx23_boot_config;
- break;
-
- case MX28:
- plat_config_data = &mx28_boot_config;
- break;
-
- case MX53:
- if (mxc_cpu_is_rev(system_rev, CHIP_REV_2_0) < 0)
- plat_config_data = &mx53to1_boot_config;
- else
- plat_config_data = &mx53to2_boot_config;
- break;
-
- case MX50:
- plat_config_data = &mx50_boot_config;
- break;
-
- case MX6:
- case MX6Q:
- case MX6DL:
- plat_config_data = &mx6q_boot_config;
- break;
-
- default:
- fprintf(stderr, "Couldn't find Boot ROM version\n");
- break;
- }
-
- fclose(cpuinfo);
- if (plat_config_data) {
- plat_config_data->m_u32Arm_type = system_rev;
- return 0;
+ break; /* quit for loop */
}
- return -1;
}
}
+
fclose(cpuinfo);
+ if (plat_config_data) {
+ plat_config_data->m_u32Arm_type = system_rev;
+ return 0;
+ }
return -1;
}

View File

@ -0,0 +1,128 @@
From: Hector Palacios <hector.palacios@digi.com>
Date: Fri, 18 Oct 2013 10:11:29 +0200
Subject: discover boot ROM version from FDT if available
New kernels don't get CPU information from U-Boot ATAGS and
so the /proc/cpuinfo file does not have the Hardware/Revision
lines filled in.
This patch gets the CPU model from the device tree information
at /proc/device-tree/compatible.
For backwards compatibility, if the CPU model cannot be retrieved
from this file, we try to get it from /proc/cpuinfo.
Signed-off-by: Hector Palacios <hector.palacios@digi.com>
Reviewed-by: Robert Hodaszi <robert.hodaszi@digi.com>
---
src/plat_boot_config.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 94 insertions(+), 1 deletion(-)
diff --git a/src/plat_boot_config.c b/src/plat_boot_config.c
index e3bf242..af7e03a 100644
--- a/src/plat_boot_config.c
+++ b/src/plat_boot_config.c
@@ -105,7 +105,91 @@ static platform_config mx6q_boot_config = {
.rom_mtd_commit_structures = v4_rom_mtd_commit_structures,
};
-int discover_boot_rom_version(void)
+#define MAX_STRLEN 256
+int get_rom_version_from_fdt(void)
+{
+ FILE *fd;
+ char line_buffer[MAX_STRLEN];
+ char *p;
+ static char *compatible = "fsl,imx";
+ char *rev;
+ int system_rev;
+
+ fd = fopen("/proc/device-tree/compatible", "r");
+ if (!fd)
+ return -1;
+
+ p = &line_buffer[0];
+ if (fgets(p, MAX_STRLEN, fd)) {
+ /*
+ * The compatible string can contain more than one string.
+ * Each string value is separated from the next one by a
+ * NULL char. We must check all values one by one until
+ * we find two consecutive NULL chars.
+ */
+ while (p[0] != 0) {
+ if (!strncmp(p, compatible, strlen(compatible))) {
+ rev = p + strlen(compatible);
+ /*
+ * check if it's an imx6 CPU series, or
+ * a parsable number.
+ */
+ if (!strncmp(rev, "6q", 2))
+ system_rev = MX6Q;
+ else if (!strncmp(rev, "6d", 2))
+ system_rev = MX6DL;
+ else if (!strncmp(rev, "6s", 2))
+ system_rev = MX6;
+ else
+ system_rev = strtoul(rev, NULL, 16);
+
+ switch (system_rev) {
+ case MX23:
+ plat_config_data = &mx23_boot_config;
+ break;
+
+ case MX28:
+ plat_config_data = &mx28_boot_config;
+ break;
+
+ case MX53:
+ /*
+ * TODO: check CPU revision
+ * Consider it is a TO2 for the
+ * moment
+ */
+ plat_config_data = &mx53to2_boot_config;
+ break;
+
+ case MX50:
+ plat_config_data = &mx50_boot_config;
+ break;
+
+ case MX6:
+ case MX6Q:
+ case MX6DL:
+ plat_config_data = &mx6q_boot_config;
+ break;
+
+ default:
+ break;
+ }
+
+ if (plat_config_data) {
+ plat_config_data->m_u32Arm_type = system_rev;
+ return 0;
+ }
+ }
+ /* Move string pointer to next possible value */
+ p += strlen(p) + 1;
+ }
+ }
+
+ fclose(fd);
+ return -1;
+}
+
+int get_rom_version_from_cpuinfo(void)
{
FILE *cpuinfo;
char line_buffer[100];
@@ -203,3 +287,12 @@ int discover_boot_rom_version(void)
}
return -1;
}
+
+int discover_boot_rom_version(void)
+{
+ /* First, try to get ROM version from FDT */
+ if (get_rom_version_from_fdt())
+ return (get_rom_version_from_cpuinfo());
+
+ return 0;
+}

View File

@ -0,0 +1,195 @@
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);

View File

@ -0,0 +1,454 @@
From: Hector Palacios <hector.palacios@digi.com>
Date: Wed, 16 Oct 2013 10:30:14 +0200
Subject: added option to verify data written to flash
This patch adds a -c (check) option to the update command.
This option will read back the data written to the flash and
compare to the original contents in RAM, to verify the write
operation was successful.
Signed-off-by: Hector Palacios <hector.palacios@digi.com>
Reviewed-by: Robert Hodaszi <robert.hodaszi@digi.com>
---
src/main.c | 22 ++++++--
src/mtd.c | 138 +++++++++++++++++++++++++++++++++++++++----------
src/mtd.h | 10 ++--
src/plat_boot_config.h | 2 +-
4 files changed, 136 insertions(+), 36 deletions(-)
diff --git a/src/main.c b/src/main.c
index 70517b0..8774045 100644
--- a/src/main.c
+++ b/src/main.c
@@ -82,10 +82,12 @@ void usage(void)
" -x .................................... Add 1k-padding in the head\n"
" -n .................................... Dry run (don't commit to flash)\n"
" -w .................................... Commit to flash\n"
+ " -c .................................... Check committed data in flash\n"
"\n"
" update [-v] [KEY] [KOBS] [-0|1] <file> .. Update a single bootstream\n"
" -v .................................... Verbose mode\n"
" -0|1 .................................. Update specified bootstream #\n"
+ " -c .................................... Check committed data in flash\n"
"\n"
" extract [-v] [KEY] [KOBS] [-0|1] <file> . Extract a bootstream from flash\n"
" -v .................................... Verbose mode\n"
@@ -390,7 +392,8 @@ int extract_main(int argc, char **argv)
return 0;
}
-static int perform_bootstream_update(struct mtd_data *md, FILE *infp, int image_mask)
+static int perform_bootstream_update(struct mtd_data *md, FILE *infp,
+ int image_mask, int check)
{
int i, r;
unsigned int size, start, avail, end, update;
@@ -435,7 +438,8 @@ static int perform_bootstream_update(struct mtd_data *md, FILE *infp, int image_
update |= UPDATE_BS(i);
}
- r = plat_config_data->rom_mtd_commit_structures(md, infp, UPDATE_LDLB | update);
+ r = plat_config_data->rom_mtd_commit_structures(md, infp,
+ UPDATE_LDLB | update, check);
if (r < 0) {
fprintf(stderr, "FAILED to commit structures\n");
return -1;
@@ -457,6 +461,7 @@ int update_main(int argc, char **argv)
char ascii[20 * 2 + 1];
int device_key;
uint8_t *keyp;
+ int check;
memset(key, 0, sizeof(key));
device_key = 0;
@@ -473,6 +478,7 @@ int update_main(int argc, char **argv)
image_mask = 0; /* no image */
flags = 0;
j = 0;
+ check = 0;
for (i = 1; i < argc; i++) {
if (argv[i][0] != '-') {
@@ -500,6 +506,9 @@ int update_main(int argc, char **argv)
exit(5);
}
break;
+ case 'c':
+ check = 1;
+ break;
case 'v':
flags |= F_VERBOSE;
break;
@@ -545,7 +554,7 @@ int update_main(int argc, char **argv)
if (flags & F_VERBOSE)
mtd_dump(md);
- r = perform_bootstream_update(md, infp, image_mask);
+ r = perform_bootstream_update(md, infp, image_mask, check);
if (r != 0) {
fprintf(stderr, "Unable to perform bootstream update\n");
usage();
@@ -597,6 +606,7 @@ int init_main(int argc, char **argv)
FILE *infp;
loff_t ofs;
int dryrun;
+ int check;
int padding = 0;
struct mtd_config cfg;
uint8_t key[16];
@@ -619,6 +629,7 @@ int init_main(int argc, char **argv)
image = 0; /* first image */
flags = 0;
dryrun = 0;
+ check = 0;
j = 0;
for (i = 1; i < argc; i++) {
@@ -640,6 +651,9 @@ int init_main(int argc, char **argv)
case 'w':
dryrun = 0;
break;
+ case 'c':
+ check = 1;
+ break;
case 'n':
dryrun = 1;
break;
@@ -738,7 +752,7 @@ int init_main(int argc, char **argv)
mtd_dump_structure(md);
if (!dryrun) {
- r = plat_config_data->rom_mtd_commit_structures(md, infp, UPDATE_ALL);
+ r = plat_config_data->rom_mtd_commit_structures(md, infp, UPDATE_ALL, check);
if (r < 0) {
fprintf(stderr, "FAILED to commit structures\n");
exit(5);
diff --git a/src/mtd.c b/src/mtd.c
index 9ea92ad..77ba307 100644
--- a/src/mtd.c
+++ b/src/mtd.c
@@ -2344,7 +2344,7 @@ int v4_rom_mtd_init(struct mtd_data *md, FILE *fp)
int mtd_commit_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)
+ loff_t end, size_t size, int ecc, int verify)
{
int chip;
loff_t end_index, search_area_indices[2], o;
@@ -2355,6 +2355,13 @@ int mtd_commit_bcb(struct mtd_data *md, char *bcb_name,
unsigned search_area_size_in_strides;
unsigned search_area_size_in_bytes;
unsigned count;
+ char *readbuf = NULL;
+
+ if (verify) {
+ readbuf = malloc(mtd_writesize(md));
+ if (NULL == readbuf)
+ return -1;
+ }
vp(md, "-------------- Start to write the [ %s ] -----\n", bcb_name);
//----------------------------------------------------------------------
@@ -2457,6 +2464,20 @@ int mtd_commit_bcb(struct mtd_data *md, char *bcb_name,
err ++;
}
+ if (verify) {
+ //------------------------------------------------------
+ // Verify the written data
+ //------------------------------------------------------
+ r = pread(md->part[chip].fd, readbuf, mtd_writesize(md), o);
+ if (r != mtd_writesize(md)) {
+ fprintf(stderr, "mtd: Failed to read @0x%llx (%d)\n", o, r);
+ goto err_free;
+ }
+ if (memcmp(md->buf, readbuf, mtd_writesize(md))) {
+ fprintf(stderr, "mtd: Verification error @0x%llx\n", o);
+ goto err_free;
+ }
+ }
}
}
@@ -2466,16 +2487,31 @@ int mtd_commit_bcb(struct mtd_data *md, char *bcb_name,
if (md->flags & F_VERBOSE)
printf("%s(%s): status %d\n\n", __func__, bcb_name, err);
- return err;
+err_free:
+ if (verify)
+ free(readbuf);
+ if (err) {
+ fprintf(stderr, "mtd: %d errors\n", err);
+ return -1;
+ }
+ else
+ return 0;
}
-int write_boot_stream(struct mtd_data *md, FILE *fp)
+int write_boot_stream(struct mtd_data *md, FILE *fp, int verify)
{
int startpage, start, size;
loff_t ofs, end;
- int i, r, chunk;
+ int i, r = 0, chunk;
int chip = 0;
struct fcb_block *fcb = &md->fcb.FCB_Block;
+ char *readbuf = NULL;
+
+ if (verify) {
+ readbuf = malloc(mtd_writesize(md));
+ if (NULL == readbuf)
+ return -1;
+ }
vp(md, "---------- Start to write the [ %s ]----\n", (char*)md->private);
for (i = 0; i < 2; i++) {
@@ -2530,7 +2566,7 @@ int write_boot_stream(struct mtd_data *md, FILE *fp)
r = fread(md->buf, 1, chunk, fp);
if (r < 0) {
fprintf(stderr, "mtd: Failed %d (fread %d)\n", r, chunk);
- return -1;
+ goto err_free;
}
if (r < chunk) {
memset(md->buf + r, 0, chunk - r);
@@ -2539,10 +2575,30 @@ int write_boot_stream(struct mtd_data *md, FILE *fp)
/* write page */
r = mtd_write_page(md, chip, ofs, 1);
- if (r != mtd_writesize(md))
+ if (r != mtd_writesize(md)) {
fprintf(stderr, "mtd: Failed to write BS @0x%llx (%d)\n",
ofs, r);
+ r = -1;
+ goto err_free;
+ }
+ if (verify) {
+ //------------------------------------------------------
+ // Verify the written data
+ //------------------------------------------------------
+ r = pread(md->part[chip].fd, readbuf,
+ mtd_writesize(md), ofs);
+ if (r != mtd_writesize(md)) {
+ fprintf(stderr, "mtd: Failed to read BS @0x%llx (%d)\n", ofs, r);
+ r = -1;
+ goto err_free;
+ }
+ if (memcmp(md->buf, readbuf, mtd_writesize(md))) {
+ fprintf(stderr, "mtd: Verification error @0x%llx\n", ofs);
+ r = -1;
+ goto err_free;
+ }
+ }
ofs += mtd_writesize(md);
size -= chunk;
}
@@ -2555,19 +2611,26 @@ int write_boot_stream(struct mtd_data *md, FILE *fp)
*/
memset(md->buf, 0, mtd_writesize(md));
r = mtd_write_page(md, chip, ofs, 1);
- if (r != mtd_writesize(md))
+ if (r != mtd_writesize(md)) {
fprintf(stderr, "Failed to write safe page\n");
+ r = -1;
+ goto err_free;
+ }
vp(md, "mtd: We write one page for save guard. *\n");
-
if (ofs >= end) {
fprintf(stderr, "mtd: Failed to write BS#%d\n", i);
- return -1;
+ r = -1;
+ goto err_free;
}
}
- return 0;
+
+err_free:
+ if (verify)
+ free(readbuf);
+ return r;
}
-int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
+int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify)
{
int startpage, start, size;
unsigned int search_area_sz, stride;
@@ -2666,7 +2729,9 @@ int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
if (r < 0)
return r;
- mtd_commit_bcb(md, "NCB", 0, 1, 0, 1, size, false);
+ r = mtd_commit_bcb(md, "NCB", 0, 1, 0, 1, size, false, verify);
+ if (r < 0)
+ return r;
}
if (flags & UPDATE_LDLB) {
@@ -2675,7 +2740,10 @@ int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
memset(md->buf, 0, mtd_writesize(md));
memcpy(md->buf, md->curr_ldlb, sizeof(*md->curr_ldlb));
- mtd_commit_bcb(md, "LDLB", 2, 3, 1, 1, mtd_writesize(md), true);
+ r = mtd_commit_bcb(md, "LDLB", 2, 3, 1, 1, mtd_writesize(md), true,
+ verify);
+ if (r < 0)
+ return r;
}
if (flags & UPDATE_DBBT) {
@@ -2684,7 +2752,11 @@ int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
memset(md->buf, 0, mtd_writesize(md));
memcpy(md->buf, md->curr_dbbt, sizeof(*md->curr_dbbt));
- mtd_commit_bcb(md, "DBBT", 4, 5, 2, 1, mtd_writesize(md), true);
+ r = mtd_commit_bcb(md, "DBBT", 4, 5, 2, 1, mtd_writesize(md), true,
+ verify);
+ if (r < 0)
+ return r;
+
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
if (md->flags & F_MULTICHIP) {
@@ -2766,7 +2838,7 @@ static void write_dbbt(struct mtd_data *md, int dbbt_num)
}
}
-int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
+int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify)
{
int size ,r;
@@ -2779,8 +2851,11 @@ int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
size = mtd_writesize(md) + mtd_oobsize(md);
r = fcb_encrypt(&md->fcb, md->buf, size, 1);
if (r < 0)
- return r;
- mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, size, false);
+ return -1;
+
+ r = mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, size, false, verify);
+ if (r < 0)
+ return -1;
//----------------------------------------------------------------------
// Write the DBBT search area.
@@ -2788,14 +2863,17 @@ int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
memset(md->buf, 0, mtd_writesize(md));
memcpy(md->buf, &(md->dbbt28), sizeof(md->dbbt28));
dbbt_checksum(md, &md->dbbt28);
- mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true);
+ r = mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true,
+ verify);
+ if (r < 0)
+ return -1;
write_dbbt(md, 1); /* only write the DBBT for nand0 */
/* write the boot image. */
- return write_boot_stream(md, fp);
+ return write_boot_stream(md, fp, verify);
}
-int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
+int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify)
{
int startpage, start, size;
unsigned int search_area_size_in_bytes, stride_size_in_bytes;
@@ -2832,7 +2910,9 @@ int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
memset(md->buf, 0, mtd_writesize(md));
memcpy(md->buf, &(md->fcb), sizeof(md->fcb));
- mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, mtd_writesize(md), true);
+ r = mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, mtd_writesize(md), true, verify);
+ if (r < 0)
+ return -1;
//----------------------------------------------------------------------
// Write the DBBT search area.
@@ -2841,7 +2921,9 @@ int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
memset(md->buf, 0, mtd_writesize(md));
memcpy(md->buf, &(md->dbbt28), sizeof(md->dbbt28));
- mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true);
+ r = mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true, verify);
+ if (r < 0)
+ return -1;
//----------------------------------------------------------------------
// Write the DBBT table area.
@@ -2985,7 +3067,7 @@ int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
return 0;
}
-int v4_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
+int v4_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify)
{
int size, i, r, chip = 0;
loff_t ofs;
@@ -2997,12 +3079,16 @@ int v4_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
r = fcb_encrypt(&md->fcb, md->buf, size, 1);
if (r < 0)
return r;
- mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, size, false);
+ r = mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, size, false, verify);
+ if (r < 0)
+ return r;
/* [2] Write the DBBT search area. */
memset(md->buf, 0, mtd_writesize(md));
memcpy(md->buf, &(md->dbbt50), sizeof(md->dbbt50));
- mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true);
+ r = mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true, verify);
+ if (r < 0)
+ return -1;
/* Write the DBBT table area. */
memset(md->buf, 0, mtd_writesize(md));
@@ -3023,7 +3109,7 @@ int v4_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
}
/* [3] Write the two boot streams. */
- return write_boot_stream(md, fp);
+ return write_boot_stream(md, fp, verify);
}
#undef ARG
diff --git a/src/mtd.h b/src/mtd.h
index 18e4d70..699e505 100644
--- a/src/mtd.h
+++ b/src/mtd.h
@@ -295,11 +295,11 @@ int mtd_markbad(struct mtd_data *md, int chip, loff_t ofs);
#define UPDATE_BS(x) (0x08 << ((x) & 1))
#define UPDATE_ALL (UPDATE_NCB | UPDATE_LDLB | UPDATE_DBBT | UPDATE_BS0 | UPDATE_BS1)
-int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags);
-int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags);
-int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags);
-int v3_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags);
-int v4_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags);
+int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify);
+int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify);
+int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify);
+int v3_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify);
+int v4_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify);
int mtd_set_ecc_mode(struct mtd_data *md, int ecc);
diff --git a/src/plat_boot_config.h b/src/plat_boot_config.h
index 8242ede..a3c03a7 100644
--- a/src/plat_boot_config.h
+++ b/src/plat_boot_config.h
@@ -55,7 +55,7 @@ typedef struct _platform_config_t {
uint32_t m_u32Arm_type;
uint32_t m_u32DBBT_FingerPrint;
int (* rom_mtd_init)(struct mtd_data *md, FILE *fp);
- int (* rom_mtd_commit_structures)(struct mtd_data *md, FILE *fp, int flags);
+ int (* rom_mtd_commit_structures)(struct mtd_data *md, FILE *fp, int flags, int verify);
} platform_config;
extern platform_config *plat_config_data;

View File

@ -13,6 +13,10 @@ SRC_URI = " \
${DIGI_MIRROR}/${PN}-${PV}.tar.gz \ ${DIGI_MIRROR}/${PN}-${PV}.tar.gz \
file://0001-makefile.am.patch \ file://0001-makefile.am.patch \
file://0002-fix-mtd-defines.patch \ file://0002-fix-mtd-defines.patch \
file://0003-cleanup-ROM-version-detection-code-and-add-cpx2-supp.patch \
file://0004-discover-boot-ROM-version-from-FDT-if-available.patch \
file://0005-dump-v1-boot-structures.patch \
file://0006-added-option-to-verify-data-written-to-flash.patch \
" "
SRC_URI[md5sum] = "2a0e55b5063605b2664fd67c95a6c686" SRC_URI[md5sum] = "2a0e55b5063605b2664fd67c95a6c686"