Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/hexagon/kernel/vm_switch.S
26439 views
1
/* SPDX-License-Identifier: GPL-2.0-only */
2
/*
3
* Context switch support for Hexagon
4
*
5
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
6
*/
7
8
#include <asm/asm-offsets.h>
9
10
.text
11
12
/*
13
* The register used as a fast-path thread information pointer
14
* is determined as a kernel configuration option. If it happens
15
* to be a callee-save register, we're going to be saving and
16
* restoring it twice here.
17
*
18
* This code anticipates a revised ABI where R20-23 are added
19
* to the set of callee-save registers, but this should be
20
* backward compatible to legacy tools.
21
*/
22
23
24
/*
25
* void switch_to(struct task_struct *prev,
26
* struct task_struct *next, struct task_struct *last);
27
*/
28
.p2align 2
29
.globl __switch_to
30
.type __switch_to, @function
31
32
/*
33
* When we exit the wormhole, we need to store the previous task
34
* in the new R0's pointer. Technically it should be R2, but they should
35
* be the same; seems like a legacy thing. In short, don't butcher
36
* R0, let it go back out unmolested.
37
*/
38
39
__switch_to:
40
/*
41
* Push callee-saves onto "prev" stack.
42
* Here, we're sneaky because the LR and FP
43
* storage of the thread_stack structure
44
* is automagically allocated by allocframe,
45
* so we pass struct size less 8.
46
*/
47
allocframe(#(_SWITCH_STACK_SIZE - 8));
48
memd(R29+#(_SWITCH_R2726))=R27:26;
49
memd(R29+#(_SWITCH_R2524))=R25:24;
50
memd(R29+#(_SWITCH_R2322))=R23:22;
51
memd(R29+#(_SWITCH_R2120))=R21:20;
52
memd(R29+#(_SWITCH_R1918))=R19:18;
53
memd(R29+#(_SWITCH_R1716))=R17:16;
54
/* Stash thread_info pointer in task_struct */
55
memw(R0+#_TASK_THREAD_INFO) = THREADINFO_REG;
56
memw(R0 +#(_TASK_STRUCT_THREAD + _THREAD_STRUCT_SWITCH_SP)) = R29;
57
/* Switch to "next" stack and restore callee saves from there */
58
R29 = memw(R1 + #(_TASK_STRUCT_THREAD + _THREAD_STRUCT_SWITCH_SP));
59
{
60
R27:26 = memd(R29+#(_SWITCH_R2726));
61
R25:24 = memd(R29+#(_SWITCH_R2524));
62
}
63
{
64
R23:22 = memd(R29+#(_SWITCH_R2322));
65
R21:20 = memd(R29+#(_SWITCH_R2120));
66
}
67
{
68
R19:18 = memd(R29+#(_SWITCH_R1918));
69
R17:16 = memd(R29+#(_SWITCH_R1716));
70
}
71
{
72
/* THREADINFO_REG is currently one of the callee-saved regs
73
* above, and so be sure to re-load it last.
74
*/
75
THREADINFO_REG = memw(R1 + #_TASK_THREAD_INFO);
76
R31:30 = memd(R29+#_SWITCH_FP);
77
}
78
{
79
R29 = add(R29,#_SWITCH_STACK_SIZE);
80
jumpr R31;
81
}
82
.size __switch_to, .-__switch_to
83
84