xref: /aosp_15_r20/external/arm-trusted-firmware/plat/rpi/common/rpi3_common.c (revision 54fd6939e177f8ff529b10183254802c76df6d08)
1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park  * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
3*54fd6939SJiyong Park  *
4*54fd6939SJiyong Park  * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park  */
6*54fd6939SJiyong Park 
7*54fd6939SJiyong Park #include <assert.h>
8*54fd6939SJiyong Park 
9*54fd6939SJiyong Park #include <platform_def.h>
10*54fd6939SJiyong Park 
11*54fd6939SJiyong Park #include <arch_helpers.h>
12*54fd6939SJiyong Park #include <common/bl_common.h>
13*54fd6939SJiyong Park #include <common/debug.h>
14*54fd6939SJiyong Park #include <bl31/interrupt_mgmt.h>
15*54fd6939SJiyong Park #include <drivers/console.h>
16*54fd6939SJiyong Park #include <drivers/rpi3/gpio/rpi3_gpio.h>
17*54fd6939SJiyong Park #include <drivers/ti/uart/uart_16550.h>
18*54fd6939SJiyong Park #include <drivers/arm/pl011.h>
19*54fd6939SJiyong Park #include <lib/xlat_tables/xlat_tables_v2.h>
20*54fd6939SJiyong Park 
21*54fd6939SJiyong Park #include <rpi_hw.h>
22*54fd6939SJiyong Park #include <rpi_shared.h>
23*54fd6939SJiyong Park 
24*54fd6939SJiyong Park #define MAP_DEVICE0	MAP_REGION_FLAT(DEVICE0_BASE,			\
25*54fd6939SJiyong Park 					DEVICE0_SIZE,			\
26*54fd6939SJiyong Park 					MT_DEVICE | MT_RW | MT_SECURE)
27*54fd6939SJiyong Park 
28*54fd6939SJiyong Park #ifdef SHARED_RAM_BASE
29*54fd6939SJiyong Park #define MAP_SHARED_RAM	MAP_REGION_FLAT(SHARED_RAM_BASE,		\
30*54fd6939SJiyong Park 					SHARED_RAM_SIZE,		\
31*54fd6939SJiyong Park 					MT_DEVICE | MT_RW | MT_SECURE)
32*54fd6939SJiyong Park #endif
33*54fd6939SJiyong Park 
34*54fd6939SJiyong Park #ifdef RPI3_PRELOADED_DTB_BASE
35*54fd6939SJiyong Park #define MAP_NS_DTB	MAP_REGION_FLAT(RPI3_PRELOADED_DTB_BASE, 0x10000, \
36*54fd6939SJiyong Park 					MT_MEMORY | MT_RW | MT_NS)
37*54fd6939SJiyong Park #endif
38*54fd6939SJiyong Park 
39*54fd6939SJiyong Park #define MAP_NS_DRAM0	MAP_REGION_FLAT(NS_DRAM0_BASE, NS_DRAM0_SIZE,	\
40*54fd6939SJiyong Park 					MT_MEMORY | MT_RW | MT_NS)
41*54fd6939SJiyong Park 
42*54fd6939SJiyong Park #define MAP_FIP		MAP_REGION_FLAT(PLAT_RPI3_FIP_BASE,		\
43*54fd6939SJiyong Park 					PLAT_RPI3_FIP_MAX_SIZE,		\
44*54fd6939SJiyong Park 					MT_MEMORY | MT_RO | MT_NS)
45*54fd6939SJiyong Park 
46*54fd6939SJiyong Park #define MAP_BL32_MEM	MAP_REGION_FLAT(BL32_MEM_BASE, BL32_MEM_SIZE,	\
47*54fd6939SJiyong Park 					MT_MEMORY | MT_RW | MT_SECURE)
48*54fd6939SJiyong Park 
49*54fd6939SJiyong Park #ifdef SPD_opteed
50*54fd6939SJiyong Park #define MAP_OPTEE_PAGEABLE	MAP_REGION_FLAT(		\
51*54fd6939SJiyong Park 				RPI3_OPTEE_PAGEABLE_LOAD_BASE,	\
52*54fd6939SJiyong Park 				RPI3_OPTEE_PAGEABLE_LOAD_SIZE,	\
53*54fd6939SJiyong Park 				MT_MEMORY | MT_RW | MT_SECURE)
54*54fd6939SJiyong Park #endif
55*54fd6939SJiyong Park 
56*54fd6939SJiyong Park /*
57*54fd6939SJiyong Park  * Table of regions for various BL stages to map using the MMU.
58*54fd6939SJiyong Park  */
59*54fd6939SJiyong Park #ifdef IMAGE_BL1
60*54fd6939SJiyong Park static const mmap_region_t plat_rpi3_mmap[] = {
61*54fd6939SJiyong Park #ifdef MAP_SHARED_RAM
62*54fd6939SJiyong Park 	MAP_SHARED_RAM,
63*54fd6939SJiyong Park #endif
64*54fd6939SJiyong Park 	MAP_DEVICE0,
65*54fd6939SJiyong Park 	MAP_FIP,
66*54fd6939SJiyong Park #ifdef SPD_opteed
67*54fd6939SJiyong Park 	MAP_OPTEE_PAGEABLE,
68*54fd6939SJiyong Park #endif
69*54fd6939SJiyong Park 	{0}
70*54fd6939SJiyong Park };
71*54fd6939SJiyong Park #endif
72*54fd6939SJiyong Park 
73*54fd6939SJiyong Park #ifdef IMAGE_BL2
74*54fd6939SJiyong Park static const mmap_region_t plat_rpi3_mmap[] = {
75*54fd6939SJiyong Park #ifdef MAP_SHARED_RAM
76*54fd6939SJiyong Park 	MAP_SHARED_RAM,
77*54fd6939SJiyong Park #endif
78*54fd6939SJiyong Park 	MAP_DEVICE0,
79*54fd6939SJiyong Park 	MAP_FIP,
80*54fd6939SJiyong Park 	MAP_NS_DRAM0,
81*54fd6939SJiyong Park #ifdef BL32_BASE
82*54fd6939SJiyong Park 	MAP_BL32_MEM,
83*54fd6939SJiyong Park #endif
84*54fd6939SJiyong Park 	{0}
85*54fd6939SJiyong Park };
86*54fd6939SJiyong Park #endif
87*54fd6939SJiyong Park 
88*54fd6939SJiyong Park #ifdef IMAGE_BL31
89*54fd6939SJiyong Park static const mmap_region_t plat_rpi3_mmap[] = {
90*54fd6939SJiyong Park #ifdef MAP_SHARED_RAM
91*54fd6939SJiyong Park 	MAP_SHARED_RAM,
92*54fd6939SJiyong Park #endif
93*54fd6939SJiyong Park 	MAP_DEVICE0,
94*54fd6939SJiyong Park #ifdef RPI3_PRELOADED_DTB_BASE
95*54fd6939SJiyong Park 	MAP_NS_DTB,
96*54fd6939SJiyong Park #endif
97*54fd6939SJiyong Park #ifdef BL32_BASE
98*54fd6939SJiyong Park 	MAP_BL32_MEM,
99*54fd6939SJiyong Park #endif
100*54fd6939SJiyong Park 	{0}
101*54fd6939SJiyong Park };
102*54fd6939SJiyong Park #endif
103*54fd6939SJiyong Park 
104*54fd6939SJiyong Park /*******************************************************************************
105*54fd6939SJiyong Park  * Function that sets up the console
106*54fd6939SJiyong Park  ******************************************************************************/
107*54fd6939SJiyong Park static console_t rpi3_console;
108*54fd6939SJiyong Park 
109*54fd6939SJiyong Park 
rpi3_use_mini_uart(void)110*54fd6939SJiyong Park static bool rpi3_use_mini_uart(void)
111*54fd6939SJiyong Park {
112*54fd6939SJiyong Park 	return rpi3_gpio_get_select(14) == RPI3_GPIO_FUNC_ALT5;
113*54fd6939SJiyong Park }
114*54fd6939SJiyong Park 
rpi3_console_init(void)115*54fd6939SJiyong Park void rpi3_console_init(void)
116*54fd6939SJiyong Park {
117*54fd6939SJiyong Park 	int console_scope = CONSOLE_FLAG_BOOT;
118*54fd6939SJiyong Park 	int rc;
119*54fd6939SJiyong Park 
120*54fd6939SJiyong Park 	if (RPI3_RUNTIME_UART != -1)
121*54fd6939SJiyong Park 		console_scope |= CONSOLE_FLAG_RUNTIME;
122*54fd6939SJiyong Park 
123*54fd6939SJiyong Park 	rpi3_gpio_init();
124*54fd6939SJiyong Park 
125*54fd6939SJiyong Park 	if (rpi3_use_mini_uart())
126*54fd6939SJiyong Park 		rc = console_16550_register(PLAT_RPI_MINI_UART_BASE,
127*54fd6939SJiyong Park 					    0,
128*54fd6939SJiyong Park 					    PLAT_RPI_UART_BAUDRATE,
129*54fd6939SJiyong Park 					    &rpi3_console);
130*54fd6939SJiyong Park 	else
131*54fd6939SJiyong Park 		rc = console_pl011_register(PLAT_RPI_PL011_UART_BASE,
132*54fd6939SJiyong Park 					    PLAT_RPI_PL011_UART_CLOCK,
133*54fd6939SJiyong Park 					    PLAT_RPI_UART_BAUDRATE,
134*54fd6939SJiyong Park 					    &rpi3_console);
135*54fd6939SJiyong Park 
136*54fd6939SJiyong Park 	if (rc == 0) {
137*54fd6939SJiyong Park 		/*
138*54fd6939SJiyong Park 		 * The crash console doesn't use the multi console API, it uses
139*54fd6939SJiyong Park 		 * the core console functions directly. It is safe to call panic
140*54fd6939SJiyong Park 		 * and let it print debug information.
141*54fd6939SJiyong Park 		 */
142*54fd6939SJiyong Park 		panic();
143*54fd6939SJiyong Park 	}
144*54fd6939SJiyong Park 
145*54fd6939SJiyong Park 	console_set_scope(&rpi3_console, console_scope);
146*54fd6939SJiyong Park }
147*54fd6939SJiyong Park 
148*54fd6939SJiyong Park /*******************************************************************************
149*54fd6939SJiyong Park  * Function that sets up the translation tables.
150*54fd6939SJiyong Park  ******************************************************************************/
rpi3_setup_page_tables(uintptr_t total_base,size_t total_size,uintptr_t code_start,uintptr_t code_limit,uintptr_t rodata_start,uintptr_t rodata_limit,uintptr_t coh_start,uintptr_t coh_limit)151*54fd6939SJiyong Park void rpi3_setup_page_tables(uintptr_t total_base, size_t total_size,
152*54fd6939SJiyong Park 			    uintptr_t code_start, uintptr_t code_limit,
153*54fd6939SJiyong Park 			    uintptr_t rodata_start, uintptr_t rodata_limit
154*54fd6939SJiyong Park #if USE_COHERENT_MEM
155*54fd6939SJiyong Park 			    , uintptr_t coh_start, uintptr_t coh_limit
156*54fd6939SJiyong Park #endif
157*54fd6939SJiyong Park 			    )
158*54fd6939SJiyong Park {
159*54fd6939SJiyong Park 	/*
160*54fd6939SJiyong Park 	 * Map the Trusted SRAM with appropriate memory attributes.
161*54fd6939SJiyong Park 	 * Subsequent mappings will adjust the attributes for specific regions.
162*54fd6939SJiyong Park 	 */
163*54fd6939SJiyong Park 	VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n",
164*54fd6939SJiyong Park 		(void *) total_base, (void *) (total_base + total_size));
165*54fd6939SJiyong Park 	mmap_add_region(total_base, total_base,
166*54fd6939SJiyong Park 			total_size,
167*54fd6939SJiyong Park 			MT_MEMORY | MT_RW | MT_SECURE);
168*54fd6939SJiyong Park 
169*54fd6939SJiyong Park 	/* Re-map the code section */
170*54fd6939SJiyong Park 	VERBOSE("Code region: %p - %p\n",
171*54fd6939SJiyong Park 		(void *) code_start, (void *) code_limit);
172*54fd6939SJiyong Park 	mmap_add_region(code_start, code_start,
173*54fd6939SJiyong Park 			code_limit - code_start,
174*54fd6939SJiyong Park 			MT_CODE | MT_SECURE);
175*54fd6939SJiyong Park 
176*54fd6939SJiyong Park 	/* Re-map the read-only data section */
177*54fd6939SJiyong Park 	VERBOSE("Read-only data region: %p - %p\n",
178*54fd6939SJiyong Park 		(void *) rodata_start, (void *) rodata_limit);
179*54fd6939SJiyong Park 	mmap_add_region(rodata_start, rodata_start,
180*54fd6939SJiyong Park 			rodata_limit - rodata_start,
181*54fd6939SJiyong Park 			MT_RO_DATA | MT_SECURE);
182*54fd6939SJiyong Park 
183*54fd6939SJiyong Park #if USE_COHERENT_MEM
184*54fd6939SJiyong Park 	/* Re-map the coherent memory region */
185*54fd6939SJiyong Park 	VERBOSE("Coherent region: %p - %p\n",
186*54fd6939SJiyong Park 		(void *) coh_start, (void *) coh_limit);
187*54fd6939SJiyong Park 	mmap_add_region(coh_start, coh_start,
188*54fd6939SJiyong Park 			coh_limit - coh_start,
189*54fd6939SJiyong Park 			MT_DEVICE | MT_RW | MT_SECURE);
190*54fd6939SJiyong Park #endif
191*54fd6939SJiyong Park 
192*54fd6939SJiyong Park 	mmap_add(plat_rpi3_mmap);
193*54fd6939SJiyong Park 
194*54fd6939SJiyong Park 	init_xlat_tables();
195*54fd6939SJiyong Park }
196*54fd6939SJiyong Park 
197*54fd6939SJiyong Park /*******************************************************************************
198*54fd6939SJiyong Park  * Gets SPSR for BL32 entry
199*54fd6939SJiyong Park  ******************************************************************************/
rpi3_get_spsr_for_bl32_entry(void)200*54fd6939SJiyong Park uint32_t rpi3_get_spsr_for_bl32_entry(void)
201*54fd6939SJiyong Park {
202*54fd6939SJiyong Park 	/*
203*54fd6939SJiyong Park 	 * The Secure Payload Dispatcher service is responsible for
204*54fd6939SJiyong Park 	 * setting the SPSR prior to entry into the BL32 image.
205*54fd6939SJiyong Park 	 */
206*54fd6939SJiyong Park 	return 0;
207*54fd6939SJiyong Park }
208*54fd6939SJiyong Park 
209*54fd6939SJiyong Park /*******************************************************************************
210*54fd6939SJiyong Park  * Gets SPSR for BL33 entry
211*54fd6939SJiyong Park  ******************************************************************************/
rpi3_get_spsr_for_bl33_entry(void)212*54fd6939SJiyong Park uint32_t rpi3_get_spsr_for_bl33_entry(void)
213*54fd6939SJiyong Park {
214*54fd6939SJiyong Park #if RPI3_BL33_IN_AARCH32
215*54fd6939SJiyong Park 	INFO("BL33 will boot in Non-secure AArch32 Hypervisor mode\n");
216*54fd6939SJiyong Park 	return SPSR_MODE32(MODE32_hyp, SPSR_T_ARM, SPSR_E_LITTLE,
217*54fd6939SJiyong Park 			   DISABLE_ALL_EXCEPTIONS);
218*54fd6939SJiyong Park #else
219*54fd6939SJiyong Park 	return SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
220*54fd6939SJiyong Park #endif
221*54fd6939SJiyong Park }
222*54fd6939SJiyong Park 
plat_get_syscnt_freq2(void)223*54fd6939SJiyong Park unsigned int plat_get_syscnt_freq2(void)
224*54fd6939SJiyong Park {
225*54fd6939SJiyong Park 	return SYS_COUNTER_FREQ_IN_TICKS;
226*54fd6939SJiyong Park }
227*54fd6939SJiyong Park 
plat_ic_get_pending_interrupt_type(void)228*54fd6939SJiyong Park uint32_t plat_ic_get_pending_interrupt_type(void)
229*54fd6939SJiyong Park {
230*54fd6939SJiyong Park 	ERROR("rpi3: Interrupt routed to EL3.\n");
231*54fd6939SJiyong Park 	return INTR_TYPE_INVAL;
232*54fd6939SJiyong Park }
233*54fd6939SJiyong Park 
plat_interrupt_type_to_line(uint32_t type,uint32_t security_state)234*54fd6939SJiyong Park uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state)
235*54fd6939SJiyong Park {
236*54fd6939SJiyong Park 	assert((type == INTR_TYPE_S_EL1) || (type == INTR_TYPE_EL3) ||
237*54fd6939SJiyong Park 	       (type == INTR_TYPE_NS));
238*54fd6939SJiyong Park 
239*54fd6939SJiyong Park 	assert(sec_state_is_valid(security_state));
240*54fd6939SJiyong Park 
241*54fd6939SJiyong Park 	/* Non-secure interrupts are signalled on the IRQ line always. */
242*54fd6939SJiyong Park 	if (type == INTR_TYPE_NS)
243*54fd6939SJiyong Park 		return __builtin_ctz(SCR_IRQ_BIT);
244*54fd6939SJiyong Park 
245*54fd6939SJiyong Park 	/* Secure interrupts are signalled on the FIQ line always. */
246*54fd6939SJiyong Park 	return  __builtin_ctz(SCR_FIQ_BIT);
247*54fd6939SJiyong Park }
248