X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Farm%2Fkernel%2Fentry-armv.S;h=8517c3c3eb3393c8ba539add942342757c117f2b;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=ec48d70c6d8b92d83db16b0f3ce9360944021c54;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index ec48d70c6..8517c3c3e 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -14,12 +14,12 @@ * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes * it to save wrong values... Be aware! */ -#include #include #include #include #include +#include #include "entry-header.S" @@ -191,6 +191,9 @@ __dabt_svc: __irq_svc: svc_entry +#ifdef CONFIG_TRACE_IRQFLAGS + bl trace_hardirqs_off +#endif #ifdef CONFIG_PREEMPT get_thread_info tsk ldr r8, [tsk, #TI_PREEMPT] @ get preempt count @@ -211,6 +214,10 @@ preempt_return: #endif ldr r0, [sp, #S_PSR] @ irqs are already disabled msr spsr_cxsf, r0 +#ifdef CONFIG_TRACE_IRQFLAGS + tst r0, #PSR_I_BIT + bleq trace_hardirqs_on +#endif ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr .ltorg @@ -398,6 +405,9 @@ __dabt_usr: __irq_usr: usr_entry +#ifdef CONFIG_TRACE_IRQFLAGS + bl trace_hardirqs_off +#endif get_thread_info tsk #ifdef CONFIG_PREEMPT ldr r8, [tsk, #TI_PREEMPT] @ get preempt count @@ -412,6 +422,9 @@ __irq_usr: teq r0, r7 strne r0, [r0, -r0] #endif +#ifdef CONFIG_TRACE_IRQFLAGS + bl trace_hardirqs_on +#endif mov why, #0 b ret_to_user @@ -423,7 +436,7 @@ __und_usr: usr_entry tst r3, #PSR_T_BIT @ Thumb mode? - bne fpundefinstr @ ignore FP + bne __und_usr_unknown @ ignore FP sub r4, r2, #4 @ @@ -435,7 +448,7 @@ __und_usr: @ 1: ldrt r0, [r4] adr r9, ret_from_exception - adr lr, fpundefinstr + adr lr, __und_usr_unknown @ @ fallthrough to call_fpe @ @@ -463,7 +476,9 @@ __und_usr: * Emulators may wish to make use of the following registers: * r0 = instruction opcode. * r2 = PC+4 + * r9 = normal "successful" return address * r10 = this threads thread_info structure. + * lr = unrecognised instruction return address */ call_fpe: tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 @@ -484,7 +499,6 @@ call_fpe: movcss r7, r5, lsr #(TIF_USING_IWMMXT + 1) bcs iwmmxt_task_enable #endif - enable_irq add pc, pc, r8, lsr #6 mov r0, r0 @@ -492,9 +506,15 @@ call_fpe: b do_fpe @ CP#1 (FPE) b do_fpe @ CP#2 (FPE) mov pc, lr @ CP#3 +#ifdef CONFIG_CRUNCH + b crunch_task_enable @ CP#4 (MaverickCrunch) + b crunch_task_enable @ CP#5 (MaverickCrunch) + b crunch_task_enable @ CP#6 (MaverickCrunch) +#else mov pc, lr @ CP#4 mov pc, lr @ CP#5 mov pc, lr @ CP#6 +#endif mov pc, lr @ CP#7 mov pc, lr @ CP#8 mov pc, lr @ CP#9 @@ -511,6 +531,7 @@ call_fpe: mov pc, lr @ CP#15 (Control) do_fpe: + enable_irq ldr r4, .LCfp add r10, r10, #TI_FPSTATE @ r10 = workspace ldr pc, [r4] @ Call FP module USR entry point @@ -526,10 +547,12 @@ do_fpe: .data ENTRY(fp_enter) - .word fpundefinstr + .word no_fp .text -fpundefinstr: +no_fp: mov pc, lr + +__und_usr_unknown: mov r0, sp adr lr, ret_from_exception b do_undefinstr @@ -560,10 +583,8 @@ ENTRY(__switch_to) add ip, r1, #TI_CPU_SAVE ldr r3, [r2, #TI_TP_VALUE] stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack -#ifndef CONFIG_MMU - add r2, r2, #TI_CPU_DOMAIN -#else - ldr r6, [r2, #TI_CPU_DOMAIN]! +#ifdef CONFIG_MMU + ldr r6, [r2, #TI_CPU_DOMAIN] #endif #if __LINUX_ARM_ARCH__ >= 6 #ifdef CONFIG_CPU_32v6K @@ -572,10 +593,6 @@ ENTRY(__switch_to) strex r5, r4, [ip] @ Clear exclusive monitor #endif #endif -#if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT) - mra r4, r5, acc0 - stmia ip, {r4, r5} -#endif #if defined(CONFIG_HAS_TLS_REG) mcr p15, 0, r3, c13, c0, 3 @ set TLS register #elif !defined(CONFIG_TLS_REG_EMUL) @@ -585,21 +602,13 @@ ENTRY(__switch_to) #ifdef CONFIG_MMU mcr p15, 0, r6, c3, c0, 0 @ Set domain register #endif -#ifdef CONFIG_VFP - @ Always disable VFP so we can lazily save/restore the old - @ state. This occurs in the context of the previous thread. - 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 + mov r5, r0 + add r4, r2, #TI_CPU_SAVE + ldr r0, =thread_notify_head + mov r1, #THREAD_NOTIFY_SWITCH + bl atomic_notifier_call_chain + mov r0, r5 + ldmia r4, {r4 - sl, fp, sp, pc} @ Load all regs saved previously __INIT @@ -633,6 +642,14 @@ ENTRY(__switch_to) * purpose. */ + .macro usr_ret, reg +#ifdef CONFIG_ARM_THUMB + bx \reg +#else + mov pc, \reg +#endif + .endm + .align 5 .globl __kuser_helper_start __kuser_helper_start: @@ -666,7 +683,7 @@ __kuser_helper_start: * * #define __kernel_dmb() \ * asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \ - * : : : "lr","cc" ) + * : : : "r0", "lr","cc" ) */ __kuser_memory_barrier: @ 0xffff0fa0 @@ -674,7 +691,7 @@ __kuser_memory_barrier: @ 0xffff0fa0 #if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_SMP) mcr p15, 0, r0, c7, c10, 5 @ dmb #endif - mov pc, lr + usr_ret lr .align 5 @@ -777,7 +794,7 @@ __kuser_cmpxchg: @ 0xffff0fc0 mov r0, #-1 adds r0, r0, #0 #endif - mov pc, lr + usr_ret lr #else @@ -791,7 +808,7 @@ __kuser_cmpxchg: @ 0xffff0fc0 #ifdef CONFIG_SMP mcr p15, 0, r0, c7, c10, 5 @ dmb #endif - mov pc, lr + usr_ret lr #endif @@ -833,16 +850,11 @@ __kuser_cmpxchg: @ 0xffff0fc0 __kuser_get_tls: @ 0xffff0fe0 #if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL) - ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0 - mov pc, lr - #else - mrc p15, 0, r0, c13, c0, 3 @ read TLS register - mov pc, lr - #endif + usr_ret lr .rep 5 .word 0 @ pad up to __kuser_helper_version