Switch from GPLv2 to GPLv2+
[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 extern void main(void);
33 extern char __stack__;
34 extern char __text_start__, __text_end__;
35 extern char __data_start__, __data_end__;
36 extern char __bss_start__, __bss_end__;
37 #if RELOCATE_INTERRUPT
38 extern char __interrupt_rom__, __interrupt_start__, __interrupt_end__;
39 #endif
40
41 /* Interrupt functions */
42
43 void lpc_halt_isr(void)
44 {
45         ao_panic(AO_PANIC_CRASH);
46 }
47
48 void lpc_ignore_isr(void)
49 {
50 }
51
52 void start(void) {
53 #ifdef AO_BOOT_CHAIN
54         if (ao_boot_check_chain()) {
55 #ifdef AO_BOOT_PIN
56                 ao_boot_check_pin();
57 #endif
58         }
59 #endif
60 #if RELOCATE_INTERRUPT
61         memcpy(&__interrupt_start__, &__interrupt_rom__, &__interrupt_end__ - &__interrupt_start__);
62         lpc_scb.sysmemremap = LPC_SCB_SYSMEMREMAP_MAP_RAM << LPC_SCB_SYSMEMREMAP_MAP;
63 #endif
64         memcpy(&__data_start__, &__text_end__, &__data_end__ - &__data_start__);
65         memset(&__bss_start__, '\0', &__bss_end__ - &__bss_start__);
66         main();
67 }
68
69 #define STRINGIFY(x) #x
70
71 #define isr(name) \
72         void __attribute__ ((weak)) lpc_ ## name ## _isr(void); \
73         _Pragma(STRINGIFY(weak lpc_ ## name ## _isr = lpc_ignore_isr))
74
75 #define isr_halt(name) \
76         void __attribute__ ((weak)) lpc_ ## name ## _isr(void); \
77         _Pragma(STRINGIFY(weak lpc_ ## name ## _isr = lpc_halt_isr))
78
79 isr(nmi)
80 isr_halt(hardfault)
81 isr_halt(memmanage)
82 isr_halt(busfault)
83 isr_halt(usagefault)
84 isr(svc)
85 isr(debugmon)
86 isr(pendsv)
87 isr(systick)
88
89 isr(pin_int0)   /* IRQ0 */
90 isr(pin_int1)
91 isr(pin_int2)
92 isr(pin_int3)
93 isr(pin_int4)   /* IRQ4 */
94 isr(pin_int5)
95 isr(pin_int6)
96 isr(pin_int7)
97
98 isr(gint0)      /* IRQ8 */
99 isr(gint1)
100 isr(ssp1)
101 isr(i2c)
102
103 isr(ct16b0)     /* IRQ16 */
104 isr(ct16b1)
105 isr(ct32b0)
106 isr(ct32b1)
107 isr(ssp0)       /* IRQ20 */
108 isr(usart)
109 isr(usb_irq)
110 isr(usb_fiq)
111
112 isr(adc)        /* IRQ24 */
113 isr(wwdt)
114 isr(bod)
115 isr(flash)
116
117 isr(usb_wakeup)
118
119 #define i(addr,name)    [(addr)/4] = lpc_ ## name ## _isr
120 #define c(addr,value)   [(addr)/4] = (value)
121
122 __attribute__ ((section(".interrupt")))
123 const void *lpc_interrupt_vector[] = {
124         [0] = &__stack__,
125         [1] = start,
126         i(0x08, nmi),
127         i(0x0c, hardfault),
128         c(0x10, 0),
129         c(0x14, 0),
130         c(0x18, 0),
131         c(0x1c, 0),
132         c(0x20, 0),
133         c(0x24, 0),
134         c(0x28, 0),
135         i(0x2c, svc),
136         i(0x30, hardfault),
137         i(0x34, hardfault),
138         i(0x38, pendsv),
139         i(0x3c, systick),
140
141         i(0x40, pin_int0),      /* IRQ0 */
142         i(0x44, pin_int1),
143         i(0x48, pin_int2),
144         i(0x4c, pin_int3),
145         i(0x50, pin_int4),      /* IRQ4 */
146         i(0x54, pin_int5),
147         i(0x58, pin_int6),
148         i(0x5c, pin_int7),
149
150         i(0x60, gint0),         /* IRQ8 */
151         i(0x64, gint1),
152         i(0x68, hardfault),
153         i(0x6c, hardfault),
154         i(0x70, hardfault),     /* IRQ12 */
155         i(0x74, hardfault),
156         i(0x78, ssp1),
157         i(0x7c, i2c),
158
159         i(0x80, ct16b0),        /* IRQ16 */
160         i(0x84, ct16b1),
161         i(0x88, ct32b0),
162         i(0x8c, ct32b1),
163         i(0x90, ssp0),          /* IRQ20 */
164         i(0x94, usart),
165         i(0x98, usb_irq),
166         i(0x9c, usb_fiq),
167
168         i(0xa0, adc),           /* IRQ24 */
169         i(0xa4, wwdt),
170         i(0xa8, bod),
171         i(0xac, flash),
172
173         i(0xb0, hardfault),     /* IRQ28 */
174         i(0xb4, hardfault),
175         i(0xb8, usb_wakeup),
176         i(0xbc, hardfault),
177 };