xref: /rk3399_ARM-atf/plat/st/stm32mp1/stm32mp1_shared_resources.c (revision ac6b3b285ab147e528a39d8e5d1dc9f5a218ed1e)
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 static const char *shres2str_id_tbl[STM32MP1_SHRES_COUNT] __unused = {
48 	[STM32MP1_SHRES_GPIOZ(0)] = "GPIOZ0",
49 	[STM32MP1_SHRES_GPIOZ(1)] = "GPIOZ1",
50 	[STM32MP1_SHRES_GPIOZ(2)] = "GPIOZ2",
51 	[STM32MP1_SHRES_GPIOZ(3)] = "GPIOZ3",
52 	[STM32MP1_SHRES_GPIOZ(4)] = "GPIOZ4",
53 	[STM32MP1_SHRES_GPIOZ(5)] = "GPIOZ5",
54 	[STM32MP1_SHRES_GPIOZ(6)] = "GPIOZ6",
55 	[STM32MP1_SHRES_GPIOZ(7)] = "GPIOZ7",
56 	[STM32MP1_SHRES_IWDG1] = "IWDG1",
57 	[STM32MP1_SHRES_USART1] = "USART1",
58 	[STM32MP1_SHRES_SPI6] = "SPI6",
59 	[STM32MP1_SHRES_I2C4] = "I2C4",
60 	[STM32MP1_SHRES_RNG1] = "RNG1",
61 	[STM32MP1_SHRES_HASH1] = "HASH1",
62 	[STM32MP1_SHRES_CRYP1] = "CRYP1",
63 	[STM32MP1_SHRES_I2C6] = "I2C6",
64 	[STM32MP1_SHRES_RTC] = "RTC",
65 	[STM32MP1_SHRES_MCU] = "MCU",
66 	[STM32MP1_SHRES_MDMA] = "MDMA",
67 	[STM32MP1_SHRES_PLL3] = "PLL3",
68 };
69 
70 static const char __unused *shres2str_id(enum stm32mp_shres id)
71 {
72 	assert(id < ARRAY_SIZE(shres2str_id_tbl));
73 
74 	return shres2str_id_tbl[id];
75 }
76 
77 static const char __unused *shres2str_state_tbl[] = {
78 	[SHRES_UNREGISTERED] = "unregistered",
79 	[SHRES_NON_SECURE] = "non-secure",
80 	[SHRES_SECURE] = "secure",
81 };
82 
83 static const char __unused *shres2str_state(unsigned int state)
84 {
85 	assert(state < ARRAY_SIZE(shres2str_state_tbl));
86 
87 	return shres2str_state_tbl[state];
88 }
89 
90 /* Get resource state: these accesses lock the registering support */
91 static void lock_registering(void)
92 {
93 	registering_locked = true;
94 }
95 
96 static bool periph_is_non_secure(enum stm32mp_shres id)
97 {
98 	lock_registering();
99 
100 	return (shres_state[id] == SHRES_NON_SECURE) ||
101 	       (shres_state[id] == SHRES_UNREGISTERED);
102 }
103 
104 static bool periph_is_secure(enum stm32mp_shres id)
105 {
106 	return !periph_is_non_secure(id);
107 }
108 
109 /* GPIOZ pin count is saved in RAM to prevent parsing FDT several times */
110 static int8_t gpioz_nbpin = -1;
111 
112 static unsigned int get_gpio_nbpin(unsigned int bank)
113 {
114 	if (bank != GPIO_BANK_Z) {
115 		int count = fdt_get_gpio_bank_pin_count(bank);
116 
117 		assert((count >= 0) || (count <= (GPIO_PIN_MAX + 1)));
118 
119 		return (unsigned int)count;
120 	}
121 
122 	if (gpioz_nbpin < 0) {
123 		int count = fdt_get_gpio_bank_pin_count(GPIO_BANK_Z);
124 
125 		assert((count == 0) || (count == STM32MP_GPIOZ_PIN_MAX_COUNT));
126 
127 		gpioz_nbpin = count;
128 	}
129 
130 	return (unsigned int)gpioz_nbpin;
131 }
132 
133 static unsigned int get_gpioz_nbpin(void)
134 {
135 	return get_gpio_nbpin(GPIO_BANK_Z);
136 }
137 
138 static void register_periph(enum stm32mp_shres id, unsigned int state)
139 {
140 	assert((id < STM32MP1_SHRES_COUNT) &&
141 	       ((state == SHRES_SECURE) || (state == SHRES_NON_SECURE)));
142 
143 	if (registering_locked) {
144 		if (shres_state[id] == state) {
145 			return;
146 		}
147 		panic();
148 	}
149 
150 	if ((shres_state[id] != SHRES_UNREGISTERED) &&
151 	    (shres_state[id] != state)) {
152 		VERBOSE("Cannot change %s from %s to %s\n",
153 			shres2str_id(id),
154 			shres2str_state(shres_state[id]),
155 			shres2str_state(state));
156 		panic();
157 	}
158 
159 	if (shres_state[id] == SHRES_UNREGISTERED) {
160 		VERBOSE("Register %s as %s\n",
161 			shres2str_id(id), shres2str_state(state));
162 	}
163 
164 	if ((id >= STM32MP1_SHRES_GPIOZ(0)) &&
165 	    (id <= STM32MP1_SHRES_GPIOZ(7)) &&
166 	    ((id - STM32MP1_SHRES_GPIOZ(0)) >= get_gpioz_nbpin())) {
167 		ERROR("Invalid GPIO pin %u, %u pin(s) available\n",
168 		      id - STM32MP1_SHRES_GPIOZ(0), get_gpioz_nbpin());
169 		panic();
170 	}
171 
172 	shres_state[id] = (uint8_t)state;
173 
174 	/* Explore clock tree to lock dependencies */
175 	if (state == SHRES_SECURE) {
176 		enum stm32mp_shres clock_res_id;
177 
178 		switch (id) {
179 		case STM32MP1_SHRES_GPIOZ(0):
180 		case STM32MP1_SHRES_GPIOZ(1):
181 		case STM32MP1_SHRES_GPIOZ(2):
182 		case STM32MP1_SHRES_GPIOZ(3):
183 		case STM32MP1_SHRES_GPIOZ(4):
184 		case STM32MP1_SHRES_GPIOZ(5):
185 		case STM32MP1_SHRES_GPIOZ(6):
186 		case STM32MP1_SHRES_GPIOZ(7):
187 			clock_res_id = GPIOZ;
188 			break;
189 		case STM32MP1_SHRES_IWDG1:
190 			clock_res_id = IWDG1;
191 			break;
192 		case STM32MP1_SHRES_USART1:
193 			clock_res_id = USART1_K;
194 			break;
195 		case STM32MP1_SHRES_SPI6:
196 			clock_res_id = SPI6_K;
197 			break;
198 		case STM32MP1_SHRES_I2C4:
199 			clock_res_id = I2C4_K;
200 			break;
201 		case STM32MP1_SHRES_RNG1:
202 			clock_res_id = RNG1_K;
203 			break;
204 		case STM32MP1_SHRES_HASH1:
205 			clock_res_id = HASH1;
206 			break;
207 		case STM32MP1_SHRES_CRYP1:
208 			clock_res_id = CRYP1;
209 			break;
210 		case STM32MP1_SHRES_I2C6:
211 			clock_res_id = I2C6_K;
212 			break;
213 		case STM32MP1_SHRES_RTC:
214 			clock_res_id = RTC;
215 			break;
216 		default:
217 			/* No clock resource dependency */
218 			return;
219 		}
220 
221 		stm32mp1_register_clock_parents_secure(clock_res_id);
222 	}
223 }
224 
225 /* Register resource by ID */
226 void stm32mp_register_secure_periph(enum stm32mp_shres id)
227 {
228 	register_periph(id, SHRES_SECURE);
229 }
230 
231 void stm32mp_register_non_secure_periph(enum stm32mp_shres id)
232 {
233 	register_periph(id, SHRES_NON_SECURE);
234 }
235 
236 /* Currently allow full access by non-secure to platform clock services */
237 bool stm32mp_nsec_can_access_clock(unsigned long clock_id)
238 {
239 	return true;
240 }
241 
242 /* Currently allow full access by non-secure to platform reset services */
243 bool stm32mp_nsec_can_access_reset(unsigned int reset_id)
244 {
245 	return true;
246 }
247 
248 static bool mckprot_protects_periph(enum stm32mp_shres id)
249 {
250 	switch (id) {
251 	case STM32MP1_SHRES_MCU:
252 	case STM32MP1_SHRES_PLL3:
253 		return true;
254 	default:
255 		return false;
256 	}
257 }
258 
259 /* ETZPC configuration at drivers initialization completion */
260 static enum etzpc_decprot_attributes shres2decprot_attr(enum stm32mp_shres id)
261 {
262 	assert((id < STM32MP1_SHRES_GPIOZ(0)) ||
263 	       (id > STM32MP1_SHRES_GPIOZ(7)));
264 
265 	if (periph_is_non_secure(id)) {
266 		return ETZPC_DECPROT_NS_RW;
267 	}
268 
269 	return ETZPC_DECPROT_S_RW;
270 }
271 
272 static void set_etzpc_secure_configuration(void)
273 {
274 	/* Some system peripherals shall be secure */
275 	etzpc_configure_decprot(STM32MP1_ETZPC_STGENC_ID, ETZPC_DECPROT_S_RW);
276 	etzpc_configure_decprot(STM32MP1_ETZPC_BKPSRAM_ID, ETZPC_DECPROT_S_RW);
277 	etzpc_configure_decprot(STM32MP1_ETZPC_DDRCTRL_ID,
278 				ETZPC_DECPROT_NS_R_S_W);
279 	etzpc_configure_decprot(STM32MP1_ETZPC_DDRPHYC_ID,
280 				ETZPC_DECPROT_NS_R_S_W);
281 
282 	/* Configure ETZPC with peripheral registering */
283 	etzpc_configure_decprot(STM32MP1_ETZPC_CRYP1_ID,
284 				shres2decprot_attr(STM32MP1_SHRES_CRYP1));
285 	etzpc_configure_decprot(STM32MP1_ETZPC_HASH1_ID,
286 				shres2decprot_attr(STM32MP1_SHRES_HASH1));
287 	etzpc_configure_decprot(STM32MP1_ETZPC_I2C4_ID,
288 				shres2decprot_attr(STM32MP1_SHRES_I2C4));
289 	etzpc_configure_decprot(STM32MP1_ETZPC_I2C6_ID,
290 				shres2decprot_attr(STM32MP1_SHRES_I2C6));
291 	etzpc_configure_decprot(STM32MP1_ETZPC_IWDG1_ID,
292 				shres2decprot_attr(STM32MP1_SHRES_IWDG1));
293 	etzpc_configure_decprot(STM32MP1_ETZPC_RNG1_ID,
294 				shres2decprot_attr(STM32MP1_SHRES_RNG1));
295 	etzpc_configure_decprot(STM32MP1_ETZPC_USART1_ID,
296 				shres2decprot_attr(STM32MP1_SHRES_USART1));
297 	etzpc_configure_decprot(STM32MP1_ETZPC_SPI6_ID,
298 				shres2decprot_attr(STM32MP1_SHRES_SPI6));
299 }
300 
301 static void check_rcc_secure_configuration(void)
302 {
303 	uint32_t n;
304 	uint32_t error = 0U;
305 	bool mckprot = stm32mp1_rcc_is_mckprot();
306 	bool secure = stm32mp1_rcc_is_secure();
307 
308 	for (n = 0U; n < ARRAY_SIZE(shres_state); n++) {
309 		if (shres_state[n] != SHRES_SECURE) {
310 			continue;
311 		}
312 
313 		if (!secure || (mckprot_protects_periph(n) && (!mckprot))) {
314 			ERROR("RCC %s MCKPROT %s and %s secure\n",
315 			      secure ? "secure" : "non-secure",
316 			      mckprot ? "set" : "not set",
317 			      shres2str_id(n));
318 			error++;
319 		}
320 	}
321 
322 	if (error != 0U) {
323 		panic();
324 	}
325 }
326 
327 static void set_gpio_secure_configuration(void)
328 {
329 	uint32_t pin;
330 
331 	for (pin = 0U; pin < get_gpioz_nbpin(); pin++) {
332 		bool secure_state = periph_is_secure(STM32MP1_SHRES_GPIOZ(pin));
333 
334 		set_gpio_secure_cfg(GPIO_BANK_Z, pin, secure_state);
335 	}
336 }
337 
338 static void print_shared_resources_state(void)
339 {
340 	unsigned int id;
341 
342 	for (id = 0U; id < STM32MP1_SHRES_COUNT; id++) {
343 		switch (shres_state[id]) {
344 		case SHRES_SECURE:
345 			INFO("stm32mp1 %s is secure\n", shres2str_id(id));
346 			break;
347 		case SHRES_NON_SECURE:
348 		case SHRES_UNREGISTERED:
349 			VERBOSE("stm32mp %s is non-secure\n", shres2str_id(id));
350 			break;
351 		default:
352 			VERBOSE("stm32mp %s is invalid\n", shres2str_id(id));
353 			panic();
354 		}
355 	}
356 }
357 
358 void stm32mp_lock_periph_registering(void)
359 {
360 	registering_locked = true;
361 
362 	print_shared_resources_state();
363 
364 	check_rcc_secure_configuration();
365 	set_etzpc_secure_configuration();
366 	set_gpio_secure_configuration();
367 }
368