1*4f2b9848SAndre Przywara /*
2*4f2b9848SAndre Przywara * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
3*4f2b9848SAndre Przywara *
4*4f2b9848SAndre Przywara * SPDX-License-Identifier: BSD-3-Clause
5*4f2b9848SAndre Przywara */
6*4f2b9848SAndre Przywara
7*4f2b9848SAndre Przywara #include <assert.h>
8*4f2b9848SAndre Przywara #include <string.h>
9*4f2b9848SAndre Przywara
10*4f2b9848SAndre Przywara #include <platform_def.h>
11*4f2b9848SAndre Przywara
12*4f2b9848SAndre Przywara #include <common/bl_common.h>
13*4f2b9848SAndre Przywara #include <common/debug.h>
14*4f2b9848SAndre Przywara #include <drivers/io/io_driver.h>
15*4f2b9848SAndre Przywara #include <drivers/io/io_fip.h>
16*4f2b9848SAndre Przywara #include <drivers/io/io_memmap.h>
17*4f2b9848SAndre Przywara #include <tools_share/firmware_image_package.h>
18*4f2b9848SAndre Przywara
19*4f2b9848SAndre Przywara /* Semihosting filenames */
20*4f2b9848SAndre Przywara #define BL2_IMAGE_NAME "bl2.bin"
21*4f2b9848SAndre Przywara #define BL31_IMAGE_NAME "bl31.bin"
22*4f2b9848SAndre Przywara #define BL32_IMAGE_NAME "bl32.bin"
23*4f2b9848SAndre Przywara #define BL33_IMAGE_NAME "bl33.bin"
24*4f2b9848SAndre Przywara
25*4f2b9848SAndre Przywara #if TRUSTED_BOARD_BOOT
26*4f2b9848SAndre Przywara #define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt"
27*4f2b9848SAndre Przywara #define TRUSTED_KEY_CERT_NAME "trusted_key.crt"
28*4f2b9848SAndre Przywara #define SOC_FW_KEY_CERT_NAME "soc_fw_key.crt"
29*4f2b9848SAndre Przywara #define TOS_FW_KEY_CERT_NAME "tos_fw_key.crt"
30*4f2b9848SAndre Przywara #define NT_FW_KEY_CERT_NAME "nt_fw_key.crt"
31*4f2b9848SAndre Przywara #define SOC_FW_CONTENT_CERT_NAME "soc_fw_content.crt"
32*4f2b9848SAndre Przywara #define TOS_FW_CONTENT_CERT_NAME "tos_fw_content.crt"
33*4f2b9848SAndre Przywara #define NT_FW_CONTENT_CERT_NAME "nt_fw_content.crt"
34*4f2b9848SAndre Przywara #endif /* TRUSTED_BOARD_BOOT */
35*4f2b9848SAndre Przywara
36*4f2b9848SAndre Przywara /* IO devices */
37*4f2b9848SAndre Przywara static const io_dev_connector_t *fip_dev_con;
38*4f2b9848SAndre Przywara static uintptr_t fip_dev_handle;
39*4f2b9848SAndre Przywara static const io_dev_connector_t *memmap_dev_con;
40*4f2b9848SAndre Przywara static uintptr_t memmap_dev_handle;
41*4f2b9848SAndre Przywara
42*4f2b9848SAndre Przywara static const io_block_spec_t fip_block_spec = {
43*4f2b9848SAndre Przywara .offset = PLAT_RPI3_FIP_BASE,
44*4f2b9848SAndre Przywara .length = PLAT_RPI3_FIP_MAX_SIZE
45*4f2b9848SAndre Przywara };
46*4f2b9848SAndre Przywara
47*4f2b9848SAndre Przywara static const io_uuid_spec_t bl2_uuid_spec = {
48*4f2b9848SAndre Przywara .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
49*4f2b9848SAndre Przywara };
50*4f2b9848SAndre Przywara
51*4f2b9848SAndre Przywara static const io_uuid_spec_t bl31_uuid_spec = {
52*4f2b9848SAndre Przywara .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
53*4f2b9848SAndre Przywara };
54*4f2b9848SAndre Przywara
55*4f2b9848SAndre Przywara static const io_uuid_spec_t bl32_uuid_spec = {
56*4f2b9848SAndre Przywara .uuid = UUID_SECURE_PAYLOAD_BL32,
57*4f2b9848SAndre Przywara };
58*4f2b9848SAndre Przywara
59*4f2b9848SAndre Przywara static const io_uuid_spec_t bl32_extra1_uuid_spec = {
60*4f2b9848SAndre Przywara .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
61*4f2b9848SAndre Przywara };
62*4f2b9848SAndre Przywara
63*4f2b9848SAndre Przywara static const io_uuid_spec_t bl32_extra2_uuid_spec = {
64*4f2b9848SAndre Przywara .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
65*4f2b9848SAndre Przywara };
66*4f2b9848SAndre Przywara
67*4f2b9848SAndre Przywara static const io_uuid_spec_t bl33_uuid_spec = {
68*4f2b9848SAndre Przywara .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
69*4f2b9848SAndre Przywara };
70*4f2b9848SAndre Przywara
71*4f2b9848SAndre Przywara #if TRUSTED_BOARD_BOOT
72*4f2b9848SAndre Przywara static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
73*4f2b9848SAndre Przywara .uuid = UUID_TRUSTED_BOOT_FW_CERT,
74*4f2b9848SAndre Przywara };
75*4f2b9848SAndre Przywara
76*4f2b9848SAndre Przywara static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
77*4f2b9848SAndre Przywara .uuid = UUID_TRUSTED_KEY_CERT,
78*4f2b9848SAndre Przywara };
79*4f2b9848SAndre Przywara
80*4f2b9848SAndre Przywara static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
81*4f2b9848SAndre Przywara .uuid = UUID_SOC_FW_KEY_CERT,
82*4f2b9848SAndre Przywara };
83*4f2b9848SAndre Przywara
84*4f2b9848SAndre Przywara static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
85*4f2b9848SAndre Przywara .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
86*4f2b9848SAndre Przywara };
87*4f2b9848SAndre Przywara
88*4f2b9848SAndre Przywara static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
89*4f2b9848SAndre Przywara .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
90*4f2b9848SAndre Przywara };
91*4f2b9848SAndre Przywara
92*4f2b9848SAndre Przywara static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
93*4f2b9848SAndre Przywara .uuid = UUID_SOC_FW_CONTENT_CERT,
94*4f2b9848SAndre Przywara };
95*4f2b9848SAndre Przywara
96*4f2b9848SAndre Przywara static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
97*4f2b9848SAndre Przywara .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
98*4f2b9848SAndre Przywara };
99*4f2b9848SAndre Przywara
100*4f2b9848SAndre Przywara static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
101*4f2b9848SAndre Przywara .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
102*4f2b9848SAndre Przywara };
103*4f2b9848SAndre Przywara #endif /* TRUSTED_BOARD_BOOT */
104*4f2b9848SAndre Przywara
105*4f2b9848SAndre Przywara static int open_fip(const uintptr_t spec);
106*4f2b9848SAndre Przywara static int open_memmap(const uintptr_t spec);
107*4f2b9848SAndre Przywara
108*4f2b9848SAndre Przywara struct plat_io_policy {
109*4f2b9848SAndre Przywara uintptr_t *dev_handle;
110*4f2b9848SAndre Przywara uintptr_t image_spec;
111*4f2b9848SAndre Przywara int (*check)(const uintptr_t spec);
112*4f2b9848SAndre Przywara };
113*4f2b9848SAndre Przywara
114*4f2b9848SAndre Przywara /* By default, load images from the FIP */
115*4f2b9848SAndre Przywara static const struct plat_io_policy policies[] = {
116*4f2b9848SAndre Przywara [FIP_IMAGE_ID] = {
117*4f2b9848SAndre Przywara &memmap_dev_handle,
118*4f2b9848SAndre Przywara (uintptr_t)&fip_block_spec,
119*4f2b9848SAndre Przywara open_memmap
120*4f2b9848SAndre Przywara },
121*4f2b9848SAndre Przywara [BL2_IMAGE_ID] = {
122*4f2b9848SAndre Przywara &fip_dev_handle,
123*4f2b9848SAndre Przywara (uintptr_t)&bl2_uuid_spec,
124*4f2b9848SAndre Przywara open_fip
125*4f2b9848SAndre Przywara },
126*4f2b9848SAndre Przywara [BL31_IMAGE_ID] = {
127*4f2b9848SAndre Przywara &fip_dev_handle,
128*4f2b9848SAndre Przywara (uintptr_t)&bl31_uuid_spec,
129*4f2b9848SAndre Przywara open_fip
130*4f2b9848SAndre Przywara },
131*4f2b9848SAndre Przywara [BL32_IMAGE_ID] = {
132*4f2b9848SAndre Przywara &fip_dev_handle,
133*4f2b9848SAndre Przywara (uintptr_t)&bl32_uuid_spec,
134*4f2b9848SAndre Przywara open_fip
135*4f2b9848SAndre Przywara },
136*4f2b9848SAndre Przywara [BL32_EXTRA1_IMAGE_ID] = {
137*4f2b9848SAndre Przywara &fip_dev_handle,
138*4f2b9848SAndre Przywara (uintptr_t)&bl32_extra1_uuid_spec,
139*4f2b9848SAndre Przywara open_fip
140*4f2b9848SAndre Przywara },
141*4f2b9848SAndre Przywara [BL32_EXTRA2_IMAGE_ID] = {
142*4f2b9848SAndre Przywara &fip_dev_handle,
143*4f2b9848SAndre Przywara (uintptr_t)&bl32_extra2_uuid_spec,
144*4f2b9848SAndre Przywara open_fip
145*4f2b9848SAndre Przywara },
146*4f2b9848SAndre Przywara [BL33_IMAGE_ID] = {
147*4f2b9848SAndre Przywara &fip_dev_handle,
148*4f2b9848SAndre Przywara (uintptr_t)&bl33_uuid_spec,
149*4f2b9848SAndre Przywara open_fip
150*4f2b9848SAndre Przywara },
151*4f2b9848SAndre Przywara #if TRUSTED_BOARD_BOOT
152*4f2b9848SAndre Przywara [TRUSTED_BOOT_FW_CERT_ID] = {
153*4f2b9848SAndre Przywara &fip_dev_handle,
154*4f2b9848SAndre Przywara (uintptr_t)&tb_fw_cert_uuid_spec,
155*4f2b9848SAndre Przywara open_fip
156*4f2b9848SAndre Przywara },
157*4f2b9848SAndre Przywara [TRUSTED_KEY_CERT_ID] = {
158*4f2b9848SAndre Przywara &fip_dev_handle,
159*4f2b9848SAndre Przywara (uintptr_t)&trusted_key_cert_uuid_spec,
160*4f2b9848SAndre Przywara open_fip
161*4f2b9848SAndre Przywara },
162*4f2b9848SAndre Przywara [SOC_FW_KEY_CERT_ID] = {
163*4f2b9848SAndre Przywara &fip_dev_handle,
164*4f2b9848SAndre Przywara (uintptr_t)&soc_fw_key_cert_uuid_spec,
165*4f2b9848SAndre Przywara open_fip
166*4f2b9848SAndre Przywara },
167*4f2b9848SAndre Przywara [TRUSTED_OS_FW_KEY_CERT_ID] = {
168*4f2b9848SAndre Przywara &fip_dev_handle,
169*4f2b9848SAndre Przywara (uintptr_t)&tos_fw_key_cert_uuid_spec,
170*4f2b9848SAndre Przywara open_fip
171*4f2b9848SAndre Przywara },
172*4f2b9848SAndre Przywara [NON_TRUSTED_FW_KEY_CERT_ID] = {
173*4f2b9848SAndre Przywara &fip_dev_handle,
174*4f2b9848SAndre Przywara (uintptr_t)&nt_fw_key_cert_uuid_spec,
175*4f2b9848SAndre Przywara open_fip
176*4f2b9848SAndre Przywara },
177*4f2b9848SAndre Przywara [SOC_FW_CONTENT_CERT_ID] = {
178*4f2b9848SAndre Przywara &fip_dev_handle,
179*4f2b9848SAndre Przywara (uintptr_t)&soc_fw_cert_uuid_spec,
180*4f2b9848SAndre Przywara open_fip
181*4f2b9848SAndre Przywara },
182*4f2b9848SAndre Przywara [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
183*4f2b9848SAndre Przywara &fip_dev_handle,
184*4f2b9848SAndre Przywara (uintptr_t)&tos_fw_cert_uuid_spec,
185*4f2b9848SAndre Przywara open_fip
186*4f2b9848SAndre Przywara },
187*4f2b9848SAndre Przywara [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
188*4f2b9848SAndre Przywara &fip_dev_handle,
189*4f2b9848SAndre Przywara (uintptr_t)&nt_fw_cert_uuid_spec,
190*4f2b9848SAndre Przywara open_fip
191*4f2b9848SAndre Przywara },
192*4f2b9848SAndre Przywara #endif /* TRUSTED_BOARD_BOOT */
193*4f2b9848SAndre Przywara };
194*4f2b9848SAndre Przywara
open_fip(const uintptr_t spec)195*4f2b9848SAndre Przywara static int open_fip(const uintptr_t spec)
196*4f2b9848SAndre Przywara {
197*4f2b9848SAndre Przywara int result;
198*4f2b9848SAndre Przywara uintptr_t local_image_handle;
199*4f2b9848SAndre Przywara
200*4f2b9848SAndre Przywara /* See if a Firmware Image Package is available */
201*4f2b9848SAndre Przywara result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
202*4f2b9848SAndre Przywara if (result == 0) {
203*4f2b9848SAndre Przywara result = io_open(fip_dev_handle, spec, &local_image_handle);
204*4f2b9848SAndre Przywara if (result == 0) {
205*4f2b9848SAndre Przywara VERBOSE("Using FIP\n");
206*4f2b9848SAndre Przywara io_close(local_image_handle);
207*4f2b9848SAndre Przywara }
208*4f2b9848SAndre Przywara }
209*4f2b9848SAndre Przywara return result;
210*4f2b9848SAndre Przywara }
211*4f2b9848SAndre Przywara
open_memmap(const uintptr_t spec)212*4f2b9848SAndre Przywara static int open_memmap(const uintptr_t spec)
213*4f2b9848SAndre Przywara {
214*4f2b9848SAndre Przywara int result;
215*4f2b9848SAndre Przywara uintptr_t local_image_handle;
216*4f2b9848SAndre Przywara
217*4f2b9848SAndre Przywara result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
218*4f2b9848SAndre Przywara if (result == 0) {
219*4f2b9848SAndre Przywara result = io_open(memmap_dev_handle, spec, &local_image_handle);
220*4f2b9848SAndre Przywara if (result == 0) {
221*4f2b9848SAndre Przywara VERBOSE("Using Memmap\n");
222*4f2b9848SAndre Przywara io_close(local_image_handle);
223*4f2b9848SAndre Przywara }
224*4f2b9848SAndre Przywara }
225*4f2b9848SAndre Przywara return result;
226*4f2b9848SAndre Przywara }
227*4f2b9848SAndre Przywara
plat_rpi3_io_setup(void)228*4f2b9848SAndre Przywara void plat_rpi3_io_setup(void)
229*4f2b9848SAndre Przywara {
230*4f2b9848SAndre Przywara int io_result;
231*4f2b9848SAndre Przywara
232*4f2b9848SAndre Przywara io_result = register_io_dev_fip(&fip_dev_con);
233*4f2b9848SAndre Przywara assert(io_result == 0);
234*4f2b9848SAndre Przywara
235*4f2b9848SAndre Przywara io_result = register_io_dev_memmap(&memmap_dev_con);
236*4f2b9848SAndre Przywara assert(io_result == 0);
237*4f2b9848SAndre Przywara
238*4f2b9848SAndre Przywara /* Open connections to devices and cache the handles */
239*4f2b9848SAndre Przywara io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
240*4f2b9848SAndre Przywara &fip_dev_handle);
241*4f2b9848SAndre Przywara assert(io_result == 0);
242*4f2b9848SAndre Przywara
243*4f2b9848SAndre Przywara io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
244*4f2b9848SAndre Przywara &memmap_dev_handle);
245*4f2b9848SAndre Przywara assert(io_result == 0);
246*4f2b9848SAndre Przywara
247*4f2b9848SAndre Przywara /* Ignore improbable errors in release builds */
248*4f2b9848SAndre Przywara (void)io_result;
249*4f2b9848SAndre Przywara }
250*4f2b9848SAndre Przywara
251*4f2b9848SAndre Przywara /*
252*4f2b9848SAndre Przywara * Return an IO device handle and specification which can be used to access
253*4f2b9848SAndre Przywara * an image. Use this to enforce platform load policy
254*4f2b9848SAndre Przywara */
plat_get_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)255*4f2b9848SAndre Przywara int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
256*4f2b9848SAndre Przywara uintptr_t *image_spec)
257*4f2b9848SAndre Przywara {
258*4f2b9848SAndre Przywara int result;
259*4f2b9848SAndre Przywara const struct plat_io_policy *policy;
260*4f2b9848SAndre Przywara
261*4f2b9848SAndre Przywara assert(image_id < ARRAY_SIZE(policies));
262*4f2b9848SAndre Przywara
263*4f2b9848SAndre Przywara policy = &policies[image_id];
264*4f2b9848SAndre Przywara result = policy->check(policy->image_spec);
265*4f2b9848SAndre Przywara if (result == 0) {
266*4f2b9848SAndre Przywara *image_spec = policy->image_spec;
267*4f2b9848SAndre Przywara *dev_handle = *(policy->dev_handle);
268*4f2b9848SAndre Przywara }
269*4f2b9848SAndre Przywara
270*4f2b9848SAndre Przywara return result;
271*4f2b9848SAndre Przywara }
272