mirror of
https://github.com/apache/nuttx.git
synced 2026-06-08 01:42:58 +08:00
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:
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user