mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-06-03 11:29:42 +08:00
Merge branch 'feature/add_xtensa_source_to_esp8266' into 'master'
Add xtensa source to esp8266 component See merge request sdk/ESP8266_RTOS_SDK!70
This commit is contained in:
@ -3,7 +3,7 @@
|
||||
#
|
||||
COMPONENT_ADD_INCLUDEDIRS += include
|
||||
COMPONENT_PRIV_INCLUDEDIRS := include/driver
|
||||
COMPONENT_SRCDIRS := driver
|
||||
COMPONENT_SRCDIRS := driver source
|
||||
|
||||
LIBS ?=
|
||||
ifndef CONFIG_NO_BLOBS
|
||||
|
@ -1,7 +1,7 @@
|
||||
gwen:
|
||||
crypto: 21b4121
|
||||
espnow: 21b4121
|
||||
main: 21b4121
|
||||
core: 0655d69
|
||||
minic: 21b4121
|
||||
net80211: 21b4121
|
||||
pp: 21b4121
|
||||
|
Binary file not shown.
443
components/esp8266/source/os_cpu_a.S
Normal file
443
components/esp8266/source/os_cpu_a.S
Normal file
@ -0,0 +1,443 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* Xtensa Port
|
||||
*
|
||||
* Target : All Xtensa configurable and Diamond preconfigured processors; windowed and call0 ABI.
|
||||
* Port By : Ross Morley, Tensilica Inc. : ross@tensilica.com, ross@computer.org
|
||||
* Web URL : http://www.tensilica.com
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#include <xtensa/coreasm.h>
|
||||
#include <xtensa/config/specreg.h>
|
||||
|
||||
#include "freertos/xtensa_rtos.h"
|
||||
|
||||
.extern _xt_tick_divisor
|
||||
.extern _xt_context_save
|
||||
.extern _xt_context_restore
|
||||
.extern pxCurrentTCB
|
||||
.extern CCOMPARE_AddVal
|
||||
|
||||
// .section .iram.text
|
||||
.section .text
|
||||
|
||||
.macro xtos_lock ax
|
||||
rsil \ax, XCHAL_EXCM_LEVEL
|
||||
.endm
|
||||
|
||||
.macro xtos_unlock ax
|
||||
wsr \ax, PS
|
||||
.endm
|
||||
|
||||
/*
|
||||
**********************************************************************************************************
|
||||
* vPortYield
|
||||
* void vPortYield(void)
|
||||
* maually switch the context.
|
||||
*
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
|
||||
.globl vPortYield
|
||||
.type vPortYield,@function
|
||||
.align 4
|
||||
.literal_position
|
||||
vPortYield:
|
||||
wsr a0, EXCSAVE_1 /* preserve a0 */
|
||||
addi sp, sp, -XT_STK_FRMSZ
|
||||
s32i a0, sp, XT_STK_PC
|
||||
|
||||
addi a0, sp, XT_STK_FRMSZ
|
||||
s32i a0, sp, XT_STK_A1
|
||||
rsr a0, PS
|
||||
s32i a0, sp, XT_STK_PS
|
||||
rsr a0, EXCSAVE_1 /* save interruptee's a0 */
|
||||
s32i a0, sp, XT_STK_A0
|
||||
movi a0, _xt_user_exit
|
||||
s32i a0, sp, XT_STK_EXIT
|
||||
|
||||
call0 _xt_int_enter
|
||||
call0 vPortEnterCritical
|
||||
call0 vTaskSwitchContext
|
||||
call0 vPortExitCritical
|
||||
call0 _xt_int_exit
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
**********************************************************************************************************
|
||||
* _xt_int_enter
|
||||
* void _xt_int_enter(void)
|
||||
*
|
||||
* Implements the Xtensa RTOS porting layer's XT_RTOS_INT_ENTER function for uC/OS-II.
|
||||
* Saves the rest of the interrupt context (not already saved) and implements OSIntEnter().
|
||||
* 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 _xt_int_enter
|
||||
.type _xt_int_enter,@function
|
||||
.align 4
|
||||
.literal_position
|
||||
_xt_int_enter:
|
||||
|
||||
/* Save a12-13 in the stack frame as required by _xt_context_save. */
|
||||
s32i a12, sp, XT_STK_A12
|
||||
s32i a13, sp, 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
|
||||
|
||||
movi a0, pxCurrentTCB
|
||||
l32i a0, a0, 0
|
||||
s32i sp, a0, 0
|
||||
|
||||
/* Retrieve the return address and return to interrupt handler. */
|
||||
mov a0, a12
|
||||
ret
|
||||
|
||||
/*
|
||||
**********************************************************************************************************
|
||||
* _xt_int_exit
|
||||
* void _xt_int_exit(void)
|
||||
*
|
||||
* Implements the Xtensa RTOS porting layer's XT_RTOS_INT_EXIT function for uC/OS-II.
|
||||
* Calls OSIntExit() to perform task context switching, restores the (possibly) new task's
|
||||
* context, and returns 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 detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
|
||||
*
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
.globl _xt_int_exit
|
||||
.type _xt_int_exit,@function
|
||||
.align 4
|
||||
_xt_int_exit:
|
||||
/*
|
||||
Call0 ABI callee-saved regs a12-15 need to be saved before possible preemption.
|
||||
However a12-13 were already saved by _xt_int_enter().
|
||||
Save A14, A15 in sp to a14, a15 in cpu
|
||||
*/
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
s32i a14, sp, XT_STK_A14
|
||||
s32i a15, sp, XT_STK_A15
|
||||
#endif
|
||||
|
||||
/*
|
||||
Save A14, A15 in sp to a14, a15 in cpu
|
||||
*/
|
||||
movi sp, pxCurrentTCB
|
||||
l32i sp, sp, 0
|
||||
l32i sp, sp, 0
|
||||
|
||||
/*
|
||||
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.
|
||||
We are still on the same stack so there's no need to load the SP.
|
||||
*/
|
||||
movi a14, pxCurrentTCB
|
||||
l32i a14, a14, 0
|
||||
addi a15, sp, XT_STK_FRMSZ
|
||||
s32i a15, a14 , 0
|
||||
|
||||
/* Restore full context from interrupt stack frame 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.
|
||||
*/
|
||||
/*rsil a0, 0 */ /* reenable ints above level 1 */
|
||||
/*rsync*/
|
||||
|
||||
l32i a0, sp, XT_STK_EXIT
|
||||
ret
|
||||
|
||||
/*
|
||||
**********************************************************************************************************
|
||||
* _xt_timer_int
|
||||
* void _xt_timer_int(void)
|
||||
*
|
||||
* Implements the Xtensa RTOS porting layer's XT_RTOS_TIMER_INT function for uC/OS-II.
|
||||
* Called every timer interrupt.
|
||||
* Manages the tick timer and calls OSTimeTick() every tick, and calls OSTmrSignal() when required.
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
/* Define local variable offsets in stack frame for Call0 ABI. */
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
#define __xt_timer_int_a0 0 /* ENTRY()/RET() saves/restores */
|
||||
#define __xt_timer_int_a2 4 /* preserve a2 */
|
||||
#define __xt_timer_int_a3 8 /* preserve a3 */
|
||||
#endif
|
||||
|
||||
.globl _xt_timer_int
|
||||
.type _xt_timer_int,@function
|
||||
.align 4
|
||||
_xt_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)
|
||||
|
||||
.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, __xt_timer_int_a2
|
||||
s32i a3, sp, __xt_timer_int_a3
|
||||
#endif
|
||||
|
||||
/* Call the uCOS-II tick handler. */
|
||||
#ifdef __XTENSA_CALL0_ABI__ /* OSTimeTick() */
|
||||
call0 xPortSysTickHandle
|
||||
#else
|
||||
call4 xTaskIncrementTick
|
||||
#endif
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
/* Restore a2 and a3. */
|
||||
l32i a2, sp, __xt_timer_int_a2
|
||||
l32i a3, sp, __xt_timer_int_a3
|
||||
#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 */
|
||||
|
||||
RET(16)
|
||||
|
||||
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
#define __xt_timer_int1_a0 0 /* ENTRY()/RET() saves/restores */
|
||||
#define __xt_timer_int1_a2 4 /* preserve a2 */
|
||||
#define __xt_timer_int1_a3 8 /* preserve a3 */
|
||||
#endif
|
||||
|
||||
.globl _xt_timer_int1
|
||||
.type _xt_timer_int1,@function
|
||||
.align 4
|
||||
_xt_timer_int1:
|
||||
|
||||
ENTRY(16)
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
/* Preserve a2 and a3 across C calls. */
|
||||
s32i a2, sp, __xt_timer_int1_a2
|
||||
s32i a3, sp, __xt_timer_int1_a3
|
||||
#endif
|
||||
|
||||
/* Call the uCOS-II tick handler. */
|
||||
call0 vTaskSwitchContext
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
/* Restore a2 and a3. */
|
||||
l32i a2, sp, __xt_timer_int1_a2
|
||||
l32i a3, sp, __xt_timer_int1_a3
|
||||
#endif
|
||||
|
||||
RET(16)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
**********************************************************************************************************
|
||||
* _xt_tick_timer_init
|
||||
* void _xt_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).
|
||||
*
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
.globl _xt_tick_timer_init
|
||||
.type _xt_tick_timer_init,@function
|
||||
.align 4
|
||||
_xt_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. */
|
||||
movi a2, 0 /* protect critical section */
|
||||
xsr a2, INTENABLE
|
||||
movi a3, XT_TIMER_INTEN
|
||||
or a2, a2, a3
|
||||
wsr a2, INTENABLE /* set new INTENABLE, no need to rsync */
|
||||
|
||||
RET(16)
|
||||
|
||||
|
||||
.globl _xt_update_xt_ccompare
|
||||
.type _xt_update_xt_ccompare,@function
|
||||
.align 4
|
||||
_xt_update_xt_ccompare:
|
||||
|
||||
ENTRY(16)
|
||||
|
||||
/* Set up the periodic tick timer (assume enough time to complete init). */
|
||||
movi a3, XT_TICK_DIVISOR
|
||||
rsr a2, XT_CCOMPARE /* current cycle count */
|
||||
add a2, a2, a3 /* time of first timer interrupt */
|
||||
wsr a2, XT_CCOMPARE /* set the comparator */
|
||||
esync
|
||||
|
||||
RET(16)
|
||||
|
||||
|
||||
.globl _xt_set_xt_ccompare_val
|
||||
.type _xt_set_xt_ccompare_val,@function
|
||||
.align 4
|
||||
_xt_set_xt_ccompare_val:
|
||||
|
||||
ENTRY(16)
|
||||
|
||||
/* Set up the periodic tick timer (assume enough time to complete init). */
|
||||
movi a3, CCOMPARE_AddVal
|
||||
l32i a2, a3, 0
|
||||
wsr a2, XT_CCOMPARE /* set the comparator */
|
||||
esync
|
||||
|
||||
RET(16)
|
||||
|
||||
/*
|
||||
**********************************************************************************************************
|
||||
* isr_unmask
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
.globl _xt_isr_unmask
|
||||
.type _xt_isr_unmask,@function
|
||||
.align 4
|
||||
_xt_isr_unmask:
|
||||
|
||||
ENTRY(16)
|
||||
|
||||
/* Enable the timer interrupt at the device level. */
|
||||
xtos_lock a7
|
||||
rsr a3, INTENABLE
|
||||
or a5, a3, a2
|
||||
wsr a5, INTENABLE
|
||||
xtos_unlock a7
|
||||
mov a2, a3
|
||||
/*movi a3, 0 */ /* protect critical section */
|
||||
/*xsr a3, INTENABLE */
|
||||
/*or a3, a2, a3 */
|
||||
/*wsr a3, INTENABLE */ /* set new INTENABLE, no need to rsync */
|
||||
|
||||
RET(16)
|
||||
|
||||
|
||||
.globl _xt_isr_mask
|
||||
.type _xt_isr_mask,@function
|
||||
.align 4
|
||||
_xt_isr_mask:
|
||||
|
||||
ENTRY(16)
|
||||
|
||||
/* Enable the timer interrupt at the device level. */
|
||||
xtos_lock a7
|
||||
rsr a3, INTENABLE
|
||||
or a5, a3, a2
|
||||
xor a5, a5, a2
|
||||
wsr a5, INTENABLE
|
||||
xtos_unlock a7
|
||||
mov a2, a3
|
||||
/*movi a3, 0 */ /* protect critical section */
|
||||
/*xsr a3, INTENABLE*/
|
||||
/*and a3, a2, a3 */
|
||||
/*wsr a3, INTENABLE*/ /* set new INTENABLE, no need to rsync */
|
||||
|
||||
RET(16)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.global _xt_read_ints
|
||||
.type _xt_read_ints,@function
|
||||
.align 4
|
||||
_xt_read_ints:
|
||||
|
||||
ENTRY(16)
|
||||
|
||||
rsr a2, INTERRUPT
|
||||
|
||||
RET(16)
|
||||
|
||||
.global _xt_clear_ints
|
||||
.type _xt_clear_ints,@function
|
||||
.align 4
|
||||
_xt_clear_ints:
|
||||
|
||||
ENTRY(16)
|
||||
|
||||
wsr a2, INTCLEAR
|
||||
|
||||
RET(16)
|
||||
|
338
components/esp8266/source/xtensa_context.S
Normal file
338
components/esp8266/source/xtensa_context.S
Normal file
@ -0,0 +1,338 @@
|
||||
/*******************************************************************************
|
||||
Copyright (c) 2006-2009 by Tensilica Inc. ALL RIGHTS RESERVED.
|
||||
These coded instructions, statements, and computer programs are the
|
||||
copyrighted works and confidential proprietary information of Tensilica Inc.
|
||||
They may not be modified, copied, reproduced, distributed, or disclosed to
|
||||
third parties in any manner, medium, or form, in whole or in part, without
|
||||
the prior written consent of Tensilica Inc.
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
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 "freertos/xtensa_rtos.h"
|
||||
|
||||
// .section .iram.text
|
||||
.section .text
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
_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 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_TMP+0 /* temp. save stuff in stack frame */
|
||||
s32i a13, sp, XT_STK_TMP+4
|
||||
s32i a9, sp, XT_STK_TMP+8
|
||||
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_TMP+0 /* recover stuff from stack frame */
|
||||
l32i a13, sp, XT_STK_TMP+4
|
||||
l32i a9, sp, XT_STK_TMP+8
|
||||
#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 */
|
||||
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 */
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
55
components/esp8266/source/xtensa_init.c
Normal file
55
components/esp8266/source/xtensa_init.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*******************************************************************************
|
||||
Copyright (c) 2006-2009 by Tensilica Inc. ALL RIGHTS RESERVED.
|
||||
These coded instructions, statements, and computer programs are the
|
||||
copyrighted works and confidential proprietary information of Tensilica Inc.
|
||||
They may not be modified, copied, reproduced, distributed, or disclosed to
|
||||
third parties in any manner, medium, or form, in whole or in part, without
|
||||
the prior written consent of Tensilica Inc.
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
XTENSA INITIALIZATION ROUTINES CODED IN C
|
||||
|
||||
This header is a place to put miscellaneous Xtensa RTOS-generic initialization
|
||||
functions that are implemented in C.
|
||||
|
||||
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.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef XTENSA_INIT_H
|
||||
#define XTENSA_INIT_H
|
||||
|
||||
#ifdef XT_BOARD
|
||||
#include <xtensa/xtbsp.h>
|
||||
#endif
|
||||
|
||||
#include "freertos/xtensa_rtos.h"
|
||||
|
||||
|
||||
#ifdef XT_RTOS_TIMER_INT
|
||||
#ifndef XT_CLOCK_FREQ
|
||||
|
||||
unsigned _xt_tick_divisor = 0; /* cached number of cycles per tick */
|
||||
|
||||
/*
|
||||
Compute and initialize at run-time the tick divisor (the number of
|
||||
processor clock cycles in an RTOS tick, used to set the tick timer).
|
||||
Called when the processor clock frequency is not known at compile-time.
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
_xt_tick_divisor_init(void)
|
||||
{
|
||||
#ifdef XT_BOARD
|
||||
_xt_tick_divisor = xtbsp_clock_freq_hz() / XT_TICK_PER_SEC;
|
||||
#else
|
||||
#error "No way to obtain processor clock frequency"
|
||||
#endif /* XT_BOARD */
|
||||
}
|
||||
|
||||
#endif /* XT_CLOCK_FREQ */
|
||||
#endif /* XT_RTOS_TIMER_INT */
|
||||
|
||||
#endif /* XTENSA_INIT_H */
|
1397
components/esp8266/source/xtensa_vectors.S
Normal file
1397
components/esp8266/source/xtensa_vectors.S
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user