mirror of
https://github.com/apache/nuttx.git
synced 2026-06-07 09:18:00 +08:00
Xtensa: A little more interrupt handling logic
This commit is contained in:
@@ -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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+24
-24
@@ -48,6 +48,7 @@
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <arch/types.h>
|
||||
#include <arch/chip/core-isa.h>
|
||||
|
||||
/* 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)
|
||||
|
||||
@@ -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 <nuttx/config.h>
|
||||
#include <arch/chip/core-isa.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#ifdef CONFIG_XTENSA_USE_OVLY
|
||||
# include <xtensa/overlay_os_asm.h>
|
||||
#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
|
||||
|
||||
@@ -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 <xtensa/overlay_os_asm.h>
|
||||
#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
|
||||
|
||||
@@ -46,7 +46,9 @@
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
#include <arch/chip/core-isa.h>
|
||||
|
||||
#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],
|
||||
|
||||
@@ -45,15 +45,11 @@
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <arch/irq.h>
|
||||
#include <arch/chip/core-isa.h>
|
||||
|
||||
#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 */
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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 <gnutt@nuttx.org>
|
||||
*
|
||||
* 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 <xtensa/coreasm.h>
|
||||
#endif
|
||||
|
||||
#include <xtensa/corebits.h>
|
||||
#include <xtensa/config/system.h>
|
||||
|
||||
/* 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=<value>" where <value> 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 */
|
||||
Reference in New Issue
Block a user