blob: cafcf6dd55239f2c2896163cb13c8fa12bcb20fa [file] [log] [blame]
Antonio Nino Diazae6779e2017-11-06 14:49:04 +00001/*
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +08002 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
Antonio Nino Diazae6779e2017-11-06 14:49:04 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8#include <bl_common.h>
9#include <debug.h>
10#include <firmware_image_package.h>
11#include <io_driver.h>
12#include <io_fip.h>
13#include <io_memmap.h>
14#include <platform_def.h>
15#include <string.h>
16
17/* Semihosting filenames */
18#define BL2_IMAGE_NAME "bl2.bin"
19#define BL31_IMAGE_NAME "bl31.bin"
20#define BL32_IMAGE_NAME "bl32.bin"
21#define BL33_IMAGE_NAME "bl33.bin"
22
23#if TRUSTED_BOARD_BOOT
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +080024#define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt"
Antonio Nino Diazae6779e2017-11-06 14:49:04 +000025#define TRUSTED_KEY_CERT_NAME "trusted_key.crt"
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +080026#define SOC_FW_KEY_CERT_NAME "soc_fw_key.crt"
27#define TOS_FW_KEY_CERT_NAME "tos_fw_key.crt"
28#define NT_FW_KEY_CERT_NAME "nt_fw_key.crt"
29#define SOC_FW_CONTENT_CERT_NAME "soc_fw_content.crt"
30#define TOS_FW_CONTENT_CERT_NAME "tos_fw_content.crt"
31#define NT_FW_CONTENT_CERT_NAME "nt_fw_content.crt"
Antonio Nino Diazae6779e2017-11-06 14:49:04 +000032#endif /* TRUSTED_BOARD_BOOT */
33
34/* IO devices */
35static const io_dev_connector_t *fip_dev_con;
36static uintptr_t fip_dev_handle;
37static const io_dev_connector_t *memmap_dev_con;
38static uintptr_t memmap_dev_handle;
39
40static const io_block_spec_t fip_block_spec = {
41 .offset = PLAT_RPI3_FIP_BASE,
42 .length = PLAT_RPI3_FIP_MAX_SIZE
43};
44
45static const io_uuid_spec_t bl2_uuid_spec = {
46 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
47};
48
49static const io_uuid_spec_t bl31_uuid_spec = {
50 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
51};
52
53static const io_uuid_spec_t bl32_uuid_spec = {
54 .uuid = UUID_SECURE_PAYLOAD_BL32,
55};
56
Ying-Chun Liu (PaulLiu)d9f76e62018-06-10 02:00:27 +080057static const io_uuid_spec_t bl32_extra1_uuid_spec = {
58 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
59};
60
61static const io_uuid_spec_t bl32_extra2_uuid_spec = {
62 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
63};
64
Antonio Nino Diazae6779e2017-11-06 14:49:04 +000065static const io_uuid_spec_t bl33_uuid_spec = {
66 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
67};
68
69#if TRUSTED_BOARD_BOOT
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +080070static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
71 .uuid = UUID_TRUSTED_BOOT_FW_CERT,
Antonio Nino Diazae6779e2017-11-06 14:49:04 +000072};
73
74static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
75 .uuid = UUID_TRUSTED_KEY_CERT,
76};
77
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +080078static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
79 .uuid = UUID_SOC_FW_KEY_CERT,
Antonio Nino Diazae6779e2017-11-06 14:49:04 +000080};
81
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +080082static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
83 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
Antonio Nino Diazae6779e2017-11-06 14:49:04 +000084};
85
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +080086static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
87 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
Antonio Nino Diazae6779e2017-11-06 14:49:04 +000088};
89
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +080090static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
91 .uuid = UUID_SOC_FW_CONTENT_CERT,
Antonio Nino Diazae6779e2017-11-06 14:49:04 +000092};
93
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +080094static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
95 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
Antonio Nino Diazae6779e2017-11-06 14:49:04 +000096};
97
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +080098static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
99 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000100};
101#endif /* TRUSTED_BOARD_BOOT */
102
103static int open_fip(const uintptr_t spec);
104static int open_memmap(const uintptr_t spec);
105
106struct plat_io_policy {
107 uintptr_t *dev_handle;
108 uintptr_t image_spec;
109 int (*check)(const uintptr_t spec);
110};
111
112/* By default, load images from the FIP */
113static const struct plat_io_policy policies[] = {
114 [FIP_IMAGE_ID] = {
115 &memmap_dev_handle,
116 (uintptr_t)&fip_block_spec,
117 open_memmap
118 },
119 [BL2_IMAGE_ID] = {
120 &fip_dev_handle,
121 (uintptr_t)&bl2_uuid_spec,
122 open_fip
123 },
124 [BL31_IMAGE_ID] = {
125 &fip_dev_handle,
126 (uintptr_t)&bl31_uuid_spec,
127 open_fip
128 },
129 [BL32_IMAGE_ID] = {
130 &fip_dev_handle,
131 (uintptr_t)&bl32_uuid_spec,
132 open_fip
133 },
Ying-Chun Liu (PaulLiu)d9f76e62018-06-10 02:00:27 +0800134 [BL32_IMAGE_ID] = {
135 &fip_dev_handle,
136 (uintptr_t)&bl32_uuid_spec,
137 open_fip
138 },
139 [BL32_EXTRA1_IMAGE_ID] = {
140 &fip_dev_handle,
141 (uintptr_t)&bl32_extra1_uuid_spec,
142 open_fip
143 },
144 [BL32_EXTRA2_IMAGE_ID] = {
145 &fip_dev_handle,
146 (uintptr_t)&bl32_extra2_uuid_spec,
147 open_fip
148 },
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000149 [BL33_IMAGE_ID] = {
150 &fip_dev_handle,
151 (uintptr_t)&bl33_uuid_spec,
152 open_fip
153 },
154#if TRUSTED_BOARD_BOOT
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +0800155 [TRUSTED_BOOT_FW_CERT_ID] = {
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000156 &fip_dev_handle,
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +0800157 (uintptr_t)&tb_fw_cert_uuid_spec,
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000158 open_fip
159 },
160 [TRUSTED_KEY_CERT_ID] = {
161 &fip_dev_handle,
162 (uintptr_t)&trusted_key_cert_uuid_spec,
163 open_fip
164 },
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +0800165 [SOC_FW_KEY_CERT_ID] = {
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000166 &fip_dev_handle,
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +0800167 (uintptr_t)&soc_fw_key_cert_uuid_spec,
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000168 open_fip
169 },
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +0800170 [TRUSTED_OS_FW_KEY_CERT_ID] = {
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000171 &fip_dev_handle,
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +0800172 (uintptr_t)&tos_fw_key_cert_uuid_spec,
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000173 open_fip
174 },
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +0800175 [NON_TRUSTED_FW_KEY_CERT_ID] = {
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000176 &fip_dev_handle,
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +0800177 (uintptr_t)&nt_fw_key_cert_uuid_spec,
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000178 open_fip
179 },
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +0800180 [SOC_FW_CONTENT_CERT_ID] = {
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000181 &fip_dev_handle,
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +0800182 (uintptr_t)&soc_fw_cert_uuid_spec,
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000183 open_fip
184 },
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +0800185 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000186 &fip_dev_handle,
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +0800187 (uintptr_t)&tos_fw_cert_uuid_spec,
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000188 open_fip
189 },
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +0800190 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000191 &fip_dev_handle,
Ying-Chun Liu (PaulLiu)9128df62018-07-04 02:26:48 +0800192 (uintptr_t)&nt_fw_cert_uuid_spec,
Antonio Nino Diazae6779e2017-11-06 14:49:04 +0000193 open_fip
194 },
195#endif /* TRUSTED_BOARD_BOOT */
196};
197
198static int open_fip(const uintptr_t spec)
199{
200 int result;
201 uintptr_t local_image_handle;
202
203 /* See if a Firmware Image Package is available */
204 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
205 if (result == 0) {
206 result = io_open(fip_dev_handle, spec, &local_image_handle);
207 if (result == 0) {
208 VERBOSE("Using FIP\n");
209 io_close(local_image_handle);
210 }
211 }
212 return result;
213}
214
215static int open_memmap(const uintptr_t spec)
216{
217 int result;
218 uintptr_t local_image_handle;
219
220 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
221 if (result == 0) {
222 result = io_open(memmap_dev_handle, spec, &local_image_handle);
223 if (result == 0) {
224 VERBOSE("Using Memmap\n");
225 io_close(local_image_handle);
226 }
227 }
228 return result;
229}
230
231void plat_rpi3_io_setup(void)
232{
233 int io_result;
234
235 io_result = register_io_dev_fip(&fip_dev_con);
236 assert(io_result == 0);
237
238 io_result = register_io_dev_memmap(&memmap_dev_con);
239 assert(io_result == 0);
240
241 /* Open connections to devices and cache the handles */
242 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
243 &fip_dev_handle);
244 assert(io_result == 0);
245
246 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
247 &memmap_dev_handle);
248 assert(io_result == 0);
249
250 /* Ignore improbable errors in release builds */
251 (void)io_result;
252}
253
254/*
255 * Return an IO device handle and specification which can be used to access
256 * an image. Use this to enforce platform load policy
257 */
258int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
259 uintptr_t *image_spec)
260{
261 int result;
262 const struct plat_io_policy *policy;
263
264 assert(image_id < ARRAY_SIZE(policies));
265
266 policy = &policies[image_id];
267 result = policy->check(policy->image_spec);
268 if (result == 0) {
269 *image_spec = policy->image_spec;
270 *dev_handle = *(policy->dev_handle);
271 }
272
273 return result;
274}