blob: a4e83897ededa327860d681aad29c4e0885ef584 [file] [log] [blame]
Haojian Zhuang602362d2017-06-01 12:15:14 +08001/*
Haojian Zhuang1b4b4122018-01-25 16:13:05 +08002 * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
Haojian Zhuang602362d2017-06-01 12:15:14 +08003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Haojian Zhuang602362d2017-06-01 12:15:14 +08007#include <assert.h>
Haojian Zhuang602362d2017-06-01 12:15:14 +08008#include <errno.h>
Haojian Zhuang602362d2017-06-01 12:15:14 +08009#include <string.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010
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>
Haojian Zhuang602362d2017-06-01 12:15:14 +080024
25struct plat_io_policy {
26 uintptr_t *dev_handle;
27 uintptr_t image_spec;
28 int (*check)(const uintptr_t spec);
29};
30
31static const io_dev_connector_t *ufs_dev_con, *fip_dev_con;
32static uintptr_t ufs_dev_handle, fip_dev_handle;
33
34static int check_ufs(const uintptr_t spec);
35static int check_fip(const uintptr_t spec);
36size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size);
37size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size);
38
39static const io_block_spec_t ufs_fip_spec = {
40 .offset = HIKEY960_FIP_BASE,
41 .length = HIKEY960_FIP_MAX_SIZE,
42};
43
Haojian Zhuang602362d2017-06-01 12:15:14 +080044static 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
Haojian Zhuang602362d2017-06-01 12:15:14 +080057static const io_uuid_spec_t scp_bl2_uuid_spec = {
58 .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
59};
60
61static const io_uuid_spec_t bl31_uuid_spec = {
62 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
63};
64
Victor Chong91287682017-05-28 00:14:37 +090065static const io_uuid_spec_t bl32_uuid_spec = {
66 .uuid = UUID_SECURE_PAYLOAD_BL32,
67};
68
Victor Chong7d787f52017-08-16 13:53:56 +090069static const io_uuid_spec_t bl32_extra1_uuid_spec = {
70 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
71};
72
73static const io_uuid_spec_t bl32_extra2_uuid_spec = {
74 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
75};
76
Haojian Zhuang602362d2017-06-01 12:15:14 +080077static const io_uuid_spec_t bl33_uuid_spec = {
78 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
79};
80
Teddy Reeddd3f0a82018-09-03 17:38:50 -040081#if TRUSTED_BOARD_BOOT
82static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
83 .uuid = UUID_TRUSTED_KEY_CERT,
84};
85
86static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
87 .uuid = UUID_SCP_FW_KEY_CERT,
88};
89
90static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
91 .uuid = UUID_SOC_FW_KEY_CERT,
92};
93
94static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
95 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
96};
97
98static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
99 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
100};
101
102static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
103 .uuid = UUID_SCP_FW_CONTENT_CERT,
104};
105
106static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
107 .uuid = UUID_SOC_FW_CONTENT_CERT,
108};
109
110static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
111 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
112};
113
114static 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
Haojian Zhuang602362d2017-06-01 12:15:14 +0800119static const struct plat_io_policy policies[] = {
120 [FIP_IMAGE_ID] = {
121 &ufs_dev_handle,
122 (uintptr_t)&ufs_fip_spec,
123 check_ufs
124 },
Haojian Zhuang602362d2017-06-01 12:15:14 +0800125 [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 },
Victor Chong91287682017-05-28 00:14:37 +0900135 [BL32_IMAGE_ID] = {
136 &fip_dev_handle,
137 (uintptr_t)&bl32_uuid_spec,
138 check_fip
139 },
Victor Chong7d787f52017-08-16 13:53:56 +0900140 [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 },
Haojian Zhuang602362d2017-06-01 12:15:14 +0800150 [BL33_IMAGE_ID] = {
151 &fip_dev_handle,
152 (uintptr_t)&bl33_uuid_spec,
153 check_fip
Teddy Reeddd3f0a82018-09-03 17:38:50 -0400154 },
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 */
Haojian Zhuang602362d2017-06-01 12:15:14 +0800202};
203
204static 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
218static 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
235void 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 */
259int 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
277size_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
282size_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}