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 | |
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
-rw-r--r-- | apps/main.c | 27 | ||||
-rw-r--r-- | firmware/export/s3c2440.h | 83 | ||||
-rw-r--r-- | firmware/kernel.c | 10 | ||||
-rw-r--r-- | firmware/target/arm/crt0.S | 8 | ||||
-rw-r--r-- | firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c | 115 |
5 files changed, 201 insertions, 42 deletions
diff --git a/apps/main.c b/apps/main.c index 2dd90ef5fe..7b1368f460 100644 --- a/apps/main.c +++ b/apps/main.c | |||
@@ -558,6 +558,33 @@ static void init(void) | |||
558 | #if CONFIG_CHARGING | 558 | #if CONFIG_CHARGING |
559 | car_adapter_mode_init(); | 559 | car_adapter_mode_init(); |
560 | #endif | 560 | #endif |
561 | |||
562 | int fd = creat("/timer_regs.txt"); | ||
563 | |||
564 | if (fd >= 0) | ||
565 | { | ||
566 | fdprintf(fd, "TCFG0: %08X\n", TCFG0); | ||
567 | fdprintf(fd, "TCFG1: %08X\n", TCFG1); | ||
568 | fdprintf(fd, "TCON: %08X\n", TCON); | ||
569 | fdprintf(fd, "TCFG0: %08X\n", TCFG0); | ||
570 | fdprintf(fd, "TCNTB0: %08X\n", TCNTB0); | ||
571 | fdprintf(fd, "TCMPB0: %08X\n", TCMPB0); | ||
572 | fdprintf(fd, "TCNTO0: %08X\n", TCNTO0); | ||
573 | fdprintf(fd, "TCNTB1: %08X\n", TCNTB1); | ||
574 | fdprintf(fd, "TCMPB1: %08X\n", TCMPB1); | ||
575 | fdprintf(fd, "TCNTO1: %08X\n", TCNTO1); | ||
576 | fdprintf(fd, "TCNTB2: %08X\n", TCNTB2); | ||
577 | fdprintf(fd, "TCMPB2: %08X\n", TCMPB2); | ||
578 | fdprintf(fd, "TCNTO2: %08X\n", TCNTO2); | ||
579 | fdprintf(fd, "TCNTB3: %08X\n", TCNTB3); | ||
580 | fdprintf(fd, "TCMPB3: %08X\n", TCMPB3); | ||
581 | fdprintf(fd, "TCNTO3: %08X\n", TCNTO3); | ||
582 | fdprintf(fd, "TCNTB4: %08X\n", TCNTB4); | ||
583 | fdprintf(fd, "TCNTO4: %08X\n", TCNTO4); | ||
584 | |||
585 | |||
586 | close(fd); | ||
587 | } | ||
561 | } | 588 | } |
562 | 589 | ||
563 | #ifdef CPU_PP | 590 | #ifdef CPU_PP |
diff --git a/firmware/export/s3c2440.h b/firmware/export/s3c2440.h index 4a799da3e2..72c33e227c 100644 --- a/firmware/export/s3c2440.h +++ b/firmware/export/s3c2440.h | |||
@@ -16,6 +16,8 @@ | |||
16 | * KIND, either express or implied. | 16 | * KIND, either express or implied. |
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | #ifndef __S3C2440_H__ | ||
20 | #define __S3C2440_H__ | ||
19 | 21 | ||
20 | /* Memory Controllers */ | 22 | /* Memory Controllers */ |
21 | 23 | ||
@@ -74,6 +76,86 @@ | |||
74 | #define SUBSRCPND (*(volatile int *)0x4A000018) /* Sub source pending */ | 76 | #define SUBSRCPND (*(volatile int *)0x4A000018) /* Sub source pending */ |
75 | #define INTSUBMSK (*(volatile int *)0x4A00001C) /* Interrupt sub mask */ | 77 | #define INTSUBMSK (*(volatile int *)0x4A00001C) /* Interrupt sub mask */ |
76 | 78 | ||
79 | /* Interrupt indexes - INTOFFSET - IRQ mode only */ | ||
80 | /* Arbiter 5 => Arbiter 6 Req 5 */ | ||
81 | #define ADC_OFFSET 31 /* REQ4 */ | ||
82 | #define RTC_OFFSET 30 /* REQ3 */ | ||
83 | #define SPI1_OFFSET 29 /* REQ2 */ | ||
84 | #define UART0_OFFSET 28 /* REQ1 */ | ||
85 | /* Arbiter 4 => Arbiter 6 Req 4 */ | ||
86 | #define IIC_OFFSET 27 /* REQ5 */ | ||
87 | #define USBH_OFFSET 26 /* REQ4 */ | ||
88 | #define USBD_OFFSET 25 /* REQ3 */ | ||
89 | #define NFCON_OFFSET 24 /* REQ2 */ | ||
90 | #define UART1_OFFSET 23 /* REQ1 */ | ||
91 | #define SPI0_OFFSET 22 /* REQ0 */ | ||
92 | /* Arbiter 3 => Arbiter 6 Req 3 */ | ||
93 | #define SDI_OFFSET 21 /* REQ5 */ | ||
94 | #define DMA3_OFFSET 20 /* REQ4 */ | ||
95 | #define DMA2_OFFSET 19 /* REQ3 */ | ||
96 | #define DMA1_OFFSET 18 /* REQ2 */ | ||
97 | #define DMA0_OFFSET 17 /* REQ1 */ | ||
98 | #define LCD_OFFSET 16 /* REQ0 */ | ||
99 | /* Arbiter 2 => Arbiter 6 Req 2 */ | ||
100 | #define UART2_OFFSET 15 /* REQ5 */ | ||
101 | #define TIMER4_OFFSET 14 /* REQ4 */ | ||
102 | #define TIMER3_OFFSET 13 /* REQ3 */ | ||
103 | #define TIMER2_OFFSET 12 /* REQ2 */ | ||
104 | #define TIMER1_OFFSET 11 /* REQ1 */ | ||
105 | #define TIMER0_OFFSET 10 /* REQ0 */ | ||
106 | /* Arbiter 1 => Arbiter 6 Req 1 */ | ||
107 | #define WDT_AC97_OFFSET 9 /* REQ5 */ | ||
108 | #define TICK_OFFSET 8 /* REQ4 */ | ||
109 | #define nBATT_FLT_OFFSET 7 /* REQ3 */ | ||
110 | #define CAM_OFFSET 6 /* REQ2 */ | ||
111 | #define EINT8_23_OFFSET 5 /* REQ1 */ | ||
112 | #define EINT4_7_OFFSET 4 /* REQ0 */ | ||
113 | /* Arbiter 0 => Arbiter 6 Req 0 */ | ||
114 | #define EINT3_OFFSET 3 /* REQ4 */ | ||
115 | #define EINT2_OFFSET 2 /* REQ3 */ | ||
116 | #define EINT1_OFFSET 1 /* REQ2 */ | ||
117 | #define EINT0_OFFSET 0 /* REQ1 */ | ||
118 | |||
119 | /* Interrupt bitmasks - SRCPND, INTMOD, INTMSK, INTPND */ | ||
120 | /* Arbiter 5 => Arbiter 6 Req 5 */ | ||
121 | #define ADC_MASK (1 << 31) /* REQ4 */ | ||
122 | #define RTC_MASK (1 << 30) /* REQ3 */ | ||
123 | #define SPI1_MASK (1 << 29) /* REQ2 */ | ||
124 | #define UART0_MASK (1 << 28) /* REQ1 */ | ||
125 | /* Arbiter 4 => Arbiter 6 Req 4 */ | ||
126 | #define IIC_MASK (1 << 27) /* REQ5 */ | ||
127 | #define USBH_MASK (1 << 26) /* REQ4 */ | ||
128 | #define USBD_MASK (1 << 25) /* REQ3 */ | ||
129 | #define NFCON_MASK (1 << 24) /* REQ2 */ | ||
130 | #define UART1_MASK (1 << 23) /* REQ1 */ | ||
131 | #define SPI0_MASK (1 << 22) /* REQ0 */ | ||
132 | /* Arbiter 3 => Arbiter 6 Req 3 */ | ||
133 | #define SDI_MASK (1 << 21) /* REQ5 */ | ||
134 | #define DMA3_MASK (1 << 20) /* REQ4 */ | ||
135 | #define DMA2_MASK (1 << 19) /* REQ3 */ | ||
136 | #define DMA1_MASK (1 << 18) /* REQ2 */ | ||
137 | #define DMA0_MASK (1 << 17) /* REQ1 */ | ||
138 | #define LCD_MASK (1 << 16) /* REQ0 */ | ||
139 | /* Arbiter 2 => Arbiter 6 Req 2 */ | ||
140 | #define UART2_MASK (1 << 15) /* REQ5 */ | ||
141 | #define TIMER4_MASK (1 << 14) /* REQ4 */ | ||
142 | #define TIMER3_MASK (1 << 13) /* REQ3 */ | ||
143 | #define TIMER2_MASK (1 << 12) /* REQ2 */ | ||
144 | #define TIMER1_MASK (1 << 11) /* REQ1 */ | ||
145 | #define TIMER0_MASK (1 << 10) /* REQ0 */ | ||
146 | /* Arbiter 1 => Arbiter 6 Req 1 */ | ||
147 | #define WDT_AC97_MASK (1 << 9) /* REQ5 */ | ||
148 | #define TICK_MASK (1 << 8) /* REQ4 */ | ||
149 | #define nBATT_FLT_MASK (1 << 7) /* REQ3 */ | ||
150 | #define CAM_MASK (1 << 6) /* REQ2 */ | ||
151 | #define EINT8_23_MASK (1 << 5) /* REQ1 */ | ||
152 | #define EINT4_7_MASK (1 << 4) /* REQ0 */ | ||
153 | /* Arbiter 0 => Arbiter 6 Req 0 */ | ||
154 | #define EINT3_MASK (1 << 3) /* REQ4 */ | ||
155 | #define EINT2_MASK (1 << 2) /* REQ3 */ | ||
156 | #define EINT1_MASK (1 << 1) /* REQ2 */ | ||
157 | #define EINT0_MASK (1 << 0) /* REQ1 */ | ||
158 | |||
77 | /* DMA */ | 159 | /* DMA */ |
78 | 160 | ||
79 | #define DISRC0 (*(volatile int *)0x4B000000) /* DMA 0 initial source */ | 161 | #define DISRC0 (*(volatile int *)0x4B000000) /* DMA 0 initial source */ |
@@ -465,3 +547,4 @@ | |||
465 | #define DRAM1 0x31000000 | 547 | #define DRAM1 0x31000000 |
466 | #define BOOTRAM 0x40000000 | 548 | #define BOOTRAM 0x40000000 |
467 | 549 | ||
550 | #endif /* __S3C2440_H__ */ | ||
diff --git a/firmware/kernel.c b/firmware/kernel.c index fcee53f331..2d4ccde267 100644 --- a/firmware/kernel.c +++ b/firmware/kernel.c | |||
@@ -724,8 +724,13 @@ void tick_start(unsigned int interval_in_ms) | |||
724 | INTMSK &= ~(1 << 14); // timer 4 unmask interrupts | 724 | INTMSK &= ~(1 << 14); // timer 4 unmask interrupts |
725 | } | 725 | } |
726 | 726 | ||
727 | void timer4(void) { | 727 | void TIMER4(void) |
728 | { | ||
728 | int i; | 729 | int i; |
730 | |||
731 | SRCPND = TIMER4_MASK; | ||
732 | INTPND = TIMER4_MASK; | ||
733 | |||
729 | /* Run through the list of tick tasks */ | 734 | /* Run through the list of tick tasks */ |
730 | for(i = 0; i < MAX_NUM_TICK_TASKS; i++) | 735 | for(i = 0; i < MAX_NUM_TICK_TASKS; i++) |
731 | { | 736 | { |
@@ -736,9 +741,6 @@ void timer4(void) { | |||
736 | } | 741 | } |
737 | 742 | ||
738 | current_tick++; | 743 | current_tick++; |
739 | |||
740 | /* following needs to be fixed. */ | ||
741 | /*wake_up_thread();*/ | ||
742 | } | 744 | } |
743 | #endif | 745 | #endif |
744 | 746 | ||
diff --git a/firmware/target/arm/crt0.S b/firmware/target/arm/crt0.S index c513bd7ce7..e7a0a38f36 100644 --- a/firmware/target/arm/crt0.S +++ b/firmware/target/arm/crt0.S | |||
@@ -198,14 +198,6 @@ data_abort_handler: | |||
198 | mov r1, #2 | 198 | mov r1, #2 |
199 | b UIE | 199 | b UIE |
200 | 200 | ||
201 | irq_handler: | ||
202 | #ifndef STUB | ||
203 | stmfd sp!, {r0-r11, r12, lr} | ||
204 | bl irq | ||
205 | ldmfd sp!, {r0-r11, r12, lr} | ||
206 | #endif | ||
207 | subs pc, lr, #4 | ||
208 | |||
209 | #ifdef STUB | 201 | #ifdef STUB |
210 | UIE: | 202 | UIE: |
211 | b UIE | 203 | b UIE |
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 | ||