blob: 2a518e19db7d5f2c8ea0154742a0d070c71b33a8 [file] [log] [blame]
Etienne Carriere7ad2c012019-12-08 08:14:03 +01001/*
Yann Gautier37bea082022-02-14 11:10:59 +01002 * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
Etienne Carriere7ad2c012019-12-08 08:14:03 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Etienne Carrierebeb53d92020-05-13 10:13:54 +02007#include <assert.h>
8#include <stdint.h>
9
Etienne Carrierebeb53d92020-05-13 10:13:54 +020010#include <common/debug.h>
Etienne Carriere7a4a34f2020-05-13 10:07:45 +020011#include <drivers/st/etzpc.h>
Etienne Carrierebeb53d92020-05-13 10:13:54 +020012#include <drivers/st/stm32_gpio.h>
13
Yann Gautier37bea082022-02-14 11:10:59 +010014#include <platform_def.h>
Etienne Carriere7ad2c012019-12-08 08:14:03 +010015#include <stm32mp_shared_resources.h>
16
Etienne Carriere7a4a34f2020-05-13 10:07:45 +020017/*
18 * Once one starts to get the resource registering state, one cannot register
19 * new resources. This ensures resource state cannot change.
20 */
21static bool registering_locked;
22
23/*
24 * Shared peripherals and resources registration
25 *
26 * Each resource assignation is stored in a table. The state defaults
27 * to PERIPH_UNREGISTERED if the resource is not explicitly assigned.
28 *
29 * Resource driver that as not embedded (a.k.a their related CFG_xxx build
30 * directive is disabled) are assigned to the non-secure world.
31 *
32 * Each pin of the GPIOZ bank can be secure or non-secure.
33 *
34 * It is the platform responsibility the ensure resource assignation
35 * matches the access permission firewalls configuration.
36 */
37enum shres_state {
38 SHRES_UNREGISTERED = 0,
39 SHRES_SECURE,
40 SHRES_NON_SECURE,
41};
42
43/* Force uint8_t array for array of enum shres_state for size considerations */
44static uint8_t shres_state[STM32MP1_SHRES_COUNT];
45
Etienne Carrieree704f992020-05-13 15:51:56 +020046static const char *shres2str_id_tbl[STM32MP1_SHRES_COUNT] __unused = {
47 [STM32MP1_SHRES_GPIOZ(0)] = "GPIOZ0",
48 [STM32MP1_SHRES_GPIOZ(1)] = "GPIOZ1",
49 [STM32MP1_SHRES_GPIOZ(2)] = "GPIOZ2",
50 [STM32MP1_SHRES_GPIOZ(3)] = "GPIOZ3",
51 [STM32MP1_SHRES_GPIOZ(4)] = "GPIOZ4",
52 [STM32MP1_SHRES_GPIOZ(5)] = "GPIOZ5",
53 [STM32MP1_SHRES_GPIOZ(6)] = "GPIOZ6",
54 [STM32MP1_SHRES_GPIOZ(7)] = "GPIOZ7",
55 [STM32MP1_SHRES_IWDG1] = "IWDG1",
56 [STM32MP1_SHRES_USART1] = "USART1",
57 [STM32MP1_SHRES_SPI6] = "SPI6",
58 [STM32MP1_SHRES_I2C4] = "I2C4",
59 [STM32MP1_SHRES_RNG1] = "RNG1",
60 [STM32MP1_SHRES_HASH1] = "HASH1",
61 [STM32MP1_SHRES_CRYP1] = "CRYP1",
62 [STM32MP1_SHRES_I2C6] = "I2C6",
63 [STM32MP1_SHRES_RTC] = "RTC",
64 [STM32MP1_SHRES_MCU] = "MCU",
65 [STM32MP1_SHRES_MDMA] = "MDMA",
66 [STM32MP1_SHRES_PLL3] = "PLL3",
67};
68
69static const char __unused *shres2str_id(enum stm32mp_shres id)
70{
71 assert(id < ARRAY_SIZE(shres2str_id_tbl));
72
73 return shres2str_id_tbl[id];
74}
75
76static const char __unused *shres2str_state_tbl[] = {
77 [SHRES_UNREGISTERED] = "unregistered",
78 [SHRES_NON_SECURE] = "non-secure",
79 [SHRES_SECURE] = "secure",
80};
81
82static const char __unused *shres2str_state(unsigned int state)
83{
84 assert(state < ARRAY_SIZE(shres2str_state_tbl));
85
86 return shres2str_state_tbl[state];
87}
88
Etienne Carriere7a4a34f2020-05-13 10:07:45 +020089/* Get resource state: these accesses lock the registering support */
90static void lock_registering(void)
91{
92 registering_locked = true;
93}
94
95static bool periph_is_non_secure(enum stm32mp_shres id)
96{
97 lock_registering();
98
99 return (shres_state[id] == SHRES_NON_SECURE) ||
100 (shres_state[id] == SHRES_UNREGISTERED);
101}
102
103static bool periph_is_secure(enum stm32mp_shres id)
104{
105 return !periph_is_non_secure(id);
106}
107
Etienne Carrierebeb53d92020-05-13 10:13:54 +0200108/* GPIOZ pin count is saved in RAM to prevent parsing FDT several times */
109static int8_t gpioz_nbpin = -1;
110
111static unsigned int get_gpio_nbpin(unsigned int bank)
112{
113 if (bank != GPIO_BANK_Z) {
114 int count = fdt_get_gpio_bank_pin_count(bank);
115
Yann Gautier466be2c2020-11-10 15:08:37 +0100116 assert((count >= 0) && ((unsigned int)count <= (GPIO_PIN_MAX + 1)));
Etienne Carrierebeb53d92020-05-13 10:13:54 +0200117
118 return (unsigned int)count;
119 }
120
121 if (gpioz_nbpin < 0) {
122 int count = fdt_get_gpio_bank_pin_count(GPIO_BANK_Z);
123
124 assert((count == 0) || (count == STM32MP_GPIOZ_PIN_MAX_COUNT));
125
126 gpioz_nbpin = count;
127 }
128
129 return (unsigned int)gpioz_nbpin;
130}
131
Etienne Carriere7a4a34f2020-05-13 10:07:45 +0200132static unsigned int get_gpioz_nbpin(void)
Etienne Carrierebeb53d92020-05-13 10:13:54 +0200133{
134 return get_gpio_nbpin(GPIO_BANK_Z);
135}
136
Etienne Carriere1bbb9242020-05-13 14:22:01 +0200137static void register_periph(enum stm32mp_shres id, unsigned int state)
138{
139 assert((id < STM32MP1_SHRES_COUNT) &&
140 ((state == SHRES_SECURE) || (state == SHRES_NON_SECURE)));
141
142 if (registering_locked) {
143 if (shres_state[id] == state) {
144 return;
145 }
146 panic();
147 }
148
149 if ((shres_state[id] != SHRES_UNREGISTERED) &&
150 (shres_state[id] != state)) {
151 VERBOSE("Cannot change %s from %s to %s\n",
152 shres2str_id(id),
153 shres2str_state(shres_state[id]),
154 shres2str_state(state));
155 panic();
156 }
157
158 if (shres_state[id] == SHRES_UNREGISTERED) {
159 VERBOSE("Register %s as %s\n",
160 shres2str_id(id), shres2str_state(state));
161 }
162
163 if ((id >= STM32MP1_SHRES_GPIOZ(0)) &&
164 (id <= STM32MP1_SHRES_GPIOZ(7)) &&
Yann Gautier466be2c2020-11-10 15:08:37 +0100165 ((unsigned int)(id - STM32MP1_SHRES_GPIOZ(0)) >= get_gpioz_nbpin())) {
Yann Gautier37bea082022-02-14 11:10:59 +0100166 ERROR("Invalid GPIO pin %d, %u pin(s) available\n",
Etienne Carriere1bbb9242020-05-13 14:22:01 +0200167 id - STM32MP1_SHRES_GPIOZ(0), get_gpioz_nbpin());
168 panic();
169 }
170
171 shres_state[id] = (uint8_t)state;
172
173 /* Explore clock tree to lock dependencies */
174 if (state == SHRES_SECURE) {
175 enum stm32mp_shres clock_res_id;
176
177 switch (id) {
178 case STM32MP1_SHRES_GPIOZ(0):
179 case STM32MP1_SHRES_GPIOZ(1):
180 case STM32MP1_SHRES_GPIOZ(2):
181 case STM32MP1_SHRES_GPIOZ(3):
182 case STM32MP1_SHRES_GPIOZ(4):
183 case STM32MP1_SHRES_GPIOZ(5):
184 case STM32MP1_SHRES_GPIOZ(6):
185 case STM32MP1_SHRES_GPIOZ(7):
186 clock_res_id = GPIOZ;
187 break;
188 case STM32MP1_SHRES_IWDG1:
189 clock_res_id = IWDG1;
190 break;
191 case STM32MP1_SHRES_USART1:
192 clock_res_id = USART1_K;
193 break;
194 case STM32MP1_SHRES_SPI6:
195 clock_res_id = SPI6_K;
196 break;
197 case STM32MP1_SHRES_I2C4:
198 clock_res_id = I2C4_K;
199 break;
200 case STM32MP1_SHRES_RNG1:
201 clock_res_id = RNG1_K;
202 break;
203 case STM32MP1_SHRES_HASH1:
204 clock_res_id = HASH1;
205 break;
206 case STM32MP1_SHRES_CRYP1:
207 clock_res_id = CRYP1;
208 break;
209 case STM32MP1_SHRES_I2C6:
210 clock_res_id = I2C6_K;
211 break;
212 case STM32MP1_SHRES_RTC:
213 clock_res_id = RTC;
214 break;
215 default:
216 /* No clock resource dependency */
217 return;
218 }
219
220 stm32mp1_register_clock_parents_secure(clock_res_id);
221 }
222}
223
224/* Register resource by ID */
225void stm32mp_register_secure_periph(enum stm32mp_shres id)
226{
227 register_periph(id, SHRES_SECURE);
228}
229
230void stm32mp_register_non_secure_periph(enum stm32mp_shres id)
231{
232 register_periph(id, SHRES_NON_SECURE);
233}
234
Etienne Carriere0cfbff92020-05-13 10:16:21 +0200235static void register_periph_iomem(uintptr_t base, unsigned int state)
236{
237 enum stm32mp_shres id;
238
239 switch (base) {
240 case CRYP1_BASE:
241 id = STM32MP1_SHRES_CRYP1;
242 break;
243 case HASH1_BASE:
244 id = STM32MP1_SHRES_HASH1;
245 break;
246 case I2C4_BASE:
247 id = STM32MP1_SHRES_I2C4;
248 break;
249 case I2C6_BASE:
250 id = STM32MP1_SHRES_I2C6;
251 break;
252 case IWDG1_BASE:
253 id = STM32MP1_SHRES_IWDG1;
254 break;
255 case RNG1_BASE:
256 id = STM32MP1_SHRES_RNG1;
257 break;
258 case RTC_BASE:
259 id = STM32MP1_SHRES_RTC;
260 break;
261 case SPI6_BASE:
262 id = STM32MP1_SHRES_SPI6;
263 break;
264 case USART1_BASE:
265 id = STM32MP1_SHRES_USART1;
266 break;
267
268 case GPIOA_BASE:
269 case GPIOB_BASE:
270 case GPIOC_BASE:
271 case GPIOD_BASE:
272 case GPIOE_BASE:
273 case GPIOF_BASE:
274 case GPIOG_BASE:
275 case GPIOH_BASE:
276 case GPIOI_BASE:
277 case GPIOJ_BASE:
278 case GPIOK_BASE:
279 case USART2_BASE:
280 case USART3_BASE:
281 case UART4_BASE:
282 case UART5_BASE:
283 case USART6_BASE:
284 case UART7_BASE:
285 case UART8_BASE:
286 case IWDG2_BASE:
287 /* Allow drivers to register some non-secure resources */
288 VERBOSE("IO for non-secure resource 0x%x\n",
289 (unsigned int)base);
290 if (state != SHRES_NON_SECURE) {
291 panic();
292 }
293
294 return;
295
296 default:
297 panic();
298 }
299
300 register_periph(id, state);
301}
302
303void stm32mp_register_secure_periph_iomem(uintptr_t base)
304{
305 register_periph_iomem(base, SHRES_SECURE);
306}
307
308void stm32mp_register_non_secure_periph_iomem(uintptr_t base)
309{
310 register_periph_iomem(base, SHRES_NON_SECURE);
311}
312
Etienne Carriere63b22062020-05-13 10:19:50 +0200313void stm32mp_register_secure_gpio(unsigned int bank, unsigned int pin)
314{
315 switch (bank) {
316 case GPIO_BANK_Z:
317 register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_SECURE);
318 break;
319 default:
320 ERROR("GPIO bank %u cannot be secured\n", bank);
321 panic();
322 }
323}
324
325void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin)
326{
327 switch (bank) {
328 case GPIO_BANK_Z:
329 register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_NON_SECURE);
330 break;
331 default:
332 break;
333 }
334}
335
Etienne Carrierec8d47a72020-05-13 13:53:15 +0200336static bool stm32mp_gpio_bank_is_non_secure(unsigned int bank)
337{
338 unsigned int non_secure = 0U;
339 unsigned int i;
340
341 lock_registering();
342
343 if (bank != GPIO_BANK_Z) {
344 return true;
345 }
346
347 for (i = 0U; i < get_gpioz_nbpin(); i++) {
348 if (periph_is_non_secure(STM32MP1_SHRES_GPIOZ(i))) {
349 non_secure++;
350 }
351 }
352
353 return non_secure == get_gpioz_nbpin();
354}
355
Etienne Carriere875f85a2020-05-13 10:20:34 +0200356static bool stm32mp_gpio_bank_is_secure(unsigned int bank)
357{
358 unsigned int secure = 0U;
359 unsigned int i;
360
361 lock_registering();
362
363 if (bank != GPIO_BANK_Z) {
364 return false;
365 }
366
367 for (i = 0U; i < get_gpioz_nbpin(); i++) {
368 if (periph_is_secure(STM32MP1_SHRES_GPIOZ(i))) {
369 secure++;
370 }
371 }
372
373 return secure == get_gpioz_nbpin();
374}
375
Etienne Carriere7ad2c012019-12-08 08:14:03 +0100376bool stm32mp_nsec_can_access_clock(unsigned long clock_id)
377{
Etienne Carriere875f85a2020-05-13 10:20:34 +0200378 enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT;
379
380 switch (clock_id) {
381 case CK_CSI:
382 case CK_HSE:
383 case CK_HSE_DIV2:
384 case CK_HSI:
385 case CK_LSE:
386 case CK_LSI:
387 case PLL1_P:
388 case PLL1_Q:
389 case PLL1_R:
390 case PLL2_P:
391 case PLL2_Q:
392 case PLL2_R:
393 case PLL3_P:
394 case PLL3_Q:
395 case PLL3_R:
396 case RTCAPB:
397 return true;
398 case GPIOZ:
399 /* Allow clock access if at least one pin is non-secure */
400 return !stm32mp_gpio_bank_is_secure(GPIO_BANK_Z);
401 case CRYP1:
402 shres_id = STM32MP1_SHRES_CRYP1;
403 break;
404 case HASH1:
405 shres_id = STM32MP1_SHRES_HASH1;
406 break;
407 case I2C4_K:
408 shres_id = STM32MP1_SHRES_I2C4;
409 break;
410 case I2C6_K:
411 shres_id = STM32MP1_SHRES_I2C6;
412 break;
413 case IWDG1:
414 shres_id = STM32MP1_SHRES_IWDG1;
415 break;
416 case RNG1_K:
417 shres_id = STM32MP1_SHRES_RNG1;
418 break;
419 case RTC:
420 shres_id = STM32MP1_SHRES_RTC;
421 break;
422 case SPI6_K:
423 shres_id = STM32MP1_SHRES_SPI6;
424 break;
425 case USART1_K:
426 shres_id = STM32MP1_SHRES_USART1;
427 break;
428 default:
429 return false;
430 }
431
432 return periph_is_non_secure(shres_id);
Etienne Carriere7ad2c012019-12-08 08:14:03 +0100433}
434
Etienne Carriere7ad2c012019-12-08 08:14:03 +0100435bool stm32mp_nsec_can_access_reset(unsigned int reset_id)
436{
Etienne Carrierec8d47a72020-05-13 13:53:15 +0200437 enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT;
438
439 switch (reset_id) {
440 case CRYP1_R:
441 shres_id = STM32MP1_SHRES_CRYP1;
442 break;
443 case GPIOZ_R:
444 /* GPIOZ reset mandates all pins are non-secure */
445 return stm32mp_gpio_bank_is_non_secure(GPIO_BANK_Z);
446 case HASH1_R:
447 shres_id = STM32MP1_SHRES_HASH1;
448 break;
449 case I2C4_R:
450 shres_id = STM32MP1_SHRES_I2C4;
451 break;
452 case I2C6_R:
453 shres_id = STM32MP1_SHRES_I2C6;
454 break;
455 case MCU_R:
456 shres_id = STM32MP1_SHRES_MCU;
457 break;
458 case MDMA_R:
459 shres_id = STM32MP1_SHRES_MDMA;
460 break;
461 case RNG1_R:
462 shres_id = STM32MP1_SHRES_RNG1;
463 break;
464 case SPI6_R:
465 shres_id = STM32MP1_SHRES_SPI6;
466 break;
467 case USART1_R:
468 shres_id = STM32MP1_SHRES_USART1;
469 break;
470 default:
471 return false;
472 }
473
474 return periph_is_non_secure(shres_id);
Etienne Carriere7ad2c012019-12-08 08:14:03 +0100475}
Etienne Carriere7a4a34f2020-05-13 10:07:45 +0200476
477static bool mckprot_protects_periph(enum stm32mp_shres id)
478{
479 switch (id) {
480 case STM32MP1_SHRES_MCU:
481 case STM32MP1_SHRES_PLL3:
482 return true;
483 default:
484 return false;
485 }
486}
487
488/* ETZPC configuration at drivers initialization completion */
489static enum etzpc_decprot_attributes shres2decprot_attr(enum stm32mp_shres id)
490{
491 assert((id < STM32MP1_SHRES_GPIOZ(0)) ||
492 (id > STM32MP1_SHRES_GPIOZ(7)));
493
494 if (periph_is_non_secure(id)) {
495 return ETZPC_DECPROT_NS_RW;
496 }
497
498 return ETZPC_DECPROT_S_RW;
499}
500
501static void set_etzpc_secure_configuration(void)
502{
503 /* Some system peripherals shall be secure */
504 etzpc_configure_decprot(STM32MP1_ETZPC_STGENC_ID, ETZPC_DECPROT_S_RW);
505 etzpc_configure_decprot(STM32MP1_ETZPC_BKPSRAM_ID, ETZPC_DECPROT_S_RW);
506 etzpc_configure_decprot(STM32MP1_ETZPC_DDRCTRL_ID,
507 ETZPC_DECPROT_NS_R_S_W);
508 etzpc_configure_decprot(STM32MP1_ETZPC_DDRPHYC_ID,
509 ETZPC_DECPROT_NS_R_S_W);
510
511 /* Configure ETZPC with peripheral registering */
512 etzpc_configure_decprot(STM32MP1_ETZPC_CRYP1_ID,
513 shres2decprot_attr(STM32MP1_SHRES_CRYP1));
514 etzpc_configure_decprot(STM32MP1_ETZPC_HASH1_ID,
515 shres2decprot_attr(STM32MP1_SHRES_HASH1));
516 etzpc_configure_decprot(STM32MP1_ETZPC_I2C4_ID,
517 shres2decprot_attr(STM32MP1_SHRES_I2C4));
518 etzpc_configure_decprot(STM32MP1_ETZPC_I2C6_ID,
519 shres2decprot_attr(STM32MP1_SHRES_I2C6));
520 etzpc_configure_decprot(STM32MP1_ETZPC_IWDG1_ID,
521 shres2decprot_attr(STM32MP1_SHRES_IWDG1));
522 etzpc_configure_decprot(STM32MP1_ETZPC_RNG1_ID,
523 shres2decprot_attr(STM32MP1_SHRES_RNG1));
524 etzpc_configure_decprot(STM32MP1_ETZPC_USART1_ID,
525 shres2decprot_attr(STM32MP1_SHRES_USART1));
526 etzpc_configure_decprot(STM32MP1_ETZPC_SPI6_ID,
527 shres2decprot_attr(STM32MP1_SHRES_SPI6));
528}
529
530static void check_rcc_secure_configuration(void)
531{
532 uint32_t n;
533 uint32_t error = 0U;
534 bool mckprot = stm32mp1_rcc_is_mckprot();
535 bool secure = stm32mp1_rcc_is_secure();
536
537 for (n = 0U; n < ARRAY_SIZE(shres_state); n++) {
538 if (shres_state[n] != SHRES_SECURE) {
539 continue;
540 }
541
542 if (!secure || (mckprot_protects_periph(n) && (!mckprot))) {
Etienne Carrieree704f992020-05-13 15:51:56 +0200543 ERROR("RCC %s MCKPROT %s and %s secure\n",
Etienne Carriere7a4a34f2020-05-13 10:07:45 +0200544 secure ? "secure" : "non-secure",
545 mckprot ? "set" : "not set",
Etienne Carrieree704f992020-05-13 15:51:56 +0200546 shres2str_id(n));
Etienne Carriere7a4a34f2020-05-13 10:07:45 +0200547 error++;
548 }
549 }
550
551 if (error != 0U) {
552 panic();
553 }
554}
555
556static void set_gpio_secure_configuration(void)
557{
558 uint32_t pin;
559
560 for (pin = 0U; pin < get_gpioz_nbpin(); pin++) {
561 bool secure_state = periph_is_secure(STM32MP1_SHRES_GPIOZ(pin));
562
563 set_gpio_secure_cfg(GPIO_BANK_Z, pin, secure_state);
564 }
565}
566
567static void print_shared_resources_state(void)
568{
569 unsigned int id;
570
571 for (id = 0U; id < STM32MP1_SHRES_COUNT; id++) {
572 switch (shres_state[id]) {
573 case SHRES_SECURE:
Etienne Carrieree704f992020-05-13 15:51:56 +0200574 INFO("stm32mp1 %s is secure\n", shres2str_id(id));
Etienne Carriere7a4a34f2020-05-13 10:07:45 +0200575 break;
576 case SHRES_NON_SECURE:
577 case SHRES_UNREGISTERED:
Etienne Carrieree704f992020-05-13 15:51:56 +0200578 VERBOSE("stm32mp %s is non-secure\n", shres2str_id(id));
Etienne Carriere7a4a34f2020-05-13 10:07:45 +0200579 break;
580 default:
Etienne Carrieree704f992020-05-13 15:51:56 +0200581 VERBOSE("stm32mp %s is invalid\n", shres2str_id(id));
Etienne Carriere7a4a34f2020-05-13 10:07:45 +0200582 panic();
583 }
584 }
585}
586
587void stm32mp_lock_periph_registering(void)
588{
589 registering_locked = true;
590
591 print_shared_resources_state();
592
593 check_rcc_secure_configuration();
594 set_etzpc_secure_configuration();
595 set_gpio_secure_configuration();
596}