diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-01-18 04:42:18 -0500 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-02-11 09:30:38 -0500 |
commit | bf90e1eab682dcb79b7765989fb65835ce9d6165 (patch) | |
tree | cb1bb4364862d878e1d361d371f8392d08f606d7 /arch/arc/kernel/ctx_sw.c | |
parent | 4adeefe161a74369e44cc8e663f240ece0470dc3 (diff) |
ARC: Process-creation/scheduling/idle-loop
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/arc/kernel/ctx_sw.c')
-rw-r--r-- | arch/arc/kernel/ctx_sw.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c new file mode 100644 index 000000000000..647e37a5165e --- /dev/null +++ b/arch/arc/kernel/ctx_sw.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * Vineetg: Aug 2009 | ||
9 | * -"C" version of lowest level context switch asm macro called by schedular | ||
10 | * gcc doesn't generate the dward CFI info for hand written asm, hence can't | ||
11 | * backtrace out of it (e.g. tasks sleeping in kernel). | ||
12 | * So we cheat a bit by writing almost similar code in inline-asm. | ||
13 | * -This is a hacky way of doing things, but there is no other simple way. | ||
14 | * I don't want/intend to extend unwinding code to understand raw asm | ||
15 | */ | ||
16 | |||
17 | #include <asm/asm-offsets.h> | ||
18 | #include <linux/sched.h> | ||
19 | |||
20 | struct task_struct *__sched | ||
21 | __switch_to(struct task_struct *prev_task, struct task_struct *next_task) | ||
22 | { | ||
23 | unsigned int tmp; | ||
24 | unsigned int prev = (unsigned int)prev_task; | ||
25 | unsigned int next = (unsigned int)next_task; | ||
26 | int num_words_to_skip = 1; | ||
27 | |||
28 | __asm__ __volatile__( | ||
29 | /* FP/BLINK save generated by gcc (standard function prologue */ | ||
30 | "st.a r13, [sp, -4] \n\t" | ||
31 | "st.a r14, [sp, -4] \n\t" | ||
32 | "st.a r15, [sp, -4] \n\t" | ||
33 | "st.a r16, [sp, -4] \n\t" | ||
34 | "st.a r17, [sp, -4] \n\t" | ||
35 | "st.a r18, [sp, -4] \n\t" | ||
36 | "st.a r19, [sp, -4] \n\t" | ||
37 | "st.a r20, [sp, -4] \n\t" | ||
38 | "st.a r21, [sp, -4] \n\t" | ||
39 | "st.a r22, [sp, -4] \n\t" | ||
40 | "st.a r23, [sp, -4] \n\t" | ||
41 | "st.a r24, [sp, -4] \n\t" | ||
42 | "st.a r25, [sp, -4] \n\t" | ||
43 | "sub sp, sp, %4 \n\t" /* create gutter at top */ | ||
44 | |||
45 | /* set ksp of outgoing task in tsk->thread.ksp */ | ||
46 | "st.as sp, [%3, %1] \n\t" | ||
47 | |||
48 | "sync \n\t" | ||
49 | |||
50 | /* | ||
51 | * setup _current_task with incoming tsk. | ||
52 | * optionally, set r25 to that as well | ||
53 | * For SMP extra work to get to &_current_task[cpu] | ||
54 | * (open coded SET_CURR_TASK_ON_CPU) | ||
55 | */ | ||
56 | "st %2, [@_current_task] \n\t" | ||
57 | |||
58 | /* get ksp of incoming task from tsk->thread.ksp */ | ||
59 | "ld.as sp, [%2, %1] \n\t" | ||
60 | |||
61 | /* start loading it's CALLEE reg file */ | ||
62 | |||
63 | "add sp, sp, %4 \n\t" /* skip gutter at top */ | ||
64 | |||
65 | "ld.ab r25, [sp, 4] \n\t" | ||
66 | "ld.ab r24, [sp, 4] \n\t" | ||
67 | "ld.ab r23, [sp, 4] \n\t" | ||
68 | "ld.ab r22, [sp, 4] \n\t" | ||
69 | "ld.ab r21, [sp, 4] \n\t" | ||
70 | "ld.ab r20, [sp, 4] \n\t" | ||
71 | "ld.ab r19, [sp, 4] \n\t" | ||
72 | "ld.ab r18, [sp, 4] \n\t" | ||
73 | "ld.ab r17, [sp, 4] \n\t" | ||
74 | "ld.ab r16, [sp, 4] \n\t" | ||
75 | "ld.ab r15, [sp, 4] \n\t" | ||
76 | "ld.ab r14, [sp, 4] \n\t" | ||
77 | "ld.ab r13, [sp, 4] \n\t" | ||
78 | |||
79 | /* last (ret value) = prev : although for ARC it mov r0, r0 */ | ||
80 | "mov %0, %3 \n\t" | ||
81 | |||
82 | /* FP/BLINK restore generated by gcc (standard func epilogue */ | ||
83 | |||
84 | : "=r"(tmp) | ||
85 | : "n"((TASK_THREAD + THREAD_KSP) / 4), "r"(next), "r"(prev), | ||
86 | "n"(num_words_to_skip * 4) | ||
87 | : "blink" | ||
88 | ); | ||
89 | |||
90 | return (struct task_struct *)tmp; | ||
91 | } | ||