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