xref: /rk3399_rockchip-uboot/common/spl/spl_rkfw.c (revision a4933f72a5253a046dbe775dd49917ac4e5ca5f2)
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