c29cb15f55e3adff0cded027426cb19e15126e0e
[pandora-u-boot.git] / arch / arm / mach-imx / parse-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 }