diff options
Diffstat (limited to 'arch/arm/kernel/entry-armv.S')
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 152 |
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 |