Xtensa/ESP32: Add CPU1 startup logic

This commit is contained in:
Gregory Nutt 2016-10-31 13:15:15 -06:00
parent a8e3f79494
commit 28d1478480
6 changed files with 162 additions and 5 deletions

View File

@ -108,6 +108,10 @@
# define CONFIG_ARCH_INTERRUPTSTACK 0
#endif
/* Used for stack usage measurements */
#define STACK_COLOR 0xdeadbeef
/* In the XTENSA model, the state is copied from the stack to the TCB, but
* only a referenced is passed to get the state from the TCB.
*

View File

@ -183,12 +183,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
size_t size_of_stack;
#ifdef CONFIG_STACK_COLORATION
uint32_t *ptr;
int i;
/* Yes.. If stack debug is enabled, then fill the stack with a
* recognizable value that we can use later to test for high
* water marks.
*/
memset(tcb->stack_alloc_ptr, 0xaa, stack_size);
for (i = 0, ptr = (uint32_t *)tcb->stack_alloc_ptr;
i < stack_size;
i += sizeof(uint32_t))
{
*ptr++ = STACK_COLOR;
}
#endif
/* XTENSA uses a push-down stack: the stack grows toward lower

View File

@ -41,7 +41,8 @@ HEAD_CSRC = esp32_start.c
# Common XTENSA files (arch/xtensa/src/common)
CMN_ASRCS = xtensa_context.S xtensa_coproc.S xtensa_cpuint.S
CMN_ASRCS += xtensa_int_handlers.S xtensa_panic.S xtensa_vectors.S
CMN_ASRCS += xtensa_int_handlers.S xtensa_panic.S xtensa_user_handlers.S
CMN_ASRCS += xtensa_vectors.S
CMN_CSRCS = xtensa_assert.c xtensa_blocktask.c xtensa_copystate.c
CMN_CSRCS += xtensa_cpenable.c xtensa_createstack.c xtensa_exit.c xtensa_idle.c
@ -80,7 +81,7 @@ endif
# Required ESP32 files (arch/xtensa/src/lx6)
CHIP_ASRCS =
CHIP_ASRCS = esp32_cpuhead.S
CHIP_CSRCS = esp32_allocateheap.c esp32_clockconfig.c esp32_cpuint.c
CHIP_CSRCS += esp32_gpio.c esp32_intdecode.c esp32_irq.c esp32_region.c
CHIP_CSRCS += esp32_start.c esp32_timerisr.c

View File

@ -0,0 +1,139 @@
/****************************************************************************
* arch/xtensa/src/esp32/esp32_cpuhead.S
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
.file "esp32_cpuhead.S"
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Private Data
****************************************************************************/
section .noinit, "aw"
.align 16
.global g_cpu1_idlestack
.type g_cpu1_idlestack, @object
g_cpu1_idlestack:
.space (CONFIG_SMP_IDLETHREAD_STACKSIZE & ~15)
.Lcpu1_stacktop:
.size g_cpu1_idlestack, . - g_cpu1_idlestack
/****************************************************************************
* Public Functions
****************************************************************************/
.text
/****************************************************************************
* Name: __cpu[n]_start
*
* Description:
* Boot functions for each CPU (other than CPU0). These functions set up
* the ARM operating mode, the initial stack, and configure co-processor
* registers. At the end of the boot, esp32_cpu_boot() is called.
*
* These functions are provided by the common ARMv7-A logic.
*
* Input parameters:
* None
*
* Returned Value:
* Do not return.
*
****************************************************************************/
#if CONFIG_SMP_NCPUS > 1
.global __cpu1_start
.type __cpu1_start, #function
.Lcpu1_bottomofstack:
long .Lcpu1_stacktop
.size .Lcpu1_bottomofstack, . - .Lcpu1_bottomofstack
#ifdef CONFIG_STACK_COLORATION
.Lcpu1_bottomofstack:
long .Lcpu1_stacktop
.size .Lcpu1_bottomofstack, . - .Lcpu1_bottomofstack
.Lcpu1_stackcolor:
long STACK_COLOR
.size .Lcpu1_stackcolor, . - .Lcpu1_stackcolor
#endif
__cpu1_start:
/* Set up the stack pointer and the CPU index */
l32r .Lcpu1_bottomofstack
#ifdef CONFIG_STACK_COLORATION
/* Write a known value to the IDLE thread stack to support stack
* monitoring logic
*/
mov a0, sp
l32r a1, .Lcpu1_bottomofstack
l32r a2, .Lcpu1_stackcolor
1:
s32i a2, a1, 0
addi a2, a2, 4
bne a1, a2, 1b
#endif
/* Set up the intiali PS */
#ifdef __XTENSA_CALL0_ABI__
movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_EXCM;
#else
movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_EXCM | PS_WOE | PS_CALLINC(1);
#endif
wsr a0, PS
/* Finish initialization in C */
movi a2, 1 /* Argument 1: CPU ID */
call0 xtensa_start_handler
/* xtensa_start_handler() does not return */
2: b 2b
.size __cpu1_start, . - __cpu1_start

View File

@ -197,6 +197,12 @@ int xtensa_start_handler(int irq, FAR void *context)
xtensa_registerdump(tcb);
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* And Enable interrupts */
up_irq_enable();
#endif
/* Then switch contexts. This instantiates the exception context of the
* tcb at the head of the assigned task list. In this case, this should
* be the CPUs NULL task.
@ -265,7 +271,7 @@ int up_cpu_start(int cpu)
/* Set the CPU1 start address */
ets_set_appcpu_boot_addr((uint32_t)xtensa_start_handler);
ets_set_appcpu_boot_addr((uint32_t)__cpu1_start);
/* And way for the initial task to run on CPU1 */

View File

@ -186,7 +186,6 @@ void xtensa_irq_initialize(void)
esp32_gpioirqinitialize();
#endif
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* And finally, enable interrupts */