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