1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd 4 */ 5 6 #include <common.h> 7 #include <android_image.h> 8 #include <errno.h> 9 #include <malloc.h> 10 #include <spl_rkfw.h> 11 #include <linux/kernel.h> 12 #include <asm/arch/spl_resource_img.h> 13 14 #ifdef CONFIG_SPL_ATF 15 static const __aligned(16) struct s_fip_name_id fip_name_id[] = { 16 { BL30_IMAGE_NAME, UUID_SCP_FIRMWARE_BL30 }, /* optional */ 17 { BL31_IMAGE_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31 }, /* mandatory */ 18 { BL32_IMAGE_NAME, UUID_SECURE_PAYLOAD_BL32 }, /* optional */ 19 }; 20 21 static int file2comp_id(const char *file_name, u32 *comp_id) 22 { 23 int i; 24 25 for (i = 0; i < ARRAY_SIZE(fip_name_id); i++) { 26 if (!strcmp(file_name, fip_name_id[i].name)) { 27 *comp_id = fip_name_id[i].id; 28 return 0; 29 } 30 } 31 32 return -ENOENT; 33 } 34 35 static int open_image(const char *image_name, tboot_entry *entry, 36 struct tag_tboot_header_2k *hdr) 37 { 38 u32 i, component_num, sign_offset; 39 component_data *pcompdata; 40 boot_component *pcomp; 41 int n_found = 0; 42 u32 comp_id; 43 int ret; 44 45 ret = file2comp_id(image_name, &comp_id); 46 if (ret) { 47 printf("Can't find unknown image: %s\n", image_name); 48 return ret; 49 } 50 51 component_num = (hdr->size >> 16) & 0xffff; 52 sign_offset = (hdr->size & 0xffff) << 2; 53 pcompdata = (component_data *)((char *)hdr + sizeof(tboot_header)); 54 pcomp = (boot_component *)((char *)hdr + sign_offset + SIGNATURE_SIZE); 55 56 for (i = 0; i < component_num; i++) { 57 if (comp_id == pcomp->component_id) { 58 if (n_found < MAX_BL_CODE_NUM) { 59 memcpy(&entry[n_found].component, pcomp, 60 sizeof(boot_component)); 61 memcpy(&entry[n_found].compdata, pcompdata, 62 sizeof(component_data)); 63 n_found++; 64 } else { 65 printf("Image num excess max: %d!\n", 66 MAX_BL_CODE_NUM); 67 return -EINVAL; 68 } 69 } else { 70 if (n_found > 0) 71 break; 72 } 73 74 pcomp++; 75 pcompdata++; 76 } 77 78 if (!n_found) { 79 printf("No find %s\n", image_name); 80 return -ENONET; 81 } 82 83 return n_found; 84 } 85 86 static int check_image(struct tag_tboot_header_2k *hdr) 87 { 88 u32 hash_format[] = { 0, 160, 256, 256 }; 89 90 /* HASH format identifier */ 91 return (hash_format[hdr->flags & 0x3] == 0) ? -EINVAL : 0; 92 } 93 94 static int load_image(struct spl_load_info *info, 95 struct tag_tboot_header_2k *hdr, 96 u32 image_sector, 97 const char *image_name, 98 uintptr_t *entry_point) 99 { 100 tboot_entry entry[MAX_BL_CODE_NUM]; 101 void *image_buf = NULL; 102 ulong load_addr; 103 u32 sect_off; 104 u32 sect_cnt; 105 int image_num; 106 int i, ret; 107 108 /* Parse components from image header */ 109 image_num = open_image(image_name, entry, hdr); 110 if (image_num < 0) 111 return image_num; 112 113 /* Get all component */ 114 for (i = 0; i < image_num; i++) { 115 load_addr = entry[i].compdata.load_addr; 116 sect_cnt = entry[i].component.image_size; 117 sect_off = entry[i].component.storage_addr; 118 119 printf("%s[%d]: addr=0x%lx, size=0x%lx\n", 120 image_name, i, load_addr, (ulong)sect_cnt * 512); 121 122 /* 123 * MMC/NAND controller DMA can't access sram region, so: 124 * data -> ddr buffer -> memcpy to sram region. 125 */ 126 if (load_addr < CONFIG_SYS_SDRAM_BASE || 127 load_addr >= CONFIG_SYS_SDRAM_BASE + SDRAM_MAX_SIZE) { 128 image_buf = memalign(ARCH_DMA_MINALIGN, sect_cnt * 512); 129 if (!image_buf) { 130 printf("%s: malloc failed\n", __func__); 131 return -ENOMEM; 132 } 133 } else { 134 image_buf = (void *)load_addr; 135 } 136 137 ret = info->read(info, image_sector + sect_off, 138 sect_cnt, image_buf); 139 if (ret != sect_cnt) { 140 printf("Read '%s' failed at sector: %ld, ret=%d\n", 141 image_name, (ulong)image_sector + sect_off, ret); 142 return -EIO; 143 } 144 145 /* Verify component */ 146 ret = check_image(hdr); 147 if (ret) { 148 printf("%s[%d]: verify image fail!\n", image_name, i); 149 return ret; 150 } 151 152 /* Handle sram region */ 153 if ((ulong)image_buf != load_addr) { 154 memcpy((void *)load_addr, image_buf, sect_cnt << 9); 155 free(image_buf); 156 } 157 158 /* Fill entry_point by first component */ 159 if (i == 0) 160 *entry_point = (uintptr_t)load_addr; 161 } 162 163 return ret; 164 } 165 166 static int rkfw_load_trust(struct spl_load_info *info, u32 image_sector, 167 struct spl_image_info *spl_image, 168 int *found_rkfw, u32 try_count) 169 { 170 struct tag_tboot_header_2k hdr; 171 u32 sect_addr = image_sector; 172 int blkcnt = 4; /* header sectors, 2KB */ 173 int i, ret = 0; 174 175 /* Find valid image header */ 176 for (i = 0; i < try_count; i++) { 177 sect_addr = image_sector + (i * RKFW_RETRY_SECTOR_SIZE); 178 if (blkcnt != info->read(info, sect_addr, blkcnt, &hdr)) 179 continue; 180 181 if (hdr.tag == TBOOT_HEAD_TAG) { 182 /* Mark it */ 183 *found_rkfw = 1; 184 185 /* bl31 is mandatory */ 186 ret = load_image(info, &hdr, sect_addr, 187 BL31_IMAGE_NAME, &spl_image->entry_point); 188 if (ret) 189 continue; 190 191 /* bl32 is optional */ 192 ret = load_image(info, &hdr, sect_addr, 193 BL32_IMAGE_NAME, &spl_image->entry_point_bl32); 194 if (ret) { 195 if (ret == -ENONET) { 196 spl_image->entry_point_bl32 = -1; /* Not exist */ 197 ret = 0; 198 } else { 199 continue; 200 } 201 } 202 break; 203 } 204 } 205 206 return ret; 207 } 208 #else 209 static int rkfw_load_trust(struct spl_load_info *info, u32 image_sector, 210 struct spl_image_info *spl_image, 211 int *found_rkfw, u32 try_count) 212 { 213 struct tag_second_loader_hdr hdr; 214 int i, ret, blkcnt = 4; /* header sectors, 2KB */ 215 char *load_addr; 216 u32 sect_addr; 217 218 /* Detect valid image header */ 219 for (i = 0; i < try_count; i++) { 220 sect_addr = image_sector + (i * RKFW_RETRY_SECTOR_SIZE); 221 ret = info->read(info, sect_addr, blkcnt, &hdr); 222 if (ret != blkcnt) 223 continue; 224 225 if (!memcmp(hdr.magic, TBOOT_HEAD_TAG, 6)) { 226 *found_rkfw = 1; 227 spl_image->entry_point = (uintptr_t)hdr.loader_load_addr; 228 /* Load full binary image(right behind header) */ 229 sect_addr += blkcnt; 230 load_addr = (char *)((size_t)hdr.loader_load_addr); 231 blkcnt = DIV_ROUND_UP(hdr.loader_load_size, 512); 232 233 printf("tee.bin: addr=0x%lx, size=0x%lx\n", 234 (ulong)load_addr, (ulong)blkcnt * 512); 235 ret = info->read(info, sect_addr, blkcnt, load_addr); 236 if (ret != blkcnt) 237 continue; 238 239 break; 240 } 241 } 242 243 if (i == try_count) { 244 printf("Can not find usable uboot\n"); 245 return -ENONET; 246 } 247 248 return 0; 249 } 250 #endif 251 252 static int rkfw_load_uboot(struct spl_load_info *info, u32 image_sector, 253 struct spl_image_info *spl_image, u32 try_count) 254 { 255 struct tag_second_loader_hdr hdr; 256 int i, ret, blkcnt = 4; /* header sectors, 2KB */ 257 char *load_addr; 258 u32 sect_addr; 259 260 /* Detect valid image header */ 261 for (i = 0; i < try_count; i++) { 262 sect_addr = image_sector + (i * RKFW_RETRY_SECTOR_SIZE); 263 ret = info->read(info, sect_addr, blkcnt, &hdr); 264 if (ret != blkcnt) 265 continue; 266 267 if (!memcmp(hdr.magic, LOADER_HARD_STR, 6)) { 268 /* Load full binary image(right behind header) */ 269 sect_addr += blkcnt; 270 load_addr = (char *)((size_t)hdr.loader_load_addr); 271 blkcnt = DIV_ROUND_UP(hdr.loader_load_size, 512); 272 273 printf("u-boot.bin: addr=0x%lx, size=0x%lx\n", 274 (ulong)load_addr, (ulong)blkcnt * 512); 275 ret = info->read(info, sect_addr, blkcnt, load_addr); 276 if (ret != blkcnt) 277 continue; 278 279 break; 280 } 281 } 282 283 if (i == try_count) { 284 printf("Can not find usable uboot\n"); 285 return -ENONET; 286 } 287 288 /* Fill entry point */ 289 #ifdef CONFIG_SPL_ATF 290 spl_image->entry_point_bl33 = (uintptr_t)hdr.loader_load_addr; 291 #endif 292 #ifdef CONFIG_SPL_OPTEE 293 spl_image->entry_point_os = (uintptr_t)hdr.loader_load_addr; 294 #endif 295 return 0; 296 } 297 298 static int rkfw_load_kernel(struct spl_load_info *info, u32 image_sector, 299 struct spl_image_info *spl_image, u32 try_count) 300 { 301 struct andr_img_hdr *hdr; 302 int ret, cnt; 303 int dtb_sector, ramdisk_sector, resource_sector; 304 305 cnt = ALIGN(sizeof(struct andr_img_hdr), 512) >> 9; 306 hdr = malloc(cnt * 512); 307 if (!hdr) 308 return -ENOMEM; 309 310 ret = info->read(info, image_sector, cnt, (void *)hdr); 311 if (ret != cnt) { 312 ret = -EIO; 313 goto out; 314 } 315 316 if (memcmp(hdr->magic, ANDR_BOOT_MAGIC, strlen(ANDR_BOOT_MAGIC)) != 0) { 317 printf("SPL: boot image head magic error\n"); 318 ret = -EINVAL; 319 goto out; 320 } 321 322 ramdisk_sector = ALIGN(hdr->kernel_size, hdr->page_size); 323 resource_sector = ALIGN(hdr->kernel_size, hdr->page_size) 324 + ALIGN(hdr->ramdisk_size, hdr->page_size); 325 dtb_sector = ALIGN(hdr->kernel_size, hdr->page_size) 326 + ALIGN(hdr->ramdisk_size, hdr->page_size) 327 + ALIGN(hdr->second_size, hdr->page_size); 328 image_sector = image_sector + cnt; 329 cnt = ALIGN(hdr->kernel_size, hdr->page_size) >> 9; 330 331 /* Load kernel image */ 332 ret = info->read(info, image_sector, cnt, (void *)CONFIG_SPL_KERNEL_ADDR); 333 if (ret != cnt) { 334 ret = -EIO; 335 goto out; 336 } 337 338 /* Load ramdisk image */ 339 if (hdr->ramdisk_size) { 340 ret = info->read(info, (ramdisk_sector >> 9) + image_sector, 341 ALIGN(hdr->ramdisk_size, hdr->page_size) >> 9, 342 (void *)CONFIG_SPL_RAMDISK_ADDR); 343 if (ret != (ALIGN(hdr->ramdisk_size, hdr->page_size) >> 9)) { 344 ret = -EIO; 345 goto out; 346 } 347 } 348 349 /* Load resource, and checkout the dtb */ 350 if (hdr->second_size) { 351 struct resource_img_hdr *head = 352 (struct resource_img_hdr *)(CONFIG_SPL_FDT_ADDR + 0x100000); 353 354 ret = info->read(info, (resource_sector >> 9) + image_sector, 355 ALIGN(hdr->second_size, hdr->page_size) >> 9, 356 (void *)head); 357 if (ret != (ALIGN(hdr->second_size, hdr->page_size) >> 9)) { 358 ret = -EIO; 359 goto out; 360 } 361 #ifdef CONFIG_SPL_KERNEL_BOOT 362 if (spl_resource_image_check_header(head)) { 363 printf("Can't find kernel dtb in spl."); 364 } else { 365 struct resource_entry *entry; 366 char *dtb_temp; 367 368 entry = spl_resource_image_get_dtb_entry(head); 369 if (!entry) { 370 ret = -EIO; 371 goto out; 372 } 373 374 dtb_temp = (char *)((char *)head + entry->f_offset * 512); 375 memcpy((char *)CONFIG_SPL_FDT_ADDR, dtb_temp, 376 entry->f_size); 377 } 378 #endif 379 } else { 380 /* Load dtb image */ 381 ret = info->read(info, (dtb_sector >> 9) + image_sector, 382 ALIGN(hdr->dtb_size, hdr->page_size) >> 9, 383 (void *)CONFIG_SPL_FDT_ADDR); 384 if (ret != (ALIGN(hdr->dtb_size, hdr->page_size) >> 9)) { 385 ret = -EIO; 386 goto out; 387 } 388 } 389 390 spl_image->fdt_addr = (void *)CONFIG_SPL_FDT_ADDR; 391 #ifdef CONFIG_SPL_OPTEE 392 spl_image->entry_point_os = (uintptr_t)CONFIG_SPL_KERNEL_ADDR; 393 #endif 394 #ifdef CONFIG_SPL_ATF 395 spl_image->entry_point_bl33 = CONFIG_SPL_KERNEL_ADDR; 396 #endif 397 ret = 0; 398 out: 399 free(hdr); 400 401 return ret; 402 } 403 404 int spl_load_rkfw_image(struct spl_image_info *spl_image, 405 struct spl_load_info *info, 406 u32 trust_sector, u32 uboot_sector) 407 { 408 int ret, try_count = RKFW_RETRY_SECTOR_TIMES; 409 int found_rkfw = 0; 410 411 ret = rkfw_load_trust(info, trust_sector, spl_image, 412 &found_rkfw, try_count); 413 if (ret) { 414 printf("Load trust image failed! ret=%d\n", ret); 415 goto out; 416 } 417 418 ret = rkfw_load_uboot(info, uboot_sector, 419 spl_image, try_count); 420 if (ret) 421 printf("Load uboot image failed! ret=%d\n", ret); 422 else 423 goto boot; 424 425 ret = rkfw_load_kernel(info, uboot_sector, 426 spl_image, try_count); 427 if (ret) { 428 printf("Load kernel image failed! ret=%d\n", ret); 429 goto out; 430 } 431 432 boot: 433 #if CONFIG_IS_ENABLED(LOAD_FIT) 434 spl_image->fdt_addr = 0; 435 #endif 436 #ifdef CONFIG_SPL_ATF 437 spl_image->os = IH_OS_ARM_TRUSTED_FIRMWARE; 438 #else 439 spl_image->os = IH_OS_OP_TEE; 440 #endif 441 442 out: 443 /* If not found rockchip firmware, try others outside */ 444 return found_rkfw ? ret : -EAGAIN; 445 } 446