summaryrefslogtreecommitdiffstats
path: root/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2008-08-09 23:31:38 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2008-08-09 23:31:38 +0000
commit447ffc8bf89fde97de2d11023e77887bcb7ffb91 (patch)
tree20f124d12ccf43a6f27072770e2c32b488b74950 /firmware/target/mips/ingenic_jz47xx/system-jz4740.c
parentee398634595e30978295d75706d2316a02975398 (diff)
downloadrockbox-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.c397
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();