xref: /rk3399_ARM-atf/plat/hisilicon/hikey960/hikey960_io_storage.c (revision 1dcc28cfbac5dae3992ad9581f9ea68f6cb339c1)
1 /*
2  * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
3  *
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 
23 struct plat_io_policy {
24 	uintptr_t *dev_handle;
25 	uintptr_t image_spec;
26 	int (*check)(const uintptr_t spec);
27 };
28 
29 static const io_dev_connector_t *ufs_dev_con, *fip_dev_con;
30 static uintptr_t ufs_dev_handle, fip_dev_handle;
31 
32 static int check_ufs(const uintptr_t spec);
33 static int check_fip(const uintptr_t spec);
34 size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size);
35 size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size);
36 
37 static const io_block_spec_t ufs_fip_spec = {
38 	.offset		= HIKEY960_FIP_BASE,
39 	.length		= HIKEY960_FIP_MAX_SIZE,
40 };
41 
42 static 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 
55 static const io_uuid_spec_t scp_bl2_uuid_spec = {
56 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
57 };
58 
59 static const io_uuid_spec_t bl31_uuid_spec = {
60 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
61 };
62 
63 static const io_uuid_spec_t bl32_uuid_spec = {
64 	.uuid = UUID_SECURE_PAYLOAD_BL32,
65 };
66 
67 static const io_uuid_spec_t bl32_extra1_uuid_spec = {
68 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
69 };
70 
71 static const io_uuid_spec_t bl32_extra2_uuid_spec = {
72 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
73 };
74 
75 static const io_uuid_spec_t bl33_uuid_spec = {
76 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
77 };
78 
79 #if TRUSTED_BOARD_BOOT
80 static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
81 	.uuid = UUID_TRUSTED_KEY_CERT,
82 };
83 
84 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
85 	.uuid = UUID_SCP_FW_KEY_CERT,
86 };
87 
88 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
89 	.uuid = UUID_SOC_FW_KEY_CERT,
90 };
91 
92 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
93 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
94 };
95 
96 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
97 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
98 };
99 
100 static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
101 	.uuid = UUID_SCP_FW_CONTENT_CERT,
102 };
103 
104 static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
105 	.uuid = UUID_SOC_FW_CONTENT_CERT,
106 };
107 
108 static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
109 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
110 };
111 
112 static 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 
117 static const struct plat_io_policy policies[] = {
118 	[FIP_IMAGE_ID] = {
119 		&ufs_dev_handle,
120 		(uintptr_t)&ufs_fip_spec,
121 		check_ufs
122 	},
123 	[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 	},
133 	[BL32_IMAGE_ID] = {
134 		&fip_dev_handle,
135 		(uintptr_t)&bl32_uuid_spec,
136 		check_fip
137 	},
138 	[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 	},
148 	[BL33_IMAGE_ID] = {
149 		&fip_dev_handle,
150 		(uintptr_t)&bl33_uuid_spec,
151 		check_fip
152 	},
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 */
200 };
201 
202 static 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 
216 static 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 
233 void 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  */
257 int 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 
275 size_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 
280 size_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 }
284