xref: /rk3399_ARM-atf/plat/hisilicon/poplar/bl2_plat_setup.c (revision f336774b45468065975bcfd5721be4cb72885eee)
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;
32*f336774bSVictor Chong 	image_info_t		bl32_image_info;
33e35d0edbSJorge Ramirez-Ortiz 	image_info_t		bl33_image_info;
34e35d0edbSJorge Ramirez-Ortiz 	entry_point_info_t	bl33_ep_info;
35*f336774bSVictor Chong 	entry_point_info_t	bl32_ep_info;
36e35d0edbSJorge Ramirez-Ortiz 	entry_point_info_t	bl31_ep_info;
37e35d0edbSJorge Ramirez-Ortiz } bl2_to_bl31_params_mem_t;
38e35d0edbSJorge Ramirez-Ortiz 
39e35d0edbSJorge Ramirez-Ortiz static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
40e35d0edbSJorge Ramirez-Ortiz static bl2_to_bl31_params_mem_t bl31_params_mem;
41e35d0edbSJorge Ramirez-Ortiz 
42e35d0edbSJorge Ramirez-Ortiz meminfo_t *bl2_plat_sec_mem_layout(void)
43e35d0edbSJorge Ramirez-Ortiz {
44e35d0edbSJorge Ramirez-Ortiz 	return &bl2_tzram_layout;
45e35d0edbSJorge Ramirez-Ortiz }
46e35d0edbSJorge Ramirez-Ortiz 
47e35d0edbSJorge Ramirez-Ortiz bl31_params_t *bl2_plat_get_bl31_params(void)
48e35d0edbSJorge Ramirez-Ortiz {
49e35d0edbSJorge Ramirez-Ortiz 	bl31_params_t *bl2_to_bl31_params = NULL;
50e35d0edbSJorge Ramirez-Ortiz 
51e35d0edbSJorge Ramirez-Ortiz 	/*
52e35d0edbSJorge Ramirez-Ortiz 	 * Initialise the memory for all the arguments that needs to
53e35d0edbSJorge Ramirez-Ortiz 	 * be passed to BL3-1
54e35d0edbSJorge Ramirez-Ortiz 	 */
55e35d0edbSJorge Ramirez-Ortiz 	memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
56e35d0edbSJorge Ramirez-Ortiz 
57e35d0edbSJorge Ramirez-Ortiz 	/* Assign memory for TF related information */
58e35d0edbSJorge Ramirez-Ortiz 	bl2_to_bl31_params = &bl31_params_mem.bl31_params;
59e35d0edbSJorge Ramirez-Ortiz 	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
60e35d0edbSJorge Ramirez-Ortiz 
61e35d0edbSJorge Ramirez-Ortiz 	/* Fill BL3-1 related information */
62e35d0edbSJorge Ramirez-Ortiz 	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
63e35d0edbSJorge Ramirez-Ortiz 	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info,
64e35d0edbSJorge Ramirez-Ortiz 		       PARAM_IMAGE_BINARY, VERSION_1, 0);
65e35d0edbSJorge Ramirez-Ortiz 
66*f336774bSVictor Chong 	/* Fill BL3-2 related information if it exists */
67*f336774bSVictor Chong #ifdef BL32_BASE
68*f336774bSVictor Chong 	bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
69*f336774bSVictor Chong 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
70*f336774bSVictor Chong 		VERSION_1, 0);
71*f336774bSVictor Chong 	bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
72*f336774bSVictor Chong 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
73*f336774bSVictor Chong 		VERSION_1, 0);
74*f336774bSVictor Chong #endif
75*f336774bSVictor Chong 
76e35d0edbSJorge Ramirez-Ortiz 	/* Fill BL3-3 related information */
77e35d0edbSJorge Ramirez-Ortiz 	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
78e35d0edbSJorge Ramirez-Ortiz 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
79e35d0edbSJorge Ramirez-Ortiz 		       PARAM_EP, VERSION_1, 0);
80e35d0edbSJorge Ramirez-Ortiz 
81e35d0edbSJorge Ramirez-Ortiz 	/* BL3-3 expects to receive the primary CPU MPID (through x0) */
82e35d0edbSJorge Ramirez-Ortiz 	bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
83e35d0edbSJorge Ramirez-Ortiz 
84e35d0edbSJorge Ramirez-Ortiz 	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
85e35d0edbSJorge Ramirez-Ortiz 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info,
86e35d0edbSJorge Ramirez-Ortiz 		       PARAM_IMAGE_BINARY, VERSION_1, 0);
87e35d0edbSJorge Ramirez-Ortiz 
88e35d0edbSJorge Ramirez-Ortiz 	return bl2_to_bl31_params;
89e35d0edbSJorge Ramirez-Ortiz }
90e35d0edbSJorge Ramirez-Ortiz 
91e35d0edbSJorge Ramirez-Ortiz struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
92e35d0edbSJorge Ramirez-Ortiz {
93e35d0edbSJorge Ramirez-Ortiz 	return &bl31_params_mem.bl31_ep_info;
94e35d0edbSJorge Ramirez-Ortiz }
95e35d0edbSJorge Ramirez-Ortiz 
96e35d0edbSJorge Ramirez-Ortiz void bl2_plat_set_bl31_ep_info(image_info_t *image,
97e35d0edbSJorge Ramirez-Ortiz 			       entry_point_info_t *bl31_ep_info)
98e35d0edbSJorge Ramirez-Ortiz {
99e35d0edbSJorge Ramirez-Ortiz 	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
100e35d0edbSJorge Ramirez-Ortiz 	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
101e35d0edbSJorge Ramirez-Ortiz 				     DISABLE_ALL_EXCEPTIONS);
102e35d0edbSJorge Ramirez-Ortiz }
103e35d0edbSJorge Ramirez-Ortiz 
104*f336774bSVictor Chong /*******************************************************************************
105*f336774bSVictor Chong  * Before calling this function BL32 is loaded in memory and its entrypoint
106*f336774bSVictor Chong  * is set by load_image. This is a placeholder for the platform to change
107*f336774bSVictor Chong  * the entrypoint of BL32 and set SPSR and security state.
108*f336774bSVictor Chong  * On Poplar we only set the security state of the entrypoint
109*f336774bSVictor Chong  ******************************************************************************/
110*f336774bSVictor Chong #ifdef BL32_BASE
111*f336774bSVictor Chong void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
112*f336774bSVictor Chong 					entry_point_info_t *bl32_ep_info)
113*f336774bSVictor Chong {
114*f336774bSVictor Chong 	SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
115*f336774bSVictor Chong 	/*
116*f336774bSVictor Chong 	 * The Secure Payload Dispatcher service is responsible for
117*f336774bSVictor Chong 	 * setting the SPSR prior to entry into the BL32 image.
118*f336774bSVictor Chong 	 */
119*f336774bSVictor Chong 	bl32_ep_info->spsr = 0;
120*f336774bSVictor Chong }
121*f336774bSVictor Chong 
122*f336774bSVictor Chong /*******************************************************************************
123*f336774bSVictor Chong  * Populate the extents of memory available for loading BL32
124*f336774bSVictor Chong  ******************************************************************************/
125*f336774bSVictor Chong void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
126*f336774bSVictor Chong {
127*f336774bSVictor Chong 	/*
128*f336774bSVictor Chong 	 * Populate the extents of memory available for loading BL32.
129*f336774bSVictor Chong 	 */
130*f336774bSVictor Chong 	bl32_meminfo->total_base = BL32_BASE;
131*f336774bSVictor Chong 	bl32_meminfo->free_base = BL32_BASE;
132*f336774bSVictor Chong 	bl32_meminfo->total_size =
133*f336774bSVictor Chong 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
134*f336774bSVictor Chong 	bl32_meminfo->free_size =
135*f336774bSVictor Chong 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
136*f336774bSVictor Chong }
137*f336774bSVictor Chong #endif /* BL32_BASE */
138*f336774bSVictor Chong 
139e35d0edbSJorge Ramirez-Ortiz static uint32_t hisi_get_spsr_for_bl33_entry(void)
140e35d0edbSJorge Ramirez-Ortiz {
141e35d0edbSJorge Ramirez-Ortiz 	unsigned long el_status;
142e35d0edbSJorge Ramirez-Ortiz 	unsigned int mode;
143e35d0edbSJorge Ramirez-Ortiz 	uint32_t spsr;
144e35d0edbSJorge Ramirez-Ortiz 
145e35d0edbSJorge Ramirez-Ortiz 	/* Figure out what mode we enter the non-secure world in */
146e35d0edbSJorge Ramirez-Ortiz 	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
147e35d0edbSJorge Ramirez-Ortiz 	el_status &= ID_AA64PFR0_ELX_MASK;
148e35d0edbSJorge Ramirez-Ortiz 
149e35d0edbSJorge Ramirez-Ortiz 	mode = (el_status) ? MODE_EL2 : MODE_EL1;
150e35d0edbSJorge Ramirez-Ortiz 
151e35d0edbSJorge Ramirez-Ortiz 	/*
152e35d0edbSJorge Ramirez-Ortiz 	 * TODO: Consider the possibility of specifying the SPSR in
153e35d0edbSJorge Ramirez-Ortiz 	 * the FIP ToC and allowing the platform to have a say as
154e35d0edbSJorge Ramirez-Ortiz 	 * well.
155e35d0edbSJorge Ramirez-Ortiz 	 */
156e35d0edbSJorge Ramirez-Ortiz 	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
157e35d0edbSJorge Ramirez-Ortiz 	return spsr;
158e35d0edbSJorge Ramirez-Ortiz }
159e35d0edbSJorge Ramirez-Ortiz 
160e35d0edbSJorge Ramirez-Ortiz void bl2_plat_set_bl33_ep_info(image_info_t *image,
161e35d0edbSJorge Ramirez-Ortiz 			       entry_point_info_t *bl33_ep_info)
162e35d0edbSJorge Ramirez-Ortiz {
163e35d0edbSJorge Ramirez-Ortiz 	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
164e35d0edbSJorge Ramirez-Ortiz 	bl33_ep_info->spsr = hisi_get_spsr_for_bl33_entry();
165e35d0edbSJorge Ramirez-Ortiz 	bl33_ep_info->args.arg2 = image->image_size;
166e35d0edbSJorge Ramirez-Ortiz }
167e35d0edbSJorge Ramirez-Ortiz 
168e35d0edbSJorge Ramirez-Ortiz void bl2_plat_flush_bl31_params(void)
169e35d0edbSJorge Ramirez-Ortiz {
170e35d0edbSJorge Ramirez-Ortiz 	flush_dcache_range((unsigned long)&bl31_params_mem,
171e35d0edbSJorge Ramirez-Ortiz 			   sizeof(bl2_to_bl31_params_mem_t));
172e35d0edbSJorge Ramirez-Ortiz }
173e35d0edbSJorge Ramirez-Ortiz 
174e35d0edbSJorge Ramirez-Ortiz void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
175e35d0edbSJorge Ramirez-Ortiz {
176e35d0edbSJorge Ramirez-Ortiz 	bl33_meminfo->total_base = DDR_BASE;
177e35d0edbSJorge Ramirez-Ortiz 	bl33_meminfo->total_size = DDR_SIZE;
178e35d0edbSJorge Ramirez-Ortiz 	bl33_meminfo->free_base  = DDR_BASE;
179e35d0edbSJorge Ramirez-Ortiz 	bl33_meminfo->free_size  = DDR_SIZE;
180e35d0edbSJorge Ramirez-Ortiz }
181e35d0edbSJorge Ramirez-Ortiz 
182e35d0edbSJorge Ramirez-Ortiz void bl2_early_platform_setup(meminfo_t *mem_layout)
183e35d0edbSJorge Ramirez-Ortiz {
184e35d0edbSJorge Ramirez-Ortiz 	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
185e35d0edbSJorge Ramirez-Ortiz 
186e35d0edbSJorge Ramirez-Ortiz 	/* Enable arch timer */
187e35d0edbSJorge Ramirez-Ortiz 	generic_delay_timer_init();
188e35d0edbSJorge Ramirez-Ortiz 
189e35d0edbSJorge Ramirez-Ortiz 	bl2_tzram_layout = *mem_layout;
190e35d0edbSJorge Ramirez-Ortiz }
191e35d0edbSJorge Ramirez-Ortiz 
192e35d0edbSJorge Ramirez-Ortiz void bl2_plat_arch_setup(void)
193e35d0edbSJorge Ramirez-Ortiz {
194e35d0edbSJorge Ramirez-Ortiz 	plat_configure_mmu_el1(bl2_tzram_layout.total_base,
195e35d0edbSJorge Ramirez-Ortiz 			       bl2_tzram_layout.total_size,
196e35d0edbSJorge Ramirez-Ortiz 			       BL2_RO_BASE,
197e35d0edbSJorge Ramirez-Ortiz 			       BL2_RO_LIMIT,
198e35d0edbSJorge Ramirez-Ortiz 			       BL2_COHERENT_RAM_BASE,
199e35d0edbSJorge Ramirez-Ortiz 			       BL2_COHERENT_RAM_LIMIT);
200e35d0edbSJorge Ramirez-Ortiz }
201e35d0edbSJorge Ramirez-Ortiz 
202e35d0edbSJorge Ramirez-Ortiz void bl2_platform_setup(void)
203e35d0edbSJorge Ramirez-Ortiz {
204e35d0edbSJorge Ramirez-Ortiz 	plat_io_setup();
205e35d0edbSJorge Ramirez-Ortiz }
206e35d0edbSJorge Ramirez-Ortiz 
207e35d0edbSJorge Ramirez-Ortiz unsigned long plat_get_ns_image_entrypoint(void)
208e35d0edbSJorge Ramirez-Ortiz {
2095a3ec61fSVictor Chong 	return PLAT_POPLAR_NS_IMAGE_OFFSET;
210e35d0edbSJorge Ramirez-Ortiz }
211