aboutsummaryrefslogtreecommitdiff
path: root/arch/arc/kernel
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2013-02-11 19:52:57 +0530
committerVineet Gupta <vgupta@synopsys.com>2013-02-15 23:15:58 +0530
commit080c37473eb671a037b3e9a315303851f0675be5 (patch)
treeb407d85217f9c979eed57f2adb31bc3fb06a9c09 /arch/arc/kernel
parent8872e9e513eba636c8d4266fe667660f73cd66e6 (diff)
downloadvexpress-lsk-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.c3
-rw-r--r--arch/arc/kernel/ctx_sw.c7
-rw-r--r--arch/arc/kernel/entry.S14
3 files changed, 24 insertions, 0 deletions
diff --git a/arch/arc/kernel/asm-offsets.c b/arch/arc/kernel/asm-offsets.c
index d7770cc9aee..0dc148ebce7 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 647e37a5165..fbf739cbaf7 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 ce8670da830..69d0d376e28 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