xref: /rk3399_ARM-atf/plat/hisilicon/hikey960/hikey960_io_storage.c (revision 6971642d23d0c5e33e507eb78b7c569045e2f85d)
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 struct plat_io_policy {
27 	uintptr_t *dev_handle;
28 	uintptr_t image_spec;
29 	int (*check)(const uintptr_t spec);
30 };
31 
32 static const io_dev_connector_t *ufs_dev_con, *fip_dev_con;
33 static uintptr_t ufs_dev_handle, fip_dev_handle;
34 
35 static int check_ufs(const uintptr_t spec);
36 static int check_fip(const uintptr_t spec);
37 size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size);
38 size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size);
39 
40 static io_block_spec_t ufs_fip_spec;
41 
42 static const io_block_spec_t ufs_gpt_spec = {
43 	.offset		= 0,
44 	.length		= PLAT_PARTITION_BLOCK_SIZE *
45 			  (PLAT_PARTITION_MAX_ENTRIES / 4 + 2),
46 };
47 
48 static 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 
61 static const io_uuid_spec_t scp_bl2_uuid_spec = {
62 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
63 };
64 
65 static const io_uuid_spec_t bl31_uuid_spec = {
66 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
67 };
68 
69 static const io_uuid_spec_t bl32_uuid_spec = {
70 	.uuid = UUID_SECURE_PAYLOAD_BL32,
71 };
72 
73 static const io_uuid_spec_t bl32_extra1_uuid_spec = {
74 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
75 };
76 
77 static const io_uuid_spec_t bl32_extra2_uuid_spec = {
78 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
79 };
80 
81 #ifdef SPD_spmd
82 static const io_uuid_spec_t bl32_tos_fw_spec = {
83 	.uuid = UUID_TOS_FW_CONFIG,
84 };
85 #endif
86 
87 static const io_uuid_spec_t bl33_uuid_spec = {
88 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
89 };
90 
91 #if TRUSTED_BOARD_BOOT
92 static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
93 	.uuid = UUID_TRUSTED_KEY_CERT,
94 };
95 
96 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
97 	.uuid = UUID_SCP_FW_KEY_CERT,
98 };
99 
100 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
101 	.uuid = UUID_SOC_FW_KEY_CERT,
102 };
103 
104 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
105 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
106 };
107 
108 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
109 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
110 };
111 
112 static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
113 	.uuid = UUID_SCP_FW_CONTENT_CERT,
114 };
115 
116 static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
117 	.uuid = UUID_SOC_FW_CONTENT_CERT,
118 };
119 
120 static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
121 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
122 };
123 
124 static 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 
129 static const struct plat_io_policy policies[] = {
130 	[FIP_IMAGE_ID] = {
131 		&ufs_dev_handle,
132 		(uintptr_t)&ufs_fip_spec,
133 		check_ufs
134 	},
135 	[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 	},
145 	[BL32_IMAGE_ID] = {
146 		&fip_dev_handle,
147 		(uintptr_t)&bl32_uuid_spec,
148 		check_fip
149 	},
150 	[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 	},
160 
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 
169 	[BL33_IMAGE_ID] = {
170 		&fip_dev_handle,
171 		(uintptr_t)&bl33_uuid_spec,
172 		check_fip
173 	},
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 */
221 	[GPT_IMAGE_ID] = {
222 		&ufs_dev_handle,
223 		(uintptr_t)&ufs_gpt_spec,
224 		check_ufs
225 	},
226 };
227 
228 static 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 
242 static 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 
259 void 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 
280 int 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 
297 /* Return an IO device handle and specification which can be used to access
298  * an image. Use this to enforce platform load policy
299  */
300 int 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 
318 size_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 
323 size_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 }
327