]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
stm32mp: stm32prog: add FIP header support
authorPatrick Delaunay <patrick.delaunay@foss.st.com>
Fri, 2 Apr 2021 12:05:17 +0000 (14:05 +0200)
committerPatrice Chotard <patrice.chotard@foss.st.com>
Fri, 9 Apr 2021 09:53:00 +0000 (11:53 +0200)
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@foss.st.com>
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c

index a7e2861764c6facf66ae72e27366a22ea5187e6b..e36501a86b22280f2176968c75ce01b906c27641 100644 (file)
@@ -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))
index d0518d12235fdd6b175c427560229177835b3206..4c4d8a7a69e51bcdd893939ac739d8c201114088 100644 (file)
@@ -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;
index 18af99c78bc0192b13b5fefe0fea9b0ad4828b5c..581b10d0ac9ab1a0ff2a483cb7138f0aefb399a9 100644 (file)
@@ -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);
index a51e5e3ec86bdebf0072342b8e5d369745e24054..2b92e3b1498cfa1add532e0a653181b4da90da78 100644 (file)
@@ -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 */