]> Git Repo - u-boot.git/blob - arch/arm/mach-imx/spl_imx_romapi.c
Restore patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet"
[u-boot.git] / arch / arm / mach-imx / spl_imx_romapi.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2019 NXP
4  */
5
6 #include <errno.h>
7 #include <image.h>
8 #include <imx_container.h>
9 #include <log.h>
10 #include <asm/global_data.h>
11 #include <linux/libfdt.h>
12 #include <spl.h>
13 #include <asm/arch/sys_proto.h>
14
15 DECLARE_GLOBAL_DATA_PTR;
16
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)
19 {
20         int ret;
21
22         debug("%s 0x%x, size 0x%x\n", __func__, offset, size);
23
24         ret = rom_api_download_image(buf, offset, size);
25
26         if (ret == ROM_API_OKAY)
27                 return size;
28
29         printf("%s Failure when load 0x%x, size 0x%x\n", __func__, offset, size);
30
31         return 0;
32 }
33
34 ulong __weak spl_romapi_get_uboot_base(u32 image_offset, u32 rom_bt_dev)
35 {
36         return image_offset +
37                 (CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512 - 0x8000);
38 }
39
40 static int is_boot_from_stream_device(u32 boot)
41 {
42         u32 interface;
43
44         interface = boot >> 16;
45         if (interface >= BT_DEV_TYPE_USB)
46                 return 1;
47
48         if (interface == BT_DEV_TYPE_MMC && (boot & 1))
49                 return 1;
50
51         return 0;
52 }
53
54 static ulong spl_romapi_read_seekable(struct spl_load_info *load,
55                                       ulong offset, ulong byte,
56                                       void *buf)
57 {
58         return spl_romapi_raw_seekable_read(offset, byte, buf);
59 }
60
61 static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image,
62                                           struct spl_boot_device *bootdev,
63                                           u32 rom_bt_dev)
64 {
65         int ret;
66         u32 offset;
67         u32 pagesize, size;
68         struct legacy_img_hdr *header;
69         u32 image_offset;
70
71         ret = rom_api_query_boot_infor(QUERY_IVT_OFF, &offset);
72         if (ret != ROM_API_OKAY)
73                 goto err;
74
75         ret = rom_api_query_boot_infor(QUERY_PAGE_SZ, &pagesize);
76         if (ret != ROM_API_OKAY)
77                 goto err;
78
79         ret = rom_api_query_boot_infor(QUERY_IMG_OFF, &image_offset);
80         if (ret != ROM_API_OKAY)
81                 goto err;
82
83         header = (struct legacy_img_hdr *)(CONFIG_SPL_IMX_ROMAPI_LOADADDR);
84
85         printf("image offset 0x%x, pagesize 0x%x, ivt offset 0x%x\n",
86                image_offset, pagesize, offset);
87
88         offset = spl_romapi_get_uboot_base(image_offset, rom_bt_dev);
89
90         size = ALIGN(sizeof(struct legacy_img_hdr), pagesize);
91         ret = rom_api_download_image((u8 *)header, offset, size);
92
93         if (ret != ROM_API_OKAY) {
94                 printf("ROMAPI: download failure offset 0x%x size 0x%x\n",
95                        offset, size);
96                 return -1;
97         }
98
99         if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) {
100                 struct spl_load_info load;
101
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;
109
110                 memset(&load, 0, sizeof(load));
111                 spl_set_bl_len(&load, pagesize);
112                 load.read = spl_romapi_read_seekable;
113
114                 ret = spl_load_imx_container(spl_image, &load, offset);
115         } else {
116                 /* TODO */
117                 puts("Can't support legacy image\n");
118                 return -1;
119         }
120
121         return 0;
122
123 err:
124         puts("ROMAPI: Failure query boot infor pagesize/offset\n");
125         return -1;
126 }
127
128 struct stream_state {
129         u8 *base;
130         u8 *end;
131         u32 pagesize;
132 };
133
134 static ulong spl_romapi_read_stream(struct spl_load_info *load, ulong sector,
135                                ulong count, void *buf)
136 {
137         struct stream_state *ss = load->priv;
138         u8 *end = (u8*)(sector + count);
139         u32 bytes;
140         int ret;
141
142         if (end > ss->end) {
143                 bytes = end - ss->end;
144                 bytes += ss->pagesize - 1;
145                 bytes /= ss->pagesize;
146                 bytes *= ss->pagesize;
147
148                 debug("downloading another 0x%x bytes\n", bytes);
149                 ret = rom_api_download_image(ss->end, 0, bytes);
150
151                 if (ret != ROM_API_OKAY) {
152                         printf("Failure download %d\n", bytes);
153                         return 0;
154                 }
155
156                 ss->end += bytes;
157         }
158
159         memcpy(buf, (void *)(sector), count);
160         return count;
161 }
162
163 static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector,
164                                ulong count, void *buf)
165 {
166         memcpy(buf, (void *)(sector), count);
167
168         if (load->priv) {
169                 ulong *p = (ulong *)load->priv;
170                 ulong total = sector + count;
171
172                 if (total > *p)
173                         *p = total;
174         }
175
176         return count;
177 }
178
179 static u8 *search_fit_header(u8 *p, int size)
180 {
181         int i;
182
183         for (i = 0; i < size; i += 4)
184                 if (genimg_get_format(p + i) == IMAGE_FORMAT_FIT)
185                         return p + i;
186
187         return NULL;
188 }
189
190 static u8 *search_container_header(u8 *p, int size)
191 {
192         int i = 0;
193         u8 *hdr;
194
195         for (i = 0; i < size; i += 4) {
196                 hdr = p + i;
197                 if (valid_container_hdr((void *)hdr) &&
198                     (*(hdr + 1) != 0 || *(hdr + 2) != 0))
199                         return p + i;
200         }
201
202         return NULL;
203 }
204
205 static u8 *search_img_header(u8 *p, int size)
206 {
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);
211
212         return NULL;
213 }
214
215 static u32 img_header_size(void)
216 {
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);
221
222         return 0;
223 }
224
225 static int img_info_size(void *img_hdr)
226 {
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;
231
232         return (container->length_lsb + (container->length_msb << 8));
233 #else
234         return 0;
235 #endif
236 }
237
238 static int img_total_size(void *img_hdr)
239 {
240         if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
241                 int total = get_container_size((ulong)img_hdr, NULL);
242
243                 if (total < 0) {
244                         printf("invalid container image\n");
245                         return 0;
246                 }
247
248                 return total;
249         }
250
251         return 0;
252 }
253
254 static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
255                                         struct spl_boot_device *bootdev)
256 {
257         struct spl_load_info load;
258         u32 pagesize, pg;
259         int ret;
260         int i = 0;
261         u8 *p = (u8 *)CONFIG_SPL_IMX_ROMAPI_LOADADDR;
262         u8 *phdr = NULL;
263         int imagesize;
264         int total;
265
266         ret = rom_api_query_boot_infor(QUERY_PAGE_SZ, &pagesize);
267
268         if (ret != ROM_API_OKAY)
269                 puts("failure at query_boot_info\n");
270
271         pg = pagesize;
272         if (pg < 1024)
273                 pg = 1024;
274
275         for (i = 0; i < 640; i++) {
276                 ret = rom_api_download_image(p, 0, pg);
277
278                 if (ret != ROM_API_OKAY) {
279                         puts("Stream(USB) download failure\n");
280                         return -1;
281                 }
282
283                 phdr = search_img_header(p, pg);
284                 p += pg;
285
286                 if (phdr)
287                         break;
288         }
289
290         if (!phdr) {
291                 puts("Can't found uboot image in 640K range\n");
292                 return -1;
293         }
294
295         if (p - phdr < img_header_size()) {
296                 ret = rom_api_download_image(p, 0, pg);
297
298                 if (ret != ROM_API_OKAY) {
299                         puts("Stream(USB) download failure\n");
300                         return -1;
301                 }
302
303                 p += pg;
304         }
305
306         imagesize = img_info_size(phdr);
307         printf("Find img info 0x%p, size %d\n", phdr, imagesize);
308
309         if (p - phdr < imagesize) {
310                 imagesize -= p - phdr;
311                 /*need pagesize hear after ROM fix USB problme*/
312                 imagesize += pg - 1;
313                 imagesize /= pg;
314                 imagesize *= pg;
315
316                 printf("Need continue download %d\n", imagesize);
317
318                 ret = rom_api_download_image(p, 0, imagesize);
319
320                 p += imagesize;
321
322                 if (ret != ROM_API_OKAY) {
323                         printf("Failure download %d\n", imagesize);
324                         return -1;
325                 }
326         }
327
328         if (IS_ENABLED(CONFIG_SPL_LOAD_FIT)) {
329                 struct stream_state ss;
330
331                 ss.base = phdr;
332                 ss.end = p;
333                 ss.pagesize = pagesize;
334
335                 memset(&load, 0, sizeof(load));
336                 spl_set_bl_len(&load, 1);
337                 load.read = spl_romapi_read_stream;
338                 load.priv = &ss;
339
340                 return spl_load_simple_fit(spl_image, &load, (ulong)phdr, phdr);
341         }
342
343         total = img_total_size(phdr);
344         total += 3;
345         total &= ~0x3;
346
347         imagesize = total - (p - phdr);
348
349         imagesize += pagesize - 1;
350         imagesize /= pagesize;
351         imagesize *= pagesize;
352
353         printf("Download %d, Total size %d\n", imagesize, total);
354
355         ret = rom_api_download_image(p, 0, imagesize);
356         if (ret != ROM_API_OKAY)
357                 printf("ROM download failure %d\n", imagesize);
358
359         memset(&load, 0, sizeof(load));
360         spl_set_bl_len(&load, 1);
361         load.read = spl_ram_load_read;
362
363         if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER))
364                 return spl_load_imx_container(spl_image, &load, (ulong)phdr);
365
366         return -1;
367 }
368
369 int board_return_to_bootrom(struct spl_image_info *spl_image,
370                             struct spl_boot_device *bootdev)
371 {
372         int ret;
373         u32 boot, bstage;
374
375         ret = rom_api_query_boot_infor(QUERY_BT_DEV, &boot);
376         if (ret != ROM_API_OKAY)
377                 goto err;
378
379         ret = rom_api_query_boot_infor(QUERY_BT_STAGE, &bstage);
380         if (ret != ROM_API_OKAY)
381                 goto err;
382
383         printf("Boot Stage: ");
384
385         switch (bstage) {
386         case BT_STAGE_PRIMARY:
387                 printf("Primary boot\n");
388                 break;
389         case BT_STAGE_SECONDARY:
390                 printf("Secondary boot\n");
391                 break;
392         case BT_STAGE_RECOVERY:
393                 printf("Recovery boot\n");
394                 break;
395         case BT_STAGE_USB:
396                 printf("USB boot\n");
397                 break;
398         default:
399                 printf("Unknown (0x%x)\n", bstage);
400         }
401
402         if (is_boot_from_stream_device(boot))
403                 return spl_romapi_load_image_stream(spl_image, bootdev);
404
405         return spl_romapi_load_image_seekable(spl_image, bootdev, boot);
406 err:
407         puts("ROMAPI: failure at query_boot_info\n");
408         return -1;
409 }
This page took 0.054324 seconds and 4 git commands to generate.