1 /*
2 * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <assert.h>
8 #include <errno.h>
9 #include <string.h>
10
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>
21 #include <drivers/partition/partition.h>
22 #include <lib/mmio.h>
23 #include <lib/semihosting.h>
24 #include <tools_share/firmware_image_package.h>
25
26 #include "hikey960_def.h"
27 #include "hikey960_private.h"
28
29 struct plat_io_policy {
30 uintptr_t *dev_handle;
31 uintptr_t image_spec;
32 int (*check)(const uintptr_t spec);
33 };
34
35 static const io_dev_connector_t *ufs_dev_con, *fip_dev_con;
36 static uintptr_t ufs_dev_handle, fip_dev_handle;
37
38 static int check_ufs(const uintptr_t spec);
39 static int check_fip(const uintptr_t spec);
40 size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size);
41 size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size);
42
43 static io_block_spec_t ufs_fip_spec;
44
45 static const io_block_spec_t ufs_gpt_spec = {
46 .offset = 0,
47 .length = PLAT_PARTITION_BLOCK_SIZE *
48 (PLAT_PARTITION_MAX_ENTRIES / 4 + 2),
49 };
50
51 /* Fastboot serial number stored within first UFS device blocks */
52 static const io_block_spec_t ufs_fastboot_spec = {
53 .offset = UFS_BASE,
54 .length = 1 << 20,
55 };
56
57 static 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
70 static const io_uuid_spec_t scp_bl2_uuid_spec = {
71 .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
72 };
73
74 static const io_uuid_spec_t bl31_uuid_spec = {
75 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
76 };
77
78 static const io_uuid_spec_t bl32_uuid_spec = {
79 .uuid = UUID_SECURE_PAYLOAD_BL32,
80 };
81
82 static const io_uuid_spec_t bl32_extra1_uuid_spec = {
83 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
84 };
85
86 static const io_uuid_spec_t bl32_extra2_uuid_spec = {
87 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
88 };
89
90 #ifdef SPD_spmd
91 static const io_uuid_spec_t bl32_tos_fw_spec = {
92 .uuid = UUID_TOS_FW_CONFIG,
93 };
94 #endif
95
96 static const io_uuid_spec_t bl33_uuid_spec = {
97 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
98 };
99
100 #if TRUSTED_BOARD_BOOT
101 static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
102 .uuid = UUID_TRUSTED_KEY_CERT,
103 };
104
105 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
106 .uuid = UUID_SCP_FW_KEY_CERT,
107 };
108
109 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
110 .uuid = UUID_SOC_FW_KEY_CERT,
111 };
112
113 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
114 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
115 };
116
117 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
118 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
119 };
120
121 static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
122 .uuid = UUID_SCP_FW_CONTENT_CERT,
123 };
124
125 static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
126 .uuid = UUID_SOC_FW_CONTENT_CERT,
127 };
128
129 static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
130 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
131 };
132
133 static 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
138 static const struct plat_io_policy policies[] = {
139 [FIP_IMAGE_ID] = {
140 &ufs_dev_handle,
141 (uintptr_t)&ufs_fip_spec,
142 check_ufs
143 },
144 [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 },
154 [BL32_IMAGE_ID] = {
155 &fip_dev_handle,
156 (uintptr_t)&bl32_uuid_spec,
157 check_fip
158 },
159 [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 },
169
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
178 [BL33_IMAGE_ID] = {
179 &fip_dev_handle,
180 (uintptr_t)&bl33_uuid_spec,
181 check_fip
182 },
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 */
230 [GPT_IMAGE_ID] = {
231 &ufs_dev_handle,
232 (uintptr_t)&ufs_gpt_spec,
233 check_ufs
234 },
235 };
236
check_ufs(const uintptr_t spec)237 static 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
check_fip(const uintptr_t spec)251 static 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 }
265 return result;
266 }
267
hikey960_load_serialno(uint64_t * serno)268 int 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
311 closing:
312 io_close(local_handle);
313 return result;
314 }
315
hikey960_io_setup(void)316 void 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
hikey960_set_fip_addr(unsigned int image_id,const char * name)337 int 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
354 /* Return an IO device handle and specification which can be used to access
355 * an image. Use this to enforce platform load policy
356 */
plat_get_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)357 int 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
ufs_read_lun3_blks(int lba,uintptr_t buf,size_t size)375 size_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
ufs_write_lun3_blks(int lba,const uintptr_t buf,size_t size)380 size_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 }
384