xref: /optee_os/core/arch/arm/plat-stm32mp2/main.c (revision af3fb62410645ac9636d27c3d1db72c0c9fca913)
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_uart.h>
10 #include <initcall.h>
11 #include <kernel/boot.h>
12 #include <kernel/dt.h>
13 #include <kernel/interrupt.h>
14 #include <kernel/misc.h>
15 #include <kernel/spinlock.h>
16 #include <mm/core_memprot.h>
17 #include <platform_config.h>
18 #include <stm32_util.h>
19 #include <trace.h>
20 
21 register_phys_mem_pgdir(MEM_AREA_IO_NSEC, APB1_BASE, APB1_SIZE);
22 
23 register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB1_BASE, APB1_SIZE);
24 register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB2_BASE, APB2_SIZE);
25 register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB3_BASE, APB3_SIZE);
26 register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB4_BASE, APB4_SIZE);
27 register_phys_mem_pgdir(MEM_AREA_IO_SEC, AHB2_BASE, AHB2_SIZE);
28 register_phys_mem_pgdir(MEM_AREA_IO_SEC, AHB3_BASE, AHB3_SIZE);
29 register_phys_mem_pgdir(MEM_AREA_IO_SEC, AHB4_BASE, AHB4_SIZE);
30 register_phys_mem_pgdir(MEM_AREA_IO_SEC, AHB5_BASE, AHB5_SIZE);
31 register_phys_mem_pgdir(MEM_AREA_IO_SEC, SAPB_BASE, SAPB_SIZE);
32 register_phys_mem_pgdir(MEM_AREA_IO_SEC, SAHB_BASE, SAHB_SIZE);
33 
34 register_phys_mem_pgdir(MEM_AREA_IO_SEC, GIC_BASE, GIC_SIZE);
35 
36 #define _ID2STR(id)		(#id)
37 #define ID2STR(id)		_ID2STR(id)
38 
39 static TEE_Result platform_banner(void)
40 {
41 	IMSG("Platform stm32mp2: flavor %s - DT %s", ID2STR(PLATFORM_FLAVOR),
42 	     ID2STR(CFG_EMBED_DTB_SOURCE_FILE));
43 
44 	return TEE_SUCCESS;
45 }
46 
47 service_init(platform_banner);
48 
49 /*
50  * Console
51  *
52  * CFG_STM32_EARLY_CONSOLE_UART specifies the ID of the UART used for
53  * trace console. Value 0 disables the early console.
54  *
55  * We cannot use the generic serial_console support since probing
56  * the console requires the platform clock driver to be already
57  * up and ready which is done only once service_init are completed.
58  */
59 static struct stm32_uart_pdata console_data;
60 
61 void plat_console_init(void)
62 {
63 #ifdef CFG_STM32_UART
64 	/* Early console initialization before MMU setup */
65 	struct uart {
66 		paddr_t pa;
67 		bool secure;
68 	} uarts[] = {
69 		[0] = { .pa = 0 },
70 		[1] = { .pa = USART1_BASE, .secure = true, },
71 		[2] = { .pa = USART2_BASE, .secure = false, },
72 		[3] = { .pa = USART3_BASE, .secure = false, },
73 		[4] = { .pa = UART4_BASE, .secure = false, },
74 		[5] = { .pa = UART5_BASE, .secure = false, },
75 		[6] = { .pa = USART6_BASE, .secure = false, },
76 		[7] = { .pa = UART7_BASE, .secure = false, },
77 		[8] = { .pa = UART8_BASE, .secure = false, },
78 		[9] = { .pa = UART9_BASE, .secure = false, },
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 	console_data.secure = uarts[CFG_STM32_EARLY_CONSOLE_UART].secure;
89 	stm32_uart_init(&console_data, uarts[CFG_STM32_EARLY_CONSOLE_UART].pa);
90 	register_serial_console(&console_data.chip);
91 
92 	IMSG("Early console on UART#%u", CFG_STM32_EARLY_CONSOLE_UART);
93 #endif
94 }
95 
96 #ifdef CFG_STM32_UART
97 static TEE_Result init_console_from_dt(void)
98 {
99 	struct stm32_uart_pdata *pd = NULL;
100 	void *fdt = NULL;
101 	int node = 0;
102 	TEE_Result res = TEE_ERROR_GENERIC;
103 
104 	fdt = get_embedded_dt();
105 	res = get_console_node_from_dt(fdt, &node, NULL, NULL);
106 	if (res == TEE_ERROR_ITEM_NOT_FOUND) {
107 		fdt = get_external_dt();
108 		res = get_console_node_from_dt(fdt, &node, NULL, NULL);
109 		if (res == TEE_ERROR_ITEM_NOT_FOUND)
110 			return TEE_SUCCESS;
111 		if (res != TEE_SUCCESS)
112 			return res;
113 	}
114 
115 	pd = stm32_uart_init_from_dt_node(fdt, node);
116 	if (!pd) {
117 		IMSG("DTB disables console");
118 		register_serial_console(NULL);
119 		return TEE_SUCCESS;
120 	}
121 
122 	/* Replace early console with the new one */
123 	console_flush();
124 	console_data = *pd;
125 	register_serial_console(&console_data.chip);
126 	IMSG("DTB enables console (%ssecure)", pd->secure ? "" : "non-");
127 	free(pd);
128 
129 	return TEE_SUCCESS;
130 }
131 
132 /* Probe console from DT once clock inits (service init level) are completed */
133 service_init_late(init_console_from_dt);
134 #endif /*STM32_UART*/
135 
136 void boot_primary_init_intc(void)
137 {
138 	gic_init(GIC_BASE + GICC_OFFSET, GIC_BASE + GICD_OFFSET);
139 }
140 
141 void boot_secondary_init_intc(void)
142 {
143 	gic_init_per_cpu();
144 }
145