1 /*
2 * Copyright (c) 2022-2024 Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 /*
20 * This file is derivative of CMSIS V5.9.0 startup_ARMCM55.c
21 * Git SHA: 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c
22 */
23
24 #include "tfm_hal_device_header.h"
25
26 #include "device_definition.h"
27 #include "region_defs.h"
28 #include "rse_kmu_slot_ids.h"
29 #include "trng.h"
30
31 /*----------------------------------------------------------------------------
32 External References
33 *----------------------------------------------------------------------------*/
34 extern uint32_t __INITIAL_SP;
35 extern uint32_t __STACK_LIMIT;
36
37 extern __NO_RETURN void __PROGRAM_START(void);
38
39 /*----------------------------------------------------------------------------
40 Internal References
41 *----------------------------------------------------------------------------*/
42 __NO_RETURN void Reset_Handler(void);
43
44 /*----------------------------------------------------------------------------
45 Exception / Interrupt Handler
46 *----------------------------------------------------------------------------*/
47 /* Exception handler that blocks execution. */
exception_handler(void)48 __NO_RETURN void exception_handler(void)
49 {
50 while (1);
51 }
52
53 /* No IRQs are enabled in BL1, so this handler should be unreachable. In case it
54 * is ever reached, disable the IRQ that was triggered and return. In debug
55 * builds, block execution to catch the bug.
56 */
invalid_irq_handler(void)57 void invalid_irq_handler(void)
58 {
59 #ifndef NDEBUG
60 while (1);
61 #else
62 NVIC_DisableIRQ((IRQn_Type)((int32_t)__get_IPSR() - 16));
63 #endif
64 }
65
66 /*----------------------------------------------------------------------------
67 Exception / Interrupt Vector table
68 *----------------------------------------------------------------------------*/
69
70 #if defined ( __GNUC__ )
71 #pragma GCC diagnostic push
72 #pragma GCC diagnostic ignored "-Wpedantic"
73 #endif
74
75 extern const VECTOR_TABLE_Type __VECTOR_TABLE[];
76 const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = {
77 (VECTOR_TABLE_Type)(&__INITIAL_SP), /* Initial Stack Pointer */
78 Reset_Handler, /* Reset Handler */
79 exception_handler, /* -14: NMI Handler */
80 exception_handler, /* -13: Hard Fault Handler */
81 exception_handler, /* -12: MPU Fault Handler */
82 exception_handler, /* -11: Bus Fault Handler */
83 exception_handler, /* -10: Usage Fault Handler */
84 exception_handler, /* -9: Secure Fault Handler */
85 0, /* Reserved */
86 0, /* Reserved */
87 0, /* Reserved */
88 exception_handler, /* -5: SVCall Handler */
89 exception_handler, /* -4: Debug Monitor Handler */
90 0, /* Reserved */
91 exception_handler, /* -2: PendSV Handler */
92 exception_handler, /* -1: SysTick Handler */
93
94 invalid_irq_handler, /* 0: Non-Secure Watchdog Reset Request Handler */
95 invalid_irq_handler, /* 1: Non-Secure Watchdog Handler */
96 invalid_irq_handler, /* 2: SLOWCLK Timer Handler */
97 invalid_irq_handler, /* 3: TIMER 0 Handler */
98 invalid_irq_handler, /* 4: TIMER 1 Handler */
99 invalid_irq_handler, /* 5: TIMER 2 Handler */
100 0, /* 6: Reserved */
101 0, /* 7: Reserved */
102 0, /* 8: Reserved */
103 invalid_irq_handler, /* 9: MPC Combined (Secure) Handler */
104 invalid_irq_handler, /* 10: PPC Combined (Secure) Handler */
105 invalid_irq_handler, /* 11: MSC Combined (Secure) Handler */
106 invalid_irq_handler, /* 12: Bridge Error (Secure) Handler */
107 0, /* 13: Reserved */
108 invalid_irq_handler, /* 14: PPU Combined (Secure) Handler */
109 0, /* 15: Reserved */
110 invalid_irq_handler, /* 16: NPU0 Handler */
111 invalid_irq_handler, /* 17: NPU1 Handler */
112 invalid_irq_handler, /* 18: NPU2 Handler */
113 invalid_irq_handler, /* 19: NPU3 Handler */
114 invalid_irq_handler, /* 20: KMU (Secure) Handler */
115 0, /* 21: Reserved */
116 0, /* 22: Reserved */
117 0, /* 23: Reserved */
118 invalid_irq_handler, /* 24: DMA350 Combined (Secure) Handler */
119 invalid_irq_handler, /* 25: DMA350 Combined (Non-Secure) Handler */
120 invalid_irq_handler, /* 26: DMA350 Security Violation Handler */
121 invalid_irq_handler, /* 27: TIMER 3 AON Handler */
122 invalid_irq_handler, /* 28: CPU0 CTI IRQ 0 Handler */
123 invalid_irq_handler, /* 29: CPU0 CTI IRQ 1 Handler */
124 0, /* 30: Reserved */
125 0, /* 31: Reserved */
126
127 /* External interrupts */
128 invalid_irq_handler, /* 32: SAM Critical Security Fault (Secure) Handler */
129 invalid_irq_handler, /* 33: SAM Security Fault (Secure) Handler */
130 invalid_irq_handler, /* 34: GPIO Combined (Secure) Handler */
131 invalid_irq_handler, /* 35: Secure Debug Channel Handler */
132 invalid_irq_handler, /* 36: FPU Exception Handler */
133 invalid_irq_handler, /* 37: SRAM or TRAM Corrected ECC Error (Secure) Handler */
134 invalid_irq_handler, /* 38: Secure I-Cache (Secure) Handler */
135 invalid_irq_handler, /* 39: ATU (Secure) Handler */
136 invalid_irq_handler, /* 40: CMU MHU 0 Sender Handler */
137 invalid_irq_handler, /* 41: CMU MHU 0 Receiver Handler */
138 invalid_irq_handler, /* 42: CMU MHU 1 Sender Handler */
139 invalid_irq_handler, /* 43: CMU MHU 1 Receiver Handler */
140 invalid_irq_handler, /* 44: CMU MHU 2 Sender Handler */
141 invalid_irq_handler, /* 45: CMU MHU 2 Receiver Handler */
142 invalid_irq_handler, /* 46: CMU MHU 3 Sender Handler */
143 invalid_irq_handler, /* 47: CMU MHU 3 Receiver Handler */
144 invalid_irq_handler, /* 48: CMU MHU 4 Sender Handler */
145 invalid_irq_handler, /* 49: CMU MHU 4 Receiver Handler */
146 invalid_irq_handler, /* 50: CMU MHU 5 Sender Handler */
147 invalid_irq_handler, /* 51: CMU MHU 5 Receiver Handler */
148 invalid_irq_handler, /* 52: CMU MHU 6 Sender Handler */
149 invalid_irq_handler, /* 53: CMU MHU 6 Receiver Handler */
150 invalid_irq_handler, /* 54: CMU MHU 7 Sender Handler */
151 invalid_irq_handler, /* 55: CMU MHU 7 Receiver Handler */
152 invalid_irq_handler, /* 56: CMU MHU 8 Sender Handler */
153 invalid_irq_handler, /* 57: CMU MHU 8 Receiver Handler */
154 invalid_irq_handler, /* 58: Crypto Engine (Secure) Handler */
155 invalid_irq_handler, /* 59: SoC System Timer 0 AON Handler */
156 invalid_irq_handler, /* 60: SoC System Timer 1 AON Handler */
157 invalid_irq_handler, /* 61: SRAM ECC Detected Partial Write (Secure) Handler */
158 invalid_irq_handler, /* 62: Integrity Checker Handler */
159 0, /* 63: Reserved */
160 0, /* 64: Reserved */
161 0, /* 65: Reserved */
162 0, /* 66: Reserved */
163 0, /* 67: Reserved */
164 0, /* 68: Reserved */
165 0, /* 69: Reserved */
166 0, /* 70: Reserved */
167 0, /* 71: Reserved */
168 0, /* 72: Reserved */
169 0, /* 73: Reserved */
170 0, /* 74: Reserved */
171 0, /* 75: Reserved */
172 0, /* 76: Reserved */
173 0, /* 77: Reserved */
174 0, /* 78: Reserved */
175 0, /* 79: Reserved */
176 0, /* 80: Reserved */
177 0, /* 81: Reserved */
178 0, /* 82: Reserved */
179 0, /* 83: Reserved */
180 0, /* 84: Reserved */
181 0, /* 85: Reserved */
182 0, /* 86: Reserved */
183 0, /* 87: Reserved */
184 0, /* 88: Reserved */
185 0, /* 89: Reserved */
186 0, /* 90: Reserved */
187 0, /* 91: Reserved */
188 0, /* 92: Reserved */
189 0, /* 93: Reserved */
190 0, /* 94: Reserved */
191 0, /* 95: Reserved */
192 };
193
194 #if defined ( __GNUC__ )
195 #pragma GCC diagnostic pop
196 #endif
197
198 #ifdef RSE_ENABLE_TRAM
199 extern uint32_t stdio_is_initialized;
200
201 /*
202 * This can't be inlined, since the stack push to get space for the local
203 * variables is done at the start of the function, and the function which calls
204 * this includes an explict stack set which removes the space allocated for
205 * locals.
206 */
setup_tram_encryption(void)207 static void __attribute__ ((noinline)) setup_tram_encryption(void) {
208 enum lcm_bool_t sp_enabled;
209 enum lcm_lcs_t lcs;
210 uint32_t random_word;
211 uint32_t idx;
212 uint8_t tram_key[32];
213 uint8_t prbg_seed[KMU_PRBG_SEED_LEN];
214
215 const struct kmu_key_export_config_t tram_key_export_config = {
216 TRAM_BASE_S + 0x8, /* TRAM key register */
217 0, /* No delay */
218 0x01, /* Increment by 4 bytes with each write */
219 KMU_DESTINATION_PORT_WIDTH_32_BITS, /* Write 32 bits with each write */
220 KMU_DESTINATION_PORT_WIDTH_8_WRITES, /* Perform 8 writes (total 256 bits) */
221 true, /* refresh the masking */
222 false, /* Don't disable the masking */
223 };
224
225 /* Redefine these, as at this point the constants haven't been loaded */
226 struct kmu_dev_cfg_t kmu_dev_cfg_s = {
227 .base = KMU_BASE_S
228 };
229 struct kmu_dev_t kmu_dev_s = {
230 .cfg = &(kmu_dev_cfg_s)
231 };
232 struct tram_dev_cfg_t tram_dev_cfg_s = {
233 .base = TRAM_BASE_S
234 };
235 struct tram_dev_t tram_dev_s = {&tram_dev_cfg_s};
236 struct lcm_dev_cfg_t lcm_dev_cfg_s = {
237 .base = LCM_BASE_S
238 };
239 struct lcm_dev_t lcm_dev_s = {&lcm_dev_cfg_s};
240
241 stdio_is_initialized = 0;
242
243 lcm_get_sp_enabled(&lcm_dev_s, &sp_enabled);
244 lcm_get_lcs(&lcm_dev_s, &lcs);
245
246 bl1_trng_generate_random(prbg_seed, sizeof(prbg_seed));
247 kmu_init(&kmu_dev_s, prbg_seed);
248
249 /* The secure provisioning reset resets the KMU which wipes the keyslots,
250 * but it's still a warm reset so the DMA ICS doesn't run. Because of this,
251 * we need to generate a new TRAM key.
252 */
253 if (sp_enabled == LCM_TRUE && (lcs == LCM_LCS_CM || lcs == LCM_LCS_DM)) {
254 bl1_trng_generate_random(tram_key, sizeof(tram_key));
255
256 kmu_set_key(&kmu_dev_s, RSE_KMU_SLOT_TRAM_KEY, tram_key, sizeof(tram_key));
257 }
258
259 kmu_set_key_export_config(&kmu_dev_s, RSE_KMU_SLOT_TRAM_KEY, &tram_key_export_config);
260 kmu_set_key_export_config_locked(&kmu_dev_s, RSE_KMU_SLOT_TRAM_KEY);
261 kmu_set_key_locked(&kmu_dev_s, RSE_KMU_SLOT_TRAM_KEY);
262 kmu_export_key(&kmu_dev_s, RSE_KMU_SLOT_TRAM_KEY);
263
264 tram_enable_encryption(&tram_dev_s);
265
266 if (sp_enabled == LCM_TRUE && (lcs == LCM_LCS_CM || lcs == LCM_LCS_DM)) {
267 bl1_trng_generate_random((uint8_t *)&random_word, sizeof(random_word));
268
269 for (idx = 0; idx < DTCM_SIZE / sizeof(uint32_t); idx++) {
270 ((uint32_t *)DTCM_BASE_S)[idx] = random_word;
271 }
272 }
273
274 stdio_is_initialized = 0;
275 };
276 #endif /* RSE_ENABLE_TRAM */
277
278 /*----------------------------------------------------------------------------
279 Reset Handler called on controller reset
280 *----------------------------------------------------------------------------*/
Reset_Handler(void)281 void Reset_Handler(void)
282 {
283 #ifdef RSE_SUPPORT_ROM_LIB_RELOCATION
284 /*
285 * Use the GOT table from ROM at this point. This saves copying it into
286 * SRAM.
287 */
288 __asm volatile("ldr r9, =__etext \n");
289 #endif /* RSE_SUPPORT_ROM_LIB_RELOCATION */
290
291 /* Enable cacheing, particularly to avoid ECC errors in VM0/1 */
292 SCB_EnableICache();
293 SCB_EnableDCache();
294
295 #ifdef RSE_ENABLE_TRAM
296 /* Set MSP to be in VM0 to start with */
297 __set_MSP(CM_PROVISIONING_BUNDLE_START);
298 __set_MSPLIM(VM0_BASE_S);
299
300 setup_tram_encryption();
301
302 /* Now switch back to the right stack (which is in the TRAM) */
303 __set_MSPLIM(0);
304 __set_MSP((uint32_t)(&__INITIAL_SP));
305 #endif /* RSE_ENABLE_TRAM */
306
307 __set_MSPLIM((uint32_t)(&__STACK_LIMIT));
308
309 SystemInit(); /* CMSIS System Initialization */
310 __PROGRAM_START(); /* Enter PreMain (C library entry point) */
311 }
312