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