1 // SPDX-License-Identifier: GPL-2.0+
8 #include <imx_container.h>
10 #include <asm/global_data.h>
11 #include <linux/libfdt.h>
13 #include <asm/arch/sys_proto.h>
15 DECLARE_GLOBAL_DATA_PTR;
17 /* Caller need ensure the offset and size to align with page size */
18 ulong spl_romapi_raw_seekable_read(u32 offset, u32 size, void *buf)
22 debug("%s 0x%x, size 0x%x\n", __func__, offset, size);
24 ret = rom_api_download_image(buf, offset, size);
26 if (ret == ROM_API_OKAY)
29 printf("%s Failure when load 0x%x, size 0x%x\n", __func__, offset, size);
34 ulong __weak spl_romapi_get_uboot_base(u32 image_offset, u32 rom_bt_dev)
37 (CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512 - 0x8000);
40 static int is_boot_from_stream_device(u32 boot)
44 interface = boot >> 16;
45 if (interface >= BT_DEV_TYPE_USB)
48 if (interface == BT_DEV_TYPE_MMC && (boot & 1))
54 static ulong spl_romapi_read_seekable(struct spl_load_info *load,
55 ulong offset, ulong byte,
58 return spl_romapi_raw_seekable_read(offset, byte, buf);
61 static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image,
62 struct spl_boot_device *bootdev,
68 struct legacy_img_hdr *header;
71 ret = rom_api_query_boot_infor(QUERY_IVT_OFF, &offset);
72 if (ret != ROM_API_OKAY)
75 ret = rom_api_query_boot_infor(QUERY_PAGE_SZ, &pagesize);
76 if (ret != ROM_API_OKAY)
79 ret = rom_api_query_boot_infor(QUERY_IMG_OFF, &image_offset);
80 if (ret != ROM_API_OKAY)
83 header = (struct legacy_img_hdr *)(CONFIG_SPL_IMX_ROMAPI_LOADADDR);
85 printf("image offset 0x%x, pagesize 0x%x, ivt offset 0x%x\n",
86 image_offset, pagesize, offset);
88 offset = spl_romapi_get_uboot_base(image_offset, rom_bt_dev);
90 size = ALIGN(sizeof(struct legacy_img_hdr), pagesize);
91 ret = rom_api_download_image((u8 *)header, offset, size);
93 if (ret != ROM_API_OKAY) {
94 printf("ROMAPI: download failure offset 0x%x size 0x%x\n",
99 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) {
100 struct spl_load_info load;
102 memset(&load, 0, sizeof(load));
103 spl_set_bl_len(&load, pagesize);
104 load.read = spl_romapi_read_seekable;
105 return spl_load_simple_fit(spl_image, &load, offset, header);
106 } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER) &&
107 valid_container_hdr((void *)header)) {
108 struct spl_load_info load;
110 memset(&load, 0, sizeof(load));
111 spl_set_bl_len(&load, pagesize);
112 load.read = spl_romapi_read_seekable;
114 ret = spl_load_imx_container(spl_image, &load, offset);
117 puts("Can't support legacy image\n");
124 puts("ROMAPI: Failure query boot infor pagesize/offset\n");
128 struct stream_state {
134 static ulong spl_romapi_read_stream(struct spl_load_info *load, ulong sector,
135 ulong count, void *buf)
137 struct stream_state *ss = load->priv;
138 u8 *end = (u8*)(sector + count);
143 bytes = end - ss->end;
144 bytes += ss->pagesize - 1;
145 bytes /= ss->pagesize;
146 bytes *= ss->pagesize;
148 debug("downloading another 0x%x bytes\n", bytes);
149 ret = rom_api_download_image(ss->end, 0, bytes);
151 if (ret != ROM_API_OKAY) {
152 printf("Failure download %d\n", bytes);
159 memcpy(buf, (void *)(sector), count);
163 static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector,
164 ulong count, void *buf)
166 memcpy(buf, (void *)(sector), count);
169 ulong *p = (ulong *)load->priv;
170 ulong total = sector + count;
179 static u8 *search_fit_header(u8 *p, int size)
183 for (i = 0; i < size; i += 4)
184 if (genimg_get_format(p + i) == IMAGE_FORMAT_FIT)
190 static u8 *search_container_header(u8 *p, int size)
195 for (i = 0; i < size; i += 4) {
197 if (valid_container_hdr((void *)hdr) &&
198 (*(hdr + 1) != 0 || *(hdr + 2) != 0))
205 static u8 *search_img_header(u8 *p, int size)
207 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT))
208 return search_fit_header(p, size);
209 else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER))
210 return search_container_header(p, size);
215 static u32 img_header_size(void)
217 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT))
218 return sizeof(struct fdt_header);
219 else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER))
220 return sizeof(struct container_hdr);
225 static int img_info_size(void *img_hdr)
227 #ifdef CONFIG_SPL_LOAD_FIT
228 return fit_get_size(img_hdr);
229 #elif defined CONFIG_SPL_LOAD_IMX_CONTAINER
230 struct container_hdr *container = img_hdr;
232 return (container->length_lsb + (container->length_msb << 8));
238 static int img_total_size(void *img_hdr)
240 if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
241 int total = get_container_size((ulong)img_hdr, NULL);
244 printf("invalid container image\n");
254 static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
255 struct spl_boot_device *bootdev)
257 struct spl_load_info load;
261 u8 *p = (u8 *)CONFIG_SPL_IMX_ROMAPI_LOADADDR;
266 ret = rom_api_query_boot_infor(QUERY_PAGE_SZ, &pagesize);
268 if (ret != ROM_API_OKAY)
269 puts("failure at query_boot_info\n");
275 for (i = 0; i < 640; i++) {
276 ret = rom_api_download_image(p, 0, pg);
278 if (ret != ROM_API_OKAY) {
279 puts("Stream(USB) download failure\n");
283 phdr = search_img_header(p, pg);
291 puts("Can't found uboot image in 640K range\n");
295 if (p - phdr < img_header_size()) {
296 ret = rom_api_download_image(p, 0, pg);
298 if (ret != ROM_API_OKAY) {
299 puts("Stream(USB) download failure\n");
306 imagesize = img_info_size(phdr);
307 printf("Find img info 0x%p, size %d\n", phdr, imagesize);
309 if (p - phdr < imagesize) {
310 imagesize -= p - phdr;
311 /*need pagesize hear after ROM fix USB problme*/
316 printf("Need continue download %d\n", imagesize);
318 ret = rom_api_download_image(p, 0, imagesize);
322 if (ret != ROM_API_OKAY) {
323 printf("Failure download %d\n", imagesize);
328 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT)) {
329 struct stream_state ss;
333 ss.pagesize = pagesize;
335 memset(&load, 0, sizeof(load));
336 spl_set_bl_len(&load, 1);
337 load.read = spl_romapi_read_stream;
340 return spl_load_simple_fit(spl_image, &load, (ulong)phdr, phdr);
343 total = img_total_size(phdr);
347 imagesize = total - (p - phdr);
349 imagesize += pagesize - 1;
350 imagesize /= pagesize;
351 imagesize *= pagesize;
353 printf("Download %d, Total size %d\n", imagesize, total);
355 ret = rom_api_download_image(p, 0, imagesize);
356 if (ret != ROM_API_OKAY)
357 printf("ROM download failure %d\n", imagesize);
359 memset(&load, 0, sizeof(load));
360 spl_set_bl_len(&load, 1);
361 load.read = spl_ram_load_read;
363 if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER))
364 return spl_load_imx_container(spl_image, &load, (ulong)phdr);
369 int board_return_to_bootrom(struct spl_image_info *spl_image,
370 struct spl_boot_device *bootdev)
375 ret = rom_api_query_boot_infor(QUERY_BT_DEV, &boot);
376 if (ret != ROM_API_OKAY)
379 ret = rom_api_query_boot_infor(QUERY_BT_STAGE, &bstage);
380 if (ret != ROM_API_OKAY)
383 printf("Boot Stage: ");
386 case BT_STAGE_PRIMARY:
387 printf("Primary boot\n");
389 case BT_STAGE_SECONDARY:
390 printf("Secondary boot\n");
392 case BT_STAGE_RECOVERY:
393 printf("Recovery boot\n");
396 printf("USB boot\n");
399 printf("Unknown (0x%x)\n", bstage);
402 if (is_boot_from_stream_device(boot))
403 return spl_romapi_load_image_stream(spl_image, bootdev);
405 return spl_romapi_load_image_seekable(spl_image, bootdev, boot);
407 puts("ROMAPI: failure at query_boot_info\n");