diff --git a/arch/xtensa/src/common/xtensa.h b/arch/xtensa/src/common/xtensa.h index 97e59788e8..422ec0b96f 100644 --- a/arch/xtensa/src/common/xtensa.h +++ b/arch/xtensa/src/common/xtensa.h @@ -276,6 +276,7 @@ void xtensa_user(int exccause, uint32_t *regs) noreturn_function; /* Software interrupt handler */ #ifdef CONFIG_SMP +void __cpu1_start(void) noreturn_function; int xtensa_intercpu_interrupt(int tocpu, int intcode); void xtensa_pause_handler(void); #endif diff --git a/arch/xtensa/src/common/xtensa_assert.c b/arch/xtensa/src/common/xtensa_assert.c index 565e71ff5c..24b7fd7e23 100644 --- a/arch/xtensa/src/common/xtensa_assert.c +++ b/arch/xtensa/src/common/xtensa_assert.c @@ -164,7 +164,6 @@ void up_assert(const uint8_t *filename, int lineno) filename, lineno); #endif - CURRENT_REGS = regs; xtensa_assert(EXIT_FAILURE); } diff --git a/arch/xtensa/src/common/xtensa_int_handlers.S b/arch/xtensa/src/common/xtensa_int_handlers.S index 6946aa9b17..0cf3c2f129 100644 --- a/arch/xtensa/src/common/xtensa_int_handlers.S +++ b/arch/xtensa/src/common/xtensa_int_handlers.S @@ -125,7 +125,7 @@ * a consequence of context switching. */ - mov s12, sp /* a12 = address of save area */ + mov a12, sp /* a12 = address of save area */ ._xtensa_dispatch_level&level&: diff --git a/arch/xtensa/src/common/xtensa_user_handler.S b/arch/xtensa/src/common/xtensa_user_handler.S index 75776a5eee..abf043da2b 100644 --- a/arch/xtensa/src/common/xtensa_user_handler.S +++ b/arch/xtensa/src/common/xtensa_user_handler.S @@ -274,7 +274,7 @@ _xtensa_syscall_handler: /* Save EPC */ -#ifidef XCHAL_HAVE_LOOPS +#ifdef XCHAL_HAVE_LOOPS /* Save A2 and A3 now to give us some registers to work with. A0, A2 * and A3 are now available. NOTE that A3 will get saved again in * _xtensa_context_save(). diff --git a/arch/xtensa/src/common/xtensa_vectors.S b/arch/xtensa/src/common/xtensa_vectors.S index 99af68c442..726824f058 100644 --- a/arch/xtensa/src/common/xtensa_vectors.S +++ b/arch/xtensa/src/common/xtensa_vectors.S @@ -215,6 +215,8 @@ _xtensa_nmi_vector: .size _xtensa_nmi_vector, . - _xtensa_nmi_vector .end literal_prefix +#endif /* XCHAL_HAVE_NMI */ + /**************************************************************************** * Name: _debug_exception_vector * diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs index 6ea97e9bcb..5d6beb98d0 100644 --- a/arch/xtensa/src/esp32/Make.defs +++ b/arch/xtensa/src/esp32/Make.defs @@ -41,7 +41,7 @@ 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_user_handlers.S +CMN_ASRCS += xtensa_int_handlers.S xtensa_panic.S xtensa_user_handler.S CMN_ASRCS += xtensa_vectors.S CMN_CSRCS = xtensa_assert.c xtensa_blocktask.c xtensa_copystate.c @@ -81,7 +81,7 @@ endif # Required ESP32 files (arch/xtensa/src/lx6) -CHIP_ASRCS = esp32_cpuhead.S +CHIP_ASRCS = 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 @@ -89,9 +89,8 @@ CHIP_CSRCS += esp32_start.c esp32_timerisr.c # Configuration-dependent ESP32 files ifeq ($(CONFIG_SMP),y) -CHIP_ASRCS = esp32_cpuindex.S -CMN_CSRCS += esp32_cpustart.c esp32_intercpu_interrupt.c -#CMN_CSRCS += esp32_cpuidlestack.c +CHIP_ASRCS = esp32_cpuhead.S esp32_cpuindex.S +CMN_CSRCS += esp32_cpuidlestack.c esp32_cpustart.c esp32_intercpu_interrupt.c endif ifeq ($(CONFIG_ESP32_UART),y) diff --git a/arch/xtensa/src/esp32/esp32_clockconfig.c b/arch/xtensa/src/esp32/esp32_clockconfig.c index 4f841b11be..f2f7df08ea 100644 --- a/arch/xtensa/src/esp32/esp32_clockconfig.c +++ b/arch/xtensa/src/esp32/esp32_clockconfig.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/xtensa/src/esp32/exp32_cpuindex.S + * arch/xtensa/src/esp32/esp32_clockconfig.C * * Mofidifed by use in NuttX by: * diff --git a/arch/xtensa/src/esp32/esp32_cpuhead.S b/arch/xtensa/src/esp32/esp32_cpuhead.S index 9afae45d82..9fb05f66ea 100644 --- a/arch/xtensa/src/esp32/esp32_cpuhead.S +++ b/arch/xtensa/src/esp32/esp32_cpuhead.S @@ -40,15 +40,19 @@ ****************************************************************************/ #include +#include +#include + +#ifdef CONFIG_SMP /**************************************************************************** * Private Data ****************************************************************************/ - section .noinit, "aw" - .align 16 + .section .noinit, "aw" .global g_cpu1_idlestack .type g_cpu1_idlestack, @object + .align 16 g_cpu1_idlestack: .space (CONFIG_SMP_IDLETHREAD_STACKSIZE & ~15) @@ -79,30 +83,36 @@ g_cpu1_idlestack: * ****************************************************************************/ -#if CONFIG_SMP_NCPUS > 1 - .global __cpu1_start - .type __cpu1_start, #function + .type __cpu1_start, @function + + .align 4 .Lcpu1_bottomofstack: - long .Lcpu1_stacktop + .long .Lcpu1_stacktop .size .Lcpu1_bottomofstack, . - .Lcpu1_bottomofstack #ifdef CONFIG_STACK_COLORATION .Lcpu1_bottomofstack: - long .Lcpu1_stacktop + .long .Lcpu1_stacktop .size .Lcpu1_bottomofstack, . - .Lcpu1_bottomofstack .Lcpu1_stackcolor: - long STACK_COLOR + .long STACK_COLOR .size .Lcpu1_stackcolor, . - .Lcpu1_stackcolor #endif + .align 4 + __cpu1_start: /* Set up the stack pointer and the CPU index */ - l32r .Lcpu1_bottomofstack + l32r sp, .Lcpu1_bottomofstack + + /* Does it make since to have co-processors enabled on the IDLE thread? */ + +//#warning REVISIT: Must set aside co-processor save ares #ifdef CONFIG_STACK_COLORATION /* Write a known value to the IDLE thread stack to support stack @@ -122,9 +132,9 @@ __cpu1_start: /* Set up the intiali PS */ #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_EXCM; + 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); + movi a0, (PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_EXCM | PS_WOE | PS_CALLINC(1)) #endif wsr a0, PS @@ -135,5 +145,6 @@ __cpu1_start: /* xtensa_start_handler() does not return */ -2: b 2b +2: j 2b .size __cpu1_start, . - __cpu1_start +#endif /* CONFIG_SMP */ diff --git a/arch/xtensa/src/esp32/esp32_cpuidlestack.c b/arch/xtensa/src/esp32/esp32_cpuidlestack.c new file mode 100644 index 0000000000..e1f0941ce9 --- /dev/null +++ b/arch/xtensa/src/esp32/esp32_cpuidlestack.c @@ -0,0 +1,114 @@ +/**************************************************************************** + * arch/xtensa/src/esp32/esp32_cpuidlestack.c + * + * Mofidifed by use in NuttX by: + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Derives from software originally provided by Expressif Systems: + * + * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "xtensa.h" +#include "esp32_smp.h" + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_cpu_idlestack + * + * Description: + * Allocate a stack for the CPU[n] IDLE task (n > 0) if appropriate and + * setup up stack-related information in the IDLE task's TCB. This + * function is always called before up_cpu_start(). This function is + * only called for the CPU's initial IDLE task; up_create_task is used for + * all normal tasks, pthreads, and kernel threads for all CPUs. + * + * The initial IDLE task is a special case because the CPUs can be started + * in different wans in different environments: + * + * 1. The CPU may already have been started and waiting in a low power + * state for up_cpu_start(). In this case, the IDLE thread's stack + * has already been allocated and is already in use. Here + * up_cpu_idlestack() only has to provide information about the + * already allocated stack. + * + * 2. The CPU may be disabled but started when up_cpu_start() is called. + * In this case, a new stack will need to be created for the IDLE + * thread and this function is then equivalent to: + * + * return up_create_stack(tcb, stack_size, TCB_FLAG_TTYPE_KERNEL); + * + * The following TCB fields must be initialized by this function: + * + * - adj_stack_size: Stack size after adjustment for hardware, processor, + * etc. This value is retained only for debug purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of + * the stack pointer. + * + * Inputs: + * - cpu: CPU index that indicates which CPU the IDLE task is + * being created for. + * - tcb: The TCB of new CPU IDLE task + * - stack_size: The requested stack size for the IDLE task. At least + * this much must be allocated. This should be + * CONFIG_SMP_IDLETHREAD_STACKSIZE. + * + ****************************************************************************/ + +int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size) +{ + uintptr_t topofstack; + + /* XTENSA uses a push-down stack: the stack grows toward lower* addresses + * in memory. The stack pointer register points to the lowest, valid + * working address (the "top" of the stack). Items on the stack are + * referenced as positive word offsets from sp. + */ + + /* Save information about pre-allocated IDLE thread stack */ + + + tcb->stack_alloc_ptr = g_cpu1_idlestack; + tcb->adj_stack_size = CPU1_IDLETHREAD_STACKSIZE; + topofstack = (uintptr_t)g_cpu1_idlestack + CPU1_IDLETHREAD_STACKSIZE; + tcb->adj_stack_ptr = (uint32_t *)topofstack; + +#if XCHAL_CP_NUM > 0 + /* Does it make since to have co-processors enabled on the IDLE thread? */ + +//#warning REVISIT: Need to set co-processor save are in TCB +#endif + + return OK; +} + +#endif /* CONFIG_SMP */ + diff --git a/arch/xtensa/src/esp32/esp32_cpuindex.S b/arch/xtensa/src/esp32/esp32_cpuindex.S index 0059f256e2..f62eed1202 100644 --- a/arch/xtensa/src/esp32/esp32_cpuindex.S +++ b/arch/xtensa/src/esp32/esp32_cpuindex.S @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/xtensa/src/esp32/exp32_cpuindex.S + * arch/xtensa/src/esp32/esp32_cpuindex.S * * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/arch/xtensa/src/esp32/esp32_cpustart.c b/arch/xtensa/src/esp32/esp32_cpustart.c index 6bb2a57f3c..40f9882a5e 100644 --- a/arch/xtensa/src/esp32/esp32_cpustart.c +++ b/arch/xtensa/src/esp32/esp32_cpustart.c @@ -52,7 +52,7 @@ #include "chip/esp32_dport.h" #include "esp32_region.h" #include "esp32_cpuint.h" -#include "esp32_intercpu_interrupt.h" +#include "esp32_smp.h" #ifdef CONFIG_SMP @@ -193,6 +193,14 @@ int xtensa_start_handler(int irq, FAR void *context) esp32_detach_peripheral(1, i);; } +#if 0 /* Does it make since to have co-processors enabled on the IDLE thread? */ +#if XTENSA_CP_ALLSET != 0 + /* Set initial co-processor state */ + + xtensa_coproc_enable(struct xtensa_cpstate_s *cpstate, int cpset); +#endif +#endif + /* Dump registers so that we can see what is going to happen on return */ xtensa_registerdump(tcb); diff --git a/arch/xtensa/src/esp32/esp32_intercpu_interrupt.c b/arch/xtensa/src/esp32/esp32_intercpu_interrupt.c index 963e1d5156..66ae7bac06 100644 --- a/arch/xtensa/src/esp32/esp32_intercpu_interrupt.c +++ b/arch/xtensa/src/esp32/esp32_intercpu_interrupt.c @@ -41,11 +41,14 @@ #include #include +#include #include #include +#include #include +#include "chip/esp32_dport.h" #include "xtensa.h" #ifdef CONFIG_SMP diff --git a/arch/xtensa/src/esp32/esp32_irq.c b/arch/xtensa/src/esp32/esp32_irq.c index bf4eec3be6..4c1d15008f 100644 --- a/arch/xtensa/src/esp32/esp32_irq.c +++ b/arch/xtensa/src/esp32/esp32_irq.c @@ -48,7 +48,7 @@ #include "xtensa.h" #include "esp32_cpuint.h" -#include "esp32_intercpu_interrupt.h" +#include "esp32_smp.h" /**************************************************************************** * Public Data diff --git a/arch/xtensa/src/esp32/esp32_intercpu_interrupt.h b/arch/xtensa/src/esp32/esp32_smp.h similarity index 82% rename from arch/xtensa/src/esp32/esp32_intercpu_interrupt.h rename to arch/xtensa/src/esp32/esp32_smp.h index 5b2c7eeae7..22d934e7a6 100644 --- a/arch/xtensa/src/esp32/esp32_intercpu_interrupt.h +++ b/arch/xtensa/src/esp32/esp32_smp.h @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/xtensa/src/esp32/esp32_intercpu_interrupt.h + * arch/xtensa/src/esp32/esp32_smp.h * * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt > @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __ARCH_XTENSA_SRC_ESP32_ESP32_INTERCPU_INTERRUPT_H -#define __ARCH_XTENSA_SRC_ESP32_ESP32_INTERCPU_INTERRUPT_H +#ifndef __ARCH_XTENSA_SRC_ESP32_ESP32_SMP_H +#define __ARCH_XTENSA_SRC_ESP32_ESP32_SMP_H /**************************************************************************** * Included Files @@ -44,8 +44,18 @@ #ifdef CONFIG_SMP + /**************************************************************************** - * Pre-processor Definitions + * Public Data + ****************************************************************************/ + +/* This is the CPU1 IDLE stack */ + +#define CPU1_IDLETHREAD_STACKSIZE (CONFIG_SMP_IDLETHREAD_STACKSIZE & ~15) +extern uint32_t g_cpu1_idlestack[CPU1_IDLETHREAD_STACKSIZE / 34]; + +/**************************************************************************** + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -60,4 +70,4 @@ int esp32_fromcpu0_interrupt(int irq, FAR void *context); int esp32_fromcpu1_interrupt(int irq, FAR void *context); #endif /* CONFIG_SMP */ -#endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_INTERCPU_INTERRUPT_H */ +#endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_SMP_H */