Xtensa/ESP32: Add up_cpu_idlestack() and fix some compile issues.

This commit is contained in:
Gregory Nutt 2016-10-31 14:56:48 -06:00
parent 28d1478480
commit 4d0b0e44f1
14 changed files with 176 additions and 29 deletions

View File

@ -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

View File

@ -164,7 +164,6 @@ void up_assert(const uint8_t *filename, int lineno)
filename, lineno);
#endif
CURRENT_REGS = regs;
xtensa_assert(EXIT_FAILURE);
}

View File

@ -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&:

View File

@ -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().

View File

@ -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
*

View File

@ -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)

View File

@ -1,5 +1,5 @@
/****************************************************************************
* arch/xtensa/src/esp32/exp32_cpuindex.S
* arch/xtensa/src/esp32/esp32_clockconfig.C
*
* Mofidifed by use in NuttX by:
*

View File

@ -40,15 +40,19 @@
****************************************************************************/
#include <nuttx/config.h>
#include <arch/xtensa/xtensa_corebits.h>
#include <arch/esp32/core-isa.h>
#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 */

View File

@ -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 <gnutt@nuttx.org>
*
* 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 <nuttx/config.h>
#include <nuttx/arch.h>
#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 */

View File

@ -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 <gnutt@nuttx.org>

View File

@ -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);

View File

@ -41,11 +41,14 @@
#include <sys/types.h>
#include <stdint.h>
#include <sched.h>
#include <assert.h>
#include <errno.h>
#include <nuttx/spinlock.h>
#include <arch/irq.h>
#include "chip/esp32_dport.h"
#include "xtensa.h"
#ifdef CONFIG_SMP

View File

@ -48,7 +48,7 @@
#include "xtensa.h"
#include "esp32_cpuint.h"
#include "esp32_intercpu_interrupt.h"
#include "esp32_smp.h"
/****************************************************************************
* Public Data

View File

@ -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 <gnutt@nuttx.org>>
@ -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 */