blob: 883085bd8533e79ebe1f1004de93e1ef05109e06 [file] [log] [blame]
Haojian Zhuang602362d2017-06-01 12:15:14 +08001/*
Lukas Hanel8a4de612022-03-01 14:18:22 +01002 * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
Haojian Zhuang602362d2017-06-01 12:15:14 +08003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Haojian Zhuang602362d2017-06-01 12:15:14 +08007#include <assert.h>
Haojian Zhuang602362d2017-06-01 12:15:14 +08008#include <errno.h>
Haojian Zhuang602362d2017-06-01 12:15:14 +08009#include <string.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010
11#include <platform_def.h>
12
13#include <arch_helpers.h>
14#include <common/debug.h>
15#include <drivers/ufs.h>
16#include <drivers/io/io_block.h>
17#include <drivers/io/io_driver.h>
18#include <drivers/io/io_fip.h>
19#include <drivers/io/io_memmap.h>
20#include <drivers/io/io_storage.h>
Haojian Zhuang32052ab2019-09-14 18:43:51 +080021#include <drivers/partition/partition.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000022#include <lib/mmio.h>
23#include <lib/semihosting.h>
24#include <tools_share/firmware_image_package.h>
Haojian Zhuang602362d2017-06-01 12:15:14 +080025
26struct plat_io_policy {
27 uintptr_t *dev_handle;
28 uintptr_t image_spec;
29 int (*check)(const uintptr_t spec);
30};
31
32static const io_dev_connector_t *ufs_dev_con, *fip_dev_con;
33static uintptr_t ufs_dev_handle, fip_dev_handle;
34
35static int check_ufs(const uintptr_t spec);
36static int check_fip(const uintptr_t spec);
37size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size);
38size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size);
39
Haojian Zhuang32052ab2019-09-14 18:43:51 +080040static io_block_spec_t ufs_fip_spec;
41
42static const io_block_spec_t ufs_gpt_spec = {
43 .offset = 0,
44 .length = PLAT_PARTITION_BLOCK_SIZE *
45 (PLAT_PARTITION_MAX_ENTRIES / 4 + 2),
Haojian Zhuang602362d2017-06-01 12:15:14 +080046};
47
Haojian Zhuang602362d2017-06-01 12:15:14 +080048static const io_block_dev_spec_t ufs_dev_spec = {
49 /* It's used as temp buffer in block driver. */
50 .buffer = {
51 .offset = HIKEY960_UFS_DATA_BASE,
52 .length = HIKEY960_UFS_DATA_SIZE,
53 },
54 .ops = {
55 .read = ufs_read_lun3_blks,
56 .write = ufs_write_lun3_blks,
57 },
58 .block_size = UFS_BLOCK_SIZE,
59};
60
Haojian Zhuang602362d2017-06-01 12:15:14 +080061static const io_uuid_spec_t scp_bl2_uuid_spec = {
62 .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
63};
64
65static const io_uuid_spec_t bl31_uuid_spec = {
66 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
67};
68
Victor Chong91287682017-05-28 00:14:37 +090069static const io_uuid_spec_t bl32_uuid_spec = {
70 .uuid = UUID_SECURE_PAYLOAD_BL32,
71};
72
Victor Chong7d787f52017-08-16 13:53:56 +090073static const io_uuid_spec_t bl32_extra1_uuid_spec = {
74 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
75};
76
77static const io_uuid_spec_t bl32_extra2_uuid_spec = {
78 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
79};
80
Lukas Hanel8a4de612022-03-01 14:18:22 +010081#ifdef SPD_spmd
82static const io_uuid_spec_t bl32_tos_fw_spec = {
83 .uuid = UUID_TOS_FW_CONFIG,
84};
85#endif
86
Haojian Zhuang602362d2017-06-01 12:15:14 +080087static const io_uuid_spec_t bl33_uuid_spec = {
88 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
89};
90
Teddy Reeddd3f0a82018-09-03 17:38:50 -040091#if TRUSTED_BOARD_BOOT
92static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
93 .uuid = UUID_TRUSTED_KEY_CERT,
94};
95
96static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
97 .uuid = UUID_SCP_FW_KEY_CERT,
98};
99
100static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
101 .uuid = UUID_SOC_FW_KEY_CERT,
102};
103
104static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
105 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
106};
107
108static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
109 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
110};
111
112static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
113 .uuid = UUID_SCP_FW_CONTENT_CERT,
114};
115
116static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
117 .uuid = UUID_SOC_FW_CONTENT_CERT,
118};
119
120static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
121 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
122};
123
124static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
125 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
126};
127#endif /* TRUSTED_BOARD_BOOT */
128
Haojian Zhuang602362d2017-06-01 12:15:14 +0800129static const struct plat_io_policy policies[] = {
130 [FIP_IMAGE_ID] = {
131 &ufs_dev_handle,
132 (uintptr_t)&ufs_fip_spec,
133 check_ufs
134 },
Haojian Zhuang602362d2017-06-01 12:15:14 +0800135 [SCP_BL2_IMAGE_ID] = {
136 &fip_dev_handle,
137 (uintptr_t)&scp_bl2_uuid_spec,
138 check_fip
139 },
140 [BL31_IMAGE_ID] = {
141 &fip_dev_handle,
142 (uintptr_t)&bl31_uuid_spec,
143 check_fip
144 },
Victor Chong91287682017-05-28 00:14:37 +0900145 [BL32_IMAGE_ID] = {
146 &fip_dev_handle,
147 (uintptr_t)&bl32_uuid_spec,
148 check_fip
149 },
Victor Chong7d787f52017-08-16 13:53:56 +0900150 [BL32_EXTRA1_IMAGE_ID] = {
151 &fip_dev_handle,
152 (uintptr_t)&bl32_extra1_uuid_spec,
153 check_fip
154 },
155 [BL32_EXTRA2_IMAGE_ID] = {
156 &fip_dev_handle,
157 (uintptr_t)&bl32_extra2_uuid_spec,
158 check_fip
159 },
Lukas Hanel8a4de612022-03-01 14:18:22 +0100160
161#ifdef SPD_spmd
162 [TOS_FW_CONFIG_ID] = {
163 &fip_dev_handle,
164 (uintptr_t)&bl32_tos_fw_spec,
165 check_fip
166 },
167#endif
168
Haojian Zhuang602362d2017-06-01 12:15:14 +0800169 [BL33_IMAGE_ID] = {
170 &fip_dev_handle,
171 (uintptr_t)&bl33_uuid_spec,
172 check_fip
Teddy Reeddd3f0a82018-09-03 17:38:50 -0400173 },
174#if TRUSTED_BOARD_BOOT
175 [TRUSTED_KEY_CERT_ID] = {
176 &fip_dev_handle,
177 (uintptr_t)&trusted_key_cert_uuid_spec,
178 check_fip
179 },
180 [SCP_FW_KEY_CERT_ID] = {
181 &fip_dev_handle,
182 (uintptr_t)&scp_fw_key_cert_uuid_spec,
183 check_fip
184 },
185 [SOC_FW_KEY_CERT_ID] = {
186 &fip_dev_handle,
187 (uintptr_t)&soc_fw_key_cert_uuid_spec,
188 check_fip
189 },
190 [TRUSTED_OS_FW_KEY_CERT_ID] = {
191 &fip_dev_handle,
192 (uintptr_t)&tos_fw_key_cert_uuid_spec,
193 check_fip
194 },
195 [NON_TRUSTED_FW_KEY_CERT_ID] = {
196 &fip_dev_handle,
197 (uintptr_t)&nt_fw_key_cert_uuid_spec,
198 check_fip
199 },
200 [SCP_FW_CONTENT_CERT_ID] = {
201 &fip_dev_handle,
202 (uintptr_t)&scp_fw_cert_uuid_spec,
203 check_fip
204 },
205 [SOC_FW_CONTENT_CERT_ID] = {
206 &fip_dev_handle,
207 (uintptr_t)&soc_fw_cert_uuid_spec,
208 check_fip
209 },
210 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
211 &fip_dev_handle,
212 (uintptr_t)&tos_fw_cert_uuid_spec,
213 check_fip
214 },
215 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
216 &fip_dev_handle,
217 (uintptr_t)&nt_fw_cert_uuid_spec,
218 check_fip
219 },
220#endif /* TRUSTED_BOARD_BOOT */
Haojian Zhuang32052ab2019-09-14 18:43:51 +0800221 [GPT_IMAGE_ID] = {
222 &ufs_dev_handle,
223 (uintptr_t)&ufs_gpt_spec,
224 check_ufs
225 },
Haojian Zhuang602362d2017-06-01 12:15:14 +0800226};
227
228static int check_ufs(const uintptr_t spec)
229{
230 int result;
231 uintptr_t local_handle;
232
233 result = io_dev_init(ufs_dev_handle, (uintptr_t)NULL);
234 if (result == 0) {
235 result = io_open(ufs_dev_handle, spec, &local_handle);
236 if (result == 0)
237 io_close(local_handle);
238 }
239 return result;
240}
241
242static int check_fip(const uintptr_t spec)
243{
244 int result;
245 uintptr_t local_image_handle;
246
247 /* See if a Firmware Image Package is available */
248 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
249 if (result == 0) {
250 result = io_open(fip_dev_handle, spec, &local_image_handle);
251 if (result == 0) {
252 VERBOSE("Using FIP\n");
253 io_close(local_image_handle);
254 }
255 }
256 return result;
257}
258
259void hikey960_io_setup(void)
260{
261 int result;
262
263 result = register_io_dev_block(&ufs_dev_con);
264 assert(result == 0);
265
266 result = register_io_dev_fip(&fip_dev_con);
267 assert(result == 0);
268
269 result = io_dev_open(ufs_dev_con, (uintptr_t)&ufs_dev_spec,
270 &ufs_dev_handle);
271 assert(result == 0);
272
273 result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle);
274 assert(result == 0);
275
276 /* Ignore improbable errors in release builds */
277 (void)result;
278}
279
Haojian Zhuang32052ab2019-09-14 18:43:51 +0800280int hikey960_set_fip_addr(unsigned int image_id, const char *name)
281{
282 const partition_entry_t *entry;
283
284 if (ufs_fip_spec.length == 0) {
285 partition_init(GPT_IMAGE_ID);
286 entry = get_partition_entry(name);
287 if (entry == NULL) {
288 ERROR("Could NOT find the %s partition!\n", name);
289 return -ENOENT;
290 }
291 ufs_fip_spec.offset = entry->start;
292 ufs_fip_spec.length = entry->length;
293 }
294 return 0;
295}
296
Haojian Zhuang602362d2017-06-01 12:15:14 +0800297/* Return an IO device handle and specification which can be used to access
298 * an image. Use this to enforce platform load policy
299 */
300int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
301 uintptr_t *image_spec)
302{
303 int result;
304 const struct plat_io_policy *policy;
305
306 assert(image_id < ARRAY_SIZE(policies));
307
308 policy = &policies[image_id];
309 result = policy->check(policy->image_spec);
310 assert(result == 0);
311
312 *image_spec = policy->image_spec;
313 *dev_handle = *(policy->dev_handle);
314
315 return result;
316}
317
318size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size)
319{
320 return ufs_read_blocks(3, lba, buf, size);
321}
322
323size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size)
324{
325 return ufs_write_blocks(3, lba, buf, size);
326}