[XTENSA] Add support for configurable registers and coprocessors
The Xtensa architecture allows to define custom instructions and registers. Registers that are bound to a coprocessor are only accessible if the corresponding enable bit is set, which allows to implement a 'lazy' context switch mechanism. Other registers needs to be saved and restore at the time of the context switch or during interrupt handling. This patch adds support for these additional states: - save and restore registers that are used by the compiler upon interrupt entry and exit. - context switch additional registers unbound to any coprocessor - 'lazy' context switch of registers bound to a coprocessor - ptrace interface to provide access to additional registers - update configuration files in include/asm-xtensa/variant-fsf Signed-off-by: Chris Zankel <chris@zankel.net>
This commit is contained in:
@@ -46,42 +46,6 @@ static inline int irqs_disabled(void)
|
||||
return flags & 0xf;
|
||||
}
|
||||
|
||||
#define RSR_CPENABLE(x) do { \
|
||||
__asm__ __volatile__("rsr %0," __stringify(CPENABLE) : "=a" (x)); \
|
||||
} while(0);
|
||||
#define WSR_CPENABLE(x) do { \
|
||||
__asm__ __volatile__("wsr %0," __stringify(CPENABLE)";rsync" \
|
||||
:: "a" (x));} while(0);
|
||||
|
||||
#define clear_cpenable() __clear_cpenable()
|
||||
|
||||
static inline void __clear_cpenable(void)
|
||||
{
|
||||
#if XCHAL_HAVE_CP
|
||||
unsigned long i = 0;
|
||||
WSR_CPENABLE(i);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void enable_coprocessor(int i)
|
||||
{
|
||||
#if XCHAL_HAVE_CP
|
||||
int cp;
|
||||
RSR_CPENABLE(cp);
|
||||
cp |= 1 << i;
|
||||
WSR_CPENABLE(cp);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void disable_coprocessor(int i)
|
||||
{
|
||||
#if XCHAL_HAVE_CP
|
||||
int cp;
|
||||
RSR_CPENABLE(cp);
|
||||
cp &= ~(1 << i);
|
||||
WSR_CPENABLE(cp);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define smp_read_barrier_depends() do { } while(0)
|
||||
#define read_barrier_depends() do { } while(0)
|
||||
@@ -111,7 +75,6 @@ extern void *_switch_to(void *last, void *next);
|
||||
|
||||
#define switch_to(prev,next,last) \
|
||||
do { \
|
||||
clear_cpenable(); \
|
||||
(last) = _switch_to(prev, next); \
|
||||
} while(0)
|
||||
|
||||
@@ -244,7 +207,7 @@ static inline void spill_registers(void)
|
||||
"wsr a13," __stringify(SAR) "\n\t"
|
||||
"wsr a14," __stringify(PS) "\n\t"
|
||||
:: "a" (&a0), "a" (&ps)
|
||||
: "a2", "a3", "a12", "a13", "a14", "a15", "memory");
|
||||
: "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", "memory");
|
||||
}
|
||||
|
||||
#define arch_align_stack(x) (x)
|
||||
|
||||
Reference in New Issue
Block a user