1 /*
2  * Copyright (c) 2018-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 "target_cfg.h"
19 #include "Driver_MPC.h"
20 #include "platform_retarget_dev.h"
21 #include "region_defs.h"
22 #include "tfm_plat_defs.h"
23 #include "region.h"
24 
25 #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
26 
27 /* The section names come from the scatter file */
28 REGION_DECLARE(Load$$LR$$, LR_NS_PARTITION, $$Base);
29 REGION_DECLARE(Image$$, ER_VENEER, $$Base);
30 REGION_DECLARE(Image$$, VENEER_ALIGN, $$Limit);
31 #ifdef BL2
32 REGION_DECLARE(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base);
33 #endif /* BL2 */
34 
35 const struct memory_region_limits memory_regions = {
36     .non_secure_code_start =
37         (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
38         BL2_HEADER_SIZE,
39 
40     .non_secure_partition_base =
41         (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base),
42 
43     .non_secure_partition_limit =
44         (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
45         NS_PARTITION_SIZE - 1,
46 
47     .veneer_base =
48         (uint32_t)&REGION_NAME(Image$$, ER_VENEER, $$Base),
49 
50     .veneer_limit =
51         (uint32_t)&REGION_NAME(Image$$, VENEER_ALIGN, $$Limit),
52 
53 #ifdef BL2
54     .secondary_partition_base =
55         (uint32_t)&REGION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base),
56 
57     .secondary_partition_limit =
58         (uint32_t)&REGION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base) +
59         SECONDARY_PARTITION_SIZE - 1,
60 #endif /* BL2 */
61 };
62 
63 /* Allows software, via SAU, to define the code region as a NSC */
64 #define NSCCFG_CODENSC  1
65 
66 /* Import MPC driver */
67 extern ARM_DRIVER_MPC Driver_SRAM1_MPC, Driver_SRAM2_MPC;
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 struct platform_data_t tfm_peripheral_std_uart = {
95         UART0_BASE_NS,
96         UART0_BASE_NS + 0xFFF,
97         PPC_SP_DO_NOT_CONFIGURE,
98         -1
99 };
100 
101 struct platform_data_t tfm_peripheral_uart1 = {
102         UART1_BASE_S,
103         UART1_BASE_S + 0xFFF,
104         PPC_SP_APB_PPC_EXP1,
105         CMSDK_UART1_APB_PPC_POS
106 };
107 
108 struct platform_data_t tfm_peripheral_timer0 = {
109         CMSDK_TIMER0_BASE_S,
110         CMSDK_TIMER1_BASE_S - 1,
111         PPC_SP_APB_PPC0,
112         CMSDK_TIMER0_APB_PPC_POS
113 };
114 
enable_fault_handlers(void)115 enum tfm_plat_err_t enable_fault_handlers(void)
116 {
117     /* Secure fault is not present in the Baseline implementation. */
118     /* Fault handler enable registers are not present in a Baseline
119      * implementation.
120      */
121     return TFM_PLAT_ERR_SUCCESS;
122 }
123 
system_reset_cfg(void)124 enum tfm_plat_err_t system_reset_cfg(void)
125 {
126     struct sysctrl_t *sysctrl = (struct sysctrl_t *)CMSDK_SYSCTRL_BASE_S;
127     uint32_t reg_value = SCB->AIRCR;
128 
129     /* Enable system reset request for CPU 0, to be triggered via
130      * NVIC_SystemReset function.
131      */
132     sysctrl->resetmask |= ENABLE_CPU0_SYSTEM_RESET_REQUEST;
133 
134     /* Clear SCB_AIRCR_VECTKEY value */
135     reg_value &= ~(uint32_t)(SCB_AIRCR_VECTKEY_Msk);
136 
137     /* Enable system reset request for the secure world only */
138     reg_value |= (uint32_t)(SCB_AIRCR_WRITE_MASK | SCB_AIRCR_SYSRESETREQS_Msk);
139 
140     SCB->AIRCR = reg_value;
141 
142     return TFM_PLAT_ERR_SUCCESS;
143 }
144 
init_debug(void)145 enum tfm_plat_err_t init_debug(void)
146 {
147     volatile struct sysctrl_t *sys_ctrl =
148                                        (struct sysctrl_t *)CMSDK_SYSCTRL_BASE_S;
149 
150 #if defined(DAUTH_NONE)
151     /* Set all the debug enable selector bits to 1 */
152     sys_ctrl->secdbgset = All_SEL_STATUS;
153     /* Set all the debug enable bits to 0 */
154     sys_ctrl->secdbgclr =
155                    DBGEN_STATUS | NIDEN_STATUS | SPIDEN_STATUS | SPNIDEN_STATUS;
156 #elif defined(DAUTH_NS_ONLY)
157     /* Set all the debug enable selector bits to 1 */
158     sys_ctrl->secdbgset = All_SEL_STATUS;
159     /* Set the debug enable bits to 1 for NS, and 0 for S mode */
160     sys_ctrl->secdbgset = DBGEN_STATUS | NIDEN_STATUS;
161     sys_ctrl->secdbgclr = SPIDEN_STATUS | SPNIDEN_STATUS;
162 #elif defined(DAUTH_FULL)
163     /* Set all the debug enable selector bits to 1 */
164     sys_ctrl->secdbgset = All_SEL_STATUS;
165     /* Set all the debug enable bits to 1 */
166     sys_ctrl->secdbgset =
167                    DBGEN_STATUS | NIDEN_STATUS | SPIDEN_STATUS | SPNIDEN_STATUS;
168 #else
169 
170 #if !defined(DAUTH_CHIP_DEFAULT)
171 #error "No debug authentication setting is provided."
172 #endif
173 
174     /* Set all the debug enable selector bits to 0 */
175     sys_ctrl->secdbgclr = All_SEL_STATUS;
176 
177     /* No need to set any enable bits because the value depends on
178      * input signals.
179      */
180 #endif
181     return TFM_PLAT_ERR_SUCCESS;
182 }
183 
184 /*----------------- NVIC interrupt target state to NS configuration ----------*/
nvic_interrupt_target_state_cfg(void)185 enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void)
186 {
187     /* Target every interrupt to NS; unimplemented interrupts will be WI */
188     for (uint8_t i=0; i<sizeof(NVIC->ITNS)/sizeof(NVIC->ITNS[0]); i++) {
189         NVIC->ITNS[i] = 0xFFFFFFFF;
190     }
191 
192     /* Make sure that MPC and PPC are targeted to S state */
193     NVIC_ClearTargetState(MPC_IRQn);
194     NVIC_ClearTargetState(PPC_IRQn);
195 
196 #ifdef SECURE_UART1
197     /* UART1 is a secure peripheral, so its IRQs have to target S state */
198     NVIC_ClearTargetState(UARTRX1_IRQn);
199     NVIC_ClearTargetState(UARTTX1_IRQn);
200     NVIC_ClearTargetState(UART1_IRQn);
201 #endif
202 
203     return TFM_PLAT_ERR_SUCCESS;
204 }
205 
206 /*----------------- NVIC interrupt enabling for S peripherals ----------------*/
nvic_interrupt_enable(void)207 enum tfm_plat_err_t nvic_interrupt_enable(void)
208 {
209     struct spctrl_def* spctrl = CMSDK_SPCTRL;
210     int32_t ret = ARM_DRIVER_OK;
211 
212     /* MPC interrupt enabling */
213     ret = Driver_SRAM1_MPC.EnableInterrupt();
214     if (ret != ARM_DRIVER_OK) {
215         return TFM_PLAT_ERR_SYSTEM_ERR;
216     }
217     ret = Driver_SRAM2_MPC.EnableInterrupt();
218     if (ret != ARM_DRIVER_OK) {
219         return TFM_PLAT_ERR_SYSTEM_ERR;
220     }
221     NVIC_EnableIRQ(MPC_IRQn);
222 
223     /* PPC interrupt enabling */
224     /* Clear pending PPC interrupts */
225     /* In the PPC configuration function, we have used the Non-Secure
226      * Privilege Control Block to grant unprivilged NS access to some
227      * peripherals used by NS. That triggers a PPC0 exception as that
228      * register is meant for NS privileged access only. Clear it here
229      */
230     spctrl->secppcintclr = CMSDK_APB_PPC0_INT_POS_MASK;
231 
232     /* Enable PPC interrupts for APB PPC */
233     spctrl->secppcinten |= CMSDK_APB_PPC0_INT_POS_MASK |
234                            CMSDK_APB_PPC1_INT_POS_MASK |
235                            CMSDK_APB_PPCEXP0_INT_POS_MASK |
236                            CMSDK_APB_PPCEXP1_INT_POS_MASK |
237                            CMSDK_APB_PPCEXP2_INT_POS_MASK |
238                            CMSDK_APB_PPCEXP3_INT_POS_MASK;
239     NVIC_EnableIRQ(PPC_IRQn);
240 
241     return TFM_PLAT_ERR_SUCCESS;
242 }
243 
244 /*------------------- SAU/IDAU configuration functions -----------------------*/
245 struct sau_cfg_t {
246     uint32_t RBAR;
247     uint32_t RLAR;
248     bool nsc;
249 };
250 
251 const struct sau_cfg_t sau_cfg[] = {
252     {
253         ((uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base)),
254         ((uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
255         NS_PARTITION_SIZE - 1),
256         false,
257     },
258     {
259         NS_DATA_START,
260         NS_DATA_LIMIT,
261         false,
262     },
263     {
264         (uint32_t)&REGION_NAME(Image$$, ER_VENEER, $$Base),
265         (uint32_t)&REGION_NAME(Image$$, VENEER_ALIGN, $$Limit) - 1,
266         true,
267     },
268     {
269         PERIPHERALS_BASE_NS_START,
270 #ifdef SECURE_UART1
271         (UART1_BASE_NS - 1),
272         false,
273     },
274     {
275         UART2_BASE_NS,
276 #endif
277         PERIPHERALS_BASE_NS_END,
278         false,
279     },
280 #ifdef BL2
281     {
282         (uint32_t)&REGION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base),
283         (uint32_t)&REGION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base) +
284         SECONDARY_PARTITION_SIZE - 1,
285         false,
286     },
287 #endif
288 };
289 
sau_and_idau_cfg(void)290 void sau_and_idau_cfg(void)
291 {
292     struct spctrl_def *spctrl = CMSDK_SPCTRL;
293     uint32_t i;
294 
295     /* Ensure all memory accesses are completed */
296     __DMB();
297 
298     /* Enables SAU */
299     TZ_SAU_Enable();
300 
301     for (i = 0; i < ARRAY_SIZE(sau_cfg); i++) {
302         SAU->RNR = i;
303         SAU->RBAR = sau_cfg[i].RBAR & SAU_RBAR_BADDR_Msk;
304         SAU->RLAR = (sau_cfg[i].RLAR & SAU_RLAR_LADDR_Msk) |
305                     (sau_cfg[i].nsc ? SAU_RLAR_NSC_Msk : 0U) |
306                     SAU_RLAR_ENABLE_Msk;
307     }
308 
309     /* Allows SAU to define the code region as a NSC */
310     spctrl->nsccfg |= NSCCFG_CODENSC;
311 
312     /* Ensure the write is completed and flush pipeline */
313     __DSB();
314     __ISB();
315 }
316 
317 /*------------------- Memory configuration functions -------------------------*/
318 
mpc_init_cfg(void)319 int32_t mpc_init_cfg(void)
320 {
321     int32_t ret = ARM_DRIVER_OK;
322 
323     ret = Driver_SRAM1_MPC.Initialize();
324     if (ret != ARM_DRIVER_OK) {
325         return ret;
326     }
327 
328     ret = Driver_SRAM1_MPC.ConfigRegion(
329                                       memory_regions.non_secure_partition_base,
330                                       memory_regions.non_secure_partition_limit,
331                                       ARM_MPC_ATTR_NONSECURE);
332     if (ret != ARM_DRIVER_OK) {
333         return ret;
334     }
335 
336 #ifdef BL2
337     /* Secondary image region */
338     ret = Driver_SRAM1_MPC.ConfigRegion(memory_regions.secondary_partition_base,
339                                   memory_regions.secondary_partition_limit,
340                                   ARM_MPC_ATTR_NONSECURE);
341     if (ret != ARM_DRIVER_OK) {
342         return ret;
343     }
344 #endif /* BL2 */
345 
346     ret = Driver_SRAM2_MPC.Initialize();
347     if (ret != ARM_DRIVER_OK) {
348         return ret;
349     }
350 
351     ret = Driver_SRAM2_MPC.ConfigRegion(NS_DATA_START, NS_DATA_LIMIT,
352                                         ARM_MPC_ATTR_NONSECURE);
353     if (ret != ARM_DRIVER_OK) {
354         return ret;
355     }
356 
357     /* Lock down the MPC configuration */
358     ret = Driver_SRAM1_MPC.LockDown();
359     if (ret != ARM_DRIVER_OK) {
360         return ret;
361     }
362 
363     ret = Driver_SRAM2_MPC.LockDown();
364     if (ret != ARM_DRIVER_OK) {
365         return ret;
366     }
367 
368     /* Add barriers to assure the MPC configuration is done before continue
369      * the execution.
370      */
371     __DSB();
372     __ISB();
373 
374     return ARM_DRIVER_OK;
375 }
376 
377 /*---------------------- PPC configuration functions -------------------------*/
378 
ppc_init_cfg(void)379 void ppc_init_cfg(void)
380 {
381     struct spctrl_def* spctrl = CMSDK_SPCTRL;
382     struct nspctrl_def* nspctrl = CMSDK_NSPCTRL;
383 
384     /* Grant non-secure access to peripherals in the PPC0
385      * (timer0 and 1, dualtimer, watchdog, mhu 0 and 1)
386      */
387     spctrl->apbnsppc0 |= (1U << CMSDK_TIMER0_APB_PPC_POS) |
388                          (1U << CMSDK_TIMER1_APB_PPC_POS) |
389                          (1U << CMSDK_DTIMER_APB_PPC_POS) |
390                          (1U << CMSDK_MHU0_APB_PPC_POS) |
391                          (1U << CMSDK_MHU1_APB_PPC_POS);
392 
393     /* Grant non-secure access for APB peripherals on EXP1 */
394     spctrl->apbnsppcexp1 |= (1U << CMSDK_SPI0_APB_PPC_POS) |
395                             (1U << CMSDK_SPI1_APB_PPC_POS) |
396                             (1U << CMSDK_SPI2_APB_PPC_POS) |
397                             (1U << CMSDK_SPI3_APB_PPC_POS) |
398                             (1U << CMSDK_SPI4_APB_PPC_POS) |
399                             (1U << CMSDK_UART0_APB_PPC_POS) |
400 #ifdef SECURE_UART1
401     /* To statically configure a peripheral as secure, skip PPC NS peripheral
402      * configuration for the given device.
403      */
404 #else
405                             (1U << CMSDK_UART1_APB_PPC_POS) |
406 #endif
407                             (1U << CMSDK_UART2_APB_PPC_POS) |
408                             (1U << CMSDK_UART3_APB_PPC_POS) |
409                             (1U << CMSDK_UART4_APB_PPC_POS) |
410                             (1U << CMSDK_I2C0_APB_PPC_POS) |
411                             (1U << CMSDK_I2C1_APB_PPC_POS) |
412                             (1U << CMSDK_I2C2_APB_PPC_POS) |
413                             (1U << CMSDK_I2C3_APB_PPC_POS);
414     /* Grant non-secure access for APB peripherals on EXP2 */
415     spctrl->apbnsppcexp2 |= (1U << CMSDK_FPGA_SCC_PPC_POS) |
416                             (1U << CMSDK_FPGA_AUDIO_PPC_POS) |
417                             (1U << CMSDK_FPGA_IO_PPC_POS);
418 
419     /* Grant non-secure access to all peripherals on AHB EXP:
420      * Make sure that all possible peripherals are enabled by default
421      */
422     spctrl->ahbnsppcexp0 |= (1U << CMSDK_VGA_PPC_POS) |
423                             (1U << CMSDK_GPIO0_PPC_POS) |
424                             (1U << CMSDK_GPIO1_PPC_POS) |
425                             (1U << CMSDK_GPIO2_PPC_POS) |
426                             (1U << CMSDK_GPIO3_PPC_POS) |
427                             (1U << MPS2_ETHERNET_PPC_POS);
428 
429     spctrl->ahbnsppcexp1 |= (1U << CMSDK_DMA0_PPC_POS) |
430                             (1U << CMSDK_DMA1_PPC_POS) |
431                             (1U << CMSDK_DMA2_PPC_POS) |
432                             (1U << CMSDK_DMA3_PPC_POS);
433 
434     /* in NS, grant un-privileged for UART0 */
435     nspctrl->apbnspppcexp1 |= (1U << CMSDK_UART0_APB_PPC_POS);
436 
437     /* in NS, grant un-privileged access for LEDs */
438     nspctrl->apbnspppcexp2 |= (1U << CMSDK_FPGA_SCC_PPC_POS) |
439                               (1U << CMSDK_FPGA_IO_PPC_POS);
440 
441     /* Configure the response to a security violation as a
442      * bus error instead of RAZ/WI
443      */
444     spctrl->secrespcfg |= 1U;
445 }
446 
ppc_configure_to_non_secure(enum ppc_bank_e bank,uint16_t pos)447 void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint16_t pos)
448 {
449     /* Setting NS flag for peripheral to enable NS access */
450     struct spctrl_def* spctrl = CMSDK_SPCTRL;
451     ((uint32_t*)&(spctrl->ahbnsppc0))[bank] |= (1U << pos);
452 }
453 
ppc_configure_to_secure(enum ppc_bank_e bank,uint16_t pos)454 void ppc_configure_to_secure(enum ppc_bank_e bank, uint16_t pos)
455 {
456     /* Clear NS flag for peripheral to prevent NS access */
457     struct spctrl_def* spctrl = CMSDK_SPCTRL;
458     ((uint32_t*)&(spctrl->ahbnsppc0))[bank] &= ~(1U << pos);
459 }
460 
ppc_en_secure_unpriv(enum ppc_bank_e bank,uint16_t pos)461 void ppc_en_secure_unpriv(enum ppc_bank_e bank, uint16_t pos)
462 {
463     struct spctrl_def* spctrl = CMSDK_SPCTRL;
464     ((uint32_t*)&(spctrl->ahbspppc0))[bank] |= (1U << pos);
465 }
466 
ppc_clr_secure_unpriv(enum ppc_bank_e bank,uint16_t pos)467 void ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint16_t pos)
468 {
469     struct spctrl_def* spctrl = CMSDK_SPCTRL;
470     ((uint32_t*)&(spctrl->ahbspppc0))[bank] &= ~(1U << pos);
471 }
472 
ppc_clear_irq(void)473 void ppc_clear_irq(void)
474 {
475     struct spctrl_def* spctrl = CMSDK_SPCTRL;
476     /* Clear APB PPC EXP2 IRQ */
477     spctrl->secppcintclr = CMSDK_APB_PPCEXP2_INT_POS_MASK;
478 }
479