xref: /rk3399_ARM-atf/plat/hisilicon/poplar/bl2_plat_setup.c (revision 264410306381d4edceeb03b3a0e8db66605427be)
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 <desc_image_load.h>
13 #include <dw_mmc.h>
14 #include <emmc.h>
15 #include <errno.h>
16 #include <generic_delay_timer.h>
17 #include <mmio.h>
18 #include <optee_utils.h>
19 #include <partition/partition.h>
20 #include <platform.h>
21 #include <string.h>
22 #include "hi3798cv200.h"
23 #include "plat_private.h"
24 
25 /* Memory ranges for code and read only data sections */
26 #define BL2_RO_BASE	(unsigned long)(&__RO_START__)
27 #define BL2_RO_LIMIT	(unsigned long)(&__RO_END__)
28 
29 /* Memory ranges for coherent memory section */
30 #define BL2_COHERENT_RAM_BASE	(unsigned long)(&__COHERENT_RAM_START__)
31 #define BL2_COHERENT_RAM_LIMIT	(unsigned long)(&__COHERENT_RAM_END__)
32 
33 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
34 
35 #if !LOAD_IMAGE_V2
36 
37 /*******************************************************************************
38  * This structure represents the superset of information that is passed to
39  * BL31, e.g. while passing control to it from BL2, bl31_params
40  * and other platform specific params
41  ******************************************************************************/
42 typedef struct bl2_to_bl31_params_mem {
43 	bl31_params_t		bl31_params;
44 	image_info_t		bl31_image_info;
45 	image_info_t		bl32_image_info;
46 	image_info_t		bl33_image_info;
47 	entry_point_info_t	bl33_ep_info;
48 	entry_point_info_t	bl32_ep_info;
49 	entry_point_info_t	bl31_ep_info;
50 } bl2_to_bl31_params_mem_t;
51 
52 static bl2_to_bl31_params_mem_t bl31_params_mem;
53 
54 meminfo_t *bl2_plat_sec_mem_layout(void)
55 {
56 	return &bl2_tzram_layout;
57 }
58 
59 #ifdef SCP_BL2_BASE
60 void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo)
61 {
62 	/*
63 	 * This platform has no SCP_BL2 yet
64 	 */
65 }
66 #endif
67 #endif /* LOAD_IMAGE_V2 */
68 
69 /*******************************************************************************
70  * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
71  * Return 0 on success, -1 otherwise.
72  ******************************************************************************/
73 #if LOAD_IMAGE_V2
74 int plat_poplar_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info)
75 #else
76 int bl2_plat_handle_scp_bl2(struct image_info *scp_bl2_image_info)
77 #endif
78 {
79 	/*
80 	 * This platform has no SCP_BL2 yet
81 	 */
82 	return 0;
83 }
84 
85 /*******************************************************************************
86  * Gets SPSR for BL32 entry
87  ******************************************************************************/
88 uint32_t poplar_get_spsr_for_bl32_entry(void)
89 {
90 	/*
91 	 * The Secure Payload Dispatcher service is responsible for
92 	 * setting the SPSR prior to entry into the BL3-2 image.
93 	 */
94 	return 0;
95 }
96 
97 /*******************************************************************************
98  * Gets SPSR for BL33 entry
99  ******************************************************************************/
100 #ifndef AARCH32
101 uint32_t poplar_get_spsr_for_bl33_entry(void)
102 {
103 	unsigned long el_status;
104 	unsigned int mode;
105 	uint32_t spsr;
106 
107 	/* Figure out what mode we enter the non-secure world in */
108 	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
109 	el_status &= ID_AA64PFR0_ELX_MASK;
110 
111 	mode = (el_status) ? MODE_EL2 : MODE_EL1;
112 
113 	/*
114 	 * TODO: Consider the possibility of specifying the SPSR in
115 	 * the FIP ToC and allowing the platform to have a say as
116 	 * well.
117 	 */
118 	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
119 	return spsr;
120 }
121 #else
122 uint32_t poplar_get_spsr_for_bl33_entry(void)
123 {
124 	unsigned int hyp_status, mode, spsr;
125 
126 	hyp_status = GET_VIRT_EXT(read_id_pfr1());
127 
128 	mode = (hyp_status) ? MODE32_hyp : MODE32_svc;
129 
130 	/*
131 	 * TODO: Consider the possibility of specifying the SPSR in
132 	 * the FIP ToC and allowing the platform to have a say as
133 	 * well.
134 	 */
135 	spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1,
136 			SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
137 	return spsr;
138 }
139 #endif /* AARCH32 */
140 
141 #if LOAD_IMAGE_V2
142 int poplar_bl2_handle_post_image_load(unsigned int image_id)
143 {
144 	int err = 0;
145 	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
146 #ifdef SPD_opteed
147 	bl_mem_params_node_t *pager_mem_params = NULL;
148 	bl_mem_params_node_t *paged_mem_params = NULL;
149 #endif
150 
151 	assert(bl_mem_params);
152 
153 	switch (image_id) {
154 #ifdef AARCH64
155 	case BL32_IMAGE_ID:
156 #ifdef SPD_opteed
157 		pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
158 		assert(pager_mem_params);
159 
160 		paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
161 		assert(paged_mem_params);
162 
163 		err = parse_optee_header(&bl_mem_params->ep_info,
164 				&pager_mem_params->image_info,
165 				&paged_mem_params->image_info);
166 		if (err != 0) {
167 			WARN("OPTEE header parse error.\n");
168 		}
169 
170 		/*
171 		 * OP-TEE expect to receive DTB address in x2.
172 		 * This will be copied into x2 by dispatcher.
173 		 * Set this (arg3) if necessary
174 		 */
175 		/* bl_mem_params->ep_info.args.arg3 = PLAT_HIKEY_DT_BASE; */
176 #endif
177 		bl_mem_params->ep_info.spsr = poplar_get_spsr_for_bl32_entry();
178 		break;
179 #endif
180 
181 	case BL33_IMAGE_ID:
182 		/* BL33 expects to receive the primary CPU MPID (through r0) */
183 		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
184 		bl_mem_params->ep_info.spsr = poplar_get_spsr_for_bl33_entry();
185 		break;
186 
187 #ifdef SCP_BL2_BASE
188 	case SCP_BL2_IMAGE_ID:
189 		/* The subsequent handling of SCP_BL2 is platform specific */
190 		err = plat_poplar_bl2_handle_scp_bl2(&bl_mem_params->image_info);
191 		if (err) {
192 			WARN("Failure in platform-specific handling of SCP_BL2 image.\n");
193 		}
194 		break;
195 #endif
196 	}
197 
198 	return err;
199 }
200 
201 /*******************************************************************************
202  * This function can be used by the platforms to update/use image
203  * information for given `image_id`.
204  ******************************************************************************/
205 int bl2_plat_handle_post_image_load(unsigned int image_id)
206 {
207 	return poplar_bl2_handle_post_image_load(image_id);
208 }
209 
210 #else /* LOAD_IMAGE_V2 */
211 
212 bl31_params_t *bl2_plat_get_bl31_params(void)
213 {
214 	bl31_params_t *bl2_to_bl31_params = NULL;
215 
216 	/*
217 	 * Initialise the memory for all the arguments that needs to
218 	 * be passed to BL3-1
219 	 */
220 	memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
221 
222 	/* Assign memory for TF related information */
223 	bl2_to_bl31_params = &bl31_params_mem.bl31_params;
224 	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
225 
226 	/* Fill BL3-1 related information */
227 	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
228 	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info,
229 		       PARAM_IMAGE_BINARY, VERSION_1, 0);
230 
231 	/* Fill BL3-2 related information if it exists */
232 #ifdef BL32_BASE
233 	bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
234 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
235 		VERSION_1, 0);
236 	bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
237 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
238 		VERSION_1, 0);
239 #endif
240 
241 	/* Fill BL3-3 related information */
242 	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
243 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
244 		       PARAM_EP, VERSION_1, 0);
245 
246 	/* BL3-3 expects to receive the primary CPU MPID (through x0) */
247 	bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
248 
249 	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
250 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info,
251 		       PARAM_IMAGE_BINARY, VERSION_1, 0);
252 
253 	return bl2_to_bl31_params;
254 }
255 
256 struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
257 {
258 #if DEBUG
259 	bl31_params_mem.bl31_ep_info.args.arg1 = POPLAR_BL31_PLAT_PARAM_VAL;
260 #endif
261 
262 	return &bl31_params_mem.bl31_ep_info;
263 }
264 
265 void bl2_plat_set_bl31_ep_info(image_info_t *image,
266 			       entry_point_info_t *bl31_ep_info)
267 {
268 	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
269 	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
270 				     DISABLE_ALL_EXCEPTIONS);
271 }
272 
273 /*******************************************************************************
274  * Before calling this function BL32 is loaded in memory and its entrypoint
275  * is set by load_image. This is a placeholder for the platform to change
276  * the entrypoint of BL32 and set SPSR and security state.
277  * On Poplar we only set the security state of the entrypoint
278  ******************************************************************************/
279 #ifdef BL32_BASE
280 void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
281 					entry_point_info_t *bl32_ep_info)
282 {
283 	SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
284 	/*
285 	 * The Secure Payload Dispatcher service is responsible for
286 	 * setting the SPSR prior to entry into the BL32 image.
287 	 */
288 	bl32_ep_info->spsr = 0;
289 }
290 
291 /*******************************************************************************
292  * Populate the extents of memory available for loading BL32
293  ******************************************************************************/
294 void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
295 {
296 	/*
297 	 * Populate the extents of memory available for loading BL32.
298 	 */
299 	bl32_meminfo->total_base = BL32_BASE;
300 	bl32_meminfo->free_base = BL32_BASE;
301 	bl32_meminfo->total_size =
302 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
303 	bl32_meminfo->free_size =
304 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
305 }
306 #endif /* BL32_BASE */
307 
308 void bl2_plat_set_bl33_ep_info(image_info_t *image,
309 			       entry_point_info_t *bl33_ep_info)
310 {
311 	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
312 	bl33_ep_info->spsr = poplar_get_spsr_for_bl33_entry();
313 	bl33_ep_info->args.arg2 = image->image_size;
314 }
315 
316 void bl2_plat_flush_bl31_params(void)
317 {
318 	flush_dcache_range((unsigned long)&bl31_params_mem,
319 			   sizeof(bl2_to_bl31_params_mem_t));
320 }
321 
322 void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
323 {
324 	bl33_meminfo->total_base = DDR_BASE;
325 	bl33_meminfo->total_size = DDR_SIZE;
326 	bl33_meminfo->free_base  = DDR_BASE;
327 	bl33_meminfo->free_size  = DDR_SIZE;
328 }
329 #endif /* LOAD_IMAGE_V2 */
330 
331 void bl2_early_platform_setup(meminfo_t *mem_layout)
332 {
333 #if !POPLAR_RECOVERY
334 	dw_mmc_params_t params = EMMC_INIT_PARAMS(POPLAR_EMMC_DESC_BASE);
335 #endif
336 
337 	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
338 
339 	/* Enable arch timer */
340 	generic_delay_timer_init();
341 
342 	bl2_tzram_layout = *mem_layout;
343 
344 #if !POPLAR_RECOVERY
345 	/* SoC-specific emmc register are initialized/configured by bootrom */
346 	INFO("BL2: initializing emmc\n");
347 	dw_mmc_init(&params);
348 #endif
349 
350 	plat_io_setup();
351 }
352 
353 void bl2_plat_arch_setup(void)
354 {
355 	plat_configure_mmu_el1(bl2_tzram_layout.total_base,
356 			       bl2_tzram_layout.total_size,
357 			       BL2_RO_BASE,
358 			       BL2_RO_LIMIT,
359 			       BL2_COHERENT_RAM_BASE,
360 			       BL2_COHERENT_RAM_LIMIT);
361 }
362 
363 void bl2_platform_setup(void)
364 {
365 }
366 
367 uintptr_t plat_get_ns_image_entrypoint(void)
368 {
369 #ifdef PRELOADED_BL33_BASE
370 	return PRELOADED_BL33_BASE;
371 #else
372 	return PLAT_POPLAR_NS_IMAGE_OFFSET;
373 #endif
374 }
375