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