diff --git a/bsp/ls1cdev/libraries/ls1c_public.c b/bsp/ls1cdev/libraries/ls1c_public.c index 652fd2e219f38c172078f8fb4911446b382c627c..84518f0bd041866b791c522973a08cd6d10d6ab9 100644 --- a/bsp/ls1cdev/libraries/ls1c_public.c +++ b/bsp/ls1cdev/libraries/ls1c_public.c @@ -77,3 +77,41 @@ unsigned int reg_read_32(volatile unsigned int *addr) +/** + * ffs - find first bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ +int ls1c_ffs(int x) +{ + int r = 1; + + if (!x) + return 0; + if (!(x & 0xffff)) { + x >>= 16; + r += 16; + } + if (!(x & 0xff)) { + x >>= 8; + r += 8; + } + if (!(x & 0xf)) { + x >>= 4; + r += 4; + } + if (!(x & 3)) { + x >>= 2; + r += 2; + } + if (!(x & 1)) { + x >>= 1; + r += 1; + } + return r; +} + + diff --git a/bsp/ls1cdev/libraries/ls1c_public.h b/bsp/ls1cdev/libraries/ls1c_public.h index d3b410c4210d919f9ce2b46ffd4b827fde8b71a9..3ecabeafaaa9dec214725e18ad507100fc431f44 100644 --- a/bsp/ls1cdev/libraries/ls1c_public.h +++ b/bsp/ls1cdev/libraries/ls1c_public.h @@ -73,6 +73,12 @@ void reg_write_32(unsigned int data, volatile unsigned int *addr); unsigned int reg_read_32(volatile unsigned int *addr); +/** + * ffs - find first bit set + * @x: the word to search + */ +int ls1c_ffs(int x); + #endif diff --git a/bsp/ls1cdev/rtconfig.py b/bsp/ls1cdev/rtconfig.py index e4eb2f962a1d65d838df1063aa759d58e18c714c..c8da0ea47787ff256a3cb29e99d4b4c69509c6cd 100644 --- a/bsp/ls1cdev/rtconfig.py +++ b/bsp/ls1cdev/rtconfig.py @@ -12,7 +12,8 @@ if os.getenv('RTT_CC'): if CROSS_TOOL == 'gcc': PLATFORM = 'gcc' - EXEC_PATH = '/opt/opt/gcc-4.3-ls232/bin' +# EXEC_PATH = '/opt/opt/gcc-4.3-ls232/bin' + EXEC_PATH = r'D:\mgc\embedded\codebench\bin' else: print '================ERROR===========================' print 'Not support %s yet!' % CROSS_TOOL diff --git a/libcpu/mips/loongson_1c/interrupt.c b/libcpu/mips/loongson_1c/interrupt.c index b39b579731a157135d0b711112aa13c0c4086a79..cc0b8e4e9c702e485183336a0a44d53b50217f24 100644 --- a/libcpu/mips/loongson_1c/interrupt.c +++ b/libcpu/mips/loongson_1c/interrupt.c @@ -18,8 +18,10 @@ #include #include #include "ls1c.h" +#include "ls1c_public.h" -#define MAX_INTR 32 + +#define MAX_INTR (LS1C_NR_IRQS) extern rt_uint32_t rt_interrupt_nest; rt_uint32_t rt_interrupt_from_thread; @@ -50,13 +52,26 @@ static void rt_hw_interrupt_handler(int vector, void *param) void rt_hw_interrupt_init(void) { rt_int32_t idx; + rt_int32_t i; + rt_uint32_t c0_status = 0; + + // 设置协处理器0的状态寄存器SR的IM7-2,允许中断 + c0_status = read_c0_status(); + c0_status |= 0xFC00; + write_c0_status(c0_status); - /* pci active low */ - ls1c_hw0_icregs->int_pol = -1; //must be done here 20110802 lgnq - /* make all interrupts level triggered */ - (ls1c_hw0_icregs+0)->int_edge = 0x0000e000; - /* mask all interrupts */ - (ls1c_hw0_icregs+0)->int_clr = 0xffffffff; + // 龙芯1c的中断分为五组 + for (i=0; i<5; i++) + { + /* disable */ + (ls1c_hw0_icregs+i)->int_en = 0x0; + /* pci active low */ + (ls1c_hw0_icregs+i)->int_pol = -1; //must be done here 20110802 lgnq + /* make all interrupts level triggered */ + (ls1c_hw0_icregs+i)->int_edge = 0x00000000; + /* mask all interrupts */ + (ls1c_hw0_icregs+i)->int_clr = 0xffffffff; + } rt_memset(irq_handle_table, 0x00, sizeof(irq_handle_table)); for (idx = 0; idx < MAX_INTR; idx ++) @@ -115,6 +130,51 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, return old_handler; } + +/** + * 执行中断处理函数 + * @IRQn 中断号 + */ +void ls1c_do_IRQ(int IRQn) +{ + rt_isr_handler_t irq_func; + void *param; + + // 找到中断处理函数 + irq_func = irq_handle_table[IRQn].handler; + param = irq_handle_table[IRQn].param; + + // 执行中断处理函数 + irq_func(IRQn, param); + +#ifdef RT_USING_INTERRUPT_INFO + irq_handle_table[IRQn].counter++; +#endif + + return ; +} + + +void ls1c_irq_dispatch(int n) +{ + rt_uint32_t intstatus, irq; + + /* Receive interrupt signal, compute the irq */ + intstatus = (ls1c_hw0_icregs+n)->int_isr & (ls1c_hw0_icregs+n)->int_en; + if (0 == intstatus) + return ; + + // 执行中断处理函数 + irq = ls1c_ffs(intstatus) - 1; + ls1c_do_IRQ((n<<5) + irq); + + /* ack interrupt */ + (ls1c_hw0_icregs+n)->int_clr |= (1 << irq); + + return ; +} + + void rt_interrupt_dispatch(void *ptreg) { int irq; @@ -139,50 +199,25 @@ void rt_interrupt_dispatch(void *ptreg) { rt_hw_timer_handler(); } - - if (pending_im & CAUSEF_IP2) + else if (pending_im & CAUSEF_IP2) { - /* the hardware interrupt */ - status = ls1c_hw0_icregs->int_isr; - if (!status) - return; - - for (irq = MAX_INTR; irq > 0; --irq) - { - if ((status & (1 << irq))) - { - status &= ~(1 << irq); - - irq_func = irq_handle_table[irq].handler; - param = irq_handle_table[irq].param; - - /* do interrupt */ - irq_func(irq, param); - -#ifdef RT_USING_INTERRUPT_INFO - irq_handle_table[irq].counter++; -#endif /* RT_USING_INTERRUPT_INFO */ - - /* ack interrupt */ - ls1c_hw0_icregs->int_clr |= (1 << irq); - } - } + ls1c_irq_dispatch(0); } else if (pending_im & CAUSEF_IP3) { - rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); + ls1c_irq_dispatch(1); } else if (pending_im & CAUSEF_IP4) { - rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); + ls1c_irq_dispatch(2); } else if (pending_im & CAUSEF_IP5) { - rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); + ls1c_irq_dispatch(3); } else if (pending_im & CAUSEF_IP6) { - rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); + ls1c_irq_dispatch(4); } }