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: 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 6b8c72a..379daa8 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", -- cgit v1.1 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: 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 37ff9c4..ca24a5c 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"); -- cgit v1.1 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: 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 b8b3ee3..c5b33b5 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 7b3b243..6a2d9d8 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 dc429ce..0e49ab3 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 0164976..2d417d4 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 920a16a..2da4b94 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 8763a36..9fe69ea 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 27de4cf..d2bc79d 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 87eee4a..b293211 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 fdceea4..a766aa2 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 c25ea84..76d0cd6 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 3ca79d8..21075c2 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 354ee34..b3da1f2 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 177084a..8e573d9 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 37931f9..715a55a 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 a92d9d5..6dfe3e1 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 5ef9334..30f54c8 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 fbe46c4..ead61d0 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 c59cdcc..b79c1c3 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 bd639c2..6c4d360 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 96efc11..12c27b3 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 49b6df3..5d2770a 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 eba812f..953dfee 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 18357c0..5c6991f 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 d45b6f5..a514427 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 7a8d74b..292649f 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 1d2e897..8f9b58c 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 94a6684..c38886f 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 d3f418b..359c93d 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 19b2f02..5113ba8 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 a1db819..9d526a1 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_ */ -- cgit v1.1 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: 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 8e573d9..360fedd 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) { @@ -2212,39 +2211,40 @@ static int kwbimage_generate(struct image_tool_params *params, 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 * function is ignored, so we have to put required kwbimage aligning * 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; -- cgit v1.1 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: 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 360fedd..4dce495 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; -- cgit v1.1 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: 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 348a320..6bef461 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: -- cgit v1.1 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: 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 b1f2e97..ac484c7 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 90f8833..0584ed2 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 90cf00c..588c259 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 -- cgit v1.1 From 6add83991b2887619d0b25e4068b4c0082a4596a Mon Sep 17 00:00:00 2001 From: Tony Dinh Date: Sun, 2 Apr 2023 21:42:33 -0700 Subject: 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 6e7949a..8ec9fb0 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); -- cgit v1.1