xref: /rk3399_ARM-atf/plat/arm/common/arm_io_storage.c (revision 51faada71a219a8b94cd8d8e423f0f22e9da4d8f)
1 /*
2  * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of ARM nor the names of its contributors may be used
15  * to endorse or promote products derived from this software without specific
16  * prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 #include <assert.h>
31 #include <debug.h>
32 #include <firmware_image_package.h>
33 #include <io_driver.h>
34 #include <io_fip.h>
35 #include <io_memmap.h>
36 #include <io_storage.h>
37 #include <platform_def.h>
38 #include <string.h>
39 #include <utils.h>
40 
41 /* IO devices */
42 static const io_dev_connector_t *fip_dev_con;
43 static uintptr_t fip_dev_handle;
44 static const io_dev_connector_t *memmap_dev_con;
45 static uintptr_t memmap_dev_handle;
46 
47 static const io_block_spec_t fip_block_spec = {
48 	.offset = PLAT_ARM_FIP_BASE,
49 	.length = PLAT_ARM_FIP_MAX_SIZE
50 };
51 
52 static const io_uuid_spec_t bl2_uuid_spec = {
53 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
54 };
55 
56 static const io_uuid_spec_t scp_bl2_uuid_spec = {
57 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
58 };
59 
60 static const io_uuid_spec_t bl31_uuid_spec = {
61 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
62 };
63 
64 static const io_uuid_spec_t bl32_uuid_spec = {
65 	.uuid = UUID_SECURE_PAYLOAD_BL32,
66 };
67 
68 static const io_uuid_spec_t bl33_uuid_spec = {
69 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
70 };
71 
72 #if TRUSTED_BOARD_BOOT
73 static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
74 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
75 };
76 
77 static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
78 	.uuid = UUID_TRUSTED_KEY_CERT,
79 };
80 
81 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
82 	.uuid = UUID_SCP_FW_KEY_CERT,
83 };
84 
85 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
86 	.uuid = UUID_SOC_FW_KEY_CERT,
87 };
88 
89 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
90 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
91 };
92 
93 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
94 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
95 };
96 
97 static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
98 	.uuid = UUID_SCP_FW_CONTENT_CERT,
99 };
100 
101 static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
102 	.uuid = UUID_SOC_FW_CONTENT_CERT,
103 };
104 
105 static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
106 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
107 };
108 
109 static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
110 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
111 };
112 #endif /* TRUSTED_BOARD_BOOT */
113 
114 
115 static int open_fip(const uintptr_t spec);
116 static int open_memmap(const uintptr_t spec);
117 
118 struct plat_io_policy {
119 	uintptr_t *dev_handle;
120 	uintptr_t image_spec;
121 	int (*check)(const uintptr_t spec);
122 };
123 
124 /* By default, ARM platforms load images from the FIP */
125 static const struct plat_io_policy policies[] = {
126 	[FIP_IMAGE_ID] = {
127 		&memmap_dev_handle,
128 		(uintptr_t)&fip_block_spec,
129 		open_memmap
130 	},
131 	[BL2_IMAGE_ID] = {
132 		&fip_dev_handle,
133 		(uintptr_t)&bl2_uuid_spec,
134 		open_fip
135 	},
136 	[SCP_BL2_IMAGE_ID] = {
137 		&fip_dev_handle,
138 		(uintptr_t)&scp_bl2_uuid_spec,
139 		open_fip
140 	},
141 	[BL31_IMAGE_ID] = {
142 		&fip_dev_handle,
143 		(uintptr_t)&bl31_uuid_spec,
144 		open_fip
145 	},
146 	[BL32_IMAGE_ID] = {
147 		&fip_dev_handle,
148 		(uintptr_t)&bl32_uuid_spec,
149 		open_fip
150 	},
151 	[BL33_IMAGE_ID] = {
152 		&fip_dev_handle,
153 		(uintptr_t)&bl33_uuid_spec,
154 		open_fip
155 	},
156 #if TRUSTED_BOARD_BOOT
157 	[TRUSTED_BOOT_FW_CERT_ID] = {
158 		&fip_dev_handle,
159 		(uintptr_t)&tb_fw_cert_uuid_spec,
160 		open_fip
161 	},
162 	[TRUSTED_KEY_CERT_ID] = {
163 		&fip_dev_handle,
164 		(uintptr_t)&trusted_key_cert_uuid_spec,
165 		open_fip
166 	},
167 	[SCP_FW_KEY_CERT_ID] = {
168 		&fip_dev_handle,
169 		(uintptr_t)&scp_fw_key_cert_uuid_spec,
170 		open_fip
171 	},
172 	[SOC_FW_KEY_CERT_ID] = {
173 		&fip_dev_handle,
174 		(uintptr_t)&soc_fw_key_cert_uuid_spec,
175 		open_fip
176 	},
177 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
178 		&fip_dev_handle,
179 		(uintptr_t)&tos_fw_key_cert_uuid_spec,
180 		open_fip
181 	},
182 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
183 		&fip_dev_handle,
184 		(uintptr_t)&nt_fw_key_cert_uuid_spec,
185 		open_fip
186 	},
187 	[SCP_FW_CONTENT_CERT_ID] = {
188 		&fip_dev_handle,
189 		(uintptr_t)&scp_fw_cert_uuid_spec,
190 		open_fip
191 	},
192 	[SOC_FW_CONTENT_CERT_ID] = {
193 		&fip_dev_handle,
194 		(uintptr_t)&soc_fw_cert_uuid_spec,
195 		open_fip
196 	},
197 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
198 		&fip_dev_handle,
199 		(uintptr_t)&tos_fw_cert_uuid_spec,
200 		open_fip
201 	},
202 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
203 		&fip_dev_handle,
204 		(uintptr_t)&nt_fw_cert_uuid_spec,
205 		open_fip
206 	},
207 #endif /* TRUSTED_BOARD_BOOT */
208 };
209 
210 
211 /* Weak definitions may be overridden in specific ARM standard platform */
212 #pragma weak plat_arm_io_setup
213 #pragma weak plat_arm_get_alt_image_source
214 
215 
216 static int open_fip(const uintptr_t spec)
217 {
218 	int result;
219 	uintptr_t local_image_handle;
220 
221 	/* See if a Firmware Image Package is available */
222 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
223 	if (result == 0) {
224 		result = io_open(fip_dev_handle, spec, &local_image_handle);
225 		if (result == 0) {
226 			VERBOSE("Using FIP\n");
227 			io_close(local_image_handle);
228 		}
229 	}
230 	return result;
231 }
232 
233 
234 static int open_memmap(const uintptr_t spec)
235 {
236 	int result;
237 	uintptr_t local_image_handle;
238 
239 	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
240 	if (result == 0) {
241 		result = io_open(memmap_dev_handle, spec, &local_image_handle);
242 		if (result == 0) {
243 			VERBOSE("Using Memmap\n");
244 			io_close(local_image_handle);
245 		}
246 	}
247 	return result;
248 }
249 
250 
251 void arm_io_setup(void)
252 {
253 	int io_result;
254 
255 	io_result = register_io_dev_fip(&fip_dev_con);
256 	assert(io_result == 0);
257 
258 	io_result = register_io_dev_memmap(&memmap_dev_con);
259 	assert(io_result == 0);
260 
261 	/* Open connections to devices and cache the handles */
262 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
263 				&fip_dev_handle);
264 	assert(io_result == 0);
265 
266 	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
267 				&memmap_dev_handle);
268 	assert(io_result == 0);
269 
270 	/* Ignore improbable errors in release builds */
271 	(void)io_result;
272 }
273 
274 void plat_arm_io_setup(void)
275 {
276 	arm_io_setup();
277 }
278 
279 int plat_arm_get_alt_image_source(
280 	unsigned int image_id __unused,
281 	uintptr_t *dev_handle __unused,
282 	uintptr_t *image_spec __unused)
283 {
284 	/* By default do not try an alternative */
285 	return -ENOENT;
286 }
287 
288 /* Return an IO device handle and specification which can be used to access
289  * an image. Use this to enforce platform load policy */
290 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
291 			  uintptr_t *image_spec)
292 {
293 	int result;
294 	const struct plat_io_policy *policy;
295 
296 	assert(image_id < ARRAY_SIZE(policies));
297 
298 	policy = &policies[image_id];
299 	result = policy->check(policy->image_spec);
300 	if (result == 0) {
301 		*image_spec = policy->image_spec;
302 		*dev_handle = *(policy->dev_handle);
303 	} else {
304 		VERBOSE("Trying alternative IO\n");
305 		result = plat_arm_get_alt_image_source(image_id, dev_handle,
306 						       image_spec);
307 	}
308 
309 	return result;
310 }
311 
312 /*
313  * See if a Firmware Image Package is available,
314  * by checking if TOC is valid or not.
315  */
316 int arm_io_is_toc_valid(void)
317 {
318 	int result;
319 
320 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
321 
322 	return (result == 0);
323 }
324 
325