diff options
| author | Rogerz Zhang <[email protected]> | 2013-04-01 19:06:22 +0800 |
|---|---|---|
| committer | Rogerz Zhang <[email protected]> | 2013-04-01 19:06:22 +0800 |
| commit | 489b3822f04878737eb0736a123ef7e1fa21e58c (patch) | |
| tree | 226b28a3a8d67558431f509b8db55e5d26a8773d /libcpu | |
| parent | 158e9cdf9132e1d51c526f103d31eb07e56adace (diff) | |
| parent | d781e564606ab40184612bacf0a0bfa5dc094400 (diff) | |
Merge remote-tracking branch 'official/master' into auto-ci
Diffstat (limited to 'libcpu')
| -rw-r--r-- | libcpu/arm/AT91SAM7X/interrupt.c | 37 | ||||
| -rw-r--r-- | libcpu/arm/AT91SAM7X/trap.c | 15 | ||||
| -rwxr-xr-x | libcpu/arm/at91sam926x/cpu.c | 56 | ||||
| -rwxr-xr-x | libcpu/arm/at91sam926x/interrupt.c | 468 | ||||
| -rwxr-xr-x | libcpu/arm/at91sam926x/trap.c | 9 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m3/cpuport.c | 40 | ||||
| -rw-r--r-- | libcpu/arm/lpc214x/cpuport.c | 70 | ||||
| -rw-r--r-- | libcpu/arm/lpc24xx/interrupt.c | 56 | ||||
| -rw-r--r-- | libcpu/arm/lpc24xx/trap.c | 17 | ||||
| -rw-r--r-- | libcpu/arm/s3c24x0/interrupt.c | 79 | ||||
| -rw-r--r-- | libcpu/arm/s3c24x0/trap.c | 35 | ||||
| -rw-r--r-- | libcpu/arm/sep4020/interrupt.c | 86 | ||||
| -rw-r--r-- | libcpu/arm/sep4020/trap.c | 44 | ||||
| -rw-r--r-- | libcpu/mips/jz47xx/interrupt.c | 41 | ||||
| -rw-r--r-- | libcpu/mips/loongson/interrupt.c | 106 | ||||
| -rw-r--r-- | libcpu/mips/loongson_1b/interrupt.c | 57 | ||||
| -rw-r--r-- | libcpu/ppc/ppc405/interrupt.c | 26 | ||||
| -rw-r--r-- | libcpu/ppc/ppc405/serial.c | 6 |
18 files changed, 788 insertions, 460 deletions
diff --git a/libcpu/arm/AT91SAM7X/interrupt.c b/libcpu/arm/AT91SAM7X/interrupt.c index d3cbbcda2e..71884f9f3f 100644 --- a/libcpu/arm/AT91SAM7X/interrupt.c +++ b/libcpu/arm/AT91SAM7X/interrupt.c @@ -10,13 +10,18 @@ * Change Logs: * Date Author Notes * 2006-08-23 Bernard first version + * 2013-03-29 aozima Modify the interrupt interface implementations. */ #include <rtthread.h> +#include <rthw.h> #include "AT91SAM7X256.h" #define MAX_HANDLERS 32 +/* exception and interrupt handler table */ +struct rt_irq_desc irq_desc[MAX_HANDLERS]; + extern rt_uint32_t rt_interrupt_nest; rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; @@ -27,7 +32,7 @@ rt_uint32_t rt_thread_switch_interrupt_flag; */ /*@{*/ -void rt_hw_interrupt_handler(int vector) +static void rt_hw_interrupt_handler(int vector, void *param) { rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); } @@ -35,10 +40,17 @@ void rt_hw_interrupt_handler(int vector) /** * This function will initialize hardware interrupt */ -void rt_hw_interrupt_init() +void rt_hw_interrupt_init(void) { rt_base_t index; + /* init exceptions table */ + for(index=0; index < MAX_HANDLERS; index++) + { + irq_desc[index].handler = (rt_isr_handler_t)rt_hw_interrupt_handler; + irq_desc[index].param = RT_NULL; + } + for (index = 0; index < MAX_HANDLERS; index ++) { AT91C_BASE_AIC->AIC_SVR[index] = (rt_uint32_t)rt_hw_interrupt_handler; @@ -76,16 +88,27 @@ void rt_hw_interrupt_umask(int vector) /** * This function will install a interrupt service routine to a interrupt. * @param vector the interrupt number - * @param new_handler the interrupt service routine to be installed - * @param old_handler the old interrupt service routine + * @param handler the interrupt service routine to be installed + * @param param the parameter for interrupt service routine + * @name unused. + * + * @return the old handler */ -void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler) +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, char *name) { + rt_isr_handler_t old_handler = RT_NULL; if(vector >= 0 && vector < MAX_HANDLERS) { - if (old_handler != RT_NULL) *old_handler = (rt_isr_handler_t)AT91C_BASE_AIC->AIC_SVR[vector]; - if (new_handler != RT_NULL) AT91C_BASE_AIC->AIC_SVR[vector] = (rt_uint32_t)new_handler; + old_handler = irq_desc[vector].handler; + if (handler != RT_NULL) + { + irq_desc[vector].handler = (rt_isr_handler_t)handler; + irq_desc[vector].param = param; + } } + + return old_handler; } /*@}*/ diff --git a/libcpu/arm/AT91SAM7X/trap.c b/libcpu/arm/AT91SAM7X/trap.c index 2e137fc009..74d1cba445 100644 --- a/libcpu/arm/AT91SAM7X/trap.c +++ b/libcpu/arm/AT91SAM7X/trap.c @@ -22,23 +22,28 @@ */ /*@{*/ -void rt_hw_trap_irq() +void rt_hw_trap_irq(void) { - rt_isr_handler_t hander = (rt_isr_handler_t)AT91C_BASE_AIC->AIC_IVR; + int irqno; + extern struct rt_irq_desc irq_desc[]; - hander(AT91C_BASE_AIC->AIC_ISR); + /* get interrupt number */ + irqno = AT91C_BASE_AIC->AIC_ISR; + + /* invoke isr with parameters */ + irq_desc[irqno].handler(irqno, irq_desc[irqno].param); /* end of interrupt */ AT91C_BASE_AIC->AIC_EOICR = 0; } -void rt_hw_trap_fiq() +void rt_hw_trap_fiq(void) { rt_kprintf("fast interrupt request\n"); } extern struct rt_thread* rt_current_thread; -void rt_hw_trap_abort() +void rt_hw_trap_abort(void) { rt_kprintf("Abort occured!!! Thread [%s] suspended.\n",rt_current_thread->name); rt_thread_suspend(rt_current_thread); diff --git a/libcpu/arm/at91sam926x/cpu.c b/libcpu/arm/at91sam926x/cpu.c index abda8deb29..dce573c83d 100755 --- a/libcpu/arm/at91sam926x/cpu.c +++ b/libcpu/arm/at91sam926x/cpu.c @@ -190,4 +190,60 @@ void rt_hw_cpu_shutdown() } } +#ifdef RT_USING_CPU_FFS +/** + * This function finds the first bit set (beginning with the least significant bit) + * in value and return the index of that bit. + * + * Bits are numbered starting at 1 (the least significant bit). A return value of + * zero from any of these functions means that the argument was zero. + * + * @return return the index of the first bit set. If value is 0, then this function + * shall return 0. + */ +#if defined(__CC_ARM) +int __rt_ffs(int value) +{ + register rt_uint32_t x; + + if (value == 0) + return value; + + __asm + { + rsb x, value, #0 + and x, x, value + clz x, x + rsb x, x, #32 + } + + return x; +} +#elif defined(__IAR_SYSTEMS_ICC__) +int __rt_ffs(int value) +{ + if (value == 0) + return value; + + __ASM("RSB r4, r0, #0"); + __ASM("AND r4, r4, r0"); + __ASM("CLZ r4, r4"); + __ASM("RSB r0, r4, #32"); +} +#elif defined(__GNUC__) +int __rt_ffs(int value) +{ + if (value == 0) + return value; + + value &= (-value); + asm ("clz %0, %1": "=r"(value) :"r"(value)); + + return (32 - value); +} +#endif + +#endif + + /*@}*/ diff --git a/libcpu/arm/at91sam926x/interrupt.c b/libcpu/arm/at91sam926x/interrupt.c index 31e49283dd..0a1809e43b 100755 --- a/libcpu/arm/at91sam926x/interrupt.c +++ b/libcpu/arm/at91sam926x/interrupt.c @@ -12,15 +12,16 @@ * 2011-01-13 weety first version */ -#include <rtthread.h> +#include <rthw.h> #include "at91sam926x.h" -#define MAX_HANDLERS (AIC_IRQS + PIN_IRQS) +#define MAX_HANDLERS (AIC_IRQS + PIN_IRQS) extern rt_uint32_t rt_interrupt_nest; /* exception and interrupt handler table */ -rt_isr_handler_t isr_table[MAX_HANDLERS]; +struct rt_irq_desc irq_desc[MAX_HANDLERS]; + rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_thread_switch_interrupt_flag; @@ -37,38 +38,38 @@ rt_uint32_t at91_extern_irq; * The default interrupt priority levels (0 = lowest, 7 = highest). */ static rt_uint32_t at91sam9260_default_irq_priority[MAX_HANDLERS] = { - 7, /* Advanced Interrupt Controller */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A */ - 1, /* Parallel IO Controller B */ - 1, /* Parallel IO Controller C */ - 0, /* Analog-to-Digital Converter */ - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 0, /* Multimedia Card Interface */ - 2, /* USB Device Port */ - 6, /* Two-Wire Interface */ - 5, /* Serial Peripheral Interface 0 */ - 5, /* Serial Peripheral Interface 1 */ - 5, /* Serial Synchronous Controller */ - 0, - 0, - 0, /* Timer Counter 0 */ - 0, /* Timer Counter 1 */ - 0, /* Timer Counter 2 */ - 2, /* USB Host port */ - 3, /* Ethernet */ - 0, /* Image Sensor Interface */ - 5, /* USART 3 */ - 5, /* USART 4 */ - 5, /* USART 5 */ - 0, /* Timer Counter 3 */ - 0, /* Timer Counter 4 */ - 0, /* Timer Counter 5 */ - 0, /* Advanced Interrupt Controller */ - 0, /* Advanced Interrupt Controller */ - 0, /* Advanced Interrupt Controller */ + 7, /* Advanced Interrupt Controller */ + 7, /* System Peripherals */ + 1, /* Parallel IO Controller A */ + 1, /* Parallel IO Controller B */ + 1, /* Parallel IO Controller C */ + 0, /* Analog-to-Digital Converter */ + 5, /* USART 0 */ + 5, /* USART 1 */ + 5, /* USART 2 */ + 0, /* Multimedia Card Interface */ + 2, /* USB Device Port */ + 6, /* Two-Wire Interface */ + 5, /* Serial Peripheral Interface 0 */ + 5, /* Serial Peripheral Interface 1 */ + 5, /* Serial Synchronous Controller */ + 0, + 0, + 0, /* Timer Counter 0 */ + 0, /* Timer Counter 1 */ + 0, /* Timer Counter 2 */ + 2, /* USB Host port */ + 3, /* Ethernet */ + 0, /* Image Sensor Interface */ + 5, /* USART 3 */ + 5, /* USART 4 */ + 5, /* USART 5 */ + 0, /* Timer Counter 3 */ + 0, /* Timer Counter 4 */ + 0, /* Timer Counter 5 */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ }; /** @@ -79,45 +80,47 @@ static rt_uint32_t at91sam9260_default_irq_priority[MAX_HANDLERS] = { void rt_hw_interrupt_mask(int irq); void rt_hw_interrupt_umask(int irq); -rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector) +rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param) { - rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); - return RT_NULL; + rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); + return RT_NULL; } -rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector) +rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector, void *param) { - rt_uint32_t isr, pio, irq_n; + rt_uint32_t isr, pio, irq_n; + void *parameter; - if (vector == AT91SAM9260_ID_PIOA) - { - pio = AT91_PIOA; - irq_n = AIC_IRQS; - } - else if (vector == AT91SAM9260_ID_PIOB) - { - pio = AT91_PIOB; - irq_n = AIC_IRQS + 32; - } - else if (vector == AT91SAM9260_ID_PIOC) - { - pio = AT91_PIOC; - irq_n = AIC_IRQS + 32*2; - } - else - return RT_NULL; - isr = at91_sys_read(pio+PIO_ISR) & at91_sys_read(pio+PIO_IMR); - while (isr) - { - if (isr & 1) - { - isr_table[irq_n](irq_n); - } - isr >>= 1; - irq_n++; - } + if (vector == AT91SAM9260_ID_PIOA) + { + pio = AT91_PIOA; + irq_n = AIC_IRQS; + } + else if (vector == AT91SAM9260_ID_PIOB) + { + pio = AT91_PIOB; + irq_n = AIC_IRQS + 32; + } + else if (vector == AT91SAM9260_ID_PIOC) + { + pio = AT91_PIOC; + irq_n = AIC_IRQS + 32*2; + } + else + return RT_NULL; + isr = at91_sys_read(pio+PIO_ISR) & at91_sys_read(pio+PIO_IMR); + while (isr) + { + if (isr & 1) + { + parameter = irq_desc[irq_n].param; + irq_desc[irq_n].handler(irq_n, parameter); + } + isr >>= 1; + irq_n++; + } - return RT_NULL; + return RT_NULL; } /* @@ -125,52 +128,61 @@ rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector) */ void at91_aic_init(rt_uint32_t *priority) { - rt_uint32_t i; + rt_uint32_t i; - /* - * The IVR is used by macro get_irqnr_and_base to read and verify. - * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. - */ - for (i = 0; i < AIC_IRQS; i++) { - /* Put irq number in Source Vector Register: */ - at91_sys_write(AT91_AIC_SVR(i), i); - /* Active Low interrupt, with the specified priority */ - at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); - //AT91_AIC_SRCTYPE_FALLING + /* + * The IVR is used by macro get_irqnr_and_base to read and verify. + * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. + */ + for (i = 0; i < AIC_IRQS; i++) { + /* Put irq number in Source Vector Register: */ + at91_sys_write(AT91_AIC_SVR(i), i); + /* Active Low interrupt, with the specified priority */ + at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); + //AT91_AIC_SRCTYPE_FALLING - /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ - if (i < 8) - at91_sys_write(AT91_AIC_EOICR, 0); - } + /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ + if (i < 8) + at91_sys_write(AT91_AIC_EOICR, 0); + } - /* - * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS - * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU - */ - at91_sys_write(AT91_AIC_SPU, AIC_IRQS); + /* + * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS + * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU + */ + at91_sys_write(AT91_AIC_SPU, AIC_IRQS); - /* No debugging in AIC: Debug (Protect) Control Register */ - at91_sys_write(AT91_AIC_DCR, 0); + /* No debugging in AIC: Debug (Protect) Control Register */ + at91_sys_write(AT91_AIC_DCR, 0); - /* Disable and clear all interrupts initially */ - at91_sys_write(AT91_AIC_IDCR, 0xFFFFFFFF); - at91_sys_write(AT91_AIC_ICCR, 0xFFFFFFFF); + /* Disable and clear all interrupts initially */ + at91_sys_write(AT91_AIC_IDCR, 0xFFFFFFFF); + at91_sys_write(AT91_AIC_ICCR, 0xFFFFFFFF); } static void at91_gpio_irq_init() { - at91_sys_write(AT91_PIOA+PIO_IDR, 0xffffffff); - at91_sys_write(AT91_PIOB+PIO_IDR, 0xffffffff); - at91_sys_write(AT91_PIOC+PIO_IDR, 0xffffffff); + int i, idx; + char *name[] = {"PIOA", "PIOB", "PIOC"}; + + at91_sys_write(AT91_PIOA+PIO_IDR, 0xffffffff); + at91_sys_write(AT91_PIOB+PIO_IDR, 0xffffffff); + at91_sys_write(AT91_PIOC+PIO_IDR, 0xffffffff); - isr_table[AT91SAM9260_ID_PIOA] = (rt_isr_handler_t)at91_gpio_irq_handle; - isr_table[AT91SAM9260_ID_PIOB] = (rt_isr_handler_t)at91_gpio_irq_handle; - isr_table[AT91SAM9260_ID_PIOC] = (rt_isr_handler_t)at91_gpio_irq_handle; + idx = AT91SAM9260_ID_PIOA; + for (i = 0; i < 3; i++) + { + rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, name[i]); + irq_desc[idx].handler = (rt_isr_handler_t)at91_gpio_irq_handle; + irq_desc[idx].param = RT_NULL; + irq_desc[idx].counter = 0; + idx++; + } - rt_hw_interrupt_umask(AT91SAM9260_ID_PIOA); - rt_hw_interrupt_umask(AT91SAM9260_ID_PIOB); - rt_hw_interrupt_umask(AT91SAM9260_ID_PIOC); + rt_hw_interrupt_umask(AT91SAM9260_ID_PIOA); + rt_hw_interrupt_umask(AT91SAM9260_ID_PIOB); + rt_hw_interrupt_umask(AT91SAM9260_ID_PIOC); } @@ -179,53 +191,56 @@ static void at91_gpio_irq_init() */ void rt_hw_interrupt_init(void) { - rt_int32_t i; - register rt_uint32_t idx; - rt_uint32_t *priority = at91sam9260_default_irq_priority; - - at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) - | (1 << AT91SAM9260_ID_IRQ2); + rt_int32_t i; + register rt_uint32_t idx; + rt_uint32_t *priority = at91sam9260_default_irq_priority; + + at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) + | (1 << AT91SAM9260_ID_IRQ2); - /* Initialize the AIC interrupt controller */ - at91_aic_init(priority); + /* Initialize the AIC interrupt controller */ + at91_aic_init(priority); - /* init exceptions table */ - for(idx=0; idx < MAX_HANDLERS; idx++) - { - isr_table[idx] = (rt_isr_handler_t)rt_hw_interrupt_handle; - } + /* init exceptions table */ + for(idx=0; idx < MAX_HANDLERS; idx++) + { + rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, "default"); + irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle; + irq_desc[idx].param = RT_NULL; + irq_desc[idx].counter = 0; + } - at91_gpio_irq_init(); + at91_gpio_irq_init(); - /* init interrupt nest, and context in thread sp */ - rt_interrupt_nest = 0; - rt_interrupt_from_thread = 0; - rt_interrupt_to_thread = 0; - rt_thread_switch_interrupt_flag = 0; + /* init interrupt nest, and context in thread sp */ + rt_interrupt_nest = 0; + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = 0; + rt_thread_switch_interrupt_flag = 0; } static void at91_gpio_irq_mask(int irq) { - rt_uint32_t pin, pio, bank; + rt_uint32_t pin, pio, bank; - bank = (irq - AIC_IRQS)>>5; + bank = (irq - AIC_IRQS)>>5; - if (bank == 0) - { - pio = AT91_PIOA; - } - else if (bank == 1) - { - pio = AT91_PIOB; - } - else if (bank == 2) - { - pio = AT91_PIOC; - } - else - return; - pin = 1 << ((irq - AIC_IRQS) & 31); - at91_sys_write(pio+PIO_IDR, pin); + if (bank == 0) + { + pio = AT91_PIOA; + } + else if (bank == 1) + { + pio = AT91_PIOB; + } + else if (bank == 2) + { + pio = AT91_PIOC; + } + else + return; + pin = 1 << ((irq - AIC_IRQS) & 31); + at91_sys_write(pio+PIO_IDR, pin); } /** @@ -234,39 +249,39 @@ static void at91_gpio_irq_mask(int irq) */ void rt_hw_interrupt_mask(int irq) { - if (irq >= AIC_IRQS) - { - at91_gpio_irq_mask(irq); - } - else - { - /* Disable interrupt on AIC */ - at91_sys_write(AT91_AIC_IDCR, 1 << irq); - } + if (irq >= AIC_IRQS) + { + at91_gpio_irq_mask(irq); + } + else + { + /* Disable interrupt on AIC */ + at91_sys_write(AT91_AIC_IDCR, 1 << irq); + } } static void at91_gpio_irq_umask(int irq) { - rt_uint32_t pin, pio, bank; + rt_uint32_t pin, pio, bank; - bank = (irq - AIC_IRQS)>>5; + bank = (irq - AIC_IRQS)>>5; - if (bank == 0) - { - pio = AT91_PIOA; - } - else if (bank == 1) - { - pio = AT91_PIOB; - } - else if (bank == 2) - { - pio = AT91_PIOC; - } - else - return; - pin = 1 << ((irq - AIC_IRQS) & 31); - at91_sys_write(pio+PIO_IER, pin); + if (bank == 0) + { + pio = AT91_PIOA; + } + else if (bank == 1) + { + pio = AT91_PIOB; + } + else if (bank == 2) + { + pio = AT91_PIOC; + } + else + return; + pin = 1 << ((irq - AIC_IRQS) & 31); + at91_sys_write(pio+PIO_IER, pin); } /** @@ -275,30 +290,43 @@ static void at91_gpio_irq_umask(int irq) */ void rt_hw_interrupt_umask(int irq) { - if (irq >= AIC_IRQS) - { - at91_gpio_irq_umask(irq); - } - else - { - /* Enable interrupt on AIC */ - at91_sys_write(AT91_AIC_IECR, 1 << irq); - } + if (irq >= AIC_IRQS) + { + at91_gpio_irq_umask(irq); + } + else + { + /* Enable interrupt on AIC */ + at91_sys_write(AT91_AIC_IECR, 1 << irq); + } } /** * This function will install a interrupt service routine to a interrupt. * @param vector the interrupt number - * @param new_handler the interrupt service routine to be installed - * @param old_handler the old interrupt service routine + * @param handler the interrupt service routine to be installed + * @param param the interrupt service function parameter + * @param name the interrupt name + * @return old handler */ -void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler) +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, char *name) { - if(vector < MAX_HANDLERS) - { - if (old_handler != RT_NULL) *old_handler = isr_table[vector]; - if (new_handler != RT_NULL) isr_table[vector] = new_handler; - } + rt_isr_handler_t old_handler = RT_NULL; + + if(vector < MAX_HANDLERS) + { + old_handler = irq_desc[vector].handler; + if (handler != RT_NULL) + { + rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name); + irq_desc[vector].handler = (rt_isr_handler_t)handler; + irq_desc[vector].param = param; + irq_desc[vector].counter = 0; + } + } + + return old_handler; } /*@}*/ @@ -306,32 +334,54 @@ void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_ha static int at91_aic_set_type(unsigned irq, unsigned type) { - unsigned int smr, srctype; + unsigned int smr, srctype; - switch (type) { - case IRQ_TYPE_LEVEL_HIGH: - srctype = AT91_AIC_SRCTYPE_HIGH; - break; - case IRQ_TYPE_EDGE_RISING: - srctype = AT91_AIC_SRCTYPE_RISING; - break; - case IRQ_TYPE_LEVEL_LOW: - if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ - srctype = AT91_AIC_SRCTYPE_LOW; - else - return -1; - break; - case IRQ_TYPE_EDGE_FALLING: - if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ - srctype = AT91_AIC_SRCTYPE_FALLING; - else - return -1; - break; - default: - return -1; - } + switch (type) { + case IRQ_TYPE_LEVEL_HIGH: + srctype = AT91_AIC_SRCTYPE_HIGH; + break; + case IRQ_TYPE_EDGE_RISING: + srctype = AT91_AIC_SRCTYPE_RISING; + break; + case IRQ_TYPE_LEVEL_LOW: + if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ + srctype = AT91_AIC_SRCTYPE_LOW; + else + return -1; + break; + case IRQ_TYPE_EDGE_FALLING: + if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ + srctype = AT91_AIC_SRCTYPE_FALLING; + else + return -1; + break; + default: + return -1; + } + + smr = at91_sys_read(AT91_AIC_SMR(irq)) & ~AT91_AIC_SRCTYPE; + at91_sys_write(AT91_AIC_SMR(irq), smr | srctype); + return 0; +} - smr = at91_sys_read(AT91_AIC_SMR(irq)) & ~AT91_AIC_SRCTYPE; - at91_sys_write(AT91_AIC_SMR(irq), smr | srctype); - return 0; +#ifdef RT_USING_FINSH +void list_irq(void) +{ + int irq; + + rt_kprintf("number\tcount\tname\n"); + for (irq = 0; irq < MAX_HANDLERS; irq++) + { + if (rt_strncmp(irq_desc[irq].name, "default", sizeof("default"))) + { + rt_kprintf("%02ld: %10ld %s\n", irq, irq_desc[irq].counter, irq_desc[irq].name); + } + } } + +#include <finsh.h> +FINSH_FUNCTION_EXPORT(list_irq, list system irq); + +#endif + + diff --git a/libcpu/arm/at91sam926x/trap.c b/libcpu/arm/at91sam926x/trap.c index 2d09c2d56e..9be71ddcae 100755 --- a/libcpu/arm/at91sam926x/trap.c +++ b/libcpu/arm/at91sam926x/trap.c @@ -138,12 +138,13 @@ void rt_hw_trap_resv(struct rt_hw_register *regs) rt_hw_cpu_shutdown(); } -extern rt_isr_handler_t isr_table[]; +extern struct rt_irq_desc irq_desc[]; void rt_hw_trap_irq() { rt_isr_handler_t isr_func; rt_uint32_t irqstat, irq, mask; + void *param; //rt_kprintf("irq interrupt request\n"); /* get irq number */ irq = at91_sys_read(AT91_AIC_IVR); @@ -158,11 +159,13 @@ void rt_hw_trap_irq() //at91_sys_write(AT91_AIC_EOICR, 0x55555555); /* get interrupt service routine */ - isr_func = isr_table[irq]; + isr_func = irq_desc[irq].handler; + param = irq_desc[irq].param; /* turn to interrupt service routine */ - isr_func(irq); + isr_func(irq, param); at91_sys_write(AT91_AIC_EOICR, 0x55555555); //EIOCR must be write any value after interrupt, or else can't response next interrupt + irq_desc[irq].counter ++; } void rt_hw_trap_fiq() diff --git a/libcpu/arm/cortex-m3/cpuport.c b/libcpu/arm/cortex-m3/cpuport.c index b85e9a0956..c96073a6a9 100644 --- a/libcpu/arm/cortex-m3/cpuport.c +++ b/libcpu/arm/cortex-m3/cpuport.c @@ -148,3 +148,43 @@ void rt_hw_cpu_shutdown(void) RT_ASSERT(0); } +#ifdef RT_USING_CPU_FFS +/** + * This function finds the first bit set (beginning with the least significant bit) + * in value and return the index of that bit. + * + * Bits are numbered starting at 1 (the least significant bit). A return value of + * zero from any of these functions means that the argument was zero. + * + * @return return the index of the first bit set. If value is 0, then this function + * shall return 0. + */ +#if defined(__CC_ARM) +__asm int __rt_ffs(int value) +{ + CMP r0, #0x00 + BEQ exit + RBIT r0, r0 + CLZ r0, r0 + ADDS r0, r0, #0x01 + +exit + BX lr +} +#elif defined(__IAR_SYSTEMS_ICC__) +int __rt_ffs(int value) +{ + if (value == 0) return value; + + __ASM("RBIT r0, r0"); + __ASM("CLZ r0, r0"); + __ASM("ADDS r0, r0, #0x01"); +} +#elif defined(__GNUC__) +int __rt_ffs(int value) +{ + return __builtin_ffs(value); +} +#endif + +#endif diff --git a/libcpu/arm/lpc214x/cpuport.c b/libcpu/arm/lpc214x/cpuport.c index 512ff89f08..1cd33b897b 100644 --- a/libcpu/arm/lpc214x/cpuport.c +++ b/libcpu/arm/lpc214x/cpuport.c @@ -10,9 +10,11 @@ * Change Logs: * Date Author Notes * 2011-06-15 aozima the first version for lpc214x + * 2013-03-29 aozima Modify the interrupt interface implementations. */ #include <rtthread.h> +#include <rthw.h> #include "lpc214x.h" #define MAX_HANDLERS 32 @@ -20,6 +22,9 @@ extern rt_uint32_t rt_interrupt_nest; +/* exception and interrupt handler table */ +struct rt_irq_desc irq_desc[MAX_HANDLERS]; + /** * @addtogroup LPC214x */ @@ -71,7 +76,7 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_thread_switch_interrupt_flag; -void rt_hw_interrupt_handler(int vector) +void rt_hw_interrupt_handler(int vector, void *param) { rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); } @@ -79,7 +84,7 @@ void rt_hw_interrupt_handler(int vector) /** * This function will initialize hardware interrupt */ -void rt_hw_interrupt_init() +void rt_hw_interrupt_init(void) { rt_base_t index; rt_uint32_t *vect_addr, *vect_ctl; @@ -90,12 +95,15 @@ void rt_hw_interrupt_init() /* set all to IRQ */ VICIntSelect = 0; + rt_memset(irq_desc, 0x00, sizeof(irq_desc)); for (index = 0; index < MAX_HANDLERS; index ++) { + irq_desc[index].handler = rt_hw_interrupt_handler; + vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + (index << 2)); vect_ctl = (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + (index << 2)); - *vect_addr = (rt_uint32_t)rt_hw_interrupt_handler; + *vect_addr = (rt_uint32_t)&irq_desc[index]; *vect_ctl = 0xF; } @@ -127,30 +135,39 @@ void rt_hw_interrupt_umask(int vector) /** * This function will install a interrupt service routine to a interrupt. * @param vector the interrupt number - * @param new_handler the interrupt service routine to be installed - * @param old_handler the old interrupt service routine + * @param handler the interrupt service routine to be installed + * @param param the interrupt service function parameter + * @param name the interrupt name + * @return old handler */ -void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler) +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, char *name) { - if(vector >= 0 && vector < MAX_HANDLERS) - { - /* get VIC address */ - rt_uint32_t* vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + (vector << 2)); - rt_uint32_t* vect_ctl = (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + (vector << 2)); + rt_isr_handler_t old_handler = RT_NULL; - /* assign IRQ slot and enable this slot */ - *vect_ctl = 0x20 | (vector & 0x1F); + if(vector >= 0 && vector < MAX_HANDLERS) + { + rt_uint32_t* vect_ctl = (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + (vector << 2)); - if (old_handler != RT_NULL) *old_handler = (rt_isr_handler_t) *vect_addr; - if (new_handler != RT_NULL) *vect_addr = (rt_uint32_t) new_handler; - } + /* assign IRQ slot and enable this slot */ + *vect_ctl = 0x20 | (vector & 0x1F); + + old_handler = irq_desc[vector].handler; + if (handler != RT_NULL) + { + irq_desc[vector].handler = handler; + irq_desc[vector].param = param; + } + } + + return old_handler; } /** * this function will reset CPU * */ -void rt_hw_cpu_reset() +void rt_hw_cpu_reset(void) { } @@ -165,18 +182,23 @@ void rt_hw_cpu_shutdown() while (1); } -void rt_hw_trap_irq() +void rt_hw_trap_irq(void) { - rt_isr_handler_t isr_func; + int irqno; + struct rt_irq_desc* irq; + extern struct rt_irq_desc irq_desc[]; + + irq = (struct rt_irq_desc*) VICVectAddr; + irqno = ((rt_uint32_t) irq - (rt_uint32_t) &irq_desc[0])/sizeof(struct rt_irq_desc); - isr_func = (rt_isr_handler_t) VICVectAddr; - isr_func(0); + /* invoke isr */ + irq->handler(irqno, irq->param); - /* acknowledge Interrupt */ - // VICVectAddr = 0; + /* acknowledge Interrupt */ + // VICVectAddr = 0; } -void rt_hw_trap_fiq() +void rt_hw_trap_fiq(void) { rt_kprintf("fast interrupt request\n"); } diff --git a/libcpu/arm/lpc24xx/interrupt.c b/libcpu/arm/lpc24xx/interrupt.c index b18c1e10ff..16d1dd7e99 100644 --- a/libcpu/arm/lpc24xx/interrupt.c +++ b/libcpu/arm/lpc24xx/interrupt.c @@ -10,31 +10,34 @@ * Change Logs: * Date Author Notes * 2008-12-11 XuXinming first version + * 2013-03-29 aozima Modify the interrupt interface implementations. */ #include <rtthread.h> +#include <rthw.h> #include "LPC24xx.h" #define MAX_HANDLERS 32 +/* exception and interrupt handler table */ +struct rt_irq_desc irq_desc[MAX_HANDLERS]; + extern rt_uint32_t rt_interrupt_nest; /* exception and interrupt handler table */ rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_thread_switch_interrupt_flag; - /** * @addtogroup LPC2478 */ /*@{*/ - -void rt_hw_interrupt_handle(int vector) +void rt_hw_interrupt_handler(int vector, void *param) { rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); } -void rt_hw_interrupt_init() +void rt_hw_interrupt_init(void) { register int i; @@ -45,11 +48,15 @@ void rt_hw_interrupt_init() VICVectAddr = 0; VICIntSelect = 0; - for ( i = 0; i < 32; i++ ) + /* init exceptions table */ + rt_memset(irq_desc, 0x00, sizeof(irq_desc)); + for(i=0; i < MAX_HANDLERS; i++) { - vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + i*4); - vect_cntl = (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + i*4); - *vect_addr = 0x0; + irq_desc[i].handler = rt_hw_interrupt_handler; + + vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + i*4); + vect_cntl = (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + i*4); + *vect_addr = (rt_uint32_t)&irq_desc[i]; *vect_cntl = 0xF; } @@ -70,20 +77,31 @@ void rt_hw_interrupt_umask(int vector) VICIntEnable = (1 << vector); } -void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler) +/** + * This function will install a interrupt service routine to a interrupt. + * @param vector the interrupt number + * @param handler the interrupt service routine to be installed + * @param param the parameter for interrupt service routine + * @name unused. + * + * @return the old handler + */ +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, char *name) { - rt_uint32_t *vect_addr; - - if(vector < MAX_HANDLERS) - { - /* find first un-assigned VIC address for the handler */ - vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + vector*4); + rt_isr_handler_t old_handler = RT_NULL; - /* get old handler */ - if (old_handler != RT_NULL) *old_handler = (rt_isr_handler_t)*vect_addr; - - *vect_addr = (rt_uint32_t)new_handler; /* set interrupt vector */ + if(vector >= 0 && vector < MAX_HANDLERS) + { + old_handler = irq_desc[vector].handler; + if (handler != RT_NULL) + { + irq_desc[vector].handler = handler; + irq_desc[vector].param = param; + } } + + return old_handler; } /*@}*/ diff --git a/libcpu/arm/lpc24xx/trap.c b/libcpu/arm/lpc24xx/trap.c index 1aa58bc0d6..71d88101fc 100644 --- a/libcpu/arm/lpc24xx/trap.c +++ b/libcpu/arm/lpc24xx/trap.c @@ -126,17 +126,20 @@ void rt_hw_trap_resv(struct rt_hw_register *regs) } extern rt_isr_handler_t isr_table[]; -void rt_hw_trap_irq() +void rt_hw_trap_irq(void) { - rt_isr_handler_t isr_func; - - isr_func = (rt_isr_handler_t) VICVectAddr; + int irqno; + struct rt_irq_desc* irq; + extern struct rt_irq_desc irq_desc[]; - /* fixme, how to get interrupt number */ - isr_func(0); + irq = (struct rt_irq_desc*) VICVectAddr; + irqno = ((rt_uint32_t) irq - (rt_uint32_t) &irq_desc[0])/sizeof(struct rt_irq_desc); + + /* invoke isr */ + irq->handler(irqno, irq->param); } -void rt_hw_trap_fiq() +void rt_hw_trap_fiq(void) { rt_kprintf("fast interrupt request\n"); } diff --git a/libcpu/arm/s3c24x0/interrupt.c b/libcpu/arm/s3c24x0/interrupt.c index 18cdbaa09f..df0c1406d3 100644 --- a/libcpu/arm/s3c24x0/interrupt.c +++ b/libcpu/arm/s3c24x0/interrupt.c @@ -10,9 +10,11 @@ * Change Logs: * Date Author Notes * 2006-03-13 Bernard first version + * 2013-03-29 aozima Modify the interrupt interface implementations. */ #include <rtthread.h> +#include <rthw.h> #include "s3c24x0.h" #define MAX_HANDLERS 32 @@ -20,7 +22,7 @@ extern rt_uint32_t rt_interrupt_nest; /* exception and interrupt handler table */ -rt_isr_handler_t isr_table[MAX_HANDLERS]; +struct rt_irq_desc isr_table[MAX_HANDLERS]; rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_thread_switch_interrupt_flag; @@ -29,10 +31,9 @@ rt_uint32_t rt_thread_switch_interrupt_flag; */ /*@{*/ -rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector) +static void rt_hw_interrupt_handle(int vector, void *param) { rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); - return RT_NULL; } /** @@ -40,37 +41,38 @@ rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector) */ void rt_hw_interrupt_init(void) { - register rt_uint32_t idx; + register rt_uint32_t idx; - /* all clear source pending */ - SRCPND = 0x0; + /* all clear source pending */ + SRCPND = 0x0; - /* all clear sub source pending */ - SUBSRCPND = 0x0; + /* all clear sub source pending */ + SUBSRCPND = 0x0; - /* all=IRQ mode */ - INTMOD = 0x0; + /* all=IRQ mode */ + INTMOD = 0x0; - /* all interrupt disabled include global bit */ - INTMSK = BIT_ALLMSK; + /* all interrupt disabled include global bit */ + INTMSK = BIT_ALLMSK; - /* all sub interrupt disable */ - INTSUBMSK = BIT_SUB_ALLMSK; + /* all sub interrupt disable */ + INTSUBMSK = BIT_SUB_ALLMSK; - /* all clear interrupt pending */ - INTPND = BIT_ALLMSK; + /* all clear interrupt pending */ + INTPND = BIT_ALLMSK; - /* init exceptions table */ - for(idx=0; idx < MAX_HANDLERS; idx++) - { - isr_table[idx] = (rt_isr_handler_t)rt_hw_interrupt_handle; - } + /* init exceptions table */ + rt_memset(isr_table, 0x00, sizeof(isr_table)); + for(idx=0; idx < MAX_HANDLERS; idx++) + { + isr_table[idx].handler = rt_hw_interrupt_handle; + } - /* init interrupt nest, and context in thread sp */ - rt_interrupt_nest = 0; - rt_interrupt_from_thread = 0; - rt_interrupt_to_thread = 0; - rt_thread_switch_interrupt_flag = 0; + /* init interrupt nest, and context in thread sp */ + rt_interrupt_nest = 0; + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = 0; + rt_thread_switch_interrupt_flag = 0; } /** @@ -105,13 +107,26 @@ void rt_hw_interrupt_umask(int vector) * @param new_handler the interrupt service routine to be installed * @param old_handler the old interrupt service routine */ -void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler) +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, char *name) { - if(vector < MAX_HANDLERS) - { - if (old_handler != RT_NULL) *old_handler = isr_table[vector]; - if (new_handler != RT_NULL) isr_table[vector] = new_handler; - } + rt_isr_handler_t old_handler = RT_NULL; + + if(vector < MAX_HANDLERS) + { + old_handler = isr_table[vector].handler; + + if (handler != RT_NULL) + { +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); +#endif /* RT_USING_INTERRUPT_INFO */ + isr_table[vector].handler = handler; + isr_table[vector].param = param; + } + } + + return old_handler; } /*@}*/ diff --git a/libcpu/arm/s3c24x0/trap.c b/libcpu/arm/s3c24x0/trap.c index bdeae9aab0..f1c81768c9 100644 --- a/libcpu/arm/s3c24x0/trap.c +++ b/libcpu/arm/s3c24x0/trap.c @@ -12,6 +12,7 @@ * 2006-03-13 Bernard first version * 2006-05-27 Bernard add skyeye support * 2007-11-19 Yi.Qiu fix rt_hw_trap_irq function + * 2013-03-29 aozima Modify the interrupt interface implementations. */ #include <rtthread.h> @@ -140,29 +141,35 @@ void rt_hw_trap_resv(struct rt_hw_register *regs) rt_hw_cpu_shutdown(); } -extern rt_isr_handler_t isr_table[]; +extern struct rt_irq_desc isr_table[]; -void rt_hw_trap_irq() +void rt_hw_trap_irq(void) { - unsigned long intstat; - rt_isr_handler_t isr_func; + unsigned long irq; + rt_isr_handler_t isr_func; + void *param; - intstat = INTOFFSET; + irq = INTOFFSET; - if (intstat == INTGLOBAL) return; + if (irq == INTGLOBAL) return; - /* get interrupt service routine */ - isr_func = isr_table[intstat]; + /* get interrupt service routine */ + isr_func = isr_table[irq].handler; + param = isr_table[irq].param; - /* turn to interrupt service routine */ - isr_func(intstat); + /* turn to interrupt service routine */ + isr_func(irq, param); - /* clear pending register */ - /* note: must be the last, if not, may repeat*/ - ClearPending(1 << intstat); + /* clear pending register */ + /* note: must be the last, if not, may repeat*/ + ClearPending(1 << irq); + +#ifdef RT_USING_INTERRUPT_INFO + isr_table[irq].counter++; +#endif /* RT_USING_INTERRUPT_INFO */ } -void rt_hw_trap_fiq() +void rt_hw_trap_fiq(void) { rt_kprintf("fast interrupt request\n"); } diff --git a/libcpu/arm/sep4020/interrupt.c b/libcpu/arm/sep4020/interrupt.c index 8ed22dc816..88130c1a33 100644 --- a/libcpu/arm/sep4020/interrupt.c +++ b/libcpu/arm/sep4020/interrupt.c @@ -10,9 +10,11 @@ * Change Logs: * Date Author Notes * 2006-03-13 Bernard first version + * 2013-03-29 aozima Modify the interrupt interface implementations. */ #include <rtthread.h> +#include <rthw.h> #include <sep4020.h> #define MAX_HANDLERS 32 @@ -20,7 +22,7 @@ extern rt_uint32_t rt_interrupt_nest; /* exception and interrupt handler table */ -rt_isr_handler_t isr_table[MAX_HANDLERS]; +struct rt_irq_desc isr_table[MAX_HANDLERS]; rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_thread_switch_interrupt_flag; @@ -38,44 +40,45 @@ rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector) /** * This function will initialize hardware interrupt */ -void rt_hw_interrupt_init() +void rt_hw_interrupt_init(void) { - register rt_uint32_t idx; + register rt_uint32_t idx; - /*Make sure all intc registers in proper state*/ + /*Make sure all intc registers in proper state*/ - /*mask all the irq*/ - *(RP)(INTC_IMR) = 0xFFFFFFFF; + /*mask all the irq*/ + *(RP)(INTC_IMR) = 0xFFFFFFFF; - /*enable all the irq*/ - *(RP)(INTC_IER) = 0XFFFFFFFF; + /*enable all the irq*/ + *(RP)(INTC_IER) = 0XFFFFFFFF; - /*Dont use any forced irq*/ - *(RP)(INTC_IFR) = 0x0; + /*Dont use any forced irq*/ + *(RP)(INTC_IFR) = 0x0; - /*Disable all the fiq*/ - *(RP)(INTC_FIER) = 0x0; + /*Disable all the fiq*/ + *(RP)(INTC_FIER) = 0x0; - /*Mask all the fiq*/ - *(RP)(INTC_FIMR) = 0x0F; + /*Mask all the fiq*/ + *(RP)(INTC_FIMR) = 0x0F; - /*Dont use forced fiq*/ - *(RP)(INTC_FIFR) = 0x0; + /*Dont use forced fiq*/ + *(RP)(INTC_FIFR) = 0x0; - /*Intrrupt priority register*/ - *(RP)(INTC_IPLR) = 0x0; + /*Intrrupt priority register*/ + *(RP)(INTC_IPLR) = 0x0; - /* init exceptions table */ - for(idx=0; idx < MAX_HANDLERS; idx++) - { - isr_table[idx] = (rt_isr_handler_t)rt_hw_interrupt_handle; - } + /* init exceptions table */ + rt_memset(isr_table, 0x00, sizeof(isr_table)); + for(idx=0; idx < MAX_HANDLERS; idx++) + { + isr_table[idx].handler = rt_hw_interrupt_handle; + } - /* init interrupt nest, and context in thread sp */ - rt_interrupt_nest = 0; - rt_interrupt_from_thread = 0; - rt_interrupt_to_thread = 0; - rt_thread_switch_interrupt_flag = 0; + /* init interrupt nest, and context in thread sp */ + rt_interrupt_nest = 0; + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = 0; + rt_thread_switch_interrupt_flag = 0; } /** @@ -108,15 +111,26 @@ void rt_hw_interrupt_umask(rt_uint32_t vector) * @param new_handler the interrupt service routine to be installed * @param old_handler the old interrupt service routine */ -void rt_hw_interrupt_install(rt_uint32_t vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler) +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, char *name) { - if(vector < MAX_HANDLERS) - { - if (*old_handler != RT_NULL) - *old_handler = isr_table[vector]; - if (new_handler != RT_NULL) - isr_table[vector] = new_handler; - } + rt_isr_handler_t old_handler = RT_NULL; + + if(vector < MAX_HANDLERS) + { + old_handler = isr_table[vector].handler; + + if (handler != RT_NULL) + { +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); +#endif /* RT_USING_INTERRUPT_INFO */ + isr_table[vector].handler = handler; + isr_table[vector].param = param; + } + } + + return old_handler; } /*@}*/ diff --git a/libcpu/arm/sep4020/trap.c b/libcpu/arm/sep4020/trap.c index e7a6e369f9..33da0d9e98 100644 --- a/libcpu/arm/sep4020/trap.c +++ b/libcpu/arm/sep4020/trap.c @@ -12,6 +12,7 @@ * 2006-03-13 Bernard first version * 2006-05-27 Bernard add skyeye support * 2007-11-19 Yi.Qiu fix rt_hw_trap_irq function + * 2013-03-29 aozima Modify the interrupt interface implementations. */ #include <rtthread.h> @@ -131,31 +132,38 @@ void rt_hw_trap_resv(struct rt_hw_register *regs) rt_hw_cpu_shutdown(); } -extern rt_isr_handler_t isr_table[]; +extern struct rt_irq_desc isr_table[]; -void rt_hw_trap_irq() +void rt_hw_trap_irq(void) { - unsigned long intstat; - rt_uint32_t i = 0; - rt_isr_handler_t isr_func; + unsigned long intstat; + rt_uint32_t irq = 0; + rt_isr_handler_t isr_func; + void *param; - /*Get the final intrrupt source*/ - intstat = *(RP)(INTC_IFSR);; + /*Get the final intrrupt source*/ + intstat = *(RP)(INTC_IFSR);; - /*Shift to get the intrrupt number*/ - while(intstat != 1) - { - intstat = intstat >> 1; - i++; - } - /* get interrupt service routine */ - isr_func = isr_table[i]; + /*Shift to get the intrrupt number*/ + while(intstat != 1) + { + intstat = intstat >> 1; + irq++; + } - /* turn to interrupt service routine */ - isr_func(i); + /* get interrupt service routine */ + isr_func = isr_table[irq].isr_handle; + param = isr_table[irq].param; + + /* turn to interrupt service routine */ + isr_func(irq, param); + +#ifdef RT_USING_INTERRUPT_INFO + isr_table[irq].counter++; +#endif /* RT_USING_INTERRUPT_INFO */ } -void rt_hw_trap_fiq() +void rt_hw_trap_fiq(void) { rt_kprintf("fast interrupt request\n"); } diff --git a/libcpu/mips/jz47xx/interrupt.c b/libcpu/mips/jz47xx/interrupt.c index 7d531cbd71..0ea4827ee2 100644 --- a/libcpu/mips/jz47xx/interrupt.c +++ b/libcpu/mips/jz47xx/interrupt.c @@ -11,7 +11,7 @@ * Date Author Notes * 2010-07-09 Bernard first version */ -#include <rtthread.h> +#include <rthw.h> #include "jz47xx.h" #define JZ47XX_MAX_INTR 32 @@ -20,7 +20,7 @@ extern rt_uint32_t rt_interrupt_nest; rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_thread_switch_interrupt_flag; -static rt_isr_handler_t irq_handle_table[JZ47XX_MAX_INTR]; +static struct rt_irq_desc irq_handle_table[JZ47XX_MAX_INTR]; /** * @addtogroup Jz47xx @@ -39,9 +39,10 @@ void rt_hw_interrupt_init() { rt_int32_t index; + rt_memset(irq_handle_table, 0x00, sizeof(irq_handle_table)); for (index = 0; index < JZ47XX_MAX_INTR; index ++) { - irq_handle_table[index] = (rt_isr_handler_t)rt_hw_interrupt_handler; + irq_handle_table[index].handler = (rt_isr_handler_t)rt_hw_interrupt_handler; } /* init interrupt nest, and context in thread sp */ @@ -73,18 +74,30 @@ void rt_hw_interrupt_umask(int vector) /** * This function will install a interrupt service routine to a interrupt. * @param vector the interrupt number - * @param new_handler the interrupt service routine to be installed - * @param old_handler the old interrupt service routine + * @param handler the interrupt service routine to be installed + * @param param the interrupt service function parameter + * @param name the interrupt name + * @return old handler */ -void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler) +rt_isr_handler_t rt_hw_interrupt_install(int vector, + rt_isr_handler_t handler, + void *param, + char *name) { + rt_isr_handler_t old_handler = RT_NULL; + if (vector >= 0 && vector < JZ47XX_MAX_INTR) { - if (old_handler != RT_NULL) - *old_handler = irq_handle_table[vector]; - if (new_handler != RT_NULL) - irq_handle_table[vector] = (rt_isr_handler_t)new_handler; + old_handler = irq_handle_table[vector].handler; + +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(irq_handle_table[vector].name, name, RT_NAME_MAX); +#endif /* RT_USING_INTERRUPT_INFO */ + irq_handle_table[vector].handler = handler; + irq_handle_table[vector].param = param; } + + return old_handler; } void rt_interrupt_dispatch(void *ptreg) @@ -102,10 +115,14 @@ void rt_interrupt_dispatch(void *ptreg) if ((pending & (1<<i))) { pending &= ~(1<<i); - irq_func = irq_handle_table[i]; + irq_func = irq_handle_table[i].handler; /* do interrupt */ - (*irq_func)(i); + (*irq_func)(i, irq_handle_table[i].param); + +#ifdef RT_USING_INTERRUPT_INFO + irq_handle_table[i].counter++; +#endif /* RT_USING_INTERRUPT_INFO */ /* ack interrupt */ INTC_IPR = (1 << i); diff --git a/libcpu/mips/loongson/interrupt.c b/libcpu/mips/loongson/interrupt.c index 4b97068a70..7e59ec950d 100644 --- a/libcpu/mips/loongson/interrupt.c +++ b/libcpu/mips/loongson/interrupt.c @@ -10,8 +10,11 @@ * Change Logs: * Date Author Notes * 2010-10-15 Bernard first version + * 2013-03-29 aozima Modify the interrupt interface implementations. */ + #include <rtthread.h> +#include <rthw.h> #include "soc3210.h" #define MAX_INTR 32 @@ -20,17 +23,17 @@ extern rt_uint32_t rt_interrupt_nest; rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_thread_switch_interrupt_flag; -static rt_isr_handler_t irq_handle_table[MAX_INTR]; +static struct rt_irq_desc irq_handle_table[MAX_INTR]; void rt_interrupt_dispatch(void *ptreg); void rt_hw_timer_handler(); /** * @addtogroup Loongson SoC3210 */ - + /*@{*/ -void rt_hw_interrupt_handler(int vector) +static void rt_hw_interrupt_handler(int vector, void *param) { rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); } @@ -40,11 +43,12 @@ void rt_hw_interrupt_handler(int vector) */ void rt_hw_interrupt_init(void) { - rt_int32_t index; + rt_int32_t idx; - for (index = 0; index < MAX_INTR; index ++) + rt_memset(irq_handle_table, 0x00, sizeof(irq_handle_table)); + for (idx = 0; idx < MAX_INTR; idx ++) { - irq_handle_table[index] = (rt_isr_handler_t)rt_hw_interrupt_handler; + irq_handle_table[idx].handler = rt_hw_interrupt_handler; } /* init interrupt nest, and context in thread sp */ @@ -79,52 +83,70 @@ void rt_hw_interrupt_umask(int vector) * @param new_handler the interrupt service routine to be installed * @param old_handler the old interrupt service routine */ -void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler) +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, char *name) { - if (vector >= 0 && vector < MAX_INTR) - { - if (old_handler != RT_NULL) - *old_handler = irq_handle_table[vector]; - if (new_handler != RT_NULL) - irq_handle_table[vector] = (rt_isr_handler_t)new_handler; - } + rt_isr_handler_t old_handler = RT_NULL; + + if(vector < MAX_INTR) + { + old_handler = irq_handle_table[vector].handler; + + if (handler != RT_NULL) + { +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(irq_handle_table[vector].name, name, RT_NAME_MAX); +#endif /* RT_USING_INTERRUPT_INFO */ + irq_handle_table[vector].handler = handler; + irq_handle_table[vector].param = param; + } + } + + return old_handler; } void rt_interrupt_dispatch(void *ptreg) { - int i; - rt_isr_handler_t irq_func; - static rt_uint32_t status = 0; - rt_uint32_t c0_status; + int irq; + void *param; + rt_isr_handler_t irq_func; + static rt_uint32_t status = 0; + rt_uint32_t c0_status; - /* check os timer */ - c0_status = read_c0_status(); - if (c0_status & 0x8000) - { - rt_hw_timer_handler(); - } + /* check os timer */ + c0_status = read_c0_status(); + if (c0_status & 0x8000) + { + rt_hw_timer_handler(); + } - if (c0_status & 0x0400) - { - /* the hardware interrupt */ - status |= INT_ISR; - if (!status) return; + if (c0_status & 0x0400) + { + /* the hardware interrupt */ + status |= INT_ISR; + if (!status) return; - for (i = MAX_INTR; i > 0; --i) - { - if ((status & (1<<i))) - { - status &= ~(1<<i); - irq_func = irq_handle_table[i]; + for (irq = MAX_INTR; irq > 0; --irq) + { + if ((status & (1 << irq))) + { + status &= ~(1 << irq); - /* do interrupt */ - (*irq_func)(i); + irq_func = irq_handle_table[irq].handler; + param = irq_handle_table[irq].param; - /* ack interrupt */ - INT_CLR = (1 << i); - } - } - } + /* do interrupt */ + (*irq_func)(irq, param); + +#ifdef RT_USING_INTERRUPT_INFO + irq_handle_table[irq].counter++; +#endif /* RT_USING_INTERRUPT_INFO */ + + /* ack interrupt */ + INT_CLR = (1 << irq); + } + } + } } /*@}*/ diff --git a/libcpu/mips/loongson_1b/interrupt.c b/libcpu/mips/loongson_1b/interrupt.c index 63240053a8..c5b4bad038 100644 --- a/libcpu/mips/loongson_1b/interrupt.c +++ b/libcpu/mips/loongson_1b/interrupt.c @@ -11,9 +11,11 @@ * Date Author Notes * 2010-10-15 Bernard first version * 2010-10-15 lgnq modified for LS1B + * 2013-03-29 aozima Modify the interrupt interface implementations. */ #include <rtthread.h> +#include <rthw.h> #include "ls1b.h" #define MAX_INTR 32 @@ -23,7 +25,7 @@ rt_uint32_t rt_interrupt_from_thread; rt_uint32_t rt_interrupt_to_thread; rt_uint32_t rt_thread_switch_interrupt_flag; -static rt_isr_handler_t irq_handle_table[MAX_INTR]; +static struct rt_irq_desc irq_handle_table[MAX_INTR]; void rt_interrupt_dispatch(void *ptreg); void rt_hw_timer_handler(); @@ -36,7 +38,7 @@ static struct ls1b_intc_regs volatile *ls1b_hw0_icregs /*@{*/ -void rt_hw_interrupt_handler(int vector) +static void rt_hw_interrupt_handler(int vector, void *param) { rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); } @@ -46,7 +48,7 @@ void rt_hw_interrupt_handler(int vector) */ void rt_hw_interrupt_init(void) { - rt_int32_t index; + rt_int32_t idx; /* pci active low */ ls1b_hw0_icregs->int_pol = -1; //must be done here 20110802 lgnq @@ -55,9 +57,10 @@ void rt_hw_interrupt_init(void) /* mask all interrupts */ (ls1b_hw0_icregs+0)->int_clr = 0xffffffff; - for (index = 0; index < MAX_INTR; index ++) + rt_memset(irq_handle_table, 0x00, sizeof(irq_handle_table)); + for (idx = 0; idx < MAX_INTR; idx ++) { - irq_handle_table[index] = (rt_isr_handler_t)rt_hw_interrupt_handler; + irq_handle_table[idx].handler = rt_hw_interrupt_handler; } /* init interrupt nest, and context in thread sp */ @@ -92,20 +95,32 @@ void rt_hw_interrupt_umask(int vector) * @param new_handler the interrupt service routine to be installed * @param old_handler the old interrupt service routine */ -void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler) +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, char *name) { + rt_isr_handler_t old_handler = RT_NULL; + if (vector >= 0 && vector < MAX_INTR) { - if (old_handler != RT_NULL) - *old_handler = irq_handle_table[vector]; - if (new_handler != RT_NULL) - irq_handle_table[vector] = (rt_isr_handler_t)new_handler; - } + old_handler = irq_handle_table[vector].handler; + + if (handler != RT_NULL) + { +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(irq_handle_table[vector].name, name, RT_NAME_MAX); +#endif /* RT_USING_INTERRUPT_INFO */ + irq_handle_table[vector].handler = handler; + irq_handle_table[vector].param = param; + } + } + + return old_handler; } void rt_interrupt_dispatch(void *ptreg) { - int i; + int irq; + void *param; rt_isr_handler_t irq_func; static rt_uint32_t status = 0; rt_uint32_t c0_status; @@ -134,18 +149,24 @@ void rt_interrupt_dispatch(void *ptreg) if (!status) return; - for (i = MAX_INTR; i > 0; --i) + for (irq = MAX_INTR; irq > 0; --irq) { - if ((status & (1<<i))) + if ((status & (1 << irq))) { - status &= ~(1<<i); - irq_func = irq_handle_table[i]; + status &= ~(1 << irq); + + irq_func = irq_handle_table[irq].handler; + param = irq_handle_table[irq].param; /* do interrupt */ - (*irq_func)(i); + (*irq_func)(irq, param); + +#ifdef RT_USING_INTERRUPT_INFO + irq_handle_table[irq].counter++; +#endif /* RT_USING_INTERRUPT_INFO */ /* ack interrupt */ - ls1b_hw0_icregs->int_clr |= (1 << i); + ls1b_hw0_icregs->int_clr |= (1 << irq); } } } diff --git a/libcpu/ppc/ppc405/interrupt.c b/libcpu/ppc/ppc405/interrupt.c index d0e174612c..dc93dd67a3 100644 --- a/libcpu/ppc/ppc405/interrupt.c +++ b/libcpu/ppc/ppc405/interrupt.c @@ -12,7 +12,7 @@ * 2009-01-05 Bernard first version */ -#include <rtthread.h> +#include <rthw.h> #include <asm/ppc4xx.h> #include <asm/processor.h> @@ -21,12 +21,12 @@ extern volatile rt_uint8_t rt_interrupt_nest; /* exception and interrupt handler table */ #define MAX_HANDLERS 32 -rt_isr_handler_t isr_table[MAX_HANDLERS]; +struct rt_irq_desc isr_table[MAX_HANDLERS]; rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_thread_switch_interrput_flag; -rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector) +rt_isr_handler_t rt_hw_interrupt_handler(rt_uint32_t vector, void* param) { rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); return RT_NULL; @@ -42,9 +42,9 @@ void uic_int_handler (unsigned int vec) rt_interrupt_enter(); /* Allow external interrupts to the CPU. */ - if (isr_table [vec] != 0) + if (isr_table [vec].handler != 0) { - (*isr_table[vec])(vec); + (*isr_table[vec].handler)(vec, isr_table[vec].param); } uic_irq_ack(vec); @@ -78,21 +78,24 @@ void uic_interrupt(rt_uint32_t uic_base, int vec_base) } } -void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler) +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, + void* param, char* name) { int intVal; + rt_isr_handler_t old_handler; if (((int)vector < 0) || ((int) vector >= MAX_HANDLERS)) { - return; /* out of range */ + return RT_NULL; /* out of range */ } /* install the handler in the system interrupt table */ intVal = rt_hw_interrupt_disable (); /* lock interrupts to prevent races */ - if (*old_handler != RT_NULL) *old_handler = isr_table[vector]; - if (new_handler != RT_NULL) isr_table[vector] = new_handler; - + old_handler = isr_table[vector].handler; + isr_table[vector].handler = new_handler; + isr_table[vector].param = param; + rt_hw_interrupt_enable (intVal); } @@ -120,7 +123,8 @@ void rt_hw_interrupt_init() /* set default interrupt handler */ for (vector = 0; vector < MAX_HANDLERS; vector++) { - isr_table [vector] = (rt_isr_handler_t)rt_hw_interrupt_handle; + isr_table [vector].handler = (rt_isr_handler_t)rt_hw_interrupt_handler; + isr_table [vector].param = RT_NULL; } /* initialize interrupt nest, and context in thread sp */ diff --git a/libcpu/ppc/ppc405/serial.c b/libcpu/ppc/ppc405/serial.c index ca935fafdd..f682796f6e 100644 --- a/libcpu/ppc/ppc405/serial.c +++ b/libcpu/ppc/ppc405/serial.c @@ -220,12 +220,12 @@ void rt_serial_set_baudrate(struct rt_ppc405_serial* device) out_8((rt_uint8_t *)device->hw_base + UART_DLM, bdiv >> 8); /* set baudrate divisor */ } -void rt_serial_isr(int irqno) +void rt_serial_isr(int irqno, void* param) { unsigned char status; struct rt_ppc405_serial *device; - device = (struct rt_ppc405_serial*) &ppc405_serial; + device = (struct rt_ppc405_serial*) param; status = in_8((rt_uint8_t *)device->hw_base + UART_LSR); if (status & 0x01) @@ -289,7 +289,7 @@ void rt_hw_serial_init(void) device->hw_base = UART0_BASE; device->baudrate = 115200; device->irqno = VECNUM_U0; - rt_hw_interrupt_install(device->irqno, rt_serial_isr, RT_NULL); /* install isr */ + rt_hw_interrupt_install(device->irqno, rt_serial_isr, device, "serial"); /* install isr */ rt_memset(device->rx_buffer, 0, sizeof(device->rx_buffer)); device->read_index = device->save_index = 0; |
