aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
diff options
context:
space:
mode:
authorPatrick Delaunay <patrick.delaunay@foss.st.com>2022-03-28 19:25:29 +0200
committerPatrice Chotard <patrice.chotard@foss.st.com>2022-05-10 10:56:39 +0200
commit49d0ecb1231dd7f8558ede64cb724e43189cfcd3 (patch)
tree48dc90dd6547e336f75377140f6b36229dfc5b64 /arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
parente82ab4c8906fc2e1e42065e4207ff0c36f343553 (diff)
stm32mp: stm32prog: add support of STM32IMAGE version 2
Add support of new header for the STM32IMAGE version V2 in command stm32prog command for STM32MP13x family. Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com> Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com> Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
Diffstat (limited to 'arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c')
-rw-r--r--arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c119
1 files changed, 83 insertions, 36 deletions
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
index 5d53e6146f..3e1fdee5b3 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
@@ -205,52 +205,98 @@ 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)
+static bool stm32prog_is_stm32_header_v1(struct stm32_header_v1 *header)
{
unsigned int i;
- if (!raw_header || !header) {
- log_debug("%s:no header data\n", __func__);
- return;
+ if (header->magic_number !=
+ (('S' << 0) | ('T' << 8) | ('M' << 16) | (0x32 << 24))) {
+ log_debug("%s:invalid magic number : 0x%x\n",
+ __func__, header->magic_number);
+ return false;
+ }
+ if (header->header_version != 0x00010000) {
+ log_debug("%s:invalid header version : 0x%x\n",
+ __func__, header->header_version);
+ return false;
}
- header->type = HEADER_NONE;
- header->image_checksum = 0x0;
- header->image_length = 0x0;
-
- if (stm32prog_is_fip_header((struct fip_toc_header *)raw_header)) {
- header->type = HEADER_FIP;
- return;
+ if (header->reserved1 || header->reserved2) {
+ log_debug("%s:invalid reserved field\n", __func__);
+ return false;
+ }
+ for (i = 0; i < sizeof(header->padding); i++) {
+ if (header->padding[i] != 0) {
+ log_debug("%s:invalid padding field\n", __func__);
+ return false;
+ }
}
- if (raw_header->magic_number !=
+ return true;
+}
+
+static bool stm32prog_is_stm32_header_v2(struct stm32_header_v2 *header)
+{
+ unsigned int i;
+
+ if (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;
+ __func__, header->magic_number);
+ return false;
}
- /* only header v1.0 supported */
- if (raw_header->header_version != 0x00010000) {
+ if (header->header_version != 0x00020000) {
log_debug("%s:invalid header version : 0x%x\n",
- __func__, raw_header->header_version);
+ __func__, header->header_version);
+ return false;
+ }
+ if (header->reserved1 || header->reserved2)
+ return false;
+
+ for (i = 0; i < sizeof(header->padding); i++) {
+ if (header->padding[i] != 0) {
+ log_debug("%s:invalid padding field\n", __func__);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void stm32prog_header_check(uintptr_t raw_header, struct image_header_s *header)
+{
+ struct stm32_header_v1 *v1_header = (struct stm32_header_v1 *)raw_header;
+ struct stm32_header_v2 *v2_header = (struct stm32_header_v2 *)raw_header;
+
+ if (!raw_header || !header) {
+ log_debug("%s:no header data\n", __func__);
return;
}
- if (raw_header->reserved1 != 0x0 || raw_header->reserved2) {
- log_debug("%s:invalid reserved field\n", __func__);
+
+ if (stm32prog_is_fip_header((struct fip_toc_header *)raw_header)) {
+ header->type = HEADER_FIP;
+ header->length = 0;
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;
- }
+ if (stm32prog_is_stm32_header_v1(v1_header)) {
+ header->type = HEADER_STM32IMAGE;
+ header->image_checksum = le32_to_cpu(v1_header->image_checksum);
+ header->image_length = le32_to_cpu(v1_header->image_length);
+ header->length = sizeof(struct stm32_header_v1);
+ return;
+ }
+ if (stm32prog_is_stm32_header_v2(v2_header)) {
+ header->type = HEADER_STM32IMAGE_V2;
+ header->image_checksum = le32_to_cpu(v2_header->image_checksum);
+ header->image_length = le32_to_cpu(v2_header->image_length);
+ header->length = sizeof(struct stm32_header_v1) +
+ v2_header->extension_headers_length;
+ return;
}
- 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;
+ header->type = HEADER_NONE;
+ header->image_checksum = 0x0;
+ header->image_length = 0x0;
}
static u32 stm32prog_header_checksum(u32 addr, struct image_header_s *header)
@@ -480,11 +526,11 @@ static int parse_flash_layout(struct stm32prog_data *data,
data->part_nb = 0;
/* check if STM32image is detected */
- stm32prog_header_check((struct raw_header_s *)addr, &header);
+ stm32prog_header_check(addr, &header);
if (header.type == HEADER_STM32IMAGE) {
u32 checksum;
- addr = addr + BL_HEADER_SIZE;
+ addr = addr + header.length;
size = header.image_length;
checksum = stm32prog_header_checksum(addr, &header);
@@ -1560,7 +1606,7 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part)
int ret, i;
void *fsbl;
struct image_header_s header;
- struct raw_header_s raw_header;
+ struct stm32_header_v2 raw_header; /* V2 size > v1 size */
struct dfu_entity *dfu;
long size, offset;
@@ -1572,17 +1618,18 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part)
/* read header */
dfu_transaction_cleanup(dfu);
- size = BL_HEADER_SIZE;
+ size = sizeof(raw_header);
ret = dfu->read_medium(dfu, 0, (void *)&raw_header, &size);
if (ret)
return ret;
- stm32prog_header_check(&raw_header, &header);
- if (header.type != HEADER_STM32IMAGE)
+ stm32prog_header_check((ulong)&raw_header, &header);
+ if (header.type != HEADER_STM32IMAGE &&
+ header.type != HEADER_STM32IMAGE_V2)
return -ENOENT;
/* read header + payload */
- size = header.image_length + BL_HEADER_SIZE;
+ size = header.image_length + header.length;
size = round_up(size, part->dev->mtd->erasesize);
fsbl = calloc(1, size);
if (!fsbl)