xref: /optee_os/core/arch/arm/plat-stm32mp1/plat_tzc400.c (revision 5f7f88c6b9d618d1e068166bbf2b07757350791d)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2019-2020, STMicroelectronics
4  */
5 
6 #include <assert.h>
7 #include <config.h>
8 #include <drivers/tzc400.h>
9 #include <initcall.h>
10 #include <kernel/interrupt.h>
11 #include <kernel/panic.h>
12 #include <mm/core_memprot.h>
13 #include <platform_config.h>
14 #include <trace.h>
15 #include <util.h>
16 
17 #ifdef CFG_STM32MP15
18 #define TZC_FILTERS_MASK	GENMASK_32(1, 0)
19 #endif
20 #ifdef CFG_STM32MP13
21 #define TZC_FILTERS_MASK	GENMASK_32(0, 0)
22 #endif
23 
24 static enum itr_return tzc_it_handler(struct itr_handler *handler __unused)
25 {
26 	EMSG("TZC permission failure");
27 	tzc_fail_dump();
28 
29 	if (IS_ENABLED(CFG_STM32MP_PANIC_ON_TZC_PERM_VIOLATION))
30 		panic();
31 	else
32 		tzc_int_clear();
33 
34 	return ITRR_HANDLED;
35 }
36 
37 static struct itr_handler tzc_itr_handler = {
38 	.it = STM32MP1_IRQ_TZC,
39 	.handler = tzc_it_handler,
40 };
41 DECLARE_KEEP_PAGER(tzc_itr_handler);
42 
43 static bool tzc_region_is_non_secure(unsigned int i, uint64_t pa, size_t size)
44 {
45 	struct tzc_region_config region_cfg = { };
46 	uint32_t ns_cpu_mask = TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID);
47 	uint32_t filters_mask = TZC_FILTERS_MASK;
48 	vaddr_t base = pa;
49 
50 	if (tzc_get_region_config(i, &region_cfg))
51 		panic();
52 
53 	return region_cfg.base == base && region_cfg.top == (base + size - 1) &&
54 	       region_cfg.sec_attr == TZC_REGION_S_NONE &&
55 	       (region_cfg.ns_device_access & ns_cpu_mask) == ns_cpu_mask &&
56 	       region_cfg.filters == filters_mask;
57 }
58 
59 static bool tzc_region_is_secure(unsigned int i, vaddr_t base, size_t size)
60 {
61 	struct tzc_region_config region_cfg = { };
62 	uint32_t filters_mask = TZC_FILTERS_MASK;
63 
64 	if (tzc_get_region_config(i, &region_cfg))
65 		panic();
66 
67 	return region_cfg.base == base && region_cfg.top == (base + size - 1) &&
68 	       region_cfg.sec_attr == TZC_REGION_S_RDWR &&
69 	       region_cfg.ns_device_access == 0 &&
70 	       region_cfg.filters == filters_mask;
71 }
72 
73 static TEE_Result init_stm32mp1_tzc(void)
74 {
75 	TEE_Result res = TEE_ERROR_GENERIC;
76 	void *base = phys_to_virt(TZC_BASE, MEM_AREA_IO_SEC, 1);
77 	unsigned int region_index = 1;
78 	const uint64_t dram_start = DDR_BASE;
79 	const uint64_t dram_end = dram_start + CFG_DRAM_SIZE;
80 	const uint64_t tzdram_start = CFG_TZDRAM_START;
81 	const uint64_t tzdram_size = CFG_TZDRAM_SIZE;
82 	const uint64_t tzdram_end = tzdram_start + tzdram_size;
83 
84 	assert(base);
85 
86 	tzc_init((vaddr_t)base);
87 	tzc_dump_state();
88 
89 	/*
90 	 * Early boot stage is in charge of configuring memory regions
91 	 * OP-TEE hence here only check this complies with static Core
92 	 * expectations.
93 	 */
94 	if (dram_start < tzdram_start) {
95 		if (!tzc_region_is_non_secure(region_index, dram_start,
96 					      tzdram_start - dram_start))
97 			panic("Unexpected TZC area on non-secure region");
98 
99 		region_index++;
100 	}
101 
102 	if (!tzc_region_is_secure(region_index, tzdram_start, tzdram_size))
103 		panic("Unexpected TZC configuration on secure region");
104 
105 	if (tzdram_end < dram_end) {
106 		region_index++;
107 
108 		if (!tzc_region_is_non_secure(region_index, tzdram_end,
109 					      dram_end - tzdram_end))
110 			panic("Unexpected TZC area on non-secure region");
111 	}
112 
113 	res = interrupt_add_handler_with_chip(interrupt_get_main_chip(),
114 					      &tzc_itr_handler);
115 	if (res)
116 		panic();
117 
118 	interrupt_enable(tzc_itr_handler.chip, tzc_itr_handler.it);
119 	tzc_set_action(TZC_ACTION_INT);
120 
121 	return TEE_SUCCESS;
122 }
123 driver_init(init_stm32mp1_tzc);
124