mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 04:52:59 +01:00
cpu/esp_common: xtensa vendor files added
This commit is contained in:
parent
fe3d325fd9
commit
5f1383c27d
@ -1,4 +1,6 @@
|
||||
# add a list of subdirectories, that should also be build
|
||||
DIRS += vendor
|
||||
|
||||
ifneq (, $(filter esp_now, $(USEMODULE)))
|
||||
DIRS += esp-now
|
||||
endif
|
||||
|
4
cpu/esp_common/vendor/Makefile
vendored
Normal file
4
cpu/esp_common/vendor/Makefile
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# Add a list of subdirectories, that should also be built:
|
||||
DIRS += xtensa
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
4
cpu/esp_common/vendor/README.md
vendored
Normal file
4
cpu/esp_common/vendor/README.md
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
The subdirectories here contain third-party software components used by the RIOT port for ESP32.
|
||||
|
||||
### xtensa
|
||||
The files in this directory are from the [FreeRTOS port for Xtensa](https://github.com/tensilica/freertos) configurable processors and Diamond processors. All of these files are copyright of Cadence Design Systems Inc. and licensed under the MIT license.
|
3
cpu/esp_common/vendor/xtensa/Makefile
vendored
Normal file
3
cpu/esp_common/vendor/xtensa/Makefile
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE=xtensa
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
30
cpu/esp_common/vendor/xtensa/README.md
vendored
Normal file
30
cpu/esp_common/vendor/xtensa/README.md
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
All files in this directory are from the [FreeRTOS port for Xtensa](https://github.com/tensilica/freertos) configurable processors and Diamond processors. All of these files are copyright of Cadence Design Systems Inc., see below.
|
||||
|
||||
Some of the files are slightly modified for the RIOT OS port.
|
||||
|
||||
Please note the following copyright notices for all these files:
|
||||
|
||||
```
|
||||
/*******************************************************************************
|
||||
Copyright (c) 2006-2015 Cadence Design Systems Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
```
|
636
cpu/esp_common/vendor/xtensa/portasm.S
vendored
Normal file
636
cpu/esp_common/vendor/xtensa/portasm.S
vendored
Normal file
@ -0,0 +1,636 @@
|
||||
/*
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifdef RIOT_VERSION
|
||||
#include "xtensa_conf.h"
|
||||
|
||||
#define pxCurrentTCB sched_active_thread
|
||||
#define port_xSchedulerRunning sched_num_threads
|
||||
#define port_switch_flag sched_context_switch_request
|
||||
#define port_interruptNesting irq_interrupt_nesting
|
||||
#define vTaskSwitchContext sched_run
|
||||
#define configISR_STACK_SIZE ISR_STACKSIZE
|
||||
|
||||
.extern sched_active_thread
|
||||
.extern sched_num_threads
|
||||
.extern sched_context_switch_request
|
||||
.extern irq_interrupt_nesting
|
||||
#endif
|
||||
|
||||
#include "xtensa_context.h"
|
||||
|
||||
#define TOPOFSTACK_OFFS 0x00 /* StackType_t *pxTopOfStack */
|
||||
#define CP_TOPOFSTACK_OFFS 0x04 /* xMPU_SETTINGS.coproc_area */
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Interrupt stack. The size of the interrupt stack is determined by the config
|
||||
* parameter "configISR_STACK_SIZE" in FreeRTOSConfig.h
|
||||
*******************************************************************************
|
||||
*/
|
||||
.data
|
||||
.align 16
|
||||
.global port_IntStack
|
||||
port_IntStack:
|
||||
.space configISR_STACK_SIZE
|
||||
.global port_IntStackTop
|
||||
port_IntStackTop:
|
||||
.word 0
|
||||
|
||||
#ifndef RIOT_VERSION
|
||||
port_switch_flag:
|
||||
.word 0
|
||||
#endif
|
||||
|
||||
.text
|
||||
.literal_position
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* _frxt_setup_switch
|
||||
* void _frxt_setup_switch(void);
|
||||
*
|
||||
* Sets an internal flag indicating that a task switch is required on return
|
||||
* from interrupt handling.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
.global _frxt_setup_switch
|
||||
.type _frxt_setup_switch,@function
|
||||
.align 4
|
||||
_frxt_setup_switch:
|
||||
|
||||
ENTRY(16)
|
||||
|
||||
movi a2, port_switch_flag
|
||||
movi a3, 1
|
||||
s32i a3, a2, 0
|
||||
|
||||
RET(16)
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* _frxt_int_enter
|
||||
* void _frxt_int_enter(void)
|
||||
*
|
||||
* Implements the Xtensa RTOS porting layer's XT_RTOS_INT_ENTER function for
|
||||
* freeRTOS. Saves the rest of the interrupt context (not already saved).
|
||||
* May only be called from assembly code by the 'call0' instruction, with
|
||||
* interrupts disabled.
|
||||
* See the detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
.globl _frxt_int_enter
|
||||
.type _frxt_int_enter,@function
|
||||
.align 4
|
||||
_frxt_int_enter:
|
||||
|
||||
/* Save a12-13 in the stack frame as required by _xt_context_save. */
|
||||
s32i a12, a1, XT_STK_A12
|
||||
s32i a13, a1, XT_STK_A13
|
||||
|
||||
/* Save return address in a safe place (free a0). */
|
||||
mov a12, a0
|
||||
|
||||
/* Save the rest of the interrupted context (preserves A12-13). */
|
||||
call0 _xt_context_save
|
||||
|
||||
/*
|
||||
Save interrupted task's SP in TCB only if not nesting.
|
||||
Manage nesting directly rather than call the generic IntEnter()
|
||||
(in windowed ABI we can't call a C function here anyway because PS.EXCM is still set).
|
||||
*/
|
||||
|
||||
movi a2, port_xSchedulerRunning
|
||||
movi a3, port_interruptNesting
|
||||
l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */
|
||||
beqz a2, 1f /* scheduler not running, no tasks */
|
||||
l32i a2, a3, 0 /* a2 = port_interruptNesting */
|
||||
addi a2, a2, 1 /* increment nesting count */
|
||||
s32i a2, a3, 0 /* save nesting count */
|
||||
bnei a2, 1, .Lnested /* !=0 before incr, so nested */
|
||||
|
||||
movi a2, pxCurrentTCB
|
||||
l32i a2, a2, 0 /* a2 = current TCB */
|
||||
beqz a2, 1f
|
||||
s32i a1, a2, TOPOFSTACK_OFFS /* pxCurrentTCB->pxTopOfStack = SP */
|
||||
movi a1, port_IntStackTop /* a1 = top of intr stack */
|
||||
|
||||
.Lnested:
|
||||
1:
|
||||
mov a0, a12 /* restore return addr and return */
|
||||
ret
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* _frxt_int_exit
|
||||
* void _frxt_int_exit(void)
|
||||
*
|
||||
* Implements the Xtensa RTOS porting layer's XT_RTOS_INT_EXIT function for
|
||||
* FreeRTOS. If required, calls vPortYieldFromInt() to perform task context
|
||||
* switching, restore the (possibly) new task's context, and return to the
|
||||
* exit dispatcher saved in the task's stack frame at XT_STK_EXIT.
|
||||
* May only be called from assembly code by the 'call0' instruction. Does not
|
||||
* return to caller.
|
||||
* See the description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
.globl _frxt_int_exit
|
||||
.type _frxt_int_exit,@function
|
||||
.align 4
|
||||
_frxt_int_exit:
|
||||
|
||||
movi a2, port_xSchedulerRunning
|
||||
movi a3, port_interruptNesting
|
||||
rsil a0, XCHAL_EXCM_LEVEL /* lock out interrupts */
|
||||
l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */
|
||||
beqz a2, .Lnoswitch /* scheduler not running, no tasks */
|
||||
l32i a2, a3, 0 /* a2 = port_interruptNesting */
|
||||
addi a2, a2, -1 /* decrement nesting count */
|
||||
s32i a2, a3, 0 /* save nesting count */
|
||||
bnez a2, .Lnesting /* !=0 after decr so still nested */
|
||||
|
||||
movi a2, pxCurrentTCB
|
||||
l32i a2, a2, 0 /* a2 = current TCB */
|
||||
beqz a2, 1f /* no task ? go to dispatcher */
|
||||
l32i a1, a2, TOPOFSTACK_OFFS /* SP = pxCurrentTCB->pxTopOfStack */
|
||||
|
||||
movi a2, port_switch_flag /* address of switch flag */
|
||||
l32i a3, a2, 0 /* a3 = port_switch_flag */
|
||||
beqz a3, .Lnoswitch /* flag = 0 means no switch reqd */
|
||||
movi a3, 0
|
||||
s32i a3, a2, 0 /* zero out the flag for next time */
|
||||
|
||||
1:
|
||||
/*
|
||||
Call0 ABI callee-saved regs a12-15 need to be saved before possible preemption.
|
||||
However a12-13 were already saved by _frxt_int_enter().
|
||||
*/
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
s32i a14, a1, XT_STK_A14
|
||||
s32i a15, a1, XT_STK_A15
|
||||
#endif
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
call0 vPortYieldFromInt /* call dispatch inside the function; never returns */
|
||||
#else
|
||||
call4 vPortYieldFromInt /* this one returns */
|
||||
call0 _frxt_dispatch /* tail-call dispatcher */
|
||||
/* Never returns here. */
|
||||
#endif
|
||||
|
||||
.Lnoswitch:
|
||||
/*
|
||||
If we came here then about to resume the interrupted task.
|
||||
*/
|
||||
|
||||
.Lnesting:
|
||||
/*
|
||||
We come here only if there was no context switch, that is if this
|
||||
is a nested interrupt, or the interrupted task was not preempted.
|
||||
In either case there's no need to load the SP.
|
||||
*/
|
||||
|
||||
/* Restore full context from interrupt stack frame */
|
||||
call0 _xt_context_restore
|
||||
|
||||
/*
|
||||
Must return via the exit dispatcher corresponding to the entrypoint from which
|
||||
this was called. Interruptee's A0, A1, PS, PC are restored and the interrupt
|
||||
stack frame is deallocated in the exit dispatcher.
|
||||
*/
|
||||
l32i a0, a1, XT_STK_EXIT
|
||||
ret
|
||||
|
||||
/*
|
||||
**********************************************************************************************************
|
||||
* _frxt_timer_int
|
||||
* void _frxt_timer_int(void)
|
||||
*
|
||||
* Implements the Xtensa RTOS porting layer's XT_RTOS_TIMER_INT function for FreeRTOS.
|
||||
* Called every timer interrupt.
|
||||
* Manages the tick timer and calls xPortSysTickHandler() every tick.
|
||||
* See the detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
|
||||
*
|
||||
* Callable from C (obeys ABI conventions). Implemented in assmebly code for performance.
|
||||
*
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
.globl _frxt_timer_int
|
||||
.type _frxt_timer_int,@function
|
||||
.align 4
|
||||
_frxt_timer_int:
|
||||
|
||||
/*
|
||||
Xtensa timers work by comparing a cycle counter with a preset value. Once the match occurs
|
||||
an interrupt is generated, and the handler has to set a new cycle count into the comparator.
|
||||
To avoid clock drift due to interrupt latency, the new cycle count is computed from the old,
|
||||
not the time the interrupt was serviced. However if a timer interrupt is ever serviced more
|
||||
than one tick late, it is necessary to process multiple ticks until the new cycle count is
|
||||
in the future, otherwise the next timer interrupt would not occur until after the cycle
|
||||
counter had wrapped (2^32 cycles later).
|
||||
|
||||
do {
|
||||
ticks++;
|
||||
old_ccompare = read_ccompare_i();
|
||||
write_ccompare_i( old_ccompare + divisor );
|
||||
service one tick;
|
||||
diff = read_ccount() - old_ccompare;
|
||||
} while ( diff > divisor );
|
||||
*/
|
||||
|
||||
ENTRY(16)
|
||||
/* In RIOT-OS the timer is used in a different way and is realized in C functions. */
|
||||
#if 0
|
||||
|
||||
.L_xt_timer_int_catchup:
|
||||
|
||||
/* Update the timer comparator for the next tick. */
|
||||
#ifdef XT_CLOCK_FREQ
|
||||
movi a2, XT_TICK_DIVISOR /* a2 = comparator increment */
|
||||
#else
|
||||
movi a3, _xt_tick_divisor
|
||||
l32i a2, a3, 0 /* a2 = comparator increment */
|
||||
#endif
|
||||
rsr a3, XT_CCOMPARE /* a3 = old comparator value */
|
||||
add a4, a3, a2 /* a4 = new comparator value */
|
||||
wsr a4, XT_CCOMPARE /* update comp. and clear interrupt */
|
||||
esync
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
/* Preserve a2 and a3 across C calls. */
|
||||
s32i a2, sp, 4
|
||||
s32i a3, sp, 8
|
||||
#endif
|
||||
|
||||
/* Call the FreeRTOS tick handler (see port.c). */
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
call0 xPortSysTickHandler
|
||||
#else
|
||||
call4 xPortSysTickHandler
|
||||
#endif
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
/* Restore a2 and a3. */
|
||||
l32i a2, sp, 4
|
||||
l32i a3, sp, 8
|
||||
#endif
|
||||
|
||||
/* Check if we need to process more ticks to catch up. */
|
||||
esync /* ensure comparator update complete */
|
||||
rsr a4, CCOUNT /* a4 = cycle count */
|
||||
sub a4, a4, a3 /* diff = ccount - old comparator */
|
||||
blt a2, a4, .L_xt_timer_int_catchup /* repeat while diff > divisor */
|
||||
|
||||
#endif
|
||||
RET(16)
|
||||
|
||||
/*
|
||||
**********************************************************************************************************
|
||||
* _frxt_tick_timer_init
|
||||
* void _frxt_tick_timer_init(void)
|
||||
*
|
||||
* Initialize timer and timer interrrupt handler (_xt_tick_divisor_init() has already been been called).
|
||||
* Callable from C (obeys ABI conventions on entry).
|
||||
*
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
#if 0
|
||||
.globl _frxt_tick_timer_init
|
||||
.type _frxt_tick_timer_init,@function
|
||||
.align 4
|
||||
_frxt_tick_timer_init:
|
||||
|
||||
ENTRY(16)
|
||||
|
||||
/* Set up the periodic tick timer (assume enough time to complete init). */
|
||||
#ifdef XT_CLOCK_FREQ
|
||||
movi a3, XT_TICK_DIVISOR
|
||||
#else
|
||||
movi a2, _xt_tick_divisor
|
||||
l32i a3, a2, 0
|
||||
#endif
|
||||
rsr a2, CCOUNT /* current cycle count */
|
||||
add a2, a2, a3 /* time of first timer interrupt */
|
||||
wsr a2, XT_CCOMPARE /* set the comparator */
|
||||
|
||||
/*
|
||||
Enable the timer interrupt at the device level. Don't write directly
|
||||
to the INTENABLE register because it may be virtualized.
|
||||
*/
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
movi a2, XT_TIMER_INTEN
|
||||
call0 xt_ints_on
|
||||
#else
|
||||
movi a6, XT_TIMER_INTEN
|
||||
call4 xt_ints_on
|
||||
#endif
|
||||
|
||||
RET(16)
|
||||
#endif
|
||||
|
||||
/*
|
||||
**********************************************************************************************************
|
||||
* DISPATCH THE HIGH READY TASK
|
||||
* void _frxt_dispatch(void)
|
||||
*
|
||||
* Switch context to the highest priority ready task, restore its state and dispatch control to it.
|
||||
*
|
||||
* This is a common dispatcher that acts as a shared exit path for all the context switch functions
|
||||
* including vPortYield() and vPortYieldFromInt(), all of which tail-call this dispatcher
|
||||
* (for windowed ABI vPortYieldFromInt() calls it indirectly via _frxt_int_exit() ).
|
||||
*
|
||||
* The Xtensa port uses different stack frames for solicited and unsolicited task suspension (see
|
||||
* comments on stack frames in xtensa_context.h). This function restores the state accordingly.
|
||||
* If restoring a task that solicited entry, restores the minimal state and leaves CPENABLE clear.
|
||||
* If restoring a task that was preempted, restores all state including the task's CPENABLE.
|
||||
*
|
||||
* Entry:
|
||||
* pxCurrentTCB points to the TCB of the task to suspend,
|
||||
* Because it is tail-called without a true function entrypoint, it needs no 'entry' instruction.
|
||||
*
|
||||
* Exit:
|
||||
* If incoming task called vPortYield() (solicited), this function returns as if from vPortYield().
|
||||
* If incoming task was preempted by an interrupt, this function jumps to exit dispatcher.
|
||||
*
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
.globl _frxt_dispatch
|
||||
.type _frxt_dispatch,@function
|
||||
.align 4
|
||||
_frxt_dispatch:
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
call0 vTaskSwitchContext // Get next TCB to resume
|
||||
movi a2, pxCurrentTCB
|
||||
#else
|
||||
movi a2, pxCurrentTCB
|
||||
call4 vTaskSwitchContext // Get next TCB to resume
|
||||
#endif
|
||||
l32i a3, a2, 0
|
||||
l32i sp, a3, TOPOFSTACK_OFFS /* SP = next_TCB->pxTopOfStack; */
|
||||
s32i a3, a2, 0
|
||||
|
||||
/* Determine the type of stack frame. */
|
||||
l32i a2, sp, XT_STK_EXIT /* exit dispatcher or solicited flag */
|
||||
bnez a2, .L_frxt_dispatch_stk
|
||||
|
||||
.L_frxt_dispatch_sol:
|
||||
|
||||
/* Solicited stack frame. Restore minimal context and return from vPortYield(). */
|
||||
l32i a3, sp, XT_SOL_PS
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
l32i a12, sp, XT_SOL_A12
|
||||
l32i a13, sp, XT_SOL_A13
|
||||
l32i a14, sp, XT_SOL_A14
|
||||
l32i a15, sp, XT_SOL_A15
|
||||
#endif
|
||||
l32i a0, sp, XT_SOL_PC
|
||||
#if XCHAL_CP_NUM > 0
|
||||
/* Ensure wsr.CPENABLE is complete (should be, it was cleared on entry). */
|
||||
rsync
|
||||
#endif
|
||||
/* As soons as PS is restored, interrupts can happen. No need to sync PS. */
|
||||
wsr a3, PS
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
addi sp, sp, XT_SOL_FRMSZ
|
||||
ret
|
||||
#else
|
||||
retw
|
||||
#endif
|
||||
|
||||
.L_frxt_dispatch_stk:
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
/* Restore CPENABLE from task's co-processor save area. */
|
||||
movi a3, pxCurrentTCB
|
||||
l32i a3, a3, 0 /* a3 = pxCurrentTCB */
|
||||
#ifdef RIOT_VERSION
|
||||
addi a2, a3, -XT_CP_SIZE /* a2 = pxCurrentTCB->cp_state */
|
||||
#else
|
||||
l32i a2, a3, CP_TOPOFSTACK_OFFS /* StackType_t *pxStack; */
|
||||
#endif
|
||||
l16ui a3, a2, XT_CPENABLE /* CPENABLE = cpenable; */
|
||||
wsr a3, CPENABLE
|
||||
#endif
|
||||
|
||||
/* Interrupt stack frame. Restore full context and return to exit dispatcher. */
|
||||
call0 _xt_context_restore
|
||||
|
||||
/* In Call0 ABI, restore callee-saved regs (A12, A13 already restored). */
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
l32i a14, sp, XT_STK_A14
|
||||
l32i a15, sp, XT_STK_A15
|
||||
#endif
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
/* Ensure wsr.CPENABLE has completed. */
|
||||
rsync
|
||||
#endif
|
||||
|
||||
/*
|
||||
Must return via the exit dispatcher corresponding to the entrypoint from which
|
||||
this was called. Interruptee's A0, A1, PS, PC are restored and the interrupt
|
||||
stack frame is deallocated in the exit dispatcher.
|
||||
*/
|
||||
l32i a0, sp, XT_STK_EXIT
|
||||
ret
|
||||
|
||||
|
||||
/*
|
||||
**********************************************************************************************************
|
||||
* PERFORM A SOLICTED CONTEXT SWITCH (from a task)
|
||||
* void vPortYield(void)
|
||||
*
|
||||
* This function saves the minimal state needed for a solicited task suspension, clears CPENABLE,
|
||||
* then tail-calls the dispatcher _frxt_dispatch() to perform the actual context switch
|
||||
*
|
||||
* At Entry:
|
||||
* pxCurrentTCB points to the TCB of the task to suspend
|
||||
* Callable from C (obeys ABI conventions on entry).
|
||||
*
|
||||
* Does not return to caller.
|
||||
*
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
.globl vPortYield
|
||||
.type vPortYield,@function
|
||||
.align 4
|
||||
vPortYield:
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
addi sp, sp, -XT_SOL_FRMSZ
|
||||
#else
|
||||
entry sp, XT_SOL_FRMSZ
|
||||
#endif
|
||||
|
||||
rsr a2, PS
|
||||
s32i a0, sp, XT_SOL_PC
|
||||
s32i a2, sp, XT_SOL_PS
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
s32i a12, sp, XT_SOL_A12 /* save callee-saved registers */
|
||||
s32i a13, sp, XT_SOL_A13
|
||||
s32i a14, sp, XT_SOL_A14
|
||||
s32i a15, sp, XT_SOL_A15
|
||||
#else
|
||||
/* Spill register windows. Calling xthal_window_spill() causes extra */
|
||||
/* spills and reloads, so we will set things up to call the _nw version */
|
||||
/* instead to save cycles. */
|
||||
movi a6, ~(PS_WOE_MASK|PS_INTLEVEL_MASK) /* spills a4-a7 if needed */
|
||||
and a2, a2, a6 /* clear WOE, INTLEVEL */
|
||||
addi a2, a2, XCHAL_EXCM_LEVEL /* set INTLEVEL */
|
||||
wsr a2, PS
|
||||
rsync
|
||||
call0 xthal_window_spill_nw
|
||||
l32i a2, sp, XT_SOL_PS /* restore PS */
|
||||
wsr a2, PS
|
||||
#endif
|
||||
|
||||
rsil a2, XCHAL_EXCM_LEVEL /* disable low/med interrupts */
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
/* Save coprocessor callee-saved state (if any). At this point CPENABLE */
|
||||
/* should still reflect which CPs were in use (enabled). */
|
||||
call0 _xt_coproc_savecs
|
||||
#endif
|
||||
|
||||
movi a2, pxCurrentTCB
|
||||
movi a3, 0
|
||||
l32i a2, a2, 0 /* a2 = pxCurrentTCB */
|
||||
s32i a3, sp, XT_SOL_EXIT /* 0 to flag as solicited frame */
|
||||
s32i sp, a2, TOPOFSTACK_OFFS /* pxCurrentTCB->pxTopOfStack = SP */
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
/* Clear CPENABLE, also in task's co-processor state save area. */
|
||||
#ifdef RIOT_VERSION
|
||||
addi a2, a2, -XT_CP_SIZE /* a2 = pxCurrentTCB->cp_state */
|
||||
#else
|
||||
l32i a2, a2, CP_TOPOFSTACK_OFFS /* a2 = pxCurrentTCB->cp_state */
|
||||
#endif
|
||||
movi a3, 0
|
||||
wsr a3, CPENABLE
|
||||
beqz a2, 1f
|
||||
s16i a3, a2, XT_CPENABLE /* clear saved cpenable */
|
||||
1:
|
||||
#endif
|
||||
|
||||
/* Tail-call dispatcher. */
|
||||
call0 _frxt_dispatch
|
||||
/* Never reaches here. */
|
||||
|
||||
|
||||
/*
|
||||
**********************************************************************************************************
|
||||
* PERFORM AN UNSOLICITED CONTEXT SWITCH (from an interrupt)
|
||||
* void vPortYieldFromInt(void)
|
||||
*
|
||||
* This calls the context switch hook (removed), saves and clears CPENABLE, then tail-calls the dispatcher
|
||||
* _frxt_dispatch() to perform the actual context switch.
|
||||
*
|
||||
* At Entry:
|
||||
* Interrupted task context has been saved in an interrupt stack frame at pxCurrentTCB->pxTopOfStack.
|
||||
* pxCurrentTCB points to the TCB of the task to suspend,
|
||||
* Callable from C (obeys ABI conventions on entry).
|
||||
*
|
||||
* At Exit:
|
||||
* Windowed ABI defers the actual context switch until the stack is unwound to interrupt entry.
|
||||
* Call0 ABI tail-calls the dispatcher directly (no need to unwind) so does not return to caller.
|
||||
*
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
.globl vPortYieldFromInt
|
||||
.type vPortYieldFromInt,@function
|
||||
.align 4
|
||||
vPortYieldFromInt:
|
||||
|
||||
ENTRY(16)
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
/* Save CPENABLE in task's co-processor save area, and clear CPENABLE. */
|
||||
movi a3, pxCurrentTCB
|
||||
l32i a3, a3, 0 /* a3 = pxCurrentTCB */
|
||||
#ifdef RIOT_VERSION
|
||||
addi a2, a3, -XT_CP_SIZE /* a2 = pxCurrentTCB->cp_state */
|
||||
#else
|
||||
l32i a2, a3, CP_TOPOFSTACK_OFFS /* a2 = pxCurrentTCB->cp_state */
|
||||
#endif
|
||||
|
||||
rsr a3, CPENABLE
|
||||
s16i a3, a2, XT_CPENABLE /* cp_state->cpenable = CPENABLE; */
|
||||
movi a3, 0
|
||||
wsr a3, CPENABLE /* disable all co-processors */
|
||||
#endif
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
/* Tail-call dispatcher. */
|
||||
call0 _frxt_dispatch
|
||||
/* Never reaches here. */
|
||||
#else
|
||||
RET(16)
|
||||
#endif
|
||||
|
||||
/*
|
||||
**********************************************************************************************************
|
||||
* _frxt_task_coproc_state
|
||||
* void _frxt_task_coproc_state(void)
|
||||
*
|
||||
* Implements the Xtensa RTOS porting layer's XT_RTOS_CP_STATE function for FreeRTOS.
|
||||
*
|
||||
* May only be called when a task is running, not within an interrupt handler (returns 0 in that case).
|
||||
* May only be called from assembly code by the 'call0' instruction. Does NOT obey ABI conventions.
|
||||
* Returns in A15 a pointer to the base of the co-processor state save area for the current task.
|
||||
* See the detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
|
||||
*
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
#if XCHAL_CP_NUM > 0
|
||||
|
||||
.globl _frxt_task_coproc_state
|
||||
.type _frxt_task_coproc_state,@function
|
||||
.align 4
|
||||
_frxt_task_coproc_state:
|
||||
|
||||
movi a15, port_xSchedulerRunning /* if (port_xSchedulerRunning */
|
||||
l32i a15, a15, 0
|
||||
beqz a15, 1f
|
||||
movi a15, port_interruptNesting /* && port_interruptNesting == 0 */
|
||||
l32i a15, a15, 0
|
||||
bnez a15, 1f
|
||||
movi a15, pxCurrentTCB
|
||||
l32i a15, a15, 0 /* && pxCurrentTCB != 0) { */
|
||||
beqz a15, 2f
|
||||
#ifdef RIOT_VERSION
|
||||
addi a15, a15, -XT_CP_SIZE /* a15 = pxCurrentTCB->cp_state */
|
||||
#else
|
||||
l32i a15, a15, CP_TOPOFSTACK_OFFS
|
||||
#endif
|
||||
ret
|
||||
|
||||
1: movi a15, 0
|
||||
2: ret
|
||||
|
||||
#endif /* XCHAL_CP_NUM > 0 */
|
127
cpu/esp_common/vendor/xtensa/xtensa_api.h
vendored
Normal file
127
cpu/esp_common/vendor/xtensa/xtensa_api.h
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
/*******************************************************************************
|
||||
Copyright (c) 2006-2015 Cadence Design Systems Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
Xtensa-specific API for RTOS ports.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XTENSA_API_H
|
||||
#define XTENSA_API_H
|
||||
|
||||
#include <xtensa/hal.h>
|
||||
|
||||
#include "xtensa_context.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* 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.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
extern xt_handler xt_set_interrupt_handler(int n, xt_handler f, void * arg);
|
||||
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
Call this function to enable the specified interrupts.
|
||||
|
||||
mask - Bit mask of interrupts to be enabled.
|
||||
|
||||
Returns the previous state of the interrupt enables.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
extern unsigned int xt_ints_on(unsigned int mask);
|
||||
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
Call this function to disable the specified interrupts.
|
||||
|
||||
mask - Bit mask of interrupts to be disabled.
|
||||
|
||||
Returns the previous state of the interrupt enables.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
extern unsigned int 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);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* XTENSA_API_H */
|
624
cpu/esp_common/vendor/xtensa/xtensa_context.S
vendored
Normal file
624
cpu/esp_common/vendor/xtensa/xtensa_context.S
vendored
Normal file
@ -0,0 +1,624 @@
|
||||
/*******************************************************************************
|
||||
Copyright (c) 2006-2015 Cadence Design Systems Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
XTENSA CONTEXT SAVE AND RESTORE ROUTINES
|
||||
|
||||
Low-level Call0 functions for handling generic context save and restore of
|
||||
registers not specifically addressed by the interrupt vectors and handlers.
|
||||
Those registers (not handled by these functions) are PC, PS, A0, A1 (SP).
|
||||
Except for the calls to RTOS functions, this code is generic to Xtensa.
|
||||
|
||||
Note that in Call0 ABI, interrupt handlers are expected to preserve the callee-
|
||||
save regs (A12-A15), which is always the case if the handlers are coded in C.
|
||||
However A12, A13 are made available as scratch registers for interrupt dispatch
|
||||
code, so are presumed saved anyway, and are always restored even in Call0 ABI.
|
||||
Only A14, A15 are truly handled as callee-save regs.
|
||||
|
||||
Because Xtensa is a configurable architecture, this port supports all user
|
||||
generated configurations (except restrictions stated in the release notes).
|
||||
This is accomplished by conditional compilation using macros and functions
|
||||
defined in the Xtensa HAL (hardware adaptation layer) for your configuration.
|
||||
Only the processor state included in your configuration is saved and restored,
|
||||
including any processor state added by user configuration options or TIE.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
/* Warn nicely if this file gets named with a lowercase .s instead of .S: */
|
||||
#define NOERROR #
|
||||
NOERROR: .error "C preprocessor needed for this file: make sure its filename\
|
||||
ends in uppercase .S, or use xt-xcc's -x assembler-with-cpp option."
|
||||
|
||||
#include "xtensa_rtos.h"
|
||||
#include "xtensa_context.h"
|
||||
|
||||
#ifdef XT_USE_OVLY
|
||||
#include <xtensa/overlay_os_asm.h>
|
||||
#endif
|
||||
|
||||
.text
|
||||
.literal_position
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
_xt_context_save
|
||||
|
||||
!! MUST BE CALLED ONLY BY 'CALL0' INSTRUCTION !!
|
||||
|
||||
Saves all Xtensa processor state except PC, PS, A0, A1 (SP), A12, A13, in the
|
||||
interrupt stack frame defined in xtensa_rtos.h.
|
||||
Its counterpart is _xt_context_restore (which also restores A12, A13).
|
||||
|
||||
Caller is expected to have saved PC, PS, A0, A1 (SP), A12, A13 in the frame.
|
||||
This function preserves A12 & A13 in order to provide the caller with 2 scratch
|
||||
regs that need not be saved over the call to this function. The choice of which
|
||||
2 regs to provide is governed by xthal_window_spill_nw and xthal_save_extra_nw,
|
||||
to avoid moving data more than necessary. Caller can assign regs accordingly.
|
||||
|
||||
Entry Conditions:
|
||||
A0 = Return address in caller.
|
||||
A1 = Stack pointer of interrupted thread or handler ("interruptee").
|
||||
Original A12, A13 have already been saved in the interrupt stack frame.
|
||||
Other processor state except PC, PS, A0, A1 (SP), A12, A13, is as at the
|
||||
point of interruption.
|
||||
If windowed ABI, PS.EXCM = 1 (exceptions disabled).
|
||||
|
||||
Exit conditions:
|
||||
A0 = Return address in caller.
|
||||
A1 = Stack pointer of interrupted thread or handler ("interruptee").
|
||||
A12, A13 as at entry (preserved).
|
||||
If windowed ABI, PS.EXCM = 1 (exceptions disabled).
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
.global _xt_context_save
|
||||
.type _xt_context_save,@function
|
||||
.align 4
|
||||
_xt_context_save:
|
||||
|
||||
s32i a2, sp, XT_STK_A2
|
||||
s32i a3, sp, XT_STK_A3
|
||||
s32i a4, sp, XT_STK_A4
|
||||
s32i a5, sp, XT_STK_A5
|
||||
s32i a6, sp, XT_STK_A6
|
||||
s32i a7, sp, XT_STK_A7
|
||||
s32i a8, sp, XT_STK_A8
|
||||
s32i a9, sp, XT_STK_A9
|
||||
s32i a10, sp, XT_STK_A10
|
||||
s32i a11, sp, XT_STK_A11
|
||||
|
||||
/*
|
||||
Call0 ABI callee-saved regs a12-15 do not need to be saved here.
|
||||
a12-13 are the caller's responsibility so it can use them as scratch.
|
||||
So only need to save a14-a15 here for Windowed ABI (not Call0).
|
||||
*/
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
s32i a14, sp, XT_STK_A14
|
||||
s32i a15, sp, XT_STK_A15
|
||||
#endif
|
||||
|
||||
rsr a3, SAR
|
||||
s32i a3, sp, XT_STK_SAR
|
||||
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
rsr a3, LBEG
|
||||
s32i a3, sp, XT_STK_LBEG
|
||||
rsr a3, LEND
|
||||
s32i a3, sp, XT_STK_LEND
|
||||
rsr a3, LCOUNT
|
||||
s32i a3, sp, XT_STK_LCOUNT
|
||||
#endif
|
||||
|
||||
#if XT_USE_SWPRI
|
||||
/* Save virtual priority mask */
|
||||
movi a3, _xt_vpri_mask
|
||||
l32i a3, a3, 0
|
||||
s32i a3, sp, XT_STK_VPRI
|
||||
#endif
|
||||
|
||||
#if XCHAL_EXTRA_SA_SIZE > 0 || !defined(__XTENSA_CALL0_ABI__)
|
||||
mov a9, a0 /* preserve ret addr */
|
||||
#endif
|
||||
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
/*
|
||||
To spill the reg windows, temp. need pre-interrupt stack ptr and a4-15.
|
||||
Need to save a9,12,13 temporarily (in frame temps) and recover originals.
|
||||
Interrupts need to be disabled below XCHAL_EXCM_LEVEL and window overflow
|
||||
and underflow exceptions disabled (assured by PS.EXCM == 1).
|
||||
*/
|
||||
s32i a12, sp, XT_STK_TMP0 /* temp. save stuff in stack frame */
|
||||
s32i a13, sp, XT_STK_TMP1
|
||||
s32i a9, sp, XT_STK_TMP2
|
||||
|
||||
/*
|
||||
Save the overlay state if we are supporting overlays. Since we just saved
|
||||
three registers, we can conveniently use them here. Note that as of now,
|
||||
overlays only work for windowed calling ABI.
|
||||
*/
|
||||
#ifdef XT_USE_OVLY
|
||||
l32i a9, sp, XT_STK_PC /* recover saved PC */
|
||||
_xt_overlay_get_state a9, a12, a13
|
||||
s32i a9, sp, XT_STK_OVLY /* save overlay state */
|
||||
#endif
|
||||
|
||||
l32i a12, sp, XT_STK_A12 /* recover original a9,12,13 */
|
||||
l32i a13, sp, XT_STK_A13
|
||||
l32i a9, sp, XT_STK_A9
|
||||
addi sp, sp, XT_STK_FRMSZ /* restore the interruptee's SP */
|
||||
call0 xthal_window_spill_nw /* preserves only a4,5,8,9,12,13 */
|
||||
addi sp, sp, -XT_STK_FRMSZ
|
||||
l32i a12, sp, XT_STK_TMP0 /* recover stuff from stack frame */
|
||||
l32i a13, sp, XT_STK_TMP1
|
||||
l32i a9, sp, XT_STK_TMP2
|
||||
#endif
|
||||
|
||||
#if XCHAL_EXTRA_SA_SIZE > 0
|
||||
/*
|
||||
NOTE: Normally the xthal_save_extra_nw macro only affects address
|
||||
registers a2-a5. It is theoretically possible for Xtensa processor
|
||||
designers to write TIE that causes more address registers to be
|
||||
affected, but it is generally unlikely. If that ever happens,
|
||||
more registers need to be saved/restored around this macro invocation.
|
||||
Here we assume a9,12,13 are preserved.
|
||||
Future Xtensa tools releases might limit the regs that can be affected.
|
||||
*/
|
||||
addi a2, sp, XT_STK_EXTRA /* where to save it */
|
||||
# if XCHAL_EXTRA_SA_ALIGN > 16
|
||||
movi a3, -XCHAL_EXTRA_SA_ALIGN
|
||||
and a2, a2, a3 /* align dynamically >16 bytes */
|
||||
# endif
|
||||
call0 xthal_save_extra_nw /* destroys a0,2,3,4,5 */
|
||||
#endif
|
||||
|
||||
#if XCHAL_EXTRA_SA_SIZE > 0 || !defined(__XTENSA_CALL0_ABI__)
|
||||
mov a0, a9 /* retrieve ret addr */
|
||||
#endif
|
||||
|
||||
ret
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
_xt_context_restore
|
||||
|
||||
!! MUST BE CALLED ONLY BY 'CALL0' INSTRUCTION !!
|
||||
|
||||
Restores all Xtensa processor state except PC, PS, A0, A1 (SP) (and in Call0
|
||||
ABI, A14, A15 which are preserved by all interrupt handlers) from an interrupt
|
||||
stack frame defined in xtensa_rtos.h .
|
||||
Its counterpart is _xt_context_save (whose caller saved A12, A13).
|
||||
|
||||
Caller is responsible to restore PC, PS, A0, A1 (SP).
|
||||
|
||||
Entry Conditions:
|
||||
A0 = Return address in caller.
|
||||
A1 = Stack pointer of interrupted thread or handler ("interruptee").
|
||||
|
||||
Exit conditions:
|
||||
A0 = Return address in caller.
|
||||
A1 = Stack pointer of interrupted thread or handler ("interruptee").
|
||||
Other processor state except PC, PS, A0, A1 (SP), is as at the point
|
||||
of interruption.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
.global _xt_context_restore
|
||||
.type _xt_context_restore,@function
|
||||
.align 4
|
||||
_xt_context_restore:
|
||||
|
||||
#if XCHAL_EXTRA_SA_SIZE > 0
|
||||
/*
|
||||
NOTE: Normally the xthal_restore_extra_nw macro only affects address
|
||||
registers a2-a5. It is theoretically possible for Xtensa processor
|
||||
designers to write TIE that causes more address registers to be
|
||||
affected, but it is generally unlikely. If that ever happens,
|
||||
more registers need to be saved/restored around this macro invocation.
|
||||
Here we only assume a13 is preserved.
|
||||
Future Xtensa tools releases might limit the regs that can be affected.
|
||||
*/
|
||||
mov a13, a0 /* preserve ret addr */
|
||||
addi a2, sp, XT_STK_EXTRA /* where to find it */
|
||||
# if XCHAL_EXTRA_SA_ALIGN > 16
|
||||
movi a3, -XCHAL_EXTRA_SA_ALIGN
|
||||
and a2, a2, a3 /* align dynamically >16 bytes */
|
||||
# endif
|
||||
call0 xthal_restore_extra_nw /* destroys a0,2,3,4,5 */
|
||||
mov a0, a13 /* retrieve ret addr */
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
l32i a2, sp, XT_STK_LBEG
|
||||
l32i a3, sp, XT_STK_LEND
|
||||
wsr a2, LBEG
|
||||
l32i a2, sp, XT_STK_LCOUNT
|
||||
wsr a3, LEND
|
||||
wsr a2, LCOUNT
|
||||
#endif
|
||||
|
||||
#ifdef XT_USE_OVLY
|
||||
/*
|
||||
If we are using overlays, this is a good spot to check if we need
|
||||
to restore an overlay for the incoming task. Here we have a bunch
|
||||
of registers to spare. Note that this step is going to use a few
|
||||
bytes of storage below SP (SP-20 to SP-32) if an overlay is going
|
||||
to be restored.
|
||||
*/
|
||||
l32i a2, sp, XT_STK_PC /* retrieve PC */
|
||||
l32i a3, sp, XT_STK_PS /* retrieve PS */
|
||||
l32i a4, sp, XT_STK_OVLY /* retrieve overlay state */
|
||||
l32i a5, sp, XT_STK_A1 /* retrieve stack ptr */
|
||||
_xt_overlay_check_map a2, a3, a4, a5, a6
|
||||
s32i a2, sp, XT_STK_PC /* save updated PC */
|
||||
s32i a3, sp, XT_STK_PS /* save updated PS */
|
||||
#endif
|
||||
|
||||
#ifdef XT_USE_SWPRI
|
||||
/* Restore virtual interrupt priority and interrupt enable */
|
||||
movi a3, _xt_intdata
|
||||
l32i a4, a3, 0 /* a4 = _xt_intenable */
|
||||
l32i a5, sp, XT_STK_VPRI /* a5 = saved _xt_vpri_mask */
|
||||
and a4, a4, a5
|
||||
wsr a4, INTENABLE /* update INTENABLE */
|
||||
s32i a5, a3, 4 /* restore _xt_vpri_mask */
|
||||
#endif
|
||||
|
||||
l32i a3, sp, XT_STK_SAR
|
||||
l32i a2, sp, XT_STK_A2
|
||||
wsr a3, SAR
|
||||
l32i a3, sp, XT_STK_A3
|
||||
l32i a4, sp, XT_STK_A4
|
||||
l32i a5, sp, XT_STK_A5
|
||||
l32i a6, sp, XT_STK_A6
|
||||
l32i a7, sp, XT_STK_A7
|
||||
l32i a8, sp, XT_STK_A8
|
||||
l32i a9, sp, XT_STK_A9
|
||||
l32i a10, sp, XT_STK_A10
|
||||
l32i a11, sp, XT_STK_A11
|
||||
|
||||
/*
|
||||
Call0 ABI callee-saved regs a12-15 do not need to be restored here.
|
||||
However a12-13 were saved for scratch before XT_RTOS_INT_ENTER(),
|
||||
so need to be restored anyway, despite being callee-saved in Call0.
|
||||
*/
|
||||
l32i a12, sp, XT_STK_A12
|
||||
l32i a13, sp, XT_STK_A13
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
l32i a14, sp, XT_STK_A14
|
||||
l32i a15, sp, XT_STK_A15
|
||||
#endif
|
||||
|
||||
ret
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
_xt_coproc_init
|
||||
|
||||
Initializes global co-processor management data, setting all co-processors
|
||||
to "unowned". Leaves CPENABLE as it found it (does NOT clear it).
|
||||
|
||||
Called during initialization of the RTOS, before any threads run.
|
||||
|
||||
This may be called from normal Xtensa single-threaded application code which
|
||||
might use co-processors. The Xtensa run-time initialization enables all
|
||||
co-processors. They must remain enabled here, else a co-processor exception
|
||||
might occur outside of a thread, which the exception handler doesn't expect.
|
||||
|
||||
Entry Conditions:
|
||||
Xtensa single-threaded run-time environment is in effect.
|
||||
No thread is yet running.
|
||||
|
||||
Exit conditions:
|
||||
None.
|
||||
|
||||
Obeys ABI conventions per prototype:
|
||||
void _xt_coproc_init(void)
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
|
||||
.global _xt_coproc_init
|
||||
.type _xt_coproc_init,@function
|
||||
.align 4
|
||||
_xt_coproc_init:
|
||||
ENTRY0
|
||||
|
||||
/* Initialize thread co-processor ownerships to 0 (unowned). */
|
||||
movi a2, _xt_coproc_owner_sa /* a2 = base of owner array */
|
||||
addi a3, a2, XCHAL_CP_MAX << 2 /* a3 = top+1 of owner array */
|
||||
movi a4, 0 /* a4 = 0 (unowned) */
|
||||
1: s32i a4, a2, 0
|
||||
addi a2, a2, 4
|
||||
bltu a2, a3, 1b
|
||||
|
||||
RET0
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
_xt_coproc_release
|
||||
|
||||
Releases any and all co-processors owned by a given thread. The thread is
|
||||
identified by it's co-processor state save area defined in xtensa_context.h .
|
||||
|
||||
Must be called before a thread's co-proc save area is deleted to avoid
|
||||
memory corruption when the exception handler tries to save the state.
|
||||
May be called when a thread terminates or completes but does not delete
|
||||
the co-proc save area, to avoid the exception handler having to save the
|
||||
thread's co-proc state before another thread can use it (optimization).
|
||||
|
||||
Entry Conditions:
|
||||
A2 = Pointer to base of co-processor state save area.
|
||||
|
||||
Exit conditions:
|
||||
None.
|
||||
|
||||
Obeys ABI conventions per prototype:
|
||||
void _xt_coproc_release(void * coproc_sa_base)
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
|
||||
.global _xt_coproc_release
|
||||
.type _xt_coproc_release,@function
|
||||
.align 4
|
||||
_xt_coproc_release:
|
||||
ENTRY0 /* a2 = base of save area */
|
||||
|
||||
movi a3, _xt_coproc_owner_sa /* a3 = base of owner array */
|
||||
addi a4, a3, XCHAL_CP_MAX << 2 /* a4 = top+1 of owner array */
|
||||
movi a5, 0 /* a5 = 0 (unowned) */
|
||||
|
||||
rsil a6, XCHAL_EXCM_LEVEL /* lock interrupts */
|
||||
|
||||
1: l32i a7, a3, 0 /* a7 = owner at a3 */
|
||||
bne a2, a7, 2f /* if (coproc_sa_base == owner) */
|
||||
s32i a5, a3, 0 /* owner = unowned */
|
||||
2: addi a3, a3, 1<<2 /* a3 = next entry in owner array */
|
||||
bltu a3, a4, 1b /* repeat until end of array */
|
||||
|
||||
3: wsr a6, PS /* restore interrupts */
|
||||
|
||||
RET0
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
_xt_coproc_savecs
|
||||
|
||||
If there is a current thread and it has a coprocessor state save area, then
|
||||
save all callee-saved state into this area. This function is called from the
|
||||
solicited context switch handler. It calls a system-specific function to get
|
||||
the coprocessor save area base address.
|
||||
|
||||
Entry conditions:
|
||||
- The thread being switched out is still the current thread.
|
||||
- CPENABLE state reflects which coprocessors are active.
|
||||
- Registers have been saved/spilled already.
|
||||
|
||||
Exit conditions:
|
||||
- All necessary CP callee-saved state has been saved.
|
||||
- Registers a2-a7, a13-a15 have been trashed.
|
||||
|
||||
Must be called from assembly code only, using CALL0.
|
||||
*******************************************************************************/
|
||||
#if XCHAL_CP_NUM > 0
|
||||
|
||||
.extern _xt_coproc_sa_offset /* external reference */
|
||||
|
||||
.global _xt_coproc_savecs
|
||||
.type _xt_coproc_savecs,@function
|
||||
.align 4
|
||||
_xt_coproc_savecs:
|
||||
|
||||
/* At entry, CPENABLE should be showing which CPs are enabled. */
|
||||
|
||||
rsr a2, CPENABLE /* a2 = which CPs are enabled */
|
||||
beqz a2, .Ldone /* quick exit if none */
|
||||
mov a14, a0 /* save return address */
|
||||
call0 XT_RTOS_CP_STATE /* get address of CP save area */
|
||||
mov a0, a14 /* restore return address */
|
||||
beqz a15, .Ldone /* if none then nothing to do */
|
||||
s16i a2, a15, XT_CP_CS_ST /* save mask of CPs being stored */
|
||||
movi a13, _xt_coproc_sa_offset /* array of CP save offsets */
|
||||
l32i a15, a15, XT_CP_ASA /* a15 = base of aligned save area */
|
||||
|
||||
#if XCHAL_CP0_SA_SIZE
|
||||
bbci.l a2, 0, 2f /* CP 0 not enabled */
|
||||
l32i a14, a13, 0 /* a14 = _xt_coproc_sa_offset[0] */
|
||||
add a3, a14, a15 /* a3 = save area for CP 0 */
|
||||
xchal_cp0_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
#if XCHAL_CP1_SA_SIZE
|
||||
bbci.l a2, 1, 2f /* CP 1 not enabled */
|
||||
l32i a14, a13, 4 /* a14 = _xt_coproc_sa_offset[1] */
|
||||
add a3, a14, a15 /* a3 = save area for CP 1 */
|
||||
xchal_cp1_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
#if XCHAL_CP2_SA_SIZE
|
||||
bbci.l a2, 2, 2f
|
||||
l32i a14, a13, 8
|
||||
add a3, a14, a15
|
||||
xchal_cp2_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
#if XCHAL_CP3_SA_SIZE
|
||||
bbci.l a2, 3, 2f
|
||||
l32i a14, a13, 12
|
||||
add a3, a14, a15
|
||||
xchal_cp3_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
#if XCHAL_CP4_SA_SIZE
|
||||
bbci.l a2, 4, 2f
|
||||
l32i a14, a13, 16
|
||||
add a3, a14, a15
|
||||
xchal_cp4_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
#if XCHAL_CP5_SA_SIZE
|
||||
bbci.l a2, 5, 2f
|
||||
l32i a14, a13, 20
|
||||
add a3, a14, a15
|
||||
xchal_cp5_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
#if XCHAL_CP6_SA_SIZE
|
||||
bbci.l a2, 6, 2f
|
||||
l32i a14, a13, 24
|
||||
add a3, a14, a15
|
||||
xchal_cp6_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
#if XCHAL_CP7_SA_SIZE
|
||||
bbci.l a2, 7, 2f
|
||||
l32i a14, a13, 28
|
||||
add a3, a14, a15
|
||||
xchal_cp7_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
.Ldone:
|
||||
ret
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
_xt_coproc_restorecs
|
||||
|
||||
Restore any callee-saved coprocessor state for the incoming thread.
|
||||
This function is called from coprocessor exception handling, when giving
|
||||
ownership to a thread that solicited a context switch earlier. It calls a
|
||||
system-specific function to get the coprocessor save area base address.
|
||||
|
||||
Entry conditions:
|
||||
- The incoming thread is set as the current thread.
|
||||
- CPENABLE is set up correctly for all required coprocessors.
|
||||
- a2 = mask of coprocessors to be restored.
|
||||
|
||||
Exit conditions:
|
||||
- All necessary CP callee-saved state has been restored.
|
||||
- CPENABLE - unchanged.
|
||||
- Registers a2-a7, a13-a15 have been trashed.
|
||||
|
||||
Must be called from assembly code only, using CALL0.
|
||||
*******************************************************************************/
|
||||
#if XCHAL_CP_NUM > 0
|
||||
|
||||
.global _xt_coproc_restorecs
|
||||
.type _xt_coproc_restorecs,@function
|
||||
.align 4
|
||||
_xt_coproc_restorecs:
|
||||
|
||||
mov a14, a0 /* save return address */
|
||||
call0 XT_RTOS_CP_STATE /* get address of CP save area */
|
||||
mov a0, a14 /* restore return address */
|
||||
beqz a15, .Ldone2 /* if none then nothing to do */
|
||||
l16ui a3, a15, XT_CP_CS_ST /* a3 = which CPs have been saved */
|
||||
xor a3, a3, a2 /* clear the ones being restored */
|
||||
s32i a3, a15, XT_CP_CS_ST /* update saved CP mask */
|
||||
movi a13, _xt_coproc_sa_offset /* array of CP save offsets */
|
||||
l32i a15, a15, XT_CP_ASA /* a15 = base of aligned save area */
|
||||
|
||||
#if XCHAL_CP0_SA_SIZE
|
||||
bbci.l a2, 0, 2f /* CP 0 not enabled */
|
||||
l32i a14, a13, 0 /* a14 = _xt_coproc_sa_offset[0] */
|
||||
add a3, a14, a15 /* a3 = save area for CP 0 */
|
||||
xchal_cp0_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
#if XCHAL_CP1_SA_SIZE
|
||||
bbci.l a2, 1, 2f /* CP 1 not enabled */
|
||||
l32i a14, a13, 4 /* a14 = _xt_coproc_sa_offset[1] */
|
||||
add a3, a14, a15 /* a3 = save area for CP 1 */
|
||||
xchal_cp1_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
#if XCHAL_CP2_SA_SIZE
|
||||
bbci.l a2, 2, 2f
|
||||
l32i a14, a13, 8
|
||||
add a3, a14, a15
|
||||
xchal_cp2_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
#if XCHAL_CP3_SA_SIZE
|
||||
bbci.l a2, 3, 2f
|
||||
l32i a14, a13, 12
|
||||
add a3, a14, a15
|
||||
xchal_cp3_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
#if XCHAL_CP4_SA_SIZE
|
||||
bbci.l a2, 4, 2f
|
||||
l32i a14, a13, 16
|
||||
add a3, a14, a15
|
||||
xchal_cp4_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
#if XCHAL_CP5_SA_SIZE
|
||||
bbci.l a2, 5, 2f
|
||||
l32i a14, a13, 20
|
||||
add a3, a14, a15
|
||||
xchal_cp5_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
#if XCHAL_CP6_SA_SIZE
|
||||
bbci.l a2, 6, 2f
|
||||
l32i a14, a13, 24
|
||||
add a3, a14, a15
|
||||
xchal_cp6_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
#if XCHAL_CP7_SA_SIZE
|
||||
bbci.l a2, 7, 2f
|
||||
l32i a14, a13, 28
|
||||
add a3, a14, a15
|
||||
xchal_cp7_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
|
||||
2:
|
||||
#endif
|
||||
|
||||
.Ldone2:
|
||||
ret
|
||||
|
||||
#endif
|
355
cpu/esp_common/vendor/xtensa/xtensa_context.h
vendored
Normal file
355
cpu/esp_common/vendor/xtensa/xtensa_context.h
vendored
Normal file
@ -0,0 +1,355 @@
|
||||
/*******************************************************************************
|
||||
Copyright (c) 2006-2015 Cadence Design Systems Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
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>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Align a value up to nearest n-byte boundary, where n is a power of 2. */
|
||||
#define ALIGNUP(n, val) (((val) + (n)-1) & -(n))
|
||||
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
Macros that help define structures for both C and assembler.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
|
||||
|
||||
#define STRUCT_BEGIN .pushsection .text; .struct 0
|
||||
#define STRUCT_FIELD(ctype,size,asname,name) asname: .space size
|
||||
#define STRUCT_AFIELD(ctype,size,asname,name,n) asname: .space (size)*(n)
|
||||
#define STRUCT_END(sname) sname##Size:; .popsection
|
||||
|
||||
#else
|
||||
|
||||
#define STRUCT_BEGIN typedef struct {
|
||||
#define STRUCT_FIELD(ctype,size,asname,name) ctype name;
|
||||
#define STRUCT_AFIELD(ctype,size,asname,name,n) ctype name[n];
|
||||
#define STRUCT_END(sname) } sname;
|
||||
|
||||
#endif //_ASMLANGUAGE || __ASSEMBLER__
|
||||
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
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) /* exit point for dispatch */
|
||||
STRUCT_FIELD (long, 4, XT_STK_PC, pc) /* return PC */
|
||||
STRUCT_FIELD (long, 4, XT_STK_PS, ps) /* return PS */
|
||||
STRUCT_FIELD (long, 4, XT_STK_A0, a0)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A1, a1) /* stack pointer before interrupt */
|
||||
STRUCT_FIELD (long, 4, XT_STK_A2, a2)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A3, a3)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A4, a4)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A5, a5)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A6, a6)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A7, a7)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A8, a8)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A9, a9)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A10, a10)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A11, a11)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A12, a12)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A13, a13)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A14, a14)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A15, a15)
|
||||
STRUCT_FIELD (long, 4, XT_STK_SAR, sar)
|
||||
STRUCT_FIELD (long, 4, XT_STK_EXCCAUSE, exccause)
|
||||
STRUCT_FIELD (long, 4, XT_STK_EXCVADDR, excvaddr)
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
STRUCT_FIELD (long, 4, XT_STK_LBEG, lbeg)
|
||||
STRUCT_FIELD (long, 4, XT_STK_LEND, lend)
|
||||
STRUCT_FIELD (long, 4, XT_STK_LCOUNT, lcount)
|
||||
#endif
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
/* Temporary space for saving stuff during window spill */
|
||||
STRUCT_FIELD (long, 4, XT_STK_TMP0, tmp0)
|
||||
STRUCT_FIELD (long, 4, XT_STK_TMP1, tmp1)
|
||||
STRUCT_FIELD (long, 4, XT_STK_TMP2, tmp2)
|
||||
#endif
|
||||
#ifdef XT_USE_SWPRI
|
||||
/* Storage for virtual priority mask */
|
||||
STRUCT_FIELD (long, 4, XT_STK_VPRI, vpri)
|
||||
#endif
|
||||
#ifdef XT_USE_OVLY
|
||||
/* Storage for overlay state */
|
||||
STRUCT_FIELD (long, 4, XT_STK_OVLY, 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
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_PC, pc)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_PS, ps)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_A12, a12) /* should be on 16-byte alignment */
|
||||
STRUCT_FIELD (long, 4, XT_SOL_A13, a13)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_A14, a14)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_A15, a15)
|
||||
#else
|
||||
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_PC, pc)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_PS, ps)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_A0, a0) /* should be on 16-byte alignment */
|
||||
STRUCT_FIELD (long, 4, XT_SOL_A1, a1)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_A2, a2)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_A3, 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 (12 + XT_CP_SA_SIZE + XCHAL_TOTAL_SA_ALIGN)
|
||||
#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
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* XTENSA_CONTEXT_H */
|
137
cpu/esp_common/vendor/xtensa/xtensa_intr.c
vendored
Normal file
137
cpu/esp_common/vendor/xtensa/xtensa_intr.c
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
/*******************************************************************************
|
||||
Copyright (c) 2006-2015 Cadence Design Systems Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
Xtensa-specific interrupt and exception functions for RTOS ports.
|
||||
Also see xtensa_intr_asm.S.
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <xtensa/config/core.h>
|
||||
|
||||
#include "xtensa_api.h"
|
||||
|
||||
|
||||
#if XCHAL_HAVE_EXCEPTIONS
|
||||
|
||||
/* Handler table is in xtensa_intr_asm.S */
|
||||
|
||||
extern xt_exc_handler _xt_exception_table[XCHAL_EXCCAUSE_NUM];
|
||||
|
||||
|
||||
/*
|
||||
Default handler for unhandled exceptions.
|
||||
*/
|
||||
void xt_unhandled_exception(XtExcFrame *frame)
|
||||
{
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This function registers a handler for the specified exception.
|
||||
The function returns the address of the previous handler.
|
||||
On error, it returns 0.
|
||||
*/
|
||||
xt_exc_handler xt_set_exception_handler(int n, xt_exc_handler f)
|
||||
{
|
||||
xt_exc_handler old;
|
||||
|
||||
if( n < 0 || n >= XCHAL_EXCCAUSE_NUM )
|
||||
return 0; /* invalid exception number */
|
||||
|
||||
old = _xt_exception_table[n];
|
||||
|
||||
if (f) {
|
||||
_xt_exception_table[n] = f;
|
||||
}
|
||||
else {
|
||||
_xt_exception_table[n] = &xt_unhandled_exception;
|
||||
}
|
||||
|
||||
return ((old == &xt_unhandled_exception) ? 0 : old);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_INTERRUPTS
|
||||
|
||||
/* Handler table is in xtensa_intr_asm.S */
|
||||
|
||||
typedef struct xt_handler_table_entry {
|
||||
void * handler;
|
||||
void * arg;
|
||||
} xt_handler_table_entry;
|
||||
|
||||
extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS];
|
||||
|
||||
|
||||
/*
|
||||
Default handler for unhandled interrupts.
|
||||
*/
|
||||
void xt_unhandled_interrupt(void * arg)
|
||||
{
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This function registers a handler for the specified interrupt. The "arg"
|
||||
parameter specifies the argument to be passed to the handler when it is
|
||||
invoked. The function returns the address of the previous handler.
|
||||
On error, it returns 0.
|
||||
*/
|
||||
xt_handler xt_set_interrupt_handler(int n, xt_handler f, void * arg)
|
||||
{
|
||||
xt_handler_table_entry * entry;
|
||||
xt_handler old;
|
||||
|
||||
if( n < 0 || n >= XCHAL_NUM_INTERRUPTS )
|
||||
return 0; /* invalid interrupt number */
|
||||
if( Xthal_intlevel[n] > XCHAL_EXCM_LEVEL )
|
||||
return 0; /* priority level too high to safely handle in C */
|
||||
|
||||
#ifdef MODULE_ESP_SDK
|
||||
/* for compatibility reasons with SDK, we use _xtos_interrupt_table */
|
||||
/* in reverse order */
|
||||
entry = _xt_interrupt_table + (XCHAL_NUM_INTERRUPTS - n);
|
||||
#else
|
||||
entry = _xt_interrupt_table + n;
|
||||
#endif
|
||||
old = entry->handler;
|
||||
|
||||
if (f) {
|
||||
entry->handler = f;
|
||||
entry->arg = arg;
|
||||
}
|
||||
else {
|
||||
entry->handler = &xt_unhandled_interrupt;
|
||||
entry->arg = (void*)n;
|
||||
}
|
||||
|
||||
return ((old == &xt_unhandled_interrupt) ? 0 : old);
|
||||
}
|
||||
|
||||
|
||||
#endif /* XCHAL_HAVE_INTERRUPTS */
|
183
cpu/esp_common/vendor/xtensa/xtensa_intr_asm.S
vendored
Normal file
183
cpu/esp_common/vendor/xtensa/xtensa_intr_asm.S
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
/*******************************************************************************
|
||||
Copyright (c) 2006-2015 Cadence Design Systems Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
Xtensa interrupt handling data and assembly routines.
|
||||
Also see xtensa_intr.c and xtensa_vectors.S.
|
||||
******************************************************************************/
|
||||
|
||||
#include <xtensa/hal.h>
|
||||
#include <xtensa/config/core.h>
|
||||
|
||||
#include "xtensa_context.h"
|
||||
|
||||
#if XCHAL_HAVE_INTERRUPTS
|
||||
|
||||
.literal_position
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
INTENABLE virtualization information.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
.data
|
||||
.global _xt_intdata
|
||||
.align 8
|
||||
_xt_intdata:
|
||||
.global _xt_intenable
|
||||
.type _xt_intenable,@object
|
||||
.size _xt_intenable,4
|
||||
.global _xt_vpri_mask
|
||||
.type _xt_vpri_mask,@object
|
||||
.size _xt_vpri_mask,4
|
||||
|
||||
_xt_intenable: .word 0 /* Virtual INTENABLE */
|
||||
_xt_vpri_mask: .word 0xFFFFFFFF /* Virtual priority mask */
|
||||
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
Table of C-callable interrupt handlers for each interrupt. Note that not all
|
||||
slots can be filled, because interrupts at level > EXCM_LEVEL will not be
|
||||
dispatched to a C handler by default.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
/*
|
||||
in SDK we use _xtos_interrupt_table_ which is provided as symbol
|
||||
_xt_interrupt_table_ by ld script
|
||||
*/
|
||||
#ifndef MODULE_ESP_SDK
|
||||
.data
|
||||
.global _xt_interrupt_table
|
||||
.align 8
|
||||
|
||||
_xt_interrupt_table:
|
||||
|
||||
.set i, 0
|
||||
.rept XCHAL_NUM_INTERRUPTS
|
||||
.word xt_unhandled_interrupt /* handler address */
|
||||
.word i /* handler arg (default: intnum) */
|
||||
.set i, i+1
|
||||
.endr
|
||||
#endif
|
||||
|
||||
#endif /* XCHAL_HAVE_INTERRUPTS */
|
||||
|
||||
|
||||
#if XCHAL_HAVE_EXCEPTIONS
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
Table of C-callable exception handlers for each exception. Note that not all
|
||||
slots will be active, because some exceptions (e.g. coprocessor exceptions)
|
||||
are always handled by the OS and cannot be hooked by user handlers.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
.data
|
||||
.global _xt_exception_table
|
||||
.align 4
|
||||
|
||||
_xt_exception_table:
|
||||
.rept XCHAL_EXCCAUSE_NUM
|
||||
.word xt_unhandled_exception /* handler address */
|
||||
.endr
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
unsigned int xt_ints_on ( unsigned int mask )
|
||||
|
||||
Enables a set of interrupts. Does not simply set INTENABLE directly, but
|
||||
computes it as a function of the current virtual priority.
|
||||
Can be called from interrupt handlers.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
.text
|
||||
.align 4
|
||||
.global xt_ints_on
|
||||
.type xt_ints_on,@function
|
||||
|
||||
xt_ints_on:
|
||||
|
||||
ENTRY0
|
||||
#if XCHAL_HAVE_INTERRUPTS
|
||||
movi a3, 0
|
||||
movi a4, _xt_intdata
|
||||
xsr a3, INTENABLE /* Disables all interrupts */
|
||||
rsync
|
||||
l32i a3, a4, 0 /* a3 = _xt_intenable */
|
||||
l32i a6, a4, 4 /* a6 = _xt_vpri_mask */
|
||||
or a5, a3, a2 /* a5 = _xt_intenable | mask */
|
||||
s32i a5, a4, 0 /* _xt_intenable |= mask */
|
||||
and a5, a5, a6 /* a5 = _xt_intenable & _xt_vpri_mask */
|
||||
wsr a5, INTENABLE /* Reenable interrupts */
|
||||
mov a2, a3 /* Previous mask */
|
||||
#else
|
||||
movi a2, 0 /* Return zero */
|
||||
#endif
|
||||
RET0
|
||||
|
||||
.size xt_ints_on, . - xt_ints_on
|
||||
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
unsigned int xt_ints_off ( unsigned int mask )
|
||||
|
||||
Disables a set of interrupts. Does not simply set INTENABLE directly,
|
||||
but computes it as a function of the current virtual priority.
|
||||
Can be called from interrupt handlers.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
.text
|
||||
.align 4
|
||||
.global xt_ints_off
|
||||
.type xt_ints_off,@function
|
||||
|
||||
xt_ints_off:
|
||||
|
||||
ENTRY0
|
||||
#if XCHAL_HAVE_INTERRUPTS
|
||||
movi a3, 0
|
||||
movi a4, _xt_intdata
|
||||
xsr a3, INTENABLE /* Disables all interrupts */
|
||||
rsync
|
||||
l32i a3, a4, 0 /* a3 = _xt_intenable */
|
||||
l32i a6, a4, 4 /* a6 = _xt_vpri_mask */
|
||||
or a5, a3, a2 /* a5 = _xt_intenable | mask */
|
||||
xor a5, a5, a2 /* a5 = _xt_intenable & ~mask */
|
||||
s32i a5, a4, 0 /* _xt_intenable &= ~mask */
|
||||
and a5, a5, a6 /* a5 = _xt_intenable & _xt_vpri_mask */
|
||||
wsr a5, INTENABLE /* Reenable interrupts */
|
||||
mov a2, a3 /* Previous mask */
|
||||
#else
|
||||
movi a2, 0 /* return zero */
|
||||
#endif
|
||||
RET0
|
||||
|
||||
.size xt_ints_off, . - xt_ints_off
|
247
cpu/esp_common/vendor/xtensa/xtensa_rtos.h
vendored
Normal file
247
cpu/esp_common/vendor/xtensa/xtensa_rtos.h
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
/*******************************************************************************
|
||||
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
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>
|
||||
#ifndef RIOT_VERSION
|
||||
#include <xtensa/simcall.h>
|
||||
#endif
|
||||
#define XT_BOARD 1
|
||||
|
||||
/*
|
||||
Include any RTOS specific definitions that are needed by this header.
|
||||
*/
|
||||
#ifndef RIOT_VERSION
|
||||
#include <FreeRTOSConfig.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
Convert FreeRTOSConfig definitions to XTENSA definitions.
|
||||
However these can still be overridden from the command line.
|
||||
*/
|
||||
|
||||
#ifndef XT_SIMULATOR
|
||||
#if configXT_SIMULATOR
|
||||
#define XT_SIMULATOR 1 /* Simulator mode */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef XT_BOARD
|
||||
#if configXT_BOARD
|
||||
#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 RIOT-OS
|
||||
|
||||
/*
|
||||
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 "RIOT-OS/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 _frxt_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 _frxt_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 _frxt_timer_int
|
||||
#ifndef RIOT_VERSION
|
||||
#define XT_TICK_PER_SEC configTICK_RATE_HZ
|
||||
#endif
|
||||
|
||||
/*
|
||||
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 _frxt_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
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Xtensa Port Version.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#define XTENSA_PORT_VERSION 1.5
|
||||
#define XTENSA_PORT_VERSION_STRING "1.5"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* XTENSA_RTOS_H */
|
170
cpu/esp_common/vendor/xtensa/xtensa_timer.h
vendored
Normal file
170
cpu/esp_common/vendor/xtensa/xtensa_timer.h
vendored
Normal file
@ -0,0 +1,170 @@
|
||||
/*******************************************************************************
|
||||
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
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>
|
||||
|
||||
#ifndef RIOT_VERSION
|
||||
#include "xtensa_rtos.h" /* in case this wasn't included directly */
|
||||
#include <FreeRTOSConfig.h>
|
||||
#endif /* ifndef RIOT_VERSION */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
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."
|
||||
|
||||
#else
|
||||
|
||||
#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)
|
||||
#define XT_TIMER_INTPRI XCHAL_INT_LEVEL(XT_TIMER_INTNUM)
|
||||
#define XT_TIMER_INTEN (1 << XT_TIMER_INTNUM)
|
||||
|
||||
#if XT_TIMER_INTNUM == XTHAL_TIMER_UNCONFIGURED
|
||||
#error "The timer selected by XT_TIMER_INDEX does not exist in this core."
|
||||
#elif XT_TIMER_INTPRI > XCHAL_EXCM_LEVEL
|
||||
#error "The timer interrupt cannot be high priority (use medium or low)."
|
||||
#endif
|
||||
|
||||
#endif /* XCHAL_NUM_TIMERS */
|
||||
|
||||
#ifndef RIOT_VERSION
|
||||
/*
|
||||
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 configCPU_CLOCK_HZ
|
||||
#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 configTICK_RATE_HZ /* 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
|
||||
#endif /* ifndef RIOT_VERSION */
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
extern unsigned _xt_tick_divisor;
|
||||
extern void _xt_tick_divisor_init(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* XTENSA_TIMER_H */
|
1933
cpu/esp_common/vendor/xtensa/xtensa_vectors.S
vendored
Normal file
1933
cpu/esp_common/vendor/xtensa/xtensa_vectors.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user