1 /*
2  * Copyright (c) 2018-2023 Arm Limited. All rights reserved.
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 "target_cfg.h"
18 #include "Driver_MPC.h"
19 #include "Driver_PPC.h"
20 #include "platform_description.h"
21 #include "device_definition.h"
22 #include "region_defs.h"
23 #include "tfm_plat_defs.h"
24 #include "region.h"
25 #include "cmsis_driver_config.h"
26 
27 #define MIN(A, B) (((A) < (B)) ? (A) : (B))
28 #define MAX(A, B) (((A) > (B)) ? (A) : (B))
29 
30 /* The section names come from the scatter file */
31 REGION_DECLARE(Load$$LR$$, LR_NS_PARTITION, $$Base);
32 REGION_DECLARE(Image$$, ER_VENEER, $$Base);
33 REGION_DECLARE(Image$$, VENEER_ALIGN, $$Limit);
34 REGION_DECLARE(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base);
35 
36 const struct memory_region_limits memory_regions = {
37     .non_secure_code_start =
38         (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
39         BL2_HEADER_SIZE,
40 
41     .non_secure_partition_base =
42         (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base),
43 
44     .non_secure_partition_limit =
45         (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
46         NS_PARTITION_SIZE - 1,
47 
48     .veneer_base =
49         (uint32_t)&REGION_NAME(Image$$, ER_VENEER, $$Base),
50 
51     .veneer_limit =
52         (uint32_t)&REGION_NAME(Image$$, VENEER_ALIGN, $$Limit) - 1,
53 };
54 
55 /* Allows software, via SAU, to define the code region as a NSC */
56 #define NSCCFG_CODENSC  1
57 
58 /* Import MPC driver */
59 extern ARM_DRIVER_MPC Driver_MRAM_MPC;
60 extern ARM_DRIVER_MPC Driver_ISRAM0_MPC, Driver_ISRAM1_MPC;
61 extern ARM_DRIVER_MPC Driver_ISRAM2_MPC, Driver_ISRAM3_MPC;
62 
63 /* Import PPC driver */
64 extern ARM_DRIVER_PPC Driver_APB_PPC0, Driver_APB_PPC1;
65 extern ARM_DRIVER_PPC Driver_AHB_PPCEXP0, Driver_AHB_PPCEXP1;
66 extern ARM_DRIVER_PPC Driver_APB_PPCEXP0, Driver_APB_PPCEXP1;
67 extern ARM_DRIVER_PPC Driver_APB_PPCEXP2, Driver_APB_PPCEXP3;
68 
69 /* Define Peripherals NS address range for the platform */
70 #define PERIPHERALS_BASE_NS_START (0x40000000)
71 #define PERIPHERALS_BASE_NS_END   (0x4FFFFFFF)
72 
73 /* Enable system reset request for CPU 0 */
74 #define ENABLE_CPU0_SYSTEM_RESET_REQUEST (1U << 4U)
75 
76 /* To write into AIRCR register, 0x5FA value must be write to the VECTKEY field,
77  * otherwise the processor ignores the write.
78  */
79 #define SCB_AIRCR_WRITE_MASK ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos))
80 
81 /* Debug configuration flags */
82 #define SPNIDEN_SEL_STATUS (0x01u << 7)
83 #define SPNIDEN_STATUS     (0x01u << 6)
84 #define SPIDEN_SEL_STATUS  (0x01u << 5)
85 #define SPIDEN_STATUS      (0x01u << 4)
86 #define NIDEN_SEL_STATUS   (0x01u << 3)
87 #define NIDEN_STATUS       (0x01u << 2)
88 #define DBGEN_SEL_STATUS   (0x01u << 1)
89 #define DBGEN_STATUS       (0x01u << 0)
90 
91 #define All_SEL_STATUS (SPNIDEN_SEL_STATUS | SPIDEN_SEL_STATUS | \
92                         NIDEN_SEL_STATUS | DBGEN_SEL_STATUS)
93 
94 static ARM_DRIVER_PPC *const ppc_bank_drivers[] = {
95     0,                      /* AHB PPC0 */
96     0,                      /* Reserved */
97     0,                      /* Reserved */
98     0,                      /* Reserved */
99     &Driver_AHB_PPCEXP0,    /* AHB PPCEXP0 */
100     0,                      /* AHB PPCEXP1 */
101     0,                      /* AHB PPCEXP2 */
102     0,                      /* AHB PPCEXP3 */
103     &Driver_APB_PPC0,       /* APB PPC0 */
104     &Driver_APB_PPC1,       /* APB PPC1 */
105     0,                      /* Reserved */
106     0,                      /* Reserved */
107     &Driver_APB_PPCEXP0,    /* APB PPCEXP0 */
108     &Driver_APB_PPCEXP1,    /* APB PPCEXP1 */
109 };
110 
111 #define PPC_BANK_COUNT \
112     (sizeof(ppc_bank_drivers)/sizeof(ppc_bank_drivers[0]))
113 
114 
115 struct platform_data_t tfm_peripheral_std_uart = {
116         MUSCA_S1_UART1_NS_BASE,
117         MUSCA_S1_UART1_NS_BASE + 0xFFF,
118         PPC_SP_DO_NOT_CONFIGURE,
119         -1
120 };
121 
122 struct platform_data_t tfm_peripheral_timer0 = {
123         MUSCA_S1_CMSDK_TIMER0_S_BASE,
124         MUSCA_S1_CMSDK_TIMER1_S_BASE - 1,
125         PPC_SP_APB_PPC0,
126         CMSDK_TIMER0_APB_PPC_POS
127 };
128 
129 #ifdef PSA_API_TEST_IPC
130 
131 /* Below data structure are only used for PSA FF tests, and this pattern is
132  * definitely not to be followed for real life use cases, as it can break
133  * security.
134  */
135 
136 struct platform_data_t
137     tfm_peripheral_FF_TEST_UART_REGION = {
138         MUSCA_S1_UART1_NS_BASE,
139         MUSCA_S1_UART1_NS_BASE + 0xFFF,
140         PPC_SP_DO_NOT_CONFIGURE,
141         -1
142 };
143 
144 struct platform_data_t
145     tfm_peripheral_FF_TEST_WATCHDOG_REGION = {
146         MUSCA_S1_CMSDK_WATCHDOG_S_BASE,
147         MUSCA_S1_CMSDK_WATCHDOG_S_BASE + 0xFFF,
148         PPC_SP_DO_NOT_CONFIGURE,
149         -1
150 };
151 
152 #define FF_TEST_NVMEM_REGION_START 0x3003F800
153 #define FF_TEST_NVMEM_REGION_END 0x3003FBFF
154 #define FF_TEST_SERVER_PARTITION_MMIO_START 0x3003FC00
155 #define FF_TEST_SERVER_PARTITION_MMIO_END 0x3003FCFF
156 #define FF_TEST_DRIVER_PARTITION_MMIO_START 0x3003FE00
157 #define FF_TEST_DRIVER_PARTITION_MMIO_END 0x3003FEFF
158 
159 struct platform_data_t
160     tfm_peripheral_FF_TEST_NVMEM_REGION = {
161         FF_TEST_NVMEM_REGION_START,
162         FF_TEST_NVMEM_REGION_END,
163         PPC_SP_DO_NOT_CONFIGURE,
164         -1
165 };
166 
167 struct platform_data_t
168     tfm_peripheral_FF_TEST_SERVER_PARTITION_MMIO = {
169         FF_TEST_SERVER_PARTITION_MMIO_START,
170         FF_TEST_SERVER_PARTITION_MMIO_END,
171         PPC_SP_DO_NOT_CONFIGURE,
172         -1
173 };
174 
175 struct platform_data_t
176     tfm_peripheral_FF_TEST_DRIVER_PARTITION_MMIO = {
177         FF_TEST_DRIVER_PARTITION_MMIO_START,
178         FF_TEST_DRIVER_PARTITION_MMIO_END,
179         PPC_SP_DO_NOT_CONFIGURE,
180         -1
181 };
182 
183 #endif
184 
enable_fault_handlers(void)185 enum tfm_plat_err_t enable_fault_handlers(void)
186 {
187     /* Explicitly set secure fault priority to the highest */
188     NVIC_SetPriority(SecureFault_IRQn, 0);
189 
190     /* Enables BUS, MEM, USG and Secure faults */
191     SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk
192                   | SCB_SHCSR_BUSFAULTENA_Msk
193                   | SCB_SHCSR_MEMFAULTENA_Msk
194                   | SCB_SHCSR_SECUREFAULTENA_Msk;
195     return TFM_PLAT_ERR_SUCCESS;
196 }
197 
system_reset_cfg(void)198 enum tfm_plat_err_t system_reset_cfg(void)
199 {
200     struct sysctrl_t *sysctrl = (struct sysctrl_t *)CMSDK_SYSCTRL_BASE_S;
201     uint32_t reg_value = SCB->AIRCR;
202 
203     /* Enable system reset request for CPU 0, to be triggered via
204      * NVIC_SystemReset function.
205      */
206     sysctrl->resetmask |= ENABLE_CPU0_SYSTEM_RESET_REQUEST;
207 
208     /* Clear SCB_AIRCR_VECTKEY value */
209     reg_value &= ~(uint32_t)(SCB_AIRCR_VECTKEY_Msk);
210 
211     /* Enable system reset request only to the secure world */
212     reg_value |= (uint32_t)(SCB_AIRCR_WRITE_MASK | SCB_AIRCR_SYSRESETREQS_Msk);
213 
214     SCB->AIRCR = reg_value;
215 
216     return TFM_PLAT_ERR_SUCCESS;
217 }
218 
init_debug(void)219 enum tfm_plat_err_t init_debug(void)
220 {
221     volatile struct sysctrl_t *sys_ctrl =
222                                        (struct sysctrl_t *)CMSDK_SYSCTRL_BASE_S;
223 
224 #if defined(DAUTH_NONE)
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 0 */
228     sys_ctrl->secdbgclr = DBGEN_STATUS |
229                           NIDEN_STATUS |
230                           SPIDEN_STATUS |
231                           SPNIDEN_STATUS;
232 
233 #elif defined(DAUTH_NS_ONLY)
234     /* Set all the debug enable selector bits to 1 */
235     sys_ctrl->secdbgset = All_SEL_STATUS;
236     /* Set the debug enable bits to 1 for NS, and 0 for S mode */
237     sys_ctrl->secdbgset = DBGEN_STATUS | NIDEN_STATUS;
238     sys_ctrl->secdbgclr = SPIDEN_STATUS | SPNIDEN_STATUS;
239 #elif defined(DAUTH_FULL)
240     /* Set all the debug enable selector bits to 1 */
241     sys_ctrl->secdbgset = All_SEL_STATUS;
242     /* Set all the debug enable bits to 1 */
243     sys_ctrl->secdbgset = DBGEN_STATUS |
244                           NIDEN_STATUS |
245                           SPIDEN_STATUS |
246                           SPNIDEN_STATUS;
247 #else
248 
249 #if !defined(DAUTH_CHIP_DEFAULT)
250 #error "No debug authentication setting is provided."
251 #endif
252 
253     /* Set all the debug enable selector bits to 0 */
254     sys_ctrl->secdbgclr = All_SEL_STATUS;
255 
256     /* No need to set any enable bits because the value depends on
257      * input signals.
258      */
259 #endif
260     return TFM_PLAT_ERR_SUCCESS;
261 }
262 
263 /*----------------- NVIC interrupt target state to NS configuration ----------*/
nvic_interrupt_target_state_cfg(void)264 enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void)
265 {
266     /* Target every interrupt to NS; unimplemented interrupts will be WI */
267     for (uint8_t i=0; i<sizeof(NVIC->ITNS)/sizeof(NVIC->ITNS[0]); i++) {
268         NVIC->ITNS[i] = 0xFFFFFFFF;
269     }
270 
271     /* Make sure that MPC and PPC are targeted to S state */
272     NVIC_ClearTargetState(S_MPC_COMBINED_IRQn);
273     NVIC_ClearTargetState(S_PPC_COMBINED_IRQn);
274 
275     return TFM_PLAT_ERR_SUCCESS;
276 }
277 
278 /*----------------- NVIC interrupt enabling for S peripherals ----------------*/
nvic_interrupt_enable()279 enum tfm_plat_err_t nvic_interrupt_enable()
280 {
281     int32_t ret = ARM_DRIVER_OK;
282 
283     /* MPC interrupt enabling */
284     ret = Driver_MRAM_MPC.EnableInterrupt();
285     if (ret != ARM_DRIVER_OK) {
286         return TFM_PLAT_ERR_SYSTEM_ERR;
287     }
288     NVIC_EnableIRQ(S_MPC_COMBINED_IRQn);
289 
290     /* PPC interrupt enabling */
291     /* Clear pending PPC interrupts */
292     /* In the PPC configuration function, we have used the Non-Secure
293      * Privilege Control Block to grant unprivilged NS access to some
294      * peripherals used by NS. That triggers a PPC0 exception as that
295      * register is meant for NS privileged access only. Clear it here
296      */
297 
298     /* Enable PPC interrupts for APB PPC */
299     Driver_APB_PPC0.ClearInterrupt();
300 
301     ret = Driver_APB_PPC0.EnableInterrupt();
302     if (ret != ARM_DRIVER_OK) {
303         return TFM_PLAT_ERR_SYSTEM_ERR;
304     }
305     ret = Driver_APB_PPC1.EnableInterrupt();
306     if (ret != ARM_DRIVER_OK) {
307         return TFM_PLAT_ERR_SYSTEM_ERR;
308     }
309     ret = Driver_AHB_PPCEXP0.EnableInterrupt();
310     if (ret != ARM_DRIVER_OK) {
311         return TFM_PLAT_ERR_SYSTEM_ERR;
312     }
313 
314     ret = Driver_APB_PPCEXP0.EnableInterrupt();
315     if (ret != ARM_DRIVER_OK) {
316         return TFM_PLAT_ERR_SYSTEM_ERR;
317     }
318     ret = Driver_APB_PPCEXP1.EnableInterrupt();
319     if (ret != ARM_DRIVER_OK) {
320         return TFM_PLAT_ERR_SYSTEM_ERR;
321     }
322 
323     NVIC_EnableIRQ(S_PPC_COMBINED_IRQn);
324 
325 #ifdef PSA_API_TEST_IPC
326     NVIC_EnableIRQ(FF_TEST_UART_IRQ);
327 #endif
328 
329     return TFM_PLAT_ERR_SUCCESS;
330 }
331 
332 /*------------------- SAU/IDAU configuration functions -----------------------*/
333 
sau_and_idau_cfg(void)334 void sau_and_idau_cfg(void)
335 {
336     /* Ensure all memory accesses are completed */
337     __DMB();
338 
339     /* Enables SAU */
340     TZ_SAU_Enable();
341 
342     /* Configures SAU regions to be non-secure */
343     SAU->RNR  = 0U;
344     SAU->RBAR = (memory_regions.non_secure_partition_base
345                 & SAU_RBAR_BADDR_Msk);
346     SAU->RLAR = (memory_regions.non_secure_partition_limit
347                 & SAU_RLAR_LADDR_Msk)
348                 | SAU_RLAR_ENABLE_Msk;
349 
350     SAU->RNR  = 1U;
351     SAU->RBAR = (NS_DATA_START & SAU_RBAR_BADDR_Msk);
352     SAU->RLAR = (NS_DATA_LIMIT & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk;
353 
354     /* Configures veneers region to be non-secure callable */
355     SAU->RNR  = 2U;
356     SAU->RBAR = (memory_regions.veneer_base  & SAU_RBAR_BADDR_Msk);
357     SAU->RLAR = (memory_regions.veneer_limit & SAU_RLAR_LADDR_Msk)
358                 | SAU_RLAR_ENABLE_Msk
359                 | SAU_RLAR_NSC_Msk;
360 
361     /* Configure the peripherals space */
362     SAU->RNR  = 3U;
363     SAU->RBAR = (PERIPHERALS_BASE_NS_START & SAU_RBAR_BADDR_Msk);
364     SAU->RLAR = (PERIPHERALS_BASE_NS_END & SAU_RLAR_LADDR_Msk)
365                 | SAU_RLAR_ENABLE_Msk;
366 
367     /* Allows SAU to define the code region as a NSC */
368     struct spctrl_def* spctrl = CMSDK_SPCTRL;
369     spctrl->nsccfg |= NSCCFG_CODENSC;
370 
371     /* Ensure the write is completed and flush pipeline */
372     __DSB();
373     __ISB();
374 }
375 
376 /*------------------- Memory configuration functions -------------------------*/
377 
mpc_init_region_with_attr(ARM_DRIVER_MPC * region,uintptr_t region_base,uintptr_t region_limit,uintptr_t attr_range_start,uintptr_t attr_range_limit,ARM_MPC_SEC_ATTR attr)378 int32_t mpc_init_region_with_attr(ARM_DRIVER_MPC *region,
379                          uintptr_t region_base, uintptr_t region_limit,
380                          uintptr_t attr_range_start, uintptr_t attr_range_limit,
381                          ARM_MPC_SEC_ATTR attr)
382 {
383     uintptr_t range_start = MAX(region_base, attr_range_start);
384     uintptr_t range_limit = MIN(region_limit, attr_range_limit);
385 
386     if (range_start < range_limit) {
387         /* ConfigRegion checks whether the range addresses are aligned at MPC
388          * block border
389          */
390         return region->ConfigRegion(range_start, range_limit, attr);
391     }
392     return ARM_DRIVER_OK;
393 }
394 
mpc_init_cfg(void)395 int32_t mpc_init_cfg(void)
396 {
397     ARM_DRIVER_MPC* mpc_data_region0 = &Driver_ISRAM0_MPC;
398     ARM_DRIVER_MPC* mpc_data_region1 = &Driver_ISRAM1_MPC;
399     ARM_DRIVER_MPC* mpc_data_region2 = &Driver_ISRAM2_MPC;
400     ARM_DRIVER_MPC* mpc_data_region3 = &Driver_ISRAM3_MPC;
401 
402     int32_t ret = ARM_DRIVER_OK;
403 
404     ret = Driver_MRAM_MPC.Initialize();
405     if (ret != ARM_DRIVER_OK) {
406         return ret;
407     }
408 
409     ret = Driver_MRAM_MPC.ConfigRegion(memory_regions.non_secure_partition_base,
410                                  memory_regions.non_secure_partition_limit,
411                                  ARM_MPC_ATTR_NONSECURE);
412     if (ret != ARM_DRIVER_OK) {
413         return ret;
414     }
415 
416     ret = mpc_data_region0->Initialize();
417     if (ret != ARM_DRIVER_OK) {
418         return ret;
419     }
420 
421     ret = mpc_data_region0->ConfigRegion(MPC_ISRAM0_RANGE_BASE_S,
422                                    MPC_ISRAM0_RANGE_LIMIT_S,
423                                    ARM_MPC_ATTR_SECURE);
424     if (ret != ARM_DRIVER_OK) {
425         return ret;
426     }
427 
428     ret = mpc_data_region1->Initialize();
429     if (ret != ARM_DRIVER_OK) {
430         return ret;
431     }
432 
433     ret = mpc_data_region1->ConfigRegion(MPC_ISRAM1_RANGE_BASE_S,
434                                    MPC_ISRAM1_RANGE_LIMIT_S,
435                                    ARM_MPC_ATTR_SECURE);
436     if (ret != ARM_DRIVER_OK) {
437         return ret;
438     }
439 
440     ret = mpc_data_region2->Initialize();
441     if (ret != ARM_DRIVER_OK) {
442         return ret;
443     }
444 
445     ret = mpc_data_region2->ConfigRegion(MPC_ISRAM2_RANGE_BASE_NS,
446                                    MPC_ISRAM2_RANGE_LIMIT_NS,
447                                    ARM_MPC_ATTR_NONSECURE);
448     if (ret != ARM_DRIVER_OK) {
449         return ret;
450     }
451 
452     ret = mpc_data_region3->Initialize();
453     if (ret != ARM_DRIVER_OK) {
454         return ret;
455     }
456 
457     ret = mpc_data_region3->ConfigRegion(MPC_ISRAM3_RANGE_BASE_NS,
458                                    MPC_ISRAM3_RANGE_LIMIT_NS,
459                                    ARM_MPC_ATTR_NONSECURE);
460     if (ret != ARM_DRIVER_OK) {
461         return ret;
462     }
463 
464     /* NOTE: The recommended and expected way of programming MPCs requires to
465      * lock each MPC at this point, so no further configuration is allowed.
466      * However there is a hardware issue in Musca-S1, that makes it necessary to
467      * allow re-configuration before reset. Therefore locking is skipped here.
468      */
469 
470     /* Add barriers to assure the MPC configuration is done before continue
471      * the execution.
472      */
473     __DSB();
474     __ISB();
475 
476     return ARM_DRIVER_OK;
477 }
478 
479 /*  Due to a hardware issue NVIC_SystemReset() does not reset all the MPCs,
480  *  and these retain incorrect settings after reset. This can block the
481  *  boot process.
482  *  To avoid such cases mpc_revert_non_secure_to_secure_cfg() is implemented
483  *  to revert the MPC settings back to secure.
484  */
mpc_revert_non_secure_to_secure_cfg(void)485 void mpc_revert_non_secure_to_secure_cfg(void)
486 {
487     ARM_DRIVER_MPC* mpc_data_region2 = &Driver_ISRAM2_MPC;
488     ARM_DRIVER_MPC* mpc_data_region3 = &Driver_ISRAM3_MPC;
489 
490     Driver_MRAM_MPC.ConfigRegion(MPC_MRAM_RANGE_BASE_S,
491                                  MPC_MRAM_RANGE_LIMIT_S,
492                                  ARM_MPC_ATTR_SECURE);
493 
494     mpc_data_region2->ConfigRegion(MPC_ISRAM2_RANGE_BASE_S,
495                                    MPC_ISRAM2_RANGE_LIMIT_S,
496                                    ARM_MPC_ATTR_SECURE);
497 
498     mpc_data_region3->ConfigRegion(MPC_ISRAM3_RANGE_BASE_S,
499                                    MPC_ISRAM3_RANGE_LIMIT_S,
500                                    ARM_MPC_ATTR_SECURE);
501 
502     /* Add barriers to assure the MPC configuration is done before continue
503      * the execution.
504      */
505     __DSB();
506     __ISB();
507 }
508 
509 /*---------------------- PPC configuration functions -------------------------*/
510 
ppc_init_cfg(void)511 int32_t ppc_init_cfg(void)
512 {
513     struct spctrl_def* spctrl = CMSDK_SPCTRL;
514 
515     /* Grant non-secure access to peripherals in the PPC0
516      * (timer0 and 1, dualtimer, mhu 0 and 1)
517      */
518     int32_t ret = ARM_DRIVER_OK;
519 
520     ret = Driver_APB_PPC0.Initialize();
521     if (ret != ARM_DRIVER_OK) {
522         return ret;
523     }
524     ret = Driver_APB_PPC0.ConfigPeriph(CMSDK_TIMER0_APB_PPC_POS,
525                                  ARM_PPC_NONSECURE_ONLY,
526                                  ARM_PPC_PRIV_ONLY);
527     if (ret != ARM_DRIVER_OK) {
528         return ret;
529     }
530     ret = Driver_APB_PPC0.ConfigPeriph(CMSDK_TIMER1_APB_PPC_POS,
531                                  ARM_PPC_NONSECURE_ONLY,
532                                  ARM_PPC_PRIV_ONLY);
533     if (ret != ARM_DRIVER_OK) {
534         return ret;
535     }
536     ret = Driver_APB_PPC0.ConfigPeriph(CMSDK_DTIMER_APB_PPC_POS,
537                                  ARM_PPC_NONSECURE_ONLY,
538                                  ARM_PPC_PRIV_ONLY);
539     if (ret != ARM_DRIVER_OK) {
540         return ret;
541     }
542     ret = Driver_APB_PPC0.ConfigPeriph(CMSDK_MHU0_APB_PPC_POS,
543                                  ARM_PPC_NONSECURE_ONLY,
544                                  ARM_PPC_PRIV_ONLY);
545     if (ret != ARM_DRIVER_OK) {
546         return ret;
547     }
548     ret = Driver_APB_PPC0.ConfigPeriph(CMSDK_MHU1_APB_PPC_POS,
549                                  ARM_PPC_NONSECURE_ONLY,
550                                  ARM_PPC_PRIV_ONLY);
551     if (ret != ARM_DRIVER_OK) {
552         return ret;
553     }
554 
555     ret = Driver_APB_PPC1.Initialize();
556     if (ret != ARM_DRIVER_OK) {
557         return ret;
558     }
559 
560     /* Grant non-secure access for all APB peripherals on EXP1.
561      * For the specific APB PPC bit definitions on EXP1 see region_defs.h
562      */
563     ret = Driver_AHB_PPCEXP0.Initialize();
564     if (ret != ARM_DRIVER_OK) {
565         return ret;
566     }
567     ret = Driver_AHB_PPCEXP0.ConfigPeriph(MUSCA_S1_GPIO_AHB_PPC_POS,
568                                  ARM_PPC_NONSECURE_ONLY,
569                                  ARM_PPC_PRIV_AND_NONPRIV);
570     if (ret != ARM_DRIVER_OK) {
571         return ret;
572     }
573 
574     ret = Driver_APB_PPCEXP0.Initialize();
575     if (ret != ARM_DRIVER_OK) {
576         return ret;
577     }
578 
579     ret = Driver_APB_PPCEXP1.Initialize();
580     if (ret != ARM_DRIVER_OK) {
581         return ret;
582     }
583 
584     ret = Driver_APB_PPCEXP1.ConfigPeriph(MUSCA_S1_UART0_APB_PPC_POS,
585                                  ARM_PPC_NONSECURE_ONLY,
586                                  ARM_PPC_PRIV_AND_NONPRIV);
587     if (ret != ARM_DRIVER_OK) {
588         return ret;
589     }
590     ret = Driver_APB_PPCEXP1.ConfigPeriph(MUSCA_S1_UART1_APB_PPC_POS,
591                                  ARM_PPC_NONSECURE_ONLY,
592                                  ARM_PPC_PRIV_AND_NONPRIV);
593     if (ret != ARM_DRIVER_OK) {
594         return ret;
595     }
596     ret = Driver_APB_PPCEXP1.ConfigPeriph(MUSCA_S1_SPI_APB_PPC_POS,
597                                  ARM_PPC_NONSECURE_ONLY,
598                                  ARM_PPC_PRIV_AND_NONPRIV);
599     if (ret != ARM_DRIVER_OK) {
600         return ret;
601     }
602     ret = Driver_APB_PPCEXP1.ConfigPeriph(MUSCA_S1_I2C0_APB_PPC_POS,
603                                  ARM_PPC_NONSECURE_ONLY,
604                                  ARM_PPC_PRIV_AND_NONPRIV);
605     if (ret != ARM_DRIVER_OK) {
606         return ret;
607     }
608     ret = Driver_APB_PPCEXP1.ConfigPeriph(MUSCA_S1_I2C1_APB_PPC_POS,
609                                  ARM_PPC_NONSECURE_ONLY,
610                                  ARM_PPC_PRIV_AND_NONPRIV);
611     if (ret != ARM_DRIVER_OK) {
612         return ret;
613     }
614     ret = Driver_APB_PPCEXP1.ConfigPeriph(MUSCA_S1_I2S_APB_PPC_POS,
615                                  ARM_PPC_NONSECURE_ONLY,
616                                  ARM_PPC_PRIV_AND_NONPRIV);
617     if (ret != ARM_DRIVER_OK) {
618         return ret;
619     }
620     ret = Driver_APB_PPCEXP1.ConfigPeriph(MUSCA_S1_PWM0_APB_PPC_POS,
621                                  ARM_PPC_NONSECURE_ONLY,
622                                  ARM_PPC_PRIV_AND_NONPRIV);
623     if (ret != ARM_DRIVER_OK) {
624         return ret;
625     }
626     ret = Driver_APB_PPCEXP1.ConfigPeriph(MUSCA_S1_RTC_APB_PPC_POS,
627                                  ARM_PPC_NONSECURE_ONLY,
628                                  ARM_PPC_PRIV_AND_NONPRIV);
629     if (ret != ARM_DRIVER_OK) {
630         return ret;
631     }
632     ret = Driver_APB_PPCEXP1.ConfigPeriph(MUSCA_S1_PVT_APB_PPC_POS,
633                                  ARM_PPC_NONSECURE_ONLY,
634                                  ARM_PPC_PRIV_AND_NONPRIV);
635     if (ret != ARM_DRIVER_OK) {
636         return ret;
637     }
638     ret = Driver_APB_PPCEXP1.ConfigPeriph(MUSCA_S1_GPTIMER0_APB_PPC_POS,
639                                  ARM_PPC_NONSECURE_ONLY,
640                                  ARM_PPC_PRIV_AND_NONPRIV);
641     if (ret != ARM_DRIVER_OK) {
642         return ret;
643     }
644     ret = Driver_APB_PPCEXP1.ConfigPeriph(MUSCA_S1_GPTIMER1_APB_PPC_POS,
645                                  ARM_PPC_NONSECURE_ONLY,
646                                  ARM_PPC_PRIV_AND_NONPRIV);
647     if (ret != ARM_DRIVER_OK) {
648         return ret;
649     }
650     ret = Driver_APB_PPCEXP1.ConfigPeriph(MUSCA_S1_PWM1_APB_PPC_POS,
651                                  ARM_PPC_NONSECURE_ONLY,
652                                  ARM_PPC_PRIV_AND_NONPRIV);
653     if (ret != ARM_DRIVER_OK) {
654         return ret;
655     }
656     ret = Driver_APB_PPCEXP1.ConfigPeriph(MUSCA_S1_PWM2_APB_PPC_POS,
657                                  ARM_PPC_NONSECURE_ONLY,
658                                  ARM_PPC_PRIV_AND_NONPRIV);
659     if (ret != ARM_DRIVER_OK) {
660         return ret;
661     }
662 
663     /* Configure the response to a security violation as a
664      * bus error instead of RAZ/WI
665      */
666     spctrl->secrespcfg |= 1U;
667 
668     return ARM_DRIVER_OK;
669 }
670 
ppc_configure_to_non_secure(enum ppc_bank_e bank,uint16_t pos)671 void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint16_t pos)
672 {
673     /* Setting NS flag for peripheral to enable NS access */
674     ARM_DRIVER_PPC *ppc_driver;
675 
676     if (bank >= PPC_BANK_COUNT) {
677         return;
678     }
679 
680     ppc_driver = ppc_bank_drivers[bank];
681     if (ppc_driver) {
682         ppc_driver->ConfigPeriph(pos, ARM_PPC_NONSECURE_ONLY,
683                                  ARM_PPC_PRIV_ONLY);
684     }
685 }
686 
ppc_configure_to_secure(enum ppc_bank_e bank,uint16_t pos)687 void ppc_configure_to_secure(enum ppc_bank_e bank, uint16_t pos)
688 {
689     /* Clear NS flag for peripheral to prevent NS access */
690     ARM_DRIVER_PPC *ppc_driver;
691 
692     if (bank >= PPC_BANK_COUNT) {
693         return;
694     }
695 
696     ppc_driver = ppc_bank_drivers[bank];
697     if (ppc_driver) {
698         ppc_driver->ConfigPeriph(pos, ARM_PPC_SECURE_ONLY,
699                                  ARM_PPC_PRIV_ONLY);
700     }
701 }
702 
ppc_en_secure_unpriv(enum ppc_bank_e bank,uint16_t pos)703 void ppc_en_secure_unpriv(enum ppc_bank_e bank, uint16_t pos)
704 {
705     ARM_DRIVER_PPC *ppc_driver;
706 
707     if (bank >= PPC_BANK_COUNT) {
708         return;
709     }
710 
711     ppc_driver = ppc_bank_drivers[bank];
712     if (ppc_driver) {
713         ppc_driver->ConfigPeriph(pos, ARM_PPC_SECURE_ONLY,
714                                  ARM_PPC_PRIV_AND_NONPRIV);
715     }
716 }
717 
ppc_clr_secure_unpriv(enum ppc_bank_e bank,uint16_t pos)718 void ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint16_t pos)
719 {
720     ARM_DRIVER_PPC *ppc_driver;
721 
722     if (bank >= PPC_BANK_COUNT) {
723         return;
724     }
725 
726     ppc_driver = ppc_bank_drivers[bank];
727     if (ppc_driver) {
728         ppc_driver->ConfigPeriph(pos, ARM_PPC_SECURE_ONLY,
729                                  ARM_PPC_PRIV_ONLY);
730     }
731 }
732 
ppc_clear_irq(void)733 void ppc_clear_irq(void)
734 {
735     Driver_AHB_PPCEXP0.ClearInterrupt();
736     Driver_APB_PPC0.ClearInterrupt();
737     Driver_APB_PPC1.ClearInterrupt();
738     Driver_APB_PPCEXP0.ClearInterrupt();
739     Driver_APB_PPCEXP1.ClearInterrupt();
740 }
741