blob: 32f78bdddfb0b6cfaa997e614f93a1c47581c80e [file] [log] [blame]
Peng Fan1a7e6252019-08-22 07:42:33 +00001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2018-2019 NXP
4 */
5
6#include <common.h>
7#include <errno.h>
8#include <spl.h>
9#include <asm/arch/image.h>
10
11static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
12 struct spl_load_info *info,
13 struct container_hdr *container,
14 int image_index,
15 u32 container_sector)
16{
17 struct boot_img_t *images;
18 ulong sector;
19 u32 sectors;
20
21 if (image_index > container->num_images) {
22 debug("Invalid image number\n");
23 return NULL;
24 }
25
26 images = (struct boot_img_t *)((u8 *)container +
27 sizeof(struct container_hdr));
28
29 if (images[image_index].offset % info->bl_len) {
30 printf("%s: image%d offset not aligned to %u\n",
31 __func__, image_index, info->bl_len);
32 return NULL;
33 }
34
35 sectors = roundup(images[image_index].size, info->bl_len) /
36 info->bl_len;
37 sector = images[image_index].offset / info->bl_len +
38 container_sector;
39
40 debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
41 container, sector, sectors);
42 if (info->read(info, sector, sectors,
43 (void *)images[image_index].entry) != sectors) {
44 printf("%s wrong\n", __func__);
45 return NULL;
46 }
47
48 return &images[image_index];
49}
50
51static int read_auth_container(struct spl_image_info *spl_image,
52 struct spl_load_info *info, ulong sector)
53{
54 struct container_hdr *container = NULL;
55 u16 length;
56 u32 sectors;
57 int i, size;
58
59 size = roundup(CONTAINER_HDR_ALIGNMENT, info->bl_len);
60 sectors = size / info->bl_len;
61
62 /*
63 * It will not override the ATF code, so safe to use it here,
64 * no need malloc
65 */
66 container = (struct container_hdr *)spl_get_load_buffer(-size, size);
67
68 debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
69 container, sector, sectors);
70 if (info->read(info, sector, sectors, container) != sectors)
71 return -EIO;
72
73 if (container->tag != 0x87 && container->version != 0x0) {
74 printf("Wrong container header");
75 return -ENOENT;
76 }
77
78 if (!container->num_images) {
79 printf("Wrong container, no image found");
80 return -ENOENT;
81 }
82
83 length = container->length_lsb + (container->length_msb << 8);
84 debug("Container length %u\n", length);
85
86 if (length > CONTAINER_HDR_ALIGNMENT) {
87 size = roundup(length, info->bl_len);
88 sectors = size / info->bl_len;
89
90 container = (struct container_hdr *)spl_get_load_buffer(-size, size);
91
92 debug("%s: container: %p sector: %lu sectors: %u\n",
93 __func__, container, sector, sectors);
94 if (info->read(info, sector, sectors, container) !=
95 sectors)
96 return -EIO;
97 }
98
99 for (i = 0; i < container->num_images; i++) {
100 struct boot_img_t *image = read_auth_image(spl_image, info,
101 container, i,
102 sector);
103
104 if (!image)
105 return -EINVAL;
106
107 if (i == 0) {
108 spl_image->load_addr = image->dst;
109 spl_image->entry_point = image->entry;
110 }
111 }
112
113 return 0;
114}
115
116int spl_load_imx_container(struct spl_image_info *spl_image,
117 struct spl_load_info *info, ulong sector)
118{
119 return read_auth_container(spl_image, info, sector);
120}