diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index a4c40c4c4..ddfc5e703 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -28,6 +28,13 @@ PLAT_XLAT_TABLES_DYNAMIC := 1 STM32MP_DDR_DUAL_AXI_PORT:= 1 STM32MP_DDR_32BIT_INTERFACE:= 1 +# STM32 image header version v1.0 +STM32_HEADER_VERSION_MAJOR:= 1 +STM32_HEADER_VERSION_MINOR:= 0 + +# STM32 image header binary type for BL2 +STM32_HEADER_BL2_BINARY_TYPE:= 0x10 + ifeq ($(AARCH32_SP),sp_min) # Disable Neon support: sp_min runtime may conflict with non-secure world TF_CFLAGS += -mfloat-abi=soft @@ -427,5 +434,8 @@ tf-a-%.stm32: ${STM32IMAGE} tf-a-%.bin $(eval ENTRY = $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}')) ${Q}${STM32IMAGE} -s $(word 2,$^) -d $@ \ -l $(LOADADDR) -e ${ENTRY} \ - -v ${STM32_TF_VERSION} + -v ${STM32_TF_VERSION} \ + -m ${STM32_HEADER_VERSION_MAJOR} \ + -n ${STM32_HEADER_VERSION_MINOR} \ + -b ${STM32_HEADER_BL2_BINARY_TYPE} @echo diff --git a/tools/stm32image/stm32image.c b/tools/stm32image/stm32image.c index fb1dee072..bd4720c5c 100644 --- a/tools/stm32image/stm32image.c +++ b/tools/stm32image/stm32image.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -22,16 +22,16 @@ #define VER_MINOR 1 #define VER_VARIANT 0 #define HEADER_VERSION_V1 0x1 -#define TF_BINARY_TYPE 0x10 +#define HEADER_VERSION_V2 0x2 +#define PADDING_HEADER_MAGIC __be32_to_cpu(0x5354FFFF) +#define PADDING_HEADER_FLAG (1 << 31) +#define PADDING_HEADER_LENGTH 0x180 -/* Default option : bit0 => no signature */ -#define HEADER_DEFAULT_OPTION (__cpu_to_le32(0x00000001)) - -struct stm32_header { +struct stm32_header_v1 { uint32_t magic_number; uint8_t image_signature[64]; uint32_t image_checksum; - uint8_t header_version[4]; + uint8_t header_version[4]; uint32_t image_length; uint32_t image_entry_point; uint32_t reserved1; @@ -45,31 +45,50 @@ struct stm32_header { uint8_t binary_type; }; -static void stm32image_default_header(struct stm32_header *ptr) +struct stm32_header_v2 { + uint32_t magic_number; + uint8_t image_signature[64]; + uint32_t image_checksum; + uint8_t header_version[4]; + uint32_t image_length; + uint32_t image_entry_point; + uint32_t reserved1; + uint32_t load_address; + uint32_t reserved2; + uint32_t version_number; + uint32_t extension_flags; + uint32_t extension_headers_length; + uint32_t binary_type; + uint8_t padding[16]; + uint32_t extension_header_type; + uint32_t extension_header_length; + uint8_t extension_padding[376]; +}; + +static void stm32image_default_header(void *ptr) { - if (!ptr) { + struct stm32_header_v1 *header = (struct stm32_header_v1 *)ptr; + + if (!header) { return; } - ptr->magic_number = HEADER_MAGIC; - ptr->option_flags = HEADER_DEFAULT_OPTION; - ptr->ecdsa_algorithm = __cpu_to_le32(1); - ptr->version_number = __cpu_to_le32(0); - ptr->binary_type = TF_BINARY_TYPE; + header->magic_number = HEADER_MAGIC; + header->version_number = __cpu_to_le32(0); } -static uint32_t stm32image_checksum(void *start, uint32_t len) +static uint32_t stm32image_checksum(void *start, uint32_t len, + uint32_t header_size) { uint32_t csum = 0; - uint32_t hdr_len = sizeof(struct stm32_header); uint8_t *p; - if (len < hdr_len) { + if (len < header_size) { return 0; } - p = (unsigned char *)start + hdr_len; - len -= hdr_len; + p = (unsigned char *)start + header_size; + len -= header_size; while (len > 0) { csum += *p; @@ -82,7 +101,8 @@ static uint32_t stm32image_checksum(void *start, uint32_t len) static void stm32image_print_header(const void *ptr) { - struct stm32_header *stm32hdr = (struct stm32_header *)ptr; + struct stm32_header_v1 *stm32hdr = (struct stm32_header_v1 *)ptr; + struct stm32_header_v2 *stm32hdr_v2 = (struct stm32_header_v2 *)ptr; printf("Image Type : ST Microelectronics STM32 V%d.%d\n", stm32hdr->header_version[VER_MAJOR], @@ -95,40 +115,87 @@ static void stm32image_print_header(const void *ptr) __le32_to_cpu(stm32hdr->image_entry_point)); printf("Checksum : 0x%08x\n", __le32_to_cpu(stm32hdr->image_checksum)); - printf("Option : 0x%08x\n", - __le32_to_cpu(stm32hdr->option_flags)); - printf("Version : 0x%08x\n", + + switch (stm32hdr->header_version[VER_MAJOR]) { + case HEADER_VERSION_V1: + printf("Option : 0x%08x\n", + __le32_to_cpu(stm32hdr->option_flags)); + break; + + case HEADER_VERSION_V2: + printf("Extension : 0x%08x\n", + __le32_to_cpu(stm32hdr_v2->extension_flags)); + break; + + default: + printf("Incorrect header version\n"); + } + + printf("Version : 0x%08x\n", __le32_to_cpu(stm32hdr->version_number)); } -static void stm32image_set_header(void *ptr, struct stat *sbuf, int ifd, - uint32_t loadaddr, uint32_t ep, uint32_t ver, - uint32_t major, uint32_t minor) +static int stm32image_set_header(void *ptr, struct stat *sbuf, int ifd, + uint32_t loadaddr, uint32_t ep, uint32_t ver, + uint32_t major, uint32_t minor, + uint32_t binary_type, uint32_t header_size) { - struct stm32_header *stm32hdr = (struct stm32_header *)ptr; + struct stm32_header_v1 *stm32hdr = (struct stm32_header_v1 *)ptr; + struct stm32_header_v2 *stm32hdr_v2 = (struct stm32_header_v2 *)ptr; + uint32_t ext_size = 0U; + uint32_t ext_flags = 0U; - stm32image_default_header(stm32hdr); + stm32image_default_header(ptr); stm32hdr->header_version[VER_MAJOR] = major; stm32hdr->header_version[VER_MINOR] = minor; stm32hdr->load_address = __cpu_to_le32(loadaddr); stm32hdr->image_entry_point = __cpu_to_le32(ep); stm32hdr->image_length = __cpu_to_le32((uint32_t)sbuf->st_size - - sizeof(struct stm32_header)); + header_size); stm32hdr->image_checksum = - __cpu_to_le32(stm32image_checksum(ptr, sbuf->st_size)); + __cpu_to_le32(stm32image_checksum(ptr, sbuf->st_size, + header_size)); + + switch (stm32hdr->header_version[VER_MAJOR]) { + case HEADER_VERSION_V1: + /* Default option for header v1 : bit0 => no signature */ + stm32hdr->option_flags = __cpu_to_le32(0x00000001); + stm32hdr->ecdsa_algorithm = __cpu_to_le32(1); + stm32hdr->binary_type = (uint8_t)binary_type; + break; + + case HEADER_VERSION_V2: + stm32hdr_v2->binary_type = binary_type; + ext_size += PADDING_HEADER_LENGTH; + ext_flags |= PADDING_HEADER_FLAG; + stm32hdr_v2->extension_flags = + __cpu_to_le32(ext_flags); + stm32hdr_v2->extension_headers_length = + __cpu_to_le32(ext_size); + stm32hdr_v2->extension_header_type = PADDING_HEADER_MAGIC; + stm32hdr_v2->extension_header_length = + __cpu_to_le32(PADDING_HEADER_LENGTH); + break; + + default: + return -1; + } + stm32hdr->version_number = __cpu_to_le32(ver); + + return 0; } static int stm32image_create_header_file(char *srcname, char *destname, uint32_t loadaddr, uint32_t entry, uint32_t version, uint32_t major, - uint32_t minor) + uint32_t minor, uint32_t binary_type) { - int src_fd, dest_fd; + int src_fd, dest_fd, header_size; struct stat sbuf; unsigned char *ptr; - struct stm32_header stm32image_header; + void *stm32image_header; dest_fd = open(destname, O_RDWR | O_CREAT | O_TRUNC | O_APPEND, 0666); if (dest_fd == -1) { @@ -154,15 +221,32 @@ static int stm32image_create_header_file(char *srcname, char *destname, return -1; } - memset(&stm32image_header, 0, sizeof(struct stm32_header)); + switch (major) { + case HEADER_VERSION_V1: + stm32image_header = malloc(sizeof(struct stm32_header_v1)); + header_size = sizeof(struct stm32_header_v1); + break; - if (write(dest_fd, &stm32image_header, sizeof(struct stm32_header)) != - sizeof(struct stm32_header)) { - fprintf(stderr, "Write error %s: %s\n", destname, - strerror(errno)); + case HEADER_VERSION_V2: + stm32image_header = malloc(sizeof(struct stm32_header_v2)); + header_size = sizeof(struct stm32_header_v2); + break; + + default: return -1; } + memset(stm32image_header, 0, header_size); + if (write(dest_fd, stm32image_header, header_size) != + header_size) { + fprintf(stderr, "Write error %s: %s\n", destname, + strerror(errno)); + free(stm32image_header); + return -1; + } + + free(stm32image_header); + if (write(dest_fd, ptr, sbuf.st_size) != sbuf.st_size) { fprintf(stderr, "Write error on %s: %s\n", destname, strerror(errno)); @@ -184,8 +268,11 @@ static int stm32image_create_header_file(char *srcname, char *destname, return -1; } - stm32image_set_header(ptr, &sbuf, dest_fd, loadaddr, entry, version, - major, minor); + if (stm32image_set_header(ptr, &sbuf, dest_fd, loadaddr, + entry, version, major, minor, + binary_type, header_size) != 0) { + return -1; + } stm32image_print_header(ptr); @@ -196,13 +283,22 @@ static int stm32image_create_header_file(char *srcname, char *destname, int main(int argc, char *argv[]) { - int opt, loadaddr = -1, entry = -1, err = 0, version = 0; - int major = HEADER_VERSION_V1; + int opt; + int loadaddr = -1; + int entry = -1; + int err = 0; + int version = 0; + int binary_type = -1; + int major = HEADER_VERSION_V2; int minor = 0; - char *dest = NULL, *src = NULL; + char *dest = NULL; + char *src = NULL; - while ((opt = getopt(argc, argv, ":s:d:l:e:v:m:n:")) != -1) { + while ((opt = getopt(argc, argv, ":b:s:d:l:e:v:m:n:")) != -1) { switch (opt) { + case 'b': + binary_type = strtol(optarg, NULL, 0); + break; case 's': src = optarg; break; @@ -226,7 +322,7 @@ int main(int argc, char *argv[]) break; default: fprintf(stderr, - "Usage : %s [-s srcfile] [-d destfile] [-l loadaddr] [-e entry_point] [-m major] [-n minor]\n", + "Usage : %s [-s srcfile] [-d destfile] [-l loadaddr] [-e entry_point] [-m major] [-n minor] [-b binary_type]\n", argv[0]); return -1; } @@ -252,8 +348,14 @@ int main(int argc, char *argv[]) return -1; } + if (binary_type == -1) { + fprintf(stderr, "Missing -b option\n"); + return -1; + } + err = stm32image_create_header_file(src, dest, loadaddr, - entry, version, major, minor); + entry, version, major, minor, + binary_type); return err; }