1 /***********************************************************************************************************************
2 * Copyright [2020-2022] Renesas Electronics Corporation and/or its affiliates. All Rights Reserved.
3 *
4 * This software and documentation are supplied by Renesas Electronics America Inc. and may only be used with products
5 * of Renesas Electronics Corp. and its affiliates ("Renesas"). No other uses are authorized. Renesas products are
6 * sold pursuant to Renesas terms and conditions of sale. Purchasers are solely responsible for the selection and use
7 * of Renesas products and Renesas assumes no liability. No license, express or implied, to any intellectual property
8 * right is granted by Renesas. This software is protected under all applicable laws, including copyright laws. Renesas
9 * reserves the right to change or discontinue this software and/or this documentation. THE SOFTWARE AND DOCUMENTATION
10 * IS DELIVERED TO YOU "AS IS," AND RENESAS MAKES NO REPRESENTATIONS OR WARRANTIES, AND TO THE FULLEST EXTENT
11 * PERMISSIBLE UNDER APPLICABLE LAW, DISCLAIMS ALL WARRANTIES, WHETHER EXPLICITLY OR IMPLICITLY, INCLUDING WARRANTIES
12 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT, WITH RESPECT TO THE SOFTWARE OR
13 * DOCUMENTATION. RENESAS SHALL HAVE NO LIABILITY ARISING OUT OF ANY SECURITY VULNERABILITY OR BREACH. TO THE MAXIMUM
14 * EXTENT PERMITTED BY LAW, IN NO EVENT WILL RENESAS BE LIABLE TO YOU IN CONNECTION WITH THE SOFTWARE OR DOCUMENTATION
15 * (OR ANY PERSON OR ENTITY CLAIMING RIGHTS DERIVED FROM YOU) FOR ANY LOSS, DAMAGES, OR CLAIMS WHATSOEVER, INCLUDING,
16 * WITHOUT LIMITATION, ANY DIRECT, CONSEQUENTIAL, SPECIAL, INDIRECT, PUNITIVE, OR INCIDENTAL DAMAGES; ANY LOST PROFITS,
17 * OTHER ECONOMIC DAMAGE, PROPERTY DAMAGE, OR PERSONAL INJURY; AND EVEN IF RENESAS HAS BEEN ADVISED OF THE POSSIBILITY
18 * OF SUCH LOSS, DAMAGES, CLAIMS OR COSTS.
19 **********************************************************************************************************************/
20
21 /*******************************************************************************************************************//**
22 * @addtogroup BSP_MCU
23 * @{
24 **********************************************************************************************************************/
25
26 /***********************************************************************************************************************
27 * Includes <System Includes> , "Project Includes"
28 **********************************************************************************************************************/
29 #include <string.h>
30 #include "bsp_api.h"
31
32 /***********************************************************************************************************************
33 * Macro definitions
34 **********************************************************************************************************************/
35
36 /* Mask to select CP bits( 0xF00000 ) */
37 #define CP_MASK (0xFU << 20)
38
39 /* Value to write to OAD register of MPU stack monitor to enable NMI when a stack overflow is detected. */
40 #define BSP_STACK_POINTER_MONITOR_NMI_ON_DETECTION (0xA500U)
41
42 /* Key code for writing PRCR register. */
43 #define BSP_PRV_PRCR_KEY (0xA500U)
44 #define BSP_PRV_PRCR_PRC1_UNLOCK ((BSP_PRV_PRCR_KEY) | 0x2U)
45 #define BSP_PRV_PRCR_LOCK ((BSP_PRV_PRCR_KEY) | 0x0U)
46
47 #if defined(__ICCARM__)
48 #define BSP_PRV_STACK_LIMIT ((uint32_t) __section_begin(".stack"))
49 #define BSP_PRV_STACK_TOP ((uint32_t) __section_end(".stack"))
50 #elif defined(__ARMCC_VERSION)
51 #define BSP_PRV_STACK_LIMIT ((uint32_t) &Image$$STACK$$ZI$$Base)
52 #define BSP_PRV_STACK_TOP ((uint32_t) &Image$$STACK$$ZI$$Base + \
53 (uint32_t) &Image$$STACK$$ZI$$Length)
54 #elif defined(__GNUC__)
55 #define BSP_PRV_STACK_LIMIT ((uint32_t) &__StackLimit)
56 #define BSP_PRV_STACK_TOP ((uint32_t) &__StackTop)
57 #endif
58
59 #define BSP_TZ_STACK_SEAL_VALUE (0xFEF5EDA5)
60
61 /***********************************************************************************************************************
62 * Typedef definitions
63 **********************************************************************************************************************/
64
65 /***********************************************************************************************************************
66 * Exported global variables (to be accessed by other files)
67 **********************************************************************************************************************/
68
69 /** System Clock Frequency (Core Clock) */
70 uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT;
71
72 #if defined(__ARMCC_VERSION)
73 extern uint32_t Image$$BSS$$ZI$$Base;
74 extern uint32_t Image$$BSS$$ZI$$Length;
75 extern uint32_t Load$$DATA$$Base;
76 extern uint32_t Image$$DATA$$Base;
77 extern uint32_t Image$$DATA$$Length;
78 extern uint32_t Image$$STACK$$ZI$$Base;
79 extern uint32_t Image$$STACK$$ZI$$Length;
80 #elif defined(__GNUC__)
81
82 /* Generated by linker. */
83 extern uint32_t __etext;
84 extern uint32_t __data_start__;
85 extern uint32_t __data_end__;
86 extern uint32_t __bss_start__;
87 extern uint32_t __bss_end__;
88 extern uint32_t __StackLimit;
89 extern uint32_t __StackTop;
90 #elif defined(__ICCARM__)
91 #pragma section=".bss"
92 #pragma section=".data"
93 #pragma section=".data_init"
94 #pragma section=".stack"
95 #endif
96
97 /* Initialize static constructors */
98 #if defined(__ARMCC_VERSION)
99 extern void (* Image$$INIT_ARRAY$$Base[])(void);
100 extern void (* Image$$INIT_ARRAY$$Limit[])(void);
101 #elif defined(__GNUC__)
102
103 extern void (* __init_array_start[])(void);
104
105 extern void (* __init_array_end[])(void);
106 #elif defined(__ICCARM__)
107 extern void __call_ctors(void const *, void const *);
108
109 #pragma section = "SHT$$PREINIT_ARRAY" const
110 #pragma section = "SHT$$INIT_ARRAY" const
111 #endif
112
113 extern void * __Vectors[];
114
115 extern void R_BSP_SecurityInit(void);
116
117 /***********************************************************************************************************************
118 * Private global variables and functions
119 **********************************************************************************************************************/
120
121 #if BSP_FEATURE_BSP_RESET_TRNG
122 static void bsp_reset_trng_circuit(void);
123
124 #endif
125
126 #if defined(__ICCARM__)
127
128 void R_BSP_WarmStart(bsp_warm_start_event_t event);
129
130 #pragma weak R_BSP_WarmStart
131
132 #elif defined(__GNUC__) || defined(__ARMCC_VERSION)
133
134 void R_BSP_WarmStart(bsp_warm_start_event_t event) __attribute__((weak));
135
136 #endif
137
138 #if BSP_CFG_EARLY_INIT
139 static void bsp_init_uninitialized_vars(void);
140
141 #endif
142
143 /*******************************************************************************************************************//**
144 * Initialize the MCU and the runtime environment.
145 **********************************************************************************************************************/
SystemInit(void)146 void SystemInit (void)
147 {
148 #if __FPU_USED
149
150 /* Enable the FPU only when it is used.
151 * Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C) */
152
153 /* Set bits 20-23 (CP10 and CP11) to enable FPU. */
154 SCB->CPACR = (uint32_t) CP_MASK;
155 #endif
156
157 #if BSP_TZ_SECURE_BUILD
158
159 /* Seal the main stack for secure projects. Reference:
160 * https://developer.arm.com/documentation/100720/0300
161 * https://developer.arm.com/support/arm-security-updates/armv8-m-stack-sealing */
162 uint32_t * p_main_stack_top = (uint32_t *) __Vectors[0];
163 *p_main_stack_top = BSP_TZ_STACK_SEAL_VALUE;
164 #endif
165
166 #if !BSP_TZ_NONSECURE_BUILD
167
168 /* VTOR is in undefined state out of RESET:
169 * https://developer.arm.com/documentation/100235/0004/the-cortex-m33-peripherals/system-control-block/system-control-block-registers-summary?lang=en.
170 * Set the Secure/Non-Secure VTOR to the vector table address based on the build. This is skipped for non-secure
171 * projects because SCB_NS->VTOR is set by the secure project before the non-secure project runs. */
172 SCB->VTOR = (uint32_t) &__Vectors;
173 #endif
174
175 #if !BSP_TZ_CFG_SKIP_INIT
176 #if BSP_FEATURE_BSP_VBATT_HAS_VBTCR1_BPWSWSTP
177
178 /* Unlock VBTCR1 register. */
179 R_SYSTEM->PRCR = (uint16_t) BSP_PRV_PRCR_PRC1_UNLOCK;
180
181 /* The VBTCR1.BPWSWSTP must be set after reset on MCUs that have VBTCR1.BPWSWSTP. Reference section 11.2.1
182 * "VBATT Control Register 1 (VBTCR1)" and Figure 11.2 "Setting flow of the VBTCR1.BPWSWSTP bit" in the RA4M1 manual
183 * R01UM0007EU0110. This must be done before bsp_clock_init because LOCOCR, LOCOUTCR, SOSCCR, and SOMCR cannot
184 * be accessed until VBTSR.VBTRVLD is set. */
185 R_SYSTEM->VBTCR1 = 1U;
186 FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->VBTSR_b.VBTRVLD, 1U);
187
188 /* Lock VBTCR1 register. */
189 R_SYSTEM->PRCR = (uint16_t) BSP_PRV_PRCR_LOCK;
190 #endif
191 #endif
192
193 #if BSP_FEATURE_TFU_SUPPORTED
194 R_BSP_MODULE_START(FSP_IP_TFU, 0U);
195 #endif
196
197 #if BSP_CFG_EARLY_INIT
198
199 /* Initialize uninitialized BSP variables early for use in R_BSP_WarmStart. */
200 bsp_init_uninitialized_vars();
201 #endif
202
203 /* Call pre clock initialization hook. */
204 R_BSP_WarmStart(BSP_WARM_START_RESET);
205
206 #if BSP_TZ_CFG_SKIP_INIT
207
208 /* Initialize clock variables to be used with R_BSP_SoftwareDelay. */
209 bsp_clock_freq_var_init();
210 #else
211
212 /* Configure system clocks. */
213 bsp_clock_init();
214
215 #if BSP_FEATURE_BSP_RESET_TRNG
216
217 /* To prevent an undesired current draw, this MCU requires a reset
218 * of the TRNG circuit after the clocks are initialized */
219
220 bsp_reset_trng_circuit();
221 #endif
222 #endif
223
224 /* Call post clock initialization hook. */
225 R_BSP_WarmStart(BSP_WARM_START_POST_CLOCK);
226
227 #if BSP_FEATURE_BSP_HAS_SP_MON
228
229 /* Disable MSP monitoring */
230 R_MPU_SPMON->SP[0].CTL = 0;
231
232 /* Setup NMI interrupt */
233 R_MPU_SPMON->SP[0].OAD = BSP_STACK_POINTER_MONITOR_NMI_ON_DETECTION;
234
235 /* Setup start address */
236 R_MPU_SPMON->SP[0].SA = BSP_PRV_STACK_LIMIT;
237
238 /* Setup end address */
239 R_MPU_SPMON->SP[0].EA = BSP_PRV_STACK_TOP;
240
241 /* Set SPEEN bit to enable NMI on stack monitor exception. NMIER bits cannot be cleared after reset, so no need
242 * to read-modify-write. */
243 R_ICU->NMIER = R_ICU_NMIER_SPEEN_Msk;
244
245 /* Enable MSP monitoring */
246 R_MPU_SPMON->SP[0].CTL = 1U;
247 #endif
248
249 #if BSP_FEATURE_TZ_HAS_TRUSTZONE
250
251 /* Use CM33 stack monitor. */
252 __set_MSPLIM(BSP_PRV_STACK_LIMIT);
253 #endif
254
255 #if BSP_CFG_C_RUNTIME_INIT
256
257 /* Initialize C runtime environment. */
258 /* Zero out BSS */
259 #if defined(__ARMCC_VERSION)
260 memset((uint8_t *) &Image$$BSS$$ZI$$Base, 0U, (uint32_t) &Image$$BSS$$ZI$$Length);
261 #elif defined(__GNUC__)
262 memset(&__bss_start__, 0U, ((uint32_t) &__bss_end__ - (uint32_t) &__bss_start__));
263 #elif defined(__ICCARM__)
264 memset((uint32_t *) __section_begin(".bss"), 0U, (uint32_t) __section_size(".bss"));
265 #endif
266
267 /* Copy initialized RAM data from ROM to RAM. */
268 #if defined(__ARMCC_VERSION)
269 memcpy((uint8_t *) &Image$$DATA$$Base, (uint8_t *) &Load$$DATA$$Base, (uint32_t) &Image$$DATA$$Length);
270 #elif defined(__GNUC__)
271 memcpy(&__data_start__, &__etext, ((uint32_t) &__data_end__ - (uint32_t) &__data_start__));
272 #elif defined(__ICCARM__)
273 memcpy((uint32_t *) __section_begin(".data"), (uint32_t *) __section_begin(".data_init"),
274 (uint32_t) __section_size(".data"));
275
276 /* Copy functions to be executed from RAM. */
277 #pragma section=".code_in_ram"
278 #pragma section=".code_in_ram_init"
279 memcpy((uint32_t *) __section_begin(".code_in_ram"),
280 (uint32_t *) __section_begin(".code_in_ram_init"),
281 (uint32_t) __section_size(".code_in_ram"));
282
283 /* Copy main thread TLS to RAM. */
284 #pragma section="__DLIB_PERTHREAD_init"
285 #pragma section="__DLIB_PERTHREAD"
286 memcpy((uint32_t *) __section_begin("__DLIB_PERTHREAD"), (uint32_t *) __section_begin("__DLIB_PERTHREAD_init"),
287 (uint32_t) __section_size("__DLIB_PERTHREAD_init"));
288 #endif
289
290 /* Initialize static constructors */
291 #if defined(__ARMCC_VERSION)
292 int32_t count = Image$$INIT_ARRAY$$Limit - Image$$INIT_ARRAY$$Base;
293 for (int32_t i = 0; i < count; i++)
294 {
295 void (* p_init_func)(void) =
296 (void (*)(void))((uint32_t) &Image$$INIT_ARRAY$$Base + (uint32_t) Image$$INIT_ARRAY$$Base[i]);
297 p_init_func();
298 }
299
300 #elif defined(__GNUC__)
301 int32_t count = __init_array_end - __init_array_start;
302 for (int32_t i = 0; i < count; i++)
303 {
304 __init_array_start[i]();
305 }
306
307 #elif defined(__ICCARM__)
308 void const * pibase = __section_begin("SHT$$PREINIT_ARRAY");
309 void const * ilimit = __section_end("SHT$$INIT_ARRAY");
310 __call_ctors(pibase, ilimit);
311 #endif
312 #endif // BSP_CFG_C_RUNTIME_INIT
313
314 /* Initialize SystemCoreClock variable. */
315 SystemCoreClockUpdate();
316
317 #if !BSP_CFG_PFS_PROTECT
318 #if BSP_TZ_SECURE_BUILD
319 R_PMISC->PWPRS = 0; ///< Clear BOWI bit - writing to PFSWE bit enabled
320 R_PMISC->PWPRS = 1U << BSP_IO_PWPR_PFSWE_OFFSET; ///< Set PFSWE bit - writing to PFS register enabled
321 #else
322 R_PMISC->PWPR = 0; ///< Clear BOWI bit - writing to PFSWE bit enabled
323 R_PMISC->PWPR = 1U << BSP_IO_PWPR_PFSWE_OFFSET; ///< Set PFSWE bit - writing to PFS register enabled
324 #endif
325 #endif
326
327 #if FSP_PRIV_TZ_USE_SECURE_REGS
328
329 /* Ensure that the PMSAR registers are reset (Soft reset does not reset PMSAR). */
330 R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR);
331
332 for (uint32_t i = 0; i < 9; i++)
333 {
334 R_PMISC->PMSAR[i].PMSAR = UINT16_MAX;
335 }
336 R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR);
337 #endif
338
339 #if BSP_TZ_SECURE_BUILD
340
341 /* Initialize security features. */
342 R_BSP_SecurityInit();
343 #endif
344
345 /* Call Post C runtime initialization hook. */
346 R_BSP_WarmStart(BSP_WARM_START_POST_C);
347
348 /* Initialize ELC events that will be used to trigger NVIC interrupts. */
349 bsp_irq_cfg();
350
351 /* Call any BSP specific code. No arguments are needed so NULL is sent. */
352 bsp_init(NULL);
353 }
354
355 /*******************************************************************************************************************//**
356 * This function is called at various points during the startup process.
357 * This function is declared as a weak symbol higher up in this file because it is meant to be overridden by a user
358 * implemented version. One of the main uses for this function is to call functional safety code during the startup
359 * process. To use this function just copy this function into your own code and modify it to meet your needs.
360 *
361 * @param[in] event Where the code currently is in the start up process
362 **********************************************************************************************************************/
R_BSP_WarmStart(bsp_warm_start_event_t event)363 void R_BSP_WarmStart (bsp_warm_start_event_t event)
364 {
365 if (BSP_WARM_START_RESET == event)
366 {
367 /* C runtime environment has not been setup so you cannot use globals. System clocks are not setup. */
368 }
369
370 if (BSP_WARM_START_POST_CLOCK == event)
371 {
372 /* C runtime environment has not been setup so you cannot use globals. Clocks have been initialized. */
373 }
374 else if (BSP_WARM_START_POST_C == event)
375 {
376 /* C runtime environment, system clocks, and pins are all setup. */
377 }
378 else
379 {
380 /* Do nothing */
381 }
382 }
383
384 /*******************************************************************************************************************//**
385 * Disable TRNG circuit to prevent unnecessary current draw which may otherwise occur when the Crypto module
386 * is not in use.
387 **********************************************************************************************************************/
388 #if BSP_FEATURE_BSP_RESET_TRNG
bsp_reset_trng_circuit(void)389 static void bsp_reset_trng_circuit (void)
390 {
391 volatile uint8_t read_port = 0U;
392 FSP_PARAMETER_NOT_USED(read_port); /// Prevent compiler 'unused' warning
393
394 /* Release register protection for low power modes (per RA2A1 User's Manual (R01UH0888EJ0100) Figure 11.13 "Example
395 * of initial setting flow for an unused circuit") */
396 R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_OM_LPC_BATT);
397
398 /* Enable TRNG function (disable stop function) */
399 #if BSP_FEATURE_BSP_HAS_SCE_ON_RA2
400 R_BSP_MODULE_START(FSP_IP_TRNG, 0); ///< TRNG Module Stop needs to be started/stopped for RA2 series.
401 #elif BSP_FEATURE_BSP_HAS_SCE5
402 R_BSP_MODULE_START(FSP_IP_SCE, 0); ///< TRNG Module Stop needs to be started/stopped for RA4 series.
403 #else
404 #error "BSP_FEATURE_BSP_RESET_TRNG is defined but not handled."
405 #endif
406
407 /* Wait for at least 3 PCLKB cycles */
408 read_port = R_PFS->PORT[0].PIN[0].PmnPFS_b.PODR;
409 read_port = R_PFS->PORT[0].PIN[0].PmnPFS_b.PODR;
410 read_port = R_PFS->PORT[0].PIN[0].PmnPFS_b.PODR;
411
412 /* Disable TRNG function */
413 #if BSP_FEATURE_BSP_HAS_SCE_ON_RA2
414 R_BSP_MODULE_STOP(FSP_IP_TRNG, 0); ///< TRNG Module Stop needs to be started/stopped for RA2 series.
415 #elif BSP_FEATURE_BSP_HAS_SCE5
416 R_BSP_MODULE_STOP(FSP_IP_SCE, 0); ///< TRNG Module Stop needs to be started/stopped for RA4 series.
417 #else
418 #error "BSP_FEATURE_BSP_RESET_TRNG is defined but not handled."
419 #endif
420
421 /* Reapply register protection for low power modes (per RA2A1 User's Manual (R01UH0888EJ0100) Figure 11.13 "Example
422 * of initial setting flow for an unused circuit") */
423 R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_OM_LPC_BATT);
424 }
425
426 #endif
427
428 #if BSP_CFG_EARLY_INIT
429
430 /*******************************************************************************************************************//**
431 * Initialize BSP variables not handled by C runtime startup.
432 **********************************************************************************************************************/
bsp_init_uninitialized_vars(void)433 static void bsp_init_uninitialized_vars (void)
434 {
435 g_protect_pfswe_counter = 0;
436
437 extern volatile uint16_t g_protect_counters[];
438 for (uint32_t i = 0; i < 4; i++)
439 {
440 g_protect_counters[i] = 0;
441 }
442
443 extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[];
444 for (uint32_t i = 0; i < 16; i++)
445 {
446 g_bsp_group_irq_sources[i] = 0;
447 }
448
449 #if BSP_CFG_EARLY_INIT
450
451 /* Set SystemCoreClock to MOCO */
452 SystemCoreClock = BSP_MOCO_HZ;
453 #endif
454 }
455
456 #endif
457
458 /** @} (end addtogroup BSP_MCU) */
459