[PATCH] stm32mp: stm32prog: add FIP header support

Patrice CHOTARD patrice.chotard at foss.st.com
Fri Apr 9 12:02:17 CEST 2021


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 <patrick.delaunay at foss.st.com>
> ---
> 
>  .../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 */
> 
Applied to u-boot-stm/master

Thanks
Patrice


More information about the U-Boot mailing list