cff3b0d235ae3651d08c41a25285f30a84350db6
[project/bcm63xx/atf.git] / plat / hisilicon / hikey960 / hikey960_io_storage.c
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 }