arch/xtensa: General cleanup, remove dead code
There was a bunch of dead historical cruft floating around in the arch/xtensa tree, left over from older code versions. It's time to do a cleanup pass. This is entirely refactoring and size optimization, no behavior changes on any in-tree devices should be present. Among the more notable changes: + xtensa_context.h offered an elaborate API to deal with a stack frame and context layout that we no longer use. + xtensa_rtos.h was entirely dead code + xtensa_timer.h was a parallel abstraction layer implementing in the architecture layer what we're already doing in our timer driver. + The architecture thread structs (_callee_saved and _thread_arch) aren't used by current code, and had dead fields that were removed. Unfortunately for standards compliance and C++ compatibility it's not possible to leave an empty struct here, so they have a single byte field. + xtensa_api.h was really just some interrupt management inlines used by irq.h, so fold that code into the outer header. + Remove the stale assembly offsets. This architecture doesn't use that facility. All told, more than a thousand lines have been removed. Not bad. Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
parent
deca2301f6
commit
eb1ef50b6b
22 changed files with 102 additions and 1155 deletions
|
@ -3,7 +3,46 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <arch/xtensa/xtensa_context.h>
|
||||
/*
|
||||
* MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN
|
||||
*
|
||||
* Convenient where the frame size requirements are the same for both ABIs.
|
||||
* ENTRY(sz), RET(sz) are for framed functions (have locals or make calls).
|
||||
* ENTRY0, RET0 are for frameless functions (no locals, no calls).
|
||||
*
|
||||
* where size = size of stack frame in bytes (must be >0 and aligned to 16).
|
||||
* For framed functions the frame is created and the return address saved at
|
||||
* base of frame (Call0 ABI) or as determined by hardware (Windowed ABI). For
|
||||
* frameless functions, there is no frame and return address remains in
|
||||
* a0.
|
||||
*
|
||||
* Note: Because CPP macros expand to a single line, macros requiring
|
||||
* multi-line expansions are implemented as assembler macros.
|
||||
*/
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
/* Call0 */
|
||||
#define ENTRY(sz) entry1 sz
|
||||
.macro entry1 size=0x10
|
||||
addi sp, sp, -\size
|
||||
s32i a0, sp, 0
|
||||
.endm
|
||||
#define ENTRY0
|
||||
#define RET(sz) ret1 sz
|
||||
.macro ret1 size=0x10
|
||||
l32i a0, sp, 0
|
||||
addi sp, sp, \size
|
||||
ret
|
||||
.endm
|
||||
#define RET0 ret
|
||||
#else
|
||||
/* Windowed */
|
||||
#define ENTRY(sz) entry sp, sz
|
||||
#define ENTRY0 entry sp, 0x10
|
||||
#define RET(sz) retw
|
||||
#define RET0 retw
|
||||
#endif /* __XTENSA_CALL0_ABI__ */
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomically clear a memory location
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Control arrives here at _start from the reset vector or from crt0-app.S.
|
||||
*/
|
||||
|
||||
#include <arch/xtensa/xtensa_rtos.h>
|
||||
#include <xtensa/coreasm.h>
|
||||
|
||||
/* Exports */
|
||||
.global _start
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <arch/cpu.h>
|
||||
#include <kernel_structs.h>
|
||||
#include <inttypes.h>
|
||||
#include <kernel_arch_data.h>
|
||||
#include <xtensa/config/specreg.h>
|
||||
#include <xtensa-asm2-context.h>
|
||||
#if defined(CONFIG_XTENSA_ENABLE_BACKTRACE)
|
||||
|
@ -105,18 +104,6 @@ void z_xtensa_fatal_error(unsigned int reason, const z_arch_esf_t *esf)
|
|||
z_fatal_error(reason, esf);
|
||||
}
|
||||
|
||||
XTENSA_ERR_NORET void FatalErrorHandler(void)
|
||||
{
|
||||
z_xtensa_fatal_error(K_ERR_CPU_EXCEPTION, NULL);
|
||||
}
|
||||
|
||||
XTENSA_ERR_NORET void ReservedInterruptHandler(unsigned int intNo)
|
||||
{
|
||||
LOG_ERR("INTENABLE = 0x%x INTERRUPT = 0x%x (%x)",
|
||||
get_sreg(INTENABLE), (1 << intNo), intNo);
|
||||
z_xtensa_fatal_error(K_ERR_SPURIOUS_IRQ, NULL);
|
||||
}
|
||||
|
||||
void exit(int return_code)
|
||||
{
|
||||
#ifdef XT_SIMULATOR
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
#include <zephyr/types.h>
|
||||
#include <stdio.h>
|
||||
#include <arch/xtensa/xtensa_api.h>
|
||||
#include <kernel_arch_data.h>
|
||||
#include <arch/xtensa/irq.h>
|
||||
#include <sys/__assert.h>
|
||||
/*
|
||||
* @internal
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <kernel.h>
|
||||
#include <irq_offload.h>
|
||||
#include <arch/xtensa/arch.h>
|
||||
#include <arch/xtensa/xtensa_api.h>
|
||||
|
||||
/*
|
||||
* Xtensa core should support software interrupt in order to allow using
|
||||
|
|
|
@ -1,55 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2014 Wind River Systems, Inc.
|
||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* Copyright (c) 2021 Intel Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Xtensa kernel structure member offset definition file
|
||||
*
|
||||
* This module is responsible for the generation of the absolute symbols whose
|
||||
* value represents the member offsets for various Xtensa kernel
|
||||
* structures.
|
||||
*
|
||||
* All of the absolute symbols defined by this module will be present in the
|
||||
* final kernel or kernel ELF image (due to the linker's reference to
|
||||
* the _OffsetAbsSyms symbol).
|
||||
*
|
||||
* INTERNAL
|
||||
* It is NOT necessary to define the offset for every member of a structure.
|
||||
* Typically, only those members that are accessed by assembly language routines
|
||||
* are defined; however, it doesn't hurt to define all fields for the sake of
|
||||
* completeness.
|
||||
*/
|
||||
|
||||
#include <kernel.h>
|
||||
#include <kernel_arch_data.h>
|
||||
#include <gen_offset.h>
|
||||
#include <kernel_offsets.h>
|
||||
|
||||
/* Xtensa-specific k_thread structure member offsets */
|
||||
GEN_OFFSET_SYM(_callee_saved_t, topOfStack);
|
||||
GEN_OFFSET_SYM(_callee_saved_t, retval);
|
||||
|
||||
GEN_OFFSET_SYM(_thread_arch_t, preempCoprocReg);
|
||||
#if XCHAL_CP_NUM > 0
|
||||
GEN_OFFSET_SYM(tPreempCoprocReg, cpStack);
|
||||
#endif
|
||||
|
||||
/* Xtensa-specific _thread_arch_t structure member offsets */
|
||||
GEN_OFFSET_SYM(_thread_arch_t, flags);
|
||||
|
||||
/* Xtensa-specific ESF structure member offsets */
|
||||
GEN_OFFSET_SYM(__esf_t, sp);
|
||||
GEN_OFFSET_SYM(__esf_t, pc);
|
||||
|
||||
/* size of the entire __esf_t structure */
|
||||
GEN_ABSOLUTE_SYM(____esf_t_SIZEOF, sizeof(__esf_t));
|
||||
|
||||
/* size of the struct k_thread structure without save area for coproc regs */
|
||||
GEN_ABSOLUTE_SYM(_K_THREAD_NO_FLOAT_SIZEOF,
|
||||
sizeof(struct k_thread) - sizeof(tCoopCoprocReg) -
|
||||
sizeof(tPreempCoprocReg) + XT_CP_DESCR_SIZE);
|
||||
/* No offsets required in Xtensa, but this file must be present for
|
||||
* the build. Usage is the same as other architectures if you want to
|
||||
* add some.
|
||||
*/
|
||||
|
||||
GEN_ABS_SYM_END
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <arch/xtensa/xtensa_rtos.h>
|
||||
#include <xtensa/coreasm.h>
|
||||
|
||||
/* WINDOW OVERFLOW AND UNDERFLOW EXCEPTION VECTORS AND ALLOCA EXCEPTION
|
||||
* HANDLER
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Wind River Systems, Inc.
|
||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Private kernel definitions (XTENSA)
|
||||
*
|
||||
* This file contains private kernel structures definitions and various
|
||||
* other definitions for the XTENSA processors family architecture.
|
||||
*
|
||||
* This file is also included by assembly language files which must #define
|
||||
* _ASMLANGUAGE before including this header file. Note that kernel
|
||||
* assembly source files obtains structure offset values via "absolute symbols"
|
||||
* in the offsets.o module.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_ARCH_XTENSA_INCLUDE_KERNEL_ARCH_DATA_H_
|
||||
#define ZEPHYR_ARCH_XTENSA_INCLUDE_KERNEL_ARCH_DATA_H_
|
||||
|
||||
#include <toolchain.h>
|
||||
#include <linker/sections.h>
|
||||
#include <arch/cpu.h>
|
||||
|
||||
#if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
|
||||
#include <kernel.h> /* public kernel API */
|
||||
#include <zephyr/types.h>
|
||||
#include <sys/dlist.h>
|
||||
#include <sys/util.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Bitmask definitions for the struct k_thread->flags bit field */
|
||||
|
||||
/* executing context is interrupt handler */
|
||||
#define INT_ACTIVE (1 << 1)
|
||||
/* executing context is exception handler */
|
||||
#define EXC_ACTIVE (1 << 2)
|
||||
/* thread uses floating point unit */
|
||||
#define USE_FP 0x010
|
||||
|
||||
typedef struct __esf __esf_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*! _ASMLANGUAGE && ! __ASSEMBLER__ */
|
||||
|
||||
#endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_KERNEL_ARCH_DATA_H_ */
|
|
@ -12,20 +12,14 @@
|
|||
|
||||
#ifndef _ASMLANGUAGE
|
||||
#include <kernel_internal.h>
|
||||
#include <kernel_arch_data.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void FatalErrorHandler(void);
|
||||
extern void ReservedInterruptHandler(unsigned int intNo);
|
||||
extern void z_xtensa_fatal_error(unsigned int reason, const z_arch_esf_t *esf);
|
||||
|
||||
/* Defined in xtensa_context.S */
|
||||
extern void z_xt_coproc_init(void);
|
||||
|
||||
extern K_KERNEL_STACK_ARRAY_DEFINE(z_interrupt_stacks, CONFIG_MP_NUM_CPUS,
|
||||
CONFIG_ISR_STACK_SIZE);
|
||||
|
||||
|
@ -117,15 +111,15 @@ static inline void arch_cohere_stacks(struct k_thread *old_thread,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline bool arch_is_in_isr(void)
|
||||
{
|
||||
return arch_curr_cpu()->nested != 0U;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_KERNEL_ARCH_FUNC_H_ */
|
||||
|
|
|
@ -1,43 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Wind River Systems, Inc.
|
||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* Copyright (c) 2021 Intel Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_ARCH_XTENSA_INCLUDE_OFFSETS_SHORT_ARCH_H_
|
||||
#define ZEPHYR_ARCH_XTENSA_INCLUDE_OFFSETS_SHORT_ARCH_H_
|
||||
|
||||
#include <offsets.h>
|
||||
|
||||
/* kernel */
|
||||
#define KERNEL_OFFSET(field) _kernel_offset_to_##field
|
||||
|
||||
#define _kernel_offset_to_flags \
|
||||
(___kernel_t_arch_OFFSET + ___kernel_arch_t_flags_OFFSET)
|
||||
|
||||
/* end - kernel */
|
||||
|
||||
/* threads */
|
||||
#define THREAD_OFFSET(field) _thread_offset_to_##field
|
||||
|
||||
#define _thread_offset_to_sp \
|
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_topOfStack_OFFSET)
|
||||
|
||||
#define _thread_offset_to_retval \
|
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_retval_OFFSET)
|
||||
|
||||
#define _thread_offset_to_coopCoprocReg \
|
||||
(___thread_t_arch_OFFSET + ___thread_arch_t_coopCoprocReg_OFFSET)
|
||||
|
||||
#define _thread_offset_to_preempCoprocReg \
|
||||
(___thread_t_arch_OFFSET + ___thread_arch_t_preempCoprocReg_OFFSET)
|
||||
|
||||
#define _thread_offset_to_cpStack \
|
||||
(_thread_offset_to_preempCoprocReg + __tPreempCoprocReg_cpStack_OFFSET)
|
||||
|
||||
#define _thread_offset_to_cpEnable \
|
||||
(_thread_offset_to_cpStack + XT_CPENABLE)
|
||||
|
||||
/* end - threads */
|
||||
|
||||
#endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_OFFSETS_SHORT_ARCH_H_ */
|
||||
/* Empty File */
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <drivers/timer/system_timer.h>
|
||||
#include <sys_clock.h>
|
||||
#include <spinlock.h>
|
||||
#include <arch/xtensa/xtensa_rtos.h>
|
||||
|
||||
/**
|
||||
* @file
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <drivers/timer/system_timer.h>
|
||||
#include <sys_clock.h>
|
||||
#include <spinlock.h>
|
||||
#include <arch/xtensa/xtensa_rtos.h>
|
||||
|
||||
#define TIMER_IRQ UTIL_CAT(XCHAL_TIMER, \
|
||||
UTIL_CAT(CONFIG_XTENSA_TIMER_ID, _INTERRUPT))
|
||||
|
|
|
@ -20,17 +20,6 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
/**
|
||||
* @brief Exception Stack Frame
|
||||
*
|
||||
* A pointer to an "exception stack frame" (ESF) is passed as an argument
|
||||
* to exception handlers registered via nanoCpuExcConnect().
|
||||
*/
|
||||
struct __esf {
|
||||
/* FIXME - not finished yet */
|
||||
sys_define_gpr_with_alias(a1, sp);
|
||||
uint32_t pc;
|
||||
};
|
||||
|
||||
/* Xtensa uses a variable length stack frame depending on how many
|
||||
* register windows are in use. This isn't a struct type, it just
|
||||
|
|
|
@ -6,11 +6,51 @@
|
|||
#ifndef ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_IRQ_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_IRQ_H_
|
||||
|
||||
#include <arch/xtensa/xtensa_api.h>
|
||||
#include <xtensa/xtruntime.h>
|
||||
|
||||
#define CONFIG_GEN_IRQ_START_VECTOR 0
|
||||
|
||||
/*
|
||||
* Call this function to enable the specified interrupts.
|
||||
*
|
||||
* mask - Bit mask of interrupts to be enabled.
|
||||
*/
|
||||
static inline void z_xt_ints_on(unsigned int mask)
|
||||
{
|
||||
int val;
|
||||
|
||||
__asm__ volatile("rsr.intenable %0" : "=r"(val));
|
||||
val |= mask;
|
||||
__asm__ volatile("wsr.intenable %0; rsync" : : "r"(val));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Call this function to disable the specified interrupts.
|
||||
*
|
||||
* mask - Bit mask of interrupts to be disabled.
|
||||
*/
|
||||
static inline void z_xt_ints_off(unsigned int mask)
|
||||
{
|
||||
int val;
|
||||
|
||||
__asm__ volatile("rsr.intenable %0" : "=r"(val));
|
||||
val &= ~mask;
|
||||
__asm__ volatile("wsr.intenable %0; rsync" : : "r"(val));
|
||||
}
|
||||
|
||||
/*
|
||||
* Call this function to set the specified (s/w) interrupt.
|
||||
*/
|
||||
static inline void z_xt_set_intset(unsigned int arg)
|
||||
{
|
||||
#if XCHAL_HAVE_INTERRUPTS
|
||||
__asm__ volatile("wsr.intset %0; rsync" : : "r"(arg));
|
||||
#else
|
||||
ARG_UNUSED(arg);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MULTI_LEVEL_INTERRUPTS
|
||||
|
||||
/* for _soc_irq_*() */
|
||||
|
|
|
@ -1,109 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
* Copyright (c) 2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Per-arch thread definition
|
||||
*
|
||||
* This file contains definitions for
|
||||
*
|
||||
* struct _thread_arch
|
||||
* struct _callee_saved
|
||||
*
|
||||
* necessary to instantiate instances of struct k_thread.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_XTENSA_THREAD_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_XTENSA_THREAD_H_
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
#include <zephyr/types.h>
|
||||
#include <arch/xtensa/xtensa_context.h>
|
||||
|
||||
/*
|
||||
* The following structure defines the set of 'non-volatile' integer registers.
|
||||
* These registers must be preserved by a called C function. These are the
|
||||
* only registers that need to be saved/restored when a cooperative context
|
||||
* switch occurs.
|
||||
/* Xtensa doesn't use these structs, but Zephyr core requires they be
|
||||
* defined so they can be included in struct _thread_base. Dummy
|
||||
* field exists for sizeof compatibility with C++.
|
||||
*/
|
||||
|
||||
struct _callee_saved {
|
||||
/*
|
||||
* The following registers are considered non-volatile, i.e.
|
||||
* callee-saved, but their values are pushed onto the stack rather than
|
||||
* stored in the k_thread structure:
|
||||
*/
|
||||
uint32_t retval; /* a2 */
|
||||
XtExcFrame *topOfStack; /* a1 = sp */
|
||||
char dummy;
|
||||
};
|
||||
|
||||
typedef struct _callee_saved _callee_saved_t;
|
||||
|
||||
/*
|
||||
* The following structure defines the set of 'non-volatile' x87 FPU/MMX/SSE
|
||||
* registers. These registers must be preserved by a called C function.
|
||||
* These are the only registers that need to be saved/restored when a
|
||||
* cooperative context switch occurs.
|
||||
*/
|
||||
typedef struct s_coopCoprocReg {
|
||||
|
||||
/*
|
||||
* This structure intentionally left blank. Coprocessor's registers are
|
||||
* all 'volatile' and saved using the lazy context switch mechanism.
|
||||
*/
|
||||
|
||||
} tCoopCoprocReg;
|
||||
|
||||
/*
|
||||
* The following structure defines the set of 'volatile' x87 FPU/MMX/SSE
|
||||
* registers. These registers need not be preserved by a called C function.
|
||||
* Given that they are not preserved across function calls, they must be
|
||||
* save/restored (along with s_coopCoprocReg) when a preemptive context switch
|
||||
* occurs.
|
||||
*/
|
||||
typedef struct s_preempCoprocReg {
|
||||
/*
|
||||
* This structure reserved coprocessor control and save area memory.
|
||||
*/
|
||||
#if XCHAL_CP_NUM > 0
|
||||
char __aligned(4) cpStack[XT_CP_SIZE];
|
||||
#endif
|
||||
} tPreempCoprocReg;
|
||||
|
||||
/*
|
||||
* The thread control structure definition. It contains the
|
||||
* various fields to manage a _single_ thread.
|
||||
*/
|
||||
struct _thread_arch {
|
||||
/*
|
||||
* See the above flag definitions above for valid bit settings. This
|
||||
* field must remain near the start of struct k_thread, specifically
|
||||
* before any #ifdef'ed fields since the host tools currently use a
|
||||
* fixed offset to read the 'flags' field.
|
||||
*/
|
||||
uint32_t flags;
|
||||
|
||||
/*
|
||||
* The location of all floating point related structures/fields MUST be
|
||||
* located at the end of struct k_thread. This way only the threads
|
||||
* that actually utilize non-integer capabilities need to account for
|
||||
* the increased memory required for storing FP state when sizing
|
||||
* stacks.
|
||||
*
|
||||
* Given that stacks "grow down" on Xtensa, and the k_thread is located
|
||||
* at the start of a thread's "workspace" memory, the stacks of threads
|
||||
* that do not utilize floating point instruction can effectively
|
||||
* consume the memory occupied by the 'tCoopCoprocReg' and
|
||||
* 'tPreempCoprocReg' structures without ill effect.
|
||||
*/
|
||||
|
||||
/* non-volatile coprocessor's register storage */
|
||||
tCoopCoprocReg coopCoprocReg;
|
||||
|
||||
/* volatile coprocessor's register storage */
|
||||
tPreempCoprocReg preempCoprocReg;
|
||||
char dummy;
|
||||
};
|
||||
|
||||
typedef struct _thread_arch _thread_arch_t;
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_API_H_
|
||||
#define ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_API_H_
|
||||
|
||||
#include <xtensa/hal.h>
|
||||
#include "xtensa_rtos.h"
|
||||
#include "xtensa_context.h"
|
||||
|
||||
/*
|
||||
* Call this function to enable the specified interrupts.
|
||||
*
|
||||
* mask - Bit mask of interrupts to be enabled.
|
||||
*/
|
||||
static inline void z_xt_ints_on(unsigned int mask)
|
||||
{
|
||||
int val;
|
||||
|
||||
__asm__ volatile("rsr.intenable %0" : "=r"(val));
|
||||
val |= mask;
|
||||
__asm__ volatile("wsr.intenable %0; rsync" : : "r"(val));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Call this function to disable the specified interrupts.
|
||||
*
|
||||
* mask - Bit mask of interrupts to be disabled.
|
||||
*/
|
||||
static inline void z_xt_ints_off(unsigned int mask)
|
||||
{
|
||||
int val;
|
||||
|
||||
__asm__ volatile("rsr.intenable %0" : "=r"(val));
|
||||
val &= ~mask;
|
||||
__asm__ volatile("wsr.intenable %0; rsync" : : "r"(val));
|
||||
}
|
||||
|
||||
/*
|
||||
* Call this function to set the specified (s/w) interrupt.
|
||||
*/
|
||||
static inline void z_xt_set_intset(unsigned int arg)
|
||||
{
|
||||
#if XCHAL_HAVE_INTERRUPTS
|
||||
__asm__ volatile("wsr.intset %0; rsync" : : "r"(arg));
|
||||
#else
|
||||
ARG_UNUSED(arg);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Call this function to clear the specified (s/w or edge-triggered)
|
||||
* interrupt.
|
||||
*/
|
||||
static inline void _xt_set_intclear(unsigned int arg)
|
||||
{
|
||||
#if XCHAL_HAVE_INTERRUPTS
|
||||
__asm__ volatile("wsr.intclear %0; rsync" : : "r"(arg));
|
||||
#else
|
||||
ARG_UNUSED(arg);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_API_H_ */
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_CONFIG_H_
|
||||
#define ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_CONFIG_H_
|
||||
|
||||
#include <xtensa/hal.h>
|
||||
#include <xtensa/config/core.h>
|
||||
#include <xtensa/config/system.h> /* required for XSHAL_CLIB */
|
||||
|
||||
#include "xtensa_context.h"
|
||||
|
||||
/*
|
||||
* STACK REQUIREMENTS
|
||||
*
|
||||
* This section defines the minimum stack size, and the extra space required to
|
||||
* be allocated for saving coprocessor state and/or C library state information
|
||||
* (if thread safety is enabled for the C library). The sizes are in bytes.
|
||||
*
|
||||
* Stack sizes for individual threads should be derived from these minima based
|
||||
* on the maximum call depth of the task and the maximum level of interrupt
|
||||
* nesting. A minimum stack size is defined by XT_STACK_MIN_SIZE. This minimum
|
||||
* is based on the requirement for a task that calls nothing else but can be
|
||||
* interrupted. This assumes that interrupt handlers do not call more than a
|
||||
* few levels deep. If this is not true, i.e. one or more interrupt handlers
|
||||
* make deep calls then the minimum must be increased.
|
||||
*
|
||||
* If the Xtensa processor configuration includes coprocessors, then space is
|
||||
* allocated to save the coprocessor state on the stack.
|
||||
*
|
||||
* If thread safety is enabled for the C runtime library,
|
||||
* (XT_USE_THREAD_SAFE_CLIB is defined) then space is allocated to save the C
|
||||
* library context in the TCB.
|
||||
*
|
||||
* Allocating insufficient stack space is a common source of hard-to-find
|
||||
* errors. During development, it is best to enable the FreeRTOS stack
|
||||
* checking features.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* XT_USE_THREAD_SAFE_CLIB -- Define this to a nonzero value to enable
|
||||
* thread-safe use of the C library. This will require extra stack space to be
|
||||
* allocated for threads that use the C library reentrant functions. See below
|
||||
* for more information.
|
||||
*
|
||||
* NOTE: The Xtensa toolchain supports multiple C libraries and not all of them
|
||||
* support thread safety. Check your core configuration to see which C library
|
||||
* was chosen for your system.
|
||||
*
|
||||
* XT_STACK_MIN_SIZE -- The minimum stack size for any task. It is
|
||||
* recommended that you do not use a stack smaller than this for any task. In
|
||||
* case you want to use stacks smaller than this size, you must verify that the
|
||||
* smaller size(s) will work under all operating conditions.
|
||||
*
|
||||
* XT_STACK_EXTRA -- The amount of extra stack space to allocate for a
|
||||
* task that does not make C library reentrant calls. Add this to the amount of
|
||||
* stack space required by the task itself.
|
||||
*
|
||||
* XT_STACK_EXTRA_CLIB -- The amount of space to allocate for C library
|
||||
* state.
|
||||
*/
|
||||
|
||||
/* Extra space required for interrupt/exception hooks. */
|
||||
#ifdef XT_INTEXC_HOOKS
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
#define STK_INTEXC_EXTRA 0x200
|
||||
#else
|
||||
#define STK_INTEXC_EXTRA 0x180
|
||||
#endif
|
||||
#else
|
||||
#define STK_INTEXC_EXTRA 0
|
||||
#endif
|
||||
|
||||
/* Check C library thread safety support and compute size of C library save
|
||||
* area.
|
||||
*/
|
||||
#if XT_USE_THREAD_SAFE_CLIB > 0u
|
||||
#if XSHAL_CLIB == XTHAL_CLIB_XCLIB
|
||||
#define XT_HAVE_THREAD_SAFE_CLIB 0
|
||||
#error "Thread-safe operation is not yet supported for the XCLIB C library."
|
||||
#elif XSHAL_CLIB == XTHAL_CLIB_NEWLIB
|
||||
#define XT_HAVE_THREAD_SAFE_CLIB 1
|
||||
#if !defined __ASSEMBLER__
|
||||
#include <sys/reent.h>
|
||||
#define XT_CLIB_CONTEXT_AREA_SIZE ((sizeof(struct _reent) + 15) + (-16))
|
||||
#define XT_CLIB_GLOBAL_PTR _impure_ptr
|
||||
#endif
|
||||
#else
|
||||
#define XT_HAVE_THREAD_SAFE_CLIB 0
|
||||
#error "The selected C runtime library is not thread safe."
|
||||
#endif
|
||||
#else
|
||||
#define XT_CLIB_CONTEXT_AREA_SIZE 0
|
||||
#endif
|
||||
|
||||
/* Extra size -- interrupt frame plus coprocessor save area plus hook space.
|
||||
*
|
||||
* NOTE: Make sure XT_INTEXC_HOOKS is undefined unless you really need the
|
||||
* hooks.
|
||||
*/
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
#define XT_XTRA_SIZE (XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x10 + XT_CP_SIZE)
|
||||
#else
|
||||
#define XT_XTRA_SIZE (XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x20 + XT_CP_SIZE)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Space allocated for user code -- function calls and local variables.
|
||||
*
|
||||
* NOTE: This number can be adjusted to suit your needs. You must verify that
|
||||
* the amount of space you reserve is adequate for the worst-case conditions in
|
||||
* your application. NOTE: The windowed ABI requires more stack, since space
|
||||
* has to be reserved for spilling register windows.
|
||||
*/
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
#define XT_USER_SIZE 0x200
|
||||
#else
|
||||
#define XT_USER_SIZE 0x400
|
||||
#endif
|
||||
|
||||
/* Minimum recommended stack size. */
|
||||
#define XT_STACK_MIN_SIZE \
|
||||
((XT_XTRA_SIZE + XT_USER_SIZE) / sizeof(unsigned char))
|
||||
|
||||
/* OS overhead with and without C library thread context. */
|
||||
#define XT_STACK_EXTRA (XT_XTRA_SIZE)
|
||||
#define XT_STACK_EXTRA_CLIB (XT_XTRA_SIZE + XT_CLIB_CONTEXT_AREA_SIZE)
|
||||
|
||||
|
||||
#endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_CONFIG_H_ */
|
|
@ -1,323 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* XTENSA CONTEXT FRAMES AND MACROS FOR RTOS ASSEMBLER SOURCES
|
||||
*
|
||||
* This header contains definitions and macros for use primarily by Xtensa RTOS
|
||||
* assembly coded source files. It includes and uses the Xtensa hardware
|
||||
* abstraction layer (HAL) to deal with config specifics. It may also be
|
||||
* included in C source files.
|
||||
*
|
||||
* Supports only Xtensa Exception Architecture 2 (XEA2). XEA1 not supported.
|
||||
*
|
||||
* NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_CONTEXT_H_
|
||||
#define ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_CONTEXT_H_
|
||||
|
||||
#include <xtensa/config/tie.h>
|
||||
#include <xtensa/corebits.h>
|
||||
#include <xtensa/config/system.h>
|
||||
#include <xtensa/xtruntime-frames.h>
|
||||
|
||||
#ifdef __ASSEMBLER__
|
||||
#include <xtensa/coreasm.h>
|
||||
#else /* __ASSEMBLER__ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
/* Align a value up to nearest n-byte boundary, where n is a power of 2. */
|
||||
#define ALIGNUP(n, val) (((val) + (n)-1) & -(n))
|
||||
|
||||
/*
|
||||
* INTERRUPT/EXCEPTION STACK FRAME FOR A THREAD OR NESTED INTERRUPT
|
||||
*
|
||||
* A stack frame of this structure is allocated for any interrupt or exception.
|
||||
* It goes on the current stack. If the RTOS has a system stack for handling
|
||||
* interrupts, every thread stack must allow space for just one interrupt stack
|
||||
* frame, then nested interrupt stack frames go on the system stack.
|
||||
*
|
||||
* The frame includes basic registers (explicit) and "extra" registers
|
||||
* introduced by user TIE or the use of the MAC16 option in the user's Xtensa
|
||||
* config. The frame size is minimized by omitting regs not applicable to
|
||||
* user's config.
|
||||
*
|
||||
* For Windowed ABI, this stack frame includes the interruptee's base save
|
||||
* area, another base save area to manage gcc nested functions, and a little
|
||||
* temporary space to help manage the spilling of the register windows.
|
||||
*/
|
||||
|
||||
STRUCT_BEGIN
|
||||
STRUCT_FIELD(long, 4, XT_STK_, exit) /* exit point for dispatch */
|
||||
STRUCT_FIELD(long, 4, XT_STK_, pc) /* return PC */
|
||||
STRUCT_FIELD(long, 4, XT_STK_, ps) /* return PS */
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a0)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a1) /* stack pointer before irq */
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a2)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a3)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a4)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a5)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a6)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a7)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a8)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a9)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a10)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a11)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a12)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a13)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a14)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a15)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, sar)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, exccause)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, excvaddr)
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
STRUCT_FIELD(long, 4, XT_STK_, lbeg)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, lend)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, lcount)
|
||||
#endif
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
/* Temporary space for saving stuff during window spill */
|
||||
STRUCT_FIELD(long, 4, XT_STK_, tmp0)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, tmp1)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, tmp2)
|
||||
#endif
|
||||
#ifdef XT_USE_SWPRI
|
||||
/* Storage for virtual priority mask */
|
||||
STRUCT_FIELD(long, 4, XT_STK_, vpri)
|
||||
#endif
|
||||
#ifdef XT_USE_OVLY
|
||||
/* Storage for overlay state */
|
||||
STRUCT_FIELD(long, 4, XT_STK_, ovly)
|
||||
#endif
|
||||
STRUCT_END(XtExcFrame)
|
||||
|
||||
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
|
||||
#define XT_STK_NEXT1 XtExcFrameSize
|
||||
#else
|
||||
#define XT_STK_NEXT1 sizeof(XtExcFrame)
|
||||
#endif
|
||||
|
||||
/* Allocate extra storage if needed */
|
||||
#if XCHAL_EXTRA_SA_SIZE != 0
|
||||
|
||||
#if XCHAL_EXTRA_SA_ALIGN <= 16
|
||||
#define XT_STK_EXTRA ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1)
|
||||
#else
|
||||
/* If need more alignment than stack, add space for dynamic alignment */
|
||||
#define XT_STK_EXTRA (ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1) \
|
||||
+ XCHAL_EXTRA_SA_ALIGN)
|
||||
#endif
|
||||
#define XT_STK_NEXT2 (XT_STK_EXTRA + XCHAL_EXTRA_SA_SIZE)
|
||||
|
||||
#else
|
||||
|
||||
#define XT_STK_NEXT2 XT_STK_NEXT1
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the frame size. Add space for 4 registers (interruptee's base save
|
||||
* area) and some space for gcc nested functions if any.
|
||||
*/
|
||||
#define XT_STK_FRMSZ (ALIGNUP(0x10, XT_STK_NEXT2) + 0x20)
|
||||
|
||||
|
||||
/*
|
||||
* SOLICITED STACK FRAME FOR A THREAD
|
||||
*
|
||||
* A stack frame of this structure is allocated whenever a thread enters the
|
||||
* RTOS kernel intentionally (and synchronously) to submit to thread
|
||||
* scheduling. It goes on the current thread's stack.
|
||||
*
|
||||
* The solicited frame only includes registers that are required to be
|
||||
* preserved by the callee according to the compiler's ABI conventions, some
|
||||
* space to save the return address for returning to the caller, and the
|
||||
* caller's PS register. For Windowed ABI, this stack frame includes the
|
||||
* caller's base save area.
|
||||
*
|
||||
* Note on XT_SOL_EXIT field:
|
||||
*
|
||||
* It is necessary to distinguish a solicited from an interrupt stack frame.
|
||||
* This field corresponds to XT_STK_EXIT in the interrupt stack frame and is
|
||||
* always at the same offset (0). It can be written with a code (usually 0) to
|
||||
* distinguish a solicted frame from an interrupt frame. An RTOS port may opt
|
||||
* to ignore this field if it has another way of distinguishing frames.
|
||||
*/
|
||||
|
||||
STRUCT_BEGIN
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, exit)
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, pc)
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, ps)
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, next)
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a12) /* should be on 16-byte alignment */
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a13)
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a14)
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a15)
|
||||
#else
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a0) /* should be on 16-byte alignment */
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a1)
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a2)
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a3)
|
||||
#endif
|
||||
STRUCT_END(XtSolFrame)
|
||||
|
||||
/* Size of solicited stack frame */
|
||||
#define XT_SOL_FRMSZ ALIGNUP(0x10, XtSolFrameSize)
|
||||
|
||||
|
||||
/*
|
||||
* CO-PROCESSOR STATE SAVE AREA FOR A THREAD
|
||||
*
|
||||
* The RTOS must provide an area per thread to save the state of co-processors
|
||||
* when that thread does not have control. Co-processors are context-switched
|
||||
* lazily (on demand) only when a new thread uses a co-processor instruction,
|
||||
* otherwise a thread retains ownership of the co-processor even when it loses
|
||||
* control of the processor. An Xtensa co-processor exception is triggered when
|
||||
* any co-processor instruction is executed by a thread that is not the owner,
|
||||
* and the context switch of that co-processor is then performed by the handler.
|
||||
* Ownership represents which thread's state is currently in the co-processor.
|
||||
*
|
||||
* Co-processors may not be used by interrupt or exception handlers. If a
|
||||
* co-processor instruction is executed by an interrupt or exception handler,
|
||||
* the co-processor exception handler will trigger a kernel panic and freeze.
|
||||
* This restriction is introduced to reduce the overhead of saving and
|
||||
* restoring co-processor state (which can be quite large) and in particular
|
||||
* remove that overhead from interrupt handlers.
|
||||
*
|
||||
* The co-processor state save area may be in any convenient per-thread
|
||||
* location such as in the thread control block or above the thread stack area.
|
||||
* It need not be in the interrupt stack frame since interrupts don't use
|
||||
* co-processors.
|
||||
*
|
||||
* Along with the save area for each co-processor, two bitmasks with flags per
|
||||
* co-processor (laid out as in the CPENABLE reg) help manage context-switching
|
||||
* co-processors as efficiently as possible:
|
||||
*
|
||||
* XT_CPENABLE
|
||||
*
|
||||
* The contents of a non-running thread's CPENABLE register. It represents the
|
||||
* co-processors owned (and whose state is still needed) by the thread. When a
|
||||
* thread is preempted, its CPENABLE is saved here. When a thread solicits a
|
||||
* context-swtich, its CPENABLE is cleared - the compiler has saved the
|
||||
* (caller-saved) co-proc state if it needs to. When a non-running thread
|
||||
* loses ownership of a CP, its bit is cleared. When a thread runs, it's
|
||||
* XT_CPENABLE is loaded into the CPENABLE reg. Avoids co-processor exceptions
|
||||
* when no change of ownership is needed.
|
||||
*
|
||||
* XT_CPSTORED
|
||||
*
|
||||
* A bitmask with the same layout as CPENABLE, a bit per co-processor.
|
||||
* Indicates whether the state of each co-processor is saved in the state save
|
||||
* area. When a thread enters the kernel, only the state of co-procs still
|
||||
* enabled in CPENABLE is saved. When the co-processor exception handler
|
||||
* assigns ownership of a co-processor to a thread, it restores the saved state
|
||||
* only if this bit is set, and clears this bit.
|
||||
*
|
||||
* XT_CP_CS_ST
|
||||
*
|
||||
* A bitmask with the same layout as CPENABLE, a bit per co-processor.
|
||||
* Indicates whether callee-saved state is saved in the state save area.
|
||||
* Callee-saved state is saved by itself on a solicited context switch, and
|
||||
* restored when needed by the coprocessor exception handler. Unsolicited
|
||||
* switches will cause the entire coprocessor to be saved when necessary.
|
||||
*
|
||||
* XT_CP_ASA
|
||||
*
|
||||
* Pointer to the aligned save area. Allows it to be aligned more than the
|
||||
* overall save area (which might only be stack-aligned or TCB-aligned).
|
||||
* Especially relevant for Xtensa cores configured with a very large data path
|
||||
* that requires alignment greater than 16 bytes (ABI stack alignment).
|
||||
*/
|
||||
|
||||
#define XT_CP_DESCR_SIZE 12
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
|
||||
/* Offsets of each coprocessor save area within the 'aligned save area': */
|
||||
#define XT_CP0_SA 0
|
||||
#define XT_CP1_SA ALIGNUP(XCHAL_CP1_SA_ALIGN, XT_CP0_SA + XCHAL_CP0_SA_SIZE)
|
||||
#define XT_CP2_SA ALIGNUP(XCHAL_CP2_SA_ALIGN, XT_CP1_SA + XCHAL_CP1_SA_SIZE)
|
||||
#define XT_CP3_SA ALIGNUP(XCHAL_CP3_SA_ALIGN, XT_CP2_SA + XCHAL_CP2_SA_SIZE)
|
||||
#define XT_CP4_SA ALIGNUP(XCHAL_CP4_SA_ALIGN, XT_CP3_SA + XCHAL_CP3_SA_SIZE)
|
||||
#define XT_CP5_SA ALIGNUP(XCHAL_CP5_SA_ALIGN, XT_CP4_SA + XCHAL_CP4_SA_SIZE)
|
||||
#define XT_CP6_SA ALIGNUP(XCHAL_CP6_SA_ALIGN, XT_CP5_SA + XCHAL_CP5_SA_SIZE)
|
||||
#define XT_CP7_SA ALIGNUP(XCHAL_CP7_SA_ALIGN, XT_CP6_SA + XCHAL_CP6_SA_SIZE)
|
||||
#define XT_CP_SA_SIZE ALIGNUP(16, XT_CP7_SA + XCHAL_CP7_SA_SIZE)
|
||||
|
||||
/* Offsets within the overall save area: */
|
||||
|
||||
/* (2 bytes) coprocessors active for this thread */
|
||||
#define XT_CPENABLE 0
|
||||
|
||||
/* (2 bytes) coprocessors saved for this thread */
|
||||
#define XT_CPSTORED 2
|
||||
|
||||
/* (2 bytes) coprocessor callee-saved regs stored for this thread */
|
||||
#define XT_CP_CS_ST 4
|
||||
|
||||
/* (4 bytes) ptr to aligned save area */
|
||||
#define XT_CP_ASA 8
|
||||
|
||||
/* Overall size allows for dynamic alignment: */
|
||||
#define XT_CP_SIZE ALIGNUP(XCHAL_TOTAL_SA_ALIGN, \
|
||||
XT_CP_DESCR_SIZE + XT_CP_SA_SIZE)
|
||||
#else
|
||||
#define XT_CP_SIZE 0
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN
|
||||
*
|
||||
* Convenient where the frame size requirements are the same for both ABIs.
|
||||
* ENTRY(sz), RET(sz) are for framed functions (have locals or make calls).
|
||||
* ENTRY0, RET0 are for frameless functions (no locals, no calls).
|
||||
*
|
||||
* where size = size of stack frame in bytes (must be >0 and aligned to 16).
|
||||
* For framed functions the frame is created and the return address saved at
|
||||
* base of frame (Call0 ABI) or as determined by hardware (Windowed ABI). For
|
||||
* frameless functions, there is no frame and return address remains in
|
||||
* a0.
|
||||
*
|
||||
* Note: Because CPP macros expand to a single line, macros requiring
|
||||
* multi-line expansions are implemented as assembler macros.
|
||||
*/
|
||||
|
||||
#ifdef __ASSEMBLER__
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
/* Call0 */
|
||||
#define ENTRY(sz) entry1 sz
|
||||
.macro entry1 size=0x10
|
||||
addi sp, sp, -\size
|
||||
s32i a0, sp, 0
|
||||
.endm
|
||||
#define ENTRY0
|
||||
#define RET(sz) ret1 sz
|
||||
.macro ret1 size=0x10
|
||||
l32i a0, sp, 0
|
||||
addi sp, sp, \size
|
||||
ret
|
||||
.endm
|
||||
#define RET0 ret
|
||||
#else
|
||||
/* Windowed */
|
||||
#define ENTRY(sz) entry sp, sz
|
||||
#define ENTRY0 entry sp, 0x10
|
||||
#define RET(sz) retw
|
||||
#define RET0 retw
|
||||
#endif /* __XTENSA_CALL0_ABI__ */
|
||||
#else /* __ASSEMBLER__ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
|
||||
#endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_CONTEXT_H_ */
|
|
@ -1,204 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* RTOS-SPECIFIC INFORMATION FOR XTENSA RTOS ASSEMBLER SOURCES
|
||||
* (FreeRTOS Port)
|
||||
*
|
||||
* This header is the primary glue between generic Xtensa RTOS support
|
||||
* sources and a specific RTOS port for Xtensa. It contains definitions
|
||||
* and macros for use primarily by Xtensa assembly coded source files.
|
||||
*
|
||||
* Macros in this header map callouts from generic Xtensa files to specific
|
||||
* RTOS functions. It may also be included in C source files.
|
||||
*
|
||||
* Xtensa RTOS ports support all RTOS-compatible configurations of the Xtensa
|
||||
* architecture, using the Xtensa hardware abstraction layer (HAL) to deal
|
||||
* with configuration specifics.
|
||||
*
|
||||
* Should be included by all Xtensa generic and RTOS port-specific sources.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_RTOS_H_
|
||||
#define ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_RTOS_H_
|
||||
|
||||
#ifdef __ASSEMBLER__
|
||||
#include <xtensa/coreasm.h>
|
||||
#else
|
||||
#include <xtensa/config/core.h>
|
||||
#endif
|
||||
|
||||
#include <xtensa/corebits.h>
|
||||
#include <xtensa/config/system.h>
|
||||
|
||||
|
||||
/*
|
||||
* Convert Zephyr definitions to XTENSA definitions.
|
||||
*/
|
||||
|
||||
#undef XT_SIMULATOR
|
||||
#undef XT_BOARD
|
||||
#ifdef CONFIG_SIMULATOR_XTENSA
|
||||
#define XT_SIMULATOR 1
|
||||
#else
|
||||
#define XT_BOARD 1
|
||||
#endif
|
||||
|
||||
#undef XT_CLOCK_FREQ
|
||||
#define XT_CLOCK_FREQ DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency)
|
||||
|
||||
#ifndef XT_TIMER_INDEX
|
||||
#if defined configXT_TIMER_INDEX
|
||||
/* Index of hardware timer to be used */
|
||||
#define XT_TIMER_INDEX configXT_TIMER_INDEX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef XT_INTEXC_HOOKS
|
||||
#if configXT_INTEXC_HOOKS
|
||||
#define XT_INTEXC_HOOKS 1 /* Enables exception hooks */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (!XT_SIMULATOR) && (!XT_BOARD)
|
||||
#error Either XT_SIMULATOR or XT_BOARD must be defined.
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Name of RTOS (for messages).
|
||||
*/
|
||||
#define XT_RTOS_NAME Zephyr
|
||||
|
||||
/*
|
||||
* Define for enabling RTOS specific code. Enable only one of below lines.
|
||||
*/
|
||||
#define XT_RTOS_IS_ZEPHYR_OS 1
|
||||
#undef XT_RTOS_IS_FREE_RTOS
|
||||
|
||||
/*
|
||||
* Check some Xtensa configuration requirements and report error if not met.
|
||||
* Error messages can be customize to the RTOS port.
|
||||
*/
|
||||
|
||||
#if !XCHAL_HAVE_XEA2
|
||||
#error "Zephyr/Xtensa requires XEA2 (exception architecture 2)."
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RTOS CALLOUT MACROS MAPPED TO RTOS PORT-SPECIFIC FUNCTIONS.
|
||||
*
|
||||
* Define callout macros used in generic Xtensa code to interact with the RTOS.
|
||||
* The macros are simply the function names for use in calls from assembler
|
||||
* code.
|
||||
* Some of these functions may call back to generic functions in
|
||||
* xtensa_context.h .
|
||||
*/
|
||||
|
||||
/*
|
||||
* Inform RTOS of entry into an interrupt handler that will affect it.
|
||||
* Allows RTOS to manage switch to any system stack and count nesting level.
|
||||
* Called after minimal context has been saved, with interrupts disabled.
|
||||
* RTOS port can call0 _xt_context_save to save the rest of the context.
|
||||
* May only be called from assembly code by the 'call0' instruction.
|
||||
*/
|
||||
#define XT_RTOS_INT_ENTER _zxt_int_enter
|
||||
|
||||
/*
|
||||
* Inform RTOS of completion of an interrupt handler, and give control to
|
||||
* RTOS to perform thread/task scheduling, switch back from any system stack
|
||||
* and restore the context, and return to the exit dispatcher saved in the
|
||||
* stack frame at XT_STK_EXIT. RTOS port can call0 _xt_context_restore
|
||||
* to save the context saved in XT_RTOS_INT_ENTER via _xt_context_save,
|
||||
* leaving only a minimal part of the context to be restored by the exit
|
||||
* dispatcher. This function does not return to the place it was called from.
|
||||
* May only be called from assembly code by the 'call0' instruction.
|
||||
*/
|
||||
#define XT_RTOS_INT_EXIT _zxt_int_exit
|
||||
|
||||
/*
|
||||
* Inform RTOS of the occurrence of a tick timer interrupt.
|
||||
* If RTOS has no tick timer, leave XT_RTOS_TIMER_INT undefined.
|
||||
* May be coded in or called from C or assembly, per ABI conventions.
|
||||
* RTOS may optionally define XT_TICK_PER_SEC in its own way (eg. macro).
|
||||
*/
|
||||
#define XT_RTOS_TIMER_INT _zxt_timer_int
|
||||
|
||||
#if CONFIG_TICKLESS_KERNEL
|
||||
#define XT_TICK_PER_SEC 1000
|
||||
#else
|
||||
#define XT_TICK_PER_SEC CONFIG_SYS_CLOCK_TICKS_PER_SEC
|
||||
#endif /* CONFIG_TICKLESS_KERNEL */
|
||||
|
||||
/*
|
||||
* Return in a15 the base address of the co-processor state save area for the
|
||||
* thread that triggered a co-processor exception, or 0 if no thread was
|
||||
* running. The state save area is structured as defined in xtensa_context.h
|
||||
* and has size XT_CP_SIZE. Co-processor instructions should only be used in
|
||||
* thread code, never in interrupt handlers or the RTOS kernel. May only be
|
||||
* called from assembly code and by the 'call0' instruction. A result of 0
|
||||
* indicates an unrecoverable error.
|
||||
*
|
||||
* The implementation may use only a2-4, a15 (all other regs must be
|
||||
* preserved).
|
||||
*/
|
||||
#define XT_RTOS_CP_STATE _zxt_task_coproc_state
|
||||
|
||||
|
||||
/*
|
||||
* HOOKS TO DYNAMICALLY INSTALL INTERRUPT AND EXCEPTION HANDLERS PER LEVEL.
|
||||
*
|
||||
* This Xtensa RTOS port provides hooks for dynamically installing exception
|
||||
* and interrupt handlers to facilitate automated testing where each test case
|
||||
* can install its own handler for user exceptions and each interrupt priority
|
||||
* (level). This consists of an array of function pointers indexed by interrupt
|
||||
* priority, with index 0 being the user exception handler hook. Each entry in
|
||||
* the array is initially 0, and may be replaced by a function pointer of type
|
||||
* XT_INTEXC_HOOK. A handler may be uninstalled by installing 0.
|
||||
*
|
||||
* The handler for low and medium priority obeys ABI conventions so may be
|
||||
* coded in C. For the exception handler, the cause is the contents of the
|
||||
* EXCCAUSE reg, and the result is -1 if handled, else the cause (still needs
|
||||
* handling). For interrupt handlers, the cause is a mask of pending enabled
|
||||
* interrupts at that level, and the result is the same mask with the bits for
|
||||
* the handled interrupts cleared (those not cleared still need handling). This
|
||||
* allows a test case to either pre-handle or override the default handling for
|
||||
* the exception or interrupt level (see xtensa_vectors.S).
|
||||
*
|
||||
* High priority handlers (including NMI) must be coded in assembly, are always
|
||||
* called by 'call0' regardless of ABI, must preserve all registers except a0,
|
||||
* and must not use or modify the interrupted stack. The hook argument 'cause'
|
||||
* is not passed and the result is ignored, so as not to burden the caller
|
||||
* with saving and restoring a2 (it assumes only one interrupt per level - see
|
||||
* the discussion in high priority interrupts in xtensa_vectors.S). The handler
|
||||
* therefore should be coded to prototype 'void h(void)' even though it plugs
|
||||
* into an array of handlers of prototype 'unsigned h(unsigned)'.
|
||||
*
|
||||
* To enable interrupt/exception hooks, compile the RTOS with
|
||||
* '-DXT_INTEXC_HOOKS'.
|
||||
*/
|
||||
#define XT_INTEXC_HOOK_NUM (1 + XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
typedef unsigned int (*XT_INTEXC_HOOK)(unsigned int cause);
|
||||
extern volatile XT_INTEXC_HOOK _xt_intexc_hooks[XT_INTEXC_HOOK_NUM];
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* CONVENIENCE INCLUSIONS.
|
||||
*
|
||||
* Ensures RTOS specific files need only include this one Xtensa-generic
|
||||
* header. These headers are included last so they can use the RTOS
|
||||
* definitions above.
|
||||
*/
|
||||
|
||||
#include "xtensa_context.h"
|
||||
|
||||
#ifdef XT_RTOS_TIMER_INT
|
||||
#include "xtensa_timer.h"
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_RTOS_H_ */
|
|
@ -1,155 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* XTENSA INFORMATION FOR RTOS TICK TIMER AND CLOCK FREQUENCY
|
||||
*
|
||||
* This header contains definitions and macros for use primarily by Xtensa
|
||||
* RTOS assembly coded source files. It includes and uses the Xtensa hardware
|
||||
* abstraction layer (HAL) to deal with config specifics. It may also be
|
||||
* included in C source files.
|
||||
*
|
||||
* User may edit to modify timer selection and to specify clock frequency and
|
||||
* tick duration to match timer interrupt to the real-time tick duration.
|
||||
*
|
||||
* If the RTOS has no timer interrupt, then there is no tick timer and the
|
||||
* clock frequency is irrelevant, so all of these macros are left undefined
|
||||
* and the Xtensa core configuration need not have a timer.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_TIMER_H_
|
||||
#define ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_TIMER_H_
|
||||
|
||||
#ifdef __ASSEMBLER__
|
||||
#include <xtensa/coreasm.h>
|
||||
#endif
|
||||
|
||||
#include <xtensa/corebits.h>
|
||||
#include <xtensa/config/system.h>
|
||||
|
||||
#include "xtensa_rtos.h" /* in case this wasn't included directly */
|
||||
|
||||
#define USE_INTERNAL_TIMER 1
|
||||
#define EXTERNAL_TIMER_IRQ -1
|
||||
|
||||
#if USE_INTERNAL_TIMER || (EXTERNAL_TIMER_IRQ < 0)
|
||||
/*
|
||||
* Select timer to use for periodic tick, and determine its interrupt number
|
||||
* and priority. User may specify a timer by defining XT_TIMER_INDEX with -D,
|
||||
* in which case its validity is checked (it must exist in this core and must
|
||||
* not be on a high priority interrupt - an error will be reported in invalid).
|
||||
* Otherwise select the first low or medium priority interrupt timer available.
|
||||
*/
|
||||
#if XCHAL_NUM_TIMERS == 0
|
||||
#error "This Xtensa configuration is unsupported, it has no timers."
|
||||
#endif /* XCHAL_NUM_TIMERS */
|
||||
|
||||
#ifndef XT_TIMER_INDEX
|
||||
#if XCHAL_TIMER3_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
|
||||
#if XCHAL_INT_LEVEL(XCHAL_TIMER3_INTERRUPT) <= XCHAL_EXCM_LEVEL
|
||||
#undef XT_TIMER_INDEX
|
||||
#define XT_TIMER_INDEX 3
|
||||
#endif
|
||||
#endif
|
||||
#if XCHAL_TIMER2_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
|
||||
#if XCHAL_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL
|
||||
#undef XT_TIMER_INDEX
|
||||
#define XT_TIMER_INDEX 2
|
||||
#endif
|
||||
#endif
|
||||
#if XCHAL_TIMER1_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
|
||||
#if XCHAL_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL
|
||||
#undef XT_TIMER_INDEX
|
||||
#define XT_TIMER_INDEX 1
|
||||
#endif
|
||||
#endif
|
||||
#if XCHAL_TIMER0_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
|
||||
#if XCHAL_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL
|
||||
#undef XT_TIMER_INDEX
|
||||
#define XT_TIMER_INDEX 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifndef XT_TIMER_INDEX
|
||||
#error "There is no suitable timer in this Xtensa configuration."
|
||||
#endif
|
||||
|
||||
#define XT_CCOMPARE ((CCOMPARE) + (XT_TIMER_INDEX))
|
||||
#define XT_TIMER_INTNUM XCHAL_TIMER_INTERRUPT(XT_TIMER_INDEX)
|
||||
#if XT_TIMER_INTNUM == XTHAL_TIMER_UNCONFIGURED
|
||||
#error "The timer selected by XT_TIMER_INDEX does not exist in this core."
|
||||
#endif
|
||||
#else /* Case of an external timer which is not emulated by internal timer */
|
||||
#define XT_TIMER_INTNUM EXTERNAL_TIMER_IRQ
|
||||
#endif /* USE_INTERNAL_TIMER || (EXTERNAL_TIMER_IRQ < 0) */
|
||||
|
||||
#if USE_INTERNAL_TIMER
|
||||
#define XT_TIMER_INTPRI XCHAL_INT_LEVEL(XT_TIMER_INTNUM)
|
||||
#else
|
||||
#define XT_TIMER_INTPRI EXTERNAL_TIMER_IRQ_PRIORITY
|
||||
#endif /* USE_INTERNAL_TIMER */
|
||||
|
||||
#if XT_TIMER_INTPRI > XCHAL_EXCM_LEVEL
|
||||
#error "The timer interrupt cannot be high priority (use medium or low)."
|
||||
#endif
|
||||
|
||||
#define XT_TIMER_INTEN (1 << (XT_TIMER_INTNUM))
|
||||
|
||||
/*
|
||||
* Set processor clock frequency, used to determine clock divisor for timer
|
||||
* tick. User should BE SURE TO ADJUST THIS for the Xtensa platform being
|
||||
* used. If using a supported board via the board-independent API defined in
|
||||
* xtbsp.h, this may be left undefined and frequency and tick divisor will be
|
||||
* computed and cached during run-time initialization.
|
||||
*
|
||||
* NOTE ON SIMULATOR: Under the Xtensa instruction set simulator, the frequency
|
||||
* can only be estimated because it depends on the speed of the host and the
|
||||
* version of the simulator. Also because it runs much slower than hardware,
|
||||
* it is not possible to achieve real-time performance for most applications
|
||||
* under the simulator. A frequency too low does not allow enough time between
|
||||
* timer interrupts, starving threads. To obtain a more convenient but
|
||||
* non-real-time tick duration on the simulator, compile with xt-xcc option
|
||||
* "-DXT_SIMULATOR". Adjust this frequency to taste (it's not real-time
|
||||
* anyway!).
|
||||
*/
|
||||
#if defined(XT_SIMULATOR) && !defined(XT_CLOCK_FREQ)
|
||||
#define XT_CLOCK_FREQ DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency)
|
||||
#endif
|
||||
|
||||
#if !defined(XT_CLOCK_FREQ) && !defined(XT_BOARD)
|
||||
#error "XT_CLOCK_FREQ must be defined for the target platform."
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default number of timer "ticks" per second (default 100 for 10ms tick).
|
||||
* RTOS may define this in its own way (if applicable) in xtensa_rtos.h.
|
||||
* User may redefine this to an optimal value for the application, either by
|
||||
* editing this here or in xtensa_rtos.h, or compiling with xt-xcc option
|
||||
* "-DXT_TICK_PER_SEC=<value>" where <value> is a suitable number.
|
||||
*/
|
||||
#ifndef XT_TICK_PER_SEC
|
||||
#if CONFIG_TICKLESS_KERNEL
|
||||
#define XT_TICK_PER_SEC 1000 /* In tickless kernel 1TICK = 1msec */
|
||||
#else
|
||||
#define XT_TICK_PER_SEC CONFIG_SYS_CLOCK_TICKS_PER_SEC
|
||||
#endif /* CONFIG_TICKLESS_KERNEL */
|
||||
#endif /* XT_TICK_PER_SEC */
|
||||
|
||||
/*
|
||||
* Derivation of clock divisor for timer tick and interrupt (one per tick).
|
||||
*/
|
||||
#ifdef XT_CLOCK_FREQ
|
||||
#define XT_TICK_DIVISOR (XT_CLOCK_FREQ / XT_TICK_PER_SEC)
|
||||
#endif
|
||||
|
||||
#if USE_INTERNAL_TIMER || (EXTERNAL_TIMER_IRQ < 0)
|
||||
#ifndef __ASSEMBLER__
|
||||
extern unsigned int _xt_tick_divisor;
|
||||
extern void z_xt_tick_divisor_init(void);
|
||||
#endif
|
||||
|
||||
#endif // Internal/External timer
|
||||
|
||||
#endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_TIMER_H_ */
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <arch/xtensa/xtensa_api.h>
|
||||
#include <xtensa/xtruntime.h>
|
||||
#include <irq_nextlevel.h>
|
||||
#include <xtensa/hal.h>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <arch/xtensa/xtensa_api.h>
|
||||
#include <xtensa/xtruntime.h>
|
||||
#include <irq_nextlevel.h>
|
||||
#include <xtensa/hal.h>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue