diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-02-11 19:52:57 +0530 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-02-15 23:15:58 +0530 |
commit | 080c37473eb671a037b3e9a315303851f0675be5 (patch) | |
tree | b407d85217f9c979eed57f2adb31bc3fb06a9c09 /arch/arc/kernel | |
parent | 8872e9e513eba636c8d4266fe667660f73cd66e6 (diff) | |
download | op-kernel-dev-080c37473eb671a037b3e9a315303851f0675be5.zip op-kernel-dev-080c37473eb671a037b3e9a315303851f0675be5.tar.gz |
ARC: [optim] Cache "current" in Register r25
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc/kernel')
-rw-r--r-- | arch/arc/kernel/asm-offsets.c | 3 | ||||
-rw-r--r-- | arch/arc/kernel/ctx_sw.c | 7 | ||||
-rw-r--r-- | arch/arc/kernel/entry.S | 14 |
3 files changed, 24 insertions, 0 deletions
diff --git a/arch/arc/kernel/asm-offsets.c b/arch/arc/kernel/asm-offsets.c index d7770cc..0dc148e 100644 --- a/arch/arc/kernel/asm-offsets.c +++ b/arch/arc/kernel/asm-offsets.c @@ -24,6 +24,9 @@ int main(void) DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); DEFINE(THREAD_CALLEE_REG, offsetof(struct thread_struct, callee_reg)); +#ifdef CONFIG_ARC_CURR_IN_REG + DEFINE(THREAD_USER_R25, offsetof(struct thread_struct, user_r25)); +#endif DEFINE(THREAD_FAULT_ADDR, offsetof(struct thread_struct, fault_address)); diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c index 647e37a..fbf739c 100644 --- a/arch/arc/kernel/ctx_sw.c +++ b/arch/arc/kernel/ctx_sw.c @@ -24,6 +24,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task) unsigned int prev = (unsigned int)prev_task; unsigned int next = (unsigned int)next_task; int num_words_to_skip = 1; +#ifdef CONFIG_ARC_CURR_IN_REG + num_words_to_skip++; +#endif __asm__ __volatile__( /* FP/BLINK save generated by gcc (standard function prologue */ @@ -39,7 +42,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task) "st.a r22, [sp, -4] \n\t" "st.a r23, [sp, -4] \n\t" "st.a r24, [sp, -4] \n\t" +#ifndef CONFIG_ARC_CURR_IN_REG "st.a r25, [sp, -4] \n\t" +#endif "sub sp, sp, %4 \n\t" /* create gutter at top */ /* set ksp of outgoing task in tsk->thread.ksp */ @@ -62,7 +67,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task) "add sp, sp, %4 \n\t" /* skip gutter at top */ +#ifndef CONFIG_ARC_CURR_IN_REG "ld.ab r25, [sp, 4] \n\t" +#endif "ld.ab r24, [sp, 4] \n\t" "ld.ab r23, [sp, 4] \n\t" "ld.ab r22, [sp, 4] \n\t" diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S index ce8670d..69d0d37 100644 --- a/arch/arc/kernel/entry.S +++ b/arch/arc/kernel/entry.S @@ -32,6 +32,9 @@ * was being "CLEARED" rather then "SET". Since it is Loop INHIBIT Bit, * setting it and not clearing it clears ZOL context * + * Vineetg: May 16th, 2008 + * - r25 now contains the Current Task when in kernel + * * Vineetg: Dec 22, 2007 * Minor Surgery of Low Level ISR to make it SMP safe * - MMU_SCRATCH0 Reg used for freeing up r9 in Level 1 ISR @@ -535,6 +538,17 @@ restore_regs : ; XXX can this be optimised out IRQ_DISABLE_SAVE r9, r10 ;@r10 has prisitine (pre-disable) copy +#ifdef CONFIG_ARC_CURR_IN_REG + ; Restore User R25 + ; Earlier this used to be only for returning to user mode + ; However with 2 levels of IRQ this can also happen even if + ; in kernel mode + ld r9, [sp, PT_sp] + brhs r9, VMALLOC_START, 8f + RESTORE_USER_R25 +8: +#endif + ; Restore REG File. In case multiple Events outstanding, ; use the same priorty as rtie: EXCPN, L2 IRQ, L1 IRQ, None ; Note that we use realtime STATUS32 (not pt_regs->status32) to |