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