From fa06a6df65b7bf77c112aa3f83b3b62bf7790712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 29 Mar 2023 21:25:52 +0200 Subject: [PATCH 1/8] arm: mvebu: spl: Do not hardcode SATA block size to 512 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Find SATA block device by blk_get_devnum_by_uclass_id() function and read from it the real block size of the SATA disk. Signed-off-by: Pali Rohár --- arch/arm/mach-mvebu/spl.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c index 6b8c72a71da..379daa88a4d 100644 --- a/arch/arm/mach-mvebu/spl.c +++ b/arch/arm/mach-mvebu/spl.c @@ -208,10 +208,15 @@ int spl_parse_board_header(struct spl_image_info *spl_image, /* * For SATA srcaddr is specified in number of sectors. - * This expects that sector size is 512 bytes. + * Retrieve block size of the first SCSI device (same + * code used by the spl_sata_load_image_raw() function) + * or fallback to default sector size of 512 bytes. */ - if (IS_ENABLED(CONFIG_SPL_SATA) && mhdr->blockid == IBR_HDR_SATA_ID) - spl_image->offset *= 512; + if (IS_ENABLED(CONFIG_SPL_SATA) && mhdr->blockid == IBR_HDR_SATA_ID) { + struct blk_desc *blk_dev = blk_get_devnum_by_uclass_id(UCLASS_SCSI, 0); + unsigned long blksz = blk_dev ? blk_dev->blksz : 512; + spl_image->offset *= blksz; + } if (spl_image->offset % 4 != 0) { printf("ERROR: Wrong srcaddr (0x%08x) in kwbimage\n", From 4548b37a29035c1d946e86513b70029cb4dc08b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 11 Apr 2023 20:35:51 +0200 Subject: [PATCH 2/8] cmd: mvebu/bubt: a38x: Do not hardcode SATA block size to 512 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Find SATA block device by blk_get_devnum_by_uclass_id() function and read from it the real block size of the SATA disk. In case of error, fallback back to 512 bytes. Signed-off-by: Pali Rohár --- cmd/mvebu/bubt.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cmd/mvebu/bubt.c b/cmd/mvebu/bubt.c index 37ff9c45522..ca24a5c1c4b 100644 --- a/cmd/mvebu/bubt.c +++ b/cmd/mvebu/bubt.c @@ -924,8 +924,11 @@ static int check_image_header(void) offset = le32_to_cpu(hdr->srcaddr); size = le32_to_cpu(hdr->blocksize); - if (hdr->blockid == 0x78) /* SATA id */ - offset *= 512; + if (hdr->blockid == 0x78) { /* SATA id */ + struct blk_desc *blk_dev = IS_ENABLED(BLK) ? blk_get_devnum_by_uclass_id(UCLASS_SCSI, 0) : NULL; + unsigned long blksz = blk_dev ? blk_dev->blksz : 512; + offset *= blksz; + } if (offset % 4 != 0 || size < 4 || size % 4 != 0) { printf("Error: Bad A38x image blocksize.\n"); From 2972d7d62f8f177bf2186c7a38bdae53dff99a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 29 Mar 2023 21:25:54 +0200 Subject: [PATCH 3/8] tools: imagetool: Extend print_header() by params argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows image type print_header() callback to access struct image_tool_params *params. Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- tools/aisimage.c | 2 +- tools/atmelimage.c | 2 +- tools/default_image.c | 7 ++++++- tools/fit_common.c | 5 +++++ tools/fit_common.h | 2 ++ tools/fit_image.c | 2 +- tools/gpimage.c | 2 +- tools/imagetool.c | 4 ++-- tools/imagetool.h | 2 +- tools/imx8image.c | 2 +- tools/imx8mimage.c | 2 +- tools/imximage.c | 2 +- tools/kwbimage.c | 2 +- tools/lpc32xximage.c | 2 +- tools/mkimage.c | 2 +- tools/mtk_image.c | 2 +- tools/mxsimage.c | 2 +- tools/omapimage.c | 2 +- tools/pblimage.c | 2 +- tools/rkcommon.c | 2 +- tools/rkcommon.h | 2 +- tools/socfpgaimage.c | 2 +- tools/stm32image.c | 2 +- tools/sunxi_egon.c | 2 +- tools/sunxi_toc0.c | 2 +- tools/ublimage.c | 2 +- tools/vybridimage.c | 2 +- tools/zynqimage.c | 2 +- tools/zynqmpimage.c | 2 +- tools/zynqmpimage.h | 2 +- 30 files changed, 41 insertions(+), 29 deletions(-) diff --git a/tools/aisimage.c b/tools/aisimage.c index b8b3ee32070..c5b33b559b0 100644 --- a/tools/aisimage.c +++ b/tools/aisimage.c @@ -113,7 +113,7 @@ static int get_ais_table_id(uint32_t *ptr) return -1; } -static void aisimage_print_header(const void *hdr) +static void aisimage_print_header(const void *hdr, struct image_tool_params *params) { struct ais_header *ais_hdr = (struct ais_header *)hdr; uint32_t *ptr; diff --git a/tools/atmelimage.c b/tools/atmelimage.c index 7b3b243d58b..6a2d9d8feab 100644 --- a/tools/atmelimage.c +++ b/tools/atmelimage.c @@ -182,7 +182,7 @@ static void atmel_print_pmecc_header(const uint32_t word) printf("\t\t====================\n"); } -static void atmel_print_header(const void *ptr) +static void atmel_print_header(const void *ptr, struct image_tool_params *params) { uint32_t *ints = (uint32_t *)ptr; size_t pos; diff --git a/tools/default_image.c b/tools/default_image.c index dc429ce9e46..0e49ab33015 100644 --- a/tools/default_image.c +++ b/tools/default_image.c @@ -41,6 +41,11 @@ static int image_check_params(struct image_tool_params *params) (params->lflag && (params->dflag || params->fflag))); } +static void image_print_header(const void *ptr, struct image_tool_params *params) +{ + image_print_contents(ptr); +} + static int image_verify_header(unsigned char *ptr, int image_size, struct image_tool_params *params) { @@ -201,7 +206,7 @@ U_BOOT_IMAGE_TYPE( (void *)&header, image_check_params, image_verify_header, - image_print_contents, + image_print_header, image_set_header, image_extract_subimage, image_check_image_types, diff --git a/tools/fit_common.c b/tools/fit_common.c index 01649760ac0..2d417d47198 100644 --- a/tools/fit_common.c +++ b/tools/fit_common.c @@ -23,6 +23,11 @@ #include #include +void fit_print_header(const void *fit, struct image_tool_params *params) +{ + fit_print_contents(fit); +} + int fit_verify_header(unsigned char *ptr, int image_size, struct image_tool_params *params) { diff --git a/tools/fit_common.h b/tools/fit_common.h index 920a16acfdb..2da4b9422d4 100644 --- a/tools/fit_common.h +++ b/tools/fit_common.h @@ -10,6 +10,8 @@ #include "mkimage.h" #include +void fit_print_header(const void *fit, struct image_tool_params *params); + /** * Verify the format of FIT header pointed to by ptr * diff --git a/tools/fit_image.c b/tools/fit_image.c index 8763a36d01e..9fe69ea0d9f 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -944,7 +944,7 @@ U_BOOT_IMAGE_TYPE( (void *)&header, fit_check_params, fit_verify_header, - fit_print_contents, + fit_print_header, NULL, fit_extract_contents, fit_check_image_types, diff --git a/tools/gpimage.c b/tools/gpimage.c index 27de4cfaed7..d2bc79d46b9 100644 --- a/tools/gpimage.c +++ b/tools/gpimage.c @@ -41,7 +41,7 @@ static int gpimage_verify_header(unsigned char *ptr, int image_size, return gph_verify_header(gph, 1); } -static void gpimage_print_header(const void *ptr) +static void gpimage_print_header(const void *ptr, struct image_tool_params *params) { const struct gp_header *gph = (struct gp_header *)ptr; diff --git a/tools/imagetool.c b/tools/imagetool.c index 87eee4ad04e..b293211cf88 100644 --- a/tools/imagetool.c +++ b/tools/imagetool.c @@ -66,7 +66,7 @@ int imagetool_verify_print_header( */ if ((*curr)->print_header) { if (!params->quiet) - (*curr)->print_header(ptr); + (*curr)->print_header(ptr, params); } else { fprintf(stderr, "%s: print_header undefined for %s\n", @@ -103,7 +103,7 @@ static int imagetool_verify_print_header_by_type( */ if (tparams->print_header) { if (!params->quiet) - tparams->print_header(ptr); + tparams->print_header(ptr, params); } else { fprintf(stderr, "%s: print_header undefined for %s\n", diff --git a/tools/imagetool.h b/tools/imagetool.h index fdceea46c09..a766aa2ae91 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -132,7 +132,7 @@ struct image_type_params { */ int (*verify_header) (unsigned char *, int, struct image_tool_params *); /* Prints image information abstracting from image header */ - void (*print_header) (const void *); + void (*print_header) (const void *, struct image_tool_params *); /* * The header or image contents need to be set as per image type to * be generated using this callback function. diff --git a/tools/imx8image.c b/tools/imx8image.c index c25ea84e25c..76d0cd62dcc 100644 --- a/tools/imx8image.c +++ b/tools/imx8image.c @@ -30,7 +30,7 @@ static void imx8image_set_header(void *ptr, struct stat *sbuf, int ifd, { } -static void imx8image_print_header(const void *ptr) +static void imx8image_print_header(const void *ptr, struct image_tool_params *params) { } diff --git a/tools/imx8mimage.c b/tools/imx8mimage.c index 3ca79d865aa..21075c23799 100644 --- a/tools/imx8mimage.c +++ b/tools/imx8mimage.c @@ -60,7 +60,7 @@ static void imx8mimage_set_header(void *ptr, struct stat *sbuf, int ifd, { } -static void imx8mimage_print_header(const void *ptr) +static void imx8mimage_print_header(const void *ptr, struct image_tool_params *params) { } diff --git a/tools/imximage.c b/tools/imximage.c index 354ee34c14a..b3da1f244cd 100644 --- a/tools/imximage.c +++ b/tools/imximage.c @@ -813,7 +813,7 @@ static int imximage_verify_header(unsigned char *ptr, int image_size, return 0; } -static void imximage_print_header(const void *ptr) +static void imximage_print_header(const void *ptr, struct image_tool_params *params) { struct imx_header *imx_hdr = (struct imx_header *) ptr; uint32_t version = detect_imximage_version(imx_hdr); diff --git a/tools/kwbimage.c b/tools/kwbimage.c index 177084adf82..8e573d9eea3 100644 --- a/tools/kwbimage.c +++ b/tools/kwbimage.c @@ -1972,7 +1972,7 @@ static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd, free(image); } -static void kwbimage_print_header(const void *ptr) +static void kwbimage_print_header(const void *ptr, struct image_tool_params *params) { struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr; struct bin_hdr_v0 *bhdr; diff --git a/tools/lpc32xximage.c b/tools/lpc32xximage.c index 37931f91840..715a55a5b5b 100644 --- a/tools/lpc32xximage.c +++ b/tools/lpc32xximage.c @@ -125,7 +125,7 @@ static void print_hdr_byte(struct nand_page_0_boot_header *hdr, int ofs) printf("header[%d] = %02x\n", ofs, hdr->data[ofs]); } -static void lpc32xximage_print_header(const void *ptr) +static void lpc32xximage_print_header(const void *ptr, struct image_tool_params *params) { struct nand_page_0_boot_header *hdr = (struct nand_page_0_boot_header *)ptr; diff --git a/tools/mkimage.c b/tools/mkimage.c index a92d9d5ca57..6dfe3e1d42d 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -790,7 +790,7 @@ int main(int argc, char **argv) /* Print the image information by processing image header */ if (tparams->print_header) - tparams->print_header (ptr); + tparams->print_header (ptr, ¶ms); else { fprintf (stderr, "%s: Can't print header for %s\n", params.cmdname, tparams->name); diff --git a/tools/mtk_image.c b/tools/mtk_image.c index 5ef9334163d..30f54c8e8d8 100644 --- a/tools/mtk_image.c +++ b/tools/mtk_image.c @@ -510,7 +510,7 @@ static int mtk_image_verify_header(unsigned char *ptr, int image_size, return -1; } -static void mtk_image_print_header(const void *ptr) +static void mtk_image_print_header(const void *ptr, struct image_tool_params *params) { struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr; union lk_hdr *lk = (union lk_hdr *)ptr; diff --git a/tools/mxsimage.c b/tools/mxsimage.c index fbe46c47fae..ead61d0cd63 100644 --- a/tools/mxsimage.c +++ b/tools/mxsimage.c @@ -2239,7 +2239,7 @@ static int mxsimage_verify_header(unsigned char *ptr, int image_size, return mxsimage_verify_print_header(params->imagefile, 1); } -static void mxsimage_print_header(const void *hdr) +static void mxsimage_print_header(const void *hdr, struct image_tool_params *params) { if (imagefile) mxsimage_verify_print_header(imagefile, 0); diff --git a/tools/omapimage.c b/tools/omapimage.c index c59cdcc79b3..b79c1c3b648 100644 --- a/tools/omapimage.c +++ b/tools/omapimage.c @@ -85,7 +85,7 @@ static void omapimage_print_section(struct ch_settings *chs) chs->flags); } -static void omapimage_print_header(const void *ptr) +static void omapimage_print_header(const void *ptr, struct image_tool_params *params) { const struct ch_toc *toc = (struct ch_toc *)ptr; const struct gp_header *gph = diff --git a/tools/pblimage.c b/tools/pblimage.c index bd639c276f9..6c4d360e469 100644 --- a/tools/pblimage.c +++ b/tools/pblimage.c @@ -254,7 +254,7 @@ static int pblimage_verify_header(unsigned char *ptr, int image_size, return 0; } -static void pblimage_print_header(const void *ptr) +static void pblimage_print_header(const void *ptr, struct image_tool_params *params) { printf("Image Type: Freescale PBL Boot Image\n"); } diff --git a/tools/rkcommon.c b/tools/rkcommon.c index 96efc1192cb..12c27b34eaa 100644 --- a/tools/rkcommon.c +++ b/tools/rkcommon.c @@ -481,7 +481,7 @@ int rkcommon_verify_header(unsigned char *buf, int size, return -ENOENT; } -void rkcommon_print_header(const void *buf) +void rkcommon_print_header(const void *buf, struct image_tool_params *params) { struct header0_info header0; struct header0_info_v2 header0_v2; diff --git a/tools/rkcommon.h b/tools/rkcommon.h index 49b6df31850..5d2770a80f1 100644 --- a/tools/rkcommon.h +++ b/tools/rkcommon.h @@ -68,7 +68,7 @@ int rkcommon_verify_header(unsigned char *buf, int size, * * @buf: Pointer to the image (can be a read-only file-mapping) */ -void rkcommon_print_header(const void *buf); +void rkcommon_print_header(const void *buf, struct image_tool_params *params); /** * rkcommon_need_rc4_spl() - check if rc4 encoded spl is required diff --git a/tools/socfpgaimage.c b/tools/socfpgaimage.c index eba812fec96..953dfeed4d5 100644 --- a/tools/socfpgaimage.c +++ b/tools/socfpgaimage.c @@ -313,7 +313,7 @@ static void socfpgaimage_print_header_v1(struct socfpga_header_v1 *header) le16_to_cpu(header->checksum)); } -static void socfpgaimage_print_header(const void *ptr) +static void socfpgaimage_print_header(const void *ptr, struct image_tool_params *params) { const void *header = ptr + HEADER_OFFSET; struct socfpga_header_v0 *header_v0; diff --git a/tools/stm32image.c b/tools/stm32image.c index 18357c05182..5c6991f35de 100644 --- a/tools/stm32image.c +++ b/tools/stm32image.c @@ -99,7 +99,7 @@ static int stm32image_verify_header(unsigned char *ptr, int image_size, return 0; } -static void stm32image_print_header(const void *ptr) +static void stm32image_print_header(const void *ptr, struct image_tool_params *params) { struct stm32_header *stm32hdr = (struct stm32_header *)ptr; diff --git a/tools/sunxi_egon.c b/tools/sunxi_egon.c index d45b6f5e435..a514427809a 100644 --- a/tools/sunxi_egon.c +++ b/tools/sunxi_egon.c @@ -82,7 +82,7 @@ static int egon_verify_header(unsigned char *ptr, int image_size, return EXIT_SUCCESS; } -static void egon_print_header(const void *buf) +static void egon_print_header(const void *buf, struct image_tool_params *params) { const struct boot_file_head *header = buf; diff --git a/tools/sunxi_toc0.c b/tools/sunxi_toc0.c index 7a8d74bb8e4..292649fe90f 100644 --- a/tools/sunxi_toc0.c +++ b/tools/sunxi_toc0.c @@ -757,7 +757,7 @@ static const char *toc0_item_name(uint32_t name) return "(unknown)"; } -static void toc0_print_header(const void *buf) +static void toc0_print_header(const void *buf, struct image_tool_params *params) { const struct toc0_main_info *main_info = buf; const struct toc0_item_info *item_info = (void *)(main_info + 1); diff --git a/tools/ublimage.c b/tools/ublimage.c index 1d2e897f6b3..8f9b58c7983 100644 --- a/tools/ublimage.c +++ b/tools/ublimage.c @@ -202,7 +202,7 @@ static int ublimage_verify_header(unsigned char *ptr, int image_size, return 0; } -static void ublimage_print_header(const void *ptr) +static void ublimage_print_header(const void *ptr, struct image_tool_params *params) { struct ubl_header *ubl_hdr = (struct ubl_header *) ptr; diff --git a/tools/vybridimage.c b/tools/vybridimage.c index 94a6684c19b..c38886fa903 100644 --- a/tools/vybridimage.c +++ b/tools/vybridimage.c @@ -134,7 +134,7 @@ static void vybridimage_print_hdr_field(struct nand_page_0_boot_header *hdr, printf("header.fcb[%d] = %08x\n", idx, hdr->fcb[idx]); } -static void vybridimage_print_header(const void *ptr) +static void vybridimage_print_header(const void *ptr, struct image_tool_params *params) { struct nand_page_0_boot_header *hdr = (struct nand_page_0_boot_header *)ptr; diff --git a/tools/zynqimage.c b/tools/zynqimage.c index d3f418b0612..359c93d1acd 100644 --- a/tools/zynqimage.c +++ b/tools/zynqimage.c @@ -163,7 +163,7 @@ static int zynqimage_verify_header(unsigned char *ptr, int image_size, return 0; } -static void zynqimage_print_header(const void *ptr) +static void zynqimage_print_header(const void *ptr, struct image_tool_params *params) { struct zynq_header *zynqhdr = (struct zynq_header *)ptr; int i; diff --git a/tools/zynqmpimage.c b/tools/zynqmpimage.c index 19b2f02ff15..5113ba895f0 100644 --- a/tools/zynqmpimage.c +++ b/tools/zynqmpimage.c @@ -209,7 +209,7 @@ static void print_partition(const void *ptr, const struct partition_header *ph) printf(" Checksum : 0x%08x\n", le32_to_cpu(ph->checksum)); } -void zynqmpimage_print_header(const void *ptr) +void zynqmpimage_print_header(const void *ptr, struct image_tool_params *params) { struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr; int i; diff --git a/tools/zynqmpimage.h b/tools/zynqmpimage.h index a1db819aa36..9d526a17cdd 100644 --- a/tools/zynqmpimage.h +++ b/tools/zynqmpimage.h @@ -133,6 +133,6 @@ struct zynqmp_header { }; void zynqmpimage_default_header(struct zynqmp_header *ptr); -void zynqmpimage_print_header(const void *ptr); +void zynqmpimage_print_header(const void *ptr, struct image_tool_params *params); #endif /* _ZYNQMPIMAGE_H_ */ From 62d81d68d2446739374d6d2fa13ab32c8a4923ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 29 Mar 2023 21:25:55 +0200 Subject: [PATCH 4/8] tools: kwbimage: Simplify align code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace repeated code patterns by generic code. Signed-off-by: Pali Rohár --- tools/kwbimage.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/tools/kwbimage.c b/tools/kwbimage.c index 8e573d9eea3..360feddad19 100644 --- a/tools/kwbimage.c +++ b/tools/kwbimage.c @@ -2118,8 +2118,6 @@ static int kwbimage_verify_header(unsigned char *ptr, int image_size, return 0; } -static int kwbimage_align_size(int bootfrom, int alloc_len, struct stat s); - static int kwbimage_generate(struct image_tool_params *params, struct image_type_params *tparams) { @@ -2130,6 +2128,7 @@ static int kwbimage_generate(struct image_tool_params *params, int version; void *hdr; int ret; + int align, size; fcfg = fopen(params->imagename, "r"); if (!fcfg) { @@ -2211,6 +2210,27 @@ static int kwbimage_generate(struct image_tool_params *params, tparams->header_size = alloc_len; tparams->hdr = hdr; + /* + * Final SATA and SDIO images must be aligned to 512 bytes. + * Final SPI and NAND images must be aligned to 256 bytes. + * Final UART image must be aligned to 128 bytes. + */ + if (bootfrom == IBR_HDR_SATA_ID || bootfrom == IBR_HDR_SDIO_ID) + align = 512; + else if (bootfrom == IBR_HDR_SPI_ID || bootfrom == IBR_HDR_NAND_ID) + align = 256; + else if (bootfrom == IBR_HDR_UART_ID) + align = 128; + else + align = 4; + + /* + * The resulting image needs to be 4-byte aligned. At least + * the Marvell hdrparser tool complains if its unaligned. + * After the image data is stored 4-byte checksum. + */ + size = 4 + (align - (alloc_len + s.st_size + 4) % align) % align; + /* * This function should return aligned size of the datafile. * When skipcpy is set (datafile is skipped) then return value of this @@ -2218,33 +2238,13 @@ static int kwbimage_generate(struct image_tool_params *params, * into the preallocated header size. */ if (params->skipcpy) { - tparams->header_size += kwbimage_align_size(bootfrom, alloc_len, s); + tparams->header_size += size; return 0; } else { - return kwbimage_align_size(bootfrom, alloc_len, s); + return size; } } -static int kwbimage_align_size(int bootfrom, int alloc_len, struct stat s) -{ - /* - * The resulting image needs to be 4-byte aligned. At least - * the Marvell hdrparser tool complains if its unaligned. - * After the image data is stored 4-byte checksum. - * Final UART image must be aligned to 128 bytes. - * Final SPI and NAND images must be aligned to 256 bytes. - * Final SATA and SDIO images must be aligned to 512 bytes. - */ - if (bootfrom == IBR_HDR_SPI_ID || bootfrom == IBR_HDR_NAND_ID) - return 4 + (256 - (alloc_len + s.st_size + 4) % 256) % 256; - else if (bootfrom == IBR_HDR_SATA_ID || bootfrom == IBR_HDR_SDIO_ID) - return 4 + (512 - (alloc_len + s.st_size + 4) % 512) % 512; - else if (bootfrom == IBR_HDR_UART_ID) - return 4 + (128 - (alloc_len + s.st_size + 4) % 128) % 128; - else - return 4 + (4 - s.st_size % 4) % 4; -} - static int kwbimage_generate_config(void *ptr, struct image_tool_params *params) { struct main_hdr_v0 *mhdr0 = (struct main_hdr_v0 *)ptr; From 11af96d7e66030e5dbdd5fffd22eead1f105ed70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 29 Mar 2023 21:25:56 +0200 Subject: [PATCH 5/8] tools: kwbimage: Add support for SATA images with non-512 byte block size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SATA kwbimage contains offsets in block size unit, not in bytes. Until now kwbimage expected that SATA disk always have block size of 512 bytes. But there are 4K Native SATA disks with block size of 4096 bytes. New SATA_BLKSZ command allows to specify different block size than 512 bytes and therefore allows to generate kwbimage for disks with different block sizes. This change add support for generating SATA images with different block size. Also it add support for verifying and dumping such images. Because block size itself is not stored in SATA kwbimage, image verification is done by checking every possible block size (it is any power of two value between 512 and 32 kB). Signed-off-by: Pali Rohár --- tools/kwbimage.c | 98 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 71 insertions(+), 27 deletions(-) diff --git a/tools/kwbimage.c b/tools/kwbimage.c index 360feddad19..4dce495ff03 100644 --- a/tools/kwbimage.c +++ b/tools/kwbimage.c @@ -116,6 +116,7 @@ enum image_cfg_type { IMAGE_CFG_NAND_BADBLK_LOCATION, IMAGE_CFG_NAND_ECC_MODE, IMAGE_CFG_NAND_PAGESZ, + IMAGE_CFG_SATA_BLKSZ, IMAGE_CFG_CPU, IMAGE_CFG_BINARY, IMAGE_CFG_DATA, @@ -147,6 +148,7 @@ static const char * const id_strs[] = { [IMAGE_CFG_NAND_BADBLK_LOCATION] = "NAND_BADBLK_LOCATION", [IMAGE_CFG_NAND_ECC_MODE] = "NAND_ECC_MODE", [IMAGE_CFG_NAND_PAGESZ] = "NAND_PAGE_SIZE", + [IMAGE_CFG_SATA_BLKSZ] = "SATA_BLKSZ", [IMAGE_CFG_CPU] = "CPU", [IMAGE_CFG_BINARY] = "BINARY", [IMAGE_CFG_DATA] = "DATA", @@ -185,6 +187,7 @@ struct image_cfg_element { unsigned int nandbadblklocation; unsigned int nandeccmode; unsigned int nandpagesz; + unsigned int satablksz; struct ext_hdr_v0_reg regdata; unsigned int regdata_delay; unsigned int baudrate; @@ -992,13 +995,21 @@ static int image_fill_xip_header(void *image, struct image_tool_params *params) return 1; } +static unsigned int image_get_satablksz(void) +{ + struct image_cfg_element *e; + e = image_find_option(IMAGE_CFG_SATA_BLKSZ); + return e ? e->satablksz : 512; +} + static size_t image_headersz_align(size_t headersz, uint8_t blockid) { /* * Header needs to be 4-byte aligned, which is already ensured by code * above. Moreover UART images must have header aligned to 128 bytes * (xmodem block size), NAND images to 256 bytes (ECC calculation), - * and SATA and SDIO images to 512 bytes (storage block size). + * SDIO images to 512 bytes (SDHC/SDXC fixed block size) and SATA + * images to specified storage block size (default 512 bytes). * Note that SPI images do not have to have header size aligned * to 256 bytes because it is possible to read from SPI storage from * any offset (read offset does not have to be aligned to block size). @@ -1007,8 +1018,10 @@ static size_t image_headersz_align(size_t headersz, uint8_t blockid) return ALIGN(headersz, 128); else if (blockid == IBR_HDR_NAND_ID) return ALIGN(headersz, 256); - else if (blockid == IBR_HDR_SATA_ID || blockid == IBR_HDR_SDIO_ID) + else if (blockid == IBR_HDR_SDIO_ID) return ALIGN(headersz, 512); + else if (blockid == IBR_HDR_SATA_ID) + return ALIGN(headersz, image_get_satablksz()); else return headersz; } @@ -1076,12 +1089,11 @@ static void *image_create_v0(size_t *dataoff, struct image_tool_params *params, if (e) main_hdr->nandbadblklocation = e->nandbadblklocation; - /* - * For SATA srcaddr is specified in number of sectors. - * This expects the sector size to be 512 bytes. - */ - if (main_hdr->blockid == IBR_HDR_SATA_ID) - main_hdr->srcaddr = cpu_to_le32(le32_to_cpu(main_hdr->srcaddr) / 512); + /* For SATA srcaddr is specified in number of sectors. */ + if (main_hdr->blockid == IBR_HDR_SATA_ID) { + params->bl_len = image_get_satablksz(); + main_hdr->srcaddr = cpu_to_le32(le32_to_cpu(main_hdr->srcaddr) / params->bl_len); + } /* For PCIe srcaddr is not used and must be set to 0xFFFFFFFF. */ if (main_hdr->blockid == IBR_HDR_PEX_ID) @@ -1533,12 +1545,11 @@ static void *image_create_v1(size_t *dataoff, struct image_tool_params *params, if (e) main_hdr->flags = e->debug ? 0x1 : 0; - /* - * For SATA srcaddr is specified in number of sectors. - * This expects the sector size to be 512 bytes. - */ - if (main_hdr->blockid == IBR_HDR_SATA_ID) - main_hdr->srcaddr = cpu_to_le32(le32_to_cpu(main_hdr->srcaddr) / 512); + /* For SATA srcaddr is specified in number of sectors. */ + if (main_hdr->blockid == IBR_HDR_SATA_ID) { + params->bl_len = image_get_satablksz(); + main_hdr->srcaddr = cpu_to_le32(le32_to_cpu(main_hdr->srcaddr) / params->bl_len); + } /* For PCIe srcaddr is not used and must be set to 0xFFFFFFFF. */ if (main_hdr->blockid == IBR_HDR_PEX_ID) @@ -1702,6 +1713,13 @@ static int image_create_config_parse_oneline(char *line, case IMAGE_CFG_NAND_PAGESZ: el->nandpagesz = strtoul(value1, NULL, 16); break; + case IMAGE_CFG_SATA_BLKSZ: + el->satablksz = strtoul(value1, NULL, 0); + if (el->satablksz & (el->satablksz-1)) { + fprintf(stderr, "Invalid SATA block size '%s'\n", value1); + return -1; + } + break; case IMAGE_CFG_BINARY: argi = 0; @@ -1893,6 +1911,8 @@ static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd, struct stat s; int ret; + params->bl_len = 1; + /* * Do not use sbuf->st_size as it contains size with padding. * We need original image data size, so stat original file. @@ -2004,10 +2024,11 @@ static void kwbimage_print_header(const void *ptr, struct image_tool_params *par genimg_print_size(le32_to_cpu(mhdr->blocksize) - sizeof(uint32_t)); printf("Data Offset: "); if (mhdr->blockid == IBR_HDR_SATA_ID) - printf("%u Sector%s (LBA)\n", le32_to_cpu(mhdr->srcaddr), + printf("%u Sector%s (LBA) = ", le32_to_cpu(mhdr->srcaddr), le32_to_cpu(mhdr->srcaddr) != 1 ? "s" : ""); - else - genimg_print_size(le32_to_cpu(mhdr->srcaddr)); + genimg_print_size(le32_to_cpu(mhdr->srcaddr) * params->bl_len); + if (mhdr->blockid == IBR_HDR_SATA_ID) + printf("Sector Size: %u Bytes\n", params->bl_len); if (mhdr->blockid == IBR_HDR_SPI_ID && le32_to_cpu(mhdr->destaddr) == 0xFFFFFFFF) { printf("Load Address: XIP\n"); printf("Execute Offs: %08x\n", le32_to_cpu(mhdr->execaddr)); @@ -2033,6 +2054,7 @@ static int kwbimage_verify_header(unsigned char *ptr, int image_size, uint32_t offset; uint32_t size; uint8_t csum; + int blksz; if (header_size > 192*1024) return -FDT_ERR_BADSTRUCTURE; @@ -2091,12 +2113,28 @@ static int kwbimage_verify_header(unsigned char *ptr, int image_size, return -FDT_ERR_BADSTRUCTURE; } + if (size < 4 || size % 4 != 0) + return -FDT_ERR_BADSTRUCTURE; + /* * For SATA srcaddr is specified in number of sectors. - * This expects that sector size is 512 bytes. + * Try all possible sector sizes which are power of two, + * at least 512 bytes and up to the 32 kB. */ - if (blockid == IBR_HDR_SATA_ID) - offset *= 512; + if (blockid == IBR_HDR_SATA_ID) { + for (blksz = 512; blksz < 0x10000; blksz *= 2) { + if (offset * blksz > image_size || offset * blksz + size > image_size) + break; + + if (image_checksum32(ptr + offset * blksz, size - 4) == + *(uint32_t *)(ptr + offset * blksz + size - 4)) { + params->bl_len = blksz; + return 0; + } + } + + return -FDT_ERR_BADSTRUCTURE; + } /* * For PCIe srcaddr is always set to 0xFFFFFFFF. @@ -2105,16 +2143,14 @@ static int kwbimage_verify_header(unsigned char *ptr, int image_size, if (blockid == IBR_HDR_PEX_ID && offset == 0xFFFFFFFF) offset = header_size; - if (offset > image_size || offset % 4 != 0) - return -FDT_ERR_BADSTRUCTURE; - - if (size < 4 || offset + size > image_size || size % 4 != 0) + if (offset % 4 != 0 || offset > image_size || offset + size > image_size) return -FDT_ERR_BADSTRUCTURE; if (image_checksum32(ptr + offset, size - 4) != *(uint32_t *)(ptr + offset + size - 4)) return -FDT_ERR_BADSTRUCTURE; + params->bl_len = 1; return 0; } @@ -2129,6 +2165,7 @@ static int kwbimage_generate(struct image_tool_params *params, void *hdr; int ret; int align, size; + unsigned int satablksz; fcfg = fopen(params->imagename, "r"); if (!fcfg) { @@ -2166,6 +2203,7 @@ static int kwbimage_generate(struct image_tool_params *params, bootfrom = image_get_bootfrom(); version = image_get_version(); + satablksz = image_get_satablksz(); switch (version) { /* * Fallback to version 0 if no version is provided in the @@ -2211,11 +2249,14 @@ static int kwbimage_generate(struct image_tool_params *params, tparams->hdr = hdr; /* - * Final SATA and SDIO images must be aligned to 512 bytes. + * Final SATA images must be aligned to disk block size. + * Final SDIO images must be aligned to 512 bytes. * Final SPI and NAND images must be aligned to 256 bytes. * Final UART image must be aligned to 128 bytes. */ - if (bootfrom == IBR_HDR_SATA_ID || bootfrom == IBR_HDR_SDIO_ID) + if (bootfrom == IBR_HDR_SATA_ID) + align = satablksz; + else if (bootfrom == IBR_HDR_SDIO_ID) align = 512; else if (bootfrom == IBR_HDR_SPI_ID || bootfrom == IBR_HDR_NAND_ID) align = 256; @@ -2306,6 +2347,9 @@ static int kwbimage_generate_config(void *ptr, struct image_tool_params *params) if (version == 0 && mhdr->blockid == IBR_HDR_SATA_ID) fprintf(f, "SATA_PIO_MODE %u\n", (unsigned)mhdr0->satapiomode); + if (mhdr->blockid == IBR_HDR_SATA_ID) + fprintf(f, "SATA_BLKSZ %u\n", params->bl_len); + /* * Addresses and sizes which are specified by mkimage command line * arguments and not in kwbimage config file @@ -2486,7 +2530,7 @@ static int kwbimage_extract_subimage(void *ptr, struct image_tool_params *params offset = le32_to_cpu(mhdr->srcaddr); if (mhdr->blockid == IBR_HDR_SATA_ID) - offset *= 512; + offset *= params->bl_len; if (mhdr->blockid == IBR_HDR_PEX_ID && offset == 0xFFFFFFFF) offset = header_size; From 5d8178563bc6f3d684f1835d79cb2cb0336409d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 29 Mar 2023 21:25:57 +0200 Subject: [PATCH 6/8] tools: kwboot: Add support for parsing SATA images with non-512 block size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently kwboot expected that sector size for SATA image is always 512 bytes. If SATA image cannot be parsed with sector size of 512 bytes, try larger sector sizes which are power of two and up to the 32 kB. Maximal theoretical value is 32 kB because ATA IDENTIFY command returns sector size as 16-bit number. Signed-off-by: Pali Rohár --- tools/kwboot.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/tools/kwboot.c b/tools/kwboot.c index 348a3203d60..6bef4610ff8 100644 --- a/tools/kwboot.c +++ b/tools/kwboot.c @@ -1991,6 +1991,39 @@ _inject_baudrate_change_code(void *img, size_t *size, int for_data, } } +static int +kwboot_img_guess_sata_blksz(void *img, uint32_t blkoff, uint32_t data_size, size_t total_size) +{ + uint32_t sum, *ptr, *end; + int blksz; + + /* + * Try all possible sector sizes which are power of two, + * at least 512 bytes and up to the 32 kB. + */ + for (blksz = 512; blksz < 0x10000; blksz *= 2) { + if (blkoff * blksz > total_size || + blkoff * blksz + data_size > total_size || + data_size % 4) + break; + + /* + * Calculate data checksum and if it matches + * then tried blksz should be correct. + */ + ptr = img + blkoff * blksz; + end = (void *)ptr + data_size - 4; + for (sum = 0; ptr < end; ptr++) + sum += *ptr; + + if (sum == *end) + return blksz; + } + + /* Fallback to 512 bytes */ + return 512; +} + static const char * kwboot_img_type(uint8_t blockid) { @@ -2049,7 +2082,7 @@ kwboot_img_patch(void *img, size_t *size, int baudrate) switch (hdr->blockid) { case IBR_HDR_SATA_ID: - hdr->srcaddr = cpu_to_le32(srcaddr * 512); + hdr->srcaddr = cpu_to_le32(srcaddr * kwboot_img_guess_sata_blksz(img, srcaddr, le32_to_cpu(hdr->blocksize), *size)); break; case IBR_HDR_PEX_ID: From c62af15393b34dff4350d37e678707ad70e288a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 29 Mar 2023 21:25:58 +0200 Subject: [PATCH 7/8] arm: mvebu: spl: Allow to build SATA kwbimage for 4K Native disks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new config option CONFIG_MVEBU_SPL_SATA_BLKSZ for specifying block size of SATA disk. This information is used during building of SATA kwbimage and must be correctly set, otherwise BootROM does not load SPL. For 4K Native disks CONFIG_MVEBU_SPL_SATA_BLKSZ must be set to 4096. Signed-off-by: Pali Rohár Tested-by: Martin Rowe --- arch/arm/mach-mvebu/Kconfig | 10 ++++++++++ arch/arm/mach-mvebu/Makefile | 5 +++++ arch/arm/mach-mvebu/kwbimage.cfg.in | 3 +++ 3 files changed, 18 insertions(+) diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index b1f2e97ae73..ac484c73f62 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -381,6 +381,16 @@ config MVEBU_SPL_NAND_BADBLK_LOCATION Value 0x0 = SLC flash = BBI at page 0 or page 1 Value 0x1 = MLC flash = BBI at last page in the block +config MVEBU_SPL_SATA_BLKSZ + int "SATA block size" + depends on MVEBU_SPL_BOOT_DEVICE_SATA + range 512 32768 + default 512 + help + Block size of the SATA disk in bytes. + Typically 512 bytes for majority of disks + and 4096 bytes for 4K Native disks. + config MVEBU_EFUSE bool "Enable eFuse support" depends on HAVE_MVEBU_EFUSE diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index 90f88337bc1..0584ed2be5b 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile @@ -73,6 +73,11 @@ KWB_CFG_NAND_BLKSZ = $(CONFIG_SYS_NAND_BLOCK_SIZE) KWB_CFG_NAND_BADBLK_LOCATION = $(CONFIG_MVEBU_SPL_NAND_BADBLK_LOCATION) endif +ifneq ($(CONFIG_MVEBU_SPL_BOOT_DEVICE_SATA),) +KWB_REPLACE += SATA_BLKSZ +KWB_CFG_SATA_BLKSZ = $(CONFIG_MVEBU_SPL_SATA_BLKSZ) +endif + ifneq ($(CONFIG_SECURED_MODE_IMAGE),) KWB_REPLACE += CSK_INDEX KWB_CFG_CSK_INDEX = $(CONFIG_SECURED_MODE_CSK_INDEX) diff --git a/arch/arm/mach-mvebu/kwbimage.cfg.in b/arch/arm/mach-mvebu/kwbimage.cfg.in index 90cf00c5b98..588c259202b 100644 --- a/arch/arm/mach-mvebu/kwbimage.cfg.in +++ b/arch/arm/mach-mvebu/kwbimage.cfg.in @@ -16,6 +16,9 @@ VERSION 1 #@NAND_BLKSZ #@NAND_BADBLK_LOCATION +# SATA configuration +#@SATA_BLKSZ + # Enable BootROM output via DEBUG flag on SoCs which require it #@DEBUG From 6add83991b2887619d0b25e4068b4c0082a4596a Mon Sep 17 00:00:00 2001 From: Tony Dinh Date: Sun, 2 Apr 2023 21:42:33 -0700 Subject: [PATCH 8/8] ddr: marvell: a38x: Perform DDR training sequence again for 2nd boot - DDR Training sequence happens very fast. The speedup in boot time is negligible by skipping the training sequence during 2nd boot or after. So remove the check and skip. - This change improves the robustness of DDR training. If u-boot crashed during DDR training, the training could be left in a limbo state, where the BootROM has recorded that it is already in a 2nd boot. The training must be repeated in this scenario to get out of this limbo state, but due to the check it cannot be performed. Signed-off-by: Tony Dinh Reviewed-by: Stefan Roese --- drivers/ddr/marvell/a38x/mv_ddr_plat.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.c b/drivers/ddr/marvell/a38x/mv_ddr_plat.c index 6e7949ac72c..8ec9fb0874e 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_plat.c +++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.c @@ -1363,13 +1363,6 @@ int mv_ddr_pre_training_soc_config(const char *ddr_type) DRAM_RESET_MASK_MASKED << DRAM_RESET_MASK_OFFS); } - /* Check if DRAM is already initialized */ - if (reg_read(REG_BOOTROM_ROUTINE_ADDR) & - (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS)) { - printf("%s Training Sequence - 2nd boot - Skip\n", ddr_type); - return MV_OK; - } - /* Fix read ready phases for all SOC in reg 0x15c8 */ reg_val = reg_read(TRAINING_DBG_3_REG);