From a81abd35141cf579aba00288cf0a6028e12f6338 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 24 Jul 2013 07:47:51 -0600 Subject: [PATCH] Improve Cortex-A5 context switching so that a little less copying is done --- arch/arm/Kconfig | 1 + arch/arm/src/armv7-a/arm_allocpage.c | 12 ++-- arch/arm/src/armv7-a/arm_checkmapping.c | 8 +-- arch/arm/src/armv7-a/arm_copyarmstate.c | 2 - arch/arm/src/armv7-a/arm_dataabort.c | 9 +-- arch/arm/src/armv7-a/arm_doirq.c | 7 ++- arch/arm/src/armv7-a/arm_prefetchabort.c | 7 ++- arch/arm/src/armv7-a/arm_syscall.c | 13 ++--- arch/arm/src/armv7-a/arm_undefinedinsn.c | 3 +- arch/arm/src/armv7-a/arm_va2pte.c | 4 +- arch/arm/src/armv7-a/arm_vectors.S | 73 +++++++++++++++++------- arch/arm/src/armv7-m/up_copyarmstate.c | 3 +- arch/arm/src/common/up_internal.h | 67 +++++++++++++++++++++- arch/arm/src/sama5/sam_irq.c | 15 +++-- 14 files changed, 166 insertions(+), 58 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c38f9cc04f..4c723f8542 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -113,6 +113,7 @@ config ARCH_CHIP_SAMA5 bool "Atmel AT91SAMA5" select ARCH_CORTEXA5 select ARCH_HAVE_FPU + select ARCH_HAVE_LOWVECTORS ---help--- Atmel AT91SAMA5 (ARM Cortex-A5) diff --git a/arch/arm/src/armv7-a/arm_allocpage.c b/arch/arm/src/armv7-a/arm_allocpage.c index 3856dc531b..cb8710b475 100644 --- a/arch/arm/src/armv7-a/arm_allocpage.c +++ b/arch/arm/src/armv7-a/arm_allocpage.c @@ -117,7 +117,7 @@ static bool g_pgwrap; ****************************************************************************/ /**************************************************************************** - * Name: up_allocpage() + * Name: arm_allocpage() * * Description: * This architecture-specific function will set aside page in memory and map @@ -136,9 +136,9 @@ static bool g_pgwrap; * NOTE 2: If an in-use page is un-mapped, it may be necessary to flush the * instruction cache in some architectures. * - * NOTE 3: Allocating and filling a page is a two step process. up_allocpage() + * NOTE 3: Allocating and filling a page is a two step process. arm_allocpage() * allocates the page, and up_fillpage() fills it with data from some non- - * volatile storage device. This distinction is made because up_allocpage() + * volatile storage device. This distinction is made because arm_allocpage() * can probably be implemented in board-independent logic whereas up_fillpage() * probably must be implemented as board-specific logic. * @@ -165,7 +165,7 @@ static bool g_pgwrap; * ****************************************************************************/ -int up_allocpage(FAR struct tcb_s *tcb, FAR void **vpage) +int arm_allocpage(FAR struct tcb_s *tcb, FAR void **vpage) { uintptr_t vaddr; uintptr_t paddr; @@ -203,7 +203,7 @@ int up_allocpage(FAR struct tcb_s *tcb, FAR void **vpage) */ uintptr_t oldvaddr = PG_POOL_NDX2VA(g_ptemap[pgndx]); - pte = up_va2pte(oldvaddr); + pte = arm_va2pte(oldvaddr); *pte = 0; /* Invalidate the instruction TLB corresponding to the virtual address */ @@ -227,7 +227,7 @@ int up_allocpage(FAR struct tcb_s *tcb, FAR void **vpage) * non-cached (MMU_L2_ALLOCFLAGS) */ - pte = up_va2pte(vaddr); + pte = arm_va2pte(vaddr); *pte = (paddr | MMU_L2_ALLOCFLAGS); /* And save the new L1 index */ diff --git a/arch/arm/src/armv7-a/arm_checkmapping.c b/arch/arm/src/armv7-a/arm_checkmapping.c index 50f05cf7ed..4f20d22053 100644 --- a/arch/arm/src/armv7-a/arm_checkmapping.c +++ b/arch/arm/src/armv7-a/arm_checkmapping.c @@ -68,10 +68,10 @@ ****************************************************************************/ /**************************************************************************** - * Name: up_checkmapping() + * Name: arm_checkmapping() * * Description: - * The function up_checkmapping() returns an indication if the page fill + * The function arm_checkmapping() returns an indication if the page fill * still needs to performed or not. In certain conditions, the page fault * may occur on several threads and be queued multiple times. This function * will prevent the same page from be filled multiple times. @@ -97,7 +97,7 @@ * ****************************************************************************/ -bool up_checkmapping(FAR struct tcb_s *tcb) +bool arm_checkmapping(FAR struct tcb_s *tcb) { uintptr_t vaddr; uint32_t *pte; @@ -113,7 +113,7 @@ bool up_checkmapping(FAR struct tcb_s *tcb) /* Get the PTE associated with this virtual address */ - pte = up_va2pte(vaddr); + pte = arm_va2pte(vaddr); /* Return true if this virtual address is mapped. */ diff --git a/arch/arm/src/armv7-a/arm_copyarmstate.c b/arch/arm/src/armv7-a/arm_copyarmstate.c index 5feebfee9e..5de72aef91 100644 --- a/arch/arm/src/armv7-a/arm_copyarmstate.c +++ b/arch/arm/src/armv7-a/arm_copyarmstate.c @@ -71,8 +71,6 @@ * ****************************************************************************/ -/* A little faster than most memcpy's */ - void up_copyarmstate(uint32_t *dest, uint32_t *src) { int i; diff --git a/arch/arm/src/armv7-a/arm_dataabort.c b/arch/arm/src/armv7-a/arm_dataabort.c index 25df4f8f2e..06ff0ba353 100644 --- a/arch/arm/src/armv7-a/arm_dataabort.c +++ b/arch/arm/src/armv7-a/arm_dataabort.c @@ -101,7 +101,7 @@ #ifdef CONFIG_PAGING -void arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) +uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) { DFAR struct tcb_s *tcb = (DFAR struct tcb_s *)g_readytorun.head; uint32_t *savestate; @@ -110,7 +110,6 @@ void arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) * for register dumps and possibly context switching. */ - savestate = (uint32_t*)current_regs; current_regs = regs; @@ -172,17 +171,18 @@ void arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) */ current_regs = savestate; - return; + return regs; segfault: lldbg("Data abort. PC: %08x DFAR: %08x DFSR: %08x\n", regs[REG_PC], dfar, dfsr); PANIC(); + return regs; /* To keep the compiler happy */ } #else /* CONFIG_PAGING */ -void arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) +uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) { /* Save the saved processor context in current_regs where it can be accessed * for register dumps and possibly context switching. @@ -195,6 +195,7 @@ void arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) lldbg("Data abort. PC: %08x DFAR: %08x DFSR: %08x\n", regs[REG_PC], dfar, dfsr); PANIC(); + return regs; /* To keep the compiler happy */ } #endif /* CONFIG_PAGING */ diff --git a/arch/arm/src/armv7-a/arm_doirq.c b/arch/arm/src/armv7-a/arm_doirq.c index d7ec6fc91f..154c52c1d4 100644 --- a/arch/arm/src/armv7-a/arm_doirq.c +++ b/arch/arm/src/armv7-a/arm_doirq.c @@ -70,7 +70,7 @@ * Public Functions ****************************************************************************/ -void up_doirq(int irq, uint32_t *regs) +uint32_t *arm_doirq(int irq, uint32_t *regs) { up_ledon(LED_INIRQ); #ifdef CONFIG_SUPPRESS_INTERRUPTS @@ -100,22 +100,27 @@ void up_doirq(int irq, uint32_t *regs) * point state before returning from the interrupt. */ +#ifdef CONFIG_ARCH_FPU if (regs != current_regs) { /* Restore floating point registers */ up_restorefpu((uint32_t*)current_regs); } +#endif /* Set current_regs to NULL to indicate that we are no longer in an * interrupt handler. */ + regs = current_regs; current_regs = NULL; /* Unmask the last interrupt (global interrupts are still disabled) */ up_enable_irq(irq); #endif + up_ledoff(LED_INIRQ); + return regs; } diff --git a/arch/arm/src/armv7-a/arm_prefetchabort.c b/arch/arm/src/armv7-a/arm_prefetchabort.c index 3f5c55c70e..89a6bf904f 100644 --- a/arch/arm/src/armv7-a/arm_prefetchabort.c +++ b/arch/arm/src/armv7-a/arm_prefetchabort.c @@ -89,7 +89,7 @@ #ifdef CONFIG_PAGING -void arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) +uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) { uint32_t *savestate; @@ -150,11 +150,13 @@ void arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) regs[REG_PC], ifar, ifsr); PANIC(); } + + return regs; } #else /* CONFIG_PAGING */ -void arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) +uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) { /* Save the saved processor context in current_regs where it can be accessed * for register dumps and possibly context switching. @@ -167,6 +169,7 @@ void arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) lldbg("Prefetch abort. PC: %08x IFAR: %08x IFSR: %08x\n", regs[REG_PC], ifar, ifsr); PANIC(); + return regs; /* To keep the compiler happy */ } #endif /* CONFIG_PAGING */ diff --git a/arch/arm/src/armv7-a/arm_syscall.c b/arch/arm/src/armv7-a/arm_syscall.c index c3e6b2174a..bfeddc8313 100644 --- a/arch/arm/src/armv7-a/arm_syscall.c +++ b/arch/arm/src/armv7-a/arm_syscall.c @@ -76,19 +76,18 @@ ****************************************************************************/ /**************************************************************************** - * Name: up_syscall + * Name: arm_syscall * * Description: - * SWI interrupts will vection here with insn=the SWI - * instruction and xcp=the interrupt context + * SWI interrupts will vection here with insn=the SWI instruction and + * xcp=the interrupt context * - * The handler may get the SWI number be de-referencing - * the return address saved in the xcp and decoding - * the SWI instruction + * The handler may get the SWI number be de-referencing the return + * address saved in the xcp and decoding the SWI instruction * ****************************************************************************/ -void up_syscall(uint32_t *regs) +uint32_t *arm_syscall(uint32_t *regs) { lldbg("Syscall from 0x%x\n", regs[REG_PC]); current_regs = regs; diff --git a/arch/arm/src/armv7-a/arm_undefinedinsn.c b/arch/arm/src/armv7-a/arm_undefinedinsn.c index 4c63b467f6..af240cf56e 100644 --- a/arch/arm/src/armv7-a/arm_undefinedinsn.c +++ b/arch/arm/src/armv7-a/arm_undefinedinsn.c @@ -73,9 +73,10 @@ * Name: arm_undefinedinsn ****************************************************************************/ -void arm_undefinedinsn(uint32_t *regs) +uint32_t *arm_undefinedinsn(uint32_t *regs) { lldbg("Undefined instruction at 0x%x\n", regs[REG_PC]); current_regs = regs; PANIC(); + return regs; /* To keep the compiler happy */ } diff --git a/arch/arm/src/armv7-a/arm_va2pte.c b/arch/arm/src/armv7-a/arm_va2pte.c index 1d3aec414d..6b3decbca0 100644 --- a/arch/arm/src/armv7-a/arm_va2pte.c +++ b/arch/arm/src/armv7-a/arm_va2pte.c @@ -69,7 +69,7 @@ ****************************************************************************/ /**************************************************************************** - * Name: up_va2pte + * Name: arm_va2pte * * Description: * Convert a virtual address within the paged text region into a pointer to @@ -89,7 +89,7 @@ * ****************************************************************************/ -uint32_t *up_va2pte(uintptr_t vaddr) +uint32_t *arm_va2pte(uintptr_t vaddr) { uint32_t L1; uint32_t *L2; diff --git a/arch/arm/src/armv7-a/arm_vectors.S b/arch/arm/src/armv7-a/arm_vectors.S index 74bffde6e2..e8fe5dcede 100644 --- a/arch/arm/src/armv7-a/arm_vectors.S +++ b/arch/arm/src/armv7-a/arm_vectors.S @@ -136,20 +136,27 @@ arm_vectorirq: str r0, [sp] /* Save the user stack pointer */ mov r4, sp /* Save the SP in a preserved register */ bic sp, sp, #7 /* Force 8-byte alignement */ - bl up_decodeirq /* Call the handler */ + bl arm_decodeirq /* Call the handler */ ldr sp, [r4] /* Restore the user stack pointer */ #else mov r4, sp /* Save the SP in a preserved register */ bic sp, sp, #7 /* Force 8-byte alignement */ - bl up_decodeirq /* Call the handler */ + bl arm_decodeirq /* Call the handler */ mov sp, r4 /* Restore the possibly unaligned stack pointer */ #endif - /* Restore the CPSR, SVC modr registers and return */ + /* Upon return from arm_decodeirq, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_decodeirq: It will differ if a + * context switch is required. + */ + + /* Restore the CPSR, SVC mode registers and return */ + .Lnoirqset: - ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ - msr spsr, r0 - ldmia sp, {r0-r15}^ /* Return */ + ldr r1, [r0, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ + msr spsr, r1 + ldmia r0, {r0-r15}^ /* Return */ .Lirqtmp: .word g_irqtmp @@ -162,7 +169,7 @@ arm_vectorirq: /************************************************************************************ * Function: arm_vectorswi - * + * * Description: * SWI interrupt. We enter the SWI in SVC mode. * @@ -192,21 +199,27 @@ arm_vectorswi: stmia r0, {r1-r4} /* Then call the SWI handler with interrupts disabled. - * void up_syscall(struct xcptcontext *xcp) + * void arm_syscall(struct xcptcontext *xcp) */ mov fp, #0 /* Init frame pointer */ mov r0, sp /* Get r0=xcp */ mov r4, sp /* Save the SP in a preserved register */ bic sp, sp, #7 /* Force 8-byte alignement */ - bl up_syscall /* Call the handler */ + bl arm_syscall /* Call the handler */ mov sp, r4 /* Restore the possibly unaligned stack pointer */ + /* Upon return from arm_syscall, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_syscall: It will differ if a + * context switch is required. + */ + /* Restore the CPSR, SVC modr registers and return */ - ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ - msr spsr, r0 - ldmia sp, {r0-r15}^ /* Return */ + ldr r1, [r0, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ + msr spsr, r1 + ldmia r0, {r0-r15}^ /* Return */ .size arm_vectorswi, . - arm_vectorswi .align 5 @@ -275,11 +288,17 @@ arm_vectordata: bl arm_dataabort /* Call the handler */ mov sp, r4 /* Restore the possibly unaligned stack pointer */ + /* Upon return from arm_dataabort, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_dataabort: It will differ if a + * context switch is required. + */ + /* Restore the CPSR, SVC modr registers and return */ - ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ - msr spsr_cxsf, r0 - ldmia sp, {r0-r15}^ /* Return */ + ldr r1, [r0, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ + msr spsr_cxsf, r1 + ldmia r0, {r1-r15}^ /* Return */ .Ldaborttmp: .word g_aborttmp @@ -351,11 +370,17 @@ arm_vectorprefetch: bl arm_prefetchabort /* Call the handler */ mov sp, r4 /* Restore the possibly unaligned stack pointer */ + /* Upon return from arm_prefetchabort, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_prefetchabort: It will differ if a + * context switch is required. + */ + /* Restore the CPSR, SVC modr registers and return */ - ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ - msr spsr_cxsf, r0 - ldmia sp, {r0-r15}^ /* Return */ + ldr r1, [r0, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ + msr spsr_cxsf, r1 + ldmia r0, {r0-r15}^ /* Return */ .Lpaborttmp: .word g_aborttmp @@ -422,11 +447,17 @@ arm_vectorundefinsn: bl arm_undefinedinsn /* Call the handler */ mov sp, r4 /* Restore the possibly unaligned stack pointer */ + /* Upon return from arm_undefinedinsn, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_undefinedinsn: It will differ if a + * context switch is required. + */ + /* Restore the CPSR, SVC modr registers and return */ - ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ - msr spsr_cxsf, r0 - ldmia sp, {r0-r15}^ /* Return */ + ldr r1, [r0, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ + msr spsr_cxsf, r1 + ldmia r0, {r0-r15}^ /* Return */ .Lundeftmp: .word g_undeftmp diff --git a/arch/arm/src/armv7-m/up_copyarmstate.c b/arch/arm/src/armv7-m/up_copyarmstate.c index 32c7fce06f..b705be5ea2 100644 --- a/arch/arm/src/armv7-m/up_copyarmstate.c +++ b/arch/arm/src/armv7-m/up_copyarmstate.c @@ -99,7 +99,8 @@ void up_copyarmstate(uint32_t *dest, uint32_t *src) /* Skip over the floating point registers and save the block of ARM * registers that were saved by the hardware when the interrupt was - * taken. Indices: (SW_INT_REGS+SW_FPU_REGS) through (HW_XCPT_REGS-1) + * taken. Indices: (SW_INT_REGS+SW_FPU_REGS) through + * (XCPTCONTEXT_REGS-1) */ src += SW_FPU_REGS; diff --git a/arch/arm/src/common/up_internal.h b/arch/arm/src/common/up_internal.h index 495b51b24f..25887770d2 100644 --- a/arch/arm/src/common/up_internal.h +++ b/arch/arm/src/common/up_internal.h @@ -134,8 +134,25 @@ # endif # define up_restorestate(regs) (current_regs = regs) -/* Otherwise, for the ARM7, ARM9, and Cortex-A5. The state is copied in full - * from stack to stack. This is not very efficient. +/* The Cortex-A5 supports the same mechanism, but only lazy floating point + * register save/restore. + */ + +#elif defined(CONFIG_ARCH_CORTEXA5) + + /* If the floating point unit is present and enabled, then save the + * floating point registers as well as normal ARM registers. + */ + +# if defined(CONFIG_ARCH_FPU) +# define up_savestate(regs) up_copyarmstate(regs, (uint32_t*)current_regs) +# else +# define up_savestate(regs) up_copyfullstate(regs, (uint32_t*)current_regs) +# endif +# define up_restorestate(regs) (current_regs = regs) + +/* Otherwise, for the ARM7 and ARM9. The state is copied in full from stack + * to stack. This is not very efficient and should be fixed to match Cortex-A5. */ #else @@ -289,10 +306,17 @@ void up_systemreset(void) noreturn_function; void up_irqinitialize(void); void up_maskack_irq(int irq); +/* Exception handling logic unique to the Cortex-M family */ + #if defined(CONFIG_ARCH_CORTEXM0) || defined(CONFIG_ARCH_CORTEXM3) || \ defined(CONFIG_ARCH_CORTEXM4) +/* Interrupt dispatch */ + uint32_t *up_doirq(int irq, uint32_t *regs); + +/* Exception Handlers */ + int up_svcall(int irq, FAR void *context); int up_hardfault(int irq, FAR void *context); @@ -301,9 +325,43 @@ int up_hardfault(int irq, FAR void *context); int up_memfault(int irq, FAR void *context); # endif /* CONFIG_ARCH_CORTEXM3 || CONFIG_ARCH_CORTEXM4 */ -#else /* CONFIG_ARCH_CORTEXM0 || CONFIG_ARCH_CORTEXM3 || CONFIG_ARCH_CORTEXM4 */ + +/* Exception handling logic unique to the Cortex-A family (but should be + * back-ported to the ARM7 and ARM9 families). + */ + +#elif defined(CONFIG_ARCH_CORTEXA5) + +/* Interrupt dispatch */ + +uint32_t *arm_doirq(int irq, uint32_t *regs); + +/* Paging support */ + +#ifdef CONFIG_PAGING +void arm_pginitialize(void); +uint32_t *arm_va2pte(uintptr_t vaddr); +#else /* CONFIG_PAGING */ +# define up_pginitialize() +#endif /* CONFIG_PAGING */ + +/* Exception Handlers */ + +uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr); +uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr); +uint32_t *arm_syscall(uint32_t *regs); +uint32_t *arm_undefinedinsn(uint32_t *regs); + +/* Exception handling logic common to other ARM7 and ARM9 family. */ + +#else /* ARM7 | ARM9 */ + +/* Interrupt dispatch */ void up_doirq(int irq, uint32_t *regs); + +/* Paging support (and exception handlers) */ + #ifdef CONFIG_PAGING void up_pginitialize(void); uint32_t *up_va2pte(uintptr_t vaddr); @@ -312,6 +370,9 @@ void up_dataabort(uint32_t *regs, uint32_t far, uint32_t fsr); # define up_pginitialize() void up_dataabort(uint32_t *regs); #endif /* CONFIG_PAGING */ + +/* Exception handlers */ + void up_prefetchabort(uint32_t *regs); void up_syscall(uint32_t *regs); void up_undefinedinsn(uint32_t *regs); diff --git a/arch/arm/src/sama5/sam_irq.c b/arch/arm/src/sama5/sam_irq.c index 615f0c5cce..2f20b169df 100644 --- a/arch/arm/src/sama5/sam_irq.c +++ b/arch/arm/src/sama5/sam_irq.c @@ -283,6 +283,7 @@ void up_irqinitialize(void) putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, SAM_AIC_WPMR); +#ifndef CONFIG_ARCH_LOWVECTORS /* Set remap state 0: * * Boot state: ROM is seen at address 0x00000000 @@ -290,10 +291,15 @@ void up_irqinitialize(void) * interface) instead of ROM. * Remap State 1: HEBI is seen at address 0x00000000 (through AHB slave * interface) instead of ROM for external boot. + * + * Here we are assuming that vectors reside in the lower end of ISRAM. + * Hmmm... this probably does not matter since we will map a page to + * address 0x0000:0000 in that case anyway. */ putreg32(MATRIX_MRCR_RCB0, SAM_MATRIX_MRCR); /* Enable remap */ putreg32(AXIMX_REMAP_REMAP0, SAM_AXIMX_REMAP); /* Remap SRAM */ +#endif /* currents_regs is non-NULL only while processing an interrupt */ @@ -315,13 +321,13 @@ void up_irqinitialize(void) } /**************************************************************************** - * Name: up_decodeirq + * Name: arm_decodeirq * * Description: * This function is called from the IRQ vector handler in arm_vectors.S. * At this point, the interrupt has been taken and the registers have * been saved on the stack. This function simply needs to determine the - * the irq number of the interrupt and then to call up_doirq to dispatch + * the irq number of the interrupt and then to call arm_doirq to dispatch * the interrupt. * * Input paramters: @@ -329,7 +335,7 @@ void up_irqinitialize(void) * ****************************************************************************/ -void up_decodeirq(uint32_t *regs) +uint32_t *arm_decodeirq(uint32_t *regs) { uint32_t regval; @@ -376,11 +382,12 @@ void up_decodeirq(uint32_t *regs) /* Dispatch the interrupt */ - up_doirq((int)regval, regs); + regs = arm_doirq((int)regval, regs); /* Acknowledge interrupt */ putreg32(AIC_EOICR_ENDIT, SAM_AIC_EOICR); + return regs; } /****************************************************************************