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