summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-07-05 07:14:24 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-07-05 07:14:24 +0000
commit60efd38bbea318292502c398d41ba3c1044bbb0c (patch)
tree3ceab1cda84743906e601f2074a50054097a5a4c
parent21b90e3466b28b9885887f679b264ba4073b76bc (diff)
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.c27
-rw-r--r--firmware/export/s3c2440.h83
-rw-r--r--firmware/kernel.c10
-rw-r--r--firmware/target/arm/crt0.S8
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c115
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)
#if CONFIG_CHARGING
car_adapter_mode_init();
#endif
+
+ int fd = creat("/timer_regs.txt");
+
+ if (fd >= 0)
+ {
+ fdprintf(fd, "TCFG0: %08X\n", TCFG0);
+ fdprintf(fd, "TCFG1: %08X\n", TCFG1);
+ fdprintf(fd, "TCON: %08X\n", TCON);
+ fdprintf(fd, "TCFG0: %08X\n", TCFG0);
+ fdprintf(fd, "TCNTB0: %08X\n", TCNTB0);
+ fdprintf(fd, "TCMPB0: %08X\n", TCMPB0);
+ fdprintf(fd, "TCNTO0: %08X\n", TCNTO0);
+ fdprintf(fd, "TCNTB1: %08X\n", TCNTB1);
+ fdprintf(fd, "TCMPB1: %08X\n", TCMPB1);
+ fdprintf(fd, "TCNTO1: %08X\n", TCNTO1);
+ fdprintf(fd, "TCNTB2: %08X\n", TCNTB2);
+ fdprintf(fd, "TCMPB2: %08X\n", TCMPB2);
+ fdprintf(fd, "TCNTO2: %08X\n", TCNTO2);
+ fdprintf(fd, "TCNTB3: %08X\n", TCNTB3);
+ fdprintf(fd, "TCMPB3: %08X\n", TCMPB3);
+ fdprintf(fd, "TCNTO3: %08X\n", TCNTO3);
+ fdprintf(fd, "TCNTB4: %08X\n", TCNTB4);
+ fdprintf(fd, "TCNTO4: %08X\n", TCNTO4);
+
+
+ close(fd);
+ }
}
#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 @@
* KIND, either express or implied.
*
****************************************************************************/
+#ifndef __S3C2440_H__
+#define __S3C2440_H__
/* Memory Controllers */
@@ -74,6 +76,86 @@
#define SUBSRCPND (*(volatile int *)0x4A000018) /* Sub source pending */
#define INTSUBMSK (*(volatile int *)0x4A00001C) /* Interrupt sub mask */
+/* Interrupt indexes - INTOFFSET - IRQ mode only */
+/* Arbiter 5 => Arbiter 6 Req 5 */
+#define ADC_OFFSET 31 /* REQ4 */
+#define RTC_OFFSET 30 /* REQ3 */
+#define SPI1_OFFSET 29 /* REQ2 */
+#define UART0_OFFSET 28 /* REQ1 */
+/* Arbiter 4 => Arbiter 6 Req 4 */
+#define IIC_OFFSET 27 /* REQ5 */
+#define USBH_OFFSET 26 /* REQ4 */
+#define USBD_OFFSET 25 /* REQ3 */
+#define NFCON_OFFSET 24 /* REQ2 */
+#define UART1_OFFSET 23 /* REQ1 */
+#define SPI0_OFFSET 22 /* REQ0 */
+/* Arbiter 3 => Arbiter 6 Req 3 */
+#define SDI_OFFSET 21 /* REQ5 */
+#define DMA3_OFFSET 20 /* REQ4 */
+#define DMA2_OFFSET 19 /* REQ3 */
+#define DMA1_OFFSET 18 /* REQ2 */
+#define DMA0_OFFSET 17 /* REQ1 */
+#define LCD_OFFSET 16 /* REQ0 */
+/* Arbiter 2 => Arbiter 6 Req 2 */
+#define UART2_OFFSET 15 /* REQ5 */
+#define TIMER4_OFFSET 14 /* REQ4 */
+#define TIMER3_OFFSET 13 /* REQ3 */
+#define TIMER2_OFFSET 12 /* REQ2 */
+#define TIMER1_OFFSET 11 /* REQ1 */
+#define TIMER0_OFFSET 10 /* REQ0 */
+/* Arbiter 1 => Arbiter 6 Req 1 */
+#define WDT_AC97_OFFSET 9 /* REQ5 */
+#define TICK_OFFSET 8 /* REQ4 */
+#define nBATT_FLT_OFFSET 7 /* REQ3 */
+#define CAM_OFFSET 6 /* REQ2 */
+#define EINT8_23_OFFSET 5 /* REQ1 */
+#define EINT4_7_OFFSET 4 /* REQ0 */
+/* Arbiter 0 => Arbiter 6 Req 0 */
+#define EINT3_OFFSET 3 /* REQ4 */
+#define EINT2_OFFSET 2 /* REQ3 */
+#define EINT1_OFFSET 1 /* REQ2 */
+#define EINT0_OFFSET 0 /* REQ1 */
+
+/* Interrupt bitmasks - SRCPND, INTMOD, INTMSK, INTPND */
+/* Arbiter 5 => Arbiter 6 Req 5 */
+#define ADC_MASK (1 << 31) /* REQ4 */
+#define RTC_MASK (1 << 30) /* REQ3 */
+#define SPI1_MASK (1 << 29) /* REQ2 */
+#define UART0_MASK (1 << 28) /* REQ1 */
+/* Arbiter 4 => Arbiter 6 Req 4 */
+#define IIC_MASK (1 << 27) /* REQ5 */
+#define USBH_MASK (1 << 26) /* REQ4 */
+#define USBD_MASK (1 << 25) /* REQ3 */
+#define NFCON_MASK (1 << 24) /* REQ2 */
+#define UART1_MASK (1 << 23) /* REQ1 */
+#define SPI0_MASK (1 << 22) /* REQ0 */
+/* Arbiter 3 => Arbiter 6 Req 3 */
+#define SDI_MASK (1 << 21) /* REQ5 */
+#define DMA3_MASK (1 << 20) /* REQ4 */
+#define DMA2_MASK (1 << 19) /* REQ3 */
+#define DMA1_MASK (1 << 18) /* REQ2 */
+#define DMA0_MASK (1 << 17) /* REQ1 */
+#define LCD_MASK (1 << 16) /* REQ0 */
+/* Arbiter 2 => Arbiter 6 Req 2 */
+#define UART2_MASK (1 << 15) /* REQ5 */
+#define TIMER4_MASK (1 << 14) /* REQ4 */
+#define TIMER3_MASK (1 << 13) /* REQ3 */
+#define TIMER2_MASK (1 << 12) /* REQ2 */
+#define TIMER1_MASK (1 << 11) /* REQ1 */
+#define TIMER0_MASK (1 << 10) /* REQ0 */
+/* Arbiter 1 => Arbiter 6 Req 1 */
+#define WDT_AC97_MASK (1 << 9) /* REQ5 */
+#define TICK_MASK (1 << 8) /* REQ4 */
+#define nBATT_FLT_MASK (1 << 7) /* REQ3 */
+#define CAM_MASK (1 << 6) /* REQ2 */
+#define EINT8_23_MASK (1 << 5) /* REQ1 */
+#define EINT4_7_MASK (1 << 4) /* REQ0 */
+/* Arbiter 0 => Arbiter 6 Req 0 */
+#define EINT3_MASK (1 << 3) /* REQ4 */
+#define EINT2_MASK (1 << 2) /* REQ3 */
+#define EINT1_MASK (1 << 1) /* REQ2 */
+#define EINT0_MASK (1 << 0) /* REQ1 */
+
/* DMA */
#define DISRC0 (*(volatile int *)0x4B000000) /* DMA 0 initial source */
@@ -465,3 +547,4 @@
#define DRAM1 0x31000000
#define BOOTRAM 0x40000000
+#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)
INTMSK &= ~(1 << 14); // timer 4 unmask interrupts
}
-void timer4(void) {
+void TIMER4(void)
+{
int i;
+
+ SRCPND = TIMER4_MASK;
+ INTPND = TIMER4_MASK;
+
/* Run through the list of tick tasks */
for(i = 0; i < MAX_NUM_TICK_TASKS; i++)
{
@@ -736,9 +741,6 @@ void timer4(void) {
}
current_tick++;
-
- /* following needs to be fixed. */
- /*wake_up_thread();*/
}
#endif
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:
mov r1, #2
b UIE
-irq_handler:
-#ifndef STUB
- stmfd sp!, {r0-r11, r12, lr}
- bl irq
- ldmfd sp!, {r0-r11, r12, lr}
-#endif
- subs pc, lr, #4
-
#ifdef STUB
UIE:
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 @@
#include "panic.h"
#include "mmu-meg-fx.h"
-#include "lcd.h"
+#define default_interrupt(name) \
+ extern __attribute__((weak,alias("UIRQ"))) void name (void)
+
+default_interrupt(EINT0);
+default_interrupt(EINT1);
+default_interrupt(EINT2);
+default_interrupt(EINT3);
+default_interrupt(EINT4_7);
+default_interrupt(EINT8_23);
+default_interrupt(CAM);
+default_interrupt(nBATT_FLT);
+default_interrupt(TICK);
+default_interrupt(WDT_AC97);
+default_interrupt(TIMER0);
+default_interrupt(TIMER1);
+default_interrupt(TIMER2);
+default_interrupt(TIMER3);
+default_interrupt(TIMER4);
+default_interrupt(UART2);
+default_interrupt(LCD);
+default_interrupt(DMA0);
+default_interrupt(DMA1);
+default_interrupt(DMA2);
+default_interrupt(DMA3);
+default_interrupt(SDI);
+default_interrupt(SPI0);
+default_interrupt(UART1);
+default_interrupt(NFCON);
+default_interrupt(USBD);
+default_interrupt(USBH);
+default_interrupt(IIC);
+default_interrupt(UART0);
+default_interrupt(SPI1);
+default_interrupt(RTC);
+default_interrupt(ADC);
+
+static void (* const irqvector[32])(void) =
+{
+ EINT0, EINT1, EINT2, EINT3,
+ EINT4_7, EINT8_23, CAM, nBATT_FLT, TICK, WDT_AC97,
+ TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, UART2,
+ LCD, DMA0, DMA1, DMA2, DMA3, SDI,
+ SPI0, UART1, NFCON, USBD, IIC,
+ UART0, SPI1, RTC, ADC,
+};
-enum
+static const char * const irqname[32] =
{
- TIMER4_MASK = (1 << 14),
- LCD_MASK = (1 << 16),
- DMA0_MASK = (1 << 17),
- DMA1_MASK = (1 << 18),
- DMA2_MASK = (1 << 19),
- DMA3_MASK = (1 << 20),
- ALARM_MASK = (1 << 30),
+ "EINT0", "EINT1", "EINT2", "EINT3",
+ "EINT4_7", "EINT8_23", "CAM", "nBATT_FLT", "TICK", "WDT_AC97",
+ "TIMER0", "TIMER1", "TIMER2", "TIMER3", "TIMER4", "UART2",
+ "LCD", "DMA0", "DMA1", "DMA2", "DMA3", "SDI",
+ "SPI0", "UART1", "NFCON", "USBD", "USBH", "IIC",
+ "UART0", "SPI1", "RTC", "ADC"
};
-int system_memory_guard(int newmode)
+static void UIRQ(void)
{
- (void)newmode;
- return 0;
+ unsigned int offset = INTOFFSET;
+ panicf("Unhandled IRQ %02X: %s", offset, irqname[offset]);
}
-extern void timer4(void);
-extern void dma0(void); /* free */
-extern void dma1(void);
-extern void dma3(void);
-
-void irq(void)
+void irq_handler(void) __attribute__((interrupt ("IRQ"), naked));
+void irq_handler(void)
{
- int intpending = INTPND;
-
- SRCPND = intpending; /* Clear this interrupt. */
- INTPND = intpending; /* Clear this interrupt. */
-
- /* Timer 4 */
- if ((intpending & TIMER4_MASK) != 0)
- timer4();
- else
- {
- /* unexpected interrupt */
- }
+ asm volatile (
+ "sub lr, lr, #4 \r\n"
+ "stmfd sp!, {r0-r3, ip, lr} \r\n"
+ "mov r0, #0x4a000000 \r\n" /* INTOFFSET = 0x4a000014 */
+ "add r0, r0, #0x00000014 \r\n"
+ "ldr r0, [r0] \r\n"
+ "ldr r1, =irqvector \r\n"
+ "ldr r1, [r1, r0, lsl #2] \r\n"
+ "mov lr, pc \r\n"
+ "bx r1 \r\n"
+ "ldmfd sp!, {r0-r3, ip, pc}^ \r\n"
+ );
}
void system_reboot(void)
@@ -54,6 +93,17 @@ void system_reboot(void)
void system_init(void)
{
+ /* Disable interrupts and set all to IRQ mode */
+ INTMSK = -1;
+ INTMOD = 0;
+ SRCPND = -1;
+ INTPND = -1;
+ INTSUBMSK = -1;
+ SUBSRCPND = -1;
+
+ /* TODO: do something with PRIORITY */
+
+
/* Turn off currently-not or never-needed devices */
CLKCON &= ~(
@@ -90,6 +140,11 @@ void system_init(void)
CLKSLOW |= (1 << 7);
}
+int system_memory_guard(int newmode)
+{
+ (void)newmode;
+ return 0;
+}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ