arch/xtensa: Add the optional interrupt stack.
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
This commit is contained in:
parent
15d658403a
commit
c97d11aa7b
@ -92,6 +92,7 @@ config ARCH_X86_64
|
||||
|
||||
config ARCH_XTENSA
|
||||
bool "Xtensa"
|
||||
select ARCH_HAVE_INTERRUPTSTACK
|
||||
select ARCH_HAVE_STACKCHECK
|
||||
select ARCH_HAVE_CUSTOMOPT
|
||||
select ARCH_HAVE_TESTSET
|
||||
|
@ -85,18 +85,10 @@
|
||||
|
||||
/* Check if an interrupt stack size is configured */
|
||||
|
||||
#define HAVE_INTERRUPTSTACK 1
|
||||
|
||||
#if !defined(CONFIG_ARCH_INTERRUPTSTACK)
|
||||
#ifndef CONFIG_ARCH_INTERRUPTSTACK
|
||||
# define CONFIG_ARCH_INTERRUPTSTACK 0
|
||||
# undef HAVE_INTERRUPTSTACK
|
||||
#elif CONFIG_ARCH_INTERRUPTSTACK < 16
|
||||
# warning CONFIG_ARCH_INTERRUPTSTACK is to small
|
||||
# undef HAVE_INTERRUPTSTACK
|
||||
#endif
|
||||
|
||||
#define INTERRUPTSTACK_SIZE ((CONFIG_ARCH_INTERRUPTSTACK + 15) & ~15)
|
||||
#define INTERRUPT_STACKWORDS (INTERRUPTSTACK_SIZE >> 2)
|
||||
|
||||
/* An IDLE thread stack size for CPU0 must be defined */
|
||||
|
||||
@ -109,10 +101,6 @@
|
||||
#define IDLETHREAD_STACKSIZE ((CONFIG_IDLETHREAD_STACKSIZE + 15) & ~15)
|
||||
#define IDLETHREAD_STACKWORDS (IDLETHREAD_STACKSIZE >> 2)
|
||||
|
||||
/* Used for stack usage measurements */
|
||||
|
||||
#define STACK_COLOR 0xdeadbeef
|
||||
|
||||
/* In the XTENSA model, the state is copied from the stack to the TCB, but
|
||||
* only a referenced is passed to get the state from the TCB.
|
||||
*
|
||||
@ -150,6 +138,14 @@
|
||||
#define getreg32(a) (*(volatile uint32_t *)(a))
|
||||
#define putreg32(v,a) (*(volatile uint32_t *)(a) = (v))
|
||||
|
||||
/* This is the value used to mark the stack for subsequent stack monitoring
|
||||
* logic.
|
||||
*/
|
||||
|
||||
#define STACK_COLOR 0xdeadbeef
|
||||
#define INTSTACK_COLOR 0xdeadbeef
|
||||
#define HEAP_COLOR 'h'
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
@ -181,10 +177,11 @@ extern volatile uint32_t *g_current_regs[1];
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_INTERRUPTSTACK
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 15
|
||||
/* The (optional) interrupt stack */
|
||||
|
||||
extern uint32_t g_intstack[INTERRUPT_STACKWORDS];
|
||||
extern uint32_t g_intstackalloc; /* Allocated interrupt stack */
|
||||
extern uint32_t g_intstackbase; /* Initial top of interrupt stack */
|
||||
#endif
|
||||
|
||||
/* Address of the CPU0 IDLE thread */
|
||||
|
@ -197,16 +197,16 @@ ssize_t up_check_stack_remain(void)
|
||||
return up_check_tcbstack_remain(this_task());
|
||||
}
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 15
|
||||
size_t up_check_intstack(void)
|
||||
{
|
||||
return do_stackcheck((uintptr_t)&g_intstackalloc,
|
||||
(CONFIG_ARCH_INTERRUPTSTACK & ~3));
|
||||
(CONFIG_ARCH_INTERRUPTSTACK & ~15));
|
||||
}
|
||||
|
||||
size_t up_check_intstack_remain(void)
|
||||
{
|
||||
return (CONFIG_ARCH_INTERRUPTSTACK & ~3) - up_check_intstack();
|
||||
return (CONFIG_ARCH_INTERRUPTSTACK & ~15) - up_check_intstack();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -163,7 +163,7 @@ void xtensa_dumpstate(void)
|
||||
uint32_t sp = xtensa_getsp();
|
||||
uint32_t ustackbase;
|
||||
uint32_t ustacksize;
|
||||
#ifdef HAVE_INTERRUPTSTACK
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 15
|
||||
uint32_t istackbase;
|
||||
uint32_t istacksize;
|
||||
#endif
|
||||
@ -185,10 +185,9 @@ void xtensa_dumpstate(void)
|
||||
|
||||
/* Get the limits on the interrupt stack memory */
|
||||
|
||||
#warning REVISIT interrupt stack
|
||||
#ifdef HAVE_INTERRUPTSTACK
|
||||
istackbase = (uint32_t)&g_intstack[INTERRUPT_STACKWORDS - 1];
|
||||
istacksize = INTERRUPTSTACK_SIZE;
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 15
|
||||
istackbase = (uint32_t)&g_intstackbase;
|
||||
istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~15);
|
||||
|
||||
/* Show interrupt stack info */
|
||||
|
||||
@ -214,7 +213,7 @@ void xtensa_dumpstate(void)
|
||||
* at the base of the interrupt stack.
|
||||
*/
|
||||
|
||||
sp = &g_instack[INTERRUPTSTACK_SIZE - sizeof(uint32_t)];
|
||||
sp = g_intstackbase - sizeof(uint32_t);
|
||||
_alert("sp: %08x\n", sp);
|
||||
}
|
||||
else if (CURRENT_REGS)
|
||||
|
@ -58,6 +58,36 @@
|
||||
|
||||
#include "xtensa.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_color_intstack
|
||||
*
|
||||
* Description:
|
||||
* Set the interrupt stack to a value so that later we can determine how
|
||||
* much stack space was used by interrupt handling logic
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 15
|
||||
static inline void xtensa_color_intstack(void)
|
||||
{
|
||||
ssize_t size;
|
||||
uint32_t *ptr = (uint32_t *)&g_intstackalloc;
|
||||
|
||||
for (size = (CONFIG_ARCH_INTERRUPTSTACK & ~15);
|
||||
size > 0;
|
||||
size -= sizeof(uint32_t))
|
||||
{
|
||||
*ptr++ = INTSTACK_COLOR;
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define xtensa_color_intstack()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -81,6 +111,8 @@
|
||||
|
||||
void up_initialize(void)
|
||||
{
|
||||
xtensa_color_intstack();
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
int i;
|
||||
|
||||
|
@ -68,6 +68,19 @@
|
||||
#include "chip_macros.h"
|
||||
#include "xtensa_timer.h"
|
||||
|
||||
#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 15
|
||||
.data
|
||||
.align 16
|
||||
.global g_intstackalloc
|
||||
.global g_intstackbase
|
||||
.type g_intstackalloc, @object
|
||||
.type g_intstackbase, @object
|
||||
g_intstackalloc:
|
||||
.skip ((CONFIG_ARCH_INTERRUPTSTACK + 15) & ~15)
|
||||
g_intstackbase:
|
||||
.size g_intstackalloc, .-g_intstackalloc
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Assembly Language Macros
|
||||
****************************************************************************/
|
||||
@ -91,6 +104,21 @@
|
||||
addi \aout, \aout, 1 /* Return aout + 1 */
|
||||
.endm
|
||||
|
||||
/************************************************************************************
|
||||
* Name: setintstack
|
||||
*
|
||||
* Description:
|
||||
* Set the current stack pointer to the "top" the interrupt stack. Single CPU
|
||||
* case. Must be provided by MCU-specific logic in the SMP case.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 15
|
||||
.macro setintstack
|
||||
movi a1, g_intstackbase
|
||||
.endm
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Macro dispatch_c_isr level mask
|
||||
*
|
||||
@ -112,6 +140,7 @@
|
||||
* Entry Conditions/Side Effects:
|
||||
* level - interrupt level
|
||||
* mask - interrupt bitmask for this level
|
||||
* a12 - register save area
|
||||
*
|
||||
* Exit Conditions:
|
||||
* This macro will use registers a0 and a2-a5 and a12.
|
||||
@ -122,12 +151,6 @@
|
||||
|
||||
.macro dispatch_c_isr level mask
|
||||
|
||||
/* Initially the register save area is in SP, but that could change as
|
||||
* a consequence of context switching.
|
||||
*/
|
||||
|
||||
mov a12, sp /* Address of save area */
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
/* Get mask of pending, enabled interrupts at this level into a2. */
|
||||
|
||||
@ -143,7 +166,7 @@
|
||||
*/
|
||||
|
||||
/* Argument 1: Set of CPU interrupt to dispatch */
|
||||
mov a3, sp /* Argument 2: Top of stack = register save area */
|
||||
mov a3, a12 /* Argument 2: Top of stack = register save area */
|
||||
call0 xtensa_int_decode /* Call xtensa_int_decode */
|
||||
|
||||
/* On return from xtensa_int_decode, a2 will contain the address of the new
|
||||
@ -169,7 +192,7 @@
|
||||
*/
|
||||
|
||||
/* Argument 1: Set of CPU interrupt to dispatch */
|
||||
mov a7, sp /* Argument 2: Top of stack = register save area */
|
||||
mov a7, a12 /* Argument 2: Top of stack = register save area */
|
||||
call4 xtensa_int_decode /* Call xtensa_int_decode */
|
||||
|
||||
/* On return from xtensa_int_decode, a6 will contain the address of the new
|
||||
@ -263,6 +286,19 @@ _xtensa_level1_handler:
|
||||
mov a2, sp /* Address of state save on stack */
|
||||
call0 _xtensa_context_save /* Save full register state */
|
||||
|
||||
/* Save current SP before (possibly) overwriting it, it's the register save
|
||||
* area. This value will be used later by dispatch_c_isr to retrive the
|
||||
* register save area.
|
||||
*/
|
||||
|
||||
mov a12, sp
|
||||
|
||||
/* Switch to an interrupt stack if we have one */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 15
|
||||
setintstack
|
||||
#endif
|
||||
|
||||
/* Set up PS for C, enable interrupts above this level and clear EXCM. */
|
||||
|
||||
ps_setup 1 a0
|
||||
|
@ -142,12 +142,6 @@ void up_irqinitialize(void)
|
||||
|
||||
esp32_cpuint_initialize();
|
||||
|
||||
#if defined(CONFIG_STACK_COLORATION) && defined(HAVE_INTERRUPTSTACK)
|
||||
/* Colorize the interrupt stack for debug purposes */
|
||||
|
||||
#warning Missing logic
|
||||
#endif
|
||||
|
||||
/* Attach and enable internal interrupts */
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
Loading…
Reference in New Issue
Block a user