altos/test: Adjust CRC error rate after FEC fix
[fw/altos] / src / lpc / ao_interrupt.c
1 /*
2  * Copyright © 2013 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include <ao.h>
20 #include <string.h>
21 #include <ao_boot.h>
22
23 #ifndef IS_FLASH_LOADER
24 #error Should define IS_FLASH_LOADER
25 #define IS_FLASH_LOADER 0
26 #endif
27
28 #if !IS_FLASH_LOADER
29 #define RELOCATE_INTERRUPT      1
30 #endif
31
32 /* Interrupt functions */
33
34 void lpc_halt_isr(void)
35 {
36         ao_panic(AO_PANIC_CRASH);
37 }
38
39 void lpc_ignore_isr(void)
40 {
41 }
42
43 #define STRINGIFY(x) #x
44
45 #define isr(name) \
46         void __attribute__ ((weak)) lpc_ ## name ## _isr(void); \
47         _Pragma(STRINGIFY(weak lpc_ ## name ## _isr = lpc_ignore_isr))
48
49 #define isr_halt(name) \
50         void __attribute__ ((weak)) lpc_ ## name ## _isr(void); \
51         _Pragma(STRINGIFY(weak lpc_ ## name ## _isr = lpc_halt_isr))
52
53 isr(nmi)
54 isr_halt(hardfault)
55 isr_halt(memmanage)
56 isr_halt(busfault)
57 isr_halt(usagefault)
58 isr(svc)
59 isr(debugmon)
60 isr(pendsv)
61 isr(systick)
62
63 isr(pin_int0)   /* IRQ0 */
64 isr(pin_int1)
65 isr(pin_int2)
66 isr(pin_int3)
67 isr(pin_int4)   /* IRQ4 */
68 isr(pin_int5)
69 isr(pin_int6)
70 isr(pin_int7)
71
72 isr(gint0)      /* IRQ8 */
73 isr(gint1)
74 isr(ssp1)
75 isr(i2c)
76
77 isr(ct16b0)     /* IRQ16 */
78 isr(ct16b1)
79 isr(ct32b0)
80 isr(ct32b1)
81 isr(ssp0)       /* IRQ20 */
82 isr(usart)
83 isr(usb_irq)
84 isr(usb_fiq)
85
86 isr(adc)        /* IRQ24 */
87 isr(wwdt)
88 isr(bod)
89 isr(flash)
90
91 isr(usb_wakeup)
92
93 #define i(addr,name)    [(addr)/4] = lpc_ ## name ## _isr
94 #define c(addr,value)   [(addr)/4] = (value)
95
96 extern char __stack[];
97 void _start(void) __attribute__((__noreturn__));
98
99 __attribute__ ((section(".init")))
100 const void *const __interrupt_vector[0x30] = {
101         [0] = __stack,
102         [1] = _start,
103         i(0x08, nmi),
104         i(0x0c, hardfault),
105         c(0x10, 0),
106         c(0x14, 0),
107         c(0x18, 0),
108         c(0x1c, 0),
109         c(0x20, 0),
110         c(0x24, 0),
111         c(0x28, 0),
112         i(0x2c, svc),
113         i(0x30, hardfault),
114         i(0x34, hardfault),
115         i(0x38, pendsv),
116         i(0x3c, systick),
117
118         i(0x40, pin_int0),      /* IRQ0 */
119         i(0x44, pin_int1),
120         i(0x48, pin_int2),
121         i(0x4c, pin_int3),
122         i(0x50, pin_int4),      /* IRQ4 */
123         i(0x54, pin_int5),
124         i(0x58, pin_int6),
125         i(0x5c, pin_int7),
126
127         i(0x60, gint0),         /* IRQ8 */
128         i(0x64, gint1),
129         i(0x68, hardfault),
130         i(0x6c, hardfault),
131         i(0x70, hardfault),     /* IRQ12 */
132         i(0x74, hardfault),
133         i(0x78, ssp1),
134         i(0x7c, i2c),
135
136         i(0x80, ct16b0),        /* IRQ16 */
137         i(0x84, ct16b1),
138         i(0x88, ct32b0),
139         i(0x8c, ct32b1),
140         i(0x90, ssp0),          /* IRQ20 */
141         i(0x94, usart),
142         i(0x98, usb_irq),
143         i(0x9c, usb_fiq),
144
145         i(0xa0, adc),           /* IRQ24 */
146         i(0xa4, wwdt),
147         i(0xa8, bod),
148         i(0xac, flash),
149
150         i(0xb0, hardfault),     /* IRQ28 */
151         i(0xb4, hardfault),
152         i(0xb8, usb_wakeup),
153         i(0xbc, hardfault),
154 };
155
156 /*
157  * Previous versions of this code had a 256 byte interupt vector. Add
158  * some padding to make sure the other low ROM variables land at the
159  * same address
160  */
161
162 __attribute__ ((section(".init.0")))
163 const void *const __interrupt_pad[0x10];
164
165 void main(void) __attribute__((__noreturn__));
166
167 void *__interrupt_ram[sizeof(__interrupt_vector)/sizeof(__interrupt_vector[0])] __attribute((section(".preserve.1")));
168
169 extern char __data_source[];
170 extern char __data_start[];
171 extern char __data_size[];
172 extern char __bss_start[];
173 extern char __bss_size[];
174
175 void _start(void) {
176         memcpy(__data_start, __data_source, (uintptr_t) __data_size);
177         memset(__bss_start, '\0', (uintptr_t) __bss_size);
178
179 #ifdef AO_BOOT_CHAIN
180         if (ao_boot_check_chain()) {
181 #ifdef AO_BOOT_PIN
182                 if (ao_boot_check_pin())
183 #endif
184                 {
185                         ao_boot_chain(AO_BOOT_APPLICATION_BASE);
186                 }
187         }
188 #endif
189 #if RELOCATE_INTERRUPT
190         memcpy(__interrupt_ram, __interrupt_vector, sizeof(__interrupt_ram));
191         lpc_scb.sysmemremap = LPC_SCB_SYSMEMREMAP_MAP_RAM << LPC_SCB_SYSMEMREMAP_MAP;
192 #endif
193         main();
194 }