Extend stack debug logic to include IDLE and interrupt stacks. Also color the heap as well. Based on suggestions from David Sidrane
This commit is contained in:
parent
cfcd3cc74b
commit
b8085906b9
@ -129,6 +129,7 @@ config ARCH_CHIP_STM32
|
||||
select ARCH_HAVE_CMNVECTOR
|
||||
select ARCH_HAVE_MPU
|
||||
select ARCH_HAVE_I2CRESET
|
||||
select ARCH_HAVE_HEAPCHECK
|
||||
---help---
|
||||
STMicro STM32 architectures (ARM Cortex-M3/4).
|
||||
|
||||
|
@ -186,7 +186,7 @@ static void up_dumpstate(void)
|
||||
/* Get the limits on the interrupt stack memory */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
istackbase = (uint32_t)&g_userstack;
|
||||
istackbase = (uint32_t)&g_intstackbase;
|
||||
istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4;
|
||||
|
||||
/* Show interrupt stack info */
|
||||
@ -210,7 +210,7 @@ static void up_dumpstate(void)
|
||||
* at the base of the interrupt stack.
|
||||
*/
|
||||
|
||||
sp = g_userstack;
|
||||
sp = g_intstackbase;
|
||||
lldbg("sp: %08x\n", sp);
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ up_vectorirq:
|
||||
.word g_irqtmp
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.Lirqstackbase:
|
||||
.word up_stackbase
|
||||
.word g_intstackbase
|
||||
#endif
|
||||
.size up_vectorirq, . - up_vectorirq
|
||||
.align 5
|
||||
@ -427,20 +427,21 @@ up_vectorfiq:
|
||||
.size up_vectorfiq, . - up_vectorfiq
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_interruptstack/g_userstack
|
||||
* Name: g_intstackalloc/g_intstackbase
|
||||
************************************************************************************/
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.bss
|
||||
.align 4
|
||||
.globl g_userstack
|
||||
.type g_userstack, object
|
||||
up_interruptstack:
|
||||
.globl g_intstackalloc
|
||||
.type g_intstackalloc, object
|
||||
.globl g_intstackbase
|
||||
.type g_intstackbase, object
|
||||
g_intstackalloc:
|
||||
.skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4)
|
||||
g_userstack:
|
||||
up_stackbase:
|
||||
g_intstackbase:
|
||||
.skip 4
|
||||
.size g_userstack, 4
|
||||
.size up_interruptstack, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
.size g_intstackbase, 4
|
||||
.size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
#endif
|
||||
.end
|
||||
|
@ -258,7 +258,7 @@ exception_common:
|
||||
.size exception_common, .-exception_common
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_interruptstack/g_intstackbase
|
||||
* Name: g_intstackalloc/g_intstackbase
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
@ -267,12 +267,13 @@ exception_common:
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.bss
|
||||
.global g_intstackbase
|
||||
.global g_intstackalloc
|
||||
.global g_intstackbase
|
||||
.align 4
|
||||
up_interruptstack:
|
||||
g_intstackalloc:
|
||||
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
g_intstackbase:
|
||||
.size up_interruptstack, .-up_interruptstack
|
||||
.size g_intstackalloc, .-g_intstackalloc
|
||||
#endif
|
||||
|
||||
.end
|
||||
|
@ -186,7 +186,7 @@ static void up_dumpstate(void)
|
||||
/* Get the limits on the interrupt stack memory */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
istackbase = (uint32_t)&g_userstack;
|
||||
istackbase = (uint32_t)&g_intstackbase;
|
||||
istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4;
|
||||
|
||||
/* Show interrupt stack info */
|
||||
@ -217,7 +217,7 @@ static void up_dumpstate(void)
|
||||
* at the base of the interrupt stack.
|
||||
*/
|
||||
|
||||
sp = g_userstack;
|
||||
sp = g_intstackbase;
|
||||
lldbg("sp: %08x\n", sp);
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ arm_vectorirq:
|
||||
.word g_irqtmp
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.Lirqstackbase:
|
||||
.word up_stackbase
|
||||
.word g_intstackbase
|
||||
#endif
|
||||
.size arm_vectorirq, . - arm_vectorirq
|
||||
.align 5
|
||||
@ -481,20 +481,21 @@ arm_vectorfiq:
|
||||
.size arm_vectorfiq, . - arm_vectorfiq
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_interruptstack/g_userstack
|
||||
* Name: g_intstackalloc/g_intstackbase
|
||||
************************************************************************************/
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.bss
|
||||
.align 4
|
||||
.globl g_userstack
|
||||
.type g_userstack, object
|
||||
up_interruptstack:
|
||||
.globl g_intstackalloc
|
||||
.type g_intstackalloc, object
|
||||
.globl g_intstackbase
|
||||
.type g_intstackbase, object
|
||||
g_intstackalloc:
|
||||
.skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4)
|
||||
g_userstack:
|
||||
up_stackbase:
|
||||
g_intstackbase:
|
||||
.skip 4
|
||||
.size g_userstack, 4
|
||||
.size up_interruptstack, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
.size g_intstackbase, 4
|
||||
.size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
#endif
|
||||
.end
|
||||
|
@ -244,7 +244,7 @@ exception_common:
|
||||
.size exception_common, .-exception_common
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_interruptstack/g_intstackbase
|
||||
* Name: g_intstackalloc/g_intstackbase
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
@ -253,12 +253,13 @@ exception_common:
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.bss
|
||||
.global g_intstackalloc
|
||||
.global g_intstackbase
|
||||
.align 4
|
||||
up_interruptstack:
|
||||
g_intstackalloc:
|
||||
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
g_intstackbase:
|
||||
.size up_interruptstack, .-up_interruptstack
|
||||
.size g_intstackalloc, .-g_intstackalloc
|
||||
#endif
|
||||
|
||||
.end
|
||||
|
@ -179,7 +179,7 @@ up_vectorirq:
|
||||
.word g_irqtmp
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.Lirqstackbase:
|
||||
.word up_stackbase
|
||||
.word g_intstackbase
|
||||
#endif
|
||||
.align 5
|
||||
|
||||
@ -462,7 +462,7 @@ up_vectoraddrexcptn:
|
||||
b up_vectoraddrexcptn
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_interruptstack/g_userstack
|
||||
* Name: g_intstackalloc/g_intstackbase
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
@ -472,14 +472,13 @@ up_vectoraddrexcptn:
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.bss
|
||||
.align 4
|
||||
.globl g_userstack
|
||||
.type g_userstack, object
|
||||
up_interruptstack:
|
||||
.globl g_intstackbase
|
||||
.type g_intstackbase, object
|
||||
g_intstackalloc:
|
||||
.skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4)
|
||||
g_userstack:
|
||||
up_stackbase:
|
||||
g_intstackbase:
|
||||
.skip 4
|
||||
.size g_userstack, 4
|
||||
.size up_interruptstack, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
.size g_intstackbase, 4
|
||||
.size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
#endif
|
||||
.end
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK)
|
||||
|
||||
@ -90,7 +91,7 @@ size_t up_check_tcbstack(FAR struct tcb_s *tcb)
|
||||
*/
|
||||
|
||||
for (ptr = (FAR uint32_t *)tcb->stack_alloc_ptr, mark = tcb->adj_stack_size/4;
|
||||
*ptr == 0xDEADBEEF && mark > 0;
|
||||
*ptr == STACK_COLOR && mark > 0;
|
||||
ptr++, mark--);
|
||||
|
||||
/* If the stack is completely used, then this might mean that the stack
|
||||
@ -114,7 +115,7 @@ size_t up_check_tcbstack(FAR struct tcb_s *tcb)
|
||||
for (j = 0; j < 64; j++)
|
||||
{
|
||||
int ch;
|
||||
if (*ptr++ == 0xDEADBEEF)
|
||||
if (*ptr++ == STACK_COLOR)
|
||||
{
|
||||
ch = '.';
|
||||
}
|
||||
|
@ -82,23 +82,6 @@
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: memset32
|
||||
*
|
||||
* On most larger than 8 bit archs this will need to be word aligned so
|
||||
* so maybe some checks should be put in place?
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK)
|
||||
static void *memset32(void *s, uint32_t c, size_t n)
|
||||
{
|
||||
uint32_t *p = (uint32_t *)s;
|
||||
while (n-- > 0) *p++ = c;
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
@ -159,7 +142,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
|
||||
}
|
||||
|
||||
/* Do we need to allocate a new stack? */
|
||||
|
||||
|
||||
if (!tcb->stack_alloc_ptr)
|
||||
{
|
||||
/* Allocate the stack. If DEBUG is enabled (but not stack debug),
|
||||
@ -240,7 +223,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK)
|
||||
memset32(tcb->stack_alloc_ptr, 0xdeadbeef, tcb->adj_stack_size/4);
|
||||
up_stack_color(tcb->stack_alloc_ptr, tcb->adj_stack_size);
|
||||
#endif
|
||||
|
||||
up_ledon(LED_STACKCREATED);
|
||||
@ -249,3 +232,29 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_stack_color
|
||||
*
|
||||
* Description:
|
||||
* Write a well know value into the stack
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK)
|
||||
void up_stack_color(FAR void *stackbase, size_t nbytes)
|
||||
{
|
||||
/* Take extra care that we do not write outsize the stack boundaries */
|
||||
|
||||
uint32_t *stkptr = (uint32_t *)(((uintptr_t)stackbase + 3) & ~3);
|
||||
uintptr_t stkend = (((uintptr_t)stackbase + nbytes) & ~3);
|
||||
size_t nwords = (stkend - (uintptr_t)stackbase) >> 2;
|
||||
|
||||
/* Set the entire stack to the coloration value */
|
||||
|
||||
while (nwords-- > 0)
|
||||
{
|
||||
*stkptr++ = STACK_COLOR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -171,6 +171,14 @@
|
||||
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
****************************************************************************/
|
||||
@ -204,9 +212,10 @@ extern const uint32_t g_idle_topstack;
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
#if defined(CONFIG_ARCH_CORTEXM0) || defined(CONFIG_ARCH_CORTEXM3) || \
|
||||
defined(CONFIG_ARCH_CORTEXM4)
|
||||
extern uint32_t g_intstackbase;
|
||||
extern uint32_t g_intstackalloc; /* Allocated stack base */
|
||||
extern uint32_t g_intstackbase; /* Initial top of interrupt stack */
|
||||
# else
|
||||
extern uint32_t g_userstack;
|
||||
extern uint32_t g_intstackbase;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -484,6 +493,12 @@ void up_usbuninitialize(void);
|
||||
void up_rnginitialize(void);
|
||||
#endif
|
||||
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK)
|
||||
void up_stack_color(FAR void *stackbase, size_t nbytes);
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_COMMON_UP_INTERNAL_H */
|
||||
|
@ -779,7 +779,7 @@ kinetis_common:
|
||||
.size handlers, .-handlers
|
||||
|
||||
/************************************************************************************************
|
||||
* Name: up_interruptstack/g_intstackbase
|
||||
* Name: g_intstackalloc/g_intstackbase
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
@ -790,10 +790,10 @@ kinetis_common:
|
||||
.bss
|
||||
.global g_intstackbase
|
||||
.align 4
|
||||
up_interruptstack:
|
||||
g_intstackalloc:
|
||||
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
g_intstackbase:
|
||||
.size up_interruptstack, .-up_interruptstack
|
||||
.size g_intstackalloc, .-g_intstackalloc
|
||||
#endif
|
||||
#endif /* CONFIG_ARMV7M_CMNVECTOR */
|
||||
|
||||
|
@ -382,7 +382,7 @@ lm_irqcommon:
|
||||
.size handlers, .-handlers
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_interruptstack/g_intstackbase
|
||||
* Name: g_intstackalloc/g_intstackbase
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
@ -393,10 +393,10 @@ lm_irqcommon:
|
||||
.bss
|
||||
.global g_intstackbase
|
||||
.align 4
|
||||
up_interruptstack:
|
||||
g_intstackalloc:
|
||||
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
g_intstackbase:
|
||||
.size up_interruptstack, .-up_interruptstack
|
||||
.size g_intstackalloc, .-g_intstackalloc
|
||||
#endif
|
||||
#endif /* CONFIG_ARMV7M_CMNVECTOR */
|
||||
|
||||
|
@ -391,7 +391,7 @@ lpc17_common:
|
||||
.size handlers, .-handlers
|
||||
|
||||
/************************************************************************************************
|
||||
* Name: up_interruptstack/g_intstackbase
|
||||
* Name: g_intstackalloc/g_intstackbase
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
@ -402,10 +402,10 @@ lpc17_common:
|
||||
.bss
|
||||
.global g_intstackbase
|
||||
.align 4
|
||||
up_interruptstack:
|
||||
g_intstackalloc:
|
||||
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
g_intstackbase:
|
||||
.size up_interruptstack, .-up_interruptstack
|
||||
.size g_intstackalloc, .-g_intstackalloc
|
||||
#endif
|
||||
#endif /* CONFIG_ARMV7M_CMNVECTOR */
|
||||
|
||||
|
@ -397,7 +397,7 @@ sam_common:
|
||||
.size handlers, .-handlers
|
||||
|
||||
/************************************************************************************************
|
||||
* Name: up_interruptstack/g_intstackbase
|
||||
* Name: g_intstackalloc/g_intstackbase
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
@ -408,10 +408,10 @@ sam_common:
|
||||
.bss
|
||||
.global g_intstackbase
|
||||
.align 4
|
||||
up_interruptstack:
|
||||
g_intstackalloc:
|
||||
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
g_intstackbase:
|
||||
.size up_interruptstack, .-up_interruptstack
|
||||
.size g_intstackalloc, .-g_intstackalloc
|
||||
#endif
|
||||
#endif /* CONFIG_ARMV7M_CMNVECTOR */
|
||||
|
||||
|
@ -393,6 +393,23 @@
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_heap_color
|
||||
*
|
||||
* Description:
|
||||
* Set heap memory to a known, non-zero state to checking heap usage.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_HEAP
|
||||
static inline void up_heap_color(FAR void *start, size_t size)
|
||||
{
|
||||
memset(start, HEAP_COLOR, size);
|
||||
}
|
||||
#else
|
||||
# define up_heap_color(start,size)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -461,6 +478,10 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
|
||||
*heap_start = (FAR void*)ubase;
|
||||
*heap_size = usize;
|
||||
|
||||
/* Colorize the heap for debug */
|
||||
|
||||
up_heap_color((FAR void*)ubase, usize);
|
||||
|
||||
/* Allow user-mode access to the user heap memory */
|
||||
|
||||
stm32_mpu_uheap((uintptr_t)ubase, usize);
|
||||
@ -471,6 +492,10 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
|
||||
up_ledon(LED_HEAPALLOCATE);
|
||||
*heap_start = (FAR void*)g_idle_topstack;
|
||||
*heap_size = SRAM1_END - g_idle_topstack;
|
||||
|
||||
/* Colorize the heap for debug */
|
||||
|
||||
up_heap_color(*heap_start, *heap_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -539,6 +564,10 @@ void up_addregion(void)
|
||||
|
||||
#endif
|
||||
|
||||
/* Colorize the heap for debug */
|
||||
|
||||
up_heap_color((FAR void*)SRAM2_START, SRAM2_END-SRAM2_START);
|
||||
|
||||
/* Add the STM32F20xxx/STM32F40xxx CCM SRAM user heap region. */
|
||||
|
||||
kumm_addregion((FAR void*)SRAM2_START, SRAM2_END-SRAM2_START);
|
||||
@ -553,9 +582,13 @@ void up_addregion(void)
|
||||
|
||||
#endif
|
||||
|
||||
/* Add the external FSMC SRAM user heap region. */
|
||||
/* Colorize the heap for debug */
|
||||
|
||||
kumm_addregion((FAR void*)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE);
|
||||
up_heap_color((FAR void*)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE);
|
||||
|
||||
/* Add the external FSMC SRAM user heap region. */
|
||||
|
||||
kumm_addregion((FAR void*)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
@ -299,6 +299,16 @@ void up_irqinitialize(void)
|
||||
putreg32(0, NVIC_IRQ0_31_ENABLE);
|
||||
putreg32(0, NVIC_IRQ32_63_ENABLE);
|
||||
|
||||
/* Colorize the interrupt stack for debug purposes */
|
||||
|
||||
#if defined(CONFIG_DEBUG_STACK) && CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
{
|
||||
size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3);
|
||||
up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size),
|
||||
intstack_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The standard location for the vector table is at the beginning of FLASH
|
||||
* at address 0x0800:0000. If we are using the STMicro DFU bootloader, then
|
||||
* the vector table will be offset to a different location in FLASH and we
|
||||
|
@ -58,6 +58,18 @@
|
||||
# include "nvic.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
static inline void stm32_fpuconfig(void);
|
||||
#endif
|
||||
#ifdef CONFIG_DEBUG_STACK
|
||||
static void go_os_start(void *pv, unsigned int nbytes)
|
||||
__attribute__ ((naked,no_instrument_function,noreturn));
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@ -110,7 +122,7 @@ static inline void stm32_fpuconfig(void)
|
||||
* with the volatile FP registers stacked above the basic context.
|
||||
*/
|
||||
|
||||
regval = getcontrol();
|
||||
regval = getcontrol();
|
||||
regval |= (1 << 2);
|
||||
setcontrol(regval);
|
||||
|
||||
@ -140,7 +152,7 @@ static inline void stm32_fpuconfig(void)
|
||||
* with the volatile FP registers stacked in the saved context.
|
||||
*/
|
||||
|
||||
regval = getcontrol();
|
||||
regval = getcontrol();
|
||||
regval &= ~(1 << 2);
|
||||
setcontrol(regval);
|
||||
|
||||
@ -166,6 +178,46 @@ static inline void stm32_fpuconfig(void)
|
||||
# define stm32_fpuconfig()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: go_os_start
|
||||
*
|
||||
* Description:
|
||||
* Set the IDLE stack to the
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_STACK
|
||||
static void go_os_start(void *pv, unsigned int nbytes)
|
||||
{
|
||||
/* Set the IDLE stack to the stack coloration value then jump to
|
||||
* os_start(). We take extreme care here because were currently
|
||||
* executing on this stack.
|
||||
*
|
||||
* We want to avoid sneak stack access generated by the compiler.
|
||||
*/
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmov r1, r1, lsr #2\n" /* R1 = nwords = nbytes >> 2 */
|
||||
"\tbeq 2f\n" /* (should not happen) */
|
||||
|
||||
"\tbic r0, r0, #3\n" /* R0 = Aligned stackptr */
|
||||
"\tmovw r2, #0xbeef\n" /* R2 = STACK_COLOR = 0xdeadbeef */
|
||||
"\tmovt r2, #0xdead\n"
|
||||
|
||||
"1:\n" /* Top of the loop */
|
||||
"\tsub r1, r1, #1\n" /* R1 nwords-- */
|
||||
"\tcmp r1, #0\n" /* Check (nwords == 0) */
|
||||
"\tstr r2, [r0], #4\n" /* Save stack color word, increment stackptr */
|
||||
"\tbne 1b\n" /* Bottom of the loop */
|
||||
|
||||
"2:\n" /* Top of the loop */
|
||||
"\tmov r14, #0\n" /* LR = return address (none) */
|
||||
"\tb os_start\n" /* Branch to os_start */
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -242,9 +294,18 @@ void __start(void)
|
||||
|
||||
showprogress('\r');
|
||||
showprogress('\n');
|
||||
|
||||
#ifdef CONFIG_DEBUG_STACK
|
||||
/* Set the IDLE stack to the coloration value and jump into os_start() */
|
||||
|
||||
go_os_start((FAR void *)_ebss, CONFIG_ARCH_INTERRUPTSTACK);
|
||||
#else
|
||||
/* Call os_start() */
|
||||
|
||||
os_start();
|
||||
|
||||
/* Shoulnd't get here */
|
||||
|
||||
for(;;);
|
||||
#endif
|
||||
}
|
||||
|
@ -404,7 +404,7 @@ stm32_common:
|
||||
.size handlers, .-handlers
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_interruptstack/g_intstackbase
|
||||
* Name: g_intstackalloc/g_intstackbase
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
@ -413,13 +413,15 @@ stm32_common:
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.bss
|
||||
.global g_intstackbase
|
||||
.global g_intstackalloc
|
||||
.global g_intstackbase
|
||||
.align 4
|
||||
up_interruptstack:
|
||||
g_intstackalloc:
|
||||
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
g_intstackbase:
|
||||
.size up_interruptstack, .-up_interruptstack
|
||||
.size g_intstackalloc, .-g_intstackalloc
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_ARMV7M_CMNVECTOR */
|
||||
|
||||
/************************************************************************************
|
||||
|
@ -146,7 +146,7 @@ extern uint16_t g_idle_topstack;
|
||||
/* Address of the saved user stack pointer */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 1
|
||||
extern uint32_t g_userstack;
|
||||
extern uint32_t g_intstackbase;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -181,7 +181,7 @@ static void up_dumpstate(void)
|
||||
/* Get the limits on the interrupt stack memory */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
istackbase = (uint16_t)&g_userstack;
|
||||
istackbase = (uint16_t)&g_intstackbase;
|
||||
istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4;
|
||||
|
||||
/* Show interrupt stack info */
|
||||
@ -205,7 +205,7 @@ static void up_dumpstate(void)
|
||||
* at the base of the interrupt stack.
|
||||
*/
|
||||
|
||||
sp = g_userstack;
|
||||
sp = g_intstackbase;
|
||||
lldbg("sp: %04x\n", sp);
|
||||
}
|
||||
|
||||
|
@ -433,7 +433,7 @@ up_fullcontextrestore:
|
||||
.comm .Lspsave, 2, 1
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_interruptstack/g_userstack
|
||||
* Name: up_interruptstack/g_intstackbase
|
||||
*
|
||||
* Description:
|
||||
* If CONFIG_ARCH_INTERRUPTSTACK is defined, this sets aside memory for the
|
||||
|
@ -179,7 +179,7 @@ void up_dumpstate(void)
|
||||
/* Get the limits on the interrupt stack memory */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
istackbase = (uint32_t)&g_userstack;
|
||||
istackbase = (uint32_t)&g_intstackbase;
|
||||
istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4;
|
||||
|
||||
/* Show interrupt stack info */
|
||||
@ -203,7 +203,7 @@ void up_dumpstate(void)
|
||||
* at the base of the interrupt stack.
|
||||
*/
|
||||
|
||||
sp = g_userstack;
|
||||
sp = g_intstackbase;
|
||||
lldbg("sp: %08x\n", sp);
|
||||
}
|
||||
|
||||
|
@ -272,7 +272,7 @@ extern uint32_t g_idle_topstack; /* Start of the heap */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
# if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
extern uint16_t g_userstack;
|
||||
extern uint16_t g_intstackbase;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@ -63,7 +63,7 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
# if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
extern uint32_t g_userstack;
|
||||
extern uint32_t g_intstackbase;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@ -172,7 +172,7 @@ void up_dumpstate(void)
|
||||
/* Get the limits on the interrupt stack memory */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
istackbase = (uint32_t)&g_userstack;
|
||||
istackbase = (uint32_t)&g_intstackbase;
|
||||
istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4;
|
||||
|
||||
/* Show interrupt stack info */
|
||||
@ -196,7 +196,7 @@ void up_dumpstate(void)
|
||||
* at the base of the interrupt stack.
|
||||
*/
|
||||
|
||||
sp = g_userstack;
|
||||
sp = g_intstackbase;
|
||||
lldbg("sp: %08x\n", sp);
|
||||
}
|
||||
|
||||
|
@ -411,7 +411,7 @@ _up_vector:
|
||||
.align 2
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.Lintstack:
|
||||
.long _up_stackbase
|
||||
.long _g_intstackbase
|
||||
#endif
|
||||
.Ldoirq:
|
||||
.long _up_doirq
|
||||
@ -501,7 +501,7 @@ _up_fullcontextrestore:
|
||||
.size _up_fullcontextrestore, .-_up_fullcontextrestore
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_interruptstack/g_userstack
|
||||
* Name: g_intstackalloc/g_intstackbase
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
@ -511,15 +511,16 @@ _up_fullcontextrestore:
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.bss
|
||||
.align 2
|
||||
.globl _g_userstack
|
||||
.type _g_userstack, object
|
||||
_up_interruptstack:
|
||||
.globl _g_intstackalloc
|
||||
.type _g_intstackalloc, object
|
||||
.globl _g_intstackbase
|
||||
.type _g_intstackbase, object
|
||||
_g_intstackalloc:
|
||||
.skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4)
|
||||
_g_userstack:
|
||||
_up_stackbase:
|
||||
_g_intstackbase:
|
||||
.skip 2
|
||||
.size _g_userstack, 4
|
||||
.size _up_interruptstack, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
.size _g_intstackbase, 4
|
||||
.size _g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
#endif
|
||||
.end
|
||||
|
||||
|
@ -140,7 +140,7 @@ static void up_dumpstate(void)
|
||||
/* Get the limits on the interrupt stack memory */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
istackbase = (uint32_t)&g_userstack;
|
||||
istackbase = (uint32_t)&g_intstackbase;
|
||||
istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4;
|
||||
|
||||
/* Show interrupt stack info */
|
||||
@ -164,7 +164,7 @@ static void up_dumpstate(void)
|
||||
* at the base of the interrupt stack.
|
||||
*/
|
||||
|
||||
sp = g_userstack;
|
||||
sp = g_intstackbase;
|
||||
lldbg("sp: %08x\n", sp);
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ extern uint32_t g_idle_topstack;
|
||||
/* Address of the saved user stack pointer */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
extern uint32_t g_userstack;
|
||||
extern uint32_t g_intstackbase;
|
||||
#endif
|
||||
|
||||
/* These 'addresses' of these values are setup by the linker script. They are
|
||||
|
Loading…
x
Reference in New Issue
Block a user