summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/entry-armv.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/entry-armv.S')
-rw-r--r--arch/arm/kernel/entry-armv.S152
1 files changed, 109 insertions, 43 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index c8c737404..e659b966d 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -84,7 +84,7 @@
strb r12, [r12, #0x38] @ Disable FIQ register
.endm
- .macro get_irqnr_and_base, irqnr, irqstat, base
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov r4, #ioc_base_high @ point at IOC
.if ioc_base_low
orr r4, r4, #ioc_base_low
@@ -165,36 +165,23 @@ irq_prio_h: .byte 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
.macro disable_fiq
.endm
- .macro get_irqnr_and_base, irqnr, irqstat, base
- mov r4, #0xf3000000
- ldrb \irqstat, [r4] @ get interrupts
- adr \base, irq_prio_ebsa110
-
- teq \irqstat, #0
- ldrneb \irqnr, [\base, \irqstat] @ get IRQ number
+ .macro get_irqnr_and_base, irqnr, stat, base, tmp
+ mov \base, #IRQ_STAT
+ ldrb \stat, [\base] @ get interrupts
+ mov \irqnr, #0
+ tst \stat, #15
+ addeq \irqnr, \irqnr, #4
+ moveq \stat, \stat, lsr #4
+ tst \stat, #3
+ addeq \irqnr, \irqnr, #2
+ moveq \stat, \stat, lsr #2
+ tst \stat, #1
+ addeq \irqnr, \irqnr, #1
+ moveq \stat, \stat, lsr #1
+ tst \stat, #1 @ bit 0 should be set
.endm
.macro irq_prio_table
-irq_prio_ebsa110:
- .byte 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
- .byte 4, 4, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
- .byte 5, 5, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
- .byte 5, 5, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
-
- .byte 6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
- .byte 6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
- .byte 6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
- .byte 6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
-
- .byte 7, 0, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
- .byte 4, 4, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
- .byte 5, 5, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
- .byte 5, 5, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
-
- .byte 6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
- .byte 6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
- .byte 6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
- .byte 6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
.endm
#elif defined(CONFIG_ARCH_SHARK)
@@ -202,7 +189,7 @@ irq_prio_ebsa110:
.macro disable_fiq
.endm
- .macro get_irqnr_and_base, irqnr, irqstat, base
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov r4, #0xe0000000
orr r4, r4, #0x20
@@ -238,7 +225,7 @@ irq_prio_ebsa110:
.equ dc21285_high, ARMCSR_BASE & 0xff000000
.equ dc21285_low, ARMCSR_BASE & 0x00ffffff
- .macro get_irqnr_and_base, irqnr, irqstat, base
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov r4, #dc21285_high
.if dc21285_low
orr r4, r4, #dc21285_low
@@ -334,7 +321,7 @@ irq_prio_ebsa110:
.macro disable_fiq
.endm
- .macro get_irqnr_and_base, irqnr, irqstat, base
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \irqstat, =INTCONT_BASE
ldr \base, =soft_irq_mask
ldr \irqstat, [\irqstat] @ get interrupts
@@ -362,7 +349,7 @@ ENTRY(soft_irq_mask)
.macro disable_fiq
.endm
- .macro get_irqnr_and_base, irqnr, irqstat, base
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \irqstat, =0xffff7000
ldr \irqstat, [\irqstat] @ get interrupts
ldr \base, =soft_irq_mask
@@ -390,7 +377,7 @@ ENTRY(soft_irq_mask)
.macro disable_fiq
.endm
- .macro get_irqnr_and_base, irqnr, irqstat, base
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov r4, #0xfa000000 @ ICIP = 0xfa050000
add r4, r4, #0x00050000
ldr \irqstat, [r4] @ get irqs
@@ -428,7 +415,7 @@ ENTRY(soft_irq_mask)
.macro disable_fiq
.endm
- .macro get_irqnr_and_base, irqnr, irqstat, base
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov \irqstat, #irq_base_addr @ Virt addr IRQ regs
add \irqstat, \irqstat, #0x00001000 @ Status reg
ldr \irqstat, [\irqstat, #0] @ get interrupts
@@ -449,7 +436,7 @@ ENTRY(soft_irq_mask)
.macro disable_fiq
.endm
- .macro get_irqnr_and_base, irqnr, irqstat, base
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
/* FIXME: should not be using soo many LDRs here */
ldr \irqnr, =IO_ADDRESS(INTEGRATOR_IC_BASE)
ldr \irqstat, [\irqnr, #IRQ_STATUS] @ get masked status
@@ -470,6 +457,50 @@ ENTRY(soft_irq_mask)
.macro irq_prio_table
.endm
+#elif defined(CONFIG_ARCH_P720T)
+
+ .macro disable_fiq
+ .endm
+
+#if (INTSR2 - INTSR1) != (INTMR2 - INTMR1)
+#error INTSR stride != INTMR stride
+#endif
+
+ .macro get_irqnr_and_base, irqnr, stat, base, mask
+ mov \base, #CLPS7111_BASE
+ ldr \stat, [\base, #INTSR1]
+ ldr \mask, [\base, #INTMR1]
+ mov \irqnr, #4
+ mov \mask, \mask, lsl #16
+ and \stat, \stat, \mask, lsr #16
+ movs \stat, \stat, lsr #4
+ bne 1001f
+
+ add \base, \base, #INTSR2 - INTSR1
+ ldr \stat, [\base, #INTSR1]
+ ldr \mask, [\base, #INTMR1]
+ mov \irqnr, #16
+ mov \mask, \mask, lsl #16
+ and \stat, \stat, \mask, lsr #16
+
+1001: tst \stat, #255
+ addeq \irqnr, \irqnr, #8
+ moveq \stat, \stat, lsr #8
+ tst \stat, #15
+ addeq \irqnr, \irqnr, #4
+ moveq \stat, \stat, lsr #4
+ tst \stat, #3
+ addeq \irqnr, \irqnr, #2
+ moveq \stat, \stat, lsr #2
+ tst \stat, #1
+ addeq \irqnr, \irqnr, #1
+ moveq \stat, \stat, lsr #1
+ tst \stat, #1 @ bit 0 should be set
+ .endm
+
+ .macro irq_prio_table
+ .endm
+
#else
#error Unknown architecture
#endif
@@ -594,7 +625,7 @@ fpe_not_present:
adr r10, wfs_mask_data
ldmia r10, {r4, r5, r6, r7, r8}
ldr r10, [sp, #S_PC] @ Load PC
- sub r10, r10, #-4
+ sub r10, r10, #4
mask_pc r10, r10
ldrt r10, [r10] @ get instruction
and r5, r10, r5
@@ -660,7 +691,7 @@ __irq_svc: sub sp, sp, #S_FRAME_SIZE
add r4, sp, #S_SP
mov r6, lr
stmia r4, {r5, r6, r7, r8, r9} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
-1: get_irqnr_and_base r0, r6, r5
+1: get_irqnr_and_base r0, r6, r5, lr
movne r1, sp
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@@ -695,6 +726,28 @@ __und_svc: sub sp, sp, #S_FRAME_SIZE
ldmia sp, {r0 - pc}^ @ Restore SVC registers
.align 5
+__pabt_svc: sub sp, sp, #S_FRAME_SIZE
+ stmia sp, {r0 - r12} @ save r0 - r12
+ ldr r2, .LCabt
+ add r0, sp, #S_FRAME_SIZE
+ ldmia r2, {r2 - r4} @ get pc, cpsr
+ add r5, sp, #S_SP
+ mov r1, lr
+ stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
+ mrs r9, cpsr @ Enable interrupts if they were
+ tst r3, #I_BIT
+ biceq r9, r9, #I_BIT @ previously
+ msr cpsr_c, r9
+ mov r0, r2 @ address (pc)
+ mov r1, sp @ regs
+ bl SYMBOL_NAME(do_PrefetchAbort) @ call abort handler
+ mov r0, #I_BIT | MODE_SVC
+ msr cpsr_c, r0
+ ldr r0, [sp, #S_PSR]
+ msr spsr, r0
+ ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
+
+ .align 5
.LCirq: .word __temp_irq
.LCund: .word __temp_und
.LCabt: .word __temp_abt
@@ -744,7 +797,7 @@ __irq_usr: sub sp, sp, #S_FRAME_SIZE
stmdb r8, {sp, lr}^
alignment_trap r4, r7, __temp_irq
zero_fp
-1: get_irqnr_and_base r0, r6, r5
+1: get_irqnr_and_base r0, r6, r5, lr
movne r1, sp
adrsvc ne, lr, 1b
@
@@ -762,7 +815,7 @@ __und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
add r8, sp, #S_PC
ldmia r4, {r5 - r7}
stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0
- stmdb r8, {sp, lr}^ @ Save user r0 - r12
+ stmdb r8, {sp, lr}^ @ Save user sp, lr
alignment_trap r4, r7, __temp_und
zero_fp
adrsvc al, r9, ret_from_sys_call @ r9 = normal FP return
@@ -960,12 +1013,25 @@ vector_prefetch:
msr spsr_c, r13 @ switch to SVC_32 mode
ands lr, lr, #15
- ldreq lr, .LCtab_pabt
- ldrne lr, .LCtab_pabt + 4
+ ldr lr, [pc, lr, lsl #2]
movs pc, lr
-.LCtab_pabt: .word __pabt_usr
- .word __pabt_invalid
+.LCtab_pabt: .word __pabt_usr @ 0 (USR_26 / USR_32)
+ .word __pabt_invalid @ 1 (FIQ_26 / FIQ_32)
+ .word __pabt_invalid @ 2 (IRQ_26 / IRQ_32)
+ .word __pabt_svc @ 3 (SVC_26 / SVC_32)
+ .word __pabt_invalid @ 4
+ .word __pabt_invalid @ 5
+ .word __pabt_invalid @ 6
+ .word __pabt_invalid @ 7
+ .word __pabt_invalid @ 8
+ .word __pabt_invalid @ 9
+ .word __pabt_invalid @ a
+ .word __pabt_invalid @ b
+ .word __pabt_invalid @ c
+ .word __pabt_invalid @ d
+ .word __pabt_invalid @ e
+ .word __pabt_invalid @ f
.align 5