[PATCH] stm32mp: stm32prog: add FIP header support

Patrick Delaunay patrick.delaunay at foss.st.com
Fri Apr 2 14:05:17 CEST 2021


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 */
-- 
2.17.1



More information about the U-Boot mailing list