1 /***********************************************************************************************************************
2  * Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
3  *
4  * This file is part of Renesas SynergyTM Software Package (SSP)
5  *
6  * The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
7  * and/or its licensors ("Renesas") and subject to statutory and contractual protections.
8  *
9  * This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
10  * Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
11  * or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
12  * MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
13  * "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14  * PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
15  * CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
16  * CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
17  * included in this file may be subject to different terms.
18  **********************************************************************************************************************/
19 /***********************************************************************************************************************
20 * File Name    : system_S1JA.c
21 * Description  : Initializes C runtime environment, system clocks, pins, and interrupts. Calls warm start functions.
22 ***********************************************************************************************************************/
23 
24 /***********************************************************************************************************************
25 Includes   <System Includes> , "Project Includes"
26 ***********************************************************************************************************************/
27 #include "bsp_api.h"
28 #include "stdlib.h"
29 #if defined(BSP_MCU_GROUP_S1JA)
30 #include "r_elc.h"
31 /* This include file is need only for the 'temporary' fix to insure that the Ioport reference counter is zeroed before it
32  * gets referenced. Ioport init is currently called before the C Runtime initialization takes place.
33  * It will be removed when a more complete solution for this problem is added.
34  */
35 #include "../../../src/driver/r_ioport/hw/hw_ioport_private.h"
36 
37 /* BSP Pin Configuration. Allocate BSP pin configuration table in this module. */
38 #include "bsp_pin_cfg.h"
39 
40 /***********************************************************************************************************************
41 Macro definitions
42 ***********************************************************************************************************************/
43 
44 /***********************************************************************************************************************
45 Typedef definitions
46 ***********************************************************************************************************************/
47 
48 /***********************************************************************************************************************
49 Exported global variables (to be accessed by other files)
50 ***********************************************************************************************************************/
51 /*LDRA_NOANALYSIS LDRA_INSPECTED below not working. */
52 /*LDRA_INSPECTED 27 D This variable must be be publicly accessible per the CMSIS standard. It cannot be static. */
53 uint32_t SystemCoreClock = 0U;  /*!< System Clock Frequency (Core Clock)*/
54 /*LDRA_ANALYSIS */
55 
56 #if defined(__GNUC__)
57 /* Generated by linker. */
58 /*LDRA_INSPECTED 219 S Linker sections start with underscore. */
59 extern uint32_t __etext;
60 /*LDRA_INSPECTED 219 S Linker sections start with underscore. */
61 extern uint32_t __data_start__;
62 /*LDRA_INSPECTED 219 S Linker sections start with underscore. */
63 extern uint32_t __data_end__;
64 /*LDRA_INSPECTED 219 S Linker sections start with underscore. */
65 extern uint32_t __bss_start__;
66 /*LDRA_INSPECTED 219 S Linker sections start with underscore. */
67 extern uint32_t __bss_end__;
68 #elif defined(__ICCARM__)
69 #pragma section=".bss"
70 #pragma section=".data"
71 #pragma section=".data_init"
72 #endif
73 
74 /* Initialize Static Constructors */
75 #if defined(__GNUC__)
76 /*LDRA_INSPECTED 219 S In the GCC compiler, __init_array_start starts with underscore. */
77 /*LDRA_INSPECTED 219 S */
78 extern void (*__init_array_start []) (void);
79 /*LDRA_INSPECTED 219 S In the GCC compiler, __init_array_end starts with underscore. */
80 /*LDRA_INSPECTED 219 S */
81 extern void (*__init_array_end []) (void);
82 #elif defined(__ICCARM__)
83 extern void __call_ctors(void const *, void const *);
84 #pragma section = "SHT$$PREINIT_ARRAY" const
85 #pragma section = "SHT$$INIT_ARRAY" const
86 #endif
87 
88 /* IOPORT implementation for this BSP. */
89 extern const ioport_api_t g_ioport_on_ioport;
90 
91 /***********************************************************************************************************************
92 Private global variables and functions
93 ***********************************************************************************************************************/
94 static void bsp_section_zero(uint8_t * pstart, uint32_t bytes);
95 static void bsp_section_copy(uint8_t * psource, uint8_t * pdest, uint32_t bytes);
96 static void bsp_reset_trng_circuit(void);
97 static void bsp_init_prng(void);
98 
99 /* ram section to read for prng seed generation */
100 /*LDRA_INSPECTED 219 S*/
101 /*LDRA_INSPECTED 57 D*/
102 /*LDRA_INSPECTED 57 D*/
103 static volatile uint64_t bsp_seed BSP_PLACE_IN_SECTION_V2(".noinit");
104 
105 /** Currently this structure is not being used. Eventually it will be tool generated. */
106 static const elc_cfg_t g_elc_cfg =
107 {
108     .autostart = true,
109     .link_count  = 0U,
110     .link_list = NULL
111 };
112 
113 #if defined(__ICCARM__)
114 #pragma weak R_BSP_WarmStart
115 void R_BSP_WarmStart(bsp_warm_start_event_t event);
116 #elif defined(__GNUC__)
117 /*LDRA_INSPECTED 293 S - There is no way to implement a weak reference without using a Non ANSI/ISO construct. */
118 void R_BSP_WarmStart (bsp_warm_start_event_t event) __attribute__ ((weak));
119 #endif
120 
121 /***********************************************************************************************************************
122 * Function Name: SystemCoreClockUpdate
123 * Description  : Update SystemCoreClock variable based on current clock settings.
124 * Arguments    : none
125 * Return Value : none
126 ***********************************************************************************************************************/
SystemCoreClockUpdate(void)127 void SystemCoreClockUpdate (void)
128 {
129     SystemCoreClock = bsp_cpu_clock_get();
130 }
131 
132 /***********************************************************************************************************************
133 * Function Name: SystemInit
134 * Description  : Setup MCU.
135 * Arguments    : none
136 * Return Value : none
137 ***********************************************************************************************************************/
SystemInit(void)138 void SystemInit (void)
139 {
140     /* Call Pre C runtime initialization hook. */
141     R_BSP_WarmStart(BSP_WARM_START_PRE_C);
142 
143     /* Initialize register protection. */
144     bsp_register_protect_open();
145 
146     /* Initialize grouped interrupts. */
147     bsp_group_interrupt_open();
148 
149     /* Initialize FMI. */
150     g_fmi_on_fmi.init();
151 
152     /* Configure system clocks using CGC module. */
153     bsp_clock_init();
154 
155     /* To prevent an undesired current draw, this MCU requires a reset of the TRNG circuit subsequent to having the clocks initialized */
156     bsp_reset_trng_circuit();
157 
158     /* Temporary fix to initialize ioport reference counter to 0, needed before C runtime init. This will be removed
159      * in the next release in favor of a more complete solution. */
160     HW_IOPORT_Init_Reference_Counter();
161 
162     /* Initialize pins. */
163     g_ioport_on_ioport.init(&g_bsp_pin_cfg);
164 
165     /* Initialize C runtime environment. */
166     /* Zero out BSS */
167 #if defined(__GNUC__)
168     bsp_section_zero((uint8_t *)&__bss_start__, ((uint32_t)&__bss_end__ - (uint32_t)&__bss_start__));
169 #elif defined(__ICCARM__)
170     bsp_section_zero((uint8_t *)__section_begin(".bss"), (uint32_t)__section_size(".bss"));
171 #endif
172 
173     /* Copy initialized RAM data from ROM to RAM. */
174 #if defined(__GNUC__)
175     bsp_section_copy((uint8_t *)&__etext,
176                      (uint8_t *)&__data_start__,
177                      ((uint32_t)&__data_end__ - (uint32_t)&__data_start__));
178 #elif defined(__ICCARM__)
179     bsp_section_copy((uint8_t *)__section_begin(".data_init"),
180                      (uint8_t *)__section_begin(".data"),
181                      (uint32_t)__section_size(".data"));
182     /* Copy functions to be executed from RAM. */
183     #pragma section=".code_in_ram"
184     #pragma section=".code_in_ram_init"
185     bsp_section_copy((uint8_t *)__section_begin(".code_in_ram_init"),
186                      (uint8_t *)__section_begin(".code_in_ram"),
187                      (uint32_t)__section_size(".code_in_ram"));
188     /* Copy main thread TLS to RAM. */
189     #pragma section="__DLIB_PERTHREAD_init"
190     #pragma section="__DLIB_PERTHREAD"
191     bsp_section_copy((uint8_t *)__section_begin("__DLIB_PERTHREAD_init"),
192                      (uint8_t *)__section_begin("__DLIB_PERTHREAD"),
193                      (uint32_t)__section_size("__DLIB_PERTHREAD_init"));
194 #endif
195 
196 #if defined(__IAR_SYSTEMS_ICC__)
197     #pragma section=".stack"
198 #elif defined(__GNUC__)
199     /*LDRA_INSPECTED 219 S Linker sections start with underscore. */
200     extern uint32_t __StackLimit;
201     /*LDRA_INSPECTED 219 S Linker sections start with underscore. */
202     extern uint32_t __StackTop;
203 #endif
204 
205     R_SPMON->MSPMPUCTL = (uint16_t) 0x0000;                   /* Disable MSP monitoring  */
206 
207     R_SPMON->MSPMPUOAD = 0xA500;                              /* Setup NMI interrupt  */
208 
209 #if defined(__IAR_SYSTEMS_ICC__)
210     R_SPMON->MSPMPUSA = (uint32_t)__section_begin(".stack");   /* Setup start address  */
211     R_SPMON->MSPMPUEA = (uint32_t)__section_end(".stack") - 1U;/* Setup end address  */
212 
213 #elif defined(__GNUC__)
214     R_SPMON->MSPMPUSA = (uint32_t)&__StackLimit;               /* Setup start address  */
215     R_SPMON->MSPMPUEA = (uint32_t)&__StackTop - 1U;            /* Setup end address  */
216 
217 #endif
218 
219     R_ICU->NMIER |= (uint16_t)0x1000;                          /* Set SPEEN bit to enable NMI on stack monitor exception */
220     R_SPMON->MSPMPUCTL = (uint16_t)0x0001;                     /* Enable MSP monitoring  */
221 
222     /* Initialize SystemCoreClock variable. */
223     SystemCoreClockUpdate();
224 
225     /* Call Post C runtime initialization hook. */
226     R_BSP_WarmStart(BSP_WARM_START_POST_C);
227 
228     /* Initialize Static Constructors */
229 #if defined(__GNUC__)
230     /*LDRA_INSPECTED 219 S In the GCC compiler, __init_array_start and __init_array_end starts with underscore. */
231     /*LDRA_INSPECTED 219 S */
232     int32_t count = __init_array_end - __init_array_start;
233     for (int32_t i = 0; i < count; i++)
234     {
235         __init_array_start [i]();
236     }
237 #elif defined(__ICCARM__)
238     void const * pibase = __section_begin("SHT$$PREINIT_ARRAY");
239     void const * ilimit = __section_end("SHT$$INIT_ARRAY");
240     __call_ctors(pibase, ilimit);
241 #endif
242 
243     /* Initialize the Hardware locks to 'Unlocked' */
244     bsp_init_hardware_locks();
245 
246     /* Initialize ELC events that will be used to trigger NVIC interrupts. */
247     bsp_irq_cfg();
248 
249     /* Initialize ELC. */
250     g_elc_on_elc.init(&g_elc_cfg);
251 
252     /* Initialize the libc pseudo random number generator */
253     bsp_init_prng();
254 
255     /* Call any BSP specific code. No arguments are needed so NULL is sent. */
256     bsp_init(NULL);
257 }
258 
259 /***********************************************************************************************************************
260 * Function Name: bsp_section_zero
261 * Description  : Zero out input section
262 * Arguments    : pstart -
263 *                    Start address of the section
264 *                bytes -
265 *                    Size of section in bytes
266 * Return Value : none
267 ***********************************************************************************************************************/
bsp_section_zero(uint8_t * pstart,uint32_t bytes)268 static void bsp_section_zero (uint8_t * pstart, uint32_t bytes)
269 {
270     while (bytes > 0U)
271     {
272         bytes--;
273         pstart[bytes] = 0U;
274     }
275 }
276 
277 /***********************************************************************************************************************
278 * Function Name: bsp_section_copy
279 * Description  : Zero out input section
280 * Arguments    : psource -
281 *                    Address of where to copy data from
282 *                pdest -
283 *                    Address of where to copy data to
284 *                bytes -
285 *                    Size of section in bytes
286 * Return Value : none
287 ***********************************************************************************************************************/
bsp_section_copy(uint8_t * psource,uint8_t * pdest,uint32_t bytes)288 static void bsp_section_copy (uint8_t * psource, uint8_t * pdest, uint32_t bytes)
289 {
290     uint32_t index;
291     for (index = 0U; index < bytes; index++,pdest++,psource++)
292     {
293         *pdest = *psource;
294     }
295 }
296 
297 /***********************************************************************************************************************
298 * Function Name: R_BSP_WarmStart
299 * Description  : This function is called at various points during the startup process. This function is declared as a
300 *                weak symbol higher up in this file because it is meant to be overridden by a user implemented version.
301 *                One of the main uses for this function is to call functional safety code during the startup process.
302 *                To use this function just copy this function into your own code and modify it to meet your needs.
303 * Arguments    : event -
304 *                    Where at in the start up process the code is currently at
305 * Return Value : none
306 ***********************************************************************************************************************/
R_BSP_WarmStart(bsp_warm_start_event_t event)307 void R_BSP_WarmStart (bsp_warm_start_event_t event)
308 {
309     if (BSP_WARM_START_PRE_C == event)
310     {
311         /* C runtime environment has not been setup so you cannot use globals. System clocks and pins are not setup. */
312     }
313     else if (BSP_WARM_START_POST_C == event)
314     {
315         /* C runtime environment, system clocks, and pins are all setup. */
316     }
317     else
318     {
319         /* Unhandled case. */
320     }
321 }
322 
323 /*******************************************************************************************************************//**
324  * @brief Disable trng circuit to prevent unnecessary current draw which may otherwise occur when the Crypto module
325  * is not in use.
326  *
327  **********************************************************************************************************************/
bsp_reset_trng_circuit(void)328 static void bsp_reset_trng_circuit (void)
329 {
330     volatile uint8_t read_port = 0U;
331     SSP_PARAMETER_NOT_USED(read_port);   /// Prevent compiler 'unused' warning
332 
333     /* Enable TRNG function (disable stop function) */
334     R_MSTP->MSTPCRC_b.MSTPC28 = 0U;      ///< TRNG Module Stop needs to be started/stopped for S1 series.
335 
336     /* Wait for at least 3 PCLKB cycles */
337     read_port = R_PFS->P000PFS_b.PODR;
338     read_port = R_PFS->P000PFS_b.PODR;
339     read_port = R_PFS->P000PFS_b.PODR;
340 
341     /* Disable TRNG function (enable stop function) */
342     R_MSTP->MSTPCRC_b.MSTPC28 = 1U;
343 }
344 
345 /*******************************************************************************************************************//**
346  * @brief Read ram section that has not been initialized and use that value to generate a seed value for the libc PRNG.
347  *
348  **********************************************************************************************************************/
bsp_init_prng(void)349 static void bsp_init_prng(void)
350 {
351     uint64_t temp = (bsp_seed & 0xFFFFFFFF);
352     /*initialize srand() with SRAM value*/
353     srand( (uint32_t)(temp^(bsp_seed >> 32)) );
354     bsp_seed += (0xF4E64FE3A1E75416ULL); //large prime in LE64
355     bsp_seed ^= (0xFDAD522B9E92B837ULL); //another large prime in LE64
356 }
357 
358 #endif
359