xref: /arm-trusted-firmware/plat/arm/common/sp_min/arm_sp_min_setup.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <assert.h>
8*91f16700Schasinglulu 
9*91f16700Schasinglulu #include <platform_def.h>
10*91f16700Schasinglulu 
11*91f16700Schasinglulu #include <bl32/sp_min/platform_sp_min.h>
12*91f16700Schasinglulu #include <common/bl_common.h>
13*91f16700Schasinglulu #include <common/debug.h>
14*91f16700Schasinglulu #include <drivers/console.h>
15*91f16700Schasinglulu #include <lib/mmio.h>
16*91f16700Schasinglulu #include <plat/arm/common/plat_arm.h>
17*91f16700Schasinglulu #include <plat/common/platform.h>
18*91f16700Schasinglulu 
19*91f16700Schasinglulu static entry_point_info_t bl33_image_ep_info;
20*91f16700Schasinglulu 
21*91f16700Schasinglulu /* Weak definitions may be overridden in specific ARM standard platform */
22*91f16700Schasinglulu #pragma weak sp_min_platform_setup
23*91f16700Schasinglulu #pragma weak sp_min_plat_arch_setup
24*91f16700Schasinglulu #pragma weak plat_arm_sp_min_early_platform_setup
25*91f16700Schasinglulu 
26*91f16700Schasinglulu #define MAP_BL_SP_MIN_TOTAL	MAP_REGION_FLAT(			\
27*91f16700Schasinglulu 					BL32_BASE,			\
28*91f16700Schasinglulu 					BL32_END - BL32_BASE,		\
29*91f16700Schasinglulu 					MT_MEMORY | MT_RW | MT_SECURE)
30*91f16700Schasinglulu 
31*91f16700Schasinglulu /*
32*91f16700Schasinglulu  * Check that BL32_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page
33*91f16700Schasinglulu  * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2.
34*91f16700Schasinglulu  */
35*91f16700Schasinglulu #if !RESET_TO_SP_MIN
36*91f16700Schasinglulu CASSERT(BL32_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl32_base_overflows);
37*91f16700Schasinglulu #endif
38*91f16700Schasinglulu 
39*91f16700Schasinglulu /*******************************************************************************
40*91f16700Schasinglulu  * Return a pointer to the 'entry_point_info' structure of the next image for the
41*91f16700Schasinglulu  * security state specified. BL33 corresponds to the non-secure image type
42*91f16700Schasinglulu  * while BL32 corresponds to the secure image type. A NULL pointer is returned
43*91f16700Schasinglulu  * if the image does not exist.
44*91f16700Schasinglulu  ******************************************************************************/
45*91f16700Schasinglulu entry_point_info_t *sp_min_plat_get_bl33_ep_info(void)
46*91f16700Schasinglulu {
47*91f16700Schasinglulu 	entry_point_info_t *next_image_info;
48*91f16700Schasinglulu 
49*91f16700Schasinglulu 	next_image_info = &bl33_image_ep_info;
50*91f16700Schasinglulu 
51*91f16700Schasinglulu 	/*
52*91f16700Schasinglulu 	 * None of the images on the ARM development platforms can have 0x0
53*91f16700Schasinglulu 	 * as the entrypoint
54*91f16700Schasinglulu 	 */
55*91f16700Schasinglulu 	if (next_image_info->pc)
56*91f16700Schasinglulu 		return next_image_info;
57*91f16700Schasinglulu 	else
58*91f16700Schasinglulu 		return NULL;
59*91f16700Schasinglulu }
60*91f16700Schasinglulu 
61*91f16700Schasinglulu /*******************************************************************************
62*91f16700Schasinglulu  * Utility function to perform early platform setup.
63*91f16700Schasinglulu  ******************************************************************************/
64*91f16700Schasinglulu void arm_sp_min_early_platform_setup(void *from_bl2, uintptr_t tos_fw_config,
65*91f16700Schasinglulu 			uintptr_t hw_config, void *plat_params_from_bl2)
66*91f16700Schasinglulu {
67*91f16700Schasinglulu 	/* Initialize the console to provide early debug support */
68*91f16700Schasinglulu 	arm_console_boot_init();
69*91f16700Schasinglulu 
70*91f16700Schasinglulu #if RESET_TO_SP_MIN
71*91f16700Schasinglulu 	/* There are no parameters from BL2 if SP_MIN is a reset vector */
72*91f16700Schasinglulu 	assert(from_bl2 == NULL);
73*91f16700Schasinglulu 	assert(plat_params_from_bl2 == NULL);
74*91f16700Schasinglulu 
75*91f16700Schasinglulu 	/* Populate entry point information for BL33 */
76*91f16700Schasinglulu 	SET_PARAM_HEAD(&bl33_image_ep_info,
77*91f16700Schasinglulu 				PARAM_EP,
78*91f16700Schasinglulu 				VERSION_1,
79*91f16700Schasinglulu 				0);
80*91f16700Schasinglulu 	/*
81*91f16700Schasinglulu 	 * Tell SP_MIN where the non-trusted software image
82*91f16700Schasinglulu 	 * is located and the entry state information
83*91f16700Schasinglulu 	 */
84*91f16700Schasinglulu 	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
85*91f16700Schasinglulu 	bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
86*91f16700Schasinglulu 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
87*91f16700Schasinglulu 
88*91f16700Schasinglulu # if ARM_LINUX_KERNEL_AS_BL33
89*91f16700Schasinglulu 	/*
90*91f16700Schasinglulu 	 * According to the file ``Documentation/arm/Booting`` of the Linux
91*91f16700Schasinglulu 	 * kernel tree, Linux expects:
92*91f16700Schasinglulu 	 * r0 = 0
93*91f16700Schasinglulu 	 * r1 = machine type number, optional in DT-only platforms (~0 if so)
94*91f16700Schasinglulu 	 * r2 = Physical address of the device tree blob
95*91f16700Schasinglulu 	 */
96*91f16700Schasinglulu 	bl33_image_ep_info.args.arg0 = 0U;
97*91f16700Schasinglulu 	bl33_image_ep_info.args.arg1 = ~0U;
98*91f16700Schasinglulu 	bl33_image_ep_info.args.arg2 = (u_register_t)ARM_PRELOADED_DTB_BASE;
99*91f16700Schasinglulu # endif
100*91f16700Schasinglulu 
101*91f16700Schasinglulu #else /* RESET_TO_SP_MIN */
102*91f16700Schasinglulu 
103*91f16700Schasinglulu 	/*
104*91f16700Schasinglulu 	 * Check params passed from BL2 should not be NULL,
105*91f16700Schasinglulu 	 */
106*91f16700Schasinglulu 	bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
107*91f16700Schasinglulu 	assert(params_from_bl2 != NULL);
108*91f16700Schasinglulu 	assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
109*91f16700Schasinglulu 	assert(params_from_bl2->h.version >= VERSION_2);
110*91f16700Schasinglulu 
111*91f16700Schasinglulu 	bl_params_node_t *bl_params = params_from_bl2->head;
112*91f16700Schasinglulu 
113*91f16700Schasinglulu 	/*
114*91f16700Schasinglulu 	 * Copy BL33 entry point information.
115*91f16700Schasinglulu 	 * They are stored in Secure RAM, in BL2's address space.
116*91f16700Schasinglulu 	 */
117*91f16700Schasinglulu 	while (bl_params) {
118*91f16700Schasinglulu 		if (bl_params->image_id == BL33_IMAGE_ID) {
119*91f16700Schasinglulu 			bl33_image_ep_info = *bl_params->ep_info;
120*91f16700Schasinglulu 			break;
121*91f16700Schasinglulu 		}
122*91f16700Schasinglulu 
123*91f16700Schasinglulu 		bl_params = bl_params->next_params_info;
124*91f16700Schasinglulu 	}
125*91f16700Schasinglulu 
126*91f16700Schasinglulu 	if (bl33_image_ep_info.pc == 0)
127*91f16700Schasinglulu 		panic();
128*91f16700Schasinglulu 
129*91f16700Schasinglulu #endif /* RESET_TO_SP_MIN */
130*91f16700Schasinglulu 
131*91f16700Schasinglulu }
132*91f16700Schasinglulu 
133*91f16700Schasinglulu /*******************************************************************************
134*91f16700Schasinglulu  * Default implementation for sp_min_platform_setup2() for ARM platforms
135*91f16700Schasinglulu  ******************************************************************************/
136*91f16700Schasinglulu void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
137*91f16700Schasinglulu 			u_register_t arg2, u_register_t arg3)
138*91f16700Schasinglulu {
139*91f16700Schasinglulu 	arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
140*91f16700Schasinglulu 
141*91f16700Schasinglulu 	/*
142*91f16700Schasinglulu 	 * Initialize Interconnect for this cluster during cold boot.
143*91f16700Schasinglulu 	 * No need for locks as no other CPU is active.
144*91f16700Schasinglulu 	 */
145*91f16700Schasinglulu 	plat_arm_interconnect_init();
146*91f16700Schasinglulu 
147*91f16700Schasinglulu 	/*
148*91f16700Schasinglulu 	 * Enable Interconnect coherency for the primary CPU's cluster.
149*91f16700Schasinglulu 	 * Earlier bootloader stages might already do this (e.g. Trusted
150*91f16700Schasinglulu 	 * Firmware's BL1 does it) but we can't assume so. There is no harm in
151*91f16700Schasinglulu 	 * executing this code twice anyway.
152*91f16700Schasinglulu 	 * Platform specific PSCI code will enable coherency for other
153*91f16700Schasinglulu 	 * clusters.
154*91f16700Schasinglulu 	 */
155*91f16700Schasinglulu 	plat_arm_interconnect_enter_coherency();
156*91f16700Schasinglulu }
157*91f16700Schasinglulu 
158*91f16700Schasinglulu void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
159*91f16700Schasinglulu 			u_register_t arg2, u_register_t arg3)
160*91f16700Schasinglulu {
161*91f16700Schasinglulu 	plat_arm_sp_min_early_platform_setup(arg0, arg1, arg2, arg3);
162*91f16700Schasinglulu }
163*91f16700Schasinglulu 
164*91f16700Schasinglulu /*******************************************************************************
165*91f16700Schasinglulu  * Perform any SP_MIN platform runtime setup prior to SP_MIN exit.
166*91f16700Schasinglulu  * Common to ARM standard platforms.
167*91f16700Schasinglulu  ******************************************************************************/
168*91f16700Schasinglulu void arm_sp_min_plat_runtime_setup(void)
169*91f16700Schasinglulu {
170*91f16700Schasinglulu 	/* Initialize the runtime console */
171*91f16700Schasinglulu 	arm_console_runtime_init();
172*91f16700Schasinglulu 
173*91f16700Schasinglulu #if PLAT_RO_XLAT_TABLES
174*91f16700Schasinglulu 	arm_xlat_make_tables_readonly();
175*91f16700Schasinglulu #endif
176*91f16700Schasinglulu }
177*91f16700Schasinglulu 
178*91f16700Schasinglulu /*******************************************************************************
179*91f16700Schasinglulu  * Perform platform specific setup for SP_MIN
180*91f16700Schasinglulu  ******************************************************************************/
181*91f16700Schasinglulu void sp_min_platform_setup(void)
182*91f16700Schasinglulu {
183*91f16700Schasinglulu 	/* Initialize the GIC driver, cpu and distributor interfaces */
184*91f16700Schasinglulu 	plat_arm_gic_driver_init();
185*91f16700Schasinglulu 	plat_arm_gic_init();
186*91f16700Schasinglulu 
187*91f16700Schasinglulu 	/*
188*91f16700Schasinglulu 	 * Do initial security configuration to allow DRAM/device access
189*91f16700Schasinglulu 	 * (if earlier BL has not already done so).
190*91f16700Schasinglulu 	 */
191*91f16700Schasinglulu #if RESET_TO_SP_MIN && !JUNO_AARCH32_EL3_RUNTIME
192*91f16700Schasinglulu 	plat_arm_security_setup();
193*91f16700Schasinglulu 
194*91f16700Schasinglulu #if defined(PLAT_ARM_MEM_PROT_ADDR)
195*91f16700Schasinglulu 	arm_nor_psci_do_dyn_mem_protect();
196*91f16700Schasinglulu #endif /* PLAT_ARM_MEM_PROT_ADDR */
197*91f16700Schasinglulu 
198*91f16700Schasinglulu #endif
199*91f16700Schasinglulu 
200*91f16700Schasinglulu 	/* Enable and initialize the System level generic timer */
201*91f16700Schasinglulu #ifdef ARM_SYS_CNTCTL_BASE
202*91f16700Schasinglulu 	mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF,
203*91f16700Schasinglulu 			CNTCR_FCREQ(0U) | CNTCR_EN);
204*91f16700Schasinglulu #endif
205*91f16700Schasinglulu #ifdef ARM_SYS_TIMCTL_BASE
206*91f16700Schasinglulu 	/* Allow access to the System counter timer module */
207*91f16700Schasinglulu 	arm_configure_sys_timer();
208*91f16700Schasinglulu #endif
209*91f16700Schasinglulu 	/* Initialize power controller before setting up topology */
210*91f16700Schasinglulu 	plat_arm_pwrc_setup();
211*91f16700Schasinglulu }
212*91f16700Schasinglulu 
213*91f16700Schasinglulu void sp_min_plat_runtime_setup(void)
214*91f16700Schasinglulu {
215*91f16700Schasinglulu 	arm_sp_min_plat_runtime_setup();
216*91f16700Schasinglulu }
217*91f16700Schasinglulu 
218*91f16700Schasinglulu /*******************************************************************************
219*91f16700Schasinglulu  * Perform the very early platform specific architectural setup here. At the
220*91f16700Schasinglulu  * moment this only initializes the MMU
221*91f16700Schasinglulu  ******************************************************************************/
222*91f16700Schasinglulu void arm_sp_min_plat_arch_setup(void)
223*91f16700Schasinglulu {
224*91f16700Schasinglulu 	const mmap_region_t bl_regions[] = {
225*91f16700Schasinglulu 		MAP_BL_SP_MIN_TOTAL,
226*91f16700Schasinglulu 		ARM_MAP_BL_RO,
227*91f16700Schasinglulu #if USE_COHERENT_MEM
228*91f16700Schasinglulu 		ARM_MAP_BL_COHERENT_RAM,
229*91f16700Schasinglulu #endif
230*91f16700Schasinglulu 		{0}
231*91f16700Schasinglulu 	};
232*91f16700Schasinglulu 
233*91f16700Schasinglulu 	setup_page_tables(bl_regions, plat_arm_get_mmap());
234*91f16700Schasinglulu 
235*91f16700Schasinglulu 	enable_mmu_svc_mon(0);
236*91f16700Schasinglulu }
237*91f16700Schasinglulu 
238*91f16700Schasinglulu void sp_min_plat_arch_setup(void)
239*91f16700Schasinglulu {
240*91f16700Schasinglulu 	arm_sp_min_plat_arch_setup();
241*91f16700Schasinglulu }
242