1 /*
2 * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
3 * Copyright 2020-2022 NXP. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 */
8
9 #include "tfm_hal_device_header.h"
10 #include "target_cfg.h"
11 #include "tfm_hal_platform.h"
12 #include "tfm_plat_defs.h"
13 #include "uart_stdout.h"
14 #include "fih.h"
15 #include "region_defs.h"
16 #include "region.h"
17 #include "tfm_log.h"
18
19 /* The section names come from the scatter file */
20 REGION_DECLARE(Load$$LR$$, LR_NS_PARTITION, $$Base);
21 REGION_DECLARE(Image$$, ER_VENEER, $$Base);
22 REGION_DECLARE(Image$$, VENEER_ALIGN, $$Limit);
23 #ifdef BL2
24 REGION_DECLARE(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base);
25 #endif /* BL2 */
26
27 const struct memory_region_limits memory_regions = {
28 .non_secure_code_start =
29 (uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
30 BL2_HEADER_SIZE,
31
32 .non_secure_partition_base =
33 (uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base),
34
35 .non_secure_partition_limit =
36 (uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
37 NS_PARTITION_SIZE - 1,
38
39 .veneer_base =
40 (uint32_t)®ION_NAME(Image$$, ER_VENEER, $$Base),
41
42 .veneer_limit =
43 (uint32_t)®ION_NAME(Image$$, VENEER_ALIGN, $$Limit) - 1,
44
45 #ifdef BL2
46 .secondary_partition_base =
47 (uint32_t)®ION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base),
48
49 .secondary_partition_limit =
50 (uint32_t)®ION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base) +
51 SECONDARY_PARTITION_SIZE - 1,
52 #endif /* BL2 */
53 };
54
55 extern void BOARD_InitHardware(void);
56
tfm_hal_platform_init(void)57 FIH_RET_TYPE(enum tfm_hal_status_t) tfm_hal_platform_init(void)
58 {
59 enum tfm_plat_err_t plat_err = TFM_PLAT_ERR_SYSTEM_ERR;
60
61 BOARD_InitHardware();
62
63 stdio_init();
64
65 plat_err = enable_fault_handlers();
66 if (plat_err != TFM_PLAT_ERR_SUCCESS) {
67 FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
68 }
69
70 plat_err = system_reset_cfg();
71 if (plat_err != TFM_PLAT_ERR_SUCCESS) {
72 FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
73 }
74
75 plat_err = init_debug();
76 if (plat_err != TFM_PLAT_ERR_SUCCESS) {
77 FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
78 }
79
80 __enable_irq();
81
82 plat_err = nvic_interrupt_target_state_cfg();
83 if (plat_err != TFM_PLAT_ERR_SUCCESS) {
84 FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
85 }
86
87 plat_err = nvic_interrupt_enable();
88 if (plat_err != TFM_PLAT_ERR_SUCCESS) {
89 FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
90 }
91
92 FIH_RET(fih_int_encode(TFM_HAL_SUCCESS));
93 }
94
tfm_hal_get_ns_VTOR(void)95 uint32_t tfm_hal_get_ns_VTOR(void)
96 {
97 return memory_regions.non_secure_code_start;
98 }
99
tfm_hal_get_ns_MSP(void)100 uint32_t tfm_hal_get_ns_MSP(void)
101 {
102 return *((uint32_t *)memory_regions.non_secure_code_start);
103 }
104
tfm_hal_get_ns_entry_point(void)105 uint32_t tfm_hal_get_ns_entry_point(void)
106 {
107 return *((uint32_t *)(memory_regions.non_secure_code_start + 4));
108 }
109
enable_fault_handlers(void)110 enum tfm_plat_err_t enable_fault_handlers(void)
111 {
112 /* Explicitly set secure fault priority to the highest */
113 NVIC_SetPriority(SecureFault_IRQn, 0);
114
115 /* Enables BUS, MEM, USG and Secure faults */
116 SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk
117 | SCB_SHCSR_BUSFAULTENA_Msk
118 | SCB_SHCSR_MEMFAULTENA_Msk
119 | SCB_SHCSR_SECUREFAULTENA_Msk;
120 return TFM_PLAT_ERR_SUCCESS;
121 }
122
123 /* To write into AIRCR register, 0x5FA value must be write to the VECTKEY field,
124 * otherwise the processor ignores the write.
125 */
126 #define SCB_AIRCR_WRITE_MASK ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos))
127
system_reset_cfg(void)128 enum tfm_plat_err_t system_reset_cfg(void)
129 {
130 uint32_t reg_value = SCB->AIRCR;
131
132 /* Clear SCB_AIRCR_VECTKEY value */
133 reg_value &= ~(uint32_t)(SCB_AIRCR_VECTKEY_Msk);
134
135 /* Enable system reset request only to the secure world */
136 reg_value |= (uint32_t)(SCB_AIRCR_WRITE_MASK | SCB_AIRCR_SYSRESETREQS_Msk);
137
138 SCB->AIRCR = reg_value;
139
140 return TFM_PLAT_ERR_SUCCESS;
141 }
142
init_debug(void)143 enum tfm_plat_err_t init_debug(void)
144 {
145
146 #if !defined(DAUTH_CHIP_DEFAULT)
147 #error "Debug features are set during provisioning. Application is not able to change them as the SYSCTRL->DEBUG_LOCK_EN is locked by the MCU secure boot. "
148 #endif
149 return TFM_PLAT_ERR_SUCCESS;
150 }
151
152 /*----------------- NVIC interrupt target state to NS configuration ----------*/
nvic_interrupt_target_state_cfg(void)153 enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void)
154 {
155 /* Target every interrupt to NS; unimplemented interrupts will be WI */
156 for (uint8_t i=0; i<sizeof(NVIC->ITNS)/sizeof(NVIC->ITNS[0]); i++) {
157 NVIC->ITNS[i] = 0xFFFFFFFF;
158 }
159
160 /* Make sure that MPC and PPC are targeted to S state */
161 NVIC_ClearTargetState(SEC_VIO_IRQn);
162
163 return TFM_PLAT_ERR_SUCCESS;
164 }
165
166 /*----------------- NVIC interrupt enabling for S peripherals ----------------*/
nvic_interrupt_enable(void)167 enum tfm_plat_err_t nvic_interrupt_enable(void)
168 {
169 /* MPC/PPC interrupt enabling */
170 NVIC_EnableIRQ(SEC_VIO_IRQn);
171
172 return TFM_PLAT_ERR_SUCCESS;
173 }
174
175 /* Alternative Control Flow Integrity, using Code Watchdog Timer */
176 #if defined(FIH_ENABLE_CFI) & defined(FIH_CFI_ALT) & defined(CDOG)
177
178 #include "fsl_cdog.h"
179
180 static volatile bool cdog_init_is_done = false;
fih_cdog_init(void)181 static void fih_cdog_init(void)
182 {
183 status_t result = kStatus_Fail;
184 cdog_config_t conf;
185
186 /* Initialize CDOG */
187 CDOG_GetDefaultConfig(&conf);
188
189 conf.timeout = kCDOG_FaultCtrl_EnableInterrupt;
190 conf.miscompare = kCDOG_FaultCtrl_EnableInterrupt;
191 conf.sequence = kCDOG_FaultCtrl_EnableInterrupt;
192 conf.state = kCDOG_FaultCtrl_EnableInterrupt;
193 conf.address = kCDOG_FaultCtrl_EnableInterrupt;
194 conf.irq_pause = kCDOG_IrqPauseCtrl_Pause;
195 conf.debug_halt = kCDOG_DebugHaltCtrl_Pause;
196 conf.lock = kCDOG_LockCtrl_Lock; /* Lock */ //kCDOG_LockCtrl_Unlock;
197
198 /* Clears pending FLAGS and sets CONTROL register */
199 result = CDOG_Init(CDOG, &conf);
200 if (result != kStatus_Success)
201 {
202 ERROR_RAW("[CDOG] Init error.\n");
203 FIH_PANIC;
204 }
205
206 cdog_init_is_done = true;
207 }
208
CDOG_DriverIRQHandler(void)209 void CDOG_DriverIRQHandler(void)
210 {
211 NVIC_ClearPendingIRQ(CDOG_IRQn);
212
213 ERROR_RAW("[CDOG IRQ] ");
214
215 if ((CDOG->FLAGS & CDOG_FLAGS_TO_FLAG_MASK))
216 {
217 ERROR_RAW("Timeout ");
218 }
219 if ((CDOG->FLAGS & CDOG_FLAGS_MISCOM_FLAG_MASK))
220 {
221 ERROR_RAW("Miscompare ");
222 }
223 if ((CDOG->FLAGS & CDOG_FLAGS_SEQ_FLAG_MASK))
224 {
225 ERROR_RAW("Sequence ");
226 }
227 if ((CDOG->FLAGS & CDOG_FLAGS_CNT_FLAG_MASK))
228 {
229 ERROR_RAW("Control ");
230 }
231 if ((CDOG->FLAGS & CDOG_FLAGS_STATE_FLAG_MASK))
232 {
233 ERROR_RAW("State ");
234 }
235 if ((CDOG->FLAGS & CDOG_FLAGS_ADDR_FLAG_MASK))
236 {
237 ERROR_RAW("Address ");
238 }
239 ERROR_RAW("fault occured\n");
240
241 FIH_PANIC;
242 }
243
fih_cfi_get_and_increment(uint8_t cnt)244 fih_int fih_cfi_get_and_increment(uint8_t cnt)
245 {
246 fih_int saved_ctr = _fih_cfi_ctr;
247
248 /* HW */
249 if(cdog_init_is_done == false)
250 {
251 fih_cdog_init();
252 }
253
254 /* Start if in the IDLE state */
255 if((CDOG->STATUS & CDOG_STATUS_CURST_MASK) == CDOG_STATUS_CURST(0x5)) {
256 CDOG_Start(CDOG, 0xFFFFFFFF, fih_int_decode(saved_ctr));
257 }
258
259 CDOG_Add(CDOG, cnt);
260
261 /* SW */
262 _fih_cfi_ctr = fih_int_encode(fih_int_decode(_fih_cfi_ctr) + cnt);
263
264 return saved_ctr;
265 }
266
fih_cfi_validate(fih_int saved)267 void fih_cfi_validate(fih_int saved)
268 {
269 /* HW */
270 CDOG_Stop(CDOG, fih_int_decode(saved));
271 }
272
fih_cfi_decrement(void)273 void fih_cfi_decrement(void)
274 {
275 /* HW */
276 /* Start if in the IDLE state */
277 if((CDOG->STATUS & 0xF0000000) == 0x50000000) {
278 CDOG_Start(CDOG, 0xFFFFFFFF, (fih_int_decode(_fih_cfi_ctr)));
279 }
280 CDOG_Sub1(CDOG);
281
282 /* SW */
283 _fih_cfi_ctr = fih_int_encode(fih_int_decode(_fih_cfi_ctr) - 1);
284 }
285 #endif /* defined(FIH_ENABLE_CFI) & defined(FIH_CFI_ALT) & defined(CDOG) */
286
287