xref: /rk3399_ARM-atf/plat/hisilicon/hikey960/hikey960_io_storage.c (revision c948f77136c42a92d0bb660543a3600c36dcf7f1)
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 <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 <lib/mmio.h>
22 #include <lib/semihosting.h>
23 #include <tools_share/firmware_image_package.h>
24 
25 struct plat_io_policy {
26 	uintptr_t *dev_handle;
27 	uintptr_t image_spec;
28 	int (*check)(const uintptr_t spec);
29 };
30 
31 static const io_dev_connector_t *ufs_dev_con, *fip_dev_con;
32 static uintptr_t ufs_dev_handle, fip_dev_handle;
33 
34 static int check_ufs(const uintptr_t spec);
35 static int check_fip(const uintptr_t spec);
36 size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size);
37 size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size);
38 
39 static const io_block_spec_t ufs_fip_spec = {
40 	.offset		= HIKEY960_FIP_BASE,
41 	.length		= HIKEY960_FIP_MAX_SIZE,
42 };
43 
44 static const io_block_dev_spec_t ufs_dev_spec = {
45 	/* It's used as temp buffer in block driver. */
46 	.buffer		= {
47 		.offset	= HIKEY960_UFS_DATA_BASE,
48 		.length	= HIKEY960_UFS_DATA_SIZE,
49 	},
50 	.ops		= {
51 		.read	= ufs_read_lun3_blks,
52 		.write	= ufs_write_lun3_blks,
53 	},
54 	.block_size	= UFS_BLOCK_SIZE,
55 };
56 
57 static const io_uuid_spec_t scp_bl2_uuid_spec = {
58 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
59 };
60 
61 static const io_uuid_spec_t bl31_uuid_spec = {
62 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
63 };
64 
65 static const io_uuid_spec_t bl32_uuid_spec = {
66 	.uuid = UUID_SECURE_PAYLOAD_BL32,
67 };
68 
69 static const io_uuid_spec_t bl32_extra1_uuid_spec = {
70 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
71 };
72 
73 static const io_uuid_spec_t bl32_extra2_uuid_spec = {
74 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
75 };
76 
77 static const io_uuid_spec_t bl33_uuid_spec = {
78 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
79 };
80 
81 #if TRUSTED_BOARD_BOOT
82 static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
83 	.uuid = UUID_TRUSTED_KEY_CERT,
84 };
85 
86 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
87 	.uuid = UUID_SCP_FW_KEY_CERT,
88 };
89 
90 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
91 	.uuid = UUID_SOC_FW_KEY_CERT,
92 };
93 
94 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
95 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
96 };
97 
98 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
99 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
100 };
101 
102 static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
103 	.uuid = UUID_SCP_FW_CONTENT_CERT,
104 };
105 
106 static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
107 	.uuid = UUID_SOC_FW_CONTENT_CERT,
108 };
109 
110 static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
111 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
112 };
113 
114 static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
115 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
116 };
117 #endif /* TRUSTED_BOARD_BOOT */
118 
119 static const struct plat_io_policy policies[] = {
120 	[FIP_IMAGE_ID] = {
121 		&ufs_dev_handle,
122 		(uintptr_t)&ufs_fip_spec,
123 		check_ufs
124 	},
125 	[SCP_BL2_IMAGE_ID] = {
126 		&fip_dev_handle,
127 		(uintptr_t)&scp_bl2_uuid_spec,
128 		check_fip
129 	},
130 	[BL31_IMAGE_ID] = {
131 		&fip_dev_handle,
132 		(uintptr_t)&bl31_uuid_spec,
133 		check_fip
134 	},
135 	[BL32_IMAGE_ID] = {
136 		&fip_dev_handle,
137 		(uintptr_t)&bl32_uuid_spec,
138 		check_fip
139 	},
140 	[BL32_EXTRA1_IMAGE_ID] = {
141 		&fip_dev_handle,
142 		(uintptr_t)&bl32_extra1_uuid_spec,
143 		check_fip
144 	},
145 	[BL32_EXTRA2_IMAGE_ID] = {
146 		&fip_dev_handle,
147 		(uintptr_t)&bl32_extra2_uuid_spec,
148 		check_fip
149 	},
150 	[BL33_IMAGE_ID] = {
151 		&fip_dev_handle,
152 		(uintptr_t)&bl33_uuid_spec,
153 		check_fip
154 	},
155 #if TRUSTED_BOARD_BOOT
156 	[TRUSTED_KEY_CERT_ID] = {
157 		&fip_dev_handle,
158 		(uintptr_t)&trusted_key_cert_uuid_spec,
159 		check_fip
160 	},
161 	[SCP_FW_KEY_CERT_ID] = {
162 		&fip_dev_handle,
163 		(uintptr_t)&scp_fw_key_cert_uuid_spec,
164 		check_fip
165 	},
166 	[SOC_FW_KEY_CERT_ID] = {
167 		&fip_dev_handle,
168 		(uintptr_t)&soc_fw_key_cert_uuid_spec,
169 		check_fip
170 	},
171 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
172 		&fip_dev_handle,
173 		(uintptr_t)&tos_fw_key_cert_uuid_spec,
174 		check_fip
175 	},
176 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
177 		&fip_dev_handle,
178 		(uintptr_t)&nt_fw_key_cert_uuid_spec,
179 		check_fip
180 	},
181 	[SCP_FW_CONTENT_CERT_ID] = {
182 		&fip_dev_handle,
183 		(uintptr_t)&scp_fw_cert_uuid_spec,
184 		check_fip
185 	},
186 	[SOC_FW_CONTENT_CERT_ID] = {
187 		&fip_dev_handle,
188 		(uintptr_t)&soc_fw_cert_uuid_spec,
189 		check_fip
190 	},
191 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
192 		&fip_dev_handle,
193 		(uintptr_t)&tos_fw_cert_uuid_spec,
194 		check_fip
195 	},
196 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
197 		&fip_dev_handle,
198 		(uintptr_t)&nt_fw_cert_uuid_spec,
199 		check_fip
200 	},
201 #endif /* TRUSTED_BOARD_BOOT */
202 };
203 
204 static int check_ufs(const uintptr_t spec)
205 {
206 	int result;
207 	uintptr_t local_handle;
208 
209 	result = io_dev_init(ufs_dev_handle, (uintptr_t)NULL);
210 	if (result == 0) {
211 		result = io_open(ufs_dev_handle, spec, &local_handle);
212 		if (result == 0)
213 			io_close(local_handle);
214 	}
215 	return result;
216 }
217 
218 static int check_fip(const uintptr_t spec)
219 {
220 	int result;
221 	uintptr_t local_image_handle;
222 
223 	/* See if a Firmware Image Package is available */
224 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
225 	if (result == 0) {
226 		result = io_open(fip_dev_handle, spec, &local_image_handle);
227 		if (result == 0) {
228 			VERBOSE("Using FIP\n");
229 			io_close(local_image_handle);
230 		}
231 	}
232 	return result;
233 }
234 
235 void hikey960_io_setup(void)
236 {
237 	int result;
238 
239 	result = register_io_dev_block(&ufs_dev_con);
240 	assert(result == 0);
241 
242 	result = register_io_dev_fip(&fip_dev_con);
243 	assert(result == 0);
244 
245 	result = io_dev_open(ufs_dev_con, (uintptr_t)&ufs_dev_spec,
246 			     &ufs_dev_handle);
247 	assert(result == 0);
248 
249 	result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle);
250 	assert(result == 0);
251 
252 	/* Ignore improbable errors in release builds */
253 	(void)result;
254 }
255 
256 /* Return an IO device handle and specification which can be used to access
257  * an image. Use this to enforce platform load policy
258  */
259 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
260 			  uintptr_t *image_spec)
261 {
262 	int result;
263 	const struct plat_io_policy *policy;
264 
265 	assert(image_id < ARRAY_SIZE(policies));
266 
267 	policy = &policies[image_id];
268 	result = policy->check(policy->image_spec);
269 	assert(result == 0);
270 
271 	*image_spec = policy->image_spec;
272 	*dev_handle = *(policy->dev_handle);
273 
274 	return result;
275 }
276 
277 size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size)
278 {
279 	return ufs_read_blocks(3, lba, buf, size);
280 }
281 
282 size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size)
283 {
284 	return ufs_write_blocks(3, lba, buf, size);
285 }
286