diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 71be453e17e..5c051980e68 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -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 diff --git a/arch/xtensa/src/common/xtensa_coproc.S b/arch/xtensa/src/common/xtensa_coproc.S index 371959b2ded..8b01063bf3b 100644 --- a/arch/xtensa/src/common/xtensa_coproc.S +++ b/arch/xtensa/src/common/xtensa_coproc.S @@ -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) */ diff --git a/arch/xtensa/src/common/xtensa_initialstate.c b/arch/xtensa/src/common/xtensa_initialstate.c index fb74503ad59..b8e14e51612 100644 --- a/arch/xtensa/src/common/xtensa_initialstate.c +++ b/arch/xtensa/src/common/xtensa_initialstate.c @@ -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 } diff --git a/arch/xtensa/src/common/xtensa_user_handler.S b/arch/xtensa/src/common/xtensa_user_handler.S index abf043da2b4..fc789ccb5a3 100644 --- a/arch/xtensa/src/common/xtensa_user_handler.S +++ b/arch/xtensa/src/common/xtensa_user_handler.S @@ -63,12 +63,6 @@ #include #include -/**************************************************************************** - * 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 */