diff --git a/arch/xtensa/src/common/xtensa.h b/arch/xtensa/src/common/xtensa.h index 5a5ab2f88c..97e59788e8 100644 --- a/arch/xtensa/src/common/xtensa.h +++ b/arch/xtensa/src/common/xtensa.h @@ -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. * diff --git a/arch/xtensa/src/common/xtensa_createstack.c b/arch/xtensa/src/common/xtensa_createstack.c index c25d64cfa4..68308fb527 100644 --- a/arch/xtensa/src/common/xtensa_createstack.c +++ b/arch/xtensa/src/common/xtensa_createstack.c @@ -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 diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs index d16874c4bc..6ea97e9bcb 100644 --- a/arch/xtensa/src/esp32/Make.defs +++ b/arch/xtensa/src/esp32/Make.defs @@ -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 diff --git a/arch/xtensa/src/esp32/esp32_cpuhead.S b/arch/xtensa/src/esp32/esp32_cpuhead.S new file mode 100644 index 0000000000..9afae45d82 --- /dev/null +++ b/arch/xtensa/src/esp32/esp32_cpuhead.S @@ -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 diff --git a/arch/xtensa/src/esp32/esp32_cpustart.c b/arch/xtensa/src/esp32/esp32_cpustart.c index 6fe42912eb..6bb2a57f3c 100644 --- a/arch/xtensa/src/esp32/esp32_cpustart.c +++ b/arch/xtensa/src/esp32/esp32_cpustart.c @@ -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 */ diff --git a/arch/xtensa/src/esp32/esp32_irq.c b/arch/xtensa/src/esp32/esp32_irq.c index fae4687d5a..bf4eec3be6 100644 --- a/arch/xtensa/src/esp32/esp32_irq.c +++ b/arch/xtensa/src/esp32/esp32_irq.c @@ -186,7 +186,6 @@ void xtensa_irq_initialize(void) esp32_gpioirqinitialize(); #endif - #ifndef CONFIG_SUPPRESS_INTERRUPTS /* And finally, enable interrupts */