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