xref: /rk3399_ARM-atf/plat/st/stm32mp1/stm32mp1_shared_resources.c (revision 5f038ac6836359b3422a5b70e52733c6029f61b2)
1 /*
2  * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <stdint.h>
9 
10 #include <platform_def.h>
11 
12 #include <common/debug.h>
13 #include <drivers/st/etzpc.h>
14 #include <drivers/st/stm32_gpio.h>
15 
16 #include <stm32mp_shared_resources.h>
17 
18 /*
19  * Once one starts to get the resource registering state, one cannot register
20  * new resources. This ensures resource state cannot change.
21  */
22 static bool registering_locked;
23 
24 /*
25  * Shared peripherals and resources registration
26  *
27  * Each resource assignation is stored in a table. The state defaults
28  * to PERIPH_UNREGISTERED if the resource is not explicitly assigned.
29  *
30  * Resource driver that as not embedded (a.k.a their related CFG_xxx build
31  * directive is disabled) are assigned to the non-secure world.
32  *
33  * Each pin of the GPIOZ bank can be secure or non-secure.
34  *
35  * It is the platform responsibility the ensure resource assignation
36  * matches the access permission firewalls configuration.
37  */
38 enum shres_state {
39 	SHRES_UNREGISTERED = 0,
40 	SHRES_SECURE,
41 	SHRES_NON_SECURE,
42 };
43 
44 /* Force uint8_t array for array of enum shres_state for size considerations */
45 static uint8_t shres_state[STM32MP1_SHRES_COUNT];
46 
47 /* Get resource state: these accesses lock the registering support */
48 static void lock_registering(void)
49 {
50 	registering_locked = true;
51 }
52 
53 static bool periph_is_non_secure(enum stm32mp_shres id)
54 {
55 	lock_registering();
56 
57 	return (shres_state[id] == SHRES_NON_SECURE) ||
58 	       (shres_state[id] == SHRES_UNREGISTERED);
59 }
60 
61 static bool periph_is_secure(enum stm32mp_shres id)
62 {
63 	return !periph_is_non_secure(id);
64 }
65 
66 /* GPIOZ pin count is saved in RAM to prevent parsing FDT several times */
67 static int8_t gpioz_nbpin = -1;
68 
69 static unsigned int get_gpio_nbpin(unsigned int bank)
70 {
71 	if (bank != GPIO_BANK_Z) {
72 		int count = fdt_get_gpio_bank_pin_count(bank);
73 
74 		assert((count >= 0) || (count <= (GPIO_PIN_MAX + 1)));
75 
76 		return (unsigned int)count;
77 	}
78 
79 	if (gpioz_nbpin < 0) {
80 		int count = fdt_get_gpio_bank_pin_count(GPIO_BANK_Z);
81 
82 		assert((count == 0) || (count == STM32MP_GPIOZ_PIN_MAX_COUNT));
83 
84 		gpioz_nbpin = count;
85 	}
86 
87 	return (unsigned int)gpioz_nbpin;
88 }
89 
90 static unsigned int get_gpioz_nbpin(void)
91 {
92 	return get_gpio_nbpin(GPIO_BANK_Z);
93 }
94 
95 /* Currently allow full access by non-secure to platform clock services */
96 bool stm32mp_nsec_can_access_clock(unsigned long clock_id)
97 {
98 	return true;
99 }
100 
101 /* Currently allow full access by non-secure to platform reset services */
102 bool stm32mp_nsec_can_access_reset(unsigned int reset_id)
103 {
104 	return true;
105 }
106 
107 static bool mckprot_protects_periph(enum stm32mp_shres id)
108 {
109 	switch (id) {
110 	case STM32MP1_SHRES_MCU:
111 	case STM32MP1_SHRES_PLL3:
112 		return true;
113 	default:
114 		return false;
115 	}
116 }
117 
118 /* ETZPC configuration at drivers initialization completion */
119 static enum etzpc_decprot_attributes shres2decprot_attr(enum stm32mp_shres id)
120 {
121 	assert((id < STM32MP1_SHRES_GPIOZ(0)) ||
122 	       (id > STM32MP1_SHRES_GPIOZ(7)));
123 
124 	if (periph_is_non_secure(id)) {
125 		return ETZPC_DECPROT_NS_RW;
126 	}
127 
128 	return ETZPC_DECPROT_S_RW;
129 }
130 
131 static void set_etzpc_secure_configuration(void)
132 {
133 	/* Some system peripherals shall be secure */
134 	etzpc_configure_decprot(STM32MP1_ETZPC_STGENC_ID, ETZPC_DECPROT_S_RW);
135 	etzpc_configure_decprot(STM32MP1_ETZPC_BKPSRAM_ID, ETZPC_DECPROT_S_RW);
136 	etzpc_configure_decprot(STM32MP1_ETZPC_DDRCTRL_ID,
137 				ETZPC_DECPROT_NS_R_S_W);
138 	etzpc_configure_decprot(STM32MP1_ETZPC_DDRPHYC_ID,
139 				ETZPC_DECPROT_NS_R_S_W);
140 
141 	/* Configure ETZPC with peripheral registering */
142 	etzpc_configure_decprot(STM32MP1_ETZPC_CRYP1_ID,
143 				shres2decprot_attr(STM32MP1_SHRES_CRYP1));
144 	etzpc_configure_decprot(STM32MP1_ETZPC_HASH1_ID,
145 				shres2decprot_attr(STM32MP1_SHRES_HASH1));
146 	etzpc_configure_decprot(STM32MP1_ETZPC_I2C4_ID,
147 				shres2decprot_attr(STM32MP1_SHRES_I2C4));
148 	etzpc_configure_decprot(STM32MP1_ETZPC_I2C6_ID,
149 				shres2decprot_attr(STM32MP1_SHRES_I2C6));
150 	etzpc_configure_decprot(STM32MP1_ETZPC_IWDG1_ID,
151 				shres2decprot_attr(STM32MP1_SHRES_IWDG1));
152 	etzpc_configure_decprot(STM32MP1_ETZPC_RNG1_ID,
153 				shres2decprot_attr(STM32MP1_SHRES_RNG1));
154 	etzpc_configure_decprot(STM32MP1_ETZPC_USART1_ID,
155 				shres2decprot_attr(STM32MP1_SHRES_USART1));
156 	etzpc_configure_decprot(STM32MP1_ETZPC_SPI6_ID,
157 				shres2decprot_attr(STM32MP1_SHRES_SPI6));
158 }
159 
160 static void check_rcc_secure_configuration(void)
161 {
162 	uint32_t n;
163 	uint32_t error = 0U;
164 	bool mckprot = stm32mp1_rcc_is_mckprot();
165 	bool secure = stm32mp1_rcc_is_secure();
166 
167 	for (n = 0U; n < ARRAY_SIZE(shres_state); n++) {
168 		if (shres_state[n] != SHRES_SECURE) {
169 			continue;
170 		}
171 
172 		if (!secure || (mckprot_protects_periph(n) && (!mckprot))) {
173 			ERROR("RCC %s MCKPROT %s and %u secure\n",
174 			      secure ? "secure" : "non-secure",
175 			      mckprot ? "set" : "not set",
176 			      n);
177 			error++;
178 		}
179 	}
180 
181 	if (error != 0U) {
182 		panic();
183 	}
184 }
185 
186 static void set_gpio_secure_configuration(void)
187 {
188 	uint32_t pin;
189 
190 	for (pin = 0U; pin < get_gpioz_nbpin(); pin++) {
191 		bool secure_state = periph_is_secure(STM32MP1_SHRES_GPIOZ(pin));
192 
193 		set_gpio_secure_cfg(GPIO_BANK_Z, pin, secure_state);
194 	}
195 }
196 
197 static void print_shared_resources_state(void)
198 {
199 	unsigned int id;
200 
201 	for (id = 0U; id < STM32MP1_SHRES_COUNT; id++) {
202 		switch (shres_state[id]) {
203 		case SHRES_SECURE:
204 			INFO("stm32mp1 %u is secure\n", id);
205 			break;
206 		case SHRES_NON_SECURE:
207 		case SHRES_UNREGISTERED:
208 			VERBOSE("stm32mp %u is non-secure\n", id);
209 			break;
210 		default:
211 			VERBOSE("stm32mp %u is invalid\n", id);
212 			panic();
213 		}
214 	}
215 }
216 
217 void stm32mp_lock_periph_registering(void)
218 {
219 	registering_locked = true;
220 
221 	print_shared_resources_state();
222 
223 	check_rcc_secure_configuration();
224 	set_etzpc_secure_configuration();
225 	set_gpio_secure_configuration();
226 }
227