arm: imx8: Move container image header file to mach-imx
[platform/kernel/u-boot.git] / arch / arm / mach-imx / parse-container.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2018-2019 NXP
4  */
5
6 #include <common.h>
7 #include <errno.h>
8 #include <log.h>
9 #include <spl.h>
10 #include <asm/mach-imx/image.h>
11 #include <asm/arch/sci/sci.h>
12
13 #define SEC_SECURE_RAM_BASE             0x31800000UL
14 #define SEC_SECURE_RAM_END_BASE         (SEC_SECURE_RAM_BASE + 0xFFFFUL)
15 #define SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE      0x60000000UL
16
17 #define SECO_PT         2U
18
19 #ifdef CONFIG_AHAB_BOOT
20 static int authenticate_image(struct boot_img_t *img, int image_index)
21 {
22         sc_faddr_t start, end;
23         sc_rm_mr_t mr;
24         int err;
25         int ret = 0;
26
27         debug("img %d, dst 0x%x, src 0x%x, size 0x%x\n",
28               image_index, (uint32_t)img->dst, img->offset, img->size);
29
30         /* Find the memreg and set permission for seco pt */
31         err = sc_rm_find_memreg(-1, &mr,
32                                 img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1),
33                                 ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE) - 1);
34
35         if (err) {
36                 printf("can't find memreg for image %d load address 0x%x, error %d\n",
37                        image_index, img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1), err);
38                 return -ENOMEM;
39         }
40
41         err = sc_rm_get_memreg_info(-1, mr, &start, &end);
42         if (!err)
43                 debug("memreg %u 0x%x -- 0x%x\n", mr, start, end);
44
45         err = sc_rm_set_memreg_permissions(-1, mr,
46                                            SECO_PT, SC_RM_PERM_FULL);
47         if (err) {
48                 printf("set permission failed for img %d, error %d\n",
49                        image_index, err);
50                 return -EPERM;
51         }
52
53         err = sc_seco_authenticate(-1, SC_SECO_VERIFY_IMAGE,
54                                    1 << image_index);
55         if (err) {
56                 printf("authenticate img %d failed, return %d\n",
57                        image_index, err);
58                 ret = -EIO;
59         }
60
61         err = sc_rm_set_memreg_permissions(-1, mr,
62                                            SECO_PT, SC_RM_PERM_NONE);
63         if (err) {
64                 printf("remove permission failed for img %d, error %d\n",
65                        image_index, err);
66                 ret = -EPERM;
67         }
68
69         return ret;
70 }
71 #endif
72
73 static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
74                                           struct spl_load_info *info,
75                                           struct container_hdr *container,
76                                           int image_index,
77                                           u32 container_sector)
78 {
79         struct boot_img_t *images;
80         ulong sector;
81         u32 sectors;
82
83         if (image_index > container->num_images) {
84                 debug("Invalid image number\n");
85                 return NULL;
86         }
87
88         images = (struct boot_img_t *)((u8 *)container +
89                                        sizeof(struct container_hdr));
90
91         if (images[image_index].offset % info->bl_len) {
92                 printf("%s: image%d offset not aligned to %u\n",
93                        __func__, image_index, info->bl_len);
94                 return NULL;
95         }
96
97         sectors = roundup(images[image_index].size, info->bl_len) /
98                 info->bl_len;
99         sector = images[image_index].offset / info->bl_len +
100                 container_sector;
101
102         debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
103               container, sector, sectors);
104         if (info->read(info, sector, sectors,
105                        (void *)images[image_index].entry) != sectors) {
106                 printf("%s wrong\n", __func__);
107                 return NULL;
108         }
109
110 #ifdef CONFIG_AHAB_BOOT
111         if (authenticate_image(&images[image_index], image_index)) {
112                 printf("Failed to authenticate image %d\n", image_index);
113                 return NULL;
114         }
115 #endif
116
117         return &images[image_index];
118 }
119
120 static int read_auth_container(struct spl_image_info *spl_image,
121                                struct spl_load_info *info, ulong sector)
122 {
123         struct container_hdr *container = NULL;
124         u16 length;
125         u32 sectors;
126         int i, size, ret = 0;
127
128         size = roundup(CONTAINER_HDR_ALIGNMENT, info->bl_len);
129         sectors = size / info->bl_len;
130
131         /*
132          * It will not override the ATF code, so safe to use it here,
133          * no need malloc
134          */
135         container = (struct container_hdr *)spl_get_load_buffer(-size, size);
136
137         debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
138               container, sector, sectors);
139         if (info->read(info, sector, sectors, container) != sectors)
140                 return -EIO;
141
142         if (container->tag != 0x87 && container->version != 0x0) {
143                 printf("Wrong container header");
144                 return -ENOENT;
145         }
146
147         if (!container->num_images) {
148                 printf("Wrong container, no image found");
149                 return -ENOENT;
150         }
151
152         length = container->length_lsb + (container->length_msb << 8);
153         debug("Container length %u\n", length);
154
155         if (length > CONTAINER_HDR_ALIGNMENT) {
156                 size = roundup(length, info->bl_len);
157                 sectors = size / info->bl_len;
158
159                 container = (struct container_hdr *)spl_get_load_buffer(-size, size);
160
161                 debug("%s: container: %p sector: %lu sectors: %u\n",
162                       __func__, container, sector, sectors);
163                 if (info->read(info, sector, sectors, container) !=
164                     sectors)
165                         return -EIO;
166         }
167
168 #ifdef CONFIG_AHAB_BOOT
169         memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)container,
170                ALIGN(length, CONFIG_SYS_CACHELINE_SIZE));
171
172         ret = sc_seco_authenticate(-1, SC_SECO_AUTH_CONTAINER,
173                                    SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE);
174         if (ret) {
175                 printf("authenticate container hdr failed, return %d\n", ret);
176                 return ret;
177         }
178 #endif
179
180         for (i = 0; i < container->num_images; i++) {
181                 struct boot_img_t *image = read_auth_image(spl_image, info,
182                                                            container, i,
183                                                            sector);
184
185                 if (!image) {
186                         ret = -EINVAL;
187                         goto end_auth;
188                 }
189
190                 if (i == 0) {
191                         spl_image->load_addr = image->dst;
192                         spl_image->entry_point = image->entry;
193                 }
194         }
195
196 end_auth:
197 #ifdef CONFIG_AHAB_BOOT
198         if (sc_seco_authenticate(-1, SC_SECO_REL_CONTAINER, 0))
199                 printf("Error: release container failed!\n");
200 #endif
201         return ret;
202 }
203
204 int spl_load_imx_container(struct spl_image_info *spl_image,
205                            struct spl_load_info *info, ulong sector)
206 {
207         return read_auth_container(spl_image, info, sector);
208 }