xref: /btstack/port/renesas-ek-ra6m4a-da14531/e2-project/ra/fsp/src/bsp/cmsis/Device/RENESAS/Source/system.c (revision c30869498fb8e98c1408c9db0e7624f02f483b73)
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