[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