From 8dca7ae587abc4cac755ee0fb5f7e95df03351b9 Mon Sep 17 00:00:00 2001 From: Andy Ross Date: Thu, 7 Dec 2017 12:17:39 -0800 Subject: [PATCH] xtensa: Make high priority interrupts optional Xtensa has a "high priority" class of interrupt levels which ignore the EXCM bit and can thus interrupt running exception handlers. These can't be used for C handlers in the general case[1] because C code needs to be able to throw window over/underflow exceptions, which are not reentrant. But the high priority interrupts might be useful to a carefully designed application, or to unit tests of low level architecture code. So make their generation optional with this kconfig option. [1] ESP-32 has a high priority interrupt for its watchdog, apparently. Which is sort of OK given that it never needs to return to the interrupted code. Signed-off-by: Andy Ross --- arch/xtensa/Kconfig | 17 +++++++++++++++ arch/xtensa/core/xtensa_vectors.S | 36 +++++++++++++++++-------------- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 42eef1a9a68..d3633b1593c 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -76,6 +76,23 @@ config IRQ_OFFLOAD_INTNUM Please note that in order for IRQ offload to work correctly the selected interrupt shall have its priority shall not exceed XCHAL_EXCM_LEVEL. +config XTENSA_OMIT_HIGH_INTERRUPTS + bool + prompt "Skip generation of vectors for high priority interrupts" + default n + help + Setting this to y causes the interrupt vectors for "high + priority" Xtensa interrupts (those not masked by the EXCM bit + in PS) to be left ungenerated, so they can be handled by + application code instead. Note that high priority interrupts + cannot safely be handled by C code anyway (they will interrupt + register window exceptions, which cannot be made reentrant, so + the code under the handler must not emit them), though some + devices might still want to use built-in handling for things + like watchdogs which do not need to return into interrupted + code. Default is "n" for legacy compatibility. Consider + changing to "y" in the future. + config TOOLCHAIN_VARIANT string default RG-2016.4-linux diff --git a/arch/xtensa/core/xtensa_vectors.S b/arch/xtensa/core/xtensa_vectors.S index 779cd1d4384..37c15f69af3 100644 --- a/arch/xtensa/core/xtensa_vectors.S +++ b/arch/xtensa/core/xtensa_vectors.S @@ -80,6 +80,16 @@ #include #include "xtensa_rtos.h" +#define GEN_MED_INTERRUPT(l) \ + (XCHAL_NUM_INTLEVELS >= (l) && \ + XCHAL_DEBUGLEVEL != (l) && \ + XCHAL_EXCM_LEVEL >= (l)) + +#define GEN_HIGH_INTERRUPT(l) \ + (XCHAL_NUM_INTLEVELS >= (l) && \ + XCHAL_DEBUGLEVEL != (l) && \ + (XCHAL_EXCM_LEVEL < (l) && !defined(CONFIG_XTENSA_OMIT_HIGH_INTERRUPTS))) + /* * Defines used to access _xtos_interrupt_table. */ @@ -1015,7 +1025,7 @@ _xt_lowint1: * repeated 5 times!! */ -#if XCHAL_EXCM_LEVEL >= 2 +#if GEN_MED_INTERRUPT(2) .begin literal_prefix .Level2InterruptVector .section .Level2InterruptVector.text, "ax" @@ -1088,7 +1098,7 @@ _xt_medint2_exit: #endif /* Level 2 */ -#if XCHAL_EXCM_LEVEL >= 3 +#if GEN_MED_INTERRUPT(3) .begin literal_prefix .Level3InterruptVector .section .Level3InterruptVector.text, "ax" @@ -1161,12 +1171,7 @@ _xt_medint3_exit: #endif /* Level 3 */ -/* FIXME: For some reason, the HAL provided by the ESP32 port of FreeRTOS, - * that Zephyr uses, defines XCHAL_EXCM_LEVEL to 3. That essentially - * enables the other _Level4Vector routine, that doesn't work on ESP32. - * This is tracked by: https://jira.zephyrproject.org/browse/ZEP-2570 - */ -#if defined(CONFIG_SOC_ESP32) || (XCHAL_EXCM_LEVEL >= 4) +#if GEN_MED_INTERRUPT(4) .begin literal_prefix .Level4InterruptVector .section .Level4InterruptVector.text, "ax" @@ -1238,7 +1243,7 @@ _xt_medint4_exit: #endif /* Level 4 */ -#if XCHAL_EXCM_LEVEL >= 5 +#if GEN_MED_INTERRUPT(5) .begin literal_prefix .Level5InterruptVector .section .Level5InterruptVector.text, "ax" @@ -1310,7 +1315,7 @@ _xt_medint5_exit: #endif /* Level 5 */ -#if XCHAL_EXCM_LEVEL >= 6 +#if GEN_MED_INTERRUPT(6) .begin literal_prefix .Level6InterruptVector .section .Level6InterruptVector.text, "ax" @@ -1418,7 +1423,7 @@ _xt_medint6_exit: * Systems tools documentation: "Microprocessor Programmer's Guide". */ -#if XCHAL_NUM_INTLEVELS >=2 && XCHAL_EXCM_LEVEL <2 && XCHAL_DEBUGLEVEL !=2 +#if GEN_HIGH_INTERRUPT(2) .begin literal_prefix .Level2InterruptVector .section .Level2InterruptVector.text, "ax" @@ -1455,7 +1460,7 @@ _xt_highint2: #endif /* Level 2 */ -#if XCHAL_NUM_INTLEVELS >=3 && XCHAL_EXCM_LEVEL <3 && XCHAL_DEBUGLEVEL !=3 +#if GEN_HIGH_INTERRUPT(3) .begin literal_prefix .Level3InterruptVector .section .Level3InterruptVector.text, "ax" @@ -1493,7 +1498,7 @@ _xt_highint3: #endif /* Level 3 */ -#if !defined(CONFIG_SOC_ESP32) && XCHAL_NUM_INTLEVELS >=4 && XCHAL_EXCM_LEVEL <4 && XCHAL_DEBUGLEVEL !=4 +#if GEN_HIGH_INTERRUPT(4) .begin literal_prefix .Level4InterruptVector .section .Level4InterruptVector.text, "ax" @@ -1531,8 +1536,7 @@ _xt_highint4: #endif /* Level 4 */ -#if XCHAL_NUM_INTLEVELS >=5 && XCHAL_EXCM_LEVEL <5 && XCHAL_DEBUGLEVEL !=5 - +#if GEN_HIGH_INTERRUPT(5) .begin literal_prefix .Level5InterruptVector .section .Level5InterruptVector.text, "ax" .global _Level5Vector @@ -1571,7 +1575,7 @@ _xt_highint5: #endif /* Level 5 */ -#if XCHAL_NUM_INTLEVELS >=6 && XCHAL_EXCM_LEVEL <6 && XCHAL_DEBUGLEVEL !=6 +#if GEN_HIGH_INTERRUPT(6) .begin literal_prefix .Level6InterruptVector .section .Level6InterruptVector.text, "ax"