1 /*
2  * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <stdint.h>
8 
9 #include <platform_def.h>
10 
11 #include <common/debug.h>
12 #include <drivers/arm/tzc400.h>
13 #include <drivers/st/stm32mp1_clk.h>
14 #include <dt-bindings/clock/stm32mp1-clks.h>
15 #include <dt-bindings/soc/stm32mp15-tzc400.h>
16 #include <lib/mmio.h>
17 
18 static unsigned int region_nb;
19 
init_tzc400_begin(unsigned int region0_attr)20 static void init_tzc400_begin(unsigned int region0_attr)
21 {
22 	tzc400_init(STM32MP1_TZC_BASE);
23 	tzc400_disable_filters();
24 
25 	/* Region 0 set to cover all DRAM at 0xC000_0000 */
26 	tzc400_configure_region0(region0_attr, 0);
27 
28 	region_nb = 1U;
29 }
30 
init_tzc400_end(unsigned int action)31 static void init_tzc400_end(unsigned int action)
32 {
33 	tzc400_set_action(action);
34 	tzc400_enable_filters();
35 }
36 
tzc400_add_region(unsigned long long region_base,unsigned long long region_top,bool sec)37 static void tzc400_add_region(unsigned long long region_base,
38 			      unsigned long long region_top, bool sec)
39 {
40 	unsigned int sec_attr;
41 	unsigned int nsaid_permissions;
42 
43 	if (sec) {
44 		sec_attr = TZC_REGION_S_RDWR;
45 		nsaid_permissions = 0;
46 	} else {
47 		sec_attr = TZC_REGION_S_NONE;
48 		nsaid_permissions = TZC_REGION_NSEC_ALL_ACCESS_RDWR;
49 	}
50 
51 	tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, region_nb, region_base,
52 				region_top, sec_attr, nsaid_permissions);
53 
54 	region_nb++;
55 }
56 
57 /*******************************************************************************
58  * Initialize the TrustZone Controller. Configure Region 0 with Secure RW access
59  * and allow Non-Secure masters full access.
60  ******************************************************************************/
init_tzc400(void)61 static void init_tzc400(void)
62 {
63 	unsigned long long region_base, region_top;
64 	unsigned long long ddr_base = STM32MP_DDR_BASE;
65 	unsigned long long ddr_ns_size =
66 		(unsigned long long)stm32mp_get_ddr_ns_size();
67 	unsigned long long ddr_ns_top = ddr_base + (ddr_ns_size - 1U);
68 	unsigned long long ddr_top __unused;
69 
70 	init_tzc400_begin(TZC_REGION_S_NONE);
71 
72 	/*
73 	 * Region 1 set to cover all non-secure DRAM at 0xC000_0000. Apply the
74 	 * same configuration to all filters in the TZC.
75 	 */
76 	region_base = ddr_base;
77 	region_top = ddr_ns_top;
78 	tzc400_add_region(region_base, region_top, false);
79 
80 #ifdef AARCH32_SP_OPTEE
81 	/* Region 2 set to cover all secure DRAM. */
82 	region_base = region_top + 1U;
83 	region_top += STM32MP_DDR_S_SIZE;
84 	tzc400_add_region(region_base, region_top, true);
85 
86 	ddr_top = STM32MP_DDR_BASE + dt_get_ddr_size() - 1U;
87 	if (region_top < ddr_top) {
88 		/* Region 3 set to cover non-secure memory DRAM after BL32. */
89 		region_base = region_top + 1U;
90 		region_top = ddr_top;
91 		tzc400_add_region(region_base, region_top, false);
92 	}
93 #endif
94 
95 	/*
96 	 * Raise an interrupt (secure FIQ) if a NS device tries to access
97 	 * secure memory
98 	 */
99 	init_tzc400_end(TZC_ACTION_INT);
100 }
101 
102 /*******************************************************************************
103  * Initialize the TrustZone Controller.
104  * Early initialization create only one region with full access to secure.
105  * This setting is used before and during DDR initialization.
106  ******************************************************************************/
early_init_tzc400(void)107 static void early_init_tzc400(void)
108 {
109 	stm32mp_clk_enable(TZC1);
110 	stm32mp_clk_enable(TZC2);
111 
112 	/* Region 0 set to cover all DRAM secure at 0xC000_0000 */
113 	init_tzc400_begin(TZC_REGION_S_RDWR);
114 
115 	/* Raise an exception if a NS device tries to access secure memory */
116 	init_tzc400_end(TZC_ACTION_ERR);
117 }
118 
119 /*******************************************************************************
120  * Initialize the secure environment. At this moment only the TrustZone
121  * Controller is initialized.
122  ******************************************************************************/
stm32mp1_arch_security_setup(void)123 void stm32mp1_arch_security_setup(void)
124 {
125 	early_init_tzc400();
126 }
127 
128 /*******************************************************************************
129  * Initialize the secure environment. At this moment only the TrustZone
130  * Controller is initialized.
131  ******************************************************************************/
stm32mp1_security_setup(void)132 void stm32mp1_security_setup(void)
133 {
134 	init_tzc400();
135 }
136