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)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
38 BL2_HEADER_SIZE,
39
40 .non_secure_partition_base =
41 (uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base),
42
43 .non_secure_partition_limit =
44 (uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
45 NS_PARTITION_SIZE - 1,
46
47 .veneer_base =
48 (uint32_t)®ION_NAME(Image$$, ER_VENEER, $$Base),
49
50 .veneer_limit =
51 (uint32_t)®ION_NAME(Image$$, VENEER_ALIGN, $$Limit),
52
53 #ifdef BL2
54 .secondary_partition_base =
55 (uint32_t)®ION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base),
56
57 .secondary_partition_limit =
58 (uint32_t)®ION_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)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base)),
254 ((uint32_t)®ION_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)®ION_NAME(Image$$, ER_VENEER, $$Base),
265 (uint32_t)®ION_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)®ION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base),
283 (uint32_t)®ION_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