]> git.ipfire.org Git - thirdparty/u-boot.git/blob - common/spl/spl_imx_container.c
Move i.MX8 container image loading support to common/spl
[thirdparty/u-boot.git] / common / spl / spl_imx_container.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright 2018-2021 NXP
4 */
5
6 #define LOG_CATEGORY LOGC_ARCH
7 #include <common.h>
8 #include <stdlib.h>
9 #include <errno.h>
10 #include <imx_container.h>
11 #include <log.h>
12 #include <spl.h>
13 #ifdef CONFIG_AHAB_BOOT
14 #include <asm/mach-imx/ahab.h>
15 #endif
16
17 static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
18 struct spl_load_info *info,
19 struct container_hdr *container,
20 int image_index,
21 u32 container_sector)
22 {
23 struct boot_img_t *images;
24 ulong sector;
25 u32 sectors;
26
27 if (image_index > container->num_images) {
28 debug("Invalid image number\n");
29 return NULL;
30 }
31
32 images = (struct boot_img_t *)((u8 *)container +
33 sizeof(struct container_hdr));
34
35 if (images[image_index].offset % info->bl_len) {
36 printf("%s: image%d offset not aligned to %u\n",
37 __func__, image_index, info->bl_len);
38 return NULL;
39 }
40
41 sectors = roundup(images[image_index].size, info->bl_len) /
42 info->bl_len;
43 sector = images[image_index].offset / info->bl_len +
44 container_sector;
45
46 debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
47 container, sector, sectors);
48 if (info->read(info, sector, sectors,
49 (void *)images[image_index].dst) != sectors) {
50 printf("%s wrong\n", __func__);
51 return NULL;
52 }
53
54 #ifdef CONFIG_AHAB_BOOT
55 if (ahab_verify_cntr_image(&images[image_index], image_index))
56 return NULL;
57 #endif
58
59 return &images[image_index];
60 }
61
62 static int read_auth_container(struct spl_image_info *spl_image,
63 struct spl_load_info *info, ulong sector)
64 {
65 struct container_hdr *container = NULL;
66 u16 length;
67 u32 sectors;
68 int i, size, ret = 0;
69
70 size = roundup(CONTAINER_HDR_ALIGNMENT, info->bl_len);
71 sectors = size / info->bl_len;
72
73 /*
74 * It will not override the ATF code, so safe to use it here,
75 * no need malloc
76 */
77 container = malloc(size);
78 if (!container)
79 return -ENOMEM;
80
81 debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
82 container, sector, sectors);
83 if (info->read(info, sector, sectors, container) != sectors) {
84 ret = -EIO;
85 goto end;
86 }
87
88 if (!valid_container_hdr(container)) {
89 log_err("Wrong container header\n");
90 ret = -ENOENT;
91 goto end;
92 }
93
94 if (!container->num_images) {
95 log_err("Wrong container, no image found\n");
96 ret = -ENOENT;
97 goto end;
98 }
99
100 length = container->length_lsb + (container->length_msb << 8);
101 debug("Container length %u\n", length);
102
103 if (length > CONTAINER_HDR_ALIGNMENT) {
104 size = roundup(length, info->bl_len);
105 sectors = size / info->bl_len;
106
107 free(container);
108 container = malloc(size);
109 if (!container)
110 return -ENOMEM;
111
112 debug("%s: container: %p sector: %lu sectors: %u\n",
113 __func__, container, sector, sectors);
114 if (info->read(info, sector, sectors, container) !=
115 sectors) {
116 ret = -EIO;
117 goto end;
118 }
119 }
120
121 #ifdef CONFIG_AHAB_BOOT
122 ret = ahab_auth_cntr_hdr(container, length);
123 if (ret)
124 goto end_auth;
125 #endif
126
127 for (i = 0; i < container->num_images; i++) {
128 struct boot_img_t *image = read_auth_image(spl_image, info,
129 container, i,
130 sector);
131
132 if (!image) {
133 ret = -EINVAL;
134 goto end_auth;
135 }
136
137 if (i == 0) {
138 spl_image->load_addr = image->dst;
139 spl_image->entry_point = image->entry;
140 }
141 }
142
143 end_auth:
144 #ifdef CONFIG_AHAB_BOOT
145 ahab_auth_release();
146 #endif
147
148 end:
149 free(container);
150
151 return ret;
152 }
153
154 int spl_load_imx_container(struct spl_image_info *spl_image,
155 struct spl_load_info *info, ulong sector)
156 {
157 return read_auth_container(spl_image, info, sector);
158 }