• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <spl.h>
9 #include <asm/arch/image.h>
10 #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
authenticate_image(struct boot_img_t * img,int image_index)19 static 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
71 
read_auth_image(struct spl_image_info * spl_image,struct spl_load_info * info,struct container_hdr * container,int image_index,u32 container_sector)72 static 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 	}
108 
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
115 
116 	return &images[image_index];
117 }
118 
read_auth_container(struct spl_image_info * spl_image,struct spl_load_info * info,ulong sector)119 static 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;
125 	int i, size, ret = 0;
126 
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 	}
166 
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
178 
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 
184 		if (!image) {
185 			ret = -EINVAL;
186 			goto end_auth;
187 		}
188 
189 		if (i == 0) {
190 			spl_image->load_addr = image->dst;
191 			spl_image->entry_point = image->entry;
192 		}
193 	}
194 
195 end_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;
201 }
202 
spl_load_imx_container(struct spl_image_info * spl_image,struct spl_load_info * info,ulong sector)203 int 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 }
208