arch/xtensa: Remember to spill windows in arch_cohere_stacks()
When we reach this code in interrupt context, our upper GPRs contain a cross-stack call that may still include some registers from the interrupted thread. Those need to go out to memory before we can do our cache coherence dance here. Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
parent
fed9f5aa04
commit
ae4f7a1a06
3 changed files with 19 additions and 6 deletions
|
@ -10,12 +10,11 @@
|
|||
/*
|
||||
* xtensa_spill_reg_windows
|
||||
*
|
||||
* Globally visible symbol to do register spills. Useful for unit
|
||||
* testing, or maybe as part of a debug/watchdog/error handler. Not a
|
||||
* C function, call this via CALL0 (so you probably have to save off
|
||||
* A0, but no other registers need to be spilled). On return, all
|
||||
* registers not part of the current function will be spilled to
|
||||
* memory.
|
||||
* Spill all register windows. Not a C function, enter this via CALL0
|
||||
* (so you have to save off A0, but no other registers need to be
|
||||
* spilled). On return, all registers not part of the current
|
||||
* function will be spilled to memory. The WINDOWSTART SR will have a
|
||||
* single 1 bit corresponding to the current frame at WINDOWBASE.
|
||||
*/
|
||||
.global xtensa_spill_reg_windows
|
||||
.align 4
|
||||
|
|
|
@ -83,6 +83,15 @@ static ALWAYS_INLINE void arch_cohere_stacks(struct k_thread *old_thread,
|
|||
size_t nsz = new_thread->stack_info.size;
|
||||
size_t nsp = (size_t) new_thread->switch_handle;
|
||||
|
||||
if (old_switch_handle != NULL) {
|
||||
int32_t a0save;
|
||||
|
||||
__asm__ volatile("mov %0, a0;"
|
||||
"call0 xtensa_spill_reg_windows;"
|
||||
"mov a0, %0"
|
||||
: "=r"(a0save));
|
||||
}
|
||||
|
||||
/* The "live" area (the region between the switch handle,
|
||||
* which is the stack pointer, and the top of the stack
|
||||
* memory) of the inbound stack needs to be invalidated: it
|
||||
|
|
|
@ -326,7 +326,12 @@ _do_call_\@:
|
|||
l32i a1, a1, 0
|
||||
l32i a0, a1, BSA_A0_OFF
|
||||
addi a1, a1, BASE_SAVE_AREA_SIZE
|
||||
#ifndef CONFIG_KERNEL_COHERENCE
|
||||
/* When using coherence, the registers of the interrupted
|
||||
* context got spilled upstream in arch_cohere_stacks()
|
||||
*/
|
||||
SPILL_ALL_WINDOWS
|
||||
#endif
|
||||
mov a1, a6
|
||||
|
||||
_restore_\@:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue