xref: /rk3399_ARM-atf/plat/hisilicon/poplar/bl2_plat_setup.c (revision ff2743e544f0f82381ebb9dff8f14eacb837d2e0)
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 	default:
197 		/* Do nothing in default case */
198 		break;
199 	}
200 
201 	return err;
202 }
203 
204 /*******************************************************************************
205  * This function can be used by the platforms to update/use image
206  * information for given `image_id`.
207  ******************************************************************************/
208 int bl2_plat_handle_post_image_load(unsigned int image_id)
209 {
210 	return poplar_bl2_handle_post_image_load(image_id);
211 }
212 
213 #else /* LOAD_IMAGE_V2 */
214 
215 bl31_params_t *bl2_plat_get_bl31_params(void)
216 {
217 	bl31_params_t *bl2_to_bl31_params = NULL;
218 
219 	/*
220 	 * Initialise the memory for all the arguments that needs to
221 	 * be passed to BL3-1
222 	 */
223 	memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
224 
225 	/* Assign memory for TF related information */
226 	bl2_to_bl31_params = &bl31_params_mem.bl31_params;
227 	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
228 
229 	/* Fill BL3-1 related information */
230 	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
231 	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info,
232 		       PARAM_IMAGE_BINARY, VERSION_1, 0);
233 
234 	/* Fill BL3-2 related information if it exists */
235 #ifdef BL32_BASE
236 	bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
237 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
238 		VERSION_1, 0);
239 	bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
240 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
241 		VERSION_1, 0);
242 #endif
243 
244 	/* Fill BL3-3 related information */
245 	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
246 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
247 		       PARAM_EP, VERSION_1, 0);
248 
249 	/* BL3-3 expects to receive the primary CPU MPID (through x0) */
250 	bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
251 
252 	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
253 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info,
254 		       PARAM_IMAGE_BINARY, VERSION_1, 0);
255 
256 	return bl2_to_bl31_params;
257 }
258 
259 struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
260 {
261 #if DEBUG
262 	bl31_params_mem.bl31_ep_info.args.arg1 = POPLAR_BL31_PLAT_PARAM_VAL;
263 #endif
264 
265 	return &bl31_params_mem.bl31_ep_info;
266 }
267 
268 void bl2_plat_set_bl31_ep_info(image_info_t *image,
269 			       entry_point_info_t *bl31_ep_info)
270 {
271 	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
272 	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
273 				     DISABLE_ALL_EXCEPTIONS);
274 }
275 
276 /*******************************************************************************
277  * Before calling this function BL32 is loaded in memory and its entrypoint
278  * is set by load_image. This is a placeholder for the platform to change
279  * the entrypoint of BL32 and set SPSR and security state.
280  * On Poplar we only set the security state of the entrypoint
281  ******************************************************************************/
282 #ifdef BL32_BASE
283 void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
284 					entry_point_info_t *bl32_ep_info)
285 {
286 	SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
287 	/*
288 	 * The Secure Payload Dispatcher service is responsible for
289 	 * setting the SPSR prior to entry into the BL32 image.
290 	 */
291 	bl32_ep_info->spsr = 0;
292 }
293 
294 /*******************************************************************************
295  * Populate the extents of memory available for loading BL32
296  ******************************************************************************/
297 void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
298 {
299 	/*
300 	 * Populate the extents of memory available for loading BL32.
301 	 */
302 	bl32_meminfo->total_base = BL32_BASE;
303 	bl32_meminfo->free_base = BL32_BASE;
304 	bl32_meminfo->total_size =
305 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
306 	bl32_meminfo->free_size =
307 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
308 }
309 #endif /* BL32_BASE */
310 
311 void bl2_plat_set_bl33_ep_info(image_info_t *image,
312 			       entry_point_info_t *bl33_ep_info)
313 {
314 	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
315 	bl33_ep_info->spsr = poplar_get_spsr_for_bl33_entry();
316 	bl33_ep_info->args.arg2 = image->image_size;
317 }
318 
319 void bl2_plat_flush_bl31_params(void)
320 {
321 	flush_dcache_range((unsigned long)&bl31_params_mem,
322 			   sizeof(bl2_to_bl31_params_mem_t));
323 }
324 
325 void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
326 {
327 	bl33_meminfo->total_base = DDR_BASE;
328 	bl33_meminfo->total_size = DDR_SIZE;
329 	bl33_meminfo->free_base  = DDR_BASE;
330 	bl33_meminfo->free_size  = DDR_SIZE;
331 }
332 #endif /* LOAD_IMAGE_V2 */
333 
334 void bl2_early_platform_setup(meminfo_t *mem_layout)
335 {
336 #if !POPLAR_RECOVERY
337 	dw_mmc_params_t params = EMMC_INIT_PARAMS(POPLAR_EMMC_DESC_BASE);
338 #endif
339 
340 	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
341 
342 	/* Enable arch timer */
343 	generic_delay_timer_init();
344 
345 	bl2_tzram_layout = *mem_layout;
346 
347 #if !POPLAR_RECOVERY
348 	/* SoC-specific emmc register are initialized/configured by bootrom */
349 	INFO("BL2: initializing emmc\n");
350 	dw_mmc_init(&params);
351 #endif
352 
353 	plat_io_setup();
354 }
355 
356 void bl2_plat_arch_setup(void)
357 {
358 	plat_configure_mmu_el1(bl2_tzram_layout.total_base,
359 			       bl2_tzram_layout.total_size,
360 			       BL2_RO_BASE,
361 			       BL2_RO_LIMIT,
362 			       BL2_COHERENT_RAM_BASE,
363 			       BL2_COHERENT_RAM_LIMIT);
364 }
365 
366 void bl2_platform_setup(void)
367 {
368 }
369 
370 uintptr_t plat_get_ns_image_entrypoint(void)
371 {
372 #ifdef PRELOADED_BL33_BASE
373 	return PRELOADED_BL33_BASE;
374 #else
375 	return PLAT_POPLAR_NS_IMAGE_OFFSET;
376 #endif
377 }
378