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