Xtensa: Add EXPERIMENTAL hooks to support lazy co-processor state restore in the future.

This commit is contained in:
Gregory Nutt 2016-11-16 06:48:13 -06:00
parent 5ce3b399d5
commit 6a875bcb61
4 changed files with 54 additions and 24 deletions

View File

@ -31,6 +31,30 @@ config ARCH_FAMILY_LX6
Cadence® Tensilica® Xtensa® LX6 data plane processing unit (DPU).
The LX6 is a configurable and extensible processor core.
config ARCH_CHIP
string
default "esp32" if ARCH_CHIP_ESP32
config XTENSA_CP_LAZY
bool "Lazy co-processor state restoration"
default n
depends on EXPERIMENTAL
---help---
NuttX logic saves and restores the co-processor enabled (CPENABLE)
register on each context switch. This has disadvantages in that (1)
co-processor context will be saved and restored even if the co-
processor was never used, and (2) tasks must explicitly enable and
disable co-processors.
An alternative, "lazy" co-processor state restore is enabled with
this option. That logic works like as follows:
a. CPENABLE is set to zero on each context switch, disabling all co-
processors.
b. If/when the task attempts to use the disabled co-processor, an
exception occurs
c. The co-processor exception handler re-enables the co-processor.
config XTENSA_USE_OVLY
bool
default n
@ -41,6 +65,7 @@ config XTENSA_CP_INITSET
hex "Default co-processor enables"
default 0x0001
range 0 0xffff
depends on !XTENSA_CP_LAZY
---help---
Co-processors may be enabled on a thread by calling xtensa_coproc_enable()
and disabled by calling xtensa_coproc_disable(). Some co-processors
@ -48,10 +73,6 @@ config XTENSA_CP_INITSET
is provided by CONFIG_XTENSA_CP_INITSET. Each bit corresponds to one
coprocessor with the same bit layout as for the CPENABLE register.
config ARCH_CHIP
string
default "esp32" if ARCH_CHIP_ESP32
source arch/xtensa/src/lx6/Kconfig
if ARCH_CHIP_ESP32
source arch/xtensa/src/esp32/Kconfig

View File

@ -306,7 +306,11 @@ _xtensa_coproc_restorestate:
mov a15, a2 /* A15 is now the address of the save area */
#ifdef CONFIG_XTENSA_CP_LAZY
movi a2, 0 /* a2 = Will disable all coprocessors */
#else
l16ui a2, a15, XTENSA_CPENABLE /* a2 = Which CPs have been enable for this thread? */
#endif
wsr a2, CPENABLE /* Set CPENABLE correctly for this thread */
l16ui a2, a15, XTENSA_CPSTORED /* a2 = Which CPs have been saved for this thread? */
movi a3, 0 /* Clear the ones being restored (all of them) */

View File

@ -98,10 +98,15 @@ void up_initial_state(struct tcb_s *tcb)
#if XCHAL_CP_NUM > 0
/* Set up the co-processors that will be enabled initially when the thread
* starts (see xtensa_coproc.h)
* starts (see xtensa_coproc.h). If the lazy co-processor state restore
* logic is selected, that would be the empty set.
*/
#ifdef CONFIG_XTENSA_CP_LAZY
xcp->cpstate.cpenable = 0; /* No co-processors are enabled */
#else
xcp->cpstate.cpenable = (CONFIG_XTENSA_CP_INITSET & XTENSA_CP_ALLSET);
xcp->cpstate.cpstored = 0; /* No coprocessors haved statee saved for this thread */
#endif
xcp->cpstate.cpstored = 0; /* No co-processors haved state saved */
#endif
}

View File

@ -63,12 +63,6 @@
#include <arch/xtensa/core.h>
#include <arch/xtensa/xtensa_specregs.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#undef HAVE_LAZY_COPROC
/****************************************************************************
* Assembly Language Macros
****************************************************************************/
@ -144,13 +138,13 @@ _xtensa_to_alloca_handler:
_xtensa_to_syscall_handler:
call0 _xtensa_syscall_handler /* Jump to syscall exception handler */
#ifdef HAVE_LAZY_COPROC
#ifdef CONFIG_XTENSA_CP_LAZY
#if XCHAL_CP_NUM > 0
.align 4
_xtensa_to_coproc_handler:
call0 _xtensa_coproc_handler /* Jump to copressor exception handler */
#endif
#endif /* HAVE_LAZY_COPROC */
#endif /* CONFIG_XTENSA_CP_LAZY */
/****************************************************************************
* Name: _xtensa_user_handler
@ -173,7 +167,7 @@ _xtensa_user_handler:
rsr a0, EXCCAUSE
beqi a0, EXCCAUSE_LEVEL1INTERRUPT, _xtensa_to_level1_handler
#ifdef HAVE_LAZY_COPROC
#ifdef CONFIG_XTENSA_CP_LAZY
#if XCHAL_CP_NUM > 0
/* Handle any coprocessor exceptions. Rely on the fact that exception
* numbers above EXCCAUSE_CP0_DISABLED all relate to the coprocessors.
@ -181,7 +175,7 @@ _xtensa_user_handler:
bgeui a0, EXCCAUSE_CP0_DISABLED, _xtensa_to_coproc_handler
#endif
#endif /* HAVE_LAZY_COPROC */
#endif /* CONFIG_XTENSA_CP_LAZY */
/* Handle alloca and syscall exceptions */
@ -399,11 +393,14 @@ _xtensa_syscall_handler:
* NuttX does not currently implement this lazy co-process enable. Rather,
* NuttX follows the model:
*
* 1. A set of co-processors may be enable when each thread starts as determined by CONFIG_XTENSA_CP_INITSET.
* 2. Additional co-processors may be enabled for the thread by explicitly setting the CPENABLE register when the thread starts.
* 3. Co-processor state, including CPENABLE, is saved an restored on each context switch.
* 1. A set of co-processors may be enable when each thread starts as
* determined by CONFIG_XTENSA_CP_INITSET.
* 2. Additional co-processors may be enabled for the thread by explicitly
* setting the CPENABLE register when the thread starts.
* 3. Co-processor state, including CPENABLE, is saved an restored on each
* context switch.
* 4. Any Coprocessor[n]Disabled exceptions result in a system PANIC.
*
* These exceptions are generated by co-processor instructions, which are
* only allowed in thread code (not in interrupts or kernel code). This
* restriction is deliberately imposed to reduce the burden of state-save/
@ -414,11 +411,14 @@ _xtensa_syscall_handler:
*
****************************************************************************/
/* Disabled for now: The following logic is redundant. It simply duplicates the
* the logic in _xtensa_user_handler
#ifdef CONFIG_XTENSA_CP_LAZY
/* Lazy co-processor restoration is not implemented. Below, the logic simply
* calls xtensa_user() which will crash the system with an unhandled error
* Duplicates logic above.
*/
#ifdef HAVE_LAZY_COPROC
#error Lazy co-processor restoration is not implemented
#if XCHAL_CP_NUM > 0
.type _xtensa_coproc_handler, @function
.align 4
@ -477,4 +477,4 @@ _xtensa_coproc_handler:
1: j 1b
#endif /* XCHAL_CP_NUM */
#endif /* HAVE_LAZY_COPROC */
#endif /* CONFIG_XTENSA_CP_LAZY */