From: Patrick Delaunay Date: Fri, 2 Apr 2021 12:05:17 +0000 (+0200) Subject: stm32mp: stm32prog: add FIP header support X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=4fb7b3e10891ce8fc2d36e02e6d2f98df672e986;p=u-boot.git stm32mp: stm32prog: add FIP header support Add support of TF-A FIP header in command stm32prog for all the boot partition and not only the STM32IMAGE. This patch is a preliminary patch to support FIP as second boot stage after TF-A BL2 when CONFIG_TFABOOT is activated for trusted boot chain. The FIP is archive binary loaded by TF-A BL2, which contains the secure OS = OP-TEE and the non secure firmware and device tree = U-Boot. Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c index a7e2861764..e36501a86b 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c @@ -73,15 +73,16 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, size = simple_strtoul(argv[4], NULL, 16); /* check STM32IMAGE presence */ - if (size == 0 && - !stm32prog_header_check((struct raw_header_s *)addr, &header)) { - size = header.image_length + BL_HEADER_SIZE; - - /* uImage detected in STM32IMAGE, execute the script */ - if (IMAGE_FORMAT_LEGACY == - genimg_get_format((void *)(addr + BL_HEADER_SIZE))) - return image_source_script(addr + BL_HEADER_SIZE, - "script@1"); + if (size == 0) { + stm32prog_header_check((struct raw_header_s *)addr, &header); + if (header.type == HEADER_STM32IMAGE) { + size = header.image_length + BL_HEADER_SIZE; + + /* uImage detected in STM32IMAGE, execute the script */ + if (IMAGE_FORMAT_LEGACY == + genimg_get_format((void *)(addr + BL_HEADER_SIZE))) + return image_source_script(addr + BL_HEADER_SIZE, "script@1"); + } } if (IS_ENABLED(CONFIG_DM_VIDEO)) diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index d0518d1223..4c4d8a7a69 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -60,8 +60,6 @@ static const efi_guid_t uuid_mmc[3] = { ROOTFS_MMC2_UUID }; -DECLARE_GLOBAL_DATA_PTR; - /* order of column in flash layout file */ enum stm32prog_col_t { COL_OPTION, @@ -73,6 +71,16 @@ enum stm32prog_col_t { COL_NB_STM32 }; +#define FIP_TOC_HEADER_NAME 0xAA640001 + +struct fip_toc_header { + u32 name; + u32 serial_number; + u64 flags; +}; + +DECLARE_GLOBAL_DATA_PTR; + /* partition handling routines : CONFIG_CMD_MTDPARTS */ int mtdparts_init(void); int find_dev_and_part(const char *id, struct mtd_device **dev, @@ -88,46 +96,57 @@ char *stm32prog_get_error(struct stm32prog_data *data) return data->error; } -u8 stm32prog_header_check(struct raw_header_s *raw_header, - struct image_header_s *header) +static bool stm32prog_is_fip_header(struct fip_toc_header *header) +{ + return (header->name == FIP_TOC_HEADER_NAME) && header->serial_number; +} + +void stm32prog_header_check(struct raw_header_s *raw_header, + struct image_header_s *header) { unsigned int i; - header->present = 0; + if (!raw_header || !header) { + log_debug("%s:no header data\n", __func__); + return; + } + + header->type = HEADER_NONE; header->image_checksum = 0x0; header->image_length = 0x0; - if (!raw_header || !header) { - log_debug("%s:no header data\n", __func__); - return -1; + if (stm32prog_is_fip_header((struct fip_toc_header *)raw_header)) { + header->type = HEADER_FIP; + return; } + if (raw_header->magic_number != (('S' << 0) | ('T' << 8) | ('M' << 16) | (0x32 << 24))) { log_debug("%s:invalid magic number : 0x%x\n", __func__, raw_header->magic_number); - return -2; + return; } /* only header v1.0 supported */ if (raw_header->header_version != 0x00010000) { log_debug("%s:invalid header version : 0x%x\n", __func__, raw_header->header_version); - return -3; + return; } if (raw_header->reserved1 != 0x0 || raw_header->reserved2) { log_debug("%s:invalid reserved field\n", __func__); - return -4; + return; } for (i = 0; i < (sizeof(raw_header->padding) / 4); i++) { if (raw_header->padding[i] != 0) { log_debug("%s:invalid padding field\n", __func__); - return -5; + return; } } - header->present = 1; + header->type = HEADER_STM32IMAGE; header->image_checksum = le32_to_cpu(raw_header->image_checksum); header->image_length = le32_to_cpu(raw_header->image_length); - return 0; + return; } static u32 stm32prog_header_checksum(u32 addr, struct image_header_s *header) @@ -356,8 +375,8 @@ static int parse_flash_layout(struct stm32prog_data *data, data->part_nb = 0; /* check if STM32image is detected */ - if (!stm32prog_header_check((struct raw_header_s *)addr, - &data->header)) { + stm32prog_header_check((struct raw_header_s *)addr, &data->header); + if (data->header.type == HEADER_STM32IMAGE) { u32 checksum; addr = addr + BL_HEADER_SIZE; @@ -1410,7 +1429,7 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part) if (part->target != STM32PROG_NAND && part->target != STM32PROG_SPI_NAND) - return -1; + return -EINVAL; dfu = dfu_get_entity(part->alt_id); @@ -1420,8 +1439,10 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part) ret = dfu->read_medium(dfu, 0, (void *)&raw_header, &size); if (ret) return ret; - if (stm32prog_header_check(&raw_header, &header)) - return -1; + + stm32prog_header_check(&raw_header, &header); + if (header.type != HEADER_STM32IMAGE) + return -ENOENT; /* read header + payload */ size = header.image_length + BL_HEADER_SIZE; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index 18af99c78b..581b10d0ac 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -37,8 +37,14 @@ enum stm32prog_link_t { LINK_UNDEFINED, }; +enum stm32prog_header_t { + HEADER_NONE, + HEADER_STM32IMAGE, + HEADER_FIP, +}; + struct image_header_s { - bool present; + enum stm32prog_header_t type; u32 image_checksum; u32 image_length; }; @@ -160,8 +166,8 @@ int stm32prog_pmic_read(struct stm32prog_data *data, u32 offset, int stm32prog_pmic_start(struct stm32prog_data *data); /* generic part*/ -u8 stm32prog_header_check(struct raw_header_s *raw_header, - struct image_header_s *header); +void stm32prog_header_check(struct raw_header_s *raw_header, + struct image_header_s *header); int stm32prog_dfu_init(struct stm32prog_data *data); void stm32prog_next_phase(struct stm32prog_data *data); void stm32prog_do_reset(struct stm32prog_data *data); diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c index a51e5e3ec8..2b92e3b149 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c @@ -309,11 +309,10 @@ static u8 stm32prog_header(struct stm32prog_data *data) /* force cleanup to avoid issue with previous read */ dfu_transaction_cleanup(dfu_entity); - ret = stm32prog_header_check(data->header_data, - &data->header); + stm32prog_header_check(data->header_data, &data->header); - /* no header : max size is partition size */ - if (ret) { + /* no stm32 image header : max size is partition size */ + if (data->header.type != HEADER_STM32IMAGE) { dfu_entity->get_medium_size(dfu_entity, &size); data->header.image_length = size; } @@ -389,7 +388,7 @@ static u8 stm32prog_start(struct stm32prog_data *data, u32 address) data->dfu_seq = 0; printf("\n received length = 0x%x\n", data->cursor); - if (data->header.present) { + if (data->header.type == HEADER_STM32IMAGE) { if (data->cursor != (data->header.image_length + BL_HEADER_SIZE)) { stm32prog_err("transmission interrupted (length=0x%x expected=0x%x)", @@ -789,7 +788,7 @@ static void download_command(struct stm32prog_data *data) } } - if (image_header->present) { + if (data->header.type == HEADER_STM32IMAGE) { if (data->cursor <= BL_HEADER_SIZE) goto end; /* compute checksum on payload */