Contiki-NG
startup_cc13xx_cc26xx_gcc.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28  * OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 /**
31  * \addtogroup cc13xx-cc26xx-cpu
32  * @{
33  *
34  * \file
35  * Startup file for GCC for CC13xx/CC26xx.
36  */
37 /*---------------------------------------------------------------------------*/
38 /* Check if compiler is GNU Compiler. */
39 #if !(defined(__GNUC__))
40 #error "startup_cc13xx_cc26xx_gcc.c: Unsupported compiler!"
41 #endif
42 /*---------------------------------------------------------------------------*/
43 #include <string.h>
44 
45 #include <ti/devices/DeviceFamily.h>
46 #include DeviceFamily_constructPath(inc/hw_types.h)
47 #include DeviceFamily_constructPath(driverlib/interrupt.h)
48 #include DeviceFamily_constructPath(driverlib/setup.h)
49 /*---------------------------------------------------------------------------*/
50 /* Forward declaration of the default fault handlers. */
51 void resetISR(void);
52 static void nmiISR(void);
53 static void faultISR(void);
54 static void defaultHandler(void);
55 static void busFaultHandler(void);
56 /*---------------------------------------------------------------------------*/
57 /*
58  * External declaration for the reset handler that is to be called when the
59  * processor is started.
60  */
61 extern void _c_int00(void);
62 
63 /* The entry point for the application. */
64 extern int main(void);
65 /*---------------------------------------------------------------------------*/
66 /* Linker variable that marks the top of stack. */
67 extern unsigned long _stack_end;
68 
69 /*
70  * The vector table. Note that the proper constructs must be placed on this to
71  * ensure that it ends up at physical address 0x0000.0000.
72  */
73 __attribute__((section(".resetVecs"))) __attribute__((used))
74 static void(*const resetVectors[16])(void) =
75 {
76  (void(*)(void))((uint32_t)&_stack_end),
77  /* The initial stack pointer */
78  resetISR, /* The reset handler */
79  nmiISR, /* The NMI handler */
80  faultISR, /* The hard fault handler */
81  defaultHandler, /* The MPU fault handler */
82  busFaultHandler, /* The bus fault handler */
83  defaultHandler, /* The usage fault handler */
84  0, /* Reserved */
85  0, /* Reserved */
86  0, /* Reserved */
87  0, /* Reserved */
88  defaultHandler, /* SVCall handler */
89  defaultHandler, /* Debug monitor handler */
90  0, /* Reserved */
91  defaultHandler, /* The PendSV handler */
92  defaultHandler /* The SysTick handler */
93 };
94 /*---------------------------------------------------------------------------*/
95 /*
96  * The following are arrays of pointers to constructor functions that need to
97  * be called during startup to initialize global objects.
98  */
99 extern void (*__init_array_start[])(void);
100 extern void (*__init_array_end[])(void);
101 
102 /* The following global variable is required for C++ support. */
103 void *__dso_handle = (void *)&__dso_handle;
104 /*---------------------------------------------------------------------------*/
105 /*
106  * The following are constructs created by the linker, indicating where the
107  * the "data" and "bss" segments reside in memory. The initializers for the
108  * for the "data" segment resides immediately following the "text" segment.
109  */
110 extern uint32_t __bss_start__;
111 extern uint32_t __bss_end__;
112 extern uint32_t __data_load__;
113 extern uint32_t __data_start__;
114 extern uint32_t __data_end__;
115 /*---------------------------------------------------------------------------*/
116 /*
117  * \brief Entry point of the startup code.
118  *
119  * Initialize the .data and .bss sections, and call main.
120  */
121 void
122 localProgramStart(void)
123 {
124  uint32_t *bs;
125  uint32_t *be;
126  uint32_t *dl;
127  uint32_t *ds;
128  uint32_t *de;
129  uint32_t count;
130  uint32_t i;
131 
132  IntMasterDisable();
133 
134  /* Final trim of device */
135  SetupTrimDevice();
136 
137  /* initiailize .bss to zero */
138  bs = &__bss_start__;
139  be = &__bss_end__;
140  while(bs < be) {
141  *bs = 0;
142  bs++;
143  }
144 
145  /* relocate the .data section */
146  dl = &__data_load__;
147  ds = &__data_start__;
148  de = &__data_end__;
149  if(dl != ds) {
150  while(ds < de) {
151  *ds = *dl;
152  dl++;
153  ds++;
154  }
155  }
156 
157  /* Run any constructors */
158  count = (uint32_t)(__init_array_end - __init_array_start);
159  for(i = 0; i < count; i++) {
160  __init_array_start[i]();
161  }
162 
163  /* Call the application's entry point. */
164  main();
165 
166  /* If we ever return signal Error */
167  faultISR();
168 }
169 /*---------------------------------------------------------------------------*/
170 /*
171  * \brief Reset ISR.
172  *
173  * This is the code that gets called when the processor first starts execution
174  * following a reset event. Only the absolutely necessary set is performed,
175  * after which the application supplied entry() routine is called. Any fancy
176  * actions (such as making decisions based on the reset cause register, and
177  * resetting the bits in that register) are left solely in the hands of the
178  * application.
179  */
180 void __attribute__((naked))
181 resetISR(void)
182 {
183  __asm__ __volatile__
184  (
185  "movw r0, #:lower16:resetVectors \n"
186  "movt r0, #:upper16:resetVectors \n"
187  "ldr r0, [r0] \n"
188  "mov sp, r0 \n"
189  "bx %0 \n"
190  : /* output */
191  : /* input */
192  "r"(localProgramStart)
193  );
194 }
195 /*---------------------------------------------------------------------------*/
196 /*
197  * \brief Non-Maskable Interrupt (NMI) ISR.
198  *
199  * This is the code that gets called when the processor receives a NMI. This
200  * simply enters an infinite loop, preserving the system state for examination
201  * by a debugger.
202  */
203 static void
204 nmiISR(void)
205 {
206  /* Enter an infinite loop. */
207  for(;;) { /* hang */ }
208 }
209 /*---------------------------------------------------------------------------*/
210 /*
211  * \brief Debug stack pointer.
212  * \param sp Stack pointer.
213  *
214  * Provide a view into the CPU state from the provided stack pointer.
215  */
216 static void
217 debugHardfault(uint32_t *sp)
218 {
219  volatile uint32_t r0; /**< R0 register */
220  volatile uint32_t r1; /**< R1 register */
221  volatile uint32_t r2; /**< R2 register */
222  volatile uint32_t r3; /**< R3 register */
223  volatile uint32_t r12; /**< R12 register */
224  volatile uint32_t lr; /**< LR register */
225  volatile uint32_t pc; /**< PC register */
226  volatile uint32_t psr; /**< PSR register */
227 
228  (void)(r0 = sp[0]);
229  (void)(r1 = sp[1]);
230  (void)(r2 = sp[2]);
231  (void)(r3 = sp[3]);
232  (void)(r12 = sp[4]);
233  (void)(lr = sp[5]);
234  (void)(pc = sp[6]);
235  (void)(psr = sp[7]);
236 
237  /* Enter an infinite loop. */
238  for(;;) { /* hang */ }
239 }
240 /*---------------------------------------------------------------------------*/
241 /*
242  * \brief CPU Fault ISR.
243  *
244  * This is the code that gets called when the processor receives a fault
245  * interrupt. Setup a call to debugStackPointer with the current stack pointer.
246  * The stack pointer in this case would be the CPU state which caused the CPU
247  * fault.
248  */
249 static void
250 faultISR(void)
251 {
252  __asm__ __volatile__
253  (
254  "tst lr, #4 \n"
255  "ite eq \n"
256  "mrseq r0, msp \n"
257  "mrsne r0, psp \n"
258  "bx %0 \n"
259  : /* output */
260  : /* input */
261  "r"(debugHardfault)
262  );
263 }
264 /*---------------------------------------------------------------------------*/
265 /* Dummy variable */
266 volatile int x__;
267 
268 /*
269  * \brief Bus Fault Handler.
270  *
271  * This is the code that gets called when the processor receives an unexpected
272  * interrupt. This simply enters an infinite loop, preserving the system state
273  * for examination by a debugger.
274  */
275 static void
276 busFaultHandler(void)
277 {
278  x__ = 0;
279 
280  /* Enter an infinite loop. */
281  for(;;) { /* hang */ }
282 }
283 /*---------------------------------------------------------------------------*/
284 /*
285  * \brief Default Handler.
286  *
287  * This is the code that gets called when the processor receives an unexpected
288  * interrupt. This simply enters an infinite loop, preserving the system state
289  * for examination by a debugger.
290  */
291 static void
292 defaultHandler(void)
293 {
294  /* Enter an infinite loop. */
295  for(;;) { /* hang */ }
296 }
297 /*---------------------------------------------------------------------------*/
298 /*
299  * \brief Finalize object function.
300  *
301  * This function is called by __libc_fini_array which gets called when exit()
302  * is called. In order to support exit(), an empty _fini() stub function is
303  * required.
304  */
305 void
306 _fini(void)
307 {
308  /* Function body left empty intentionally */
309 }
310 /*---------------------------------------------------------------------------*/
311 /** @} */
static void debugHardfault(uint32_t *sp)