xref: /rk3399_ARM-atf/plat/hisilicon/poplar/bl2_plat_setup.c (revision 5a3ec61f538ca5037ebd8ba485d27310044b0f53)
1e35d0edbSJorge Ramirez-Ortiz /*
2e35d0edbSJorge Ramirez-Ortiz  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3e35d0edbSJorge Ramirez-Ortiz  *
4e35d0edbSJorge Ramirez-Ortiz  * SPDX-License-Identifier: BSD-3-Clause
5e35d0edbSJorge Ramirez-Ortiz  */
6e35d0edbSJorge Ramirez-Ortiz 
7e35d0edbSJorge Ramirez-Ortiz #include <arch_helpers.h>
8e35d0edbSJorge Ramirez-Ortiz #include <assert.h>
9e35d0edbSJorge Ramirez-Ortiz #include <bl_common.h>
10e35d0edbSJorge Ramirez-Ortiz #include <console.h>
11e35d0edbSJorge Ramirez-Ortiz #include <debug.h>
12e35d0edbSJorge Ramirez-Ortiz #include <errno.h>
13e35d0edbSJorge Ramirez-Ortiz #include <generic_delay_timer.h>
14e35d0edbSJorge Ramirez-Ortiz #include <mmio.h>
15e35d0edbSJorge Ramirez-Ortiz #include <partition/partition.h>
16e35d0edbSJorge Ramirez-Ortiz #include <platform.h>
17e35d0edbSJorge Ramirez-Ortiz #include <string.h>
18e35d0edbSJorge Ramirez-Ortiz #include "hi3798cv200.h"
19e35d0edbSJorge Ramirez-Ortiz #include "plat_private.h"
20e35d0edbSJorge Ramirez-Ortiz 
21e35d0edbSJorge Ramirez-Ortiz /* Memory ranges for code and read only data sections */
22e35d0edbSJorge Ramirez-Ortiz #define BL2_RO_BASE	(unsigned long)(&__RO_START__)
23e35d0edbSJorge Ramirez-Ortiz #define BL2_RO_LIMIT	(unsigned long)(&__RO_END__)
24e35d0edbSJorge Ramirez-Ortiz 
25e35d0edbSJorge Ramirez-Ortiz /* Memory ranges for coherent memory section */
26e35d0edbSJorge Ramirez-Ortiz #define BL2_COHERENT_RAM_BASE	(unsigned long)(&__COHERENT_RAM_START__)
27e35d0edbSJorge Ramirez-Ortiz #define BL2_COHERENT_RAM_LIMIT	(unsigned long)(&__COHERENT_RAM_END__)
28e35d0edbSJorge Ramirez-Ortiz 
29e35d0edbSJorge Ramirez-Ortiz typedef struct bl2_to_bl31_params_mem {
30e35d0edbSJorge Ramirez-Ortiz 	bl31_params_t		bl31_params;
31e35d0edbSJorge Ramirez-Ortiz 	image_info_t		bl31_image_info;
32e35d0edbSJorge Ramirez-Ortiz 	image_info_t		bl33_image_info;
33e35d0edbSJorge Ramirez-Ortiz 	entry_point_info_t	bl33_ep_info;
34e35d0edbSJorge Ramirez-Ortiz 	entry_point_info_t	bl31_ep_info;
35e35d0edbSJorge Ramirez-Ortiz } bl2_to_bl31_params_mem_t;
36e35d0edbSJorge Ramirez-Ortiz 
37e35d0edbSJorge Ramirez-Ortiz static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
38e35d0edbSJorge Ramirez-Ortiz static bl2_to_bl31_params_mem_t bl31_params_mem;
39e35d0edbSJorge Ramirez-Ortiz 
40e35d0edbSJorge Ramirez-Ortiz meminfo_t *bl2_plat_sec_mem_layout(void)
41e35d0edbSJorge Ramirez-Ortiz {
42e35d0edbSJorge Ramirez-Ortiz 	return &bl2_tzram_layout;
43e35d0edbSJorge Ramirez-Ortiz }
44e35d0edbSJorge Ramirez-Ortiz 
45e35d0edbSJorge Ramirez-Ortiz bl31_params_t *bl2_plat_get_bl31_params(void)
46e35d0edbSJorge Ramirez-Ortiz {
47e35d0edbSJorge Ramirez-Ortiz 	bl31_params_t *bl2_to_bl31_params = NULL;
48e35d0edbSJorge Ramirez-Ortiz 
49e35d0edbSJorge Ramirez-Ortiz 	/*
50e35d0edbSJorge Ramirez-Ortiz 	 * Initialise the memory for all the arguments that needs to
51e35d0edbSJorge Ramirez-Ortiz 	 * be passed to BL3-1
52e35d0edbSJorge Ramirez-Ortiz 	 */
53e35d0edbSJorge Ramirez-Ortiz 	memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
54e35d0edbSJorge Ramirez-Ortiz 
55e35d0edbSJorge Ramirez-Ortiz 	/* Assign memory for TF related information */
56e35d0edbSJorge Ramirez-Ortiz 	bl2_to_bl31_params = &bl31_params_mem.bl31_params;
57e35d0edbSJorge Ramirez-Ortiz 	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
58e35d0edbSJorge Ramirez-Ortiz 
59e35d0edbSJorge Ramirez-Ortiz 	/* Fill BL3-1 related information */
60e35d0edbSJorge Ramirez-Ortiz 	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
61e35d0edbSJorge Ramirez-Ortiz 	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info,
62e35d0edbSJorge Ramirez-Ortiz 		       PARAM_IMAGE_BINARY, VERSION_1, 0);
63e35d0edbSJorge Ramirez-Ortiz 
64e35d0edbSJorge Ramirez-Ortiz 	/* Fill BL3-3 related information */
65e35d0edbSJorge Ramirez-Ortiz 	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
66e35d0edbSJorge Ramirez-Ortiz 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
67e35d0edbSJorge Ramirez-Ortiz 		       PARAM_EP, VERSION_1, 0);
68e35d0edbSJorge Ramirez-Ortiz 
69e35d0edbSJorge Ramirez-Ortiz 	/* BL3-3 expects to receive the primary CPU MPID (through x0) */
70e35d0edbSJorge Ramirez-Ortiz 	bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
71e35d0edbSJorge Ramirez-Ortiz 
72e35d0edbSJorge Ramirez-Ortiz 	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
73e35d0edbSJorge Ramirez-Ortiz 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info,
74e35d0edbSJorge Ramirez-Ortiz 		       PARAM_IMAGE_BINARY, VERSION_1, 0);
75e35d0edbSJorge Ramirez-Ortiz 
76e35d0edbSJorge Ramirez-Ortiz 	return bl2_to_bl31_params;
77e35d0edbSJorge Ramirez-Ortiz }
78e35d0edbSJorge Ramirez-Ortiz 
79e35d0edbSJorge Ramirez-Ortiz struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
80e35d0edbSJorge Ramirez-Ortiz {
81e35d0edbSJorge Ramirez-Ortiz 	return &bl31_params_mem.bl31_ep_info;
82e35d0edbSJorge Ramirez-Ortiz }
83e35d0edbSJorge Ramirez-Ortiz 
84e35d0edbSJorge Ramirez-Ortiz void bl2_plat_set_bl31_ep_info(image_info_t *image,
85e35d0edbSJorge Ramirez-Ortiz 			       entry_point_info_t *bl31_ep_info)
86e35d0edbSJorge Ramirez-Ortiz {
87e35d0edbSJorge Ramirez-Ortiz 	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
88e35d0edbSJorge Ramirez-Ortiz 	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
89e35d0edbSJorge Ramirez-Ortiz 				     DISABLE_ALL_EXCEPTIONS);
90e35d0edbSJorge Ramirez-Ortiz }
91e35d0edbSJorge Ramirez-Ortiz 
92e35d0edbSJorge Ramirez-Ortiz static uint32_t hisi_get_spsr_for_bl33_entry(void)
93e35d0edbSJorge Ramirez-Ortiz {
94e35d0edbSJorge Ramirez-Ortiz 	unsigned long el_status;
95e35d0edbSJorge Ramirez-Ortiz 	unsigned int mode;
96e35d0edbSJorge Ramirez-Ortiz 	uint32_t spsr;
97e35d0edbSJorge Ramirez-Ortiz 
98e35d0edbSJorge Ramirez-Ortiz 	/* Figure out what mode we enter the non-secure world in */
99e35d0edbSJorge Ramirez-Ortiz 	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
100e35d0edbSJorge Ramirez-Ortiz 	el_status &= ID_AA64PFR0_ELX_MASK;
101e35d0edbSJorge Ramirez-Ortiz 
102e35d0edbSJorge Ramirez-Ortiz 	mode = (el_status) ? MODE_EL2 : MODE_EL1;
103e35d0edbSJorge Ramirez-Ortiz 
104e35d0edbSJorge Ramirez-Ortiz 	/*
105e35d0edbSJorge Ramirez-Ortiz 	 * TODO: Consider the possibility of specifying the SPSR in
106e35d0edbSJorge Ramirez-Ortiz 	 * the FIP ToC and allowing the platform to have a say as
107e35d0edbSJorge Ramirez-Ortiz 	 * well.
108e35d0edbSJorge Ramirez-Ortiz 	 */
109e35d0edbSJorge Ramirez-Ortiz 	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
110e35d0edbSJorge Ramirez-Ortiz 	return spsr;
111e35d0edbSJorge Ramirez-Ortiz }
112e35d0edbSJorge Ramirez-Ortiz 
113e35d0edbSJorge Ramirez-Ortiz void bl2_plat_set_bl33_ep_info(image_info_t *image,
114e35d0edbSJorge Ramirez-Ortiz 			       entry_point_info_t *bl33_ep_info)
115e35d0edbSJorge Ramirez-Ortiz {
116e35d0edbSJorge Ramirez-Ortiz 	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
117e35d0edbSJorge Ramirez-Ortiz 	bl33_ep_info->spsr = hisi_get_spsr_for_bl33_entry();
118e35d0edbSJorge Ramirez-Ortiz 	bl33_ep_info->args.arg2 = image->image_size;
119e35d0edbSJorge Ramirez-Ortiz }
120e35d0edbSJorge Ramirez-Ortiz 
121e35d0edbSJorge Ramirez-Ortiz void bl2_plat_flush_bl31_params(void)
122e35d0edbSJorge Ramirez-Ortiz {
123e35d0edbSJorge Ramirez-Ortiz 	flush_dcache_range((unsigned long)&bl31_params_mem,
124e35d0edbSJorge Ramirez-Ortiz 			   sizeof(bl2_to_bl31_params_mem_t));
125e35d0edbSJorge Ramirez-Ortiz }
126e35d0edbSJorge Ramirez-Ortiz 
127e35d0edbSJorge Ramirez-Ortiz void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
128e35d0edbSJorge Ramirez-Ortiz {
129e35d0edbSJorge Ramirez-Ortiz 	bl33_meminfo->total_base = DDR_BASE;
130e35d0edbSJorge Ramirez-Ortiz 	bl33_meminfo->total_size = DDR_SIZE;
131e35d0edbSJorge Ramirez-Ortiz 	bl33_meminfo->free_base  = DDR_BASE;
132e35d0edbSJorge Ramirez-Ortiz 	bl33_meminfo->free_size  = DDR_SIZE;
133e35d0edbSJorge Ramirez-Ortiz }
134e35d0edbSJorge Ramirez-Ortiz 
135e35d0edbSJorge Ramirez-Ortiz void bl2_early_platform_setup(meminfo_t *mem_layout)
136e35d0edbSJorge Ramirez-Ortiz {
137e35d0edbSJorge Ramirez-Ortiz 	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
138e35d0edbSJorge Ramirez-Ortiz 
139e35d0edbSJorge Ramirez-Ortiz 	/* Enable arch timer */
140e35d0edbSJorge Ramirez-Ortiz 	generic_delay_timer_init();
141e35d0edbSJorge Ramirez-Ortiz 
142e35d0edbSJorge Ramirez-Ortiz 	bl2_tzram_layout = *mem_layout;
143e35d0edbSJorge Ramirez-Ortiz }
144e35d0edbSJorge Ramirez-Ortiz 
145e35d0edbSJorge Ramirez-Ortiz void bl2_plat_arch_setup(void)
146e35d0edbSJorge Ramirez-Ortiz {
147e35d0edbSJorge Ramirez-Ortiz 	plat_configure_mmu_el1(bl2_tzram_layout.total_base,
148e35d0edbSJorge Ramirez-Ortiz 			       bl2_tzram_layout.total_size,
149e35d0edbSJorge Ramirez-Ortiz 			       BL2_RO_BASE,
150e35d0edbSJorge Ramirez-Ortiz 			       BL2_RO_LIMIT,
151e35d0edbSJorge Ramirez-Ortiz 			       BL2_COHERENT_RAM_BASE,
152e35d0edbSJorge Ramirez-Ortiz 			       BL2_COHERENT_RAM_LIMIT);
153e35d0edbSJorge Ramirez-Ortiz }
154e35d0edbSJorge Ramirez-Ortiz 
155e35d0edbSJorge Ramirez-Ortiz void bl2_platform_setup(void)
156e35d0edbSJorge Ramirez-Ortiz {
157e35d0edbSJorge Ramirez-Ortiz 	plat_io_setup();
158e35d0edbSJorge Ramirez-Ortiz }
159e35d0edbSJorge Ramirez-Ortiz 
160e35d0edbSJorge Ramirez-Ortiz unsigned long plat_get_ns_image_entrypoint(void)
161e35d0edbSJorge Ramirez-Ortiz {
162*5a3ec61fSVictor Chong 	return PLAT_POPLAR_NS_IMAGE_OFFSET;
163e35d0edbSJorge Ramirez-Ortiz }
164