• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2019 NXP
4  */
5 
6 #include <common.h>
7 #include <errno.h>
8 #include <image.h>
9 #include <linux/libfdt.h>
10 #include <spl.h>
11 
12 #include <asm/arch/sys_proto.h>
13 
14 DECLARE_GLOBAL_DATA_PTR;
15 
is_boot_from_stream_device(u32 boot)16 static int is_boot_from_stream_device(u32 boot)
17 {
18 	u32 interface;
19 
20 	interface = boot >> 16;
21 	if (interface >= BT_DEV_TYPE_USB)
22 		return 1;
23 
24 	if (interface == BT_DEV_TYPE_MMC && (boot & 1))
25 		return 1;
26 
27 	return 0;
28 }
29 
spl_romapi_read_seekable(struct spl_load_info * load,ulong sector,ulong count,void * buf)30 static ulong spl_romapi_read_seekable(struct spl_load_info *load,
31 				      ulong sector, ulong count,
32 				      void *buf)
33 {
34 	u32 pagesize = *(u32 *)load->priv;
35 	volatile gd_t *pgd = gd;
36 	ulong byte = count * pagesize;
37 	int ret;
38 	u32 offset;
39 
40 	offset = sector * pagesize;
41 
42 	debug("ROM API load from 0x%x, size 0x%x\n", offset, (u32)byte);
43 
44 	ret = g_rom_api->download_image(buf, offset, byte,
45 					((uintptr_t)buf) ^ offset ^ byte);
46 	gd = pgd;
47 
48 	if (ret == ROM_API_OKAY)
49 		return count;
50 
51 	printf("ROM API Failure when load 0x%x\n", offset);
52 
53 	return 0;
54 }
55 
spl_romapi_load_image_seekable(struct spl_image_info * spl_image,struct spl_boot_device * bootdev,u32 rom_bt_dev)56 static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image,
57 					  struct spl_boot_device *bootdev,
58 					  u32 rom_bt_dev)
59 {
60 	volatile gd_t *pgd = gd;
61 	int ret;
62 	u32 offset;
63 	u32 pagesize, size;
64 	struct image_header *header;
65 	u32 image_offset;
66 
67 	ret = g_rom_api->query_boot_infor(QUERY_IVT_OFF, &offset,
68 					  ((uintptr_t)&offset) ^ QUERY_IVT_OFF);
69 	ret |= g_rom_api->query_boot_infor(QUERY_PAGE_SZ, &pagesize,
70 					   ((uintptr_t)&pagesize) ^ QUERY_PAGE_SZ);
71 	ret |= g_rom_api->query_boot_infor(QUERY_IMG_OFF, &image_offset,
72 					   ((uintptr_t)&image_offset) ^ QUERY_IMG_OFF);
73 
74 	gd = pgd;
75 
76 	if (ret != ROM_API_OKAY) {
77 		puts("ROMAPI: Failure query boot infor pagesize/offset\n");
78 		return -1;
79 	}
80 
81 	header = (struct image_header *)(CONFIG_SPL_IMX_ROMAPI_LOADADDR);
82 
83 	printf("image offset 0x%x, pagesize 0x%x, ivt offset 0x%x\n",
84 	       image_offset, pagesize, offset);
85 
86 	if (((rom_bt_dev >> 16) & 0xff) ==  BT_DEV_TYPE_FLEXSPINOR)
87 		offset = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512;
88 	else
89 		offset = image_offset +
90 			CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512 - 0x8000;
91 
92 	size = ALIGN(sizeof(struct image_header), pagesize);
93 	ret = g_rom_api->download_image((u8 *)header, offset, size,
94 					((uintptr_t)header) ^ offset ^ size);
95 	gd = pgd;
96 
97 	if (ret != ROM_API_OKAY) {
98 		printf("ROMAPI: download failure offset 0x%x size 0x%x\n",
99 		       offset, size);
100 		return -1;
101 	}
102 
103 	if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
104 	    image_get_magic(header) == FDT_MAGIC) {
105 		struct spl_load_info load;
106 
107 		memset(&load, 0, sizeof(load));
108 		load.bl_len = pagesize;
109 		load.read = spl_romapi_read_seekable;
110 		load.priv = &pagesize;
111 		return spl_load_simple_fit(spl_image, &load,
112 					   offset / pagesize, header);
113 	} else {
114 		/* TODO */
115 		puts("Can't support legacy image\n");
116 		return -1;
117 	}
118 
119 	return 0;
120 }
121 
spl_ram_load_read(struct spl_load_info * load,ulong sector,ulong count,void * buf)122 static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector,
123 			       ulong count, void *buf)
124 {
125 	memcpy(buf, (void *)(sector), count);
126 
127 	if (load->priv) {
128 		ulong *p = (ulong *)load->priv;
129 		ulong total = sector + count;
130 
131 		if (total > *p)
132 			*p = total;
133 	}
134 
135 	return count;
136 }
137 
get_fit_image_size(void * fit)138 static ulong get_fit_image_size(void *fit)
139 {
140 	struct spl_image_info spl_image;
141 	struct spl_load_info spl_load_info;
142 	ulong last = (ulong)fit;
143 
144 	memset(&spl_load_info, 0, sizeof(spl_load_info));
145 	spl_load_info.bl_len = 1;
146 	spl_load_info.read = spl_ram_load_read;
147 	spl_load_info.priv = &last;
148 
149 	spl_load_simple_fit(&spl_image, &spl_load_info,
150 			    (uintptr_t)fit, fit);
151 
152 	return last - (ulong)fit;
153 }
154 
search_fit_header(u8 * p,int size)155 u8 *search_fit_header(u8 *p, int size)
156 {
157 	int i;
158 
159 	for (i = 0; i < size; i += 4)
160 		if (genimg_get_format(p + i) == IMAGE_FORMAT_FIT)
161 			return p + i;
162 
163 	return NULL;
164 }
165 
spl_romapi_load_image_stream(struct spl_image_info * spl_image,struct spl_boot_device * bootdev)166 static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
167 					struct spl_boot_device *bootdev)
168 {
169 	struct spl_load_info load;
170 	volatile gd_t *pgd = gd;
171 	u32 pagesize, pg;
172 	int ret;
173 	int i = 0;
174 	u8 *p = (u8 *)CONFIG_SPL_IMX_ROMAPI_LOADADDR;
175 	u8 *pfit = NULL;
176 	int imagesize;
177 	int total;
178 
179 	ret = g_rom_api->query_boot_infor(QUERY_PAGE_SZ, &pagesize,
180 					  ((uintptr_t)&pagesize) ^ QUERY_PAGE_SZ);
181 	gd = pgd;
182 
183 	if (ret != ROM_API_OKAY)
184 		puts("failure at query_boot_info\n");
185 
186 	pg = pagesize;
187 	if (pg < 1024)
188 		pg = 1024;
189 
190 	for (i = 0; i < 640; i++) {
191 		ret = g_rom_api->download_image(p, 0, pg,
192 						((uintptr_t)p) ^ pg);
193 		gd = pgd;
194 
195 		if (ret != ROM_API_OKAY) {
196 			puts("Steam(USB) download failure\n");
197 			return -1;
198 		}
199 
200 		pfit = search_fit_header(p, pg);
201 		p += pg;
202 
203 		if (pfit)
204 			break;
205 	}
206 
207 	if (!pfit) {
208 		puts("Can't found uboot FIT image in 640K range \n");
209 		return -1;
210 	}
211 
212 	if (p - pfit < sizeof(struct fdt_header)) {
213 		ret = g_rom_api->download_image(p, 0, pg,  ((uintptr_t)p) ^ pg);
214 		gd = pgd;
215 
216 		if (ret != ROM_API_OKAY) {
217 			puts("Steam(USB) download failure\n");
218 			return -1;
219 		}
220 
221 		p += pg;
222 	}
223 
224 	imagesize = fit_get_size(pfit);
225 	printf("Find FIT header 0x&%p, size %d\n", pfit, imagesize);
226 
227 	if (p - pfit < imagesize) {
228 		imagesize -= p - pfit;
229 		/*need pagesize hear after ROM fix USB problme*/
230 		imagesize += pg - 1;
231 		imagesize /= pg;
232 		imagesize *= pg;
233 
234 		printf("Need continue download %d\n", imagesize);
235 
236 		ret = g_rom_api->download_image(p, 0, imagesize,
237 						((uintptr_t)p) ^ imagesize);
238 		gd = pgd;
239 
240 		p += imagesize;
241 
242 		if (ret != ROM_API_OKAY) {
243 			printf("Failure download %d\n", imagesize);
244 			return -1;
245 		}
246 	}
247 
248 	total = get_fit_image_size(pfit);
249 	total += 3;
250 	total &= ~0x3;
251 
252 	imagesize = total - (p - pfit);
253 
254 	imagesize += pagesize - 1;
255 	imagesize /= pagesize;
256 	imagesize *= pagesize;
257 
258 	printf("Download %d, total fit %d\n", imagesize, total);
259 
260 	ret = g_rom_api->download_image(p, 0, imagesize,
261 					((uintptr_t)p) ^ imagesize);
262 	if (ret != ROM_API_OKAY)
263 		printf("ROM download failure %d\n", imagesize);
264 
265 	memset(&load, 0, sizeof(load));
266 	load.bl_len = 1;
267 	load.read = spl_ram_load_read;
268 
269 	return spl_load_simple_fit(spl_image, &load, (ulong)pfit, pfit);
270 }
271 
board_return_to_bootrom(struct spl_image_info * spl_image,struct spl_boot_device * bootdev)272 int board_return_to_bootrom(struct spl_image_info *spl_image,
273 			    struct spl_boot_device *bootdev)
274 {
275 	volatile gd_t *pgd = gd;
276 	int ret;
277 	u32 boot;
278 
279 	ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot,
280 					  ((uintptr_t)&boot) ^ QUERY_BT_DEV);
281 	gd =  pgd;
282 
283 	if (ret != ROM_API_OKAY) {
284 		puts("ROMAPI: failure at query_boot_info\n");
285 		return -1;
286 	}
287 
288 	if (is_boot_from_stream_device(boot))
289 		return spl_romapi_load_image_stream(spl_image, bootdev);
290 
291 	return spl_romapi_load_image_seekable(spl_image, bootdev, boot);
292 }
293