Skip to content

msp uninitialized on reset leading to usage fault for non-XIP targets #7128

@GAnthony

Description

@GAnthony

I have encountered an interesting issue while debugging an intermittent usage_fault on the TI CC3220SF, when loading the program to SRAM via OpenOCD, and running with CONFIG_INIT_STACKS enabled (per below commit).

The code in __start() assumes the msp is set to the value at the beginning of the _vector_table. Which it is, normally, when running from flash.

But, when loading to SRAM via gdb/OpenOCD, the msp register is not set (to the expected address of (_main_stack + CONFIG_MAIN_STACK_SIZE)), which causes the memset() call to push r4,r5,r6 (all zeros) onto a random stack address, and (in my case) overwriting some pinmux init code, which later causes a __usage_fault().

The code works fine when running from flash [Edit: w/o a debugger attached].

Some discussion with the original author yielded this suggestion:

We probably need some code in the early boot, before the memset(),
that sets the MSP to _main_stack + CONFIG_MAIN_STACK_SIZE, that would
only be there if running from SRAM. Maybe you can key on !CONFIG_XIP,
but I'm not sure that is still valid.

I attempted this solution, but still ran into issues later on when a call to _net_thread(....., _main_stack) initializes the _main_stack with 0xaa, overwriting a return address on the current stack, and causing yet another usage fault.

So, it seems I'm missing something with regards to stack initialization for non-XIP targets, which I'd appreciate an expert could look at.

commit 0c9268784e138f665e896ec313a91d122e012174
Author: Benjamin Walsh <benjamin.walsh@windriver.com>
Date:   Mon Nov 21 12:11:18 2016 -0500

    arm: support interrupt stack with CONFIG_INIT_STACKS
   
    Use the main stack during very early boot so that we can call memset on
    the interrupt stack. Initialize the interrupt stack before it is used
    for the rest of the pre-kernel initialization.
   
    Change-Id: I6fcc9a08678afdb82e83465cda1c7a2a8c849c9b
    Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>

diff --git a/arch/arm/core/cortex_m/reset.S b/arch/arm/core/cortex_m/reset.S
index dedb5f0..564d0a2 100644
--- a/arch/arm/core/cortex_m/reset.S
+++ b/arch/arm/core/cortex_m/reset.S
@@ -33,6 +33,7 @@
 _ASM_FILE_PROLOGUE
 
 GTEXT(__reset)
+GTEXT(memset)
 GDATA(_interrupt_stack)
 
 /**
@@ -78,6 +79,13 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start)
     msr BASEPRI, r0
 #endif
 
+#ifdef CONFIG_INIT_STACKS
+    ldr r0, =_interrupt_stack
+    mov r1, #0xaa
+    ldr r2, =CONFIG_ISR_STACK_SIZE
+    bl memset
+#endif
+

Metadata

Metadata

Assignees

Labels

area: ARMARM (32-bit) ArchitecturebugThe issue is a bug, or the PR is fixing a bugpriority: mediumMedium impact/importance bug

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions