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 <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 static const io_uuid_spec_t bl33_uuid_spec = {
82 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
83 };
84
85 #if TRUSTED_BOARD_BOOT
86 static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
87 .uuid = UUID_TRUSTED_KEY_CERT,
88 };
89
90 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
91 .uuid = UUID_SCP_FW_KEY_CERT,
92 };
93
94 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
95 .uuid = UUID_SOC_FW_KEY_CERT,
96 };
97
98 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
99 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
100 };
101
102 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
103 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
104 };
105
106 static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
107 .uuid = UUID_SCP_FW_CONTENT_CERT,
108 };
109
110 static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
111 .uuid = UUID_SOC_FW_CONTENT_CERT,
112 };
113
114 static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
115 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
116 };
117
118 static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
119 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
120 };
121 #endif /* TRUSTED_BOARD_BOOT */
122
123 static const struct plat_io_policy policies[] = {
124 [FIP_IMAGE_ID] = {
125 &ufs_dev_handle,
126 (uintptr_t)&ufs_fip_spec,
127 check_ufs
128 },
129 [SCP_BL2_IMAGE_ID] = {
130 &fip_dev_handle,
131 (uintptr_t)&scp_bl2_uuid_spec,
132 check_fip
133 },
134 [BL31_IMAGE_ID] = {
135 &fip_dev_handle,
136 (uintptr_t)&bl31_uuid_spec,
137 check_fip
138 },
139 [BL32_IMAGE_ID] = {
140 &fip_dev_handle,
141 (uintptr_t)&bl32_uuid_spec,
142 check_fip
143 },
144 [BL32_EXTRA1_IMAGE_ID] = {
145 &fip_dev_handle,
146 (uintptr_t)&bl32_extra1_uuid_spec,
147 check_fip
148 },
149 [BL32_EXTRA2_IMAGE_ID] = {
150 &fip_dev_handle,
151 (uintptr_t)&bl32_extra2_uuid_spec,
152 check_fip
153 },
154 [BL33_IMAGE_ID] = {
155 &fip_dev_handle,
156 (uintptr_t)&bl33_uuid_spec,
157 check_fip
158 },
159 #if TRUSTED_BOARD_BOOT
160 [TRUSTED_KEY_CERT_ID] = {
161 &fip_dev_handle,
162 (uintptr_t)&trusted_key_cert_uuid_spec,
163 check_fip
164 },
165 [SCP_FW_KEY_CERT_ID] = {
166 &fip_dev_handle,
167 (uintptr_t)&scp_fw_key_cert_uuid_spec,
168 check_fip
169 },
170 [SOC_FW_KEY_CERT_ID] = {
171 &fip_dev_handle,
172 (uintptr_t)&soc_fw_key_cert_uuid_spec,
173 check_fip
174 },
175 [TRUSTED_OS_FW_KEY_CERT_ID] = {
176 &fip_dev_handle,
177 (uintptr_t)&tos_fw_key_cert_uuid_spec,
178 check_fip
179 },
180 [NON_TRUSTED_FW_KEY_CERT_ID] = {
181 &fip_dev_handle,
182 (uintptr_t)&nt_fw_key_cert_uuid_spec,
183 check_fip
184 },
185 [SCP_FW_CONTENT_CERT_ID] = {
186 &fip_dev_handle,
187 (uintptr_t)&scp_fw_cert_uuid_spec,
188 check_fip
189 },
190 [SOC_FW_CONTENT_CERT_ID] = {
191 &fip_dev_handle,
192 (uintptr_t)&soc_fw_cert_uuid_spec,
193 check_fip
194 },
195 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
196 &fip_dev_handle,
197 (uintptr_t)&tos_fw_cert_uuid_spec,
198 check_fip
199 },
200 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
201 &fip_dev_handle,
202 (uintptr_t)&nt_fw_cert_uuid_spec,
203 check_fip
204 },
205 #endif /* TRUSTED_BOARD_BOOT */
206 [GPT_IMAGE_ID] = {
207 &ufs_dev_handle,
208 (uintptr_t)&ufs_gpt_spec,
209 check_ufs
210 },
211 };
212
check_ufs(const uintptr_t spec)213 static int check_ufs(const uintptr_t spec)
214 {
215 int result;
216 uintptr_t local_handle;
217
218 result = io_dev_init(ufs_dev_handle, (uintptr_t)NULL);
219 if (result == 0) {
220 result = io_open(ufs_dev_handle, spec, &local_handle);
221 if (result == 0)
222 io_close(local_handle);
223 }
224 return result;
225 }
226
check_fip(const uintptr_t spec)227 static int check_fip(const uintptr_t spec)
228 {
229 int result;
230 uintptr_t local_image_handle;
231
232 /* See if a Firmware Image Package is available */
233 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
234 if (result == 0) {
235 result = io_open(fip_dev_handle, spec, &local_image_handle);
236 if (result == 0) {
237 VERBOSE("Using FIP\n");
238 io_close(local_image_handle);
239 }
240 }
241 return result;
242 }
243
hikey960_io_setup(void)244 void hikey960_io_setup(void)
245 {
246 int result;
247
248 result = register_io_dev_block(&ufs_dev_con);
249 assert(result == 0);
250
251 result = register_io_dev_fip(&fip_dev_con);
252 assert(result == 0);
253
254 result = io_dev_open(ufs_dev_con, (uintptr_t)&ufs_dev_spec,
255 &ufs_dev_handle);
256 assert(result == 0);
257
258 result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle);
259 assert(result == 0);
260
261 /* Ignore improbable errors in release builds */
262 (void)result;
263 }
264
hikey960_set_fip_addr(unsigned int image_id,const char * name)265 int hikey960_set_fip_addr(unsigned int image_id, const char *name)
266 {
267 const partition_entry_t *entry;
268
269 if (ufs_fip_spec.length == 0) {
270 partition_init(GPT_IMAGE_ID);
271 entry = get_partition_entry(name);
272 if (entry == NULL) {
273 ERROR("Could NOT find the %s partition!\n", name);
274 return -ENOENT;
275 }
276 ufs_fip_spec.offset = entry->start;
277 ufs_fip_spec.length = entry->length;
278 }
279 return 0;
280 }
281
282 /* Return an IO device handle and specification which can be used to access
283 * an image. Use this to enforce platform load policy
284 */
plat_get_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)285 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
286 uintptr_t *image_spec)
287 {
288 int result;
289 const struct plat_io_policy *policy;
290
291 assert(image_id < ARRAY_SIZE(policies));
292
293 policy = &policies[image_id];
294 result = policy->check(policy->image_spec);
295 assert(result == 0);
296
297 *image_spec = policy->image_spec;
298 *dev_handle = *(policy->dev_handle);
299
300 return result;
301 }
302
ufs_read_lun3_blks(int lba,uintptr_t buf,size_t size)303 size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size)
304 {
305 return ufs_read_blocks(3, lba, buf, size);
306 }
307
ufs_write_lun3_blks(int lba,const uintptr_t buf,size_t size)308 size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size)
309 {
310 return ufs_write_blocks(3, lba, buf, size);
311 }
312