1 /** @file sys_startup.c
2 *   @brief Startup Source File
3 *   @date 29.May.2013
4 *   @version 03.05.02
5 *
6 *   This file contains:
7 *   - Include Files
8 *   - Type Definitions
9 *   - External Functions
10 *   - VIM RAM Setup
11 *   - Startup Routine
12 *   .
13 *   which are relevant for the Startup.
14 */
15 
16 /* (c) Texas Instruments 2009-2013, All rights reserved. */
17 
18 /* Include Files */
19 
20 #include "sys_common.h"
21 #include "system.h"
22 #include "sys_vim.h"
23 #include "sys_core.h"
24 #include "sys_selftest.h"
25 #include "esm.h"
26 #include "mibspi.h"
27 
28 /* Type Definitions */
29 
30 typedef void (*handler_fptr)(const uint8 * in, uint8 * out);
31 
32 /* External Functions */
33 
34 /*SAFETYMCUSW 94 S MR:11.1 <REVIEWED> "Startup code(handler pointers)" */
35 /*SAFETYMCUSW 296 S MR:8.6 <REVIEWED> "Startup code(library functions at block scope)" */
36 /*SAFETYMCUSW 298 S MR:  <REVIEWED> "Startup code(handler pointers)" */
37 /*SAFETYMCUSW 299 S MR:  <REVIEWED> "Startup code(typedef for handler pointers in library )" */
38 /*SAFETYMCUSW 326 S MR:8.2 <REVIEWED> "Startup code(Declaration for main in library)" */
39 /*SAFETYMCUSW 60 D MR:8.8 <REVIEWED> "Startup code(Declaration for main in library;Only doing an extern for the same)" */
40 /*SAFETYMCUSW 94 S MR:11.1 <REVIEWED> "Startup code(handler pointers)" */
41 /*SAFETYMCUSW 354 S MR:1.4 <REVIEWED> " Startup code(Extern declaration present in the library)" */
42 
43 /*SAFETYMCUSW 218 S MR:20.2 <REVIEWED> "Functions from library" */
44 
45 #ifdef __TI_COMPILER_VERSION__
46 #pragma WEAK(__TI_Handler_Table_Base)
47 #pragma WEAK(__TI_Handler_Table_Limit)
48 #pragma WEAK(__TI_CINIT_Base)
49 #pragma WEAK(__TI_CINIT_Limit)
50 
51 extern uint32   __TI_Handler_Table_Base;
52 extern uint32   __TI_Handler_Table_Limit;
53 extern uint32   __TI_CINIT_Base;
54 extern uint32   __TI_CINIT_Limit;
55 extern uint32   __TI_PINIT_Base;
56 extern uint32   __TI_PINIT_Limit;
57 extern uint32 * __binit__;
58 #endif
59 
60 extern void main(void);
61 
62 /* Startup Routine */
63 
64 /** @fn void memoryInit(uint32 ram)
65 *   @brief Memory Initialization Driver
66 *
67 *   This function is called to perform Memory initialization of selected RAM's.
68 */
memoryInit(uint32 ram)69 void memoryInit(uint32 ram)
70 {
71 	/* Enable Memory Hardware Initialization */
72 	systemREG1->MINITGCR = 0xAU;
73 
74     /* Enable Memory Hardware Initialization for selected RAM's */
75 	systemREG1->MSINENA  = ram;
76 
77 	/* Wait until Memory Hardware Initialization complete */
78 	while((systemREG1->MSTCGSTAT & 0x00000100U) != 0x00000100U)
79 	{
80 	}/* Wait */
81 
82 	/* Disable Memory Hardware Initialization */
83 	systemREG1->MINITGCR = 0x5U;
84 }
85 
_c_int00(void)86 void _c_int00(void)
87 {
88     /* Work Around for Errata DEVICE#140: ( Only on Rev A silicon)
89      *
90      * Errata Description:
91      *            The Core Compare Module(CCM-R4) may cause nERROR to be asserted after a cold power-on
92      * Workaround:
93      *            Clear ESM Group2 Channel 2 error in ESMSR2 and Compare error in CCMSR register */
94     if (DEVICE_ID_REV == 0x802AAD05U)
95     {
96         _esmCcmErrorsClear_();
97     }
98 
99     _errata_CORTEXR4_66_();
100     _errata_CORTEXR4_57_();
101     /* Reset handler: the following instructions read from the system exception status register
102      * to identify the cause of the CPU reset. */
103     /* check for power-on reset condition */
104     if ((SYS_EXCEPTION & POWERON_RESET) != 0U)
105     {
106         /* clear all reset status flags */
107         SYS_EXCEPTION = 0xFFFFU;
108         /* continue with normal start-up sequence */
109     }
110     else if ((SYS_EXCEPTION & OSC_FAILURE_RESET) != 0U)
111     {
112         /* Reset caused due to oscillator failure.
113         Add user code here to handle oscillator failure */
114     }
115     else if ((SYS_EXCEPTION & WATCHDOG_RESET) !=0U)
116     {
117         /* Reset caused due
118          *  1) windowed watchdog violation - Add user code here to handle watchdog violation.
119          *  2) ICEPICK Reset - After loading code via CCS / System Reset through CCS
120          */
121         /* Check the WatchDog Status register */
122         if(WATCHDOG_STATUS != 0U)
123         {
124             /* Add user code here to handle watchdog violation. */
125             /* Clear the Watchdog reset flag in Exception Status register */
126             SYS_EXCEPTION = WATCHDOG_RESET;
127         }
128         else
129         {
130             /* Clear the ICEPICK reset flag in Exception Status register */
131             SYS_EXCEPTION = ICEPICK_RESET;
132         }
133     }
134     else if ((SYS_EXCEPTION & CPU_RESET) !=0U)
135     {
136         /* Reset caused due to CPU reset.
137         CPU reset can be caused by CPU self-test completion, or
138         by toggling the "CPU RESET" bit of the CPU Reset Control Register. */
139         /* clear all reset status flags */
140         SYS_EXCEPTION = CPU_RESET;
141     }
142     else if ((SYS_EXCEPTION & SW_RESET) != 0U)
143     {
144         /* Reset caused due to software reset.
145         Add user code to handle software reset. */
146     }
147     else
148     {
149         /* Reset caused by nRST being driven low externally.
150         Add user code to handle external reset. */
151     }
152 
153     /* Initialize System - Clock, Flash settings with Efuse self check */
154     systemInit();
155 
156     /* Initialize CPU RAM.
157      * This function uses the system module's hardware for auto-initialization of memories and their
158      * associated protection schemes. The CPU RAM is initialized by setting bit 0 of the MSIENA register.
159      * Hence the value 0x1 passed to the function.
160      * This function will initialize the entire CPU RAM and the corresponding ECC locations.
161      */
162     memoryInit(0x1U);
163 
164     _coreEnableRamEcc_();
165     /* Release the MibSPI1 modules from local reset.
166      * This will cause the MibSPI1 RAMs to get initialized along with the parity memory.
167      */
168      mibspiREG1->GCR0 = 0x1U;
169 
170     /* Release the MibSPI3 modules from local reset.
171      * This will cause the MibSPI3 RAMs to get initialized along with the parity memory.
172      */
173     mibspiREG3->GCR0 = 0x1U;
174 
175     /* Release the MibSPI5 modules from local reset.
176      * This will cause the MibSPI5 RAMs to get initialized along with the parity memory.
177      */
178     mibspiREG5->GCR0 = 0x1U;
179 
180     /* Initialize all on-chip SRAMs except for MibSPIx RAMs The MibSPIx modules
181      * have their own auto-initialization mechanism which is triggered as soon
182      * as the modules are brought out of local reset.  */
183     /* The system module auto-init will hang on the MibSPI RAM if the module is
184      * still in local reset.  */
185     /* NOTE : Please Refer DEVICE DATASHEET for the list of Supported Memories
186      * and their channel numbers.  Memory Initialization is perfomed only on
187      * the user selected memories in HALCoGen's GUI SAFETY INIT tab.  */
188     memoryInit((1U << 1U) | (1U << 2U) | (1U << 5U) | (1U << 6U)
189                | (1U << 10U) | (1U << 8U) | (1U << 14U) | (1U << 3U)
190                | (1U << 4U) | (1U << 15U) | (1U << 16U) | (0U << 13U) );
191 
192     while ((mibspiREG1->FLG & 0x01000000U) == 0x01000000U)
193     {
194     }/* Wait */
195     /* wait for MibSPI1 RAM to complete initialization */
196     while ((mibspiREG3->FLG & 0x01000000U) == 0x01000000U)
197     {
198     }/* Wait */
199     /* wait for MibSPI3 RAM to complete initialization */
200     while ((mibspiREG5->FLG & 0x01000000U) == 0x01000000U)
201     {
202     }/* Wait */
203     /* wait for MibSPI5 RAM to complete initialization */
204 
205     /* Initialize VIM table */
206     vimInit();
207 
208 #ifdef __GNUC__
209     data_init();
210 #elif defined(__TI_COMPILER_VERSION__)
211     /* initialize copy table */
212     if ((uint32 *)&__binit__ != (uint32 *)0xFFFFFFFFU)
213     {
214         extern void copy_in(void * binit);
215         copy_in((void *)&__binit__);
216     }
217 
218     /* initialize the C global variables */
219     if (&__TI_Handler_Table_Base < &__TI_Handler_Table_Limit)
220     {
221         uint8 **tablePtr   = (uint8 **)&__TI_CINIT_Base;
222         uint8 **tableLimit = (uint8 **)&__TI_CINIT_Limit;
223 
224         while (tablePtr < tableLimit)
225         {
226             uint8 * loadAdr = *tablePtr++;
227             uint8 * runAdr  = *tablePtr++;
228             uint8  idx     = *loadAdr++;
229             handler_fptr   handler = (handler_fptr)(&__TI_Handler_Table_Base)[idx];
230 
231             (*handler)((const uint8 *)loadAdr, runAdr);
232         }
233     }
234 
235     /* initialize constructors */
236     if (__TI_PINIT_Base < __TI_PINIT_Limit)
237     {
238         void (**p0)(void) = (void *)__TI_PINIT_Base;
239 
240         while ((uint32)p0 < __TI_PINIT_Limit)
241         {
242             void (*p)(void) = *p0++;
243             p();
244         }
245     }
246 #endif
247     /* call the application */
248     main();
249 }
250