diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2007-07-05 07:14:24 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2007-07-05 07:14:24 +0000 |
commit | 60efd38bbea318292502c398d41ba3c1044bbb0c (patch) | |
tree | 3ceab1cda84743906e601f2074a50054097a5a4c /firmware/target/arm/s3c2440 | |
parent | 21b90e3466b28b9885887f679b264ba4073b76bc (diff) | |
download | rockbox-60efd38bbea318292502c398d41ba3c1044bbb0c.tar.gz rockbox-60efd38bbea318292502c398d41ba3c1044bbb0c.zip |
Gigabeat: Use vectored IRQ mode interrupts and add a trap for unhandled ones.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13792 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/s3c2440')
-rw-r--r-- | firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c | 115 |
1 files changed, 85 insertions, 30 deletions
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c index aa011dc56b..f626438de4 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c | |||
@@ -3,44 +3,83 @@ | |||
3 | #include "panic.h" | 3 | #include "panic.h" |
4 | #include "mmu-meg-fx.h" | 4 | #include "mmu-meg-fx.h" |
5 | 5 | ||
6 | #include "lcd.h" | 6 | #define default_interrupt(name) \ |
7 | extern __attribute__((weak,alias("UIRQ"))) void name (void) | ||
8 | |||
9 | default_interrupt(EINT0); | ||
10 | default_interrupt(EINT1); | ||
11 | default_interrupt(EINT2); | ||
12 | default_interrupt(EINT3); | ||
13 | default_interrupt(EINT4_7); | ||
14 | default_interrupt(EINT8_23); | ||
15 | default_interrupt(CAM); | ||
16 | default_interrupt(nBATT_FLT); | ||
17 | default_interrupt(TICK); | ||
18 | default_interrupt(WDT_AC97); | ||
19 | default_interrupt(TIMER0); | ||
20 | default_interrupt(TIMER1); | ||
21 | default_interrupt(TIMER2); | ||
22 | default_interrupt(TIMER3); | ||
23 | default_interrupt(TIMER4); | ||
24 | default_interrupt(UART2); | ||
25 | default_interrupt(LCD); | ||
26 | default_interrupt(DMA0); | ||
27 | default_interrupt(DMA1); | ||
28 | default_interrupt(DMA2); | ||
29 | default_interrupt(DMA3); | ||
30 | default_interrupt(SDI); | ||
31 | default_interrupt(SPI0); | ||
32 | default_interrupt(UART1); | ||
33 | default_interrupt(NFCON); | ||
34 | default_interrupt(USBD); | ||
35 | default_interrupt(USBH); | ||
36 | default_interrupt(IIC); | ||
37 | default_interrupt(UART0); | ||
38 | default_interrupt(SPI1); | ||
39 | default_interrupt(RTC); | ||
40 | default_interrupt(ADC); | ||
41 | |||
42 | static void (* const irqvector[32])(void) = | ||
43 | { | ||
44 | EINT0, EINT1, EINT2, EINT3, | ||
45 | EINT4_7, EINT8_23, CAM, nBATT_FLT, TICK, WDT_AC97, | ||
46 | TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, UART2, | ||
47 | LCD, DMA0, DMA1, DMA2, DMA3, SDI, | ||
48 | SPI0, UART1, NFCON, USBD, IIC, | ||
49 | UART0, SPI1, RTC, ADC, | ||
50 | }; | ||
7 | 51 | ||
8 | enum | 52 | static const char * const irqname[32] = |
9 | { | 53 | { |
10 | TIMER4_MASK = (1 << 14), | 54 | "EINT0", "EINT1", "EINT2", "EINT3", |
11 | LCD_MASK = (1 << 16), | 55 | "EINT4_7", "EINT8_23", "CAM", "nBATT_FLT", "TICK", "WDT_AC97", |
12 | DMA0_MASK = (1 << 17), | 56 | "TIMER0", "TIMER1", "TIMER2", "TIMER3", "TIMER4", "UART2", |
13 | DMA1_MASK = (1 << 18), | 57 | "LCD", "DMA0", "DMA1", "DMA2", "DMA3", "SDI", |
14 | DMA2_MASK = (1 << 19), | 58 | "SPI0", "UART1", "NFCON", "USBD", "USBH", "IIC", |
15 | DMA3_MASK = (1 << 20), | 59 | "UART0", "SPI1", "RTC", "ADC" |
16 | ALARM_MASK = (1 << 30), | ||
17 | }; | 60 | }; |
18 | 61 | ||
19 | int system_memory_guard(int newmode) | 62 | static void UIRQ(void) |
20 | { | 63 | { |
21 | (void)newmode; | 64 | unsigned int offset = INTOFFSET; |
22 | return 0; | 65 | panicf("Unhandled IRQ %02X: %s", offset, irqname[offset]); |
23 | } | 66 | } |
24 | 67 | ||
25 | extern void timer4(void); | 68 | void irq_handler(void) __attribute__((interrupt ("IRQ"), naked)); |
26 | extern void dma0(void); /* free */ | 69 | void irq_handler(void) |
27 | extern void dma1(void); | ||
28 | extern void dma3(void); | ||
29 | |||
30 | void irq(void) | ||
31 | { | 70 | { |
32 | int intpending = INTPND; | 71 | asm volatile ( |
33 | 72 | "sub lr, lr, #4 \r\n" | |
34 | SRCPND = intpending; /* Clear this interrupt. */ | 73 | "stmfd sp!, {r0-r3, ip, lr} \r\n" |
35 | INTPND = intpending; /* Clear this interrupt. */ | 74 | "mov r0, #0x4a000000 \r\n" /* INTOFFSET = 0x4a000014 */ |
36 | 75 | "add r0, r0, #0x00000014 \r\n" | |
37 | /* Timer 4 */ | 76 | "ldr r0, [r0] \r\n" |
38 | if ((intpending & TIMER4_MASK) != 0) | 77 | "ldr r1, =irqvector \r\n" |
39 | timer4(); | 78 | "ldr r1, [r1, r0, lsl #2] \r\n" |
40 | else | 79 | "mov lr, pc \r\n" |
41 | { | 80 | "bx r1 \r\n" |
42 | /* unexpected interrupt */ | 81 | "ldmfd sp!, {r0-r3, ip, pc}^ \r\n" |
43 | } | 82 | ); |
44 | } | 83 | } |
45 | 84 | ||
46 | void system_reboot(void) | 85 | void system_reboot(void) |
@@ -54,6 +93,17 @@ void system_reboot(void) | |||
54 | 93 | ||
55 | void system_init(void) | 94 | void system_init(void) |
56 | { | 95 | { |
96 | /* Disable interrupts and set all to IRQ mode */ | ||
97 | INTMSK = -1; | ||
98 | INTMOD = 0; | ||
99 | SRCPND = -1; | ||
100 | INTPND = -1; | ||
101 | INTSUBMSK = -1; | ||
102 | SUBSRCPND = -1; | ||
103 | |||
104 | /* TODO: do something with PRIORITY */ | ||
105 | |||
106 | |||
57 | /* Turn off currently-not or never-needed devices */ | 107 | /* Turn off currently-not or never-needed devices */ |
58 | 108 | ||
59 | CLKCON &= ~( | 109 | CLKCON &= ~( |
@@ -90,6 +140,11 @@ void system_init(void) | |||
90 | CLKSLOW |= (1 << 7); | 140 | CLKSLOW |= (1 << 7); |
91 | } | 141 | } |
92 | 142 | ||
143 | int system_memory_guard(int newmode) | ||
144 | { | ||
145 | (void)newmode; | ||
146 | return 0; | ||
147 | } | ||
93 | 148 | ||
94 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 149 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
95 | 150 | ||