common: Implement jump_to_application().
[gps-watch.git] / src / common / startup.c
1 /*
2  * Copyright (c) 2019 Tilman Sauerbeck (tilman at code-monkey de)
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23
24 #include <stdint.h>
25
26 void Reset_Handler (void);
27 void NMI_Handler (void) __attribute__ ((weak, alias("Dummy_Handler")));
28 void HardFault_Handler (void) __attribute__ ((weak, alias("Dummy_Handler")));
29 void SVC_Handler (void) __attribute__ ((weak, alias("Dummy_Handler")));
30 void PendSV_Handler (void) __attribute__ ((weak, alias("Dummy_Handler")));
31 void SysTick_Handler (void) __attribute__ ((weak, alias("Dummy_Handler")));
32
33 void DMA0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
34 void DMA1_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
35 void DMA2_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
36 void DMA3_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
37 void FTFA_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
38 void PMC_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
39 void LLWU_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
40 void I2C0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
41 void I2C1_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
42 void SPI0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
43 void SPI1_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
44 void UART0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
45 void UART1_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
46 void UART2_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
47 void ADC0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
48 void CMP0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
49 void TPM0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
50 void TPM1_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
51 void TPM2_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
52 void RTC_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
53 void RTC_Seconds_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
54 void PIT_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
55 void I2S0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
56 void USB0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
57 void DAC0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
58 void TSI0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
59 void MCG_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
60 void LPTMR0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
61 void PORTA_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
62 void PORTC_PORTD_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
63
64 extern void _start (void) __attribute__((noreturn));
65
66 extern uint32_t __etext;
67 extern uint32_t __data_start__;
68 extern uint32_t __data_end__;
69 extern uint32_t __bss_start__;
70 extern uint32_t __bss_end__;
71 extern uint32_t __StackTop;
72
73 __attribute__ ((section(".vectors")))
74 const void * __Vectors[48] =
75 {
76         &__StackTop, /* Initial stack pointer */
77
78         (void *) Reset_Handler,
79         (void *) NMI_Handler,
80         (void *) HardFault_Handler,
81         (void *) (0UL), /* Reserved */
82         (void *) (0UL), /* Reserved */
83         (void *) (0UL), /* Reserved */
84         (void *) (0UL), /* Reserved */
85         (void *) (0UL), /* Reserved */
86         (void *) (0UL), /* Reserved */
87         (void *) (0UL), /* Reserved */
88         (void *) SVC_Handler,
89         (void *) (0UL), /* Reserved */
90         (void *) (0UL), /* Reserved */
91         (void *) PendSV_Handler,
92         (void *) SysTick_Handler,
93
94         (void *) DMA0_IRQHandler,
95         (void *) DMA1_IRQHandler,
96         (void *) DMA2_IRQHandler,
97         (void *) DMA3_IRQHandler,
98         (void *) (0UL), /* Reserved */
99         (void *) FTFA_IRQHandler,
100         (void *) PMC_IRQHandler,
101         (void *) LLWU_IRQHandler,
102         (void *) I2C0_IRQHandler,
103         (void *) I2C1_IRQHandler,
104         (void *) SPI0_IRQHandler,
105         (void *) SPI1_IRQHandler,
106         (void *) UART0_IRQHandler,
107         (void *) UART1_IRQHandler,
108         (void *) UART2_IRQHandler,
109         (void *) ADC0_IRQHandler,
110         (void *) CMP0_IRQHandler,
111         (void *) TPM0_IRQHandler,
112         (void *) TPM1_IRQHandler,
113         (void *) TPM2_IRQHandler,
114         (void *) RTC_IRQHandler,
115         (void *) RTC_Seconds_IRQHandler,
116         (void *) PIT_IRQHandler,
117         (void *) I2S0_IRQHandler,
118         (void *) USB0_IRQHandler,
119         (void *) DAC0_IRQHandler,
120         (void *) TSI0_IRQHandler,
121         (void *) MCG_IRQHandler,
122         (void *) LPTMR0_IRQHandler,
123         (void *) (0UL), /* Reserved */
124         (void *) PORTA_IRQHandler,
125         (void *) PORTC_PORTD_IRQHandler,
126 };
127
128 void
129 Reset_Handler (void)
130 {
131         uint32_t *src, *dst;
132
133         src = &__etext;
134         dst = &__data_start__;
135
136         /* Initialize data. */
137         while (dst < &__data_end__)
138                 *dst++ = *src++;
139
140         /* Clear bss. */
141         for (dst = &__bss_start__; dst < &__bss_end__; dst++)
142                 *dst = 0;
143
144         _start();
145 }
146
147 void
148 Dummy_Handler (void)
149 {
150         for (;;) {
151         }
152 }
153
154 void
155 jump_to_application (volatile uint32_t *address)
156 {
157         volatile uint32_t *vtor = (uint32_t *) 0xe000ed08;
158         *vtor = (uint32_t) address;
159
160         asm volatile ("" ::: "memory");
161         asm volatile ("msr msp, %0" :: "r" (*(address + 0)) : "sp");
162         asm volatile ("bx %0" :: "r" (*(address + 1)));
163
164         for (;;) {
165         }
166 }