diff options
author | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2008-08-09 23:31:38 +0000 |
---|---|---|
committer | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2008-08-09 23:31:38 +0000 |
commit | 447ffc8bf89fde97de2d11023e77887bcb7ffb91 (patch) | |
tree | 20f124d12ccf43a6f27072770e2c32b488b74950 /firmware/target/mips/ingenic_jz47xx/system-jz4740.c | |
parent | ee398634595e30978295d75706d2316a02975398 (diff) | |
download | rockbox-447ffc8bf89fde97de2d11023e77887bcb7ffb91.tar.gz rockbox-447ffc8bf89fde97de2d11023e77887bcb7ffb91.tar.bz2 rockbox-447ffc8bf89fde97de2d11023e77887bcb7ffb91.zip |
* 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
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/system-jz4740.c')
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/system-jz4740.c | 397 |
1 files changed, 340 insertions, 57 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c index a4bf76608b..6d1e68e115 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 __dcache_writeback_all(void) 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 @@ void system_main(void) __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(); |