[ARM] 4185/2: entry: introduce get_irqnr_preamble and arch_ret_to_user

get_irqnr_preamble allows machines to take some action before entering the
get_irqnr_and_base loop.  On iop we enable cp6 access.

arch_ret_to_user is added to the userspace return path to allow individual
architectures to take actions, like disabling coprocessor access, before
the final return to userspace.

Per Nicolas Pitre's note, there is no need to cp_wait on the return to user
as the latency to return is sufficient.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
Dan Williams 2007-02-16 22:16:32 +01:00 committed by Russell King
parent 588ef76935
commit f80dff9da0
30 changed files with 219 additions and 26 deletions

View File

@ -27,6 +27,7 @@
* Interrupt handling. Preserves r7, r8, r9 * Interrupt handling. Preserves r7, r8, r9
*/ */
.macro irq_handler .macro irq_handler
get_irqnr_preamble r5, lr
1: get_irqnr_and_base r0, r6, r5, lr 1: get_irqnr_and_base r0, r6, r5, lr
movne r1, sp movne r1, sp
@ @

View File

@ -9,6 +9,7 @@
*/ */
#include <asm/unistd.h> #include <asm/unistd.h>
#include <asm/arch/entry-macro.S>
#include "entry-header.S" #include "entry-header.S"
@ -25,6 +26,9 @@ ret_fast_syscall:
tst r1, #_TIF_WORK_MASK tst r1, #_TIF_WORK_MASK
bne fast_work_pending bne fast_work_pending
/* perform architecture specific actions before user return */
arch_ret_to_user r1, lr
@ fast_restore_user_regs @ fast_restore_user_regs
ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr
ldr lr, [sp, #S_OFF + S_PC]! @ get pc ldr lr, [sp, #S_OFF + S_PC]! @ get pc
@ -61,6 +65,9 @@ ret_slow_syscall:
tst r1, #_TIF_WORK_MASK tst r1, #_TIF_WORK_MASK
bne work_pending bne work_pending
no_work_pending: no_work_pending:
/* perform architecture specific actions before user return */
arch_ret_to_user r1, lr
@ slow_restore_user_regs @ slow_restore_user_regs
ldr r1, [sp, #S_PSR] @ get calling cpsr ldr r1, [sp, #S_PSR] @ get calling cpsr
ldr lr, [sp, #S_PC]! @ get pc ldr lr, [sp, #S_PC]! @ get pc

View File

@ -15,6 +15,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov r4, #0xf8000000 mov r4, #0xf8000000
add r4, r4, #0x00000500 add r4, r4, #0x00000500

View File

@ -16,6 +16,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \base, =(AT91_VA_BASE_SYS) @ base virtual address of SYS peripherals ldr \base, =(AT91_VA_BASE_SYS) @ base virtual address of SYS peripherals
ldr \irqnr, [\base, #AT91_AIC_IVR] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt) ldr \irqnr, [\base, #AT91_AIC_IVR] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt)

View File

@ -1,3 +1,8 @@
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/hardware/entry-macro-iomd.S> #include <asm/hardware/entry-macro-iomd.S>
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm

View File

@ -13,6 +13,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
#if (INTSR2 - INTSR1) != (INTMR2 - INTMR1) #if (INTSR2 - INTSR1) != (INTMR2 - INTMR1)
#error INTSR stride != INTMR stride #error INTSR stride != INTMR stride
#endif #endif

View File

@ -15,6 +15,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, stat, base, tmp .macro get_irqnr_and_base, irqnr, stat, base, tmp
mov \base, #IRQ_STAT mov \base, #IRQ_STAT
ldrb \stat, [\base] @ get interrupts ldrb \stat, [\base] @ get interrupts

View File

@ -14,6 +14,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.equ dc21285_high, ARMCSR_BASE & 0xff000000 .equ dc21285_high, ARMCSR_BASE & 0xff000000
.equ dc21285_low, ARMCSR_BASE & 0x00ffffff .equ dc21285_low, ARMCSR_BASE & 0x00ffffff

View File

@ -14,6 +14,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \base, =(EP93XX_AHB_VIRT_BASE) ldr \base, =(EP93XX_AHB_VIRT_BASE)
orr \base, \base, #0x000b0000 orr \base, \base, #0x000b0000

View File

@ -11,6 +11,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
#if defined (CONFIG_CPU_H7201) || defined (CONFIG_CPU_H7202) #if defined (CONFIG_CPU_H7201) || defined (CONFIG_CPU_H7202)
@ we could use the id register on H7202, but this is not @ we could use the id register on H7202, but this is not

View File

@ -11,6 +11,13 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
#define AITC_NIVECSR 0x40 #define AITC_NIVECSR 0x40
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \irqstat, =IO_ADDRESS(IMX_AITC_BASE) ldr \irqstat, =IO_ADDRESS(IMX_AITC_BASE)

View File

@ -13,6 +13,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
/* FIXME: should not be using soo many LDRs here */ /* FIXME: should not be using soo many LDRs here */
ldr \base, =IO_ADDRESS(INTEGRATOR_IC_BASE) ldr \base, =IO_ADDRESS(INTEGRATOR_IC_BASE)

View File

@ -19,21 +19,27 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
mrc p15, 0, \tmp, c15, c1, 0
orr \tmp, \tmp, #(1 << 6)
mcr p15, 0, \tmp, c15, c1, 0 @ Enable cp6 access
.endm
/* /*
* Note: a 1-cycle window exists where iintvec will return the value * Note: a 1-cycle window exists where iintvec will return the value
* of iintbase, so we explicitly check for "bad zeros" * of iintbase, so we explicitly check for "bad zeros"
*/ */
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mrc p15, 0, \tmp, c15, c1, 0
orr \tmp, \tmp, #(1 << 6)
mcr p15, 0, \tmp, c15, c1, 0 @ Enable cp6 access
mrc p6, 0, \irqnr, c3, c2, 0 @ Read IINTVEC mrc p6, 0, \irqnr, c3, c2, 0 @ Read IINTVEC
cmp \irqnr, #0 cmp \irqnr, #0
mrceq p6, 0, \irqnr, c3, c2, 0 @ Re-read on potentially bad zero mrceq p6, 0, \irqnr, c3, c2, 0 @ Re-read on potentially bad zero
adds \irqstat, \irqnr, #1 @ Check for 0xffffffff adds \irqstat, \irqnr, #1 @ Check for 0xffffffff
movne \irqnr, \irqnr, lsr #2 @ Convert to irqnr movne \irqnr, \irqnr, lsr #2 @ Convert to irqnr
.endm
biceq \tmp, \tmp, #(1 << 6)
mcreq p15, 0, \tmp, c15, c1, 0 @ Disable cp6 access if no more interrupts .macro arch_ret_to_user, tmp1, tmp2
mrc p15, 0, \tmp1, c15, c1, 0
ands \tmp2, \tmp1, #(1 << 6)
bicne \tmp1, \tmp1, #(1 << 6)
mcrne p15, 0, \tmp1, c15, c1, 0 @ Disable cp6 access
.endm .endm

View File

@ -9,13 +9,28 @@
*/ */
#include <asm/arch/iop32x.h> #include <asm/arch/iop32x.h>
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_preamble, base, tmp
ldr \base, =IOP3XX_REG_ADDR(0x07D8) mrc p15, 0, \tmp, c15, c1, 0
ldr \irqstat, [\base] @ Read IINTSRC orr \tmp, \tmp, #(1 << 6)
cmp \irqstat, #0 mcr p15, 0, \tmp, c15, c1, 0 @ Enable cp6 access
clzne \irqnr, \irqstat mrc p15, 0, \tmp, c15, c1, 0
rsbne \irqnr, \irqnr, #31 mov \tmp, \tmp
.endm sub pc, pc, #4 @ cp_wait
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mrc p6, 0, \irqstat, c8, c0, 0 @ Read IINTSRC
cmp \irqstat, #0
clzne \irqnr, \irqstat
rsbne \irqnr, \irqnr, #31
.endm
.macro arch_ret_to_user, tmp1, tmp2
mrc p15, 0, \tmp1, c15, c1, 0
ands \tmp2, \tmp1, #(1 << 6)
bicne \tmp1, \tmp1, #(1 << 6)
mcrne p15, 0, \tmp1, c15, c1, 0 @ Disable cp6 access
.endm

View File

@ -9,14 +9,29 @@
*/ */
#include <asm/arch/iop33x.h> #include <asm/arch/iop33x.h>
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_preamble, base, tmp
ldr \base, =IOP3XX_REG_ADDR(0x07C8) mrc p15, 0, \tmp, c15, c1, 0
ldr \irqstat, [\base] @ Read IINTVEC orr \tmp, \tmp, #(1 << 6)
cmp \irqstat, #0 mcr p15, 0, \tmp, c15, c1, 0 @ Enable cp6 access
ldreq \irqstat, [\base] @ erratum 63 workaround mrc p15, 0, \tmp, c15, c1, 0
adds \irqnr, \irqstat, #1 mov \tmp, \tmp
movne \irqnr, \irqstat, lsr #2 sub pc, pc, #4 @ cp_wait
.endm .endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mrc p6, 0, \irqstat, c14, c0, 0 @ Read IINTVEC
cmp \irqstat, #0
mrceq p6, 0, \irqstat, c14, c0, 0 @ erratum 63 workaround
adds \irqnr, \irqstat, #1
movne \irqnr, \irqstat, lsr #2
.endm
.macro arch_ret_to_user, tmp1, tmp2
mrc p15, 0, \tmp1, c15, c1, 0
ands \tmp2, \tmp1, #(1 << 6)
bicne \tmp1, \tmp1, #(1 << 6)
mcrne p15, 0, \tmp1, c15, c1, 0 @ Disable cp6 access
.endm

View File

@ -12,6 +12,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov \irqnr, #0x0 @clear out irqnr as default mov \irqnr, #0x0 @clear out irqnr as default

View File

@ -5,6 +5,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \irqnr, =(IXP23XX_INTC_VIRT + IXP23XX_INTR_IRQ_ENC_ST_OFFSET) ldr \irqnr, =(IXP23XX_INTC_VIRT + IXP23XX_INTR_IRQ_ENC_ST_OFFSET)
ldr \irqnr, [\irqnr] @ get interrupt number ldr \irqnr, [\irqnr] @ get interrupt number

View File

@ -12,6 +12,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP_OFFSET) ldr \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP_OFFSET)
ldr \irqstat, [\irqstat] @ get interrupts ldr \irqstat, [\irqstat] @ get interrupts

View File

@ -14,6 +14,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov \irqstat, #irq_base_addr @ Virt addr IRQ regs mov \irqstat, #irq_base_addr @ Virt addr IRQ regs
add \irqstat, \irqstat, #0x00001000 @ Status reg add \irqstat, \irqstat, #0x00001000 @ Status reg

View File

@ -26,6 +26,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
branch_irq_lh7a400: b 1000f branch_irq_lh7a400: b 1000f

View File

@ -23,6 +23,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov \base, #io_p2v(0x00100000) mov \base, #io_p2v(0x00100000)
add \base, \base, #0x000ff000 add \base, \base, #0x000ff000

View File

@ -29,6 +29,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \base, =IO_ADDRESS(OMAP_IH1_BASE) ldr \base, =IO_ADDRESS(OMAP_IH1_BASE)
ldr \irqnr, [\base, #IRQ_ITR_REG_OFFSET] ldr \irqnr, [\base, #IRQ_ITR_REG_OFFSET]

View File

@ -28,6 +28,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
/* decode the MIC interrupt numbers */ /* decode the MIC interrupt numbers */
ldr \base, =IO_ADDRESS(PNX4008_INTCTRLMIC_BASE) ldr \base, =IO_ADDRESS(PNX4008_INTCTRLMIC_BASE)

View File

@ -13,6 +13,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
#ifdef CONFIG_PXA27x #ifdef CONFIG_PXA27x
mrc p6, 0, \irqstat, c0, c0, 0 @ ICIP mrc p6, 0, \irqstat, c0, c0, 0 @ ICIP

View File

@ -13,6 +13,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
/* /*
* The interrupt numbering scheme is defined in the * The interrupt numbering scheme is defined in the
* interrupt controller spec. To wit: * interrupt controller spec. To wit:

View File

@ -1,3 +1,8 @@
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/hardware/entry-macro-iomd.S> #include <asm/hardware/entry-macro-iomd.S>
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm

View File

@ -22,6 +22,12 @@
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/irq.h> #include <asm/irq.h>
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov \base, #S3C24XX_VA_IRQ mov \base, #S3C24XX_VA_IRQ

View File

@ -11,6 +11,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov r4, #0xfa000000 @ ICIP = 0xfa050000 mov r4, #0xfa000000 @ ICIP = 0xfa050000
add r4, r4, #0x00050000 add r4, r4, #0x00050000

View File

@ -10,6 +10,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov r4, #0xe0000000 mov r4, #0xe0000000

View File

@ -13,6 +13,12 @@
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \base, =IO_ADDRESS(VERSATILE_VIC_BASE) ldr \base, =IO_ADDRESS(VERSATILE_VIC_BASE)
ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status