From mboxrd@z Thu Jan 1 00:00:00 1970 From: Patrice CHOTARD Date: Thu, 8 Apr 2021 15:55:11 +0200 Subject: [PATCH] stm32mp: stm32prog: add FIP header support In-Reply-To: <20210402140511.1.I81e79d4b32305a46b797f1ce405c200185a0647e@changeid> References: <20210402140511.1.I81e79d4b32305a46b797f1ce405c200185a0647e@changeid> Message-ID: <6368d7f6-ef86-5be1-8a33-7ff5320e8b1b@foss.st.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi Patrick On 4/2/21 2:05 PM, Patrick Delaunay wrote: > 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 > --- > > .../cmd_stm32prog/cmd_stm32prog.c | 19 +++--- > .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 59 +++++++++++++------ > .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 12 +++- > .../cmd_stm32prog/stm32prog_serial.c | 11 ++-- > 4 files changed, 64 insertions(+), 37 deletions(-) > > 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 at 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 at 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 */ > Reviewed-by: Patrice Chotard Thanks Patrice