ARMv7-R and TMS570: Re-orider some initialization logic. __start used to called arm_boot() which would return. Then __start would call os_start(). That won't work for the TMS570 if is does a destructive memory tested because the return information will be lost in the stack. Also comment a nuisance assertion. The assertion is probably correct but certainly a nuisance during initial testing

This commit is contained in:
Gregory Nutt
2015-12-28 16:15:33 -06:00
parent 00f70474bb
commit ae0e6b4096
3 changed files with 118 additions and 42 deletions
+31
View File
@@ -46,6 +46,10 @@
* Included Files
****************************************************************************/
#ifndef __ASSEMBLY__
# include <nuttx/compiler.h>
#endif /* __ASSEMBLY__ */
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@@ -109,6 +113,33 @@ extern "C"
#define EXTERN extern
#endif
/****************************************************************************
* Name: arm_boot
*
* Description:
* Complete boot operations started in arm_head.S
*
* Boot Sequence
*
* 1. The __start entry point in armv7-r/arm_head.S is invoked upon power-
* on reset.
* 2. __start prepares CPU for code execution.
* 3a. If CONFIG_ARMV7R_MEMINIT is not defined, then __start will prepare
* memory resources by calling arm_data_initialize() and will then
* branch to this function.
* 3b. Otherwise, this function will be called without having initialized
* memory resources! We need to be very careful in this case. This
* function will perform MCU- and board-specific initialization which,
* among other things, must initialize memories. After initializatino
( of the memories, this function will call arm_data_initialize() to
* initialize the memory resources
* 4. This function will then branch to os_start() to start the operating
* system.
*
****************************************************************************/
void arm_boot(void) noreturn_function;
/****************************************************************************
* Name: arm_data_initialize
*
+9 -35
View File
@@ -117,9 +117,7 @@
/* Imported symbols */
.global arm_boot /* Called just before os_start */
.global os_start /* Start the operating system */
.global arm_data_initialize /* Perform C data initialization */
.global arm_boot /* Branch to continue initialization in C */
.global _sbss /* Start of .bss in RAM */
.global _ebss /* End+1 of .bss in RAM */
@@ -137,7 +135,8 @@
/* Exported symbols */
.global __start /* Power-up/Reset entry point */
.globl g_idle_topstack /* Top of the initial/IDLE stack */
.global arm_data_initialize /* Perform C data initialization */
.global g_idle_topstack /* Top of the initial/IDLE stack */
#ifdef CONFIG_ARCH_FPU
.cpu cortex-r4
@@ -373,7 +372,8 @@ __start:
/* Initialize .bss and .data ONLY if .bss and .data lie in RAM that is
* ready to use. Other memory, such as SDRAM, must be initialized before
* it can be used. arm_boot() will perform that memory initialization and
* .bss and .data can be initialized after arm_boot() returns.
* .bss and .data can be initialized by arm_boot() by calling this
* arm_data_initialize() later.
*/
bl arm_data_initialize
@@ -382,43 +382,17 @@ __start:
/* Perform early C-level, platform-specific initialization. Logic
* within arm_boot() must configure SDRAM and call arm_data_initialize()
* if CONFIG_ARMV7R_MEMINIT=y.
*
* This function does not return. It must give control to os_start()
* at the completion of its initialization.
*/
bl arm_boot
#ifdef CONFIG_STACK_COLORATION
/* 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 /* LR = return address (none) */
b os_start /* Branch to os_start */
b arm_boot
/* .text Data */
.Lstackpointer:
.long IDLE_STACK_TOP
#ifdef CONFIG_STACK_COLORATION
.type .Lstkinit, %object
.Lstkinit:
.long IDLE_STACK_BASE /* Beginning of the IDLE stack, then words of IDLE stack */
.long (CONFIG_IDLETHREAD_STACKSIZE >> 2)
.long STACK_COLOR /* Stack coloration word */
#endif
.size __start, .-__start
/***************************************************************************
+78 -7
View File
@@ -60,6 +60,8 @@
#include "up_internal.h"
#include "up_arch.h"
#include <nuttx/init.h>
#include "chip/tms570_sys.h"
#include "chip/tms570_esm.h"
#include "chip/tms570_pbist.h"
@@ -143,7 +145,12 @@ static inline void tms570_check_reset(void)
* do that.
*/
#if 0
ASSERT((regval & SYS_ESR_FAILALL) == 0);
#else
UNUSED(regval);
#endif
#else
/* Clear all reset status flags */
@@ -197,6 +204,49 @@ static void tms570_memory_initialize(uint32_t ramset)
putreg32(SYS_MINITGCR_DISABLE, TMS570_SYS_MINITGCR);
}
/****************************************************************************
* Name: go_os_start
*
* Description:
* Set the IDLE stack to the
*
****************************************************************************/
#ifdef CONFIG_STACK_COLORATION
static void go_os_start(void *pv, unsigned int nbytes)
naked_function noreturn_function;
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__
(
"\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 */
"\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"
"\tmov r14, #0\n" /* LR = return address (none) */
"\tb os_start\n" /* Branch to os_start */
);
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -214,15 +264,15 @@ static void tms570_memory_initialize(uint32_t ramset)
* 2. __start prepares CPU for code execution.
* 3a. If CONFIG_ARMV7R_MEMINIT is not defined, then __start will prepare
* memory resources by calling arm_data_initialize() and will then
* call this function.
* branch this function.
* 3b. Otherwise, this function will be called without having initialized
* memory resources! We need to be very careful in this case. Here,
* this function will call tms570_boardinitialize() which, among other
* things, much initialize SDRAM memory. Upon return, this function
* will call arm_data_initialize() to initialize the memory resources
* 4. This function will initialize all TMS570-specific resources and
* return to __start.
* 4. _start will then branch to os_start() to start the operating system.
* things, must initialize SDRAM memory. After initializatino of the
* memories, this function will call arm_data_initialize() to
* initialize the memory resources
* 4. This function will then branch to os_start() to start the operating
* system.
*
****************************************************************************/
@@ -259,7 +309,12 @@ void arm_boot(void)
tms570_clockconfig();
#ifdef CONFIG_TMS570_SELFTEST
/* Run a diagnostic check on the memory self-test controller. */
/* Run a diagnostic check on the memory self-test controller.
*
* REVISIT: This is a destructive test. It will most likely clobber the
* current stack content and result in a failure if this function were to
* attempt to return.
*/
tms570_memtest_selftest();
@@ -382,4 +437,20 @@ void arm_boot(void)
/* Perform common, low-level chip initialization (might do nothing) */
tms570_lowsetup();
/* Then start NuttX */
#ifdef CONFIG_STACK_COLORATION
/* Set the IDLE stack to the coloration value and jump into os_start() */
go_os_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE);
#else
/* Call os_start() */
os_start();
/* Shouldn't get here */
for (; ; );
#endif
}