xref: /rk3399_ARM-atf/plat/rpi/common/rpi4_bl31_setup.c (revision 5318255f12f88c91846b7261ce12254fb8395557)
1*97ef5305SMario Bălănică /*
2*97ef5305SMario Bălănică  * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
3*97ef5305SMario Bălănică  *
4*97ef5305SMario Bălănică  * SPDX-License-Identifier: BSD-3-Clause
5*97ef5305SMario Bălănică  */
6*97ef5305SMario Bălănică 
7*97ef5305SMario Bălănică #include <assert.h>
8*97ef5305SMario Bălănică #include <inttypes.h>
9*97ef5305SMario Bălănică #include <stdint.h>
10*97ef5305SMario Bălănică 
11*97ef5305SMario Bălănică #include <arch_helpers.h>
12*97ef5305SMario Bălănică #include <common/bl_common.h>
13*97ef5305SMario Bălănică #include <drivers/arm/gicv2.h>
14*97ef5305SMario Bălănică #include <lib/mmio.h>
15*97ef5305SMario Bălănică #include <lib/xlat_tables/xlat_mmu_helpers.h>
16*97ef5305SMario Bălănică #include <lib/xlat_tables/xlat_tables_defs.h>
17*97ef5305SMario Bălănică #include <lib/xlat_tables/xlat_tables_v2.h>
18*97ef5305SMario Bălănică #include <plat/common/platform.h>
19*97ef5305SMario Bălănică #include <platform_def.h>
20*97ef5305SMario Bălănică 
21*97ef5305SMario Bălănică #include <rpi_shared.h>
22*97ef5305SMario Bălănică 
23*97ef5305SMario Bălănică /*
24*97ef5305SMario Bălănică  * Fields at the beginning of armstub8.bin.
25*97ef5305SMario Bălănică  * While building the BL31 image, we put the stub magic into the binary.
26*97ef5305SMario Bălănică  * The GPU firmware detects this at boot time, clears that field as a
27*97ef5305SMario Bălănică  * confirmation and puts the kernel and DT address in the following words.
28*97ef5305SMario Bălănică  */
29*97ef5305SMario Bălănică extern uint32_t stub_magic;
30*97ef5305SMario Bălănică extern uint32_t dtb_ptr32;
31*97ef5305SMario Bălănică extern uint32_t kernel_entry32;
32*97ef5305SMario Bălănică 
33*97ef5305SMario Bălănică static const gicv2_driver_data_t rpi4_gic_data = {
34*97ef5305SMario Bălănică 	.gicd_base = RPI4_GIC_GICD_BASE,
35*97ef5305SMario Bălănică 	.gicc_base = RPI4_GIC_GICC_BASE,
36*97ef5305SMario Bălănică };
37*97ef5305SMario Bălănică 
38*97ef5305SMario Bălănică /*
39*97ef5305SMario Bălănică  * To be filled by the code below. At the moment BL32 is not supported.
40*97ef5305SMario Bălănică  * In the future these might be passed down from BL2.
41*97ef5305SMario Bălănică  */
42*97ef5305SMario Bălănică static entry_point_info_t bl32_image_ep_info;
43*97ef5305SMario Bălănică static entry_point_info_t bl33_image_ep_info;
44*97ef5305SMario Bălănică 
45*97ef5305SMario Bălănică /*******************************************************************************
46*97ef5305SMario Bălănică  * Return a pointer to the 'entry_point_info' structure of the next image for
47*97ef5305SMario Bălănică  * the security state specified. BL33 corresponds to the non-secure image type
48*97ef5305SMario Bălănică  * while BL32 corresponds to the secure image type. A NULL pointer is returned
49*97ef5305SMario Bălănică  * if the image does not exist.
50*97ef5305SMario Bălănică  ******************************************************************************/
bl31_plat_get_next_image_ep_info(uint32_t type)51*97ef5305SMario Bălănică entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
52*97ef5305SMario Bălănică {
53*97ef5305SMario Bălănică 	entry_point_info_t *next_image_info;
54*97ef5305SMario Bălănică 
55*97ef5305SMario Bălănică 	assert(sec_state_is_valid(type) != 0);
56*97ef5305SMario Bălănică 
57*97ef5305SMario Bălănică 	next_image_info = (type == NON_SECURE)
58*97ef5305SMario Bălănică 			? &bl33_image_ep_info : &bl32_image_ep_info;
59*97ef5305SMario Bălănică 
60*97ef5305SMario Bălănică 	/* None of the images can have 0x0 as the entrypoint. */
61*97ef5305SMario Bălănică 	if (next_image_info->pc) {
62*97ef5305SMario Bălănică 		return next_image_info;
63*97ef5305SMario Bălănică 	} else {
64*97ef5305SMario Bălănică 		return NULL;
65*97ef5305SMario Bălănică 	}
66*97ef5305SMario Bălănică }
67*97ef5305SMario Bălănică 
plat_get_ns_image_entrypoint(void)68*97ef5305SMario Bălănică uintptr_t plat_get_ns_image_entrypoint(void)
69*97ef5305SMario Bălănică {
70*97ef5305SMario Bălănică #ifdef PRELOADED_BL33_BASE
71*97ef5305SMario Bălănică 	return PRELOADED_BL33_BASE;
72*97ef5305SMario Bălănică #else
73*97ef5305SMario Bălănică 	/* Cleared by the GPU if kernel address is valid. */
74*97ef5305SMario Bălănică 	if (stub_magic == 0)
75*97ef5305SMario Bălănică 		return kernel_entry32;
76*97ef5305SMario Bălănică 
77*97ef5305SMario Bălănică 	WARN("Stub magic failure, using default kernel address 0x80000\n");
78*97ef5305SMario Bălănică 	return 0x80000;
79*97ef5305SMario Bălănică #endif
80*97ef5305SMario Bălănică }
81*97ef5305SMario Bălănică 
rpi4_get_dtb_address(void)82*97ef5305SMario Bălănică uintptr_t rpi4_get_dtb_address(void)
83*97ef5305SMario Bălănică {
84*97ef5305SMario Bălănică #ifdef RPI3_PRELOADED_DTB_BASE
85*97ef5305SMario Bălănică 	return RPI3_PRELOADED_DTB_BASE;
86*97ef5305SMario Bălănică #else
87*97ef5305SMario Bălănică 	/* Cleared by the GPU if DTB address is valid. */
88*97ef5305SMario Bălănică 	if (stub_magic == 0)
89*97ef5305SMario Bălănică 		return dtb_ptr32;
90*97ef5305SMario Bălănică 
91*97ef5305SMario Bălănică 	WARN("Stub magic failure, DTB address unknown\n");
92*97ef5305SMario Bălănică 	return 0;
93*97ef5305SMario Bălănică #endif
94*97ef5305SMario Bălănică }
95*97ef5305SMario Bălănică 
ldelay(register_t delay)96*97ef5305SMario Bălănică static void ldelay(register_t delay)
97*97ef5305SMario Bălănică {
98*97ef5305SMario Bălănică 	__asm__ volatile (
99*97ef5305SMario Bălănică 		"1:\tcbz %0, 2f\n\t"
100*97ef5305SMario Bălănică 		"sub %0, %0, #1\n\t"
101*97ef5305SMario Bălănică 		"b 1b\n"
102*97ef5305SMario Bălănică 		"2:"
103*97ef5305SMario Bălănică 		: "=&r" (delay) : "0" (delay)
104*97ef5305SMario Bălănică 	);
105*97ef5305SMario Bălănică }
106*97ef5305SMario Bălănică 
107*97ef5305SMario Bălănică /*******************************************************************************
108*97ef5305SMario Bălănică  * Perform any BL31 early platform setup. Here is an opportunity to copy
109*97ef5305SMario Bălănică  * parameters passed by the calling EL (S-EL1 in BL2 & EL3 in BL1) before
110*97ef5305SMario Bălănică  * they are lost (potentially). This needs to be done before the MMU is
111*97ef5305SMario Bălănică  * initialized so that the memory layout can be used while creating page
112*97ef5305SMario Bălănică  * tables. BL2 has flushed this information to memory, so we are guaranteed
113*97ef5305SMario Bălănică  * to pick up good data.
114*97ef5305SMario Bălănică  ******************************************************************************/
bl31_early_platform_setup2(u_register_t arg0,u_register_t arg1,u_register_t arg2,u_register_t arg3)115*97ef5305SMario Bălănică void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
116*97ef5305SMario Bălănică 				u_register_t arg2, u_register_t arg3)
117*97ef5305SMario Bălănică 
118*97ef5305SMario Bălănică {
119*97ef5305SMario Bălănică 	/*
120*97ef5305SMario Bălănică 	 * LOCAL_CONTROL:
121*97ef5305SMario Bălănică 	 * Bit 9 clear: Increment by 1 (vs. 2).
122*97ef5305SMario Bălănică 	 * Bit 8 clear: Timer source is 19.2MHz crystal (vs. APB).
123*97ef5305SMario Bălănică 	 */
124*97ef5305SMario Bălănică 	mmio_write_32(RPI4_LOCAL_CONTROL_BASE_ADDRESS, 0);
125*97ef5305SMario Bălănică 
126*97ef5305SMario Bălănică 	/* LOCAL_PRESCALER; divide-by (0x80000000 / register_val) == 1 */
127*97ef5305SMario Bălănică 	mmio_write_32(RPI4_LOCAL_CONTROL_PRESCALER, 0x80000000);
128*97ef5305SMario Bălănică 
129*97ef5305SMario Bălănică 	/* Early GPU firmware revisions need a little break here. */
130*97ef5305SMario Bălănică 	ldelay(100000);
131*97ef5305SMario Bălănică 
132*97ef5305SMario Bălănică 	/* Initialize the console to provide early debug support. */
133*97ef5305SMario Bălănică 	rpi3_console_init();
134*97ef5305SMario Bălănică 
135*97ef5305SMario Bălănică 	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
136*97ef5305SMario Bălănică 	bl33_image_ep_info.spsr = rpi3_get_spsr_for_bl33_entry();
137*97ef5305SMario Bălănică 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
138*97ef5305SMario Bălănică 
139*97ef5305SMario Bălănică #if RPI3_DIRECT_LINUX_BOOT
140*97ef5305SMario Bălănică # if RPI3_BL33_IN_AARCH32
141*97ef5305SMario Bălănică 	/*
142*97ef5305SMario Bălănică 	 * According to the file ``Documentation/arm/Booting`` of the Linux
143*97ef5305SMario Bălănică 	 * kernel tree, Linux expects:
144*97ef5305SMario Bălănică 	 * r0 = 0
145*97ef5305SMario Bălănică 	 * r1 = machine type number, optional in DT-only platforms (~0 if so)
146*97ef5305SMario Bălănică 	 * r2 = Physical address of the device tree blob
147*97ef5305SMario Bălănică 	 */
148*97ef5305SMario Bălănică 	VERBOSE("rpi: Preparing to boot 32-bit Linux kernel\n");
149*97ef5305SMario Bălănică 	bl33_image_ep_info.args.arg0 = 0U;
150*97ef5305SMario Bălănică 	bl33_image_ep_info.args.arg1 = ~0U;
151*97ef5305SMario Bălănică 	bl33_image_ep_info.args.arg2 = rpi4_get_dtb_address();
152*97ef5305SMario Bălănică # else
153*97ef5305SMario Bălănică 	/*
154*97ef5305SMario Bălănică 	 * According to the file ``Documentation/arm64/booting.txt`` of the
155*97ef5305SMario Bălănică 	 * Linux kernel tree, Linux expects the physical address of the device
156*97ef5305SMario Bălănică 	 * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
157*97ef5305SMario Bălănică 	 * must be 0.
158*97ef5305SMario Bălănică 	 */
159*97ef5305SMario Bălănică 	VERBOSE("rpi: Preparing to boot 64-bit Linux kernel\n");
160*97ef5305SMario Bălănică 	bl33_image_ep_info.args.arg0 = rpi4_get_dtb_address();
161*97ef5305SMario Bălănică 	bl33_image_ep_info.args.arg1 = 0ULL;
162*97ef5305SMario Bălănică 	bl33_image_ep_info.args.arg2 = 0ULL;
163*97ef5305SMario Bălănică 	bl33_image_ep_info.args.arg3 = 0ULL;
164*97ef5305SMario Bălănică # endif /* RPI3_BL33_IN_AARCH32 */
165*97ef5305SMario Bălănică #endif /* RPI3_DIRECT_LINUX_BOOT */
166*97ef5305SMario Bălănică }
167*97ef5305SMario Bălănică 
bl31_plat_arch_setup(void)168*97ef5305SMario Bălănică void bl31_plat_arch_setup(void)
169*97ef5305SMario Bălănică {
170*97ef5305SMario Bălănică 	/*
171*97ef5305SMario Bălănică 	 * Is the dtb_ptr32 pointer valid? If yes, map the DTB region.
172*97ef5305SMario Bălănică 	 * We map the 2MB region the DTB start address lives in, plus
173*97ef5305SMario Bălănică 	 * the next 2MB, to have enough room for expansion.
174*97ef5305SMario Bălănică 	 */
175*97ef5305SMario Bălănică 	if (stub_magic == 0) {
176*97ef5305SMario Bălănică 		unsigned long long dtb_region = dtb_ptr32;
177*97ef5305SMario Bălănică 
178*97ef5305SMario Bălănică 		dtb_region &= ~0x1fffff;	/* Align to 2 MB. */
179*97ef5305SMario Bălănică 		mmap_add_region(dtb_region, dtb_region, 4U << 20,
180*97ef5305SMario Bălănică 				MT_MEMORY | MT_RW | MT_NS);
181*97ef5305SMario Bălănică 	}
182*97ef5305SMario Bălănică 	/*
183*97ef5305SMario Bălănică 	 * Add the first page of memory, which holds the stub magic,
184*97ef5305SMario Bălănică 	 * the kernel and the DT address.
185*97ef5305SMario Bălănică 	 * This also holds the secondary CPU's entrypoints and mailboxes.
186*97ef5305SMario Bălănică 	 */
187*97ef5305SMario Bălănică 	mmap_add_region(0, 0, 4096, MT_NON_CACHEABLE | MT_RW | MT_SECURE);
188*97ef5305SMario Bălănică 
189*97ef5305SMario Bălănică 	rpi3_setup_page_tables(BL31_BASE, BL31_END - BL31_BASE,
190*97ef5305SMario Bălănică 			       BL_CODE_BASE, BL_CODE_END,
191*97ef5305SMario Bălănică 			       BL_RO_DATA_BASE, BL_RO_DATA_END
192*97ef5305SMario Bălănică #if USE_COHERENT_MEM
193*97ef5305SMario Bălănică 			       , BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END
194*97ef5305SMario Bălănică #endif
195*97ef5305SMario Bălănică 			      );
196*97ef5305SMario Bălănică 
197*97ef5305SMario Bălănică 	enable_mmu_el3(0);
198*97ef5305SMario Bălănică }
199*97ef5305SMario Bălănică 
bl31_platform_setup(void)200*97ef5305SMario Bălănică void bl31_platform_setup(void)
201*97ef5305SMario Bălănică {
202*97ef5305SMario Bălănică 	/* Configure the interrupt controller */
203*97ef5305SMario Bălănică 	gicv2_driver_init(&rpi4_gic_data);
204*97ef5305SMario Bălănică 	gicv2_distif_init();
205*97ef5305SMario Bălănică 	gicv2_pcpu_distif_init();
206*97ef5305SMario Bălănică 	gicv2_cpuif_enable();
207*97ef5305SMario Bălănică 
208*97ef5305SMario Bălănică 	plat_rpi_bl31_custom_setup();
209*97ef5305SMario Bălănică }
210