xref: /optee_os/core/arch/arm/plat-stm32mp2/main.c (revision 5395f0367b77ee32ac7ffbf7012af46c24fd3c56)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2023, STMicroelectronics
4  */
5 
6 #include <config.h>
7 #include <console.h>
8 #include <drivers/gic.h>
9 #include <drivers/stm32_rif.h>
10 #include <drivers/stm32_uart.h>
11 #include <initcall.h>
12 #include <kernel/boot.h>
13 #include <kernel/dt.h>
14 #include <kernel/interrupt.h>
15 #include <kernel/misc.h>
16 #include <kernel/spinlock.h>
17 #include <mm/core_memprot.h>
18 #include <platform_config.h>
19 #include <stm32_util.h>
20 #include <trace.h>
21 
22 register_phys_mem_pgdir(MEM_AREA_IO_NSEC, APB1_BASE, APB1_SIZE);
23 
24 register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB1_BASE, APB1_SIZE);
25 register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB2_BASE, APB2_SIZE);
26 register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB3_BASE, APB3_SIZE);
27 register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB4_BASE, APB4_SIZE);
28 register_phys_mem_pgdir(MEM_AREA_IO_SEC, AHB2_BASE, AHB2_SIZE);
29 register_phys_mem_pgdir(MEM_AREA_IO_SEC, AHB3_BASE, AHB3_SIZE);
30 register_phys_mem_pgdir(MEM_AREA_IO_SEC, AHB4_BASE, AHB4_SIZE);
31 register_phys_mem_pgdir(MEM_AREA_IO_SEC, AHB5_BASE, AHB5_SIZE);
32 register_phys_mem_pgdir(MEM_AREA_IO_SEC, SAPB_BASE, SAPB_SIZE);
33 register_phys_mem_pgdir(MEM_AREA_IO_SEC, SAHB_BASE, SAHB_SIZE);
34 
35 register_phys_mem_pgdir(MEM_AREA_IO_SEC, GIC_BASE, GIC_SIZE);
36 
37 #define _ID2STR(id)		(#id)
38 #define ID2STR(id)		_ID2STR(id)
39 
40 static TEE_Result platform_banner(void)
41 {
42 	IMSG("Platform stm32mp2: flavor %s - DT %s", ID2STR(PLATFORM_FLAVOR),
43 	     ID2STR(CFG_EMBED_DTB_SOURCE_FILE));
44 
45 	return TEE_SUCCESS;
46 }
47 
48 service_init(platform_banner);
49 
50 /*
51  * Console
52  *
53  * CFG_STM32_EARLY_CONSOLE_UART specifies the ID of the UART used for
54  * trace console. Value 0 disables the early console.
55  *
56  * We cannot use the generic serial_console support since probing
57  * the console requires the platform clock driver to be already
58  * up and ready which is done only once service_init are completed.
59  */
60 static struct stm32_uart_pdata console_data;
61 
62 void plat_console_init(void)
63 {
64 #ifdef CFG_STM32_UART
65 	/* Early console initialization before MMU setup */
66 	struct uart {
67 		paddr_t pa;
68 	} uarts[] = {
69 		[0] = { .pa = 0 },
70 		[1] = { .pa = USART1_BASE },
71 		[2] = { .pa = USART2_BASE },
72 		[3] = { .pa = USART3_BASE },
73 		[4] = { .pa = UART4_BASE },
74 		[5] = { .pa = UART5_BASE },
75 		[6] = { .pa = USART6_BASE },
76 		[7] = { .pa = UART7_BASE },
77 		[8] = { .pa = UART8_BASE },
78 		[9] = { .pa = UART9_BASE },
79 	};
80 
81 	static_assert(ARRAY_SIZE(uarts) > CFG_STM32_EARLY_CONSOLE_UART);
82 
83 	if (!uarts[CFG_STM32_EARLY_CONSOLE_UART].pa)
84 		return;
85 
86 	/* No clock yet bound to the UART console */
87 	console_data.clock = NULL;
88 	stm32_uart_init(&console_data, uarts[CFG_STM32_EARLY_CONSOLE_UART].pa);
89 	register_serial_console(&console_data.chip);
90 
91 	IMSG("Early console on UART#%u", CFG_STM32_EARLY_CONSOLE_UART);
92 #endif
93 }
94 
95 #ifdef CFG_STM32_UART
96 static TEE_Result init_console_from_dt(void)
97 {
98 	struct stm32_uart_pdata *pd = NULL;
99 	void *fdt = NULL;
100 	int node = 0;
101 	TEE_Result res = TEE_ERROR_GENERIC;
102 
103 	fdt = get_embedded_dt();
104 	res = get_console_node_from_dt(fdt, &node, NULL, NULL);
105 	if (res == TEE_ERROR_ITEM_NOT_FOUND) {
106 		fdt = get_external_dt();
107 		res = get_console_node_from_dt(fdt, &node, NULL, NULL);
108 		if (res == TEE_ERROR_ITEM_NOT_FOUND)
109 			return TEE_SUCCESS;
110 		if (res != TEE_SUCCESS)
111 			return res;
112 	}
113 
114 	pd = stm32_uart_init_from_dt_node(fdt, node);
115 	if (!pd) {
116 		IMSG("DTB disables console");
117 		register_serial_console(NULL);
118 		return TEE_SUCCESS;
119 	}
120 
121 	/* Replace early console with the new one */
122 	console_flush();
123 	console_data = *pd;
124 	register_serial_console(&console_data.chip);
125 	IMSG("DTB enables console");
126 	free(pd);
127 
128 	return TEE_SUCCESS;
129 }
130 
131 /* Probe console from DT once clock inits (service init level) are completed */
132 service_init_late(init_console_from_dt);
133 #endif /*STM32_UART*/
134 
135 vaddr_t stm32_rcc_base(void)
136 {
137 	static struct io_pa_va base = { .pa = RCC_BASE };
138 
139 	return io_pa_or_va_secure(&base, 1);
140 }
141 
142 void boot_primary_init_intc(void)
143 {
144 	gic_init(GIC_BASE + GICC_OFFSET, GIC_BASE + GICD_OFFSET);
145 }
146 
147 void boot_secondary_init_intc(void)
148 {
149 	gic_init_per_cpu();
150 }
151 
152 #ifdef CFG_STM32_RIF
153 void stm32_rif_access_violation_action(void)
154 {
155 }
156 #endif /* CFG_STM32_RIF */
157 
158 bool stm32mp_allow_probe_shared_device(const void *fdt, int node)
159 {
160 	static int uart_console_node = -1;
161 	static bool once;
162 
163 	if (!once) {
164 		get_console_node_from_dt((void *)fdt, &uart_console_node,
165 					 NULL, NULL);
166 		once = true;
167 	}
168 
169 	/* Allow OP-TEE console to be shared with non-secure world */
170 	if (node == uart_console_node)
171 		return true;
172 
173 	return false;
174 }
175