From 04de5c4452ae52969dfcc0f8abfb7764e74a5e7e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 1 Nov 2013 15:30:18 -0600 Subject: [PATCH] Port IDLE/interrupt stack coloration to ARM and ARMv7-A architectures --- arch/arm/src/arm/up_head.S | 51 ++++++++++++++++++++++-------- arch/arm/src/armv7-a/arm_head.S | 36 ++++++++++++++++++--- arch/arm/src/armv7-a/arm_pghead.S | 52 +++++++++++++++++++++++-------- arch/arm/src/sama5/sam_irq.c | 10 ++++++ arch/arm/src/stm32/stm32_start.c | 4 +-- 5 files changed, 120 insertions(+), 33 deletions(-) diff --git a/arch/arm/src/arm/up_head.S b/arch/arm/src/arm/up_head.S index f969b4f346..155c6a8797 100644 --- a/arch/arm/src/arm/up_head.S +++ b/arch/arm/src/arm/up_head.S @@ -611,10 +611,26 @@ __start: bl up_boot +#ifdef CONFIG_DEBUG_STACK + /* Write a known value to the IDLE thread stack to support stack + * monitoring logic + */ + + adr r3, .Lstkinit + ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */ + +2: /* Top of the loop */ + sub r1, r1, #1 /* R1 = Number of words remaining */ + cmp r1, #0 /* Check (nwords == 0) */ + str r2, [r0], #4 /* Save stack color word, increment stack address */ + bne 2b /* Bottom of the loop */ + +#endif + /* Finally branch to the OS entry point */ - mov lr, #0 - b os_start + mov lr, #0 /* LR = return address (none) */ + b os_start /* Branch to os_start */ /* Text-section constants: * @@ -641,26 +657,35 @@ __start: #ifdef CONFIG_PAGING .Ldataspan: - .long PG_L1_DATA_VADDR /* Virtual address in the L1 table */ - .long PG_L2_DATA_PBASE /* Physical address of the start of the L2 page table */ - .long PG_DATA_NPAGES /* Number of pages in the data region */ - .long PG_L2_DATA_NPAGE1 /* The number of text pages in the first page table */ - .long MMU_L1_DATAFLAGS /* L1 MMU flags to use */ + .long PG_L1_DATA_VADDR /* Virtual address in the L1 table */ + .long PG_L2_DATA_PBASE /* Physical address of the start of the L2 page table */ + .long PG_DATA_NPAGES /* Number of pages in the data region */ + .long PG_L2_DATA_NPAGE1 /* The number of text pages in the first page table */ + .long MMU_L1_DATAFLAGS /* L1 MMU flags to use */ .Ldatamap: - .long PG_L2_DATA_VADDR /* Virtual address in the L2 table */ - .long PG_DATA_PBASE /* Physical address of data memory */ - .long PG_DATA_NPAGES /* Number of pages in the data region */ - .long MMU_L2_DATAFLAGS /* L2 MMU flags to use */ + .long PG_L2_DATA_VADDR /* Virtual address in the L2 table */ + .long PG_DATA_PBASE /* Physical address of data memory */ + .long PG_DATA_NPAGES /* Number of pages in the data region */ + .long MMU_L2_DATAFLAGS /* L2 MMU flags to use */ #endif /* CONFIG_PAGING */ #if defined(CONFIG_BOOT_RUNFROMFLASH) || defined(CONFIG_PAGING) .Ldatainit: - .long _eronly /* Where .data defaults are stored in FLASH */ - .long _sdata /* Where .data needs to reside in SDRAM */ + .long _eronly /* Where .data defaults are stored in FLASH */ + .long _sdata /* Where .data needs to reside in SDRAM */ .long _edata #endif + +#ifdef CONFIG_DEBUG_STACK + .type .Lstkinit, %object +.Lstkinit: + .long _ebss /* Beginning of the IDLE stack, then words of IDLE stack */ + .long (CONFIG_IDLETHREAD_STACKSIZE >> 2) + .long STACK_COLOR /* Stack coloration word */ + .size .Lstkinit, . -.Lstkinit +#endif .size .Lvstart, .-.Lvstart /* Data section variables */ diff --git a/arch/arm/src/armv7-a/arm_head.S b/arch/arm/src/armv7-a/arm_head.S index 88cad42f4d..5a87e8fead 100644 --- a/arch/arm/src/armv7-a/arm_head.S +++ b/arch/arm/src/armv7-a/arm_head.S @@ -46,6 +46,7 @@ #include "sctlr.h" #include "mmu.h" #include "chip.h" +#include "up_internal.h" .file "arm_head.S" @@ -617,10 +618,26 @@ __start: bl up_boot +#ifdef CONFIG_DEBUG_STACK + /* Write a known value to the IDLE thread stack to support stack + * monitoring logic + */ + + adr r3, .Lstkinit + ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */ + +2: /* Top of the loop */ + sub r1, r1, #1 /* R1 = Number of words remaining */ + cmp r1, #0 /* Check (nwords == 0) */ + str r2, [r0], #4 /* Save stack color word, increment stack address */ + bne 2b /* Bottom of the loop */ + +#endif + /* Finally branch to the OS entry point */ - mov lr, #0 - b os_start + mov lr, #0 /* LR = return address (none) */ + b os_start /* Branch to os_start */ /* Text-section constants: * @@ -649,14 +666,23 @@ __start: .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 .size .Linitparms, . -.Linitparms -#if defined(CONFIG_BOOT_RUNFROMFLASH) +#ifdef CONFIG_BOOT_RUNFROMFLASH .type .Ldatainit, %object .Ldatainit: - .long _eronly /* Where .data defaults are stored in FLASH */ - .long _sdata /* Where .data needs to reside in SDRAM */ + .long _eronly /* Where .data defaults are stored in FLASH */ + .long _sdata /* Where .data needs to reside in SDRAM */ .long _edata .size .Ldatainit, . -.Ldatainit #endif + +#ifdef CONFIG_DEBUG_STACK + .type .Lstkinit, %object +.Lstkinit: + .long _ebss /* Beginning of the IDLE stack, then words of IDLE stack */ + .long (CONFIG_IDLETHREAD_STACKSIZE >> 2) + .long STACK_COLOR /* Stack coloration word */ + .size .Lstkinit, . -.Lstkinit +#endif .size .Lvstart, .-.Lvstart /* Data section variables */ diff --git a/arch/arm/src/armv7-a/arm_pghead.S b/arch/arm/src/armv7-a/arm_pghead.S index e3730745af..219f9e5a24 100644 --- a/arch/arm/src/armv7-a/arm_pghead.S +++ b/arch/arm/src/armv7-a/arm_pghead.S @@ -49,6 +49,7 @@ #include "pg_macros.h" #include "chip.h" +#include "up_internal.h" .file "arm_pghead.S" @@ -654,10 +655,26 @@ __start: bl up_boot +#ifdef CONFIG_DEBUG_STACK + /* Write a known value to the IDLE thread stack to support stack + * monitoring logic + */ + + adr r3, .Lstkinit + ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */ + +2: /* Top of the loop */ + sub r1, r1, #1 /* R1 = Number of words remaining */ + cmp r1, #0 /* Check (nwords == 0) */ + str r2, [r0], #4 /* Save stack color word, increment stack address */ + bne 2b /* Bottom of the loop */ + +#endif + /* Finally branch to the OS entry point */ - mov lr, #0 - b os_start + mov lr, #0 /* LR = return address (none) */ + b os_start /* Branch to os_start */ /* Text-section constants: * @@ -678,28 +695,37 @@ __start: .type .Ldataspan, %object .Ldataspan: - .long PG_L1_DATA_VADDR /* Virtual address in the L1 table */ - .long PG_L2_DATA_PBASE /* Physical address of the start of the L2 page table */ - .long PG_DATA_NPAGES /* Number of pages in the data region */ - .long PG_L2_DATA_NPAGE1 /* The number of text pages in the first page table */ - .long MMU_L1_DATAFLAGS /* L1 MMU flags to use */ + .long PG_L1_DATA_VADDR /* Virtual address in the L1 table */ + .long PG_L2_DATA_PBASE /* Physical address of the start of the L2 page table */ + .long PG_DATA_NPAGES /* Number of pages in the data region */ + .long PG_L2_DATA_NPAGE1 /* The number of text pages in the first page table */ + .long MMU_L1_DATAFLAGS /* L1 MMU flags to use */ .size .Ldataspan, . -.Ldataspan .type .Ldatamap, %object .Ldatamap: - .long PG_L2_DATA_VADDR /* Virtual address in the L2 table */ - .long PG_DATA_PBASE /* Physical address of data memory */ - .long PG_DATA_NPAGES /* Number of pages in the data region */ - .long MMU_L2_DATAFLAGS /* L2 MMU flags to use */ + .long PG_L2_DATA_VADDR /* Virtual address in the L2 table */ + .long PG_DATA_PBASE /* Physical address of data memory */ + .long PG_DATA_NPAGES /* Number of pages in the data region */ + .long MMU_L2_DATAFLAGS /* L2 MMU flags to use */ .size .Ldatamap, . -.Ldatamap .type .Ldatainit, %object .Ldatainit: - .long _eronly /* Where .data defaults are stored in FLASH */ - .long _sdata /* Where .data needs to reside in SDRAM */ + .long _eronly /* Where .data defaults are stored in FLASH */ + .long _sdata /* Where .data needs to reside in SDRAM */ .long _edata .size .Ldatainit, . -.Ldatainit +#ifdef CONFIG_DEBUG_STACK + .type .Lstkinit, %object +.Lstkinit: + .long _ebss /* Beginning of the IDLE stack, then words of IDLE stack */ + .long (CONFIG_IDLETHREAD_STACKSIZE >> 2) + .long STACK_COLOR /* Stack coloration word */ + .size .Lstkinit, . -.Lstkinit +#endif + .size .Lvstart, .-.Lvstart /* Data section variables */ diff --git a/arch/arm/src/sama5/sam_irq.c b/arch/arm/src/sama5/sam_irq.c index a7c642e210..e00affb402 100644 --- a/arch/arm/src/sama5/sam_irq.c +++ b/arch/arm/src/sama5/sam_irq.c @@ -217,6 +217,16 @@ void up_irqinitialize(void) * access to the AIC. */ + /* 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 + /* Unprotect SMR, SVR, SPU and DCR register */ putreg32(AIC_WPMR_WPKEY, SAM_AIC_WPMR); diff --git a/arch/arm/src/stm32/stm32_start.c b/arch/arm/src/stm32/stm32_start.c index 5a8fc3bb3d..418421e317 100644 --- a/arch/arm/src/stm32/stm32_start.c +++ b/arch/arm/src/stm32/stm32_start.c @@ -211,7 +211,7 @@ static void go_os_start(void *pv, unsigned int nbytes) "\tstr r2, [r0], #4\n" /* Save stack color word, increment stackptr */ "\tbne 1b\n" /* Bottom of the loop */ - "2:\n" /* Top of the loop */ + "2:\n" "\tmov r14, #0\n" /* LR = return address (none) */ "\tb os_start\n" /* Branch to os_start */ ); @@ -298,7 +298,7 @@ void __start(void) #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); + go_os_start((FAR void *)&_ebss, CONFIG_ARCH_INTERRUPTSTACK); #else /* Call os_start() */