* Add interrupt handling (but still not working)
* Clean up linker script and bootup routines


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18229 a1c6a512-1295-4272-9138-f99709370657
diff --git a/bootloader/ondavx747.c b/bootloader/ondavx747.c
index aa2a00c..a9230e7 100644
--- a/bootloader/ondavx747.c
+++ b/bootloader/ondavx747.c
@@ -86,7 +86,7 @@
     if(read_c0_config1() & (1 << 5)) printf(" * MDMX available");
     if(read_c0_config1() & (1 << 6)) printf(" * CP2 available");
     printf("C0_STATUS: 0x%x", read_c0_status());
-    unsigned char testdata[4096];
+  /*  unsigned char testdata[4096];
     char msg[30];
     int j = 0;
     while(1)
@@ -108,7 +108,7 @@
             j--;
         if(j<0)
             j = 0;
-    }
+    }*/
     while(1)
     {
         btn = button_read_device(&touch);
diff --git a/firmware/SOURCES b/firmware/SOURCES
index e6ff82d..c6cefa0 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -1082,6 +1082,7 @@
 #if CONFIG_CPU==JZ4732
 target/mips/ingenic_jz47xx/ata-nand-jz4740.c
 target/mips/ingenic_jz47xx/lcd-jz4740.c
+target/mips/ingenic_jz47xx/kernel-jz4740.c
 target/mips/ingenic_jz47xx/system-jz4740.c
 drivers/nand_id.c
 #endif
diff --git a/firmware/target/mips/ingenic_jz47xx/boot.lds b/firmware/target/mips/ingenic_jz47xx/boot.lds
index cba23e9..e3ff0c0 100644
--- a/firmware/target/mips/ingenic_jz47xx/boot.lds
+++ b/firmware/target/mips/ingenic_jz47xx/boot.lds
@@ -22,19 +22,18 @@
 {
     . = DRAMORIG;
 
-    .text : {
+    .text :
+    {
         loadaddress = .;
         _loadaddress = .;
-        _resetvectorsstart = .;
-        KEEP(*(.resetvectors));
-        *(.resetvectors);
-        _resetvectorsend = .;
         *(.init.text);
         *(.text*);
         *(.glue_7);
         *(.glue_7t);
         *(.rel.dyn);
-        . = ALIGN(0x4);
+        _vectorsstart = .;
+        KEEP(*(.vectors))
+        *(.vectors);
     } > DRAM
     
     . = ALIGN(4);
@@ -50,10 +49,9 @@
         /* Pseudo-allocate the copies of the data sections */
         _datacopy = .;
     } > DRAM
-    
-    . = ALIGN(4);
 
-    .data : {
+    .data :
+    {
         *(.icode);
         *(.irodata);
         *(.idata);
@@ -63,12 +61,11 @@
         _dataend = . ;
     } > DRAM
     
-    . = ALIGN(4);
-    
     _gp = ALIGN(16);
-    .got : {
+    .got :
+    {
         *(.got*)
-    }> DRAM
+    } > DRAM
     
     . = ALIGN(4);
 
@@ -94,16 +91,4 @@
          *(.scommon*);
          _end = .;
     } > DRAM
-    
-    . = ALIGN(4);
-
-    .vectors :
-    {
-        _vectorsstart = .;
-        KEEP(*(.vectors));
-        *(.vectors);
-        _vectorsend = .;
-    } > DRAM
-    
-    . = ALIGN(4);
 }
diff --git a/firmware/target/mips/ingenic_jz47xx/crt0.S b/firmware/target/mips/ingenic_jz47xx/crt0.S
index 2dff67c..3d2308a 100644
--- a/firmware/target/mips/ingenic_jz47xx/crt0.S
+++ b/firmware/target/mips/ingenic_jz47xx/crt0.S
@@ -45,7 +45,7 @@
     .extern system_main
 
     .global    _start
-    .section .resetvectors,"ax",%progbits
+    .section .init.text
     .set    noreorder
     .set    noat
     
@@ -125,12 +125,12 @@
     nop
 
     
-    .section .vectors,"ax",%progbits
-    .extern exception_handler
+    .section .vectors, "ax", %progbits
+    .extern real_exception_handler
     .global except_common_entry
     .type   except_common_entry,@function
 except_common_entry:
-    la     k0, exception_handler
+    la     k0, real_exception_handler
     jr     k0
     nop
     nop
@@ -138,10 +138,10 @@
 
     .extern _int
     .extern _exception
-    .global exception_handler
-    .type   exception_handler,@function
+    .global real_exception_handler
+    .type   real_exception_handler,@function
     .set noreorder
-exception_handler:
+real_exception_handler:
 
 
     addiu   sp, -0x80
@@ -257,15 +257,14 @@
     eret                   # Exception Return
     nop
     
-    .extern _except_handler
+    .extern _exception_handler
     .global _exception
     .type   _exception,@function
 _exception:
     move    a0, sp
     mfc0    a1, C0_CAUSE       # C0_CAUSE of last exception
     mfc0    a2, C0_EPC         # Exception Program Counter
-    la      k0, except_handler
+    la      k0, exception_handler
     jr      k0
     nop
-
     .set reorder
diff --git a/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c b/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
new file mode 100644
index 0000000..1d88c75
--- /dev/null
+++ b/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
@@ -0,0 +1,72 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Maurus Cuelenaere
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "system.h"
+#include "kernel.h"
+#include "timer.h"
+#include "thread.h"
+#include "jz4740.h"
+
+extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
+
+#define USE_RTC_CLOCK 0
+void tick_start(unsigned int interval_in_ms)
+{
+    unsigned int tps = interval_in_ms;
+    unsigned int latch;
+    __cpm_start_tcu();
+    
+    __tcu_disable_pwm_output(0);
+    __tcu_mask_half_match_irq(0); 
+    __tcu_unmask_full_match_irq(0);
+
+#if USE_RTC_CLOCK
+    __tcu_select_rtcclk(0);
+    __tcu_select_clk_div1(0);
+    latch = (__cpm_get_rtcclk() + (tps>>1)) / tps;
+#else    
+    __tcu_select_extalclk(0);
+    __tcu_select_clk_div4(0);
+    
+    latch = (JZ_EXTAL / 4 + (tps>>1)) / tps;
+#endif
+    REG_TCU_TDFR(0) = latch;
+    REG_TCU_TDHR(0) = latch;
+
+    __tcu_clear_full_match_flag(0);
+    __tcu_start_counter(0);
+    
+    //printf("TCSR = 0x%04x\r\n",*(volatile u16 *)0xb000204C);
+}
+
+void TCU0(void)
+{
+    int i;
+
+    /* Run through the list of tick tasks */
+    for(i = 0; i < MAX_NUM_TICK_TASKS; i++)
+    {
+        if(tick_funcs[i])
+            tick_funcs[i]();
+    }
+    current_tick++;
+}
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
index a4bf766..6d1e68e 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
@@ -28,13 +28,324 @@
 #include <string.h>
 #include "kernel.h"
 
+#define NUM_DMA  6
+#define NUM_GPIO 128
+#define IRQ_MAX  (IRQ_GPIO_0 + NUM_GPIO)
+
+static void UIRQ(void)
+{
+    panicf("Unhandled interrupt occurred\n");
+}
+
+#define default_interrupt(name) \
+  extern __attribute__((weak,alias("UIRQ"))) void name (void)
+
+default_interrupt(I2C);
+default_interrupt(EMC);
+default_interrupt(UHC);
+default_interrupt(UART0);
+default_interrupt(SADC);
+default_interrupt(MSC);
+default_interrupt(RTC);
+default_interrupt(SSI);
+default_interrupt(CIM);
+default_interrupt(AIC);
+default_interrupt(ETH);
+default_interrupt(TCU3);
+default_interrupt(TCU2);
+default_interrupt(TCU1);
+default_interrupt(TCU0);
+default_interrupt(UDC);
+default_interrupt(IPU);
+default_interrupt(LCD);
+
+default_interrupt(DMA0);
+default_interrupt(DMA1);
+default_interrupt(DMA2);
+default_interrupt(DMA3);
+default_interrupt(DMA4);
+default_interrupt(DMA5);
+
+default_interrupt(GPIO0);
+default_interrupt(GPIO1);
+default_interrupt(GPIO2);
+default_interrupt(GPIO3);
+default_interrupt(GPIO4);
+default_interrupt(GPIO5);
+default_interrupt(GPIO6);
+default_interrupt(GPIO7);
+default_interrupt(GPIO8);
+default_interrupt(GPIO9);
+default_interrupt(GPIO10);
+default_interrupt(GPIO11);
+default_interrupt(GPIO12);
+default_interrupt(GPIO13);
+default_interrupt(GPIO14);
+default_interrupt(GPIO15);
+default_interrupt(GPIO16);
+default_interrupt(GPIO17);
+default_interrupt(GPIO18);
+default_interrupt(GPIO19);
+default_interrupt(GPIO20);
+default_interrupt(GPIO21);
+default_interrupt(GPIO22);
+default_interrupt(GPIO23);
+default_interrupt(GPIO24);
+default_interrupt(GPIO25);
+default_interrupt(GPIO26);
+default_interrupt(GPIO27);
+default_interrupt(GPIO28);
+default_interrupt(GPIO29);
+default_interrupt(GPIO30);
+default_interrupt(GPIO31);
+default_interrupt(GPIO32);
+default_interrupt(GPIO33);
+default_interrupt(GPIO34);
+default_interrupt(GPIO35);
+default_interrupt(GPIO36);
+default_interrupt(GPIO37);
+default_interrupt(GPIO38);
+default_interrupt(GPIO39);
+default_interrupt(GPIO40);
+default_interrupt(GPIO41);
+default_interrupt(GPIO42);
+default_interrupt(GPIO43);
+default_interrupt(GPIO44);
+default_interrupt(GPIO45);
+default_interrupt(GPIO46);
+default_interrupt(GPIO47);
+default_interrupt(GPIO48);
+default_interrupt(GPIO49);
+default_interrupt(GPIO50);
+default_interrupt(GPIO51);
+default_interrupt(GPIO52);
+default_interrupt(GPIO53);
+default_interrupt(GPIO54);
+default_interrupt(GPIO55);
+default_interrupt(GPIO56);
+default_interrupt(GPIO57);
+default_interrupt(GPIO58);
+default_interrupt(GPIO59);
+default_interrupt(GPIO60);
+default_interrupt(GPIO61);
+default_interrupt(GPIO62);
+default_interrupt(GPIO63);
+default_interrupt(GPIO64);
+default_interrupt(GPIO65);
+default_interrupt(GPIO66);
+default_interrupt(GPIO67);
+default_interrupt(GPIO68);
+default_interrupt(GPIO69);
+default_interrupt(GPIO70);
+default_interrupt(GPIO71);
+default_interrupt(GPIO72);
+default_interrupt(GPIO73);
+default_interrupt(GPIO74);
+default_interrupt(GPIO75);
+default_interrupt(GPIO76);
+default_interrupt(GPIO77);
+default_interrupt(GPIO78);
+default_interrupt(GPIO79);
+default_interrupt(GPIO80);
+default_interrupt(GPIO81);
+default_interrupt(GPIO82);
+default_interrupt(GPIO83);
+default_interrupt(GPIO84);
+default_interrupt(GPIO85);
+default_interrupt(GPIO86);
+default_interrupt(GPIO87);
+default_interrupt(GPIO88);
+default_interrupt(GPIO89);
+default_interrupt(GPIO90);
+default_interrupt(GPIO91);
+default_interrupt(GPIO92);
+default_interrupt(GPIO93);
+default_interrupt(GPIO94);
+default_interrupt(GPIO95);
+default_interrupt(GPIO96);
+default_interrupt(GPIO97);
+default_interrupt(GPIO98);
+default_interrupt(GPIO99);
+default_interrupt(GPIO100);
+default_interrupt(GPIO101);
+default_interrupt(GPIO102);
+default_interrupt(GPIO103);
+default_interrupt(GPIO104);
+default_interrupt(GPIO105);
+default_interrupt(GPIO106);
+default_interrupt(GPIO107);
+default_interrupt(GPIO108);
+default_interrupt(GPIO109);
+default_interrupt(GPIO110);
+default_interrupt(GPIO111);
+default_interrupt(GPIO112);
+default_interrupt(GPIO113);
+default_interrupt(GPIO114);
+default_interrupt(GPIO115);
+default_interrupt(GPIO116);
+default_interrupt(GPIO117);
+default_interrupt(GPIO118);
+default_interrupt(GPIO119);
+default_interrupt(GPIO120);
+default_interrupt(GPIO121);
+default_interrupt(GPIO122);
+default_interrupt(GPIO123);
+default_interrupt(GPIO124);
+default_interrupt(GPIO125);
+default_interrupt(GPIO126);
+default_interrupt(GPIO127);
+
+static void (* const irqvector[])(void) =
+{
+    I2C,EMC,UHC,UART0,SADC,MSC,RTC,SSI,
+    CIM,AIC,ETH,UIRQ,TCU3,TCU2,TCU1,TCU0,
+    UDC,UIRQ,UIRQ,UIRQ,UIRQ,IPU,LCD,UIRQ,
+    DMA0,DMA1,DMA2,DMA3,DMA4,DMA5,UIRQ,UIRQ,
+    UIRQ,UIRQ,UIRQ,UIRQ,UIRQ,UIRQ,UIRQ,UIRQ,
+    GPIO0,GPIO1,GPIO2,GPIO3,GPIO4,GPIO5,GPIO6,GPIO7,
+    GPIO8,GPIO9,GPIO10,GPIO11,GPIO12,GPIO13,GPIO14,GPIO15,
+    GPIO16,GPIO17,GPIO18,GPIO19,GPIO20,GPIO21,GPIO22,GPIO23,
+    GPIO24,GPIO25,GPIO26,GPIO27,GPIO28,GPIO29,GPIO30,GPIO31,
+    GPIO32,GPIO33,GPIO34,GPIO35,GPIO36,GPIO37,GPIO38,GPIO39,
+    GPIO40,GPIO41,GPIO42,GPIO43,GPIO44,GPIO45,GPIO46,GPIO47,
+    GPIO48,GPIO49,GPIO50,GPIO51,GPIO52,GPIO53,GPIO54,GPIO55,
+    GPIO56,GPIO57,GPIO58,GPIO59,GPIO60,GPIO61,GPIO62,GPIO63,
+    GPIO64,GPIO65,GPIO66,GPIO67,GPIO68,GPIO69,GPIO70,GPIO71,
+    GPIO72,GPIO73,GPIO74,GPIO75,GPIO76,GPIO77,GPIO78,GPIO79,
+    GPIO80,GPIO81,GPIO82,GPIO83,GPIO84,GPIO85,GPIO86,GPIO87,
+    GPIO88,GPIO89,GPIO90,GPIO91,GPIO92,GPIO93,GPIO94,GPIO95,
+    GPIO96,GPIO97,GPIO98,GPIO99,GPIO100,GPIO101,GPIO102,GPIO103,
+    GPIO104,GPIO105,GPIO106,GPIO107,GPIO108,GPIO109,GPIO110,GPIO111,
+    GPIO112,GPIO113,GPIO114,GPIO115,GPIO116,GPIO117,GPIO118,GPIO119,
+    GPIO120,GPIO121,GPIO122,GPIO123,GPIO124,GPIO125,GPIO126,GPIO127
+};
+
+static unsigned int dma_irq_mask = 0;
+static unsigned int gpio_irq_mask[4] = {0};
+
+static void ena_irq(unsigned int irq)
+{
+    register unsigned int t;
+    if ((irq >= IRQ_GPIO_0) && (irq <= IRQ_GPIO_0 + NUM_GPIO))
+    {
+        __gpio_unmask_irq(irq - IRQ_GPIO_0);
+        t = (irq - IRQ_GPIO_0) >> 5;
+        gpio_irq_mask[t] |= (1 << ((irq - IRQ_GPIO_0) & 0x1f));
+        __intc_unmask_irq(IRQ_GPIO0 - t);
+    }
+    else if ((irq >= IRQ_DMA_0) && (irq <= IRQ_DMA_0 + NUM_DMA))
+    {
+        __dmac_channel_enable_irq(irq - IRQ_DMA_0);
+        dma_irq_mask |= (1 << (irq - IRQ_DMA_0));
+        __intc_unmask_irq(IRQ_DMAC);
+    }
+    else if (irq < 32)
+        __intc_unmask_irq(irq);
+}
+
+static void dis_irq(unsigned int irq)
+{
+    register unsigned int t;
+
+    if ((irq >= IRQ_GPIO_0) && (irq <= IRQ_GPIO_0 + NUM_GPIO))
+    {
+        __gpio_mask_irq(irq - IRQ_GPIO_0);
+        t = (irq - IRQ_GPIO_0) >> 5;
+        gpio_irq_mask[t] &= ~(1 << ((irq - IRQ_GPIO_0) & 0x1f));
+        if (!gpio_irq_mask[t])
+            __intc_mask_irq(IRQ_GPIO0 - t);
+    }
+    else if ((irq >= IRQ_DMA_0) && (irq <= IRQ_DMA_0 + NUM_DMA))
+    {
+        __dmac_channel_disable_irq(irq - IRQ_DMA_0);
+        dma_irq_mask &= ~(1 << (irq - IRQ_DMA_0));
+        if (!dma_irq_mask)
+            __intc_mask_irq(IRQ_DMAC);
+    }
+    else if (irq < 32)
+        __intc_mask_irq(irq);
+}
+
+static void ack_irq(unsigned int irq)
+{
+    __intc_ack_irq(irq);
+    if ((irq >= IRQ_GPIO_0) && (irq <= IRQ_GPIO_0 + NUM_GPIO))
+    {
+        __intc_ack_irq(IRQ_GPIO0 - ((irq - IRQ_GPIO_0)>>5));
+        __gpio_ack_irq(irq - IRQ_GPIO_0);
+    }
+    else if ((irq >= IRQ_DMA_0) && (irq <= IRQ_DMA_0 + NUM_DMA))
+    {
+        __intc_ack_irq(IRQ_DMAC);
+    }
+    else if (irq < 32)
+    {
+        __intc_ack_irq(irq);
+        /* TODO: check if really needed */
+        if (irq == IRQ_TCU0)
+        {
+          __tcu_clear_full_match_flag(0);
+        }
+    }
+}
+
+static unsigned long ipl;
+static int get_irq_number(void)
+{
+    register int irq = 0;
+    
+    ipl |= REG_INTC_IPR;
+
+    if (ipl == 0)
+        return -1;
+
+    /* find out the real irq defined in irq_xxx.c */
+    for (irq = 31; irq >= 0; irq--)
+        if (ipl & (1 << irq))
+            break;
+    
+    if (irq < 0)
+        return -1;
+
+    ipl &= ~(1 << irq);
+
+    switch (irq)
+    {
+        case IRQ_GPIO0:
+            irq = __gpio_group_irq(0) + IRQ_GPIO_0;
+            break;
+        case IRQ_GPIO1:
+            irq = __gpio_group_irq(1) + IRQ_GPIO_0 + 32;
+            break;
+        case IRQ_GPIO2:
+            irq = __gpio_group_irq(2) + IRQ_GPIO_0 + 64;
+            break;
+        case IRQ_GPIO3:
+            irq = __gpio_group_irq(3) + IRQ_GPIO_0 + 96;
+            break;
+        case IRQ_DMAC:
+            irq = __dmac_get_irq() + IRQ_DMA_0;
+            break;
+    }
+
+    return irq;
+}
+
 void intr_handler(void)
 {
+    register int irq = get_irq_number();
+    if(irq < 0)
+        return;
+    
+    ack_irq(irq);
+    if(irq > 0)
+        irqvector[irq-1]();
+    
     printf("Interrupt!");
     return;
 }
 
-void except_handler(void* stack_ptr, unsigned int cause, unsigned int epc)
+void exception_handler(void* stack_ptr, unsigned int cause, unsigned int epc)
 {
     panicf("Exception occurred: [0x%x] at 0x%x (stack at 0x%x)", cause, epc, (unsigned int)stack_ptr);
 }
@@ -211,67 +522,33 @@
 
 void dma_cache_wback_inv(unsigned long addr, unsigned long size)
 {
-	unsigned long end, a;
+    unsigned long end, a;
 
-	if (size >= CACHE_SIZE)
-		__dcache_writeback_all();
-	else
+    if (size >= CACHE_SIZE)
+        __dcache_writeback_all();
+    else
     {
-		unsigned long dc_lsize = CACHE_LINE_SIZE;
+        unsigned long dc_lsize = CACHE_LINE_SIZE;
         
-		a = addr & ~(dc_lsize - 1);
-		end = (addr + size - 1) & ~(dc_lsize - 1);
-		while (1)
+        a = addr & ~(dc_lsize - 1);
+        end = (addr + size - 1) & ~(dc_lsize - 1);
+        while (1)
         {
-			__flush_dcache_line(a);	/* Hit_Writeback_Inv_D */
-			if (a == end)
-				break;
-			a += dc_lsize;
-		}
-	}
-}
-
-extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
-
-#define USE_RTC_CLOCK 0
-void tick_start(unsigned int interval_in_ms)
-{
-    unsigned int tps = interval_in_ms;
-	unsigned int latch;
-	__cpm_start_tcu();
-	
-	__tcu_disable_pwm_output(0);
-	__tcu_mask_half_match_irq(0); 
-	__tcu_unmask_full_match_irq(0);
-
-#if USE_RTC_CLOCK
-	__tcu_select_rtcclk(0);
-	__tcu_select_clk_div1(0);
-    latch = (__cpm_get_rtcclk() + (tps>>1)) / tps;
-#else	
-	__tcu_select_extalclk(0);
-	__tcu_select_clk_div4(0);
-	
-	latch = (JZ_EXTAL / 4 + (tps>>1)) / tps;
-#endif
-	REG_TCU_TDFR(0) = latch;
-	REG_TCU_TDHR(0) = latch;
-
-	__tcu_clear_full_match_flag(0);
-	__tcu_start_counter(0);
-	
-    //printf("TCSR = 0x%04x\r\n",*(volatile u16 *)0xb000204C);
+            __flush_dcache_line(a);    /* Hit_Writeback_Inv_D */
+            if (a == end)
+                break;
+            a += dc_lsize;
+        }
+    }
 }
 
 extern int main(void);
-extern unsigned int _loadaddress;
-extern unsigned int _resetvectorsstart;
-extern unsigned int _resetvectorsend;
-extern unsigned int _vectorsstart;
-extern unsigned int _vectorsend; /* see boot.lds/app.lds */
+extern unsigned int _vectorsstart; /* see boot.lds/app.lds */
 
 void system_main(void)
 {
+    int i;
+    
     cli();
     write_c0_status(1 << 28 | 1 << 10); /* Enable CP | Mask interrupt 2 */
     
@@ -281,12 +558,18 @@
     
     __dcache_writeback_all();
     __icache_invalidate_all();
-    
-    (*((unsigned int*)(0x80000200))) = 0x42;
-    (*((unsigned int*)(0x80000204))) = 0x45;
-    (*((unsigned int*)(0x80000208))) = 0x10020;
 
-    set_c0_status(1 << 22); /* Enable Boot Exception Vectors */
+    //set_c0_status(1 << 22); /* Enable Boot Exception Vectors */
+    
+    /* Init interrupt handlers */
+    ipl = 0;
+    for(i=0;i<IRQ_MAX;i++)
+    {
+        if(irqvector[i] == UIRQ)
+            dis_irq(i);
+        else
+            ena_irq(i);
+    }
     
     sti();
     
diff --git a/firmware/target/mips/ingenic_jz47xx/system-target.h b/firmware/target/mips/ingenic_jz47xx/system-target.h
index f60bcff..cfcec9c 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-target.h
+++ b/firmware/target/mips/ingenic_jz47xx/system-target.h
@@ -31,8 +31,6 @@
 
 #define set_irq_level(status) \
     set_interrupt_status((status), ST0_IE)
-#define set_fiq_status(status) \
-    set_interrupt_status((status), ST0_IE)
 
 static inline int set_interrupt_status(int status, int mask)
 {
@@ -64,12 +62,6 @@
 #define enable_irq() \
     enable_interrupt()
 
-#define disable_fiq() \
-    disable_interrupt()
-
-#define enable_fiq() \
-    enable_interrupt()
-
 static inline int disable_interrupt_save(int mask)
 {
 	unsigned int oldstatus;
@@ -83,19 +75,13 @@
 #define disable_irq_save() \
     disable_interrupt_save(ST0_IE)
 
-#define disable_fiq_save() \
-    disable_interrupt_save(ST0_IE)
-
 static inline void restore_interrupt(int status)
 {
     write_c0_status(status);
 }
 
-#define restore_irq(cpsr) \
-    restore_interrupt(cpsr)
-
-#define restore_fiq(cpsr) \
-    restore_interrupt(cpsr)
+#define restore_irq(c0_status) \
+    restore_interrupt(c0_status)
     
 #define	swap16(x) (((x) & 0xff) << 8 | ((x) >> 8) & 0xff)
 #define	swap32(x) (((x) & 0xff) << 24 | ((x) & 0xff00) << 8 | ((x) & 0xff0000) >> 8 | ((x) >> 24) & 0xff)
@@ -108,6 +94,7 @@
 void __icache_invalidate_all(void);
 void __flush_dcache_line(unsigned long addr);
 void dma_cache_wback_inv(unsigned long addr, unsigned long size);
+int request_irq(unsigned int irq, void (*handler)(void));
 void sti(void);
 void cli(void);