diff options
author | Mazen NEIFER <mazen@nestwave.com> | 2017-01-18 22:51:10 +0100 |
---|---|---|
committer | Andrew Boie <andrew.p.boie@intel.com> | 2017-01-30 09:02:29 -0800 |
commit | 90deb32a775a03be19f72e58fc899e8f70e012ee (patch) | |
tree | 7fde0322dfddc60873b93c9529e02ee1d8d336ac | |
parent | 7b21bfdbe790a8e04f97970c3cad0db6b93faebb (diff) |
Xtensa port: Added Xtensa header generic files.
Change-Id: Ia2202080d09008fbfd4e803cd5266aa8caa16388
Signed-off-by: Mazen NEIFER <mazen@nestwave.com>
-rw-r--r-- | arch/xtensa/include/xtensa_api.h | 115 | ||||
-rw-r--r-- | arch/xtensa/include/xtensa_config.h | 158 | ||||
-rw-r--r-- | arch/xtensa/include/xtensa_context.h | 320 | ||||
-rw-r--r-- | arch/xtensa/include/xtensa_rtos.h | 228 | ||||
-rw-r--r-- | arch/xtensa/include/xtensa_timer.h | 164 |
5 files changed, 985 insertions, 0 deletions
diff --git a/arch/xtensa/include/xtensa_api.h b/arch/xtensa/include/xtensa_api.h new file mode 100644 index 000000000..6cfb6cabf --- /dev/null +++ b/arch/xtensa/include/xtensa_api.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2016 Cadence Design Systems, Inc. + * + * 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. + */ + +/****************************************************************************** + Xtensa-specific API for RTOS ports. +******************************************************************************/ + +#ifndef __XTENSA_API_H__ +#define __XTENSA_API_H__ + +#include <xtensa/hal.h> +#include "xtensa_rtos.h" +#include "xtensa_context.h" + + +/* Typedef for C-callable interrupt handler function */ +typedef void (*xt_handler)(void *); + +/* Typedef for C-callable exception handler function */ +typedef void (*xt_exc_handler)(XtExcFrame *); + + +/* +------------------------------------------------------------------------------- + Call this function to set a handler for the specified exception. + + n - Exception number (type) + f - Handler function address, NULL to uninstall handler. + + The handler will be passed a pointer to the exception frame, which is created + on the stack of the thread that caused the exception. + + If the handler returns, the thread context will be restored and the faulting + instruction will be retried. Any values in the exception frame that are + modified by the handler will be restored as part of the context. For details + of the exception frame structure see xtensa_context.h. +------------------------------------------------------------------------------- +*/ +extern xt_exc_handler _xt_set_exception_handler(int n, xt_exc_handler f); + + +/* +------------------------------------------------------------------------------- + Call this function to set a handler for the specified interrupt. + + n - Interrupt number. + f - Handler function address, NULL to uninstall handler. + arg - Argument to be passed to handler. +------------------------------------------------------------------------------- +*/ +#if XT_RTOS_IS_ZEPHYR_OS +#define _xt_set_interrupt_handler _irq_handler_set /* Map it to Zephyr's one */ +#else +extern xt_handler _xt_set_interrupt_handler(int n, xt_handler f, void * arg); +#endif + + +/* +------------------------------------------------------------------------------- + Call this function to enable the specified interrupts. + + mask - Bit mask of interrupts to be enabled. +------------------------------------------------------------------------------- +*/ +extern void _xt_ints_on(unsigned int mask); + + +/* +------------------------------------------------------------------------------- + Call this function to disable the specified interrupts. + + mask - Bit mask of interrupts to be disabled. +------------------------------------------------------------------------------- +*/ +extern void _xt_ints_off(unsigned int mask); + + +/* +------------------------------------------------------------------------------- + Call this function to set the specified (s/w) interrupt. +------------------------------------------------------------------------------- +*/ +static inline void _xt_set_intset(unsigned int arg) +{ + xthal_set_intset(arg); +} + + +/* +------------------------------------------------------------------------------- + Call this function to clear the specified (s/w or edge-triggered) + interrupt. +------------------------------------------------------------------------------- +*/ +static inline void _xt_set_intclear(unsigned int arg) +{ + xthal_set_intclear(arg); +} + + +#endif /* __XTENSA_API_H__ */ + diff --git a/arch/xtensa/include/xtensa_config.h b/arch/xtensa/include/xtensa_config.h new file mode 100644 index 000000000..b43093703 --- /dev/null +++ b/arch/xtensa/include/xtensa_config.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2016 Cadence Design Systems, Inc. + * + * 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. + */ + +/******************************************************************************* + Configuration-specific information for Xtensa build. This file must be + included in FreeRTOSConfig.h to properly set up the config-dependent + parameters correctly. + + NOTE: To enable thread-safe C library support, XT_USE_THREAD_SAFE_CLIB must + be defined to be > 0 somewhere above or on the command line. + +*******************************************************************************/ + +#ifndef XTENSA_CONFIG_H +#define XTENSA_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#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 tasks 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 tasks 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) + + +#ifdef __cplusplus +} +#endif + +#endif /* XTENSA_CONFIG_H */ + diff --git a/arch/xtensa/include/xtensa_context.h b/arch/xtensa/include/xtensa_context.h new file mode 100644 index 000000000..3079683a1 --- /dev/null +++ b/arch/xtensa/include/xtensa_context.h @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2016 Cadence Design Systems, Inc. + * + * 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. + */ + +/******************************************************************************* + + 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 XTENSA_CONTEXT_H +#define XTENSA_CONTEXT_H + +#ifdef __ASSEMBLER__ +#include <xtensa/coreasm.h> +#endif + +#include <xtensa/config/tie.h> +#include <xtensa/corebits.h> +#include <xtensa/config/system.h> +#include <xtensa/xtruntime-frames.h> + + +/* 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 interrupt */ +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 peformed 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 an + 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). +------------------------------------------------------------------------------- +*/ + +#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: */ +#define XT_CPENABLE 0 /* (2 bytes) coprocessors active for this thread */ +#define XT_CPSTORED 2 /* (2 bytes) coprocessors saved for this thread */ +#define XT_CP_CS_ST 4 /* (2 bytes) coprocessor callee-saved regs stored for this thread */ +#define XT_CP_ASA 8 /* (4 bytes) ptr to aligned save area */ +/* Overall size allows for dynamic alignment: */ +#define XT_CP_SIZE ALIGNUP(XCHAL_TOTAL_SA_ALIGN, 12 + 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 +#endif + + +#endif /* XTENSA_CONTEXT_H */ + diff --git a/arch/xtensa/include/xtensa_rtos.h b/arch/xtensa/include/xtensa_rtos.h new file mode 100644 index 000000000..7ab549abc --- /dev/null +++ b/arch/xtensa/include/xtensa_rtos.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2016 Cadence Design Systems, Inc. + * + * 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. + */ + +/******************************************************************************* + + 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 XTENSA_RTOS_H +#define 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> +#include <xtensa/simcall.h> + + +/* +Convert FreeRTOSConfig definitions to XTENSA definitions. +However these can still be overridden from the command line. +*/ + +#ifndef XT_SIMULATOR + #if CONFIG_SIMULATOR_XTENSA + #define XT_SIMULATOR 1 /* Simulator mode */ + #endif +#endif + +#ifndef XT_BOARD + #if CONFIG_BOARD_XTENSA + #define XT_BOARD 1 /* Board mode */ + #endif +#endif + +#ifndef XT_TIMER_INDEX + #if defined configXT_TIMER_INDEX + #define XT_TIMER_INDEX configXT_TIMER_INDEX /* Index of hardware timer to be used */ + #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. +*/ +// void XT_RTOS_INT_ENTER(void) +#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. +*/ +// void XT_RTOS_INT_EXIT(void) +#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). +*/ +// void XT_RTOS_TIMER_INT(void) +#define XT_RTOS_TIMER_INT _zxt_timer_int +#define XT_TICK_PER_SEC CONFIG_SYS_CLOCK_TICKS_PER_SEC + +/* +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). +*/ +// void* XT_RTOS_CP_STATE(void) +#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 (*XT_INTEXC_HOOK)(unsigned 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 + + +/******************************************************************************* + +Xtensa Port Version. + +*******************************************************************************/ + +#define XTENSA_PORT_VERSION 1.5.0 +#define XTENSA_PORT_VERSION_STRING "1.5.0" + +#endif /* XTENSA_RTOS_H */ diff --git a/arch/xtensa/include/xtensa_timer.h b/arch/xtensa/include/xtensa_timer.h new file mode 100644 index 000000000..974236abd --- /dev/null +++ b/arch/xtensa/include/xtensa_timer.h @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2016 Cadence Design Systems, Inc. + * + * 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. + */ + +/******************************************************************************* + + 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 XTENSA_TIMER_H +#define 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 */ + +#if CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_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 CONFIG_XTENSA_TIMER_IRQ +#endif /* CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0) */ + +#if CONFIG_XTENSA_INTERNAL_TIMER +#define XT_TIMER_INTPRI XCHAL_INT_LEVEL(XT_TIMER_INTNUM) +#else +#define XT_TIMER_INTPRI CONFIG_XTENSA_TIMER_IRQ_PRIORITY +#endif /* CONFIG_XTENSA_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 CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC +#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 +#define XT_TICK_PER_SEC CONFIG_SYS_CLOCK_TICKS_PER_SEC /* 10 ms tick = 100 ticks per second */ +#endif + +/* +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 CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0) +#ifndef __ASSEMBLER__ +extern unsigned _xt_tick_divisor; +extern void _xt_tick_divisor_init(void); +#endif + +#endif // Internal/External timer + +#endif /* XTENSA_TIMER_H */ + |