From 03848a9fd3fdbf17c7ae493e2d4851eac46605ac Mon Sep 17 00:00:00 2001 From: Hector Palacios Date: Fri, 18 Oct 2013 13:12:05 +0200 Subject: [PATCH] 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 Reviewed-by: Javier Viguera https://jira.digi.com/browse/DEL-797 --- ...ion-detection-code-and-add-cpx2-supp.patch | 170 +++++++ ...ot-ROM-version-from-FDT-if-available.patch | 128 +++++ .../0005-dump-v1-boot-structures.patch | 195 ++++++++ ...tion-to-verify-data-written-to-flash.patch | 454 ++++++++++++++++++ .../kobs-ng/kobs-ng_3.0.35-4.1.0.bb | 4 + 5 files changed, 951 insertions(+) create mode 100644 meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0003-cleanup-ROM-version-detection-code-and-add-cpx2-supp.patch create mode 100644 meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0004-discover-boot-ROM-version-from-FDT-if-available.patch create mode 100644 meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0005-dump-v1-boot-structures.patch create mode 100644 meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0006-added-option-to-verify-data-written-to-flash.patch diff --git a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0003-cleanup-ROM-version-detection-code-and-add-cpx2-supp.patch b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0003-cleanup-ROM-version-detection-code-and-add-cpx2-supp.patch new file mode 100644 index 000000000..d70fe428f --- /dev/null +++ b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0003-cleanup-ROM-version-detection-code-and-add-cpx2-supp.patch @@ -0,0 +1,170 @@ +From: Hector Palacios +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 +Reviewed-by: Robert Hodaszi +--- + 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; + } diff --git a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0004-discover-boot-ROM-version-from-FDT-if-available.patch b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0004-discover-boot-ROM-version-from-FDT-if-available.patch new file mode 100644 index 000000000..ce5954700 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0004-discover-boot-ROM-version-from-FDT-if-available.patch @@ -0,0 +1,128 @@ +From: Hector Palacios +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 +Reviewed-by: Robert Hodaszi +--- + 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; ++} diff --git a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0005-dump-v1-boot-structures.patch b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0005-dump-v1-boot-structures.patch new file mode 100644 index 000000000..62c786998 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0005-dump-v1-boot-structures.patch @@ -0,0 +1,195 @@ +From: Hector Palacios +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 +Reviewed-by: Robert Hodaszi +--- + 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); diff --git a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0006-added-option-to-verify-data-written-to-flash.patch b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0006-added-option-to-verify-data-written-to-flash.patch new file mode 100644 index 000000000..945f30ecf --- /dev/null +++ b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0006-added-option-to-verify-data-written-to-flash.patch @@ -0,0 +1,454 @@ +From: Hector Palacios +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 +Reviewed-by: Robert Hodaszi +--- + 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] .. 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] . 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; diff --git a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng_3.0.35-4.1.0.bb b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng_3.0.35-4.1.0.bb index 75cd5290f..a2a4af1ab 100644 --- a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng_3.0.35-4.1.0.bb +++ b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng_3.0.35-4.1.0.bb @@ -13,6 +13,10 @@ SRC_URI = " \ ${DIGI_MIRROR}/${PN}-${PV}.tar.gz \ file://0001-makefile.am.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"