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