1a30d4efbSEtienne Carriere // SPDX-License-Identifier: BSD-2-Clause
2a30d4efbSEtienne Carriere /*
3c501c3e1SLionel Debieve * Copyright (c) 2017-2025, STMicroelectronics
4a30d4efbSEtienne Carriere * Copyright (c) 2016-2018, Linaro Limited
5a30d4efbSEtienne Carriere */
6a30d4efbSEtienne Carriere
7a30d4efbSEtienne Carriere #include <boot_api.h>
8ee4d1590SEtienne Carriere #include <config.h>
9a30d4efbSEtienne Carriere #include <console.h>
10132151fbSEtienne Carriere #include <drivers/firewall_device.h>
11a30d4efbSEtienne Carriere #include <drivers/gic.h>
12*e29eb9ddSGatien Chevallier #include <drivers/rstctrl.h>
136d6aeba1SEtienne Carriere #include <drivers/pinctrl.h>
14db3e6bf9SEtienne Carriere #include <drivers/stm32_bsec.h>
152a5482f7SEtienne Carriere #include <drivers/stm32_gpio.h>
16e9f46c74SJens Wiklander #include <drivers/stm32_uart.h>
1737010ab7SGatien Chevallier #include <drivers/stm32mp_dt_bindings.h>
18db3e6bf9SEtienne Carriere #ifdef CFG_STM32MP15
19db3e6bf9SEtienne Carriere #include <drivers/stm32mp1_rcc.h>
20db3e6bf9SEtienne Carriere #endif
21986fccc8SEtienne Carriere #include <io.h>
2265401337SJens Wiklander #include <kernel/boot.h>
23651d7537SJens Wiklander #include <kernel/dt.h>
24132151fbSEtienne Carriere #include <kernel/dt_driver.h>
25a30d4efbSEtienne Carriere #include <kernel/misc.h>
26a30d4efbSEtienne Carriere #include <kernel/panic.h>
2700707cccSEtienne Carriere #include <kernel/spinlock.h>
28885b1c02SEtienne Carriere #include <kernel/tee_misc.h>
29f2e5b5e0SGatien Chevallier #include <libfdt.h>
30a30d4efbSEtienne Carriere #include <mm/core_memprot.h>
31a30d4efbSEtienne Carriere #include <platform_config.h>
32a30d4efbSEtienne Carriere #include <sm/psci.h>
33eb07694aSEtienne Carriere #include <stm32_util.h>
34986fccc8SEtienne Carriere #include <string.h>
35a78ef925SEtienne Carriere #include <trace.h>
36a30d4efbSEtienne Carriere
37acab9a17SEtienne Carriere register_phys_mem_pgdir(MEM_AREA_IO_NSEC, APB1_BASE, APB1_SIZE);
38acab9a17SEtienne Carriere register_phys_mem_pgdir(MEM_AREA_IO_NSEC, APB2_BASE, APB2_SIZE);
39acab9a17SEtienne Carriere register_phys_mem_pgdir(MEM_AREA_IO_NSEC, APB3_BASE, APB3_SIZE);
40acab9a17SEtienne Carriere register_phys_mem_pgdir(MEM_AREA_IO_NSEC, APB4_BASE, APB4_SIZE);
41acab9a17SEtienne Carriere register_phys_mem_pgdir(MEM_AREA_IO_NSEC, APB5_BASE, APB5_SIZE);
42acab9a17SEtienne Carriere register_phys_mem_pgdir(MEM_AREA_IO_NSEC, AHB4_BASE, AHB4_SIZE);
43acab9a17SEtienne Carriere register_phys_mem_pgdir(MEM_AREA_IO_NSEC, AHB5_BASE, AHB5_SIZE);
44a30d4efbSEtienne Carriere
45a3009556SMichael Scott register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB1_BASE, APB1_SIZE);
469650ed7cSEtienne Carriere register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB3_BASE, APB3_SIZE);
479650ed7cSEtienne Carriere register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB4_BASE, APB4_SIZE);
48acab9a17SEtienne Carriere register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB5_BASE, APB5_SIZE);
49dedaf8caSGatien Chevallier #ifdef CFG_STM32MP13
50dedaf8caSGatien Chevallier register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB6_BASE, APB6_SIZE);
51dedaf8caSGatien Chevallier #endif
52acab9a17SEtienne Carriere register_phys_mem_pgdir(MEM_AREA_IO_SEC, AHB4_BASE, AHB4_SIZE);
53acab9a17SEtienne Carriere register_phys_mem_pgdir(MEM_AREA_IO_SEC, AHB5_BASE, AHB5_SIZE);
54a5e82dc7SJerome Forissier register_phys_mem_pgdir(MEM_AREA_IO_SEC, GIC_BASE, GIC_SIZE);
55a30d4efbSEtienne Carriere
568db78a81SEtienne Carriere register_ddr(DDR_BASE, CFG_DRAM_SIZE);
572b7b5d91SEtienne Carriere
58a78ef925SEtienne Carriere #define _ID2STR(id) (#id)
59a78ef925SEtienne Carriere #define ID2STR(id) _ID2STR(id)
60a78ef925SEtienne Carriere
platform_banner(void)61a78ef925SEtienne Carriere static TEE_Result platform_banner(void)
62a78ef925SEtienne Carriere {
63a78ef925SEtienne Carriere IMSG("Platform stm32mp1: flavor %s - DT %s",
64a78ef925SEtienne Carriere ID2STR(PLATFORM_FLAVOR),
65a78ef925SEtienne Carriere ID2STR(CFG_EMBED_DTB_SOURCE_FILE));
66a78ef925SEtienne Carriere
67a78ef925SEtienne Carriere return TEE_SUCCESS;
68a78ef925SEtienne Carriere }
69a78ef925SEtienne Carriere service_init(platform_banner);
70a78ef925SEtienne Carriere
71ce2d526aSEtienne Carriere /*
72ce2d526aSEtienne Carriere * Console
73ce2d526aSEtienne Carriere *
74ce2d526aSEtienne Carriere * CFG_STM32_EARLY_CONSOLE_UART specifies the ID of the UART used for
75ce2d526aSEtienne Carriere * trace console. Value 0 disables the early console.
767d887fc5SEtienne Carriere *
777d887fc5SEtienne Carriere * We cannot use the generic serial_console support since probing
787d887fc5SEtienne Carriere * the console requires the platform clock driver to be already
797d887fc5SEtienne Carriere * up and ready which is done only once service_init are completed.
80ce2d526aSEtienne Carriere */
81ce2d526aSEtienne Carriere static struct stm32_uart_pdata console_data;
82ce2d526aSEtienne Carriere
plat_console_init(void)8355ab8f06SAlvin Chang void plat_console_init(void)
84a30d4efbSEtienne Carriere {
85ce2d526aSEtienne Carriere /* Early console initialization before MMU setup */
86ce2d526aSEtienne Carriere struct uart {
879b39d0faSEtienne Carriere paddr_t pa;
88ce2d526aSEtienne Carriere } uarts[] = {
89ce2d526aSEtienne Carriere [0] = { .pa = 0 },
907a1f6540SEtienne Carriere [1] = { .pa = USART1_BASE },
917a1f6540SEtienne Carriere [2] = { .pa = USART2_BASE },
927a1f6540SEtienne Carriere [3] = { .pa = USART3_BASE },
937a1f6540SEtienne Carriere [4] = { .pa = UART4_BASE },
947a1f6540SEtienne Carriere [5] = { .pa = UART5_BASE },
957a1f6540SEtienne Carriere [6] = { .pa = USART6_BASE },
967a1f6540SEtienne Carriere [7] = { .pa = UART7_BASE },
977a1f6540SEtienne Carriere [8] = { .pa = UART8_BASE },
98ce2d526aSEtienne Carriere };
99ce2d526aSEtienne Carriere
100ce2d526aSEtienne Carriere COMPILE_TIME_ASSERT(ARRAY_SIZE(uarts) > CFG_STM32_EARLY_CONSOLE_UART);
101ce2d526aSEtienne Carriere
102ce2d526aSEtienne Carriere if (!uarts[CFG_STM32_EARLY_CONSOLE_UART].pa)
103ce2d526aSEtienne Carriere return;
104ce2d526aSEtienne Carriere
1057d887fc5SEtienne Carriere /* No clock yet bound to the UART console */
1065e369f14SEtienne Carriere console_data.clock = NULL;
1077d887fc5SEtienne Carriere
108ce2d526aSEtienne Carriere stm32_uart_init(&console_data, uarts[CFG_STM32_EARLY_CONSOLE_UART].pa);
109ce2d526aSEtienne Carriere
110a30d4efbSEtienne Carriere register_serial_console(&console_data.chip);
111ce2d526aSEtienne Carriere
112ce2d526aSEtienne Carriere IMSG("Early console on UART#%u", CFG_STM32_EARLY_CONSOLE_UART);
113a30d4efbSEtienne Carriere }
114a30d4efbSEtienne Carriere
init_console_from_dt(void)1157d887fc5SEtienne Carriere static TEE_Result init_console_from_dt(void)
1167d887fc5SEtienne Carriere {
11710e1dc35SEtienne Carriere struct stm32_uart_pdata *pd = NULL;
11810e1dc35SEtienne Carriere void *fdt = NULL;
11910e1dc35SEtienne Carriere int node = 0;
120286c31d4SEtienne Carriere TEE_Result res = TEE_ERROR_GENERIC;
1217d887fc5SEtienne Carriere
122286c31d4SEtienne Carriere fdt = get_embedded_dt();
123286c31d4SEtienne Carriere res = get_console_node_from_dt(fdt, &node, NULL, NULL);
124286c31d4SEtienne Carriere if (res == TEE_ERROR_ITEM_NOT_FOUND) {
125286c31d4SEtienne Carriere fdt = get_external_dt();
126286c31d4SEtienne Carriere res = get_console_node_from_dt(fdt, &node, NULL, NULL);
127286c31d4SEtienne Carriere if (res == TEE_ERROR_ITEM_NOT_FOUND)
1287d887fc5SEtienne Carriere return TEE_SUCCESS;
129286c31d4SEtienne Carriere if (res != TEE_SUCCESS)
130286c31d4SEtienne Carriere return res;
131286c31d4SEtienne Carriere }
1327d887fc5SEtienne Carriere
1337d887fc5SEtienne Carriere pd = stm32_uart_init_from_dt_node(fdt, node);
1347d887fc5SEtienne Carriere if (!pd) {
1357d887fc5SEtienne Carriere IMSG("DTB disables console");
1367d887fc5SEtienne Carriere register_serial_console(NULL);
1377d887fc5SEtienne Carriere return TEE_SUCCESS;
1387d887fc5SEtienne Carriere }
1397d887fc5SEtienne Carriere
1407d887fc5SEtienne Carriere /* Replace early console with the new one */
1417d887fc5SEtienne Carriere console_flush();
1427d887fc5SEtienne Carriere console_data = *pd;
1437d887fc5SEtienne Carriere register_serial_console(&console_data.chip);
1447a1f6540SEtienne Carriere IMSG("DTB enables console");
145a54b2f16SJose Quaresma free(pd);
1467d887fc5SEtienne Carriere
1477d887fc5SEtienne Carriere return TEE_SUCCESS;
1487d887fc5SEtienne Carriere }
1497d887fc5SEtienne Carriere
1507d887fc5SEtienne Carriere /* Probe console from DT once clock inits (service init level) are completed */
1517d887fc5SEtienne Carriere service_init_late(init_console_from_dt);
1527d887fc5SEtienne Carriere
stm32_dbgmcu_base(void)153d8aa45ccSPascal Paillet static uintptr_t stm32_dbgmcu_base(void)
154d8aa45ccSPascal Paillet {
155d8aa45ccSPascal Paillet static void *va;
156d8aa45ccSPascal Paillet
157d8aa45ccSPascal Paillet if (!cpu_mmu_enabled())
158d8aa45ccSPascal Paillet return DBGMCU_BASE;
159d8aa45ccSPascal Paillet
160d8aa45ccSPascal Paillet if (!va)
161d8aa45ccSPascal Paillet va = phys_to_virt(DBGMCU_BASE, MEM_AREA_IO_SEC, 1);
162d8aa45ccSPascal Paillet
163d8aa45ccSPascal Paillet return (uintptr_t)va;
164d8aa45ccSPascal Paillet }
165d8aa45ccSPascal Paillet
166d8aa45ccSPascal Paillet /* SoC device ID util, returns default ID if can't access DBGMCU */
stm32mp1_dbgmcu_get_chip_dev_id(uint32_t * chip_dev_id)167d8aa45ccSPascal Paillet TEE_Result stm32mp1_dbgmcu_get_chip_dev_id(uint32_t *chip_dev_id)
168d8aa45ccSPascal Paillet {
169d8aa45ccSPascal Paillet uint32_t id = STM32MP1_CHIP_ID;
170d8aa45ccSPascal Paillet
171d8aa45ccSPascal Paillet assert(chip_dev_id);
172d8aa45ccSPascal Paillet
173d8aa45ccSPascal Paillet if (stm32_bsec_read_debug_conf() & BSEC_DBGSWGEN)
174d8aa45ccSPascal Paillet id = io_read32(stm32_dbgmcu_base() + DBGMCU_IDC) &
175d8aa45ccSPascal Paillet DBGMCU_IDC_DEV_ID_MASK;
176d8aa45ccSPascal Paillet
177d8aa45ccSPascal Paillet *chip_dev_id = id;
178d8aa45ccSPascal Paillet
179d8aa45ccSPascal Paillet return TEE_SUCCESS;
180d8aa45ccSPascal Paillet }
181d8aa45ccSPascal Paillet
182eb07694aSEtienne Carriere /*
183eb07694aSEtienne Carriere * GIC init, used also for primary/secondary boot core wake completion
184eb07694aSEtienne Carriere */
boot_primary_init_intc(void)185df913c6dSAlvin Chang void boot_primary_init_intc(void)
186a30d4efbSEtienne Carriere {
18767e55c51SEtienne Carriere gic_init(GIC_BASE + GICC_OFFSET, GIC_BASE + GICD_OFFSET);
18800707cccSEtienne Carriere
18900707cccSEtienne Carriere stm32mp_register_online_cpu();
190a30d4efbSEtienne Carriere }
191a30d4efbSEtienne Carriere
boot_secondary_init_intc(void)1928aae4669SAlvin Chang void boot_secondary_init_intc(void)
193a30d4efbSEtienne Carriere {
194f388e2b7SJens Wiklander gic_init_per_cpu();
19500707cccSEtienne Carriere
19600707cccSEtienne Carriere stm32mp_register_online_cpu();
197a30d4efbSEtienne Carriere }
198eb07694aSEtienne Carriere
199885b1c02SEtienne Carriere #ifdef CFG_STM32MP15
200885b1c02SEtienne Carriere /*
201885b1c02SEtienne Carriere * This concerns OP-TEE pager for STM32MP1 to use secure internal
202885b1c02SEtienne Carriere * RAMs to execute. TZSRAM refers the TZSRAM_BASE/TZSRAM_SIZE
203885b1c02SEtienne Carriere * used in boot.c to locate secure unpaged memory.
204885b1c02SEtienne Carriere *
205885b1c02SEtienne Carriere * STM32MP15 variants embed 640kB of contiguous securable SRAMs
206885b1c02SEtienne Carriere *
207885b1c02SEtienne Carriere * +--------------+ <-- SYSRAM_BASE
208885b1c02SEtienne Carriere * | | lower part can be assigned to secure world
209885b1c02SEtienne Carriere * | SYSRAM 256kB | 4kB granule boundary
210885b1c02SEtienne Carriere * | | upper part can be assigned to secure world
211885b1c02SEtienne Carriere * +--------------+ <-- SRAM1_BASE (= SYSRAM_BASE + SYSRAM_SIZE)
212885b1c02SEtienne Carriere | | full range assigned to non-secure world or
213885b1c02SEtienne Carriere * | SRAM1 128kB | to secure world, or to- Cortex-M4 exclusive access
214885b1c02SEtienne Carriere * +--------------+ <-- SRAM2_BASE (= SRAM1_BASE + SRAM1_SIZE)
215885b1c02SEtienne Carriere | | full range assigned to non-secure world or
216885b1c02SEtienne Carriere * | SRAM2 128kB | to secure world, or to- Cortex-M4 exclusive access
217885b1c02SEtienne Carriere * +--------------+ <-- SRAM3_BASE (= SRAM2_BASE + SRAM2_SIZE)
218885b1c02SEtienne Carriere | | full range assigned to non-secure world or
219885b1c02SEtienne Carriere * | SRAM3 64kB | to secure world, or to- Cortex-M4 exclusive access
220885b1c02SEtienne Carriere * +--------------+ <-- SRAM4_BASE (= SRAM3_BASE + SRAM3_SIZE)
221885b1c02SEtienne Carriere | | full range assigned to non-secure world or
222885b1c02SEtienne Carriere * | SRAM4 64kB | to secure world, or to- Cortex-M4 exclusive access
223885b1c02SEtienne Carriere * +--------------+ <-- SRAM4_BASE + SRAM4_SIZE
224885b1c02SEtienne Carriere *
225885b1c02SEtienne Carriere * If SRAMx memories are not used for the companion Cortex-M4
226885b1c02SEtienne Carriere * processor, OP-TEE can use this memory.
227885b1c02SEtienne Carriere *
228885b1c02SEtienne Carriere * SYSRAM configuration for secure/non-secure boundaries requires the
229885b1c02SEtienne Carriere * secure SYSRAM memory to start at the SYSRAM physical base address and grow
230885b1c02SEtienne Carriere * from there while the non-secure SYSRAM range lies at SYSRAM end addresses
231885b1c02SEtienne Carriere * with a 4KB page granule.
232885b1c02SEtienne Carriere *
233885b1c02SEtienne Carriere * SRAM1, SRAM2, SRAM3 and SRAM4 are independently assigned to secure world,
234885b1c02SEtienne Carriere * to non-secure world or possibly to Cortex-M4 exclusive access. Each
235885b1c02SEtienne Carriere * assignment covers the full related SRAMx memory range.
236885b1c02SEtienne Carriere *
237885b1c02SEtienne Carriere * Using non-secure SYSRAM or one of the SRAMx for SCMI message communication
238885b1c02SEtienne Carriere * can be done using CFG_STM32MP1_SCMI_SHM_BASE/CFG_STM32MP1_SCMI_SHM_SIZE.
239885b1c02SEtienne Carriere * This imposes related memory area is assigned to non-secure world.
240885b1c02SEtienne Carriere
241885b1c02SEtienne Carriere * Using secure internal memories (SYSRAM and/or some SRAMx) with STM32MP15
242885b1c02SEtienne Carriere * shall meet this constraints known the TZSRAM physical memory range shall
243885b1c02SEtienne Carriere * be contiguous.
244885b1c02SEtienne Carriere */
245885b1c02SEtienne Carriere
246885b1c02SEtienne Carriere #define SYSRAM_END (SYSRAM_BASE + SYSRAM_SIZE)
247885b1c02SEtienne Carriere #define SYSRAM_SEC_END (SYSRAM_BASE + SYSRAM_SEC_SIZE)
248885b1c02SEtienne Carriere #define SRAMS_END (SRAM4_BASE + SRAM4_SIZE)
249885b1c02SEtienne Carriere #define SRAMS_START SRAM1_BASE
250885b1c02SEtienne Carriere #define TZSRAM_END (CFG_TZSRAM_START + CFG_TZSRAM_SIZE)
251885b1c02SEtienne Carriere
252885b1c02SEtienne Carriere #define TZSRAM_FITS_IN_SYSRAM_SEC ((CFG_TZSRAM_START >= SYSRAM_BASE) && \
253885b1c02SEtienne Carriere (TZSRAM_END <= SYSRAM_SEC_END))
254885b1c02SEtienne Carriere
255885b1c02SEtienne Carriere #define TZSRAM_FITS_IN_SYSRAM_AND_SRAMS ((CFG_TZSRAM_START >= SYSRAM_BASE) && \
256885b1c02SEtienne Carriere (CFG_TZSRAM_START < SYSRAM_END) && \
257885b1c02SEtienne Carriere (TZSRAM_END > SYSRAM_END) && \
258885b1c02SEtienne Carriere (TZSRAM_END <= SRAMS_END) && \
259885b1c02SEtienne Carriere (SYSRAM_SIZE == SYSRAM_SEC_SIZE))
260885b1c02SEtienne Carriere
261885b1c02SEtienne Carriere #define TZSRAM_FITS_IN_SRAMS ((CFG_TZSRAM_START >= SRAMS_START) && \
262885b1c02SEtienne Carriere (CFG_TZSRAM_START < SRAMS_END) && \
263885b1c02SEtienne Carriere (TZSRAM_END <= SRAMS_END))
264885b1c02SEtienne Carriere
265885b1c02SEtienne Carriere #define TZSRAM_IS_IN_DRAM (CFG_TZSRAM_START >= CFG_DRAM_BASE)
266885b1c02SEtienne Carriere
267885b1c02SEtienne Carriere #ifdef CFG_WITH_PAGER
268885b1c02SEtienne Carriere /*
269885b1c02SEtienne Carriere * At build time, we enforce that, when pager is used,
270885b1c02SEtienne Carriere * either TZSRAM fully fits inside SYSRAM secure address range,
271885b1c02SEtienne Carriere * or TZSRAM fully fits inside the full SYSRAM and spread inside SRAMx orderly,
272885b1c02SEtienne Carriere * or TZSRAM fully fits some inside SRAMs address range,
273885b1c02SEtienne Carriere * or TZSRAM is in DDR for debug and test purpose.
274885b1c02SEtienne Carriere */
275885b1c02SEtienne Carriere static_assert(TZSRAM_FITS_IN_SYSRAM_SEC || TZSRAM_FITS_IN_SYSRAM_AND_SRAMS ||
276885b1c02SEtienne Carriere TZSRAM_FITS_IN_SRAMS || TZSRAM_IS_IN_DRAM);
277132151fbSEtienne Carriere #endif /* CFG_WITH_PAGER */
278132151fbSEtienne Carriere #endif /* CFG_STM32MP15 */
279132151fbSEtienne Carriere
secure_pager_ram(struct dt_driver_provider * fw_provider,unsigned int decprot_id,paddr_t base,size_t secure_size)280132151fbSEtienne Carriere static TEE_Result secure_pager_ram(struct dt_driver_provider *fw_provider,
281132151fbSEtienne Carriere unsigned int decprot_id,
282132151fbSEtienne Carriere paddr_t base, size_t secure_size)
283132151fbSEtienne Carriere {
284132151fbSEtienne Carriere /* Lock firewall configuration for secure internal RAMs used by pager */
285132151fbSEtienne Carriere uint32_t query_arg = DECPROT(decprot_id, DECPROT_S_RW, DECPROT_LOCK);
286132151fbSEtienne Carriere struct firewall_query fw_query = {
287132151fbSEtienne Carriere .ctrl = dt_driver_provider_priv_data(fw_provider),
288132151fbSEtienne Carriere .args = &query_arg,
289132151fbSEtienne Carriere .arg_count = 1,
290132151fbSEtienne Carriere };
291132151fbSEtienne Carriere TEE_Result res = TEE_ERROR_GENERIC;
292132151fbSEtienne Carriere bool is_pager_ram = false;
293132151fbSEtienne Carriere
294132151fbSEtienne Carriere #if defined(CFG_WITH_PAGER)
295132151fbSEtienne Carriere is_pager_ram = core_is_buffer_intersect(CFG_TZSRAM_START,
296132151fbSEtienne Carriere CFG_TZSRAM_SIZE,
297132151fbSEtienne Carriere base, secure_size);
298885b1c02SEtienne Carriere #endif
299132151fbSEtienne Carriere if (!is_pager_ram)
300885b1c02SEtienne Carriere return TEE_SUCCESS;
301132151fbSEtienne Carriere
302132151fbSEtienne Carriere res = firewall_set_memory_configuration(&fw_query, base, secure_size);
303132151fbSEtienne Carriere if (res)
304132151fbSEtienne Carriere EMSG("Failed to configure secure SRAM %#"PRIxPA"..%#"PRIxPA,
305132151fbSEtienne Carriere base, base + secure_size);
306132151fbSEtienne Carriere
307132151fbSEtienne Carriere return res;
308885b1c02SEtienne Carriere }
309885b1c02SEtienne Carriere
non_secure_scmi_ram(struct dt_driver_provider * fw_provider,unsigned int decprot_id,paddr_t base,size_t size)310132151fbSEtienne Carriere static TEE_Result non_secure_scmi_ram(struct dt_driver_provider *fw_provider,
311132151fbSEtienne Carriere unsigned int decprot_id,
312132151fbSEtienne Carriere paddr_t base, size_t size)
3131095cc2eSEtienne Carriere {
314132151fbSEtienne Carriere /* Do not lock firewall configuration for non-secure internal RAMs */
315132151fbSEtienne Carriere uint32_t query_arg = DECPROT(decprot_id, DECPROT_NS_RW, DECPROT_UNLOCK);
316132151fbSEtienne Carriere struct firewall_query fw_query = {
317132151fbSEtienne Carriere .ctrl = dt_driver_provider_priv_data(fw_provider),
318132151fbSEtienne Carriere .args = &query_arg,
319132151fbSEtienne Carriere .arg_count = 1,
320132151fbSEtienne Carriere };
321132151fbSEtienne Carriere TEE_Result res = TEE_ERROR_GENERIC;
322132151fbSEtienne Carriere
323132151fbSEtienne Carriere if (!core_is_buffer_intersect(CFG_STM32MP1_SCMI_SHM_BASE,
324132151fbSEtienne Carriere CFG_STM32MP1_SCMI_SHM_SIZE,
325132151fbSEtienne Carriere base, size))
326132151fbSEtienne Carriere return TEE_SUCCESS;
327132151fbSEtienne Carriere
328132151fbSEtienne Carriere res = firewall_set_memory_configuration(&fw_query, base, size);
329132151fbSEtienne Carriere if (res)
330132151fbSEtienne Carriere EMSG("Failed to configure non-secure SRAM %#"PRIxPA"..%#"PRIxPA,
331132151fbSEtienne Carriere base, base + size);
332132151fbSEtienne Carriere
333132151fbSEtienne Carriere return res;
334132151fbSEtienne Carriere }
335132151fbSEtienne Carriere
336132151fbSEtienne Carriere /* At run time we enforce that SRAM1 to SRAM4 are properly assigned if used */
configure_srams(struct dt_driver_provider * fw_provider)337132151fbSEtienne Carriere static void configure_srams(struct dt_driver_provider *fw_provider)
338132151fbSEtienne Carriere {
339132151fbSEtienne Carriere bool error = false;
340132151fbSEtienne Carriere
341132151fbSEtienne Carriere if (IS_ENABLED(CFG_WITH_PAGER)) {
342132151fbSEtienne Carriere if (secure_pager_ram(fw_provider, STM32MP1_ETZPC_SRAM1_ID,
343132151fbSEtienne Carriere SRAM1_BASE, SRAM1_SIZE))
344132151fbSEtienne Carriere error = true;
345132151fbSEtienne Carriere
346132151fbSEtienne Carriere if (secure_pager_ram(fw_provider, STM32MP1_ETZPC_SRAM2_ID,
347132151fbSEtienne Carriere SRAM2_BASE, SRAM2_SIZE))
348132151fbSEtienne Carriere error = true;
349132151fbSEtienne Carriere
350132151fbSEtienne Carriere if (secure_pager_ram(fw_provider, STM32MP1_ETZPC_SRAM3_ID,
351132151fbSEtienne Carriere SRAM3_BASE, SRAM3_SIZE))
352132151fbSEtienne Carriere error = true;
353132151fbSEtienne Carriere
354132151fbSEtienne Carriere #if defined(CFG_STM32MP15)
355132151fbSEtienne Carriere if (secure_pager_ram(fw_provider, STM32MP1_ETZPC_SRAM4_ID,
356132151fbSEtienne Carriere SRAM4_BASE, SRAM4_SIZE))
357132151fbSEtienne Carriere error = true;
358132151fbSEtienne Carriere #endif
359132151fbSEtienne Carriere }
360132151fbSEtienne Carriere if (CFG_STM32MP1_SCMI_SHM_BASE) {
361132151fbSEtienne Carriere if (non_secure_scmi_ram(fw_provider, STM32MP1_ETZPC_SRAM1_ID,
362132151fbSEtienne Carriere SRAM1_BASE, SRAM1_SIZE))
363132151fbSEtienne Carriere error = true;
364132151fbSEtienne Carriere
365132151fbSEtienne Carriere if (non_secure_scmi_ram(fw_provider, STM32MP1_ETZPC_SRAM2_ID,
366132151fbSEtienne Carriere SRAM2_BASE, SRAM2_SIZE))
367132151fbSEtienne Carriere error = true;
368132151fbSEtienne Carriere
369132151fbSEtienne Carriere if (non_secure_scmi_ram(fw_provider, STM32MP1_ETZPC_SRAM3_ID,
370132151fbSEtienne Carriere SRAM3_BASE, SRAM3_SIZE))
371132151fbSEtienne Carriere error = true;
372132151fbSEtienne Carriere
373132151fbSEtienne Carriere #if defined(CFG_STM32MP15)
374132151fbSEtienne Carriere if (non_secure_scmi_ram(fw_provider, STM32MP1_ETZPC_SRAM4_ID,
375132151fbSEtienne Carriere SRAM4_BASE, SRAM4_SIZE))
376132151fbSEtienne Carriere error = true;
377132151fbSEtienne Carriere #endif
378132151fbSEtienne Carriere }
379132151fbSEtienne Carriere
380132151fbSEtienne Carriere if (error)
381132151fbSEtienne Carriere panic();
382132151fbSEtienne Carriere }
383132151fbSEtienne Carriere
configure_sysram(struct dt_driver_provider * fw_provider)384132151fbSEtienne Carriere static void configure_sysram(struct dt_driver_provider *fw_provider)
385132151fbSEtienne Carriere {
386132151fbSEtienne Carriere uint32_t query_arg = DECPROT(ETZPC_TZMA1_ID, DECPROT_S_RW,
387132151fbSEtienne Carriere DECPROT_UNLOCK);
388132151fbSEtienne Carriere struct firewall_query firewall = {
389132151fbSEtienne Carriere .ctrl = dt_driver_provider_priv_data(fw_provider),
390132151fbSEtienne Carriere .args = &query_arg,
391132151fbSEtienne Carriere .arg_count = 1,
392132151fbSEtienne Carriere };
393132151fbSEtienne Carriere TEE_Result res = TEE_ERROR_GENERIC;
394132151fbSEtienne Carriere
395132151fbSEtienne Carriere res = firewall_set_memory_configuration(&firewall, SYSRAM_BASE,
396132151fbSEtienne Carriere SYSRAM_SEC_SIZE);
397132151fbSEtienne Carriere if (res)
398132151fbSEtienne Carriere panic("Unable to secure SYSRAM");
3991095cc2eSEtienne Carriere
400986fccc8SEtienne Carriere if (SYSRAM_SIZE > SYSRAM_SEC_SIZE) {
401986fccc8SEtienne Carriere size_t nsec_size = SYSRAM_SIZE - SYSRAM_SEC_SIZE;
402986fccc8SEtienne Carriere paddr_t nsec_start = SYSRAM_BASE + SYSRAM_SEC_SIZE;
403986fccc8SEtienne Carriere uint8_t *va = phys_to_virt(nsec_start, MEM_AREA_IO_NSEC,
404986fccc8SEtienne Carriere nsec_size);
405986fccc8SEtienne Carriere
406986fccc8SEtienne Carriere IMSG("Non-secure SYSRAM [%p %p]", va, va + nsec_size - 1);
407986fccc8SEtienne Carriere
408986fccc8SEtienne Carriere /* Clear content from the non-secure part */
409986fccc8SEtienne Carriere memset(va, 0, nsec_size);
410986fccc8SEtienne Carriere }
4111095cc2eSEtienne Carriere }
4126b054087SEtienne Carriere
init_late_stm32mp1_drivers(void)4136b054087SEtienne Carriere static TEE_Result init_late_stm32mp1_drivers(void)
4146b054087SEtienne Carriere {
415db3e6bf9SEtienne Carriere uint32_t __maybe_unused state = 0;
4166b054087SEtienne Carriere
417132151fbSEtienne Carriere /* Configure SYSRAM and SRAMx secure hardening */
418132151fbSEtienne Carriere if (IS_ENABLED(CFG_STM32_ETZPC)) {
419132151fbSEtienne Carriere struct dt_driver_provider *prov = NULL;
420132151fbSEtienne Carriere int node = 0;
421132151fbSEtienne Carriere
422132151fbSEtienne Carriere node = fdt_node_offset_by_compatible(get_embedded_dt(), -1,
423132151fbSEtienne Carriere "st,stm32-etzpc");
424132151fbSEtienne Carriere if (node < 0)
425132151fbSEtienne Carriere panic("Could not get ETZPC node");
426132151fbSEtienne Carriere
427132151fbSEtienne Carriere prov = dt_driver_get_provider_by_node(node, DT_DRIVER_FIREWALL);
428132151fbSEtienne Carriere assert(prov);
429132151fbSEtienne Carriere
430132151fbSEtienne Carriere configure_sysram(prov);
431132151fbSEtienne Carriere configure_srams(prov);
432132151fbSEtienne Carriere }
433132151fbSEtienne Carriere
434db3e6bf9SEtienne Carriere #ifdef CFG_STM32MP15
435db3e6bf9SEtienne Carriere /* Device in Secure Closed state require RCC secure hardening */
436db3e6bf9SEtienne Carriere if (stm32_bsec_get_state(&state))
437db3e6bf9SEtienne Carriere panic();
438db3e6bf9SEtienne Carriere if (state == BSEC_STATE_SEC_CLOSED && !stm32_rcc_is_secure())
439db3e6bf9SEtienne Carriere panic("Closed device mandates secure RCC");
440db3e6bf9SEtienne Carriere #endif
441db3e6bf9SEtienne Carriere
4426b054087SEtienne Carriere return TEE_SUCCESS;
4436b054087SEtienne Carriere }
4446b054087SEtienne Carriere
4456b054087SEtienne Carriere driver_init_late(init_late_stm32mp1_drivers);
4466b054087SEtienne Carriere
stm32_rcc_base(void)447569d17b0SEtienne Carriere vaddr_t stm32_rcc_base(void)
448569d17b0SEtienne Carriere {
449569d17b0SEtienne Carriere static struct io_pa_va base = { .pa = RCC_BASE };
450569d17b0SEtienne Carriere
451569d17b0SEtienne Carriere return io_pa_or_va_secure(&base, 1);
452569d17b0SEtienne Carriere }
453569d17b0SEtienne Carriere
get_gicd_base(void)4549b39d0faSEtienne Carriere vaddr_t get_gicd_base(void)
455eb07694aSEtienne Carriere {
4569b39d0faSEtienne Carriere struct io_pa_va base = { .pa = GIC_BASE + GICD_OFFSET };
457eb07694aSEtienne Carriere
458c2e4eb43SAnton Rybakov return io_pa_or_va_secure(&base, 1);
459eb07694aSEtienne Carriere }
46000707cccSEtienne Carriere
stm32mp_get_bsec_static_cfg(struct stm32_bsec_static_cfg * cfg)461e043ba4bSEtienne Carriere void stm32mp_get_bsec_static_cfg(struct stm32_bsec_static_cfg *cfg)
462e043ba4bSEtienne Carriere {
463e043ba4bSEtienne Carriere cfg->base = BSEC_BASE;
464e043ba4bSEtienne Carriere cfg->upper_start = STM32MP1_UPPER_OTP_START;
465e043ba4bSEtienne Carriere cfg->max_id = STM32MP1_OTP_MAX_ID;
466e043ba4bSEtienne Carriere }
467e043ba4bSEtienne Carriere
stm32mp_with_pmic(void)468944c2c63SEtienne Carriere bool __weak stm32mp_with_pmic(void)
469944c2c63SEtienne Carriere {
470944c2c63SEtienne Carriere return false;
471944c2c63SEtienne Carriere }
472944c2c63SEtienne Carriere
may_spin_lock(unsigned int * lock)47300707cccSEtienne Carriere uint32_t may_spin_lock(unsigned int *lock)
47400707cccSEtienne Carriere {
47500707cccSEtienne Carriere if (!lock || !cpu_mmu_enabled())
47600707cccSEtienne Carriere return 0;
47700707cccSEtienne Carriere
47800707cccSEtienne Carriere return cpu_spin_lock_xsave(lock);
47900707cccSEtienne Carriere }
48000707cccSEtienne Carriere
may_spin_unlock(unsigned int * lock,uint32_t exceptions)48100707cccSEtienne Carriere void may_spin_unlock(unsigned int *lock, uint32_t exceptions)
48200707cccSEtienne Carriere {
48300707cccSEtienne Carriere if (!lock || !cpu_mmu_enabled())
48400707cccSEtienne Carriere return;
48500707cccSEtienne Carriere
48600707cccSEtienne Carriere cpu_spin_unlock_xrestore(lock, exceptions);
48700707cccSEtienne Carriere }
488b9c19263SEtienne Carriere
stm32_tamp_base(void)4899b39d0faSEtienne Carriere static vaddr_t stm32_tamp_base(void)
490b9c19263SEtienne Carriere {
491b9c19263SEtienne Carriere static struct io_pa_va base = { .pa = TAMP_BASE };
492b9c19263SEtienne Carriere
493c2e4eb43SAnton Rybakov return io_pa_or_va_secure(&base, 1);
494b9c19263SEtienne Carriere }
495b9c19263SEtienne Carriere
bkpreg_base(void)4969b39d0faSEtienne Carriere static vaddr_t bkpreg_base(void)
497b9c19263SEtienne Carriere {
498b9c19263SEtienne Carriere return stm32_tamp_base() + TAMP_BKP_REGISTER_OFF;
499b9c19263SEtienne Carriere }
500b9c19263SEtienne Carriere
stm32mp_bkpreg(unsigned int idx)5019b39d0faSEtienne Carriere vaddr_t stm32mp_bkpreg(unsigned int idx)
502b9c19263SEtienne Carriere {
503b9c19263SEtienne Carriere return bkpreg_base() + (idx * sizeof(uint32_t));
504b9c19263SEtienne Carriere }
505fff9beb4SEtienne Carriere
bank_is_valid(unsigned int bank)506a9f86b17SGatien Chevallier static bool __maybe_unused bank_is_valid(unsigned int bank)
507a9f86b17SGatien Chevallier {
508a9f86b17SGatien Chevallier if (IS_ENABLED(CFG_STM32MP15))
509a9f86b17SGatien Chevallier return bank == GPIO_BANK_Z || bank <= GPIO_BANK_K;
510a9f86b17SGatien Chevallier
511a9f86b17SGatien Chevallier if (IS_ENABLED(CFG_STM32MP13))
512a9f86b17SGatien Chevallier return bank <= GPIO_BANK_I;
513a9f86b17SGatien Chevallier
514a9f86b17SGatien Chevallier panic();
515a9f86b17SGatien Chevallier }
516a9f86b17SGatien Chevallier
5178f29a74fSGatien Chevallier #ifdef CFG_STM32_DEBUG_ACCESS
init_debug(void)5188f29a74fSGatien Chevallier static TEE_Result init_debug(void)
5198f29a74fSGatien Chevallier {
5208f29a74fSGatien Chevallier TEE_Result res = TEE_SUCCESS;
5218f29a74fSGatien Chevallier uint32_t conf = stm32_bsec_read_debug_conf();
5228f29a74fSGatien Chevallier struct clk *dbg_clk = stm32mp_rcc_clock_id_to_clk(CK_DBG);
5238f29a74fSGatien Chevallier uint32_t state = 0;
5248f29a74fSGatien Chevallier
5258f29a74fSGatien Chevallier res = stm32_bsec_get_state(&state);
5268f29a74fSGatien Chevallier if (res)
5278f29a74fSGatien Chevallier return res;
5288f29a74fSGatien Chevallier
5298f29a74fSGatien Chevallier if (state != BSEC_STATE_SEC_CLOSED && conf) {
5309ea709a7SEtienne Carriere if (IS_ENABLED(CFG_INSECURE))
5318f29a74fSGatien Chevallier IMSG("WARNING: All debug accesses are allowed");
5328f29a74fSGatien Chevallier
5338f29a74fSGatien Chevallier res = stm32_bsec_write_debug_conf(conf | BSEC_DEBUG_ALL);
5348f29a74fSGatien Chevallier if (res)
5358f29a74fSGatien Chevallier return res;
5368f29a74fSGatien Chevallier
5378f29a74fSGatien Chevallier /*
5388f29a74fSGatien Chevallier * Enable DBG clock as used to access coprocessor
5398f29a74fSGatien Chevallier * debug registers
5408f29a74fSGatien Chevallier */
5418f29a74fSGatien Chevallier clk_enable(dbg_clk);
5428f29a74fSGatien Chevallier }
5438f29a74fSGatien Chevallier
5448f29a74fSGatien Chevallier return TEE_SUCCESS;
5458f29a74fSGatien Chevallier }
5468f29a74fSGatien Chevallier early_init_late(init_debug);
5478f29a74fSGatien Chevallier #endif /* CFG_STM32_DEBUG_ACCESS */
5486d6aeba1SEtienne Carriere
5496d6aeba1SEtienne Carriere /* Some generic resources need to be unpaged */
5506d6aeba1SEtienne Carriere DECLARE_KEEP_PAGER(pinctrl_apply_state);
551f2e5b5e0SGatien Chevallier
stm32mp_allow_probe_shared_device(const void * fdt,int node)552f2e5b5e0SGatien Chevallier bool stm32mp_allow_probe_shared_device(const void *fdt, int node)
553f2e5b5e0SGatien Chevallier {
554f2e5b5e0SGatien Chevallier static int uart_console_node = -1;
555f2e5b5e0SGatien Chevallier const char *compat = NULL;
556f2e5b5e0SGatien Chevallier static bool once;
557f2e5b5e0SGatien Chevallier
558f2e5b5e0SGatien Chevallier if (IS_ENABLED(CFG_STM32_ALLOW_UNSAFE_PROBE))
559f2e5b5e0SGatien Chevallier return true;
560f2e5b5e0SGatien Chevallier
561f2e5b5e0SGatien Chevallier if (!once) {
562f2e5b5e0SGatien Chevallier get_console_node_from_dt((void *)fdt, &uart_console_node,
563f2e5b5e0SGatien Chevallier NULL, NULL);
564f2e5b5e0SGatien Chevallier once = true;
565f2e5b5e0SGatien Chevallier }
566f2e5b5e0SGatien Chevallier
567f2e5b5e0SGatien Chevallier compat = fdt_stringlist_get(fdt, node, "compatible", 0, NULL);
568f2e5b5e0SGatien Chevallier
569f2e5b5e0SGatien Chevallier /*
570f2e5b5e0SGatien Chevallier * Allow OP-TEE console and MP15 I2C and RNG to be shared
571f2e5b5e0SGatien Chevallier * with non-secure world.
572f2e5b5e0SGatien Chevallier */
573f2e5b5e0SGatien Chevallier if (node == uart_console_node ||
574f2e5b5e0SGatien Chevallier !strcmp(compat, "st,stm32mp15-i2c-non-secure") ||
575f2e5b5e0SGatien Chevallier (!strcmp(compat, "st,stm32-rng") &&
576f2e5b5e0SGatien Chevallier IS_ENABLED(CFG_WITH_SOFTWARE_PRNG)))
577f2e5b5e0SGatien Chevallier return true;
578f2e5b5e0SGatien Chevallier
579f2e5b5e0SGatien Chevallier return false;
580f2e5b5e0SGatien Chevallier }
5812714147bSEtienne Carriere
5822714147bSEtienne Carriere #if defined(CFG_STM32MP15) && defined(CFG_WITH_PAGER)
stm32mp1_pa_or_sram_alias_pa(paddr_t pa)5832714147bSEtienne Carriere paddr_t stm32mp1_pa_or_sram_alias_pa(paddr_t pa)
5842714147bSEtienne Carriere {
5852714147bSEtienne Carriere /*
5862714147bSEtienne Carriere * OP-TEE uses the alias physical addresses of SRAM1/2/3/4,
5872714147bSEtienne Carriere * not the standard physical addresses. This choice was initially
5882714147bSEtienne Carriere * driven by pager that needs physically contiguous memories
5892714147bSEtienne Carriere * for internal secure memories.
5902714147bSEtienne Carriere */
5912714147bSEtienne Carriere if (core_is_buffer_inside(pa, 1, SRAM1_ALT_BASE, SRAM1_SIZE))
5922714147bSEtienne Carriere pa += SRAM1_BASE - SRAM1_ALT_BASE;
5932714147bSEtienne Carriere else if (core_is_buffer_inside(pa, 1, SRAM2_ALT_BASE, SRAM2_SIZE))
5942714147bSEtienne Carriere pa += SRAM2_BASE - SRAM2_ALT_BASE;
5952714147bSEtienne Carriere else if (core_is_buffer_inside(pa, 1, SRAM3_ALT_BASE, SRAM3_SIZE))
5962714147bSEtienne Carriere pa += SRAM3_BASE - SRAM3_ALT_BASE;
5972714147bSEtienne Carriere else if (core_is_buffer_inside(pa, 1, SRAM4_ALT_BASE, SRAM4_SIZE))
5982714147bSEtienne Carriere pa += SRAM4_BASE - SRAM4_ALT_BASE;
5992714147bSEtienne Carriere
6002714147bSEtienne Carriere return pa;
6012714147bSEtienne Carriere }
602a0cac862SEtienne Carriere
stm32mp1_ram_intersect_pager_ram(paddr_t base,size_t size)603a0cac862SEtienne Carriere bool stm32mp1_ram_intersect_pager_ram(paddr_t base, size_t size)
604a0cac862SEtienne Carriere {
605a0cac862SEtienne Carriere base = stm32mp1_pa_or_sram_alias_pa(base);
606a0cac862SEtienne Carriere
607a0cac862SEtienne Carriere return core_is_buffer_intersect(base, size, CFG_TZSRAM_START,
608a0cac862SEtienne Carriere CFG_TZSRAM_SIZE);
609a0cac862SEtienne Carriere }
6102714147bSEtienne Carriere #endif
61161491a0cSPascal Paillet
get_chip_dev_id(uint32_t * dev_id)61261491a0cSPascal Paillet static TEE_Result get_chip_dev_id(uint32_t *dev_id)
61361491a0cSPascal Paillet {
614d8aa45ccSPascal Paillet #ifdef CFG_STM32MP13
61561491a0cSPascal Paillet *dev_id = stm32mp_syscfg_get_chip_dev_id();
61661491a0cSPascal Paillet return TEE_SUCCESS;
617d8aa45ccSPascal Paillet #else /* assume CFG_STM32MP15 */
618d8aa45ccSPascal Paillet return stm32mp1_dbgmcu_get_chip_dev_id(dev_id);
619d8aa45ccSPascal Paillet #endif
62061491a0cSPascal Paillet }
62161491a0cSPascal Paillet
get_part_number(uint32_t * part_nb)62261491a0cSPascal Paillet static TEE_Result get_part_number(uint32_t *part_nb)
62361491a0cSPascal Paillet {
62461491a0cSPascal Paillet static uint32_t part_number;
62561491a0cSPascal Paillet uint32_t dev_id = 0;
62661491a0cSPascal Paillet uint32_t otp = 0;
62761491a0cSPascal Paillet size_t bit_len = 0;
62861491a0cSPascal Paillet TEE_Result res = TEE_ERROR_GENERIC;
62961491a0cSPascal Paillet
63061491a0cSPascal Paillet assert(part_nb);
63161491a0cSPascal Paillet
63261491a0cSPascal Paillet if (part_number) {
63361491a0cSPascal Paillet *part_nb = part_number;
63461491a0cSPascal Paillet return TEE_SUCCESS;
63561491a0cSPascal Paillet }
63661491a0cSPascal Paillet
63761491a0cSPascal Paillet res = get_chip_dev_id(&dev_id);
63861491a0cSPascal Paillet if (res)
63961491a0cSPascal Paillet return res;
64061491a0cSPascal Paillet
64161491a0cSPascal Paillet res = stm32_bsec_find_otp_in_nvmem_layout("part_number_otp",
64261491a0cSPascal Paillet &otp, NULL, &bit_len);
64361491a0cSPascal Paillet if (res)
64461491a0cSPascal Paillet return res;
64561491a0cSPascal Paillet
64661491a0cSPascal Paillet res = stm32_bsec_read_otp(&part_number, otp);
64761491a0cSPascal Paillet if (res)
64861491a0cSPascal Paillet return res;
64961491a0cSPascal Paillet
65061491a0cSPascal Paillet assert(bit_len < 16);
65161491a0cSPascal Paillet part_number = (part_number & GENMASK_32(bit_len, 0)) |
65261491a0cSPascal Paillet SHIFT_U32(dev_id, 16);
65361491a0cSPascal Paillet
65461491a0cSPascal Paillet *part_nb = part_number;
65561491a0cSPascal Paillet
65661491a0cSPascal Paillet return TEE_SUCCESS;
65761491a0cSPascal Paillet }
65861491a0cSPascal Paillet
stm32mp_supports_cpu_opp(uint32_t opp_id)65961491a0cSPascal Paillet bool stm32mp_supports_cpu_opp(uint32_t opp_id)
66061491a0cSPascal Paillet {
66161491a0cSPascal Paillet uint32_t part_number = 0;
66261491a0cSPascal Paillet uint32_t id = 0;
66361491a0cSPascal Paillet
66461491a0cSPascal Paillet if (get_part_number(&part_number)) {
66561491a0cSPascal Paillet DMSG("Cannot get part number");
66661491a0cSPascal Paillet panic();
66761491a0cSPascal Paillet }
66861491a0cSPascal Paillet
66961491a0cSPascal Paillet switch (part_number) {
67061491a0cSPascal Paillet case STM32MP135F_PART_NB:
67161491a0cSPascal Paillet case STM32MP135D_PART_NB:
67261491a0cSPascal Paillet case STM32MP133F_PART_NB:
67361491a0cSPascal Paillet case STM32MP133D_PART_NB:
67461491a0cSPascal Paillet case STM32MP131F_PART_NB:
67561491a0cSPascal Paillet case STM32MP131D_PART_NB:
67661491a0cSPascal Paillet case STM32MP157F_PART_NB:
67761491a0cSPascal Paillet case STM32MP157D_PART_NB:
67861491a0cSPascal Paillet case STM32MP153F_PART_NB:
67961491a0cSPascal Paillet case STM32MP153D_PART_NB:
68061491a0cSPascal Paillet case STM32MP151F_PART_NB:
68161491a0cSPascal Paillet case STM32MP151D_PART_NB:
68261491a0cSPascal Paillet id = BIT(1);
68361491a0cSPascal Paillet break;
68461491a0cSPascal Paillet default:
68561491a0cSPascal Paillet id = BIT(0);
68661491a0cSPascal Paillet break;
68761491a0cSPascal Paillet }
68861491a0cSPascal Paillet
68961491a0cSPascal Paillet return opp_id & id;
69061491a0cSPascal Paillet }
69161491a0cSPascal Paillet
stm32mp_supports_hw_cryp(void)69261491a0cSPascal Paillet bool stm32mp_supports_hw_cryp(void)
69361491a0cSPascal Paillet {
69461491a0cSPascal Paillet uint32_t part_number = 0;
69561491a0cSPascal Paillet
69661491a0cSPascal Paillet if (!IS_ENABLED(CFG_STM32_CRYP))
69761491a0cSPascal Paillet return false;
69861491a0cSPascal Paillet
69961491a0cSPascal Paillet if (get_part_number(&part_number)) {
70061491a0cSPascal Paillet DMSG("Cannot get part number");
70161491a0cSPascal Paillet panic();
70261491a0cSPascal Paillet }
70361491a0cSPascal Paillet
70461491a0cSPascal Paillet switch (part_number) {
70561491a0cSPascal Paillet case STM32MP135F_PART_NB:
70661491a0cSPascal Paillet case STM32MP135C_PART_NB:
70761491a0cSPascal Paillet case STM32MP133F_PART_NB:
70861491a0cSPascal Paillet case STM32MP133C_PART_NB:
70961491a0cSPascal Paillet case STM32MP131F_PART_NB:
71061491a0cSPascal Paillet case STM32MP131C_PART_NB:
71161491a0cSPascal Paillet return true;
71261491a0cSPascal Paillet case STM32MP157F_PART_NB:
71361491a0cSPascal Paillet case STM32MP157C_PART_NB:
71461491a0cSPascal Paillet case STM32MP153F_PART_NB:
71561491a0cSPascal Paillet case STM32MP153C_PART_NB:
71661491a0cSPascal Paillet case STM32MP151F_PART_NB:
71761491a0cSPascal Paillet case STM32MP151C_PART_NB:
71861491a0cSPascal Paillet return true;
71961491a0cSPascal Paillet default:
72061491a0cSPascal Paillet return false;
72161491a0cSPascal Paillet }
72261491a0cSPascal Paillet }
72361491a0cSPascal Paillet
stm32mp_supports_second_core(void)72461491a0cSPascal Paillet bool stm32mp_supports_second_core(void)
72561491a0cSPascal Paillet {
72661491a0cSPascal Paillet uint32_t part_number = 0;
72761491a0cSPascal Paillet
72861491a0cSPascal Paillet if (CFG_TEE_CORE_NB_CORE == 1)
72961491a0cSPascal Paillet return false;
73061491a0cSPascal Paillet
73161491a0cSPascal Paillet if (get_part_number(&part_number)) {
73261491a0cSPascal Paillet DMSG("Cannot get part number");
73361491a0cSPascal Paillet panic();
73461491a0cSPascal Paillet }
73561491a0cSPascal Paillet
73661491a0cSPascal Paillet switch (part_number) {
73761491a0cSPascal Paillet case STM32MP151F_PART_NB:
73861491a0cSPascal Paillet case STM32MP151D_PART_NB:
73961491a0cSPascal Paillet case STM32MP151C_PART_NB:
74061491a0cSPascal Paillet case STM32MP151A_PART_NB:
74161491a0cSPascal Paillet return false;
74261491a0cSPascal Paillet default:
74361491a0cSPascal Paillet return true;
74461491a0cSPascal Paillet }
74561491a0cSPascal Paillet }
746*e29eb9ddSGatien Chevallier
do_reset(const char * str __maybe_unused)747*e29eb9ddSGatien Chevallier void __noreturn do_reset(const char *str __maybe_unused)
748*e29eb9ddSGatien Chevallier {
749*e29eb9ddSGatien Chevallier struct rstctrl *rstctrl = NULL;
750*e29eb9ddSGatien Chevallier
751*e29eb9ddSGatien Chevallier if (CFG_TEE_CORE_NB_CORE > 1) {
752*e29eb9ddSGatien Chevallier /* Halt execution of other CPUs */
753*e29eb9ddSGatien Chevallier interrupt_raise_sgi(interrupt_get_main_chip(),
754*e29eb9ddSGatien Chevallier CFG_HALT_CORES_SGI,
755*e29eb9ddSGatien Chevallier ITR_CPU_MASK_TO_OTHER_CPUS);
756*e29eb9ddSGatien Chevallier mdelay(1);
757*e29eb9ddSGatien Chevallier }
758*e29eb9ddSGatien Chevallier
759*e29eb9ddSGatien Chevallier IMSG("Forced system reset %s", str);
760*e29eb9ddSGatien Chevallier console_flush();
761*e29eb9ddSGatien Chevallier
762*e29eb9ddSGatien Chevallier /* Request system reset to RCC driver */
763*e29eb9ddSGatien Chevallier rstctrl = stm32mp_rcc_reset_id_to_rstctrl(MPSYST_R);
764*e29eb9ddSGatien Chevallier rstctrl_assert(rstctrl);
765*e29eb9ddSGatien Chevallier udelay(100);
766*e29eb9ddSGatien Chevallier
767*e29eb9ddSGatien Chevallier /* Cannot occur */
768*e29eb9ddSGatien Chevallier panic();
769*e29eb9ddSGatien Chevallier }
770