diff --git a/arch/arm/src/armv7-r/arm_head.S b/arch/arm/src/armv7-r/arm_head.S index 688ffebcd92..a081d230b63 100644 --- a/arch/arm/src/armv7-r/arm_head.S +++ b/arch/arm/src/armv7-r/arm_head.S @@ -385,6 +385,11 @@ __start: * * This function does not return. It must give control to os_start() * at the completion of its initialization. + * + * Why not just call arm_boot() and branch to os_start() when it returns? + * If the stack pointer initialized above lies in SDRAM, then that may + * not be possible. Also, in the special case of the TMS570, it may + * perform a destructive test, losing the pushed content of the stack. */ b arm_boot diff --git a/arch/arm/src/tms570/tms570_boot.c b/arch/arm/src/tms570/tms570_boot.c index 3b3390f247b..725338faced 100644 --- a/arch/arm/src/tms570/tms570_boot.c +++ b/arch/arm/src/tms570/tms570_boot.c @@ -208,7 +208,7 @@ static void tms570_memory_initialize(uint32_t ramset) * Name: go_os_start * * Description: - * Set the IDLE stack to the + * Re-initialize the stack and frame pointers and branch to OS start. * ****************************************************************************/ @@ -227,22 +227,40 @@ static void go_os_start(void *pv, unsigned int nbytes) __asm__ __volatile__ ( - "\tmovs r1, r1, lsr #2\n" /* R1 = nwords = nbytes >> 2 */ - "\tbeq 2f\n" /* (should not happen) */ + "\tmovs 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 */ + "\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 */ + "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" - "\tmov r14, #0\n" /* LR = return address (none) */ - "\tb os_start\n" /* Branch to os_start */ + "\tldr sp, =g_idle_topstack\n" /* Reset the stack pointer */ + "\tmov fp, #0\n" /* Reset the frame pointer */ + "\tmov r14, #0\n" /* LR = return address (none) */ + "\tb os_start\n" /* Branch to os_start */ + ); +} + +#else +static void go_os_start(void) naked_function noreturn_function; + +static void go_os_start(void) +{ + /* Reset the stack/frame pointer and jump to os_start(). */ + + __asm__ __volatile__ + ( + "\tldr sp, =g_idle_topstack\n" /* Reset the stack pointer */ + "\tmov fp, #0\n" /* Reset the frame pointer */ + "\tmov r14, #0\n" /* LR = return address (none) */ + "\tb os_start\n" /* Branch to os_start */ ); } #endif @@ -445,12 +463,8 @@ void arm_boot(void) go_os_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE); #else - /* Call os_start() */ + /* Branch to os_start(), resetting the stack and frame pointers. */ - os_start(); - - /* Shouldn't get here */ - - for (; ; ); + go_os_start(); #endif }