blob: 475e41676930971b89caa7fb2331337d8f942d81 [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
Arthur Cassegrain97d4d812021-11-26 16:39:12 +010026#include "hikey960_def.h"
27#include "hikey960_private.h"
28
Haojian Zhuang602362d2017-06-01 12:15:14 +080029struct plat_io_policy {
30 uintptr_t *dev_handle;
31 uintptr_t image_spec;
32 int (*check)(const uintptr_t spec);
33};
34
35static const io_dev_connector_t *ufs_dev_con, *fip_dev_con;
36static uintptr_t ufs_dev_handle, fip_dev_handle;
37
38static int check_ufs(const uintptr_t spec);
39static int check_fip(const uintptr_t spec);
40size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size);
41size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size);
42
Haojian Zhuang32052ab2019-09-14 18:43:51 +080043static io_block_spec_t ufs_fip_spec;
44
45static const io_block_spec_t ufs_gpt_spec = {
46 .offset = 0,
47 .length = PLAT_PARTITION_BLOCK_SIZE *
48 (PLAT_PARTITION_MAX_ENTRIES / 4 + 2),
Haojian Zhuang602362d2017-06-01 12:15:14 +080049};
50
Arthur Cassegrain97d4d812021-11-26 16:39:12 +010051/* Fastboot serial number stored within first UFS device blocks */
52static const io_block_spec_t ufs_fastboot_spec = {
53 .offset = UFS_BASE,
54 .length = 1 << 20,
55};
56
Haojian Zhuang602362d2017-06-01 12:15:14 +080057static const io_block_dev_spec_t ufs_dev_spec = {
58 /* It's used as temp buffer in block driver. */
59 .buffer = {
60 .offset = HIKEY960_UFS_DATA_BASE,
61 .length = HIKEY960_UFS_DATA_SIZE,
62 },
63 .ops = {
64 .read = ufs_read_lun3_blks,
65 .write = ufs_write_lun3_blks,
66 },
67 .block_size = UFS_BLOCK_SIZE,
68};
69
Haojian Zhuang602362d2017-06-01 12:15:14 +080070static const io_uuid_spec_t scp_bl2_uuid_spec = {
71 .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
72};
73
74static const io_uuid_spec_t bl31_uuid_spec = {
75 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
76};
77
Victor Chong91287682017-05-28 00:14:37 +090078static const io_uuid_spec_t bl32_uuid_spec = {
79 .uuid = UUID_SECURE_PAYLOAD_BL32,
80};
81
Victor Chong7d787f52017-08-16 13:53:56 +090082static const io_uuid_spec_t bl32_extra1_uuid_spec = {
83 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
84};
85
86static const io_uuid_spec_t bl32_extra2_uuid_spec = {
87 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
88};
89
Lukas Hanel8a4de612022-03-01 14:18:22 +010090#ifdef SPD_spmd
91static const io_uuid_spec_t bl32_tos_fw_spec = {
92 .uuid = UUID_TOS_FW_CONFIG,
93};
94#endif
95
Haojian Zhuang602362d2017-06-01 12:15:14 +080096static const io_uuid_spec_t bl33_uuid_spec = {
97 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
98};
99
Teddy Reeddd3f0a82018-09-03 17:38:50 -0400100#if TRUSTED_BOARD_BOOT
101static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
102 .uuid = UUID_TRUSTED_KEY_CERT,
103};
104
105static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
106 .uuid = UUID_SCP_FW_KEY_CERT,
107};
108
109static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
110 .uuid = UUID_SOC_FW_KEY_CERT,
111};
112
113static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
114 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
115};
116
117static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
118 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
119};
120
121static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
122 .uuid = UUID_SCP_FW_CONTENT_CERT,
123};
124
125static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
126 .uuid = UUID_SOC_FW_CONTENT_CERT,
127};
128
129static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
130 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
131};
132
133static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
134 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
135};
136#endif /* TRUSTED_BOARD_BOOT */
137
Haojian Zhuang602362d2017-06-01 12:15:14 +0800138static const struct plat_io_policy policies[] = {
139 [FIP_IMAGE_ID] = {
140 &ufs_dev_handle,
141 (uintptr_t)&ufs_fip_spec,
142 check_ufs
143 },
Haojian Zhuang602362d2017-06-01 12:15:14 +0800144 [SCP_BL2_IMAGE_ID] = {
145 &fip_dev_handle,
146 (uintptr_t)&scp_bl2_uuid_spec,
147 check_fip
148 },
149 [BL31_IMAGE_ID] = {
150 &fip_dev_handle,
151 (uintptr_t)&bl31_uuid_spec,
152 check_fip
153 },
Victor Chong91287682017-05-28 00:14:37 +0900154 [BL32_IMAGE_ID] = {
155 &fip_dev_handle,
156 (uintptr_t)&bl32_uuid_spec,
157 check_fip
158 },
Victor Chong7d787f52017-08-16 13:53:56 +0900159 [BL32_EXTRA1_IMAGE_ID] = {
160 &fip_dev_handle,
161 (uintptr_t)&bl32_extra1_uuid_spec,
162 check_fip
163 },
164 [BL32_EXTRA2_IMAGE_ID] = {
165 &fip_dev_handle,
166 (uintptr_t)&bl32_extra2_uuid_spec,
167 check_fip
168 },
Lukas Hanel8a4de612022-03-01 14:18:22 +0100169
170#ifdef SPD_spmd
171 [TOS_FW_CONFIG_ID] = {
172 &fip_dev_handle,
173 (uintptr_t)&bl32_tos_fw_spec,
174 check_fip
175 },
176#endif
177
Haojian Zhuang602362d2017-06-01 12:15:14 +0800178 [BL33_IMAGE_ID] = {
179 &fip_dev_handle,
180 (uintptr_t)&bl33_uuid_spec,
181 check_fip
Teddy Reeddd3f0a82018-09-03 17:38:50 -0400182 },
183#if TRUSTED_BOARD_BOOT
184 [TRUSTED_KEY_CERT_ID] = {
185 &fip_dev_handle,
186 (uintptr_t)&trusted_key_cert_uuid_spec,
187 check_fip
188 },
189 [SCP_FW_KEY_CERT_ID] = {
190 &fip_dev_handle,
191 (uintptr_t)&scp_fw_key_cert_uuid_spec,
192 check_fip
193 },
194 [SOC_FW_KEY_CERT_ID] = {
195 &fip_dev_handle,
196 (uintptr_t)&soc_fw_key_cert_uuid_spec,
197 check_fip
198 },
199 [TRUSTED_OS_FW_KEY_CERT_ID] = {
200 &fip_dev_handle,
201 (uintptr_t)&tos_fw_key_cert_uuid_spec,
202 check_fip
203 },
204 [NON_TRUSTED_FW_KEY_CERT_ID] = {
205 &fip_dev_handle,
206 (uintptr_t)&nt_fw_key_cert_uuid_spec,
207 check_fip
208 },
209 [SCP_FW_CONTENT_CERT_ID] = {
210 &fip_dev_handle,
211 (uintptr_t)&scp_fw_cert_uuid_spec,
212 check_fip
213 },
214 [SOC_FW_CONTENT_CERT_ID] = {
215 &fip_dev_handle,
216 (uintptr_t)&soc_fw_cert_uuid_spec,
217 check_fip
218 },
219 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
220 &fip_dev_handle,
221 (uintptr_t)&tos_fw_cert_uuid_spec,
222 check_fip
223 },
224 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
225 &fip_dev_handle,
226 (uintptr_t)&nt_fw_cert_uuid_spec,
227 check_fip
228 },
229#endif /* TRUSTED_BOARD_BOOT */
Haojian Zhuang32052ab2019-09-14 18:43:51 +0800230 [GPT_IMAGE_ID] = {
231 &ufs_dev_handle,
232 (uintptr_t)&ufs_gpt_spec,
233 check_ufs
234 },
Haojian Zhuang602362d2017-06-01 12:15:14 +0800235};
236
237static int check_ufs(const uintptr_t spec)
238{
239 int result;
240 uintptr_t local_handle;
241
242 result = io_dev_init(ufs_dev_handle, (uintptr_t)NULL);
243 if (result == 0) {
244 result = io_open(ufs_dev_handle, spec, &local_handle);
245 if (result == 0)
246 io_close(local_handle);
247 }
248 return result;
249}
250
251static int check_fip(const uintptr_t spec)
252{
253 int result;
254 uintptr_t local_image_handle;
255
256 /* See if a Firmware Image Package is available */
257 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
258 if (result == 0) {
259 result = io_open(fip_dev_handle, spec, &local_image_handle);
260 if (result == 0) {
261 VERBOSE("Using FIP\n");
262 io_close(local_image_handle);
263 }
264 }
Arthur Cassegrain97d4d812021-11-26 16:39:12 +0100265 return result;
266}
267
268int hikey960_load_serialno(uint64_t *serno)
269{
270 int result;
271 size_t len = 0;
272 uintptr_t local_handle;
273 uint64_t buf[HIKEY960_SERIAL_NUMBER_SIZE / sizeof(uint64_t)];
274
275 if (serno == NULL) {
276 return -1;
277 }
278
279 result = io_dev_init(ufs_dev_handle, (uintptr_t)NULL);
280 if (result != 0) {
281 return result;
282 }
283
284 result = io_open(ufs_dev_handle,
285 (uintptr_t)&ufs_fastboot_spec, &local_handle);
286 if (result != 0) {
287 return result;
288 }
289
290 result = io_seek(local_handle, IO_SEEK_SET,
291 HIKEY960_SERIAL_NUMBER_LBA * UFS_BLOCK_SIZE);
292 if (result != 0) {
293 goto closing;
294 }
295
296 result = io_read(local_handle, (uintptr_t)buf,
297 HIKEY960_SERIAL_NUMBER_SIZE, &len);
298 if (result != 0) {
299 goto closing;
300 }
301
302 if (len != HIKEY960_SERIAL_NUMBER_SIZE) {
303 result = -1;
304 goto closing;
305 }
306
307 /* UEFI fastboot app stores a 16 bytes blob */
308 /* We extract only relevant 8 bytes serial number */
309 *serno = buf[1];
310
311closing:
312 io_close(local_handle);
Haojian Zhuang602362d2017-06-01 12:15:14 +0800313 return result;
314}
315
316void hikey960_io_setup(void)
317{
318 int result;
319
320 result = register_io_dev_block(&ufs_dev_con);
321 assert(result == 0);
322
323 result = register_io_dev_fip(&fip_dev_con);
324 assert(result == 0);
325
326 result = io_dev_open(ufs_dev_con, (uintptr_t)&ufs_dev_spec,
327 &ufs_dev_handle);
328 assert(result == 0);
329
330 result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle);
331 assert(result == 0);
332
333 /* Ignore improbable errors in release builds */
334 (void)result;
335}
336
Haojian Zhuang32052ab2019-09-14 18:43:51 +0800337int hikey960_set_fip_addr(unsigned int image_id, const char *name)
338{
339 const partition_entry_t *entry;
340
341 if (ufs_fip_spec.length == 0) {
342 partition_init(GPT_IMAGE_ID);
343 entry = get_partition_entry(name);
344 if (entry == NULL) {
345 ERROR("Could NOT find the %s partition!\n", name);
346 return -ENOENT;
347 }
348 ufs_fip_spec.offset = entry->start;
349 ufs_fip_spec.length = entry->length;
350 }
351 return 0;
352}
353
Haojian Zhuang602362d2017-06-01 12:15:14 +0800354/* Return an IO device handle and specification which can be used to access
355 * an image. Use this to enforce platform load policy
356 */
357int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
358 uintptr_t *image_spec)
359{
360 int result;
361 const struct plat_io_policy *policy;
362
363 assert(image_id < ARRAY_SIZE(policies));
364
365 policy = &policies[image_id];
366 result = policy->check(policy->image_spec);
367 assert(result == 0);
368
369 *image_spec = policy->image_spec;
370 *dev_handle = *(policy->dev_handle);
371
372 return result;
373}
374
375size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size)
376{
377 return ufs_read_blocks(3, lba, buf, size);
378}
379
380size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size)
381{
382 return ufs_write_blocks(3, lba, buf, size);
383}