Commit f80dff9d authored by Dan Williams's avatar Dan Williams Committed by Russell King

[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: default avatarDan Williams <dan.j.williams@intel.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 588ef769
...@@ -27,6 +27,7 @@ ...@@ -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
@ @
......
...@@ -9,6 +9,7 @@ ...@@ -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: ...@@ -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: ...@@ -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
......
...@@ -15,6 +15,12 @@ ...@@ -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
......
...@@ -16,6 +16,12 @@ ...@@ -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)
......
#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
...@@ -13,6 +13,12 @@ ...@@ -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
......
...@@ -15,6 +15,12 @@ ...@@ -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
......
...@@ -14,6 +14,12 @@ ...@@ -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
......
...@@ -14,6 +14,12 @@ ...@@ -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
......
...@@ -11,6 +11,12 @@ ...@@ -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
......
...@@ -11,6 +11,13 @@ ...@@ -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)
......
...@@ -13,6 +13,12 @@ ...@@ -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)
......
...@@ -19,21 +19,27 @@ ...@@ -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) .macro arch_ret_to_user, tmp1, tmp2
mcreq p15, 0, \tmp, c15, c1, 0 @ Disable cp6 access if no more interrupts 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
...@@ -12,10 +12,25 @@ ...@@ -12,10 +12,25 @@
.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
mrc p15, 0, \tmp, c15, c1, 0
mov \tmp, \tmp
sub pc, pc, #4 @ cp_wait
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \base, =IOP3XX_REG_ADDR(0x07D8) mrc p6, 0, \irqstat, c8, c0, 0 @ Read IINTSRC
ldr \irqstat, [\base] @ Read IINTSRC
cmp \irqstat, #0 cmp \irqstat, #0
clzne \irqnr, \irqstat clzne \irqnr, \irqstat
rsbne \irqnr, \irqnr, #31 rsbne \irqnr, \irqnr, #31
.endm .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
...@@ -12,11 +12,26 @@ ...@@ -12,11 +12,26 @@
.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
mrc p15, 0, \tmp, c15, c1, 0
mov \tmp, \tmp
sub pc, pc, #4 @ cp_wait
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \base, =IOP3XX_REG_ADDR(0x07C8) mrc p6, 0, \irqstat, c14, c0, 0 @ Read IINTVEC
ldr \irqstat, [\base] @ Read IINTVEC
cmp \irqstat, #0 cmp \irqstat, #0
ldreq \irqstat, [\base] @ erratum 63 workaround mrceq p6, 0, \irqstat, c14, c0, 0 @ erratum 63 workaround
adds \irqnr, \irqstat, #1 adds \irqnr, \irqstat, #1
movne \irqnr, \irqstat, lsr #2 movne \irqnr, \irqstat, lsr #2
.endm .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
...@@ -12,6 +12,12 @@ ...@@ -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
......
...@@ -5,6 +5,12 @@ ...@@ -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
......
...@@ -12,6 +12,12 @@ ...@@ -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
......
...@@ -14,6 +14,12 @@ ...@@ -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
......
...@@ -26,6 +26,12 @@ ...@@ -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
......
...@@ -23,6 +23,12 @@ ...@@ -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
......
...@@ -29,6 +29,12 @@ ...@@ -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]
......
...@@ -28,6 +28,12 @@ ...@@ -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)
......
...@@ -13,6 +13,12 @@ ...@@ -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
......
...@@ -13,6 +13,12 @@ ...@@ -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:
......
#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
...@@ -22,6 +22,12 @@ ...@@ -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
......
...@@ -11,6 +11,12 @@ ...@@ -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
......
...@@ -10,6 +10,12 @@ ...@@ -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
......
...@@ -13,6 +13,12 @@ ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment