X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=arch%2Farm%2Fkernel%2Fentry-armv.S;h=5639f1b618f9a80d7a8a9dccaff6c8ea2e1068fb;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=7fe5c2d39efdf5c97e80e48dbfe5d853d8f401e7;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 7fe5c2d39..5639f1b61 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -562,40 +562,6 @@ ENTRY(soft_irq_mask) .macro irq_prio_table .endm -#elif defined(CONFIG_ARCH_IOP310) - - .macro disable_fiq - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - mrc p13, 0, \irqstat, c4, c0, 0 @ get INTSRC - mrc p13, 0, \base, c0, c0, 0 @ get INTCTL - - tst \irqstat, #(1<<29) @ if INTSRC_BI - tstne \base, #(1<<3) @ and INTCTL_BM - movne \irqnr, #IRQ_XS80200_BCU - bne 1001f - - tst \irqstat, #(1<<28) @ if INTSRC_PI - tstne \base, #(1<<2) @ and INTCTL_PM - movne \irqnr, #IRQ_XS80200_PMU - bne 1001f - - tst \irqstat, #(1<<31) @ if INTSRC_FI - tstne \base, #(1<<0) @ and INTCTL_FM - movne \irqnr, #IRQ_XS80200_EXTFIQ - bne 1001f - - tst \irqstat, #(1<<30) @ if INTSRC_II - tstne \base, #(1<<1) @ and INTCTL_IM - movne \irqnr, #IRQ_XS80200_EXTIRQ - -1001: - .endm - - .macro irq_prio_table - .endm - #elif defined(CONFIG_ARCH_IOP321) .macro disable_fiq .endm @@ -618,6 +584,39 @@ ENTRY(soft_irq_mask) .macro irq_prio_table .endm +#elif defined(CONFIG_ARCH_IOP331) + .macro disable_fiq + .endm + + /* + * Note: only deal with normal interrupts, not FIQ + */ + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + mov \irqnr, #0 + mrc p6, 0, \irqstat, c4, c0, 0 @ Read IINTSRC0 + cmp \irqstat, #0 + bne 1002f + mrc p6, 0, \irqstat, c5, c0, 0 @ Read IINTSRC1 + cmp \irqstat, #0 + beq 1001f + clz \irqnr, \irqstat +/* + * mov \base, #31 + * subs \irqnr,\base,\irqnr + */ + rsbs \irqnr,\irqnr,#31 @ recommend by RMK + add \irqnr,\irqnr,#IRQ_IOP331_XINT8 + b 1001f +1002: clz \irqnr, \irqstat + mov \base, #31 + subs \irqnr,\base,\irqnr + add \irqnr,\irqnr,#IRQ_IOP331_DMA0_EOT +1001: + .endm + + .macro irq_prio_table + .endm + #elif defined(CONFIG_ARCH_PXA) .macro disable_fiq @@ -645,6 +644,60 @@ ENTRY(soft_irq_mask) .macro irq_prio_table .endm +#elif defined(CONFIG_ARCH_IXP2000) + + .macro disable_fiq + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + mov \irqnr, #0x0 @clear out irqnr as default + mov \base, #0xfe000000 + orr \base, \base, #0x00ff0000 + orr \base, \base, #0x0000a000 + orr \base, \base, #0x08 + ldr \irqstat, [\base] @ get interrupts + mov \tmp, #IXP2000_VALID_IRQ_MASK & 0xff000000 + orr \tmp, \tmp, #IXP2000_VALID_IRQ_MASK & 0x00ff0000 + orr \tmp, \tmp, #IXP2000_VALID_IRQ_MASK & 0x0000ff00 + orr \tmp, \tmp, #IXP2000_VALID_IRQ_MASK & 0x000000ff + and \irqstat, \irqstat, \tmp + + cmp \irqstat, #0 + beq 1001f + + clz \irqnr, \irqstat + mov \base, #31 + subs \irqnr, \base, \irqnr + + /* + * We handle PCIA and PCIB here so we don't have an + * extra layer of code just to check these two bits. + */ + cmp \irqnr, #IRQ_IXP2000_PCI + bne 1001f + + mov \base, #0xfe000000 + orr \base, \base, #0x00fd0000 + orr \base, \base, #0x0000e100 + orr \base, \base, #0x00000058 + ldr \irqstat, [\base] + + mov \tmp, #(1<<26) + tst \irqstat, \tmp + movne \irqnr, #IRQ_IXP2000_PCIA + bne 1001f + + mov \tmp, #(1<<27) + tst \irqstat, \tmp + movne \irqnr, #IRQ_IXP2000_PCIB + +1001: + .endm + + .macro irq_prio_table + .endm + #elif defined (CONFIG_ARCH_IXP4XX) .macro disable_fiq @@ -884,6 +937,82 @@ ENTRY(soft_irq_mask) .macro irq_prio_table .endm +#elif defined(CONFIG_ARCH_IMX) + + .macro disable_fiq + .endm +#define AITC_NIVECSR 0x40 + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \irqstat, =IO_ADDRESS(IMX_AITC_BASE) + @ Load offset & priority of the highest priority + @ interrupt pending. + ldr \irqnr, [\irqstat, #AITC_NIVECSR] + @ Shift off the priority leaving the offset or + @ "interrupt number" + mov \irqnr, \irqnr, lsr #16 + ldr \irqstat, =1 @ dummy compare + ldr \base, =0xFFFF // invalid interrupt + cmp \irqnr, \base + bne 1001f + ldr \irqstat, =0 +1001: + tst \irqstat, #1 @ to make the condition code = TRUE + .endm + + .macro irq_prio_table + .endm + +#elif defined(CONFIG_ARCH_H720X) + + .macro disable_fiq + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp +#if defined (CONFIG_CPU_H7201) || defined (CONFIG_CPU_H7202) + @ we could use the id register on H7202, but this is not + @ properly updated when we come back from asm_do_irq + @ without a previous return from interrupt + @ (see loops below in irq_svc, irq_usr) + @ We see unmasked pending ints only, as the masked pending ints + @ are not visible here + + mov \base, #0xf0000000 @ base register + orr \base, \base, #0x24000 @ irqbase + ldr \irqstat, [\base, #0x04] @ get interrupt status +#if defined (CONFIG_CPU_H7201) + ldr \tmp, =0x001fffff +#else + mvn \tmp, #0xc0000000 +#endif + and \irqstat, \irqstat, \tmp @ mask out unused ints + mov \irqnr, #0 + + mov \tmp, #0xff00 + orr \tmp, \tmp, #0xff + tst \irqstat, \tmp + addeq \irqnr, \irqnr, #16 + moveq \irqstat, \irqstat, lsr #16 + tst \irqstat, #255 + addeq \irqnr, \irqnr, #8 + moveq \irqstat, \irqstat, lsr #8 + tst \irqstat, #15 + addeq \irqnr, \irqnr, #4 + moveq \irqstat, \irqstat, lsr #4 + tst \irqstat, #3 + addeq \irqnr, \irqnr, #2 + moveq \irqstat, \irqstat, lsr #2 + tst \irqstat, #1 + addeq \irqnr, \irqnr, #1 + moveq \irqstat, \irqstat, lsr #1 + tst \irqstat, #1 @ bit 0 should be set + .endm + + .macro irq_prio_table + .endm + +#else +#error hynix processor selection missmatch +#endif #else #error Unknown architecture #endif @@ -1174,7 +1303,7 @@ __und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go * r0 - instruction opcode. * r10 - this threads thread_info structure. */ -call_fpe: enable_irq r10 @ Enable interrupts +call_fpe: tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 #if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) and r8, r0, #0x0f000000 @ mask out op-code bits @@ -1186,6 +1315,14 @@ call_fpe: enable_irq r10 @ Enable interrupts mov r7, #1 add r6, r10, #TI_USED_CP strb r7, [r6, r8, lsr #8] @ set appropriate used_cp[] +#ifdef CONFIG_IWMMXT + @ Test if we need to give access to iWMMXt coprocessors + ldr r5, [r10, #TI_FLAGS] + rsbs r7, r8, #(1 << 8) @ CP 0 or 1 only + movcss r7, r5, lsr #(TIF_USING_IWMMXT + 1) + bcs iwmmxt_task_enable +#endif + enable_irq r7 add pc, pc, r8, lsr #6 mov r0, r0 @@ -1264,7 +1401,11 @@ ENTRY(ret_from_exception) ENTRY(__switch_to) add ip, r1, #TI_CPU_SAVE ldr r3, [r2, #TI_CPU_DOMAIN]! - stmia ip, {r4 - sl, fp, sp, lr} @ Store most regs on stack + stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack +#if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT) + mra r4, r5, acc0 + stmia ip, {r4, r5} +#endif mcr p15, 0, r3, c3, c0, 0 @ Set domain register #ifdef CONFIG_VFP @ Always disable VFP so we can lazily save/restore the old @@ -1272,6 +1413,13 @@ ENTRY(__switch_to) VFPFMRX r4, FPEXC bic r4, r4, #FPEXC_ENABLE VFPFMXR FPEXC, r4 +#endif +#if defined(CONFIG_IWMMXT) + bl iwmmxt_task_switch +#elif defined(CONFIG_CPU_XSCALE) + add r4, r2, #40 @ cpu_context_save->extra + ldmib r4, {r4, r5} + mar acc0, r4, r5 #endif ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously