diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index a028ee2ec19..9b08f38d122 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -35,18 +35,6 @@ config XTENSA_NCOPROCESSORS int "Number of co-processors" default 1 -config XTENSA_INT_NLEVELS - int "Number of interrupt levels" - default 5 - -config XTENSA_EXCM_LEVEL - int "Level masked by PS.EXCM" - default 3 - -config XTENSA_HAVE_LOOPS - bool "Zero overhead loops" - default n - config XTENSA_HAVE_INTERRUPTS bool default n diff --git a/arch/xtensa/include/esp32/core-isa.h b/arch/xtensa/include/esp32/core-isa.h new file mode 100644 index 00000000000..6027ec64798 --- /dev/null +++ b/arch/xtensa/include/esp32/core-isa.h @@ -0,0 +1,638 @@ +/**************************************************************************** + * arch/xtensa/include/esp32/core-isa.h + * Xtensa processor CORE configuration + * + * Customer ID=11657; Build=0x5fe96; Copyright (c) 1999-2016 Tensilica Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_INCLUDE_ESP32_CORE_ISA_H +#define __ARCH_XTENSA_INCLUDE_ESP32_CORE_ISA_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Note: Macros of the form XTENSA_HAVE_*** have a value of 1 if the option + * is configured, and a value of 0 otherwise (or undefined if 0 is a valid + * numeric option. These macros are always defined. + */ + +/* ISA **********************************************************************/ + +#define XTENSA_HAVE_BE 0 /* big-endian byte ordering */ +#define XTENSA_HAVE_WINDOWED 1 /* windowed registers option */ +#define XTENSA_NUM_AREGS 64 /* num of physical addr regs */ +#define XTENSA_NUM_AREGS_LOG2 6 /* log2(XTENSA_NUM_AREGS) */ +#define XTENSA_MAX_INSTRUCTION_SIZE 3 /* max instr bytes (3..8) */ +#define XTENSA_HAVE_DEBUG 1 /* debug option */ +#define XTENSA_HAVE_DENSITY 1 /* 16-bit instructions */ +#define XTENSA_HAVE_LOOPS 1 /* zero-overhead loops */ +#define XTENSA_LOOP_BUFFER_SIZE 256 /* zero-ov. loop instr buffer size */ +#define XTENSA_HAVE_NSA 1 /* NSA/NSAU instructions */ +#define XTENSA_HAVE_MINMAX 1 /* MIN/MAX instructions */ +#define XTENSA_HAVE_SEXT 1 /* SEXT instruction */ +#define XTENSA_HAVE_DEPBITS 0 /* DEPBITS instruction */ +#define XTENSA_HAVE_CLAMPS 1 /* CLAMPS instruction */ +#define XTENSA_HAVE_MUL16 1 /* MUL16S/MUL16U instructions */ +#define XTENSA_HAVE_MUL32 1 /* MULL instruction */ +#define XTENSA_HAVE_MUL32_HIGH 1 /* MULUH/MULSH instructions */ +#define XTENSA_HAVE_DIV32 1 /* QUOS/QUOU/REMS/REMU instructions */ +#define XTENSA_HAVE_L32R 1 /* L32R instruction */ +#define XTENSA_HAVE_ABSOLUTE_LITERALS 0 /* non-PC-rel (extended) L32R */ +#define XTENSA_HAVE_CONST16 0 /* CONST16 instruction */ +#define XTENSA_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */ +#define XTENSA_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */ +#define XTENSA_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */ +#define XTENSA_HAVE_CALL4AND12 1 /* (obsolete option) */ +#define XTENSA_HAVE_ABS 1 /* ABS instruction */ +/*#define XTENSA_HAVE_POPC 0*/ /* POPC instruction */ +/*#define XTENSA_HAVE_CRC 0*/ /* CRC instruction */ +#define XTENSA_HAVE_RELEASE_SYNC 1 /* L32AI/S32RI instructions */ +#define XTENSA_HAVE_S32C1I 1 /* S32C1I instruction */ +#define XTENSA_HAVE_SPECULATION 0 /* speculation */ +#define XTENSA_HAVE_FULL_RESET 1 /* all regs/state reset */ +#define XTENSA_NUM_CONTEXTS 1 /* */ +#define XTENSA_NUM_MISC_REGS 4 /* num of scratch regs (0..4) */ +#define XTENSA_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */ +#define XTENSA_HAVE_PRID 1 /* processor ID register */ +#define XTENSA_HAVE_EXTERN_REGS 1 /* WER/RER instructions */ +#define XTENSA_HAVE_MX 0 /* MX core (Tensilica internal) */ +#define XTENSA_HAVE_MP_INTERRUPTS 0 /* interrupt distributor port */ +#define XTENSA_HAVE_MP_RUNSTALL 0 /* core RunStall control port */ +#define XTENSA_HAVE_PSO 0 /* Power Shut-Off */ +#define XTENSA_HAVE_PSO_CDM 0 /* core/debug/mem pwr domains */ +#define XTENSA_HAVE_PSO_FULL_RETENTION 0 /* all regs preserved on PSO */ +#define XTENSA_HAVE_THREADPTR 1 /* THREADPTR register */ +#define XTENSA_HAVE_BOOLEANS 1 /* boolean registers */ +#define XTENSA_HAVE_CP 1 /* CPENABLE reg (coprocessor) */ +#define XTENSA_CP_MAXCFG 8 /* max allowed cp id plus one */ +#define XTENSA_HAVE_MAC16 1 /* MAC16 package */ + +#define XTENSA_HAVE_FUSION 0 /* Fusion*/ +#define XTENSA_HAVE_FUSION_FP 0 /* Fusion FP option */ +#define XTENSA_HAVE_FUSION_LOW_POWER 0 /* Fusion Low Power option */ +#define XTENSA_HAVE_FUSION_AES 0 /* Fusion BLE/Wifi AES-128 CCM option */ +#define XTENSA_HAVE_FUSION_CONVENC 0 /* Fusion Conv Encode option */ +#define XTENSA_HAVE_FUSION_LFSR_CRC 0 /* Fusion LFSR-CRC option */ +#define XTENSA_HAVE_FUSION_BITOPS 0 /* Fusion Bit Operations Support option */ +#define XTENSA_HAVE_FUSION_AVS 0 /* Fusion AVS option */ +#define XTENSA_HAVE_FUSION_16BIT_BASEBAND 0 /* Fusion 16-bit Baseband option */ +#define XTENSA_HAVE_FUSION_VITERBI 0 /* Fusion Viterbi option */ +#define XTENSA_HAVE_FUSION_SOFTDEMAP 0 /* Fusion Soft Bit Demap option */ +#define XTENSA_HAVE_HIFIPRO 0 /* HiFiPro Audio Engine pkg */ +#define XTENSA_HAVE_HIFI4 0 /* HiFi4 Audio Engine pkg */ +#define XTENSA_HAVE_HIFI4_VFPU 0 /* HiFi4 Audio Engine VFPU option */ +#define XTENSA_HAVE_HIFI3 0 /* HiFi3 Audio Engine pkg */ +#define XTENSA_HAVE_HIFI3_VFPU 0 /* HiFi3 Audio Engine VFPU option */ +#define XTENSA_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */ +#define XTENSA_HAVE_HIFI2EP 0 /* HiFi2EP */ +#define XTENSA_HAVE_HIFI_MINI 0 + +#define XTENSA_HAVE_VECTORFPU2005 0 /* vector or user floating-point pkg */ +#define XTENSA_HAVE_USER_DPFPU 0 /* user DP floating-point pkg */ +#define XTENSA_HAVE_USER_SPFPU 0 /* user DP floating-point pkg */ +#define XTENSA_HAVE_FP 1 /* single prec floating point */ +#define XTENSA_HAVE_FP_DIV 1 /* FP with DIV instructions */ +#define XTENSA_HAVE_FP_RECIP 1 /* FP with RECIP instructions */ +#define XTENSA_HAVE_FP_SQRT 1 /* FP with SQRT instructions */ +#define XTENSA_HAVE_FP_RSQRT 1 /* FP with RSQRT instructions */ +#define XTENSA_HAVE_DFP 0 /* double precision FP pkg */ +#define XTENSA_HAVE_DFP_DIV 0 /* DFP with DIV instructions */ +#define XTENSA_HAVE_DFP_RECIP 0 /* DFP with RECIP instructions*/ +#define XTENSA_HAVE_DFP_SQRT 0 /* DFP with SQRT instructions */ +#define XTENSA_HAVE_DFP_RSQRT 0 /* DFP with RSQRT instructions*/ +#define XTENSA_HAVE_DFP_ACCEL 1 /* double precision FP acceleration pkg */ +#define XTENSA_HAVE_DFP_accel XTENSA_HAVE_DFP_ACCEL /* for backward compatibility */ + +#define XTENSA_HAVE_DFPU_SINGLE_ONLY 1 /* DFPU Coprocessor, single precision only */ +#define XTENSA_HAVE_DFPU_SINGLE_DOUBLE 0 /* DFPU Coprocessor, single and double precision */ +#define XTENSA_HAVE_VECTRA1 0 /* Vectra I pkg */ +#define XTENSA_HAVE_VECTRALX 0 /* Vectra LX pkg */ +#define XTENSA_HAVE_PDX4 0 /* PDX4 */ +#define XTENSA_HAVE_CONNXD2 0 /* ConnX D2 pkg */ +#define XTENSA_HAVE_CONNXD2_DUALLSFLIX 0 /* ConnX D2 & Dual LoadStore Flix */ +#define XTENSA_HAVE_BBE16 0 /* ConnX BBE16 pkg */ +#define XTENSA_HAVE_BBE16_RSQRT 0 /* BBE16 & vector recip sqrt */ +#define XTENSA_HAVE_BBE16_VECDIV 0 /* BBE16 & vector divide */ +#define XTENSA_HAVE_BBE16_DESPREAD 0 /* BBE16 & despread */ +#define XTENSA_HAVE_BBENEP 0 /* ConnX BBENEP pkgs */ +#define XTENSA_HAVE_BSP3 0 /* ConnX BSP3 pkg */ +#define XTENSA_HAVE_BSP3_TRANSPOSE 0 /* BSP3 & transpose32x32 */ +#define XTENSA_HAVE_SSP16 0 /* ConnX SSP16 pkg */ +#define XTENSA_HAVE_SSP16_VITERBI 0 /* SSP16 & viterbi */ +#define XTENSA_HAVE_TURBO16 0 /* ConnX Turbo16 pkg */ +#define XTENSA_HAVE_BBP16 0 /* ConnX BBP16 pkg */ +#define XTENSA_HAVE_FLIX3 0 /* basic 3-way FLIX option */ +#define XTENSA_HAVE_GRIVPEP 0 /* GRIVPEP is General Release of IVPEP */ +#define XTENSA_HAVE_GRIVPEP_HISTOGRAM 0 /* Histogram option on GRIVPEP */ + +/* Misc. ********************************************************************/ + +#define XTENSA_NUM_LOADSTORE_UNITS 1 /* load/store units */ +#define XTENSA_NUM_WRITEBUFFER_ENTRIES 4 /* size of write buffer */ +#define XTENSA_INST_FETCH_WIDTH 4 /* instr-fetch width in bytes */ +#define XTENSA_DATA_WIDTH 4 /* data width in bytes */ +#define XTENSA_DATA_PIPE_DELAY 2 /* d-side pipeline delay + * (1 = 5-stage, 2 = 7-stage) */ +#define XTENSA_CLOCK_GATING_GLOBAL 1 /* global clock gating */ +#define XTENSA_CLOCK_GATING_FUNCUNIT 1 /* funct. unit clock gating */ +/* In T1050, applies to selected core load and store instructions (see ISA): */ +#define XTENSA_UNALIGNED_LOAD_EXCEPTION 0 /* unaligned loads cause exc. */ +#define XTENSA_UNALIGNED_STORE_EXCEPTION 0 /* unaligned stores cause exc.*/ +#define XTENSA_UNALIGNED_LOAD_HW 1 /* unaligned loads work in hw */ +#define XTENSA_UNALIGNED_STORE_HW 1 /* unaligned stores work in hw*/ + +#define XTENSA_SW_VERSION 1100003 /* sw version of this header */ + +#define XTENSA_CORE_ID "esp32_v3_49_prod" /* alphanum core name + * (CoreID) set in the Xtensa + * Processor Generator */ + +#define XTENSA_BUILD_UNIQUE_ID 0x0005fe96 /* 22-bit sw build ID */ + +/* + * These definitions describe the hardware targeted by this software. + */ +#define XTENSA_HW_CONFIGID0 0xc2bcfffe /* ConfigID hi 32 bits*/ +#define XTENSA_HW_CONFIGID1 0x1cc5fe96 /* ConfigID lo 32 bits*/ +#define XTENSA_HW_VERSION_NAME "LX6.0.3" /* full version name */ +#define XTENSA_HW_VERSION_MAJOR 2600 /* major ver# of targeted hw */ +#define XTENSA_HW_VERSION_MINOR 3 /* minor ver# of targeted hw */ +#define XTENSA_HW_VERSION 260003 /* major*100+minor */ +#define XTENSA_HW_REL_LX6 1 +#define XTENSA_HW_REL_LX6_0 1 +#define XTENSA_HW_REL_LX6_0_3 1 +#define XTENSA_HW_CONFIGID_RELIABLE 1 + +/* If software targets a *range* of hardware versions, these are the bounds: */ + +#define XTENSA_HW_MIN_VERSION_MAJOR 2600 /* major v of earliest tgt hw */ +#define XTENSA_HW_MIN_VERSION_MINOR 3 /* minor v of earliest tgt hw */ +#define XTENSA_HW_MIN_VERSION 260003 /* earliest targeted hw */ +#define XTENSA_HW_MAX_VERSION_MAJOR 2600 /* major v of latest tgt hw */ +#define XTENSA_HW_MAX_VERSION_MINOR 3 /* minor v of latest tgt hw */ +#define XTENSA_HW_MAX_VERSION 260003 /* latest targeted hw */ + +/* Cache ********************************************************************/ + +#define XTENSA_ICACHE_LINESIZE 4 /* I-cache line size in bytes */ +#define XTENSA_DCACHE_LINESIZE 4 /* D-cache line size in bytes */ +#define XTENSA_ICACHE_LINEWIDTH 2 /* log2(I line size in bytes) */ +#define XTENSA_DCACHE_LINEWIDTH 2 /* log2(D line size in bytes) */ + +#define XTENSA_ICACHE_SIZE 0 /* I-cache size in bytes or 0 */ +#define XTENSA_DCACHE_SIZE 0 /* D-cache size in bytes or 0 */ + +#define XTENSA_DCACHE_IS_WRITEBACK 0 /* writeback feature */ +#define XTENSA_DCACHE_IS_COHERENT 0 /* MP coherence feature */ + +#define XTENSA_HAVE_PREFETCH 0 /* PREFCTL register */ +#define XTENSA_HAVE_PREFETCH_L1 0 /* prefetch to L1 dcache */ +#define XTENSA_PREFETCH_CASTOUT_LINES 0 /* dcache pref. castout bufsz */ +#define XTENSA_PREFETCH_ENTRIES 0 /* cache prefetch entries */ +#define XTENSA_PREFETCH_BLOCK_ENTRIES 0 /* prefetch block streams */ +#define XTENSA_HAVE_CACHE_BLOCKOPS 0 /* block prefetch for caches */ +#define XTENSA_HAVE_ICACHE_TEST 0 /* Icache test instructions */ +#define XTENSA_HAVE_DCACHE_TEST 0 /* Dcache test instructions */ +#define XTENSA_HAVE_ICACHE_DYN_WAYS 0 /* Icache dynamic way support */ +#define XTENSA_HAVE_DCACHE_DYN_WAYS 0 /* Dcache dynamic way support */ + +/* Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code */ + +#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY + +/* Cache ********************************************************************/ + +#define XTENSA_HAVE_PIF 1 /* any outbound PIF present */ +#define XTENSA_HAVE_AXI 0 /* AXI bus */ + +#define XTENSA_HAVE_PIF_WR_RESP 0 /* pif write response */ +#define XTENSA_HAVE_PIF_REQ_ATTR 0 /* pif attribute */ + +/* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */ + +/* Number of cache sets in log2(lines per way): */ + +#define XTENSA_ICACHE_SETWIDTH 0 +#define XTENSA_DCACHE_SETWIDTH 0 + +/* Cache set associativity (number of ways): */ + +#define XTENSA_ICACHE_WAYS 1 +#define XTENSA_DCACHE_WAYS 1 + +/* Cache features: */ + +#define XTENSA_ICACHE_LINE_LOCKABLE 0 +#define XTENSA_DCACHE_LINE_LOCKABLE 0 +#define XTENSA_ICACHE_ECC_PARITY 0 +#define XTENSA_DCACHE_ECC_PARITY 0 + +/* Cache access size in bytes (affects operation of SICW instruction): */ + +#define XTENSA_ICACHE_ACCESS_SIZE 1 +#define XTENSA_DCACHE_ACCESS_SIZE 1 + +#define XTENSA_DCACHE_BANKS 0 /* number of banks */ + +/* Number of encoded cache attr bits for decoded bits): */ + +#define XTENSA_CA_BITS 4 + +/* Internal I/D RAM/ROMs and XLMI *******************************************/ + +#define XTENSA_NUM_INSTROM 1 /* number of core instr. ROMs */ +#define XTENSA_NUM_INSTRAM 2 /* number of core instr. RAMs */ +#define XTENSA_NUM_DATAROM 1 /* number of core data ROMs */ +#define XTENSA_NUM_DATARAM 2 /* number of core data RAMs */ +#define XTENSA_NUM_URAM 0 /* number of core unified RAMs*/ +#define XTENSA_NUM_XLMI 1 /* number of core XLMI ports */ + +/* Instruction ROM 0: */ + +#define XTENSA_INSTROM0_VADDR 0x40800000 /* virtual address */ +#define XTENSA_INSTROM0_PADDR 0x40800000 /* physical address */ +#define XTENSA_INSTROM0_SIZE 4194304 /* size in bytes */ +#define XTENSA_INSTROM0_ECC_PARITY 0 /* ECC/parity type, 0=none */ + +/* Instruction RAM 0: */ + +#define XTENSA_INSTRAM0_VADDR 0x40000000 /* virtual address */ +#define XTENSA_INSTRAM0_PADDR 0x40000000 /* physical address */ +#define XTENSA_INSTRAM0_SIZE 4194304 /* size in bytes */ +#define XTENSA_INSTRAM0_ECC_PARITY 0 /* ECC/parity type, 0=none */ + +/* Instruction RAM 1: */ + +#define XTENSA_INSTRAM1_VADDR 0x40400000 /* virtual address */ +#define XTENSA_INSTRAM1_PADDR 0x40400000 /* physical address */ +#define XTENSA_INSTRAM1_SIZE 4194304 /* size in bytes */ +#define XTENSA_INSTRAM1_ECC_PARITY 0 /* ECC/parity type, 0=none */ + +/* Data ROM 0: */ + +#define XTENSA_DATAROM0_VADDR 0x3F400000 /* virtual address */ +#define XTENSA_DATAROM0_PADDR 0x3F400000 /* physical address */ +#define XTENSA_DATAROM0_SIZE 4194304 /* size in bytes */ +#define XTENSA_DATAROM0_ECC_PARITY 0 /* ECC/parity type, 0=none */ +#define XTENSA_DATAROM0_BANKS 1 /* number of banks */ + +/* Data RAM 0: */ +#define XTENSA_DATARAM0_VADDR 0x3FF80000 /* virtual address */ +#define XTENSA_DATARAM0_PADDR 0x3FF80000 /* physical address */ +#define XTENSA_DATARAM0_SIZE 524288 /* size in bytes */ +#define XTENSA_DATARAM0_ECC_PARITY 0 /* ECC/parity type, 0=none */ +#define XTENSA_DATARAM0_BANKS 1 /* number of banks */ + +/* Data RAM 1: */ + +#define XTENSA_DATARAM1_VADDR 0x3F800000 /* virtual address */ +#define XTENSA_DATARAM1_PADDR 0x3F800000 /* physical address */ +#define XTENSA_DATARAM1_SIZE 4194304 /* size in bytes */ +#define XTENSA_DATARAM1_ECC_PARITY 0 /* ECC/parity type, 0=none */ +#define XTENSA_DATARAM1_BANKS 1 /* number of banks */ + +/* XLMI Port 0: */ + +#define XTENSA_XLMI0_VADDR 0x3FF00000 /* virtual address */ +#define XTENSA_XLMI0_PADDR 0x3FF00000 /* physical address */ +#define XTENSA_XLMI0_SIZE 524288 /* size in bytes */ +#define XTENSA_XLMI0_ECC_PARITY 0 /* ECC/parity type, 0=none */ + +#define XTENSA_HAVE_IMEM_LOADSTORE 1 /* can load/store to IROM/IRAM*/ + +/* Interrupts and Timers ****************************************************/ + +#define XTENSA_HAVE_INTERRUPTS 1 /* interrupt option */ +#define XTENSA_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */ +#define XTENSA_HAVE_NMI 1 /* non-maskable interrupt */ +#define XTENSA_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */ +#define XTENSA_NUM_TIMERS 3 /* number of CCOMPAREn regs */ +#define XTENSA_NUM_INTERRUPTS 32 /* number of interrupts */ +#define XTENSA_NUM_INTERRUPTS_LOG2 5 /* ceil(log2(NUM_INTERRUPTS)) */ +#define XTENSA_NUM_EXTINTERRUPTS 26 /* num of external interrupts */ +#define XTENSA_INT_NLEVELS 6 /* number of interrupt levels + (not including level zero) */ +#define XTENSA_EXCM_LEVEL 3 /* level masked by PS.EXCM */ + /* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */ + +/* Masks of interrupts at each interrupt level: */ + +#define XTENSA_INTLEVEL1_MASK 0x000637FF +#define XTENSA_INTLEVEL2_MASK 0x00380000 +#define XTENSA_INTLEVEL3_MASK 0x28C08800 +#define XTENSA_INTLEVEL4_MASK 0x53000000 +#define XTENSA_INTLEVEL5_MASK 0x84010000 +#define XTENSA_INTLEVEL6_MASK 0x00000000 +#define XTENSA_INTLEVEL7_MASK 0x00004000 + +/* Masks of interrupts at each range 1..n of interrupt levels: */ + +#define XTENSA_INTLEVEL1_ANDBELOW_MASK 0x000637FF +#define XTENSA_INTLEVEL2_ANDBELOW_MASK 0x003E37FF +#define XTENSA_INTLEVEL3_ANDBELOW_MASK 0x28FEBFFF +#define XTENSA_INTLEVEL4_ANDBELOW_MASK 0x7BFEBFFF +#define XTENSA_INTLEVEL5_ANDBELOW_MASK 0xFFFFBFFF +#define XTENSA_INTLEVEL6_ANDBELOW_MASK 0xFFFFBFFF +#define XTENSA_INTLEVEL7_ANDBELOW_MASK 0xFFFFFFFF + +/* Level of each interrupt: */ + +#define XTENSA_INT0_LEVEL 1 +#define XTENSA_INT1_LEVEL 1 +#define XTENSA_INT2_LEVEL 1 +#define XTENSA_INT3_LEVEL 1 +#define XTENSA_INT4_LEVEL 1 +#define XTENSA_INT5_LEVEL 1 +#define XTENSA_INT6_LEVEL 1 +#define XTENSA_INT7_LEVEL 1 +#define XTENSA_INT8_LEVEL 1 +#define XTENSA_INT9_LEVEL 1 +#define XTENSA_INT10_LEVEL 1 +#define XTENSA_INT11_LEVEL 3 +#define XTENSA_INT12_LEVEL 1 +#define XTENSA_INT13_LEVEL 1 +#define XTENSA_INT14_LEVEL 7 +#define XTENSA_INT15_LEVEL 3 +#define XTENSA_INT16_LEVEL 5 +#define XTENSA_INT17_LEVEL 1 +#define XTENSA_INT18_LEVEL 1 +#define XTENSA_INT19_LEVEL 2 +#define XTENSA_INT20_LEVEL 2 +#define XTENSA_INT21_LEVEL 2 +#define XTENSA_INT22_LEVEL 3 +#define XTENSA_INT23_LEVEL 3 +#define XTENSA_INT24_LEVEL 4 +#define XTENSA_INT25_LEVEL 4 +#define XTENSA_INT26_LEVEL 5 +#define XTENSA_INT27_LEVEL 3 +#define XTENSA_INT28_LEVEL 4 +#define XTENSA_INT29_LEVEL 3 +#define XTENSA_INT30_LEVEL 4 +#define XTENSA_INT31_LEVEL 5 +#define XTENSA_DEBUGLEVEL 6 /* debug interrupt level */ +#define XTENSA_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */ +#define XTENSA_NMILEVEL 7 /* NMI "level" (for use with + * EXCSAVE/EPS/EPC_n, RFI n) */ + +/* Type of each interrupt: */ + +#define XTENSA_INT0_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT1_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT2_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT6_TYPE XTHAL_INTTYPE_TIMER +#define XTENSA_INT7_TYPE XTHAL_INTTYPE_SOFTWARE +#define XTENSA_INT8_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT9_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT10_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XTENSA_INT11_TYPE XTHAL_INTTYPE_PROFILING +#define XTENSA_INT12_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT13_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT14_TYPE XTHAL_INTTYPE_NMI +#define XTENSA_INT15_TYPE XTHAL_INTTYPE_TIMER +#define XTENSA_INT16_TYPE XTHAL_INTTYPE_TIMER +#define XTENSA_INT17_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT18_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT19_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT20_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT21_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT22_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XTENSA_INT23_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT24_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT25_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT26_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT27_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XTENSA_INT28_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XTENSA_INT29_TYPE XTHAL_INTTYPE_SOFTWARE +#define XTENSA_INT30_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XTENSA_INT31_TYPE XTHAL_INTTYPE_EXTERN_LEVEL + +/* Masks of interrupts for each type of interrupt: */ + +#define XTENSA_INTTYPE_MASK_UNCONFIGURED 0x00000000 +#define XTENSA_INTTYPE_MASK_SOFTWARE 0x20000080 +#define XTENSA_INTTYPE_MASK_EXTERN_EDGE 0x50400400 +#define XTENSA_INTTYPE_MASK_EXTERN_LEVEL 0x8FBE333F +#define XTENSA_INTTYPE_MASK_TIMER 0x00018040 +#define XTENSA_INTTYPE_MASK_NMI 0x00004000 +#define XTENSA_INTTYPE_MASK_WRITE_ERROR 0x00000000 +#define XTENSA_INTTYPE_MASK_PROFILING 0x00000800 + +/* Interrupt numbers assigned to specific interrupt sources: */ + +#define XTENSA_TIMER0_INTERRUPT 6 /* CCOMPARE0 */ +#define XTENSA_TIMER1_INTERRUPT 15 /* CCOMPARE1 */ +#define XTENSA_TIMER2_INTERRUPT 16 /* CCOMPARE2 */ +#undef XTENSA_TIMER3_INTERRUPT +#define XTENSA_NMI_INTERRUPT 14 /* non-maskable interrupt */ +#define XTENSA_PROFILING_INTERRUPT 11 /* profiling interrupt */ + +/* Interrupt numbers for levels at which only one interrupt is configured: */ + +#define XTENSA_INTLEVEL7_NUM 14 + +/* (There are many interrupts each at level(s) 1, 2, 3, 4, 5.) */ + +/* External interrupt mapping. + * + * These macros describe how Xtensa processor interrupt numbers + * (as numbered internally, eg. in INTERRUPT and INTENABLE registers) + * map to external BInterrupt pins, for those interrupts + * configured as external (level-triggered, edge-triggered, or NMI). + * See the Xtensa processor databook for more details. + */ + +/* Core interrupt numbers mapped to each EXTERNAL BInterrupt pin number: */ + +#define XTENSA_EXTINT0_NUM 0 /* (intlevel 1) */ +#define XTENSA_EXTINT1_NUM 1 /* (intlevel 1) */ +#define XTENSA_EXTINT2_NUM 2 /* (intlevel 1) */ +#define XTENSA_EXTINT3_NUM 3 /* (intlevel 1) */ +#define XTENSA_EXTINT4_NUM 4 /* (intlevel 1) */ +#define XTENSA_EXTINT5_NUM 5 /* (intlevel 1) */ +#define XTENSA_EXTINT6_NUM 8 /* (intlevel 1) */ +#define XTENSA_EXTINT7_NUM 9 /* (intlevel 1) */ +#define XTENSA_EXTINT8_NUM 10 /* (intlevel 1) */ +#define XTENSA_EXTINT9_NUM 12 /* (intlevel 1) */ +#define XTENSA_EXTINT10_NUM 13 /* (intlevel 1) */ +#define XTENSA_EXTINT11_NUM 14 /* (intlevel 7) */ +#define XTENSA_EXTINT12_NUM 17 /* (intlevel 1) */ +#define XTENSA_EXTINT13_NUM 18 /* (intlevel 1) */ +#define XTENSA_EXTINT14_NUM 19 /* (intlevel 2) */ +#define XTENSA_EXTINT15_NUM 20 /* (intlevel 2) */ +#define XTENSA_EXTINT16_NUM 21 /* (intlevel 2) */ +#define XTENSA_EXTINT17_NUM 22 /* (intlevel 3) */ +#define XTENSA_EXTINT18_NUM 23 /* (intlevel 3) */ +#define XTENSA_EXTINT19_NUM 24 /* (intlevel 4) */ +#define XTENSA_EXTINT20_NUM 25 /* (intlevel 4) */ +#define XTENSA_EXTINT21_NUM 26 /* (intlevel 5) */ +#define XTENSA_EXTINT22_NUM 27 /* (intlevel 3) */ +#define XTENSA_EXTINT23_NUM 28 /* (intlevel 4) */ +#define XTENSA_EXTINT24_NUM 30 /* (intlevel 4) */ +#define XTENSA_EXTINT25_NUM 31 /* (intlevel 5) */ +/* EXTERNAL BInterrupt pin numbers mapped to each core interrupt number: */ +#define XTENSA_INT0_EXTNUM 0 /* (intlevel 1) */ +#define XTENSA_INT1_EXTNUM 1 /* (intlevel 1) */ +#define XTENSA_INT2_EXTNUM 2 /* (intlevel 1) */ +#define XTENSA_INT3_EXTNUM 3 /* (intlevel 1) */ +#define XTENSA_INT4_EXTNUM 4 /* (intlevel 1) */ +#define XTENSA_INT5_EXTNUM 5 /* (intlevel 1) */ +#define XTENSA_INT8_EXTNUM 6 /* (intlevel 1) */ +#define XTENSA_INT9_EXTNUM 7 /* (intlevel 1) */ +#define XTENSA_INT10_EXTNUM 8 /* (intlevel 1) */ +#define XTENSA_INT12_EXTNUM 9 /* (intlevel 1) */ +#define XTENSA_INT13_EXTNUM 10 /* (intlevel 1) */ +#define XTENSA_INT14_EXTNUM 11 /* (intlevel 7) */ +#define XTENSA_INT17_EXTNUM 12 /* (intlevel 1) */ +#define XTENSA_INT18_EXTNUM 13 /* (intlevel 1) */ +#define XTENSA_INT19_EXTNUM 14 /* (intlevel 2) */ +#define XTENSA_INT20_EXTNUM 15 /* (intlevel 2) */ +#define XTENSA_INT21_EXTNUM 16 /* (intlevel 2) */ +#define XTENSA_INT22_EXTNUM 17 /* (intlevel 3) */ +#define XTENSA_INT23_EXTNUM 18 /* (intlevel 3) */ +#define XTENSA_INT24_EXTNUM 19 /* (intlevel 4) */ +#define XTENSA_INT25_EXTNUM 20 /* (intlevel 4) */ +#define XTENSA_INT26_EXTNUM 21 /* (intlevel 5) */ +#define XTENSA_INT27_EXTNUM 22 /* (intlevel 3) */ +#define XTENSA_INT28_EXTNUM 23 /* (intlevel 4) */ +#define XTENSA_INT30_EXTNUM 24 /* (intlevel 4) */ +#define XTENSA_INT31_EXTNUM 25 /* (intlevel 5) */ + +/* Exceptions and Vectors ***************************************************/ + +#define XTENSA_XEA_VERSION 2 /* Xtensa Exception Architecture + * number: 1 == XEA1 (old) + * 2 == XEA2 (new) + * 0 == XEAX (extern) or TX */ +#define XTENSA_HAVE_XEA1 0 /* Exception Architecture 1 */ +#define XTENSA_HAVE_XEA2 1 /* Exception Architecture 2 */ +#define XTENSA_HAVE_XEAX 0 /* External Exception Arch. */ +#define XTENSA_HAVE_EXCEPTIONS 1 /* exception option */ +#define XTENSA_HAVE_HALT 0 /* halt architecture option */ +#define XTENSA_HAVE_BOOTLOADER 0 /* boot loader (for TX) */ +#define XTENSA_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */ +#define XTENSA_HAVE_VECTOR_SELECT 1 /* relocatable vectors */ +#define XTENSA_HAVE_VECBASE 1 /* relocatable vectors */ +#define XTENSA_VECBASE_RESET_VADDR 0x40000000 /* VECBASE reset value */ +#define XTENSA_VECBASE_RESET_PADDR 0x40000000 +#define XTENSA_RESET_VECBASE_OVERLAP 0 + +#define XTENSA_RESET_VECTOR0_VADDR 0x50000000 +#define XTENSA_RESET_VECTOR0_PADDR 0x50000000 +#define XTENSA_RESET_VECTOR1_VADDR 0x40000400 +#define XTENSA_RESET_VECTOR1_PADDR 0x40000400 +#define XTENSA_RESET_VECTOR_VADDR 0x40000400 +#define XTENSA_RESET_VECTOR_PADDR 0x40000400 +#define XTENSA_USER_VECOFS 0x00000340 +#define XTENSA_USER_VECTOR_VADDR 0x40000340 +#define XTENSA_USER_VECTOR_PADDR 0x40000340 +#define XTENSA_KERNEL_VECOFS 0x00000300 +#define XTENSA_KERNEL_VECTOR_VADDR 0x40000300 +#define XTENSA_KERNEL_VECTOR_PADDR 0x40000300 +#define XTENSA_DOUBLEEXC_VECOFS 0x000003C0 +#define XTENSA_DOUBLEEXC_VECTOR_VADDR 0x400003C0 +#define XTENSA_DOUBLEEXC_VECTOR_PADDR 0x400003C0 +#define XTENSA_WINDOW_OF4_VECOFS 0x00000000 +#define XTENSA_WINDOW_UF4_VECOFS 0x00000040 +#define XTENSA_WINDOW_OF8_VECOFS 0x00000080 +#define XTENSA_WINDOW_UF8_VECOFS 0x000000C0 +#define XTENSA_WINDOW_OF12_VECOFS 0x00000100 +#define XTENSA_WINDOW_UF12_VECOFS 0x00000140 +#define XTENSA_WINDOW_VECTORS_VADDR 0x40000000 +#define XTENSA_WINDOW_VECTORS_PADDR 0x40000000 +#define XTENSA_INTLEVEL2_VECOFS 0x00000180 +#define XTENSA_INTLEVEL2_VECTOR_VADDR 0x40000180 +#define XTENSA_INTLEVEL2_VECTOR_PADDR 0x40000180 +#define XTENSA_INTLEVEL3_VECOFS 0x000001C0 +#define XTENSA_INTLEVEL3_VECTOR_VADDR 0x400001C0 +#define XTENSA_INTLEVEL3_VECTOR_PADDR 0x400001C0 +#define XTENSA_INTLEVEL4_VECOFS 0x00000200 +#define XTENSA_INTLEVEL4_VECTOR_VADDR 0x40000200 +#define XTENSA_INTLEVEL4_VECTOR_PADDR 0x40000200 +#define XTENSA_INTLEVEL5_VECOFS 0x00000240 +#define XTENSA_INTLEVEL5_VECTOR_VADDR 0x40000240 +#define XTENSA_INTLEVEL5_VECTOR_PADDR 0x40000240 +#define XTENSA_INTLEVEL6_VECOFS 0x00000280 +#define XTENSA_INTLEVEL6_VECTOR_VADDR 0x40000280 +#define XTENSA_INTLEVEL6_VECTOR_PADDR 0x40000280 +#define XTENSA_DEBUG_VECOFS XTENSA_INTLEVEL6_VECOFS +#define XTENSA_DEBUG_VECTOR_VADDR XTENSA_INTLEVEL6_VECTOR_VADDR +#define XTENSA_DEBUG_VECTOR_PADDR XTENSA_INTLEVEL6_VECTOR_PADDR +#define XTENSA_NMI_VECOFS 0x000002C0 +#define XTENSA_NMI_VECTOR_VADDR 0x400002C0 +#define XTENSA_NMI_VECTOR_PADDR 0x400002C0 +#define XTENSA_INTLEVEL7_VECOFS XTENSA_NMI_VECOFS +#define XTENSA_INTLEVEL7_VECTOR_VADDR XTENSA_NMI_VECTOR_VADDR +#define XTENSA_INTLEVEL7_VECTOR_PADDR XTENSA_NMI_VECTOR_PADDR + +/* Debug Module *************************************************************/ + +/* Misc */ + +#define XTENSA_HAVE_DEBUG_ERI 1 /* ERI to debug module */ +#define XTENSA_HAVE_DEBUG_APB 1 /* APB to debug module */ +#define XTENSA_HAVE_DEBUG_JTAG 1 /* JTAG to debug module */ + +/* On-Chip Debug (OCD) */ + +#define XTENSA_HAVE_OCD 1 /* OnChipDebug option */ +#define XTENSA_NUM_IBREAK 2 /* number of IBREAKn regs */ +#define XTENSA_NUM_DBREAK 2 /* number of DBREAKn regs */ +#define XTENSA_HAVE_OCD_DIR_ARRAY 0 /* faster OCD option (to LX4) */ +#define XTENSA_HAVE_OCD_LS32DDR 1 /* L32DDR/S32DDR (faster OCD) */ + +/* TRAX (in core) */ + +#define XTENSA_HAVE_TRAX 1 /* TRAX in debug module */ +#define XTENSA_TRAX_MEM_SIZE 16384 /* TRAX memory size in bytes */ +#define XTENSA_TRAX_MEM_SHAREABLE 1 /* start/end regs; ready sig. */ +#define XTENSA_TRAX_ATB_WIDTH 32 /* ATB width (bits), 0=no ATB */ +#define XTENSA_TRAX_TIME_WIDTH 0 /* timestamp bitwidth, 0=none */ + +/* Perf counters */ + +#define XTENSA_NUM_PERF_COUNTERS 2 /* performance counters */ + +/* MMU **********************************************************************/ + +#define XTENSA_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */ +#define XTENSA_HAVE_SPANNING_WAY 1 /* one way maps I+D 4GB vaddr */ +#define XTENSA_SPANNING_WAY 0 /* TLB spanning way number */ +#define XTENSA_HAVE_IDENTITY_MAP 1 /* vaddr == paddr always */ +#define XTENSA_HAVE_CACHEATTR 0 /* CACHEATTR register present */ +#define XTENSA_HAVE_MIMIC_CACHEATTR 1 /* region protection */ +#define XTENSA_HAVE_XLT_CACHEATTR 0 /* region prot. w/translation */ +#define XTENSA_HAVE_PTP_MMU 0 /* full MMU (with page table + * [autorefill] and protection) + * usable for an MMU-based OS */ +/* If none of the above last 4 are set, it's a custom TLB configuration. */ + +#define XTENSA_MMU_ASID_BITS 0 /* number of bits in ASIDs */ +#define XTENSA_MMU_RINGS 1 /* number of rings (1..4) */ +#define XTENSA_MMU_RING_BITS 0 /* num of bits in RING field */ + +#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */ + +#endif /* __ARCH_XTENSA_INCLUDE_ESP32_CORE_ISA_H */ diff --git a/arch/xtensa/include/irq.h b/arch/xtensa/include/irq.h index a218a1f1673..8960754da2c 100644 --- a/arch/xtensa/include/irq.h +++ b/arch/xtensa/include/irq.h @@ -48,6 +48,7 @@ #include #include +#include /* Include architecture-specific IRQ definitions */ @@ -72,32 +73,31 @@ /* IRQ Stack Frame Format. Each value is a uint32_t register index */ -#define REG_EXIT (0) /* Exit point for dispatch */ -#define REG_PC (1) /* Return PC */ -#define REG_PS (2) /* Return PS */ -#define REG_A0 (3) -#define REG_A1 (4) /* Stack pointer before interrupt */ -#define REG_A2 (5) -#define REG_A3 (6) -#define REG_A4 (7) -#define REG_A5 (8) -#define REG_A6 (9) -#define REG_A7 (10) -#define REG_A8 (11) -#define REG_A9 (12) -#define REG_A10 (13) -#define REG_A11 (14) -#define REG_A12 (15) -#define REG_A13 (16) -#define REG_A14 (17) -#define REG_A15 (18) -#define REG_SAR (19) -#define REG_EXCCAUSE (20) -#define REG_EXCVADDR (21) +#define REG_PC (0) /* Return PC */ +#define REG_PS (1) /* Return PS */ +#define REG_A0 (2) +#define REG_A1 (3) /* Stack pointer before interrupt */ +#define REG_A2 (4) +#define REG_A3 (5) +#define REG_A4 (6) +#define REG_A5 (7) +#define REG_A6 (8) +#define REG_A7 (9) +#define REG_A8 (10) +#define REG_A9 (11) +#define REG_A10 (12) +#define REG_A11 (13) +#define REG_A12 (14) +#define REG_A13 (15) +#define REG_A14 (16) +#define REG_A15 (17) +#define REG_SAR (18) +#define REG_EXCCAUSE (19) +#define REG_EXCVADDR (20) -#define _REG_LOOPS_START (22) +#define _REG_LOOPS_START (21) -#ifdef CONFIG_XTENSA_HAVE_LOOPS +#ifdef XTENSA_HAVE_LOOPS # define REG_LBEG (_REG_LOOPS_START + 0) # define REG_LEND (_REG_LOOPS_START + 1) # define REG_LCOUNT (_REG_LOOPS_START + 2) diff --git a/arch/xtensa/src/common/xtensa_context.S b/arch/xtensa/src/common/xtensa_context.S index deeca557353..e1a21412e88 100644 --- a/arch/xtensa/src/common/xtensa_context.S +++ b/arch/xtensa/src/common/xtensa_context.S @@ -31,6 +31,8 @@ * ****************************************************************************/ + .file "xtensa_context.S" + /* XTENSA CONTEXT SAVE AND RESTORE ROUTINES * * Low-level Call0 functions for handling generic context save and restore @@ -57,14 +59,15 @@ ****************************************************************************/ #include +#include #include #ifdef CONFIG_XTENSA_USE_OVLY # include #endif -#warning REVIST XCHAL_EXTRA_SA_SIZE is not yet provided -#define XCHAL_EXTRA_SA_SIZE 0 /* REMOVE ME */ +#warning REVIST XTENSA_EXTRA_SA_SIZE is not yet provided +#define XTENSA_EXTRA_SA_SIZE 0 /* REMOVE ME */ /**************************************************************************** * Public Functions @@ -155,7 +158,7 @@ _xtensa_context_save: rsr a3, SAR s32i a3, sp, (4 * REG_SAR) -#ifdef CONFIG_XTENSA_HAVE_LOOPS +#ifdef XTENSA_HAVE_LOOPS rsr a3, LBEG s32i a3, sp, (4 * REG_LBEG) rsr a3, LEND @@ -172,7 +175,7 @@ _xtensa_context_save: s32i a3, sp, (4 * REG_VPRI) #endif -#if XCHAL_EXTRA_SA_SIZE > 0 || !defined(CONFIG_XTENSA_CALL0_ABI) +#if XTENSA_EXTRA_SA_SIZE > 0 || !defined(CONFIG_XTENSA_CALL0_ABI) mov a9, a0 /* Preserve ret addr */ #endif @@ -180,7 +183,7 @@ _xtensa_context_save: /* To spill the reg windows, temp. need pre-interrupt stack ptr and * a4-15. Need to save a9,12,13 temporarily (in frame temps) and * recover originals. Interrupts need to be disabled below - * CONFIG_XTENSA_EXCM_LEVEL and window overflow and underflow exceptions + * XTENSA_EXCM_LEVEL and window overflow and underflow exceptions * disabled (assured by PS.EXCM == 1). */ @@ -210,7 +213,7 @@ _xtensa_context_save: l32i a9, sp, (4 * REG_TMP2) #endif -#if XCHAL_EXTRA_SA_SIZE > 0 +#if XTENSA_EXTRA_SA_SIZE > 0 /* NOTE: Normally the xthal_save_extra_nw macro only affects address * registers a2-a5. It is theoretically possible for Xtensa processor * designers to write TIE that causes more address registers to be @@ -221,14 +224,14 @@ _xtensa_context_save: */ addi a2, sp, (4 * REG_EXTRA) /* Where to save it */ -#if XCHAL_EXTRA_SA_ALIGN > 16 - movi a3, -XCHAL_EXTRA_SA_ALIGN +#if XTENSA_EXTRA_SA_ALIGN > 16 + movi a3, -XTENSA_EXTRA_SA_ALIGN and a2, a2, a3 /* Align dynamically >16 bytes */ #endif call0 xthal_save_extra_nw /* Destroys a0,2,3,4,5 */ #endif -#if XCHAL_EXTRA_SA_SIZE > 0 || !defined(CONFIG_XTENSA_CALL0_ABI) +#if XTENSA_EXTRA_SA_SIZE > 0 || !defined(CONFIG_XTENSA_CALL0_ABI) mov a0, a9 /* Retrieve ret addr */ #endif @@ -288,7 +291,7 @@ _xtensa_full_context_restore: _xtensa_context_restore: -#if XCHAL_EXTRA_SA_SIZE > 0 +#if XTENSA_EXTRA_SA_SIZE > 0 /* NOTE: Normally the xthal_restore_extra_nw macro only affects address * registers a2-a5. It is theoretically possible for Xtensa processor * designers to write TIE that causes more address registers to be @@ -301,15 +304,15 @@ _xtensa_context_restore: mov a13, a0 /* Preserve ret addr */ addi a2, sp, (4 * REG_EXTRA) /* Where to find it */ -#if XCHAL_EXTRA_SA_ALIGN > 16 - movi a3, -XCHAL_EXTRA_SA_ALIGN +#if XTENSA_EXTRA_SA_ALIGN > 16 + movi a3, -XTENSA_EXTRA_SA_ALIGN and a2, a2, a3 /* Align dynamically >16 bytes */ #endif call0 xthal_restore_extra_nw /* Destroys a0,2,3,4,5 */ mov a0, a13 /* Retrieve ret addr */ #endif -#ifdef CONFIG_XTENSA_HAVE_LOOPS +#ifdef XTENSA_HAVE_LOOPS l32i a2, sp, (4 * REG_LBEG) l32i a3, sp, (4 * REG_LEND) wsr a2, LBEG diff --git a/arch/xtensa/src/common/xtensa_coproc.S b/arch/xtensa/src/common/xtensa_coproc.S index 92ce8fbaf02..7e9843c7960 100644 --- a/arch/xtensa/src/common/xtensa_coproc.S +++ b/arch/xtensa/src/common/xtensa_coproc.S @@ -31,367 +31,15 @@ * ****************************************************************************/ -/* XTENSA CONTEXT SAVE AND RESTORE ROUTINES - * - * Low-level Call0 functions for handling generic context save and restore of - * registers not specifically addressed by the interrupt vectors and handlers. - * Those registers (not handled by these functions) are PC, PS, A0, A1 (SP). - * Except for the calls to RTOS functions, this code is generic to Xtensa. - * - * Note that in Call0 ABI, interrupt handlers are expected to preserve the callee- - * save regs (A12-A15), which is always the case if the handlers are coded in C. - * However A12, A13 are made available as scratch registers for interrupt dispatch - * code, so are presumed saved anyway, and are always restored even in Call0 ABI. - * Only A14, A15 are truly handled as callee-save regs. - * - * Because Xtensa is a configurable architecture, this port supports all user - * generated configurations (except restrictions stated in the release notes). - * This is accomplished by conditional compilation using macros and functions - * defined in the Xtensa HAL (hardware adaptation layer) for your configuration. - * Only the processor state included in your configuration is saved and restored, - * including any processor state added by user configuration options or TIE. - */ + .file "xtensa_coproc.S" /**************************************************************************** * Included Files ****************************************************************************/ -#include "xtensa_context.h" - -#ifdef CONFIG_XTENSA_USE_OVLY -# include -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ .text -/**************************************************************************** - * Name: _xt_coproc_init - * - * Description: - * Initializes global co-processor management data, setting all co- - * processors to "unowned". Leaves CPENABLE as it found it (does NOT clear - * it). - * - * Called during initialization of the RTOS, before any threads run. - * - * This may be called from normal Xtensa single-threaded application code - * which might use co-processors. The Xtensa run-time initialization enables - * all co-processors. They must remain enabled here, else a co-processor - * exception might occur outside of a thread, which the exception handler - * doesn't expect. - * - * Entry Conditions: - * - Xtensa single-threaded run-time environment is in effect. - * No thread is yet running. - * - * Exit conditions: - * - None. - * - * Obeys ABI conventions per prototype: - * void _xt_coproc_init(void) - * - ****************************************************************************/ - -#if CONFIG_XTENSA_NCOPROCESSORS > 0 - .global _xt_coproc_init - .type _xt_coproc_init,@function - .align 4 - .literal_position - .align 4 -_xt_coproc_init: - ENTRY0 - - /* Initialize thread co-processor ownerships to 0 (unowned). */ - - movi a2, _xt_coproc_owner_sa /* a2 = base of owner array */ - addi a3, a2, (XCHAL_CP_MAX*portNUM_PROCESSORS) << 2 /* a3 = top+1 of owner array */ - movi a4, 0 /* a4 = 0 (unowned) */ -1: s32i a4, a2, 0 - addi a2, a2, 4 - bltu a2, a3, 1b - - RET0 -#endif - -/**************************************************************************** - * Name: _xt_coproc_release - * - * Description: - * Releases any and all co-processors owned by a given thread. The thread - * is identified by it's co-processor state save area defined in - * xtensa_context.h. - * - * Must be called before a thread's co-proc save area is deleted to avoid - * memory corruption when the exception handler tries to save the state. - * May be called when a thread terminates or completes but does not delete - * the co-proc save area, to avoid the exception handler having to save - * the thread's co-proc state before another thread can use it - * (optimization). - * - * Entry Conditions: - * - A2 = Pointer to base of co-processor state save area. - * - * Exit conditions: - * - None. - * - * Obeys ABI conventions per prototype: - * void _xt_coproc_release(void * coproc_sa_base) - * - ****************************************************************************/ - -#if CONFIG_XTENSA_NCOPROCESSORS > 0 - .global _xt_coproc_release - .type _xt_coproc_release,@function - .align 4 - .literal_position - .align 4 -_xt_coproc_release: - ENTRY0 /* a2 = base of save area */ - - getcoreid a5 - movi a3, XCHAL_CP_MAX << 2 - mull a5, a5, a3 - movi a3, _xt_coproc_owner_sa /* a3 = base of owner array */ - add a3, a3, a5 - - addi a4, a3, XCHAL_CP_MAX << 2 /* a4 = top+1 of owner array */ - movi a5, 0 /* a5 = 0 (unowned) */ - - rsil a6, CONFIG_XTENSA_EXCM_LEVEL /* Lock interrupts */ - -1: l32i a7, a3, 0 /* a7 = owner at a3 */ - bne a2, a7, 2f /* if (coproc_sa_base == owner) */ - s32i a5, a3, 0 /* owner = unowned */ -2: addi a3, a3, 1 << 2 /* a3 = next entry in owner array */ - bltu a3, a4, 1b /* Repeat until end of array */ - -3: wsr a6, PS /* Restore interrupts */ - - RET0 -#endif - -/**************************************************************************** - * Name: _xt_coproc_savecs - * - * Description: - * If there is a current thread and it has a coprocessor state save area, - * then save all callee-saved state into this area. This function is called - * from the solicited context switch handler. It calls a system-specific - * function to get the coprocessor save area base address. - * - * Entry conditions: - * - The thread being switched out is still the current thread. - * - CPENABLE state reflects which coprocessors are active. - * - Registers have been saved/spilled already. - * - * Exit conditions: - * - All necessary CP callee-saved state has been saved. - * - Registers a2-a7, a13-a15 have been trashed. - * - * Must be called from assembly code only, using CALL0. - * - ****************************************************************************/ - -#if CONFIG_XTENSA_NCOPROCESSORS > 0 - .extern _xt_coproc_sa_offset /* external reference */ - .global _xt_coproc_savecs - .type _xt_coproc_savecs,@function - .align 4 - .literal_position - .align 4 -_xt_coproc_savecs: - - /* At entry, CPENABLE should be showing which CPs are enabled. */ - - rsr a2, CPENABLE /* a2 = which CPs are enabled */ - beqz a2, .Ldone /* quick exit if none */ - mov a14, a0 /* save return address */ - call0 XT_RTOS_CP_STATE /* get address of CP save area */ - mov a0, a14 /* restore return address */ - beqz a15, .Ldone /* if none then nothing to do */ - s16i a2, a15, XT_CP_CS_ST /* save mask of CPs being stored */ - movi a13, _xt_coproc_sa_offset /* array of CP save offsets */ - l32i a15, a15, XT_CP_ASA /* a15 = base of aligned save area */ - -#if XCHAL_CP0_SA_SIZE - bbci.l a2, 0, 2f /* CP 0 not enabled */ - l32i a14, a13, 0 /* a14 = _xt_coproc_sa_offset[0] */ - add a3, a14, a15 /* a3 = save area for CP 0 */ - xchal_cp0_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP1_SA_SIZE - bbci.l a2, 1, 2f /* CP 1 not enabled */ - l32i a14, a13, 4 /* a14 = _xt_coproc_sa_offset[1] */ - add a3, a14, a15 /* a3 = save area for CP 1 */ - xchal_cp1_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP2_SA_SIZE - bbci.l a2, 2, 2f - l32i a14, a13, 8 - add a3, a14, a15 - xchal_cp2_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP3_SA_SIZE - bbci.l a2, 3, 2f - l32i a14, a13, 12 - add a3, a14, a15 - xchal_cp3_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP4_SA_SIZE - bbci.l a2, 4, 2f - l32i a14, a13, 16 - add a3, a14, a15 - xchal_cp4_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP5_SA_SIZE - bbci.l a2, 5, 2f - l32i a14, a13, 20 - add a3, a14, a15 - xchal_cp5_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP6_SA_SIZE - bbci.l a2, 6, 2f - l32i a14, a13, 24 - add a3, a14, a15 - xchal_cp6_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP7_SA_SIZE - bbci.l a2, 7, 2f - l32i a14, a13, 28 - add a3, a14, a15 - xchal_cp7_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -.Ldone: - ret -#endif - -/**************************************************************************** - * Name: _xt_coproc_restorecs - * - * Description: - * Restore any callee-saved coprocessor state for the incoming thread. - * This function is called from coprocessor exception handling, when - * giving ownership to a thread that solicited a context switch earlier. - * It calls a system-specific function to get the coprocessor save area - * base address. - * - * Entry conditions: - * - The incoming thread is set as the current thread. - * - CPENABLE is set up correctly for all required coprocessors. - * - a2 = mask of coprocessors to be restored. - * - * Exit conditions: - * - All necessary CP callee-saved state has been restored. - * - CPENABLE - unchanged. - * - Registers a2-a7, a13-a15 have been trashed. - * - * Must be called from assembly code only, using CALL0. - * - ****************************************************************************/ - -#if CONFIG_XTENSA_NCOPROCESSORS > 0 - .global _xt_coproc_restorecs - .type _xt_coproc_restorecs,@function - .align 4 - .literal_position - .align 4 -_xt_coproc_restorecs: - - mov a14, a0 /* Save return address */ - call0 XT_RTOS_CP_STATE /* Get address of CP save area */ - mov a0, a14 /* Restore return address */ - beqz a15, .Ldone2 /* If none then nothing to do */ - l16ui a3, a15, XT_CP_CS_ST /* a3 = which CPs have been saved */ - xor a3, a3, a2 /* Clear the ones being restored */ - s32i a3, a15, XT_CP_CS_ST /* Update saved CP mask */ - movi a13, _xt_coproc_sa_offset /* Array of CP save offsets */ - l32i a15, a15, XT_CP_ASA /* a15 = base of aligned save area */ - -#if XCHAL_CP0_SA_SIZE - bbci.l a2, 0, 2f /* CP 0 not enabled */ - l32i a14, a13, 0 /* a14 = _xt_coproc_sa_offset[0] */ - add a3, a14, a15 /* a3 = save area for CP 0 */ - xchal_cp0_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP1_SA_SIZE - bbci.l a2, 1, 2f /* CP 1 not enabled */ - l32i a14, a13, 4 /* a14 = _xt_coproc_sa_offset[1] */ - add a3, a14, a15 /* a3 = save area for CP 1 */ - xchal_cp1_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP2_SA_SIZE - bbci.l a2, 2, 2f - l32i a14, a13, 8 - add a3, a14, a15 - xchal_cp2_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP3_SA_SIZE - bbci.l a2, 3, 2f - l32i a14, a13, 12 - add a3, a14, a15 - xchal_cp3_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP4_SA_SIZE - bbci.l a2, 4, 2f - l32i a14, a13, 16 - add a3, a14, a15 - xchal_cp4_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP5_SA_SIZE - bbci.l a2, 5, 2f - l32i a14, a13, 20 - add a3, a14, a15 - xchal_cp5_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP6_SA_SIZE - bbci.l a2, 6, 2f - l32i a14, a13, 24 - add a3, a14, a15 - xchal_cp6_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP7_SA_SIZE - bbci.l a2, 7, 2f - l32i a14, a13, 28 - add a3, a14, a15 - xchal_cp7_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -.Ldone2: - ret - -#endif diff --git a/arch/xtensa/src/common/xtensa_dumpstate.c b/arch/xtensa/src/common/xtensa_dumpstate.c index 97128013cf9..8096e887f11 100644 --- a/arch/xtensa/src/common/xtensa_dumpstate.c +++ b/arch/xtensa/src/common/xtensa_dumpstate.c @@ -46,7 +46,9 @@ #include #include + #include +#include #include "sched/sched.h" #include "xtensa.h" @@ -125,7 +127,7 @@ static inline void xtensa_registerdump(void) (unsigned long)g_current_regs[REG_EXIT], (unsigned long)g_current_regs[REG_EXCCAUSE], (unsigned long)g_current_regs[REG_EXCVADDR]); -#ifdef CONFIG_XTENSA_HAVE_LOOPS +#ifdef XTENSA_HAVE_LOOPS _alert(" LBEG: %08lx LEND: %08lx LCNT: %08lx\n", (unsigned long)g_current_regs[REG_LBEG], (unsigned long)g_current_regs[REG_LEND], diff --git a/arch/xtensa/src/common/xtensa_initialstate.c b/arch/xtensa/src/common/xtensa_initialstate.c index d447f49ad22..dab7af55cdd 100644 --- a/arch/xtensa/src/common/xtensa_initialstate.c +++ b/arch/xtensa/src/common/xtensa_initialstate.c @@ -45,15 +45,11 @@ #include #include +#include #include "xtensa.h" #include "xtensa_corebits.h" -/* Temporary for clean compile */ - -#warning REVISIT _xt_user_exit -void _xt_user_exit(void); - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -89,7 +85,6 @@ void up_initial_state(struct tcb_s *tcb) xcp->regs[REG_PC] = (uint32_t)tcb->start; /* Task entrypoint */ xcp->regs[REG_A0] = 0; /* To terminate GDB backtrace */ xcp->regs[REG_A1] = (uint32_t)tcb->adj_stack_ptr; /* Physical top of stack frame */ - xcp->regs[REG_EXIT] = (uint32_t)_xt_user_exit; /* User exception exit dispatcher */ /* Set initial PS to int level 0, EXCM disabled ('rfe' will enable), user * mode. @@ -122,7 +117,7 @@ void up_initial_state(struct tcb_s *tcb) ptr = (uint32_t *)(((uint32_t)tcb->adj_stack_ptr - XT_CP_SIZE) & ~0xf); ptr[0] = 0; ptr[1] = 0; - ptr[2] = (((uint32_t)ptr) + 12 + XCHAL_TOTAL_SA_ALIGN - 1) & -XCHAL_TOTAL_SA_ALIGN; + ptr[2] = (((uint32_t)ptr) + 12 + XTENSA_TOTAL_SA_ALIGN - 1) & -XTENSA_TOTAL_SA_ALIGN; #endif #endif /* REVISIT */ } diff --git a/arch/xtensa/src/common/xtensa_inthandlers.S b/arch/xtensa/src/common/xtensa_inthandlers.S new file mode 100644 index 00000000000..0eee1a2e74d --- /dev/null +++ b/arch/xtensa/src/common/xtensa_inthandlers.S @@ -0,0 +1,512 @@ +/**************************************************************************** + * arch/xtensa/src/common/xtensa_inthandlers.S + * + * Adapted from use in NuttX by: + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Derives from logic originally provided by Cadence Design Systems Inc. + * + * Copyright (c) 2006-2015 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ****************************************************************************/ + + .file "xtensa_inthandlers.S" + +/* NOTES on the use of 'call0' for long jumps instead of 'j': + * + * 1. This file should be assembled with the -mlongcalls option to xt-xcc. + * + * 2. The -mlongcalls compiler option causes 'call0 dest' to be expanded to + * a sequence 'l32r a0, dest' 'callx0 a0' which works regardless of the + * distance from the call to the destination. The linker then relaxes + * it back to 'call0 dest' if it determines that dest is within range. + * This allows more flexibility in locating code without the performance + * overhead of the 'l32r' literal data load in cases where the destination + * is in range of 'call0'. There is an additional benefit in that 'call0' + * has a longer range than 'j' due to the target being word-aligned, so + * the 'l32r' sequence is less likely needed. + * + * 3. The use of 'call0' with -mlongcalls requires that register a0 not be + * live at the time of the call, which is always the case for a function + * call but needs to be ensured if 'call0' is used as a jump in lieu of 'j'. + * + * 4. This use of 'call0' is independent of the C function call ABI. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "xtensa_specregs.h" +#include "xtensa_macros.h" +#include "xtensa_timer.h" + +/**************************************************************************** + * Assembly Language Macros + ****************************************************************************/ + +/* Macro extract_msb - return the input with only the highest bit set. + * + * Input : "ain" - Input value, clobbered. + * Output : "aout" - Output value, has only one bit set, MSB of "ain". + * The two arguments must be different AR registers. + */ + + .macro extract_msb aout ain +1: + addi \aout, \ain, -1 /* aout = ain - 1 */ + and \ain, \ain, \aout /* ain = ain & aout */ + bnez \ain, 1b /* repeat until ain == 0 */ + addi \aout, \aout, 1 /* return aout + 1 */ + .endm + +/* Macro dispatch_c_isr - dispatch interrupts to user ISRs. + * This will dispatch to user handlers (if any) that are registered in the + * XTOS dispatch table (_xtos_interrupt_table). These handlers would have + * been registered by calling _xtos_set_interrupt_handler(). There is one + * exception - the timer interrupt used by the OS will not be dispatched + * to a user handler - this must be handled by the caller of this macro. + * + * Level triggered and software interrupts are automatically deasserted by + * this code. + * + * ASSUMPTIONS: + * - PS.INTLEVEL is set to "level" at entry + * - PS.EXCM = 0, C calling enabled + * + * NOTE: This macro will use registers a0 and a2-a6. The arguments are: + * level -- interrupt level + * mask -- interrupt bitmask for this level + */ + + .macro dispatch_c_isr level mask + + /* Get mask of pending, enabled interrupts at this level into a2. */ + +.L_xt_user_int_&level&: + rsr a2, INTENABLE + rsr a3, INTERRUPT + movi a4, \mask + and a2, a2, a3 + and a2, a2, a4 + beqz a2, 9f /* Nothing to do */ + + /* This bit of code provides a nice debug backtrace in the debugger. + * It does take a few more instructions, so undef XT_DEBUG_BACKTRACE + * if you want to save the cycles. + * / + +#if XT_DEBUG_BACKTRACE +#ifndef CONFIG_XTENSA_CALL0_ABI + rsr a0, EPC_1 + \level - 1 /* Return address */ + movi a4, 0xC0000000 /* Constant with top 2 bits set (call size) */ + or a0, a0, a4 /* Set top 2 bits */ + addx2 a0, a4, a0 /* Clear top bit -- simulating call4 size */ +#endif +#endif + +#ifdef XT_INTEXC_HOOKS + /* Call interrupt hook if present to (pre)handle interrupts. */ + + movi a4, _xt_intexc_hooks + l32i a4, a4, \level << 2 + beqz a4, 2f + +#ifdef CONFIG_XTENSA_CALL0_ABI + callx0 a4 + beqz a2, 9f +#else + mov a6, a2 + callx4 a4 + beqz a6, 9f + mov a2, a6 +#endif +2: +#endif + + /* Now look up in the dispatch table and call user ISR if any. */ + /* If multiple bits are set then MSB has highest priority. */ + + extract_msb a4, a2 /* a4 = MSB of a2, a2 trashed */ + +#ifdef CONFIG_XTENSA_USE_SWPRI + /* Enable all interrupts at this level that are numerically higher + * than the one we just selected, since they are treated as higher + * priority. + */ + + movi a3, \mask /* a3 = all interrupts at this level */ + add a2, a4, a4 /* a2 = a4 << 1 */ + addi a2, a2, -1 /* a2 = mask of 1's <= a4 bit */ + and a2, a2, a3 /* a2 = mask of all bits <= a4 at this level */ + movi a3, _xt_intdata + l32i a6, a3, 4 /* a6 = _xt_vpri_mask */ + neg a2, a2 + addi a2, a2, -1 /* a2 = mask to apply */ + and a5, a6, a2 /* mask off all bits <= a4 bit */ + s32i a5, a3, 4 /* update _xt_vpri_mask */ + rsr a3, INTENABLE + and a3, a3, a2 /* mask off all bits <= a4 bit */ + wsr a3, INTENABLE + rsil a3, \level - 1 /* lower interrupt level by 1 */ +#endif + + movi a3, XT_TIMER_INTEN /* a3 = timer interrupt bit */ + wsr a4, INTCLEAR /* Clear sw or edge-triggered interrupt */ + beq a3, a4, 7f /* If timer interrupt then skip table */ + + find_ms_setbit a3, a4, a3, 0 /* a3 = interrupt number */ + + movi a4, _xt_interrupt_table + addx8 a3, a3, a4 /* a3 = address of interrupt table entry */ + l32i a4, a3, XIE_HANDLER /* a4 = handler address */ + +#ifdef CONFIG_XTENSA_CALL0_ABI + mov a12, a6 /* Save in callee-saved reg */ + l32i a2, a3, XIE_ARG /* a2 = handler arg */ + callx0 a4 /* call handler */ + mov a2, a12 +#else + mov a2, a6 /* Save in windowed reg */ + l32i a6, a3, XIE_ARG /* a6 = handler arg */ + callx4 a4 /* Call handler */ +#endif + +#ifdef CONFIG_XTENSA_USE_SWPRI + j 8f +#else + j .L_xt_user_int_&level& /* Check for more interrupts */ +#endif + +7: + + .ifeq XT_TIMER_INTPRI - \level +.L_xt_user_int_timer_&level&: + /* Interrupt handler for the RTOS tick timer if at this level. + We'll be reading the interrupt state again after this call + so no need to preserve any registers except a6 (vpri_mask). + */ + +#ifdef CONFIG_XTENSA_CALL0_ABI + mov a12, a6 + call0 XT_RTOS_TIMER_INT + mov a2, a12 +#else + mov a2, a6 + call4 XT_RTOS_TIMER_INT +#endif + .endif + +#ifdef CONFIG_XTENSA_USE_SWPRI + j 8f +#else + j .L_xt_user_int_&level& /* check for more interrupts */ +#endif + +#ifdef CONFIG_XTENSA_USE_SWPRI +8: + /* Restore old value of _xt_vpri_mask from a2. Also update INTENABLE from + virtual _xt_intenable which _could_ have changed during interrupt + processing. */ + + movi a3, _xt_intdata + l32i a4, a3, 0 /* a4 = _xt_intenable */ + s32i a2, a3, 4 /* update _xt_vpri_mask */ + and a4, a4, a2 /* a4 = masked intenable */ + wsr a4, INTENABLE /* update INTENABLE */ +#endif + +9: + /* done */ + + .endm + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * MEDIUM PRIORITY (LEVEL 2+) INTERRUPT VECTORS AND LOW LEVEL HANDLERS. + * + * C Prototype: + * void _xtensa_levelN_handler(void) + * + * Description: + * Medium priority interrupts are by definition those with priority greater + * than 1 and not greater than XTENSA_EXCM_LEVEL. These are disabled + * by setting PS.EXCM and therefore can easily support a C environment for + * handlers in C, and interact safely with NuttX. + * + * Each vector goes at a predetermined location according to the Xtensa + * hardware configuration, which is ensured by its placement in a special + * section known to the NuttX linker script. The vector logic performs + * the minimum necessary operations before jumping to the handler via + * a CALL0 instruction. See "NOTES on the use of call0 ..." above. + * + * The corresponding handler sets up the appropriate stack frame, saves + * a few vector-specific registers and calls _xtensa_full_context_save() + * to save the rest of the interrupted context. It then calls the C + * logic to decode the specific interrupt source and dispatch to the + * appropriate C interrupt handler. + * + ****************************************************************************/ + +#if XTENSA_EXCM_LEVEL >= 2 + .section .iram1,"ax" + .type _xtensa_level2_handler,@function + .align 4 +_xtensa_level2_handler: + mov a0, sp /* sp == a1 */ + addi sp, sp, -(4 * REG_FRMSZ) /* Allocate interrupt stack frame */ + s32i a0, sp, (4 * REG_A1) /* Save pre-interrupt SP */ + rsr a0, EPS_2 /* Save interruptee's PS */ + s32i a0, sp, (4 * REG_PS) + rsr a0, EPC_2 /* Save interruptee's PC */ + s32i a0, sp, (4 * REG_PC) + rsr a0, EXCSAVE_2 /* Save interruptee's a0 */ + s32i a0, sp, (4 * REG_A0) + + /* Save rest of interrupt context and enter RTOS. */ + + call0 _xtensa_full_context_save /* Save full register state */ + + /* Set up PS for C, enable interrupts above this level and clear EXCM. */ + +#ifdef CONFIG_XTENSA_CALL0_ABI + movi a0, PS_INTLEVEL(2) | PS_UM + #else + movi a0, PS_INTLEVEL(2) | PS_UM | PS_WOE +#endif + wsr a0, PS + rsync + + /* Decode and dispatch the interrupt. In the event of an interrupt + * level context xtensa_int_decode() will return a pointer to the new + * register state in A2. + */ + + dispatch_c_isr 2 XTENSA_INTLEVEL2_MASK + + /* Restore registers in preparation to return from interrupt */ + + call0 _xtensa_int_exit /* does not return directly here */ + + /* Restore only level-specific regs (the rest were already restored) */ + + l32i a0, sp, (4 * REG_PS) /* retrieve interruptee's PS */ + wsr a0, EPS_2 + l32i a0, sp, (4 * REG_PC) /* retrieve interruptee's PC */ + wsr a0, EPC_2 + l32i a0, sp, (4 * REG_A0) /* retrieve interruptee's A0 */ + l32i sp, sp, (4 * REG_A1) /* remove interrupt stack frame */ + rsync /* Ensure EPS and EPC written */ + + /* Return from interrupt. RFI restores the PS from EPS_2 and jumps to + * the address in EPC_2. + */ + + rfi 2 + +#endif /* XTENSA_EXCM_LEVEL >= 2 */ + +/******************************************************************************* + +HIGH PRIORITY (LEVEL > XTENSA_EXCM_LEVEL) INTERRUPT VECTORS AND HANDLERS + +High priority interrupts are by definition those with priorities greater +than XTENSA_EXCM_LEVEL. This includes non-maskable (NMI). High priority +interrupts cannot interact with the RTOS, that is they must save all regs +they use and not call any RTOS function. + +A further restriction imposed by the Xtensa windowed architecture is that +high priority interrupts must not modify the stack area even logically +"above" the top of the interrupted stack (they need to provide their +own stack or static save area). + +Cadence Design Systems recommends high priority interrupt handlers be coded in assembly +and used for purposes requiring very short service times. + +Here are templates for high priority (level 2+) interrupt vectors. +They assume only one interrupt per level to avoid the burden of identifying +which interrupts at this level are pending and enabled. This allows for +minimum latency and avoids having to save/restore a2 in addition to a0. +If more than one interrupt per high priority level is configured, this burden +is on the handler which in any case must provide a way to save and restore +registers it uses without touching the interrupted stack. + +Each vector goes at a predetermined location according to the Xtensa +hardware configuration, which is ensured by its placement in a special +section known to the Xtensa linker support package (LSP). It performs +the minimum necessary before jumping to the handler in the .text section. + +*******************************************************************************/ + +/* +Currently only shells for high priority interrupt handlers are provided +here. However a template and example can be found in the Cadence Design Systems tools +documentation: "Microprocessor Programmer's Guide". +*/ + +#if XTENSA_INT_NLEVELS >=2 && XTENSA_EXCM_LEVEL < 2 && XTENSA_DEBUGLEVEL !=2 + .section .iram1,"ax" + .type _xtensa_level2_handler, @function + .align 4 +_xtensa_level2_handler: + +#ifdef XT_INTEXC_HOOKS + /* Call interrupt hook if present to (pre)handle interrupts. */ + + movi a0, _xt_intexc_hooks + l32i a0, a0, 2<<2 + beqz a0, 1f +.Ln_xtensa_level2_handler_call_hook: + callx0 a0 /* must NOT disturb stack! */ +1: +#endif + + /* USER_EDIT: + ADD HIGH PRIORITY LEVEL 2 INTERRUPT HANDLER CODE HERE. + */ + + .align 4 +.L_xtensa_level2_handler_exit: + rsr a0, EXCSAVE_2 /* restore a0 */ + rfi 2 + +#endif /* XTENSA_INT_NLEVELS >=2 && XTENSA_EXCM_LEVEL < 2 && XTENSA_DEBUGLEVEL !=2 */ + +#if XTENSA_INT_NLEVELS >=3 && XTENSA_EXCM_LEVEL < 3 && XTENSA_DEBUGLEVEL !=3 + .section .iram1,"ax" + .type _xtensa_level3_handler,@function + .align 4 +_xtensa_level3_handler: + +#ifdef XT_INTEXC_HOOKS + /* Call interrupt hook if present to (pre)handle interrupts. */ + + movi a0, _xt_intexc_hooks + l32i a0, a0, 3<<2 + beqz a0, 1f +.Ln_xtensa_level3_handler_call_hook: + callx0 a0 /* must NOT disturb stack! */ +1: +#endif + + /* USER_EDIT: + ADD HIGH PRIORITY LEVEL 3 INTERRUPT HANDLER CODE HERE. + */ + + .align 4 +.L_xtensa_level3_handler_exit: + rsr a0, EXCSAVE_3 /* restore a0 */ + rfi 3 + +#endif /* XTENSA_INT_NLEVELS >=3 && XTENSA_EXCM_LEVEL < 3 && XTENSA_DEBUGLEVEL !=3 */ + +#if XTENSA_INT_NLEVELS >=4 && XTENSA_EXCM_LEVEL < 4 && XTENSA_DEBUGLEVEL !=4 + .section .iram1,"ax" + .type _xtensa_level4_handler,@function + .align 4 +_xtensa_level4_handler: + +#ifdef XT_INTEXC_HOOKS + /* Call interrupt hook if present to (pre)handle interrupts. */ + + movi a0, _xt_intexc_hooks + l32i a0, a0, 4<<2 + beqz a0, 1f +.Ln_xtensa_level4_handler_call_hook: + callx0 a0 /* must NOT disturb stack! */ +1: +#endif + + /* USER_EDIT: + ADD HIGH PRIORITY LEVEL 4 INTERRUPT HANDLER CODE HERE. + */ + + .align 4 +.L_xtensa_level4_handler_exit: + rsr a0, EXCSAVE_4 /* restore a0 */ + rfi 4 + +#endif /* XTENSA_INT_NLEVELS >=4 && XTENSA_EXCM_LEVEL < 4 && XTENSA_DEBUGLEVEL !=4 */ + +#if XTENSA_INT_NLEVELS >=5 && XTENSA_EXCM_LEVEL < 5 && XTENSA_DEBUGLEVEL !=5 + .section .iram1,"ax" + .type _xtensa_level5_handler,@function + .align 4 +_xtensa_level5_handler: + +#ifdef XT_INTEXC_HOOKS + /* Call interrupt hook if present to (pre)handle interrupts. */ + + movi a0, _xt_intexc_hooks + l32i a0, a0, 5<<2 + beqz a0, 1f +.Ln_xtensa_level5_handler_call_hook: + callx0 a0 /* must NOT disturb stack! */ +1: +#endif + + /* USER_EDIT: + ADD HIGH PRIORITY LEVEL 5 INTERRUPT HANDLER CODE HERE. + */ + + .align 4 +.L_xtensa_level5_handler_exit: + rsr a0, EXCSAVE_5 /* restore a0 */ + rfi 5 + +#endif /* XTENSA_INT_NLEVELS >=5 && XTENSA_EXCM_LEVEL < 5 && XTENSA_DEBUGLEVEL !=5 */ + +#if XTENSA_INT_NLEVELS >=6 && XTENSA_EXCM_LEVEL < 6 && XTENSA_DEBUGLEVEL !=6 + .section .iram1,"ax" + .type _xtensa_level6_handler, @function + .align 4 +_xtensa_level6_handler: + +#ifdef XT_INTEXC_HOOKS + /* Call interrupt hook if present to (pre)handle interrupts. */ + + movi a0, _xt_intexc_hooks + l32i a0, a0, 6<<2 + beqz a0, 1f +.Ln_xtensa_level6_handler_call_hook: + callx0 a0 /* must NOT disturb stack! */ +1: +#endif + + /* USER_EDIT: + ADD HIGH PRIORITY LEVEL 6 INTERRUPT HANDLER CODE HERE. + */ + + .align 4 +.L_xtensa_level6_handler_exit: + rsr a0, EXCSAVE_6 /* restore a0 */ + rfi 6 + +#endif /* XTENSA_INT_NLEVELS >=6 && XTENSA_EXCM_LEVEL < 6 && XTENSA_DEBUGLEVEL !=6 */ diff --git a/arch/xtensa/src/common/xtensa_intvectors.S b/arch/xtensa/src/common/xtensa_intvectors.S index cf84869b3ca..c7da5a7478f 100644 --- a/arch/xtensa/src/common/xtensa_intvectors.S +++ b/arch/xtensa/src/common/xtensa_intvectors.S @@ -58,7 +58,7 @@ * ****************************************************************************/ -#if CONFIG_XTENSA_EXCM_LEVEL >= 2 +#if XTENSA_EXCM_LEVEL >= 2 .begin literal_prefix .xtensa_level2_vector .section .xtensa_level2_vector.text, "ax" .global _xtensa_level2_vector @@ -77,7 +77,7 @@ _xtensa_level2_vector: .size _xtensa_level2_vector, . - _xtensa_level2_vector #endif -#if CONFIG_XTENSA_EXCM_LEVEL >= 3 +#if XTENSA_EXCM_LEVEL >= 3 .begin literal_prefix .xtensa_level3_vector .section .xtensa_level3_vector.text, "ax" .global _xtensa_level3_vector @@ -96,7 +96,7 @@ _xtensa_level3_vector: .size _xtensa_level3_vector, . - _xtensa_level3_vector #endif -#if CONFIG_XTENSA_EXCM_LEVEL >= 4 +#if XTENSA_EXCM_LEVEL >= 4 .begin literal_prefix .xtensa_level4_vector .section .xtensa_level4_vector.text, "ax" .global _xtensa_level4_vector @@ -115,7 +115,7 @@ _xtensa_level4_vector: .size _xtensa_level5_vector, . - _xtensa_level5_vector #endif -#if CONFIG_XTENSA_EXCM_LEVEL >= 5 +#if XTENSA_EXCM_LEVEL >= 5 .begin literal_prefix .xtensa_level5_vector .section .xtensa_level5_vector.text, "ax" .global _xtensa_level5_vector @@ -134,7 +134,7 @@ _xtensa_level5_vector: .size _xtensa_level5_vector, . - _xtensa_level5_vector #endif -#if CONFIG_XTENSA_EXCM_LEVEL >= 6 +#if XTENSA_EXCM_LEVEL >= 6 .begin literal_prefix .xtensa_level6_vector .section .xtensa_level6_vector.text, "ax" .global _xtensa_level6_vector diff --git a/arch/xtensa/src/common/xtensa_timer.h b/arch/xtensa/src/common/xtensa_timer.h new file mode 100644 index 00000000000..6adf77fea35 --- /dev/null +++ b/arch/xtensa/src/common/xtensa_timer.h @@ -0,0 +1,147 @@ +/**************************************************************************** + * arch/xtensa/src/common/xtensa_irq.S + * + * Adapted from use in NuttX by: + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Derives from logic originally provided by Cadence Design Systems Inc. + * Copyright (c) 2003-2015 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *******************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_COMMON_XTENSA_TIMER_H +#define __ARCH_XTENSA_SRC_COMMON_XTENSA_TIMER_H + +#ifdef __ASSEMBLER__ +#include +#endif + +#include +#include + +/* Select timer to use for periodic tick, and determine its interrupt number + * and priority. User may specify a timer by defining XT_TIMER_INDEX with -D, + * in which case its validity is checked (it must exist in this core and must + * not be on a high priority interrupt - an error will be reported in invalid). + * Otherwise select the first low or medium priority interrupt timer available. + */ + +#if XTENSA_NUM_TIMERS == 0 + +# error "This Xtensa configuration is unsupported, it has no timers." + +#else + +#ifndef XT_TIMER_INDEX +# if XTENSA_TIMER3_INTERRUPT != XTHAL_TIMER_UNCONFIGURED +# if XTENSA_INT_LEVEL(XTENSA_TIMER3_INTERRUPT) <= XTENSA_EXCM_LEVEL +# undef XT_TIMER_INDEX +# define XT_TIMER_INDEX 3 +# endif +# endif +# if XTENSA_TIMER2_INTERRUPT != XTHAL_TIMER_UNCONFIGURED +# if XTENSA_INT_LEVEL(XTENSA_TIMER2_INTERRUPT) <= XTENSA_EXCM_LEVEL +# undef XT_TIMER_INDEX +# define XT_TIMER_INDEX 2 +# endif +# endif +# if XTENSA_TIMER1_INTERRUPT != XTHAL_TIMER_UNCONFIGURED +# if XTENSA_INT_LEVEL(XTENSA_TIMER1_INTERRUPT) <= XTENSA_EXCM_LEVEL +# undef XT_TIMER_INDEX +# define XT_TIMER_INDEX 1 +# endif +# endif +# if XTENSA_TIMER0_INTERRUPT != XTHAL_TIMER_UNCONFIGURED +# if XTENSA_INT_LEVEL(XTENSA_TIMER0_INTERRUPT) <= XTENSA_EXCM_LEVEL +# undef XT_TIMER_INDEX +# define XT_TIMER_INDEX 0 +# endif +# endif +#endif +#ifndef XT_TIMER_INDEX +# error "There is no suitable timer in this Xtensa configuration." +#endif + +#define XT_CCOMPARE (CCOMPARE + XT_TIMER_INDEX) +#define XT_TIMER_INTNUM XTENSA_TIMER_INTERRUPT(XT_TIMER_INDEX) +#define XT_TIMER_INTPRI XTENSA_INT_LEVEL(XT_TIMER_INTNUM) +#define XT_TIMER_INTEN (1 << XT_TIMER_INTNUM) + +#if XT_TIMER_INTNUM == XTHAL_TIMER_UNCONFIGURED +# error "The timer selected by XT_TIMER_INDEX does not exist in this core." +#elif XT_TIMER_INTPRI > XTENSA_EXCM_LEVEL +# error "The timer interrupt cannot be high priority (use medium or low)." +#endif + +#endif /* XTENSA_NUM_TIMERS */ + +/* Set processor clock frequency, used to determine clock divisor for timer + * tick. User should BE SURE TO ADJUST THIS for the Xtensa platform being + * used. If using a supported board via the board-independent API defined in + * xtbsp.h, this may be left undefined and frequency and tick divisor will + * be computed and cached during run-time initialization. + * + * NOTE ON SIMULATOR: + * Under the Xtensa instruction set simulator, the frequency can only be + * estimated because it depends on the speed of the host and the version of + * the simulator. Also because it runs much slower than hardware, it is not + * possible to achieve real-time performance for most applications under the + * simulator. A frequency too low does not allow enough time between timer + * interrupts, starving threads. To obtain a more convenient but non-real- + * time tick duration on the simulator, compile with xt-xcc option + * "-DXT_SIMULATOR". Adjust this frequency to taste (it's not real-time + * anyway!). + */ + +#if defined(XT_SIMULATOR) && !defined(XT_CLOCK_FREQ) +# define XT_CLOCK_FREQ +#endif + +#if !defined(XT_CLOCK_FREQ) && !defined(XT_BOARD) +# error "XT_CLOCK_FREQ must be defined for the target platform." +#endif + +/* Default number of timer "ticks" per second (default 100 for 10ms tick). + * RTOS may define this in its own way (if applicable) in xtensa_rtos.h. + * User may redefine this to an optimal value for the application, either by + * editing this here or in xtensa_rtos.h, or compiling with xt-xcc option + * "-DXT_TICK_PER_SEC=" where is a suitable number. + */ + +#ifndef XT_TICK_PER_SEC +# define XT_TICK_PER_SEC (1000000 / CONFIG_USEC_PER_TICK) +#endif + +/* Derivation of clock divisor for timer tick and interrupt (one per tick). */ + +#ifdef XT_CLOCK_FREQ +# define XT_TICK_DIVISOR (XT_CLOCK_FREQ / XT_TICK_PER_SEC) +#endif + +#ifndef __ASSEMBLER__ +extern unsigned _xt_tick_divisor; +void _xt_tick_divisor_init(void); +#endif + +#endif /* __ARCH_XTENSA_SRC_COMMON_XTENSA_TIMER_H */