xtensa: use highest available EPC/EPS regs in restore context
There may be Xtensa SoCs which don't have high enough interrupt levels for EPC6/EPS6 to exist in _restore_context. So changes these to those which should be available according to the ISA config file. Fixes #30126 Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
parent
e36ef3e302
commit
0d7bdbc876
2 changed files with 13 additions and 4 deletions
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
#include <xtensa-asm2-s.h>
|
#include <xtensa-asm2-s.h>
|
||||||
#include <offsets.h>
|
#include <offsets.h>
|
||||||
|
#include <toolchain.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* xtensa_spill_reg_windows
|
* xtensa_spill_reg_windows
|
||||||
|
@ -145,14 +146,18 @@ _high_restore_done:
|
||||||
* should test to be able to support hardware with less than 6 levels,
|
* should test to be able to support hardware with less than 6 levels,
|
||||||
* though...
|
* though...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define RCTX_EPC_REG _CONCAT(EPC, XCHAL_NUM_INTLEVELS)
|
||||||
|
#define RCTX_EPS_REG _CONCAT(EPS, XCHAL_NUM_INTLEVELS)
|
||||||
|
|
||||||
.global _restore_context
|
.global _restore_context
|
||||||
_restore_context:
|
_restore_context:
|
||||||
call0 xtensa_restore_high_regs
|
call0 xtensa_restore_high_regs
|
||||||
|
|
||||||
l32i a0, a1, BSA_PC_OFF
|
l32i a0, a1, BSA_PC_OFF
|
||||||
wsr.EPC6 a0
|
wsr.RCTX_EPC_REG a0
|
||||||
l32i a0, a1, BSA_PS_OFF
|
l32i a0, a1, BSA_PS_OFF
|
||||||
wsr.EPS6 a0
|
wsr.RCTX_EPS_REG a0
|
||||||
|
|
||||||
l32i a0, a1, BSA_SAR_OFF
|
l32i a0, a1, BSA_SAR_OFF
|
||||||
wsr.SAR a0
|
wsr.SAR a0
|
||||||
|
@ -179,7 +184,7 @@ _restore_context:
|
||||||
l32i a3, a1, BSA_A3_OFF
|
l32i a3, a1, BSA_A3_OFF
|
||||||
addi a1, a1, BASE_SAVE_AREA_SIZE
|
addi a1, a1, BASE_SAVE_AREA_SIZE
|
||||||
|
|
||||||
rfi 6
|
rfi XCHAL_NUM_INTLEVELS
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void xtensa_switch(void *new, void **old_return);
|
* void xtensa_switch(void *new, void **old_return);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <kernel_internal.h>
|
#include <kernel_internal.h>
|
||||||
#include <kswap.h>
|
#include <kswap.h>
|
||||||
#include <_soc_inthandlers.h>
|
#include <_soc_inthandlers.h>
|
||||||
|
#include <toolchain.h>
|
||||||
#include <logging/log.h>
|
#include <logging/log.h>
|
||||||
|
|
||||||
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);
|
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);
|
||||||
|
@ -136,9 +137,12 @@ static inline unsigned int get_bits(int offset, int num_bits, unsigned int val)
|
||||||
/* The wrapper code lives here instead of in the python script that
|
/* The wrapper code lives here instead of in the python script that
|
||||||
* generates _xtensa_handle_one_int*(). Seems cleaner, still kind of
|
* generates _xtensa_handle_one_int*(). Seems cleaner, still kind of
|
||||||
* ugly.
|
* ugly.
|
||||||
|
*
|
||||||
|
* This may be unused depending on number of interrupt levels
|
||||||
|
* supported by the SoC.
|
||||||
*/
|
*/
|
||||||
#define DEF_INT_C_HANDLER(l) \
|
#define DEF_INT_C_HANDLER(l) \
|
||||||
void *xtensa_int##l##_c(void *interrupted_stack) \
|
__unused void *xtensa_int##l##_c(void *interrupted_stack) \
|
||||||
{ \
|
{ \
|
||||||
uint32_t irqs, intenable, m; \
|
uint32_t irqs, intenable, m; \
|
||||||
__asm__ volatile("rsr.interrupt %0" : "=r"(irqs)); \
|
__asm__ volatile("rsr.interrupt %0" : "=r"(irqs)); \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue