blob: b50ed87f0c04ced6c7c7dd6c0775e485bd745b07 [file] [log] [blame]
Haojian Zhuang1f73c0c2017-06-01 14:03:22 +08001/*
2 * Copyright (c) 2017, 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 <bl_common.h>
10#include <console.h>
11#include <debug.h>
Victor Chong2d9a42d2017-08-17 15:21:10 +090012#include <desc_image_load.h>
Haojian Zhuang1f73c0c2017-06-01 14:03:22 +080013#include <errno.h>
14#include <generic_delay_timer.h>
15#include <hi3660.h>
16#include <mmio.h>
Victor Chong7d787f52017-08-16 13:53:56 +090017#if LOAD_IMAGE_V2
18#ifdef SPD_opteed
19#include <optee_utils.h>
20#endif
21#endif
Haojian Zhuang1f73c0c2017-06-01 14:03:22 +080022#include <platform_def.h>
23#include <string.h>
24#include <ufs.h>
25
26#include "hikey960_def.h"
27#include "hikey960_private.h"
28
29/*
30 * The next 2 constants identify the extents of the code & RO data region.
31 * These addresses are used by the MMU setup code and therefore they must be
32 * page-aligned. It is the responsibility of the linker script to ensure that
33 * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
34 */
35#define BL2_RO_BASE (unsigned long)(&__RO_START__)
36#define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
37
38/*
39 * The next 2 constants identify the extents of the coherent memory region.
40 * These addresses are used by the MMU setup code and therefore they must be
41 * page-aligned. It is the responsibility of the linker script to ensure that
42 * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
43 * page-aligned addresses.
44 */
45#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
46#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
47
48static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
49
Victor Chong2d9a42d2017-08-17 15:21:10 +090050#if !LOAD_IMAGE_V2
51
52/*******************************************************************************
53 * This structure represents the superset of information that is passed to
54 * BL31, e.g. while passing control to it from BL2, bl31_params
55 * and other platform specific params
56 ******************************************************************************/
Haojian Zhuang1f73c0c2017-06-01 14:03:22 +080057typedef struct bl2_to_bl31_params_mem {
58 bl31_params_t bl31_params;
59 image_info_t bl31_image_info;
60 image_info_t bl32_image_info;
61 image_info_t bl33_image_info;
62 entry_point_info_t bl33_ep_info;
63 entry_point_info_t bl32_ep_info;
64 entry_point_info_t bl31_ep_info;
65} bl2_to_bl31_params_mem_t;
66
67static bl2_to_bl31_params_mem_t bl31_params_mem;
68
69meminfo_t *bl2_plat_sec_mem_layout(void)
70{
71 return &bl2_tzram_layout;
72}
73
74bl31_params_t *bl2_plat_get_bl31_params(void)
75{
76 bl31_params_t *bl2_to_bl31_params = NULL;
77
78 /*
79 * Initialise the memory for all the arguments that needs to
80 * be passed to BL3-1
81 */
82 memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
83
84 /* Assign memory for TF related information */
85 bl2_to_bl31_params = &bl31_params_mem.bl31_params;
86 SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
87
88 /* Fill BL3-1 related information */
89 bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
90 SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
91 VERSION_1, 0);
92
93 /* Fill BL3-2 related information if it exists */
Victor Chong043741c2017-09-14 01:22:14 +090094#ifdef BL32_BASE
Haojian Zhuang1f73c0c2017-06-01 14:03:22 +080095 bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
96 SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
97 VERSION_1, 0);
98 bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
99 SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
100 VERSION_1, 0);
101#endif
102
103 /* Fill BL3-3 related information */
104 bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
105 SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
106 PARAM_EP, VERSION_1, 0);
107
108 /* BL3-3 expects to receive the primary CPU MPID (through x0) */
109 bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
110
111 bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
112 SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
113 VERSION_1, 0);
114
115 return bl2_to_bl31_params;
116}
117
118/*******************************************************************************
119 * Populate the extents of memory available for loading SCP_BL2 (if used),
120 * i.e. anywhere in trusted RAM as long as it doesn't overwrite BL2.
121 ******************************************************************************/
122void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo)
123{
Victor Chong2d9a42d2017-08-17 15:21:10 +0900124 hikey960_init_ufs();
Haojian Zhuang1f73c0c2017-06-01 14:03:22 +0800125 hikey960_io_setup();
126
127 *scp_bl2_meminfo = bl2_tzram_layout;
128}
Victor Chong2d9a42d2017-08-17 15:21:10 +0900129#endif /* LOAD_IMAGE_V2 */
Haojian Zhuang1f73c0c2017-06-01 14:03:22 +0800130
131extern int load_lpm3(void);
132
Victor Chong2d9a42d2017-08-17 15:21:10 +0900133/*******************************************************************************
134 * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
135 * Return 0 on success, -1 otherwise.
136 ******************************************************************************/
137#if LOAD_IMAGE_V2
138int plat_hikey960_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info)
139#else
Haojian Zhuang1f73c0c2017-06-01 14:03:22 +0800140int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info)
Victor Chong2d9a42d2017-08-17 15:21:10 +0900141#endif
Haojian Zhuang1f73c0c2017-06-01 14:03:22 +0800142{
143 int i;
144 int *buf;
145
Victor Chong2d9a42d2017-08-17 15:21:10 +0900146 assert(scp_bl2_image_info->image_size < SCP_BL2_SIZE);
Haojian Zhuang1f73c0c2017-06-01 14:03:22 +0800147
148 INFO("BL2: Initiating SCP_BL2 transfer to SCP\n");
149
150 INFO("BL2: SCP_BL2: 0x%lx@0x%x\n",
151 scp_bl2_image_info->image_base,
152 scp_bl2_image_info->image_size);
153
154 buf = (int *)scp_bl2_image_info->image_base;
155
156 INFO("BL2: SCP_BL2 HEAD:\n");
157 for (i = 0; i < 64; i += 4)
158 INFO("BL2: SCP_BL2 0x%x 0x%x 0x%x 0x%x\n",
159 buf[i], buf[i+1], buf[i+2], buf[i+3]);
160
161 buf = (int *)(scp_bl2_image_info->image_base +
162 scp_bl2_image_info->image_size - 256);
163
164 INFO("BL2: SCP_BL2 TAIL:\n");
165 for (i = 0; i < 64; i += 4)
166 INFO("BL2: SCP_BL2 0x%x 0x%x 0x%x 0x%x\n",
167 buf[i], buf[i+1], buf[i+2], buf[i+3]);
168
Haojian Zhuang1f73c0c2017-06-01 14:03:22 +0800169 INFO("BL2: SCP_BL2 transferred to SCP\n");
170
171 load_lpm3();
172 (void)buf;
173
174 return 0;
175}
176
Victor Chong2d9a42d2017-08-17 15:21:10 +0900177void hikey960_init_ufs(void)
178{
179 ufs_params_t ufs_params;
180
181 memset(&ufs_params, 0, sizeof(ufs_params_t));
182 ufs_params.reg_base = UFS_REG_BASE;
183 ufs_params.desc_base = HIKEY960_UFS_DESC_BASE;
184 ufs_params.desc_size = HIKEY960_UFS_DESC_SIZE;
185 ufs_params.flags = UFS_FLAGS_SKIPINIT;
186 ufs_init(NULL, &ufs_params);
187}
188
189/*******************************************************************************
190 * Gets SPSR for BL32 entry
191 ******************************************************************************/
192uint32_t hikey960_get_spsr_for_bl32_entry(void)
193{
194 /*
195 * The Secure Payload Dispatcher service is responsible for
196 * setting the SPSR prior to entry into the BL3-2 image.
197 */
198 return 0;
199}
200
201/*******************************************************************************
202 * Gets SPSR for BL33 entry
203 ******************************************************************************/
204#ifndef AARCH32
205uint32_t hikey960_get_spsr_for_bl33_entry(void)
206{
207 unsigned int mode;
208 uint32_t spsr;
209
210 /* Figure out what mode we enter the non-secure world in */
211 mode = EL_IMPLEMENTED(2) ? MODE_EL2 : MODE_EL1;
212
213 /*
214 * TODO: Consider the possibility of specifying the SPSR in
215 * the FIP ToC and allowing the platform to have a say as
216 * well.
217 */
218 spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
219 return spsr;
220}
221#else
222uint32_t hikey960_get_spsr_for_bl33_entry(void)
223{
224 unsigned int hyp_status, mode, spsr;
225
226 hyp_status = GET_VIRT_EXT(read_id_pfr1());
227
228 mode = (hyp_status) ? MODE32_hyp : MODE32_svc;
229
230 /*
231 * TODO: Consider the possibility of specifying the SPSR in
232 * the FIP ToC and allowing the platform to have a say as
233 * well.
234 */
235 spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1,
236 SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
237 return spsr;
238}
239#endif /* AARCH32 */
240
241#if LOAD_IMAGE_V2
242int hikey960_bl2_handle_post_image_load(unsigned int image_id)
243{
244 int err = 0;
245 bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
Victor Chong7d787f52017-08-16 13:53:56 +0900246#ifdef SPD_opteed
247 bl_mem_params_node_t *pager_mem_params = NULL;
248 bl_mem_params_node_t *paged_mem_params = NULL;
249#endif
Victor Chong2d9a42d2017-08-17 15:21:10 +0900250 assert(bl_mem_params);
251
252 switch (image_id) {
253#ifdef AARCH64
254 case BL32_IMAGE_ID:
Victor Chong7d787f52017-08-16 13:53:56 +0900255#ifdef SPD_opteed
256 pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
257 assert(pager_mem_params);
258
259 paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
260 assert(paged_mem_params);
261
262 err = parse_optee_header(&bl_mem_params->ep_info,
263 &pager_mem_params->image_info,
264 &paged_mem_params->image_info);
265 if (err != 0) {
266 WARN("OPTEE header parse error.\n");
267 }
268#endif
Victor Chong2d9a42d2017-08-17 15:21:10 +0900269 bl_mem_params->ep_info.spsr = hikey960_get_spsr_for_bl32_entry();
270 break;
271#endif
272
273 case BL33_IMAGE_ID:
274 /* BL33 expects to receive the primary CPU MPID (through r0) */
275 bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
276 bl_mem_params->ep_info.spsr = hikey960_get_spsr_for_bl33_entry();
277 break;
278
279#ifdef SCP_BL2_BASE
280 case SCP_BL2_IMAGE_ID:
281 /* The subsequent handling of SCP_BL2 is platform specific */
282 err = plat_hikey960_bl2_handle_scp_bl2(&bl_mem_params->image_info);
283 if (err) {
284 WARN("Failure in platform-specific handling of SCP_BL2 image.\n");
285 }
286 break;
287#endif
288 }
289
290 return err;
291}
292
293/*******************************************************************************
294 * This function can be used by the platforms to update/use image
295 * information for given `image_id`.
296 ******************************************************************************/
297int bl2_plat_handle_post_image_load(unsigned int image_id)
298{
299 return hikey960_bl2_handle_post_image_load(image_id);
300}
301
302#else /* LOAD_IMAGE_V2 */
303
Haojian Zhuang1f73c0c2017-06-01 14:03:22 +0800304struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
305{
Victor Chong2d9a42d2017-08-17 15:21:10 +0900306#if DEBUG
307 bl31_params_mem.bl31_ep_info.args.arg1 = HIKEY960_BL31_PLAT_PARAM_VAL;
308#endif
309
Haojian Zhuang1f73c0c2017-06-01 14:03:22 +0800310 return &bl31_params_mem.bl31_ep_info;
311}
312
313void bl2_plat_set_bl31_ep_info(image_info_t *image,
314 entry_point_info_t *bl31_ep_info)
315{
316 SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
317 bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
318 DISABLE_ALL_EXCEPTIONS);
319}
320
Victor Chong91287682017-05-28 00:14:37 +0900321/*******************************************************************************
322 * Before calling this function BL32 is loaded in memory and its entrypoint
323 * is set by load_image. This is a placeholder for the platform to change
324 * the entrypoint of BL32 and set SPSR and security state.
325 * On Hikey we only set the security state of the entrypoint
326 ******************************************************************************/
327#ifdef BL32_BASE
328void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
329 entry_point_info_t *bl32_ep_info)
330{
331 SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
332 /*
333 * The Secure Payload Dispatcher service is responsible for
334 * setting the SPSR prior to entry into the BL32 image.
335 */
336 bl32_ep_info->spsr = 0;
337}
338
339/*******************************************************************************
340 * Populate the extents of memory available for loading BL32
341 ******************************************************************************/
342void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
343{
344 /*
345 * Populate the extents of memory available for loading BL32.
346 */
347 bl32_meminfo->total_base = BL32_BASE;
348 bl32_meminfo->free_base = BL32_BASE;
349 bl32_meminfo->total_size =
350 (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
351 bl32_meminfo->free_size =
352 (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
353}
354#endif /* BL32_BASE */
355
Haojian Zhuang1f73c0c2017-06-01 14:03:22 +0800356void bl2_plat_set_bl33_ep_info(image_info_t *image,
357 entry_point_info_t *bl33_ep_info)
358{
359 unsigned long el_status;
360 unsigned int mode;
361
362 /* Figure out what mode we enter the non-secure world in */
363 el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
364 el_status &= ID_AA64PFR0_ELX_MASK;
365
366 if (el_status)
367 mode = MODE_EL2;
368 else
369 mode = MODE_EL1;
370
371 /*
372 * TODO: Consider the possibility of specifying the SPSR in
373 * the FIP ToC and allowing the platform to have a say as
374 * well.
375 */
376 bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX,
377 DISABLE_ALL_EXCEPTIONS);
378 SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
379}
380
381void bl2_plat_flush_bl31_params(void)
382{
383 flush_dcache_range((unsigned long)&bl31_params_mem,
384 sizeof(bl2_to_bl31_params_mem_t));
385}
386
387void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
388{
389 bl33_meminfo->total_base = DDR_BASE;
390 bl33_meminfo->total_size = DDR_SIZE;
391 bl33_meminfo->free_base = DDR_BASE;
392 bl33_meminfo->free_size = DDR_SIZE;
393}
Victor Chong2d9a42d2017-08-17 15:21:10 +0900394#endif /* LOAD_IMAGE_V2 */
Haojian Zhuang1f73c0c2017-06-01 14:03:22 +0800395
396void bl2_early_platform_setup(meminfo_t *mem_layout)
397{
398 unsigned int id, uart_base;
399
400 generic_delay_timer_init();
401 hikey960_read_boardid(&id);
402 if (id == 5300)
403 uart_base = PL011_UART5_BASE;
404 else
405 uart_base = PL011_UART6_BASE;
406
407 /* Initialize the console to provide early debug support */
408 console_init(uart_base, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
409
410 /* Setup the BL2 memory layout */
411 bl2_tzram_layout = *mem_layout;
412}
413
414void bl2_plat_arch_setup(void)
415{
416 hikey960_init_mmu_el1(bl2_tzram_layout.total_base,
417 bl2_tzram_layout.total_size,
418 BL2_RO_BASE,
419 BL2_RO_LIMIT,
420 BL2_COHERENT_RAM_BASE,
421 BL2_COHERENT_RAM_LIMIT);
422}
423
424void bl2_platform_setup(void)
425{
426 /* disable WDT0 */
427 if (mmio_read_32(WDT0_REG_BASE + WDT_LOCK_OFFSET) == WDT_LOCKED) {
428 mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, WDT_UNLOCK);
429 mmio_write_32(WDT0_REG_BASE + WDT_CONTROL_OFFSET, 0);
430 mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, 0);
431 }
432}