1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2015 Google, Inc 4 * Written by Simon Glass <sjg@chromium.org> 5 * 6 * (C) 2017 Theobroma Systems Design und Consulting GmbH 7 * 8 * Helper functions for Rockchip images 9 */ 10 11 #include "imagetool.h" 12 #include <image.h> 13 #include <rc4.h> 14 #include "mkimage.h" 15 #include "rkcommon.h" 16 17 #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) 18 19 enum { 20 RK_SIGNATURE = 0x0ff0aa55, 21 }; 22 23 /** 24 * struct header0_info - header block for boot ROM 25 * 26 * This is stored at SD card block 64 (where each block is 512 bytes, or at 27 * the start of SPI flash. It is encoded with RC4. 28 * 29 * @signature: Signature (must be RKSD_SIGNATURE) 30 * @disable_rc4: 0 to use rc4 for boot image, 1 to use plain binary 31 * @init_offset: Offset in blocks of the SPL code from this header 32 * block. E.g. 4 means 2KB after the start of this header. 33 * Other fields are not used by U-Boot 34 */ 35 struct header0_info { 36 uint32_t signature; 37 uint8_t reserved[4]; 38 uint32_t disable_rc4; 39 uint16_t init_offset; 40 uint8_t reserved1[492]; 41 uint16_t init_size; 42 uint16_t init_boot_size; 43 uint8_t reserved2[2]; 44 }; 45 46 /** 47 * struct header1_info 48 */ 49 struct header1_info { 50 uint32_t magic; 51 }; 52 53 /** 54 * struct spl_info - spl info for each chip 55 * 56 * @imagename: Image name(passed by "mkimage -n") 57 * @spl_hdr: Boot ROM requires a 4-bytes spl header 58 * @spl_size: Spl size(include extra 4-bytes spl header) 59 * @spl_rc4: RC4 encode the SPL binary (same key as header) 60 */ 61 62 struct spl_info { 63 const char *imagename; 64 const char *spl_hdr; 65 const uint32_t spl_size; 66 const bool spl_rc4; 67 }; 68 69 static struct spl_info spl_infos[] = { 70 { "rk3036", "RK30", 0x1000, false }, 71 { "rk3128", "RK31", 0x1800, false }, 72 { "rk3188", "RK31", 0x8000 - 0x800, true }, 73 { "rk322x", "RK32", 0x8000 - 0x1000, false }, 74 { "rk3288", "RK32", 0x8000, false }, 75 { "rk3328", "RK32", 0x8000 - 0x1000, false }, 76 { "rk3368", "RK33", 0x8000 - 0x1000, false }, 77 { "rk3399", "RK33", 0x30000 - 0x2000, false }, 78 { "rv1108", "RK11", 0x1800, false }, 79 }; 80 81 static unsigned char rc4_key[16] = { 82 124, 78, 3, 4, 85, 5, 9, 7, 83 45, 44, 123, 56, 23, 13, 23, 17 84 }; 85 86 static struct spl_info *rkcommon_get_spl_info(char *imagename) 87 { 88 int i; 89 90 if (!imagename) 91 return NULL; 92 93 for (i = 0; i < ARRAY_SIZE(spl_infos); i++) 94 if (!strncmp(imagename, spl_infos[i].imagename, 6)) 95 return spl_infos + i; 96 97 return NULL; 98 } 99 100 int rkcommon_check_params(struct image_tool_params *params) 101 { 102 int i; 103 104 if (rkcommon_get_spl_info(params->imagename) != NULL) 105 return EXIT_SUCCESS; 106 107 /* 108 * If this is a operation (list or extract), the don't require 109 * imagename to be set. 110 */ 111 if (params->lflag || params->iflag) 112 return EXIT_SUCCESS; 113 114 fprintf(stderr, "ERROR: imagename (%s) is not supported!\n", 115 params->imagename ? params->imagename : "NULL"); 116 117 fprintf(stderr, "Available imagename:"); 118 for (i = 0; i < ARRAY_SIZE(spl_infos); i++) 119 fprintf(stderr, "\t%s", spl_infos[i].imagename); 120 fprintf(stderr, "\n"); 121 122 return EXIT_FAILURE; 123 } 124 125 const char *rkcommon_get_spl_hdr(struct image_tool_params *params) 126 { 127 struct spl_info *info = rkcommon_get_spl_info(params->imagename); 128 129 /* 130 * info would not be NULL, because of we checked params before. 131 */ 132 return info->spl_hdr; 133 } 134 135 136 int rkcommon_get_spl_size(struct image_tool_params *params) 137 { 138 struct spl_info *info = rkcommon_get_spl_info(params->imagename); 139 140 /* 141 * info would not be NULL, because of we checked params before. 142 */ 143 return info->spl_size; 144 } 145 146 bool rkcommon_need_rc4_spl(struct image_tool_params *params) 147 { 148 struct spl_info *info = rkcommon_get_spl_info(params->imagename); 149 150 /* 151 * info would not be NULL, because of we checked params before. 152 */ 153 return info->spl_rc4; 154 } 155 156 static void rkcommon_set_header0(void *buf, uint file_size, 157 struct image_tool_params *params) 158 { 159 struct header0_info *hdr = buf; 160 161 memset(buf, '\0', RK_INIT_OFFSET * RK_BLK_SIZE); 162 hdr->signature = RK_SIGNATURE; 163 hdr->disable_rc4 = !rkcommon_need_rc4_spl(params); 164 hdr->init_offset = RK_INIT_OFFSET; 165 166 hdr->init_size = DIV_ROUND_UP(file_size, RK_BLK_SIZE); 167 /* 168 * The init_size has to be a multiple of 4 blocks (i.e. of 2K) 169 * or the BootROM will not boot the image. 170 * 171 * Note: To verify that this is not a legacy constraint, we 172 * rechecked this against the RK3399 BootROM. 173 */ 174 hdr->init_size = ROUND(hdr->init_size, 4); 175 /* 176 * init_boot_size needs to be set, as it is read by the BootROM 177 * to determine the size of the next-stage bootloader (e.g. U-Boot 178 * proper), when used with the back-to-bootrom functionality. 179 * 180 * see https://lists.denx.de/pipermail/u-boot/2017-May/293267.html 181 * for a more detailed explanation by Andy Yan 182 */ 183 hdr->init_boot_size = hdr->init_size + RK_MAX_BOOT_SIZE / RK_BLK_SIZE; 184 185 rc4_encode(buf, RK_BLK_SIZE, rc4_key); 186 } 187 188 int rkcommon_set_header(void *buf, uint file_size, 189 struct image_tool_params *params) 190 { 191 struct header1_info *hdr = buf + RK_SPL_HDR_START; 192 193 if (file_size > rkcommon_get_spl_size(params)) 194 return -ENOSPC; 195 196 rkcommon_set_header0(buf, file_size, params); 197 198 /* Set up the SPL name (i.e. copy spl_hdr over) */ 199 memcpy(&hdr->magic, rkcommon_get_spl_hdr(params), RK_SPL_HDR_SIZE); 200 201 if (rkcommon_need_rc4_spl(params)) 202 rkcommon_rc4_encode_spl(buf, RK_SPL_HDR_START, 203 params->file_size - RK_SPL_HDR_START); 204 205 return 0; 206 } 207 208 static inline unsigned rkcommon_offset_to_spi(unsigned offset) 209 { 210 /* 211 * While SD/MMC images use a flat addressing, SPI images are padded 212 * to use the first 2K of every 4K sector only. 213 */ 214 return ((offset & ~0x7ff) << 1) + (offset & 0x7ff); 215 } 216 217 static int rkcommon_parse_header(const void *buf, struct header0_info *header0, 218 struct spl_info **spl_info) 219 { 220 unsigned hdr1_offset; 221 struct header1_info *hdr1_sdmmc, *hdr1_spi; 222 int i; 223 224 if (spl_info) 225 *spl_info = NULL; 226 227 /* 228 * The first header (hdr0) is always RC4 encoded, so try to decrypt 229 * with the well-known key. 230 */ 231 memcpy((void *)header0, buf, sizeof(struct header0_info)); 232 rc4_encode((void *)header0, sizeof(struct header0_info), rc4_key); 233 234 if (header0->signature != RK_SIGNATURE) 235 return -EPROTO; 236 237 /* We don't support RC4 encoded image payloads here, yet... */ 238 if (header0->disable_rc4 == 0) 239 return -ENOSYS; 240 241 hdr1_offset = header0->init_offset * RK_BLK_SIZE; 242 hdr1_sdmmc = (struct header1_info *)(buf + hdr1_offset); 243 hdr1_spi = (struct header1_info *)(buf + 244 rkcommon_offset_to_spi(hdr1_offset)); 245 246 for (i = 0; i < ARRAY_SIZE(spl_infos); i++) { 247 if (!memcmp(&hdr1_sdmmc->magic, spl_infos[i].spl_hdr, 4)) { 248 if (spl_info) 249 *spl_info = &spl_infos[i]; 250 return IH_TYPE_RKSD; 251 } else if (!memcmp(&hdr1_spi->magic, spl_infos[i].spl_hdr, 4)) { 252 if (spl_info) 253 *spl_info = &spl_infos[i]; 254 return IH_TYPE_RKSPI; 255 } 256 } 257 258 return -1; 259 } 260 261 int rkcommon_verify_header(unsigned char *buf, int size, 262 struct image_tool_params *params) 263 { 264 struct header0_info header0; 265 struct spl_info *img_spl_info, *spl_info; 266 int ret; 267 268 ret = rkcommon_parse_header(buf, &header0, &img_spl_info); 269 270 /* If this is the (unimplemented) RC4 case, then rewrite the result */ 271 if (ret == -ENOSYS) 272 return 0; 273 274 if (ret < 0) 275 return ret; 276 277 /* 278 * If no 'imagename' is specified via the commandline (e.g. if this is 279 * 'dumpimage -l' w/o any further constraints), we accept any spl_info. 280 */ 281 if (params->imagename == NULL) 282 return 0; 283 284 /* Match the 'imagename' against the 'spl_hdr' found */ 285 spl_info = rkcommon_get_spl_info(params->imagename); 286 if (spl_info && img_spl_info) 287 return strcmp(spl_info->spl_hdr, img_spl_info->spl_hdr); 288 289 return -ENOENT; 290 } 291 292 void rkcommon_print_header(const void *buf) 293 { 294 struct header0_info header0; 295 struct spl_info *spl_info; 296 uint8_t image_type; 297 int ret; 298 299 ret = rkcommon_parse_header(buf, &header0, &spl_info); 300 301 /* If this is the (unimplemented) RC4 case, then fail silently */ 302 if (ret == -ENOSYS) 303 return; 304 305 if (ret < 0) { 306 fprintf(stderr, "Error: image verification failed\n"); 307 return; 308 } 309 310 image_type = ret; 311 312 printf("Image Type: Rockchip %s (%s) boot image\n", 313 spl_info->spl_hdr, 314 (image_type == IH_TYPE_RKSD) ? "SD/MMC" : "SPI"); 315 printf("Data Size: %d bytes\n", header0.init_size * RK_BLK_SIZE); 316 } 317 318 void rkcommon_rc4_encode_spl(void *buf, unsigned int offset, unsigned int size) 319 { 320 unsigned int remaining = size; 321 322 while (remaining > 0) { 323 int step = (remaining > RK_BLK_SIZE) ? RK_BLK_SIZE : remaining; 324 325 rc4_encode(buf + offset, step, rc4_key); 326 offset += RK_BLK_SIZE; 327 remaining -= step; 328 } 329 } 330 331 int rkcommon_vrec_header(struct image_tool_params *params, 332 struct image_type_params *tparams, 333 unsigned int alignment) 334 { 335 unsigned int unpadded_size; 336 unsigned int padded_size; 337 338 /* 339 * The SPL image looks as follows: 340 * 341 * 0x0 header0 (see rkcommon.c) 342 * 0x800 spl_name ('RK30', ..., 'RK33') 343 * (start of the payload for AArch64 payloads: we expect the 344 * first 4 bytes to be available for overwriting with our 345 * spl_name) 346 * 0x804 first instruction to be executed 347 * (start of the image/payload for 32bit payloads) 348 * 349 * For AArch64 (ARMv8) payloads, natural alignment (8-bytes) is 350 * required for its sections (so the image we receive needs to 351 * have the first 4 bytes reserved for the spl_name). Reserving 352 * these 4 bytes is done using the BOOT0_HOOK infrastructure. 353 * 354 * The header is always at 0x800 (as we now use a payload 355 * prepadded using the boot0 hook for all targets): the first 356 * 4 bytes of these images can safely be overwritten using the 357 * boot magic. 358 */ 359 tparams->header_size = RK_SPL_HDR_START; 360 361 /* Allocate, clear and install the header */ 362 tparams->hdr = malloc(tparams->header_size); 363 if (!tparams->hdr) 364 return -ENOMEM; 365 memset(tparams->hdr, 0, tparams->header_size); 366 367 /* 368 * If someone passed in 0 for the alignment, we'd better handle 369 * it correctly... 370 */ 371 if (!alignment) 372 alignment = 1; 373 374 unpadded_size = tparams->header_size + params->file_size; 375 padded_size = ROUND(unpadded_size, alignment); 376 377 return padded_size - unpadded_size; 378 } 379