mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
2.3 KiB
82 lines
2.3 KiB
/* SPDX-License-Identifier: GPL-2.0-only */ |
|
/* |
|
* Context switch support for Hexagon |
|
* |
|
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. |
|
*/ |
|
|
|
#include <asm/asm-offsets.h> |
|
|
|
.text |
|
|
|
/* |
|
* The register used as a fast-path thread information pointer |
|
* is determined as a kernel configuration option. If it happens |
|
* to be a callee-save register, we're going to be saving and |
|
* restoring it twice here. |
|
* |
|
* This code anticipates a revised ABI where R20-23 are added |
|
* to the set of callee-save registers, but this should be |
|
* backward compatible to legacy tools. |
|
*/ |
|
|
|
|
|
/* |
|
* void switch_to(struct task_struct *prev, |
|
* struct task_struct *next, struct task_struct *last); |
|
*/ |
|
.p2align 2 |
|
.globl __switch_to |
|
.type __switch_to, @function |
|
|
|
/* |
|
* When we exit the wormhole, we need to store the previous task |
|
* in the new R0's pointer. Technically it should be R2, but they should |
|
* be the same; seems like a legacy thing. In short, don't butcher |
|
* R0, let it go back out unmolested. |
|
*/ |
|
|
|
__switch_to: |
|
/* |
|
* Push callee-saves onto "prev" stack. |
|
* Here, we're sneaky because the LR and FP |
|
* storage of the thread_stack structure |
|
* is automagically allocated by allocframe, |
|
* so we pass struct size less 8. |
|
*/ |
|
allocframe(#(_SWITCH_STACK_SIZE - 8)); |
|
memd(R29+#(_SWITCH_R2726))=R27:26; |
|
memd(R29+#(_SWITCH_R2524))=R25:24; |
|
memd(R29+#(_SWITCH_R2322))=R23:22; |
|
memd(R29+#(_SWITCH_R2120))=R21:20; |
|
memd(R29+#(_SWITCH_R1918))=R19:18; |
|
memd(R29+#(_SWITCH_R1716))=R17:16; |
|
/* Stash thread_info pointer in task_struct */ |
|
memw(R0+#_TASK_THREAD_INFO) = THREADINFO_REG; |
|
memw(R0 +#(_TASK_STRUCT_THREAD + _THREAD_STRUCT_SWITCH_SP)) = R29; |
|
/* Switch to "next" stack and restore callee saves from there */ |
|
R29 = memw(R1 + #(_TASK_STRUCT_THREAD + _THREAD_STRUCT_SWITCH_SP)); |
|
{ |
|
R27:26 = memd(R29+#(_SWITCH_R2726)); |
|
R25:24 = memd(R29+#(_SWITCH_R2524)); |
|
} |
|
{ |
|
R23:22 = memd(R29+#(_SWITCH_R2322)); |
|
R21:20 = memd(R29+#(_SWITCH_R2120)); |
|
} |
|
{ |
|
R19:18 = memd(R29+#(_SWITCH_R1918)); |
|
R17:16 = memd(R29+#(_SWITCH_R1716)); |
|
} |
|
{ |
|
/* THREADINFO_REG is currently one of the callee-saved regs |
|
* above, and so be sure to re-load it last. |
|
*/ |
|
THREADINFO_REG = memw(R1 + #_TASK_THREAD_INFO); |
|
R31:30 = memd(R29+#_SWITCH_FP); |
|
} |
|
{ |
|
R29 = add(R29,#_SWITCH_STACK_SIZE); |
|
jumpr R31; |
|
} |
|
.size __switch_to, .-__switch_to
|
|
|