1 /*
2 * Copyright (c) 2017-2024, Arm Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "tfm_hal_device_header.h"
18 #include "fih.h"
19 #include "target_cfg.h"
20 #include "Driver_MPC.h"
21 #include "platform_retarget_dev.h"
22 #include "region_defs.h"
23 #include "tfm_plat_defs.h"
24 #include "region.h"
25
26 #ifdef PSA_API_TEST_IPC
27 #define PSA_FF_TEST_SECURE_UART2
28 #endif
29
30 #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
31
32 /* The section names come from the scatter file */
33 REGION_DECLARE(Load$$LR$$, LR_NS_PARTITION, $$Base);
34 REGION_DECLARE(Image$$, ER_VENEER, $$Base);
35 REGION_DECLARE(Image$$, VENEER_ALIGN, $$Limit);
36
37 #ifdef BL2
38 REGION_DECLARE(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base);
39 #endif /* BL2 */
40
41 const struct memory_region_limits memory_regions = {
42 .non_secure_code_start =
43 (uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
44 BL2_HEADER_SIZE,
45
46 .non_secure_partition_base =
47 (uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base),
48
49 .non_secure_partition_limit =
50 (uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
51 NS_PARTITION_SIZE - 1,
52
53 .veneer_base = (uint32_t)®ION_NAME(Image$$, ER_VENEER, $$Base),
54 .veneer_limit = (uint32_t)®ION_NAME(Image$$, VENEER_ALIGN, $$Limit),
55
56 #ifdef BL2
57 .secondary_partition_base =
58 (uint32_t)®ION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base),
59
60 .secondary_partition_limit =
61 (uint32_t)®ION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base) +
62 SECONDARY_PARTITION_SIZE - 1,
63 #endif /* BL2 */
64 };
65
66 /* Allows software, via SAU, to define the code region as a NSC */
67 #define NSCCFG_CODENSC 1
68
69 /* Import MPC driver */
70 extern ARM_DRIVER_MPC Driver_SRAM1_MPC, Driver_SRAM2_MPC;
71
72 /* Define Peripherals NS address range for the platform */
73 #define PERIPHERALS_BASE_NS_START (0x40000000)
74 #define PERIPHERALS_BASE_NS_END (0x4FFFFFFF)
75
76 /* Enable system reset request for CPU 0 */
77 #define ENABLE_CPU0_SYSTEM_RESET_REQUEST (1U << 4U)
78
79 /* To write into AIRCR register, 0x5FA value must be write to the VECTKEY field,
80 * otherwise the processor ignores the write.
81 */
82 #define SCB_AIRCR_WRITE_MASK ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos))
83
84 /* Debug configuration flags */
85 #define SPNIDEN_SEL_STATUS (0x01u << 7)
86 #define SPNIDEN_STATUS (0x01u << 6)
87 #define SPIDEN_SEL_STATUS (0x01u << 5)
88 #define SPIDEN_STATUS (0x01u << 4)
89 #define NIDEN_SEL_STATUS (0x01u << 3)
90 #define NIDEN_STATUS (0x01u << 2)
91 #define DBGEN_SEL_STATUS (0x01u << 1)
92 #define DBGEN_STATUS (0x01u << 0)
93
94 #define All_SEL_STATUS (SPNIDEN_SEL_STATUS | SPIDEN_SEL_STATUS | \
95 NIDEN_SEL_STATUS | DBGEN_SEL_STATUS)
96
97 struct platform_data_t tfm_peripheral_std_uart = {
98 UART0_BASE_NS,
99 UART0_BASE_NS + 0xFFF,
100 PPC_SP_DO_NOT_CONFIGURE,
101 -1
102 };
103
104 struct platform_data_t tfm_peripheral_uart1 = {
105 UART1_BASE_S,
106 UART1_BASE_S + 0xFFF,
107 PPC_SP_APB_PPC_EXP1,
108 CMSDK_UART1_APB_PPC_POS
109 };
110
111 struct platform_data_t tfm_peripheral_timer0 = {
112 CMSDK_TIMER0_BASE_S,
113 CMSDK_TIMER1_BASE_S - 1,
114 PPC_SP_APB_PPC0,
115 CMSDK_TIMER0_APB_PPC_POS
116 };
117
118 #ifdef PSA_API_TEST_IPC
119
120 /* Below data structure are only used for PSA FF tests, and this pattern is
121 * definitely not to be followed for real life use cases, as it can break
122 * security.
123 */
124
125 struct platform_data_t
126 tfm_peripheral_FF_TEST_UART_REGION = {
127 UART2_BASE_S,
128 UART2_BASE_S + 0xFFF,
129 PPC_SP_APB_PPC_EXP2,
130 CMSDK_UART2_APB_PPC_POS
131 };
132
133 struct platform_data_t
134 tfm_peripheral_FF_TEST_WATCHDOG_REGION = {
135 APB_WATCHDOG_BASE_S,
136 APB_WATCHDOG_BASE_S + 0xFFF,
137 PPC_SP_DO_NOT_CONFIGURE,
138 -1
139 };
140
141 #define FF_TEST_NVMEM_REGION_START 0x102FFC00
142 #define FF_TEST_NVMEM_REGION_END 0x102FFFFF
143 #define FF_TEST_SERVER_PARTITION_MMIO_START 0x3801FC00
144 #define FF_TEST_SERVER_PARTITION_MMIO_END 0x3801FCFF
145 #define FF_TEST_DRIVER_PARTITION_MMIO_START 0x3801FE00
146 #define FF_TEST_DRIVER_PARTITION_MMIO_END 0x3801FEFF
147
148 struct platform_data_t
149 tfm_peripheral_FF_TEST_NVMEM_REGION = {
150 FF_TEST_NVMEM_REGION_START,
151 FF_TEST_NVMEM_REGION_END,
152 PPC_SP_DO_NOT_CONFIGURE,
153 -1
154 };
155
156 struct platform_data_t
157 tfm_peripheral_FF_TEST_SERVER_PARTITION_MMIO = {
158 FF_TEST_SERVER_PARTITION_MMIO_START,
159 FF_TEST_SERVER_PARTITION_MMIO_END,
160 PPC_SP_DO_NOT_CONFIGURE,
161 -1
162 };
163
164 struct platform_data_t
165 tfm_peripheral_FF_TEST_DRIVER_PARTITION_MMIO = {
166 FF_TEST_DRIVER_PARTITION_MMIO_START,
167 FF_TEST_DRIVER_PARTITION_MMIO_END,
168 PPC_SP_DO_NOT_CONFIGURE,
169 -1
170 };
171 #endif
172
enable_fault_handlers(void)173 enum tfm_plat_err_t enable_fault_handlers(void)
174 {
175 /* Explicitly set secure fault priority to the highest */
176 NVIC_SetPriority(SecureFault_IRQn, 0);
177
178 /* Enables BUS, MEM, USG and Secure faults */
179 SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk
180 | SCB_SHCSR_BUSFAULTENA_Msk
181 | SCB_SHCSR_MEMFAULTENA_Msk
182 | SCB_SHCSR_SECUREFAULTENA_Msk;
183 return TFM_PLAT_ERR_SUCCESS;
184 }
185
system_reset_cfg(void)186 enum tfm_plat_err_t system_reset_cfg(void)
187 {
188 struct sysctrl_t *sysctrl = (struct sysctrl_t *)CMSDK_SYSCTRL_BASE_S;
189 uint32_t reg_value = SCB->AIRCR;
190
191 /* Enable system reset request for CPU 0, to be triggered via
192 * NVIC_SystemReset function.
193 */
194 sysctrl->resetmask |= ENABLE_CPU0_SYSTEM_RESET_REQUEST;
195
196 /* Clear SCB_AIRCR_VECTKEY value */
197 reg_value &= ~(uint32_t)(SCB_AIRCR_VECTKEY_Msk);
198
199 /* Enable system reset request only to the secure world */
200 reg_value |= (uint32_t)(SCB_AIRCR_WRITE_MASK | SCB_AIRCR_SYSRESETREQS_Msk);
201
202 SCB->AIRCR = reg_value;
203
204 return TFM_PLAT_ERR_SUCCESS;
205 }
206
init_debug(void)207 FIH_RET_TYPE(enum tfm_plat_err_t) init_debug(void)
208 {
209 volatile struct sysctrl_t *sys_ctrl =
210 (struct sysctrl_t *)CMSDK_SYSCTRL_BASE_S;
211
212 #if defined(DAUTH_NONE)
213 /* Set all the debug enable selector bits to 1 */
214 sys_ctrl->secdbgset = All_SEL_STATUS;
215 /* Set all the debug enable bits to 0 */
216 sys_ctrl->secdbgclr =
217 DBGEN_STATUS | NIDEN_STATUS | SPIDEN_STATUS | SPNIDEN_STATUS;
218 #elif defined(DAUTH_NS_ONLY)
219 /* Set all the debug enable selector bits to 1 */
220 sys_ctrl->secdbgset = All_SEL_STATUS;
221 /* Set the debug enable bits to 1 for NS, and 0 for S mode */
222 sys_ctrl->secdbgset = DBGEN_STATUS | NIDEN_STATUS;
223 sys_ctrl->secdbgclr = SPIDEN_STATUS | SPNIDEN_STATUS;
224 #elif defined(DAUTH_FULL)
225 /* Set all the debug enable selector bits to 1 */
226 sys_ctrl->secdbgset = All_SEL_STATUS;
227 /* Set all the debug enable bits to 1 */
228 sys_ctrl->secdbgset =
229 DBGEN_STATUS | NIDEN_STATUS | SPIDEN_STATUS | SPNIDEN_STATUS;
230 #else
231
232 #if !defined(DAUTH_CHIP_DEFAULT)
233 #error "No debug authentication setting is provided."
234 #endif
235
236 /* Set all the debug enable selector bits to 0 */
237 sys_ctrl->secdbgclr = All_SEL_STATUS;
238
239 /* No need to set any enable bits because the value depends on
240 * input signals.
241 */
242 #endif
243
244 FIH_RET(fih_int_encode(TFM_PLAT_ERR_SUCCESS));
245 }
246
247 /*----------------- NVIC interrupt target state to NS configuration ----------*/
nvic_interrupt_target_state_cfg(void)248 enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void)
249 {
250 /* Target every interrupt to NS; unimplemented interrupts will be WI */
251 for (uint8_t i=0; i<sizeof(NVIC->ITNS)/sizeof(NVIC->ITNS[0]); i++) {
252 NVIC->ITNS[i] = 0xFFFFFFFF;
253 }
254
255 /* Make sure that MPC and PPC are targeted to S state */
256 NVIC_ClearTargetState(MPC_IRQn);
257 NVIC_ClearTargetState(PPC_IRQn);
258
259 #ifdef SECURE_UART1
260 /* UART1 is a secure peripheral, so its IRQs have to target S state */
261 NVIC_ClearTargetState(UARTRX1_IRQn);
262 NVIC_ClearTargetState(UARTTX1_IRQn);
263 NVIC_ClearTargetState(UART1_IRQn);
264 #endif
265
266 return TFM_PLAT_ERR_SUCCESS;
267 }
268
269 /*----------------- NVIC interrupt enabling for S peripherals ----------------*/
nvic_interrupt_enable(void)270 enum tfm_plat_err_t nvic_interrupt_enable(void)
271 {
272 struct spctrl_def* spctrl = CMSDK_SPCTRL;
273 int32_t ret = ARM_DRIVER_OK;
274
275 /* MPC interrupt enabling */
276 ret = Driver_SRAM1_MPC.EnableInterrupt();
277 if (ret != ARM_DRIVER_OK) {
278 return TFM_PLAT_ERR_SYSTEM_ERR;
279 }
280 ret = Driver_SRAM2_MPC.EnableInterrupt();
281 if (ret != ARM_DRIVER_OK) {
282 return TFM_PLAT_ERR_SYSTEM_ERR;
283 }
284 NVIC_EnableIRQ(MPC_IRQn);
285
286 /* PPC interrupt enabling */
287 /* Clear pending PPC interrupts */
288 /* In the PPC configuration function, we have used the Non-Secure
289 * Privilege Control Block to grant unprivilged NS access to some
290 * peripherals used by NS. That triggers a PPC0 exception as that
291 * register is meant for NS privileged access only. Clear it here
292 */
293 spctrl->secppcintclr = CMSDK_APB_PPC0_INT_POS_MASK;
294
295 /* Enable PPC interrupts for APB PPC */
296 spctrl->secppcinten |= CMSDK_APB_PPC0_INT_POS_MASK |
297 CMSDK_APB_PPC1_INT_POS_MASK |
298 CMSDK_APB_PPCEXP0_INT_POS_MASK |
299 CMSDK_APB_PPCEXP1_INT_POS_MASK |
300 CMSDK_APB_PPCEXP2_INT_POS_MASK |
301 CMSDK_APB_PPCEXP3_INT_POS_MASK;
302
303 NVIC_EnableIRQ(PPC_IRQn);
304
305 #ifdef PSA_FF_TEST_SECURE_UART2
306 NVIC_EnableIRQ(FF_TEST_UART_IRQ);
307 #endif
308
309 return TFM_PLAT_ERR_SUCCESS;
310 }
311
312 /*------------------- SAU/IDAU configuration functions -----------------------*/
313 #if defined(PSA_API_TEST_NS) && !defined(PSA_API_TEST_IPC)
314 #define DEV_APIS_TEST_NVMEM_REGION_START (NS_DATA_LIMIT + 1)
315 #define DEV_APIS_TEST_NVMEM_REGION_LIMIT \
316 (DEV_APIS_TEST_NVMEM_REGION_START + DEV_APIS_TEST_NVMEM_REGION_SIZE - 1)
317 #endif
318
319 struct sau_cfg_t {
320 uint32_t RBAR;
321 uint32_t RLAR;
322 bool nsc;
323 };
324
325 const struct sau_cfg_t sau_cfg[] = {
326 {
327 ((uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base)),
328 ((uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
329 NS_PARTITION_SIZE - 1),
330 false,
331 },
332 {
333 NS_DATA_START,
334 NS_DATA_LIMIT,
335 false,
336 },
337 {
338 (uint32_t)®ION_NAME(Image$$, ER_VENEER, $$Base),
339 (uint32_t)®ION_NAME(Image$$, VENEER_ALIGN, $$Limit) - 1,
340 true,
341 },
342 {
343 PERIPHERALS_BASE_NS_START,
344 #if (defined(SECURE_UART1) && defined(PSA_FF_TEST_SECURE_UART2))
345 (UART1_BASE_NS - 1),
346 false,
347 },
348 {
349 UART3_BASE_NS,
350 #elif defined(PSA_FF_TEST_SECURE_UART2)
351 (UART2_BASE_NS - 1),
352 false,
353 },
354 {
355 UART3_BASE_NS,
356 #elif defined(SECURE_UART1)
357 (UART1_BASE_NS - 1),
358 false,
359 },
360 {
361 UART2_BASE_NS,
362 #endif
363 PERIPHERALS_BASE_NS_END,
364 false,
365 },
366 #ifdef BL2
367 {
368 (uint32_t)®ION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base),
369 (uint32_t)®ION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base) +
370 SECONDARY_PARTITION_SIZE - 1,
371 false,
372 },
373 #endif
374 #if defined(PSA_API_TEST_NS) && !defined(PSA_API_TEST_IPC)
375 {
376 DEV_APIS_TEST_NVMEM_REGION_START,
377 DEV_APIS_TEST_NVMEM_REGION_LIMIT,
378 false,
379 },
380 #endif
381 };
382
383 #define NR_SAU_INIT_STEP 3
384
sau_and_idau_cfg(void)385 FIH_RET_TYPE(int32_t) sau_and_idau_cfg(void)
386 {
387 struct spctrl_def *spctrl = CMSDK_SPCTRL;
388 uint32_t i;
389
390 /* Ensure all memory accesses are completed */
391 __DMB();
392
393 /* Enables SAU */
394 TZ_SAU_Enable();
395
396 for (i = 0; i < ARRAY_SIZE(sau_cfg); i++) {
397 SAU->RNR = i;
398 SAU->RBAR = sau_cfg[i].RBAR & SAU_RBAR_BADDR_Msk;
399 SAU->RLAR = (sau_cfg[i].RLAR & SAU_RLAR_LADDR_Msk) |
400 (sau_cfg[i].nsc ? SAU_RLAR_NSC_Msk : 0U) |
401 SAU_RLAR_ENABLE_Msk;
402 }
403
404 /* Allows SAU to define the code region as a NSC */
405 spctrl->nsccfg |= NSCCFG_CODENSC;
406
407 /* Ensure the write is completed and flush pipeline */
408 __DSB();
409 __ISB();
410
411 FIH_RET(fih_int_encode(ARM_DRIVER_OK));
412 }
413
414 #ifdef TFM_FIH_PROFILE_ON
fih_verify_sau_and_idau_cfg(void)415 fih_int fih_verify_sau_and_idau_cfg(void)
416 {
417 struct spctrl_def *spctrl = CMSDK_SPCTRL;
418 uint32_t i;
419
420 /* Check SAU is enabled */
421 if ((SAU->CTRL & (SAU_CTRL_ENABLE_Msk)) != (SAU_CTRL_ENABLE_Msk)) {
422 FIH_RET(fih_int_encode(ARM_DRIVER_ERROR));
423 }
424
425 for (i = 0; i < ARRAY_SIZE(sau_cfg); i++) {
426 SAU->RNR = i;
427 if (SAU->RBAR != (sau_cfg[i].RBAR & SAU_RBAR_BADDR_Msk)) {
428 FIH_RET(fih_int_encode(ARM_DRIVER_ERROR));
429 }
430 if (SAU->RLAR != ((sau_cfg[i].RLAR & SAU_RLAR_LADDR_Msk) |
431 (sau_cfg[i].nsc ? SAU_RLAR_NSC_Msk : 0U) |
432 SAU_RLAR_ENABLE_Msk)) {
433 FIH_RET(fih_int_encode(ARM_DRIVER_ERROR));
434 }
435 }
436
437 if ((spctrl->nsccfg & (NSCCFG_CODENSC)) != (NSCCFG_CODENSC)) {
438 FIH_RET(fih_int_encode(ARM_DRIVER_ERROR));
439 }
440
441 FIH_RET(fih_int_encode(ARM_DRIVER_OK));
442 }
443 #endif /* TFM_FIH_PROFILE_ON */
444
445 /*------------------- Memory configuration functions -------------------------*/
446 #ifdef BL2
447 #define NR_MPC_INIT_STEP 7
448 #else
449 #define NR_MPC_INIT_STEP 6
450 #endif
451
mpc_init_cfg(void)452 FIH_RET_TYPE(int32_t) mpc_init_cfg(void)
453 {
454 int32_t ret = ARM_DRIVER_OK;
455
456 ret = Driver_SRAM1_MPC.Initialize();
457 if (ret != ARM_DRIVER_OK) {
458 FIH_RET(fih_int_encode(ret));
459 }
460
461 ret = Driver_SRAM1_MPC.ConfigRegion(
462 memory_regions.non_secure_partition_base,
463 memory_regions.non_secure_partition_limit,
464 ARM_MPC_ATTR_NONSECURE);
465 if (ret != ARM_DRIVER_OK) {
466 FIH_RET(fih_int_encode(ret));
467 }
468
469 #ifdef BL2
470 /* Secondary image region */
471 ret = Driver_SRAM1_MPC.ConfigRegion(memory_regions.secondary_partition_base,
472 memory_regions.secondary_partition_limit,
473 ARM_MPC_ATTR_NONSECURE);
474 if (ret != ARM_DRIVER_OK) {
475 FIH_RET(fih_int_encode(ret));
476 }
477 #endif /* BL2 */
478
479 ret = Driver_SRAM2_MPC.Initialize();
480 if (ret != ARM_DRIVER_OK) {
481 FIH_RET(fih_int_encode(ret));
482 }
483
484 ret = Driver_SRAM2_MPC.ConfigRegion(NS_DATA_START, NS_DATA_LIMIT,
485 ARM_MPC_ATTR_NONSECURE);
486 #if defined(PSA_API_TEST_NS) && !defined(PSA_API_TEST_IPC)
487 ret = Driver_SRAM2_MPC.ConfigRegion(DEV_APIS_TEST_NVMEM_REGION_START,
488 DEV_APIS_TEST_NVMEM_REGION_LIMIT,
489 ARM_MPC_ATTR_NONSECURE);
490 #endif
491 if (ret != ARM_DRIVER_OK) {
492 FIH_RET(fih_int_encode(ret));
493 }
494
495 /* Lock down the MPC configuration */
496 ret = Driver_SRAM1_MPC.LockDown();
497 if (ret != ARM_DRIVER_OK) {
498 FIH_RET(fih_int_encode(ret));
499 }
500
501 ret = Driver_SRAM2_MPC.LockDown();
502 if (ret != ARM_DRIVER_OK) {
503 FIH_RET(fih_int_encode(ret));
504 }
505
506 /* Add barriers to assure the MPC configuration is done before continue
507 * the execution.
508 */
509 __DSB();
510 __ISB();
511
512 FIH_RET(fih_int_encode(ARM_DRIVER_OK));
513 }
514
515 #ifdef TFM_FIH_PROFILE_ON
fih_verify_mpc_cfg(void)516 fih_int fih_verify_mpc_cfg(void)
517 {
518 ARM_MPC_SEC_ATTR attr;
519
520 Driver_SRAM1_MPC.GetRegionConfig(memory_regions.non_secure_partition_base,
521 memory_regions.non_secure_partition_limit,
522 &attr);
523 if (attr != ARM_MPC_ATTR_NONSECURE) {
524 FIH_RET(fih_int_encode(ARM_DRIVER_ERROR));
525 }
526
527 #ifdef BL2
528 Driver_SRAM1_MPC.GetRegionConfig(memory_regions.secondary_partition_base,
529 memory_regions.secondary_partition_limit,
530 &attr);
531 if (attr != ARM_MPC_ATTR_NONSECURE) {
532 FIH_RET(fih_int_encode(ARM_DRIVER_ERROR));
533 }
534 #endif /* BL2 */
535
536 Driver_SRAM2_MPC.GetRegionConfig(NS_DATA_START, NS_DATA_LIMIT, &attr);
537 if (attr != ARM_MPC_ATTR_NONSECURE) {
538 FIH_RET(fih_int_encode(ARM_DRIVER_ERROR));
539 }
540
541 #if defined(PSA_API_TEST_NS) && !defined(PSA_API_TEST_IPC)
542 Driver_SRAM2_MPC.GetRegionConfig(DEV_APIS_TEST_NVMEM_REGION_START,
543 DEV_APIS_TEST_NVMEM_REGION_LIMIT,
544 &attr);
545 if (attr != ARM_MPC_ATTR_NONSECURE) {
546 FIH_RET(fih_int_encode(ARM_DRIVER_ERROR));
547 }
548 #endif /* PSA_API_TEST_NS && !PSA_API_TEST_IPC */
549
550 FIH_RET(fih_int_encode(ARM_DRIVER_OK));
551 }
552 #endif /* TFM_FIH_PROFILE_ON */
553
554 /*---------------------- PPC configuration functions -------------------------*/
555 #define NR_PPC_INIT_STEP 4
556
ppc_init_cfg(void)557 FIH_RET_TYPE(int32_t) ppc_init_cfg(void)
558 {
559 struct spctrl_def* spctrl = CMSDK_SPCTRL;
560 struct nspctrl_def* nspctrl = CMSDK_NSPCTRL;
561
562 /* Grant non-secure access to peripherals in the PPC0
563 * (timer0 and 1, dualtimer, watchdog, mhu 0 and 1)
564 */
565 spctrl->apbnsppc0 |= (1U << CMSDK_TIMER0_APB_PPC_POS) |
566 (1U << CMSDK_TIMER1_APB_PPC_POS) |
567 (1U << CMSDK_DTIMER_APB_PPC_POS) |
568 (1U << CMSDK_MHU0_APB_PPC_POS) |
569 (1U << CMSDK_MHU1_APB_PPC_POS);
570
571 /* Grant non-secure access for APB peripherals on EXP1 */
572 spctrl->apbnsppcexp1 |= (1U << CMSDK_SPI0_APB_PPC_POS) |
573 (1U << CMSDK_SPI1_APB_PPC_POS) |
574 (1U << CMSDK_SPI2_APB_PPC_POS) |
575 (1U << CMSDK_SPI3_APB_PPC_POS) |
576 (1U << CMSDK_SPI4_APB_PPC_POS) |
577 (1U << CMSDK_UART0_APB_PPC_POS) |
578 #ifdef SECURE_UART1
579 /* To statically configure a peripheral as secure, skip PPC NS peripheral
580 * configuration for the given device.
581 */
582 #else
583 (1U << CMSDK_UART1_APB_PPC_POS) |
584 #endif
585
586 #ifndef PSA_FF_TEST_SECURE_UART2
587 (1U << CMSDK_UART2_APB_PPC_POS) |
588 #endif
589 (1U << CMSDK_UART3_APB_PPC_POS) |
590 (1U << CMSDK_UART4_APB_PPC_POS) |
591 (1U << CMSDK_I2C0_APB_PPC_POS) |
592 (1U << CMSDK_I2C1_APB_PPC_POS) |
593 (1U << CMSDK_I2C2_APB_PPC_POS) |
594 (1U << CMSDK_I2C3_APB_PPC_POS);
595 /* Grant non-secure access for APB peripherals on EXP2 */
596 spctrl->apbnsppcexp2 |= (1U << CMSDK_FPGA_SCC_PPC_POS) |
597 (1U << CMSDK_FPGA_AUDIO_PPC_POS) |
598 (1U << CMSDK_FPGA_IO_PPC_POS);
599
600 /* Grant non-secure access to all peripherals on AHB EXP:
601 * Make sure that all possible peripherals are enabled by default
602 */
603 spctrl->ahbnsppcexp0 |= (1U << CMSDK_VGA_PPC_POS) |
604 (1U << CMSDK_GPIO0_PPC_POS) |
605 (1U << CMSDK_GPIO1_PPC_POS) |
606 (1U << CMSDK_GPIO2_PPC_POS) |
607 (1U << CMSDK_GPIO3_PPC_POS) |
608 (1U << MPS2_ETHERNET_PPC_POS);
609
610 spctrl->ahbnsppcexp1 |= (1U << CMSDK_DMA0_PPC_POS) |
611 (1U << CMSDK_DMA1_PPC_POS) |
612 (1U << CMSDK_DMA2_PPC_POS) |
613 (1U << CMSDK_DMA3_PPC_POS);
614
615 /* in NS, grant un-privileged for UART0 */
616 nspctrl->apbnspppcexp1 |= (1U << CMSDK_UART0_APB_PPC_POS);
617
618 /* in NS, grant un-privileged access for LEDs */
619 nspctrl->apbnspppcexp2 |= (1U << CMSDK_FPGA_SCC_PPC_POS) |
620 (1U << CMSDK_FPGA_IO_PPC_POS);
621
622 /* Configure the response to a security violation as a
623 * bus error instead of RAZ/WI
624 */
625 spctrl->secrespcfg |= 1U;
626
627 FIH_RET(fih_int_encode(ARM_DRIVER_OK));
628 }
629
630 #ifdef TFM_FIH_PROFILE_ON
fih_verify_ppc_cfg(void)631 fih_int fih_verify_ppc_cfg(void)
632 {
633 struct spctrl_def* spctrl = CMSDK_SPCTRL;
634 struct nspctrl_def* nspctrl = CMSDK_NSPCTRL;
635
636 /* Check non-secure access to peripherals in the PPC0
637 * (timer0 and 1, dualtimer, watchdog)
638 */
639 if ((!(spctrl->apbnsppc0 & (1U << CMSDK_TIMER0_APB_PPC_POS))) ||
640 (!(spctrl->apbnsppc0 & (1U << CMSDK_TIMER1_APB_PPC_POS))) ||
641 (!(spctrl->apbnsppc0 & (1U << CMSDK_DTIMER_APB_PPC_POS)))) {
642 FIH_RET(fih_int_encode(ARM_DRIVER_ERROR));
643 }
644
645 /* Check non-secure access for APB peripherals on EXP1 */
646 if ((!(spctrl->apbnsppcexp1 & (1U << CMSDK_SPI0_APB_PPC_POS))) ||
647 (!(spctrl->apbnsppcexp1 & (1U << CMSDK_SPI1_APB_PPC_POS))) ||
648 (!(spctrl->apbnsppcexp1 & (1U << CMSDK_SPI2_APB_PPC_POS))) ||
649 (!(spctrl->apbnsppcexp1 & (1U << CMSDK_SPI3_APB_PPC_POS))) ||
650 (!(spctrl->apbnsppcexp1 & (1U << CMSDK_SPI4_APB_PPC_POS))) ||
651 (!(spctrl->apbnsppcexp1 & (1U << CMSDK_UART0_APB_PPC_POS))) ||
652 #ifdef SECURE_UART1
653 /* Peripheral is statically configured as secure, skip check on PPC NS
654 * peripheral configuration for the given device.
655 */
656 #else
657 (!(spctrl->apbnsppcexp1 & (1U << CMSDK_UART1_APB_PPC_POS))) ||
658
659 #endif
660
661 #ifndef PSA_FF_TEST_SECURE_UART2
662 (!(spctrl->apbnsppcexp1 & (1U << CMSDK_UART2_APB_PPC_POS))) ||
663 #endif
664 (!(spctrl->apbnsppcexp1 & (1U << CMSDK_UART3_APB_PPC_POS))) ||
665 (!(spctrl->apbnsppcexp1 & (1U << CMSDK_UART4_APB_PPC_POS))) ||
666 (!(spctrl->apbnsppcexp1 & (1U << CMSDK_I2C0_APB_PPC_POS))) ||
667 (!(spctrl->apbnsppcexp1 & (1U << CMSDK_I2C1_APB_PPC_POS))) ||
668 (!(spctrl->apbnsppcexp1 & (1U << CMSDK_I2C2_APB_PPC_POS))) ||
669 (!(spctrl->apbnsppcexp1 & (1U << CMSDK_I2C3_APB_PPC_POS)))) {
670 FIH_RET(fih_int_encode(ARM_DRIVER_ERROR));
671 }
672
673 /* In NS, check un-privileged for UART0 */
674 if (!(nspctrl->apbnspppcexp1 & (1U << CMSDK_UART0_APB_PPC_POS))) {
675 FIH_RET(fih_int_encode(ARM_DRIVER_ERROR));
676 }
677
678 /* In NS, check un-privileged access for LEDs */
679 if ((!(nspctrl->apbnspppcexp2 & (1U << CMSDK_FPGA_SCC_PPC_POS))) ||
680 (!(nspctrl->apbnspppcexp2 & (1U << CMSDK_FPGA_IO_PPC_POS)))) {
681 FIH_RET(fih_int_encode(ARM_DRIVER_ERROR));
682 }
683
684 /* Check whether the response to a security violation is a
685 * bus error instead of RAZ/WI
686 */
687 if (!(spctrl->secrespcfg & 1U)) {
688 FIH_RET(fih_int_encode(ARM_DRIVER_ERROR));
689 }
690
691 FIH_RET(fih_int_encode(ARM_DRIVER_OK));
692 }
693 #endif /* TFM_FIH_PROFILE_ON */
694
ppc_configure_to_non_secure(enum ppc_bank_e bank,uint16_t pos)695 void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint16_t pos)
696 {
697 /* Setting NS flag for peripheral to enable NS access */
698 struct spctrl_def* spctrl = CMSDK_SPCTRL;
699 ((uint32_t*)&(spctrl->ahbnsppc0))[bank] |= (1U << pos);
700 }
701
ppc_configure_to_secure(enum ppc_bank_e bank,uint16_t pos)702 FIH_RET_TYPE(int32_t) ppc_configure_to_secure(enum ppc_bank_e bank, uint16_t pos)
703 {
704 /* Clear NS flag for peripheral to prevent NS access */
705 struct spctrl_def* spctrl = CMSDK_SPCTRL;
706 ((uint32_t*)&(spctrl->ahbnsppc0))[bank] &= ~(1U << pos);
707
708 FIH_RET(fih_int_encode(ARM_DRIVER_OK));
709 }
710
ppc_en_secure_unpriv(enum ppc_bank_e bank,uint16_t pos)711 FIH_RET_TYPE(int32_t) ppc_en_secure_unpriv(enum ppc_bank_e bank, uint16_t pos)
712 {
713 struct spctrl_def* spctrl = CMSDK_SPCTRL;
714 ((uint32_t*)&(spctrl->ahbspppc0))[bank] |= (1U << pos);
715
716 FIH_RET(fih_int_encode(ARM_DRIVER_OK));
717 }
718
ppc_clr_secure_unpriv(enum ppc_bank_e bank,uint16_t pos)719 FIH_RET_TYPE(int32_t) ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint16_t pos)
720 {
721 struct spctrl_def* spctrl = CMSDK_SPCTRL;
722 ((uint32_t*)&(spctrl->ahbspppc0))[bank] &= ~(1U << pos);
723
724 FIH_RET(fih_int_encode(ARM_DRIVER_OK));
725 }
726
ppc_clear_irq(void)727 void ppc_clear_irq(void)
728 {
729 struct spctrl_def* spctrl = CMSDK_SPCTRL;
730 /* Clear APB PPC EXP2 IRQ */
731 spctrl->secppcintclr = CMSDK_APB_PPCEXP2_INT_POS_MASK;
732 }
733