blob: cff3b0d235ae3651d08c41a25285f30a84350db6 [file] [log] [blame]
Haojian Zhuang602362d2017-06-01 12:15:14 +08001/*
Haojian Zhuang1b4b4122018-01-25 16:13:05 +08002 * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
Haojian Zhuang602362d2017-06-01 12:15:14 +08003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch_helpers.h>
8#include <assert.h>
9#include <debug.h>
10#include <errno.h>
11#include <firmware_image_package.h>
12#include <io_block.h>
13#include <io_driver.h>
14#include <io_fip.h>
15#include <io_memmap.h>
16#include <io_storage.h>
17#include <mmio.h>
18#include <platform_def.h>
19#include <semihosting.h> /* For FOPEN_MODE_... */
20#include <string.h>
21#include <ufs.h>
22
23struct plat_io_policy {
24 uintptr_t *dev_handle;
25 uintptr_t image_spec;
26 int (*check)(const uintptr_t spec);
27};
28
29static const io_dev_connector_t *ufs_dev_con, *fip_dev_con;
30static uintptr_t ufs_dev_handle, fip_dev_handle;
31
32static int check_ufs(const uintptr_t spec);
33static int check_fip(const uintptr_t spec);
34size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size);
35size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size);
36
37static const io_block_spec_t ufs_fip_spec = {
38 .offset = HIKEY960_FIP_BASE,
39 .length = HIKEY960_FIP_MAX_SIZE,
40};
41
Haojian Zhuang602362d2017-06-01 12:15:14 +080042static const io_block_dev_spec_t ufs_dev_spec = {
43 /* It's used as temp buffer in block driver. */
44 .buffer = {
45 .offset = HIKEY960_UFS_DATA_BASE,
46 .length = HIKEY960_UFS_DATA_SIZE,
47 },
48 .ops = {
49 .read = ufs_read_lun3_blks,
50 .write = ufs_write_lun3_blks,
51 },
52 .block_size = UFS_BLOCK_SIZE,
53};
54
Haojian Zhuang602362d2017-06-01 12:15:14 +080055static const io_uuid_spec_t scp_bl2_uuid_spec = {
56 .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
57};
58
59static const io_uuid_spec_t bl31_uuid_spec = {
60 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
61};
62
Victor Chong91287682017-05-28 00:14:37 +090063static const io_uuid_spec_t bl32_uuid_spec = {
64 .uuid = UUID_SECURE_PAYLOAD_BL32,
65};
66
Victor Chong7d787f52017-08-16 13:53:56 +090067static const io_uuid_spec_t bl32_extra1_uuid_spec = {
68 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
69};
70
71static const io_uuid_spec_t bl32_extra2_uuid_spec = {
72 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
73};
74
Haojian Zhuang602362d2017-06-01 12:15:14 +080075static const io_uuid_spec_t bl33_uuid_spec = {
76 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
77};
78
Teddy Reeddd3f0a82018-09-03 17:38:50 -040079#if TRUSTED_BOARD_BOOT
80static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
81 .uuid = UUID_TRUSTED_KEY_CERT,
82};
83
84static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
85 .uuid = UUID_SCP_FW_KEY_CERT,
86};
87
88static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
89 .uuid = UUID_SOC_FW_KEY_CERT,
90};
91
92static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
93 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
94};
95
96static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
97 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
98};
99
100static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
101 .uuid = UUID_SCP_FW_CONTENT_CERT,
102};
103
104static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
105 .uuid = UUID_SOC_FW_CONTENT_CERT,
106};
107
108static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
109 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
110};
111
112static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
113 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
114};
115#endif /* TRUSTED_BOARD_BOOT */
116
Haojian Zhuang602362d2017-06-01 12:15:14 +0800117static const struct plat_io_policy policies[] = {
118 [FIP_IMAGE_ID] = {
119 &ufs_dev_handle,
120 (uintptr_t)&ufs_fip_spec,
121 check_ufs
122 },
Haojian Zhuang602362d2017-06-01 12:15:14 +0800123 [SCP_BL2_IMAGE_ID] = {
124 &fip_dev_handle,
125 (uintptr_t)&scp_bl2_uuid_spec,
126 check_fip
127 },
128 [BL31_IMAGE_ID] = {
129 &fip_dev_handle,
130 (uintptr_t)&bl31_uuid_spec,
131 check_fip
132 },
Victor Chong91287682017-05-28 00:14:37 +0900133 [BL32_IMAGE_ID] = {
134 &fip_dev_handle,
135 (uintptr_t)&bl32_uuid_spec,
136 check_fip
137 },
Victor Chong7d787f52017-08-16 13:53:56 +0900138 [BL32_EXTRA1_IMAGE_ID] = {
139 &fip_dev_handle,
140 (uintptr_t)&bl32_extra1_uuid_spec,
141 check_fip
142 },
143 [BL32_EXTRA2_IMAGE_ID] = {
144 &fip_dev_handle,
145 (uintptr_t)&bl32_extra2_uuid_spec,
146 check_fip
147 },
Haojian Zhuang602362d2017-06-01 12:15:14 +0800148 [BL33_IMAGE_ID] = {
149 &fip_dev_handle,
150 (uintptr_t)&bl33_uuid_spec,
151 check_fip
Teddy Reeddd3f0a82018-09-03 17:38:50 -0400152 },
153#if TRUSTED_BOARD_BOOT
154 [TRUSTED_KEY_CERT_ID] = {
155 &fip_dev_handle,
156 (uintptr_t)&trusted_key_cert_uuid_spec,
157 check_fip
158 },
159 [SCP_FW_KEY_CERT_ID] = {
160 &fip_dev_handle,
161 (uintptr_t)&scp_fw_key_cert_uuid_spec,
162 check_fip
163 },
164 [SOC_FW_KEY_CERT_ID] = {
165 &fip_dev_handle,
166 (uintptr_t)&soc_fw_key_cert_uuid_spec,
167 check_fip
168 },
169 [TRUSTED_OS_FW_KEY_CERT_ID] = {
170 &fip_dev_handle,
171 (uintptr_t)&tos_fw_key_cert_uuid_spec,
172 check_fip
173 },
174 [NON_TRUSTED_FW_KEY_CERT_ID] = {
175 &fip_dev_handle,
176 (uintptr_t)&nt_fw_key_cert_uuid_spec,
177 check_fip
178 },
179 [SCP_FW_CONTENT_CERT_ID] = {
180 &fip_dev_handle,
181 (uintptr_t)&scp_fw_cert_uuid_spec,
182 check_fip
183 },
184 [SOC_FW_CONTENT_CERT_ID] = {
185 &fip_dev_handle,
186 (uintptr_t)&soc_fw_cert_uuid_spec,
187 check_fip
188 },
189 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
190 &fip_dev_handle,
191 (uintptr_t)&tos_fw_cert_uuid_spec,
192 check_fip
193 },
194 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
195 &fip_dev_handle,
196 (uintptr_t)&nt_fw_cert_uuid_spec,
197 check_fip
198 },
199#endif /* TRUSTED_BOARD_BOOT */
Haojian Zhuang602362d2017-06-01 12:15:14 +0800200};
201
202static int check_ufs(const uintptr_t spec)
203{
204 int result;
205 uintptr_t local_handle;
206
207 result = io_dev_init(ufs_dev_handle, (uintptr_t)NULL);
208 if (result == 0) {
209 result = io_open(ufs_dev_handle, spec, &local_handle);
210 if (result == 0)
211 io_close(local_handle);
212 }
213 return result;
214}
215
216static int check_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
233void hikey960_io_setup(void)
234{
235 int result;
236
237 result = register_io_dev_block(&ufs_dev_con);
238 assert(result == 0);
239
240 result = register_io_dev_fip(&fip_dev_con);
241 assert(result == 0);
242
243 result = io_dev_open(ufs_dev_con, (uintptr_t)&ufs_dev_spec,
244 &ufs_dev_handle);
245 assert(result == 0);
246
247 result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle);
248 assert(result == 0);
249
250 /* Ignore improbable errors in release builds */
251 (void)result;
252}
253
254/* Return an IO device handle and specification which can be used to access
255 * an image. Use this to enforce platform load policy
256 */
257int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
258 uintptr_t *image_spec)
259{
260 int result;
261 const struct plat_io_policy *policy;
262
263 assert(image_id < ARRAY_SIZE(policies));
264
265 policy = &policies[image_id];
266 result = policy->check(policy->image_spec);
267 assert(result == 0);
268
269 *image_spec = policy->image_spec;
270 *dev_handle = *(policy->dev_handle);
271
272 return result;
273}
274
275size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size)
276{
277 return ufs_read_blocks(3, lba, buf, size);
278}
279
280size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size)
281{
282 return ufs_write_blocks(3, lba, buf, size);
283}