xref: /optee_os/core/arch/arm/plat-stm32mp1/main.c (revision 336e32995d9c419d9fc2a6fd5974f99761285415)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2017-2018, STMicroelectronics
4  * Copyright (c) 2016-2018, Linaro Limited
5  */
6 
7 #include <boot_api.h>
8 #include <console.h>
9 #include <drivers/gic.h>
10 #include <drivers/stm32_uart.h>
11 #include <kernel/generic_boot.h>
12 #include <kernel/dt.h>
13 #include <kernel/misc.h>
14 #include <kernel/panic.h>
15 #include <kernel/pm_stubs.h>
16 #include <kernel/spinlock.h>
17 #include <mm/core_memprot.h>
18 #include <platform_config.h>
19 #include <sm/psci.h>
20 #include <stm32_util.h>
21 #include <tee/entry_std.h>
22 #include <tee/entry_fast.h>
23 #include <trace.h>
24 
25 #ifdef CFG_WITH_NSEC_UARTS
26 register_phys_mem(MEM_AREA_IO_NSEC, USART1_BASE, SMALL_PAGE_SIZE);
27 register_phys_mem(MEM_AREA_IO_NSEC, USART2_BASE, SMALL_PAGE_SIZE);
28 register_phys_mem(MEM_AREA_IO_NSEC, USART3_BASE, SMALL_PAGE_SIZE);
29 register_phys_mem(MEM_AREA_IO_NSEC, UART4_BASE, SMALL_PAGE_SIZE);
30 register_phys_mem(MEM_AREA_IO_NSEC, UART5_BASE, SMALL_PAGE_SIZE);
31 register_phys_mem(MEM_AREA_IO_NSEC, USART6_BASE, SMALL_PAGE_SIZE);
32 register_phys_mem(MEM_AREA_IO_NSEC, UART7_BASE, SMALL_PAGE_SIZE);
33 register_phys_mem(MEM_AREA_IO_NSEC, UART8_BASE, SMALL_PAGE_SIZE);
34 #endif
35 
36 register_phys_mem(MEM_AREA_IO_SEC, GIC_BASE, GIC_SIZE);
37 register_phys_mem(MEM_AREA_IO_SEC, TAMP_BASE, SMALL_PAGE_SIZE);
38 register_phys_mem(MEM_AREA_IO_SEC, USART1_BASE, SMALL_PAGE_SIZE);
39 
40 static void main_fiq(void);
41 
42 static const struct thread_handlers handlers = {
43 	.std_smc = tee_entry_std,
44 	.fast_smc = tee_entry_fast,
45 	.nintr = main_fiq,
46 	.cpu_on = pm_panic,
47 	.cpu_off = pm_panic,
48 	.cpu_suspend = pm_panic,
49 	.cpu_resume = pm_panic,
50 	.system_off = pm_panic,
51 	.system_reset = pm_panic,
52 };
53 
54 const struct thread_handlers *generic_boot_get_handlers(void)
55 {
56 	return &handlers;
57 }
58 
59 #define _ID2STR(id)		(#id)
60 #define ID2STR(id)		_ID2STR(id)
61 
62 static TEE_Result platform_banner(void)
63 {
64 #ifdef CFG_EMBED_DTB
65 	IMSG("Platform stm32mp1: flavor %s - DT %s",
66 		ID2STR(PLATFORM_FLAVOR),
67 		ID2STR(CFG_EMBED_DTB_SOURCE_FILE));
68 #else
69 	IMSG("Platform stm32mp1: flavor %s - no device tree",
70 		ID2STR(PLATFORM_FLAVOR));
71 #endif
72 
73 	return TEE_SUCCESS;
74 }
75 service_init(platform_banner);
76 
77 /*
78  * Console
79  *
80  * CFG_STM32_EARLY_CONSOLE_UART specifies the ID of the UART used for
81  * trace console. Value 0 disables the early console.
82  *
83  * We cannot use the generic serial_console support since probing
84  * the console requires the platform clock driver to be already
85  * up and ready which is done only once service_init are completed.
86  */
87 static struct stm32_uart_pdata console_data;
88 
89 void console_init(void)
90 {
91 	/* Early console initialization before MMU setup */
92 	struct uart {
93 		uintptr_t pa;
94 		bool secure;
95 	} uarts[] = {
96 		[0] = { .pa = 0 },
97 		[1] = { .pa = USART1_BASE, .secure = true, },
98 		[2] = { .pa = USART2_BASE, .secure = false, },
99 		[3] = { .pa = USART3_BASE, .secure = false, },
100 		[4] = { .pa = UART4_BASE, .secure = false, },
101 		[5] = { .pa = UART5_BASE, .secure = false, },
102 		[6] = { .pa = USART6_BASE, .secure = false, },
103 		[7] = { .pa = UART7_BASE, .secure = false, },
104 		[8] = { .pa = UART8_BASE, .secure = false, },
105 	};
106 
107 	COMPILE_TIME_ASSERT(ARRAY_SIZE(uarts) > CFG_STM32_EARLY_CONSOLE_UART);
108 	assert(!cpu_mmu_enabled());
109 
110 	if (!uarts[CFG_STM32_EARLY_CONSOLE_UART].pa)
111 		return;
112 
113 	/* No clock yet bound to the UART console */
114 	console_data.clock = DT_INFO_INVALID_CLOCK;
115 
116 	console_data.secure = uarts[CFG_STM32_EARLY_CONSOLE_UART].secure;
117 	stm32_uart_init(&console_data, uarts[CFG_STM32_EARLY_CONSOLE_UART].pa);
118 
119 	register_serial_console(&console_data.chip);
120 
121 	IMSG("Early console on UART#%u", CFG_STM32_EARLY_CONSOLE_UART);
122 }
123 
124 #ifdef CFG_DT
125 static TEE_Result init_console_from_dt(void)
126 {
127 	struct stm32_uart_pdata *pd;
128 	void *fdt;
129 	int node;
130 
131 	if (get_console_node_from_dt(&fdt, &node, NULL, NULL))
132 		return TEE_SUCCESS;
133 
134 	pd = stm32_uart_init_from_dt_node(fdt, node);
135 	if (!pd) {
136 		IMSG("DTB disables console");
137 		register_serial_console(NULL);
138 		return TEE_SUCCESS;
139 	}
140 
141 	/* Replace early console with the new one */
142 	console_flush();
143 	console_data = *pd;
144 	free(pd);
145 	register_serial_console(&console_data.chip);
146 	IMSG("DTB enables console (%ssecure)", pd->secure ? "" : "non-");
147 
148 	return TEE_SUCCESS;
149 }
150 
151 /* Probe console from DT once clock inits (service init level) are completed */
152 service_init_late(init_console_from_dt);
153 #endif
154 
155 /*
156  * GIC init, used also for primary/secondary boot core wake completion
157  */
158 static struct gic_data gic_data;
159 
160 static void main_fiq(void)
161 {
162 	gic_it_handle(&gic_data);
163 }
164 
165 void main_init_gic(void)
166 {
167 	assert(cpu_mmu_enabled());
168 
169 	gic_init(&gic_data, get_gicc_base(), get_gicd_base());
170 	itr_init(&gic_data.chip);
171 
172 	stm32mp_register_online_cpu();
173 }
174 
175 void main_secondary_init_gic(void)
176 {
177 	gic_cpu_init(&gic_data);
178 
179 	stm32mp_register_online_cpu();
180 }
181 
182 uintptr_t get_gicc_base(void)
183 {
184 	uintptr_t pbase = GIC_BASE + GICC_OFFSET;
185 
186 	if (cpu_mmu_enabled())
187 		return (uintptr_t)phys_to_virt_io(pbase);
188 
189 	return pbase;
190 }
191 
192 uintptr_t get_gicd_base(void)
193 {
194 	uintptr_t pbase = GIC_BASE + GICD_OFFSET;
195 
196 	if (cpu_mmu_enabled())
197 		return (uintptr_t)phys_to_virt_io(pbase);
198 
199 	return pbase;
200 }
201 
202 uint32_t may_spin_lock(unsigned int *lock)
203 {
204 	if (!lock || !cpu_mmu_enabled())
205 		return 0;
206 
207 	return cpu_spin_lock_xsave(lock);
208 }
209 
210 void may_spin_unlock(unsigned int *lock, uint32_t exceptions)
211 {
212 	if (!lock || !cpu_mmu_enabled())
213 		return;
214 
215 	cpu_spin_unlock_xrestore(lock, exceptions);
216 }
217 
218 static uintptr_t stm32_tamp_base(void)
219 {
220 	static struct io_pa_va base = { .pa = TAMP_BASE };
221 
222 	return io_pa_or_va(&base);
223 }
224 
225 static uintptr_t bkpreg_base(void)
226 {
227 	return stm32_tamp_base() + TAMP_BKP_REGISTER_OFF;
228 }
229 
230 uintptr_t stm32mp_bkpreg(unsigned int idx)
231 {
232 	return bkpreg_base() + (idx * sizeof(uint32_t));
233 }
234