1 /* 2 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved 3 * 4 * SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause 5 */ 6 7 #include <image.h> 8 #include "imagetool.h" 9 10 /* magic ='S' 'T' 'M' 0x32 */ 11 #define HEADER_MAGIC be32_to_cpu(0x53544D32) 12 #define VER_MAJOR_IDX 2 13 #define VER_MINOR_IDX 1 14 #define VER_VARIANT_IDX 0 15 #define HEADER_VERSION_V1 0x1 16 /* default option : bit0 => no signature */ 17 #define HEADER_DEFAULT_OPTION (cpu_to_le32(0x00000001)) 18 19 struct stm32_header { 20 uint32_t magic_number; 21 uint32_t image_signature[64 / 4]; 22 uint32_t image_checksum; 23 uint8_t header_version[4]; 24 uint32_t image_length; 25 uint32_t image_entry_point; 26 uint32_t reserved1; 27 uint32_t load_address; 28 uint32_t reserved2; 29 uint32_t version_number; 30 uint32_t option_flags; 31 uint32_t ecdsa_algorithm; 32 uint32_t ecdsa_public_key[64 / 4]; 33 uint32_t padding[84 / 4]; 34 }; 35 36 static struct stm32_header stm32image_header; 37 38 static void stm32image_default_header(struct stm32_header *ptr) 39 { 40 if (!ptr) 41 return; 42 43 ptr->magic_number = HEADER_MAGIC; 44 ptr->header_version[VER_MAJOR_IDX] = HEADER_VERSION_V1; 45 ptr->option_flags = HEADER_DEFAULT_OPTION; 46 ptr->ecdsa_algorithm = 1; 47 } 48 49 static uint32_t stm32image_checksum(void *start, uint32_t len) 50 { 51 uint32_t csum = 0; 52 uint32_t hdr_len = sizeof(struct stm32_header); 53 uint8_t *p; 54 55 if (len < hdr_len) 56 return 0; 57 58 p = start + hdr_len; 59 len -= hdr_len; 60 61 while (len > 0) { 62 csum += *p; 63 p++; 64 len--; 65 } 66 67 return csum; 68 } 69 70 static int stm32image_check_image_types(uint8_t type) 71 { 72 if (type == IH_TYPE_STM32IMAGE) 73 return EXIT_SUCCESS; 74 return EXIT_FAILURE; 75 } 76 77 static int stm32image_verify_header(unsigned char *ptr, int image_size, 78 struct image_tool_params *params) 79 { 80 struct stm32_header *stm32hdr = (struct stm32_header *)ptr; 81 int i; 82 83 if (image_size < sizeof(struct stm32_header)) 84 return -1; 85 if (stm32hdr->magic_number != HEADER_MAGIC) 86 return -1; 87 if (stm32hdr->header_version[VER_MAJOR_IDX] != HEADER_VERSION_V1) 88 return -1; 89 if (stm32hdr->reserved1 || stm32hdr->reserved2) 90 return -1; 91 for (i = 0; i < (sizeof(stm32hdr->padding) / 4); i++) { 92 if (stm32hdr->padding[i] != 0) 93 return -1; 94 } 95 96 return 0; 97 } 98 99 static void stm32image_print_header(const void *ptr) 100 { 101 struct stm32_header *stm32hdr = (struct stm32_header *)ptr; 102 103 printf("Image Type : STMicroelectronics STM32 V%d.%d\n", 104 stm32hdr->header_version[VER_MAJOR_IDX], 105 stm32hdr->header_version[VER_MINOR_IDX]); 106 printf("Image Size : %lu bytes\n", 107 (unsigned long)le32_to_cpu(stm32hdr->image_length)); 108 printf("Image Load : 0x%08x\n", 109 le32_to_cpu(stm32hdr->load_address)); 110 printf("Entry Point : 0x%08x\n", 111 le32_to_cpu(stm32hdr->image_entry_point)); 112 printf("Checksum : 0x%08x\n", 113 le32_to_cpu(stm32hdr->image_checksum)); 114 printf("Option : 0x%08x\n", 115 le32_to_cpu(stm32hdr->option_flags)); 116 } 117 118 static void stm32image_set_header(void *ptr, struct stat *sbuf, int ifd, 119 struct image_tool_params *params) 120 { 121 struct stm32_header *stm32hdr = (struct stm32_header *)ptr; 122 123 stm32image_default_header(stm32hdr); 124 125 stm32hdr->load_address = cpu_to_le32(params->addr); 126 stm32hdr->image_entry_point = cpu_to_le32(params->ep); 127 stm32hdr->image_length = cpu_to_le32((uint32_t)sbuf->st_size - 128 sizeof(struct stm32_header)); 129 stm32hdr->image_checksum = stm32image_checksum(ptr, sbuf->st_size); 130 } 131 132 /* 133 * stm32image parameters 134 */ 135 U_BOOT_IMAGE_TYPE( 136 stm32image, 137 "STMicroelectronics STM32MP Image support", 138 sizeof(struct stm32_header), 139 (void *)&stm32image_header, 140 NULL, 141 stm32image_verify_header, 142 stm32image_print_header, 143 stm32image_set_header, 144 NULL, 145 stm32image_check_image_types, 146 NULL, 147 NULL 148 ); 149