feat(esp8266): Add fucntion to pass compiling

Remove unused code.
This commit is contained in:
Dong Heng
2018-04-19 14:22:14 +08:00
parent f8692936e0
commit bd148bbb34
2 changed files with 1405 additions and 2239 deletions

View File

@ -10,7 +10,6 @@
*/
#include <xtensa/coreasm.h>
#include <xtensa/config/specreg.h>
#include "xtos-internal.h"
#include "freertos/xtensa_rtos.h"
@ -23,6 +22,14 @@
// .section .iram.text
.section .text
.macro xtos_lock ax
rsil \ax, XCHAL_EXCM_LEVEL
.endm
.macro xtos_unlock ax
wsr \ax, PS
.endm
/*
**********************************************************************************************************
* vPortYield

View File

@ -53,865 +53,29 @@ NOTES on the use of 'call0' for long jumps instead of 'j':
#include <xtensa/coreasm.h>
#include <xtensa/config/system.h>
#include <xtensa/config/specreg.h>
#include "xtos-internal.h"
#include <xtensa/xtruntime-frames.h>
#include "freertos/xtensa_rtos.h"
#ifdef FOR_BAOFENG
#define _INTERRUPT_LEVEL 3
STRUCT_BEGIN
STRUCT_FIELD (long,4,HESF_,SAR)
STRUCT_FIELD (long,4,HESF_,WINDOWSTART)
STRUCT_FIELD (long,4,HESF_,WINDOWBASE)
STRUCT_FIELD (long,4,HESF_,EPC1)
STRUCT_FIELD (long,4,HESF_,EXCCAUSE)
STRUCT_FIELD (long,4,HESF_,EXCVADDR)
STRUCT_FIELD (long,4,HESF_,EXCSAVE1)
STRUCT_FIELD (long,4,HESF_,VPRI) /* (XEA1 only) */
#if XCHAL_HAVE_MAC16
STRUCT_FIELD (long,4,HESF_,ACCLO)
STRUCT_FIELD (long,4,HESF_,ACCHI)
/*STRUCT_AFIELD(long,4,HESF_,MR, 4)*/
#endif
#if XCHAL_HAVE_LOOPS
STRUCT_FIELD (long,4,HESF_,LCOUNT)
STRUCT_FIELD (long,4,HESF_,LBEG)
STRUCT_FIELD (long,4,HESF_,LEND)
#endif
STRUCT_AFIELD(long,4,HESF_,AREG, 64) /* address registers ar0..ar63 */
#define HESF_AR(n) HESF_AREG+((n)*4)
STRUCT_END(HighPriFrame)
#define HESF_TOTALSIZE HighPriFrameSize+32 /* 32 bytes for interrupted code's save areas under SP */
#if XCHAL_HAVE_XEA1 && HAVE_XSR /* could be made true for T1040 and T1050 */
# error "high-priority interrupt stack frame needs adjustment if HAVE_XSR is allowed with XEA1"
#endif
#define PRI_N_STACK_SIZE 2048 /* default to 1 kB stack for each level-N handling */
// Allocate save area and stack:
// (must use .bss, not .comm, because the subsequent .set does not work otherwise)
.section .bss, "aw"
.align 16
LABEL(_Pri_,_Stack): .space PRI_N_STACK_SIZE + HESF_TOTALSIZE
#if HAVE_XSR
.data
.global LABEL(_Pri_,_HandlerAddress)
LABEL(_Pri_,_HandlerAddress): .space 4
#endif
.section .UserEnter.text, "ax"
.global call_user_start
.type call_user_start,@function
.align 4
.literal_position
call_user_start:
movi a2, 0x40100000 /* note: absolute symbol, not a ptr */
wsr a2, vecbase
call0 user_start /* user exception handler */
#if 0
/*
Panic handler.
Should be reached by call0 (preferable) or jump only. If call0, a0 says where
from. If on simulator, display panic message and abort, else loop indefinitely.
*/
// .section .iram.text
.section .text
.global _xt_panic
.type _xt_panic,@function
.align 4
_xt_panic:
#ifdef XT_SIMULATOR
addi a4, a0, -3 /* point to call0 */
movi a3, _xt_panic_message
movi a2, SYS_log_msg
simcall
movi a2, SYS_gdb_abort
simcall
#else
rsil a2, XCHAL_EXCM_LEVEL /* disable all low & med ints */
1: j 1b /* loop infinitely */
#endif
.section .rodata, "a"
.align 4
_xt_panic_message:
.string "\n*** _xt_panic() was called from 0x%08x or jumped to. ***\n"
#endif
#ifdef XT_INTEXC_HOOKS
/*
Hooks to dynamically install handlers for exceptions and interrupts.
Allows automated regression frameworks to install handlers per test.
Consists of an array of function pointers indexed by interrupt level,
with index 0 containing the entry for user exceptions.
Initialized with all 0s, meaning no handler is installed at each level.
See comment in xtensa_rtos.h for more details.
*/
.data
.global _xt_intexc_hooks
.type _xt_intexc_hooks,@object
.align 4
_xt_intexc_hooks:
.fill XT_INTEXC_HOOK_NUM, 4, 0
#endif
/*******************************************************************************
EXCEPTION AND LEVEL 1 INTERRUPT VECTORS AND LOW LEVEL HANDLERS
(except window exception vectors).
Each vector goes at a predetermined location according to the Xtensa
hardware configuration, which is ensured by its placement in a special
section known to the Xtensa linker support package (LSP). It performs
the minimum necessary before jumping to the handler in the .text section.
The corresponding handler goes in the normal .text section. It sets up
the appropriate stack frame, saves a few vector-specific registers and
calls XT_RTOS_INT_ENTER to save the rest of the interrupted context
and enter the RTOS, then sets up a C environment. It then calls the
user's interrupt handler code (which may be coded in C) and finally
calls XT_RTOS_INT_EXIT to transfer control to the RTOS for scheduling.
While XT_RTOS_INT_EXIT does not return directly to the interruptee,
eventually the RTOS scheduler will want to dispatch the interrupted
task or handler. The scheduler will return to the exit point that was
saved in the interrupt stack frame at XT_STK_EXIT.
Add to compile passing.
*******************************************************************************/
/*
--------------------------------------------------------------------------------
Debug Exception.
--------------------------------------------------------------------------------
*/
#undef HAVE_XSR
#define HAVE_XSR 1
#if XCHAL_HAVE_DEBUG
#define _JOIN2(a, b) a ## b
#define _JOIN3(a, b, c) a ## b ## c
.begin literal_prefix .DebugExceptionVector
.section .DebugExceptionVector.text, "ax"
.global _DebugExceptionVector
.align 4
.literal_position
_DebugExceptionVector:
#define JOIN2(a, b) _JOIN2(a, b)
#define JOIN3(a, b, c) _JOIN3(a, b, c)
#ifdef XT_SIMULATOR
/*
In the simulator, let the debugger (if any) handle the debug exception,
or simply stop the simulation:
*/
wsr a2, EXCSAVE+XCHAL_DEBUGLEVEL /* save a2 where sim expects it */
movi a2, SYS_gdb_enter_sktloop
simcall /* have ISS handle debug exc. */
#elif 0 /* change condition to 1 to use the HAL minimal debug handler */
wsr a3, EXCSAVE+XCHAL_DEBUGLEVEL
movi a3, xthal_debugexc_defhndlr_nw /* use default debug handler */
jx a3
#else
wsr a0, EXCSAVE+XCHAL_DEBUGLEVEL /* save original a0 somewhere */
call0 user_fatal_exception_handler /* does not return */
rfi XCHAL_DEBUGLEVEL /* make a0 point here not later */
#endif
#define LABEL(a, b) _JOIN3(a, 3, b)
.end literal_prefix
#endif
/*
--------------------------------------------------------------------------------
Double Exception.
Double exceptions are not a normal occurrence. They indicate a bug of some kind.
--------------------------------------------------------------------------------
*/
#ifdef XCHAL_DOUBLEEXC_VECTOR_VADDR
.begin literal_prefix .DoubleExceptionVector
.section .DoubleExceptionVector.text, "ax"
.global _DoubleExceptionVector
.align 4
.literal_position
_DoubleExceptionVector:
#if XCHAL_HAVE_DEBUG
break 1, 4 /* unhandled double exception */
#endif
call0 user_fatal_exception_handler /* does not return */
rfde /* make a0 point here not later */
.end literal_prefix
#endif /* XCHAL_DOUBLEEXC_VECTOR_VADDR */
/*
--------------------------------------------------------------------------------
Kernel Exception (including Level 1 Interrupt from kernel mode).
--------------------------------------------------------------------------------
*/
.begin literal_prefix .KernelExceptionVector
.section .KernelExceptionVector.text, "ax"
.global _KernelExceptionVector
.align 4
.literal_position
_KernelExceptionVector:
wsr a0, EXCSAVE_1 /* preserve a0 */
call0 _xt_kernel_exc /* kernel exception handler */
/* never returns here - call0 is used as a jump (see note at top) */
.end literal_prefix
// .section .iram.text
.section .text
.align 4
.literal_position
_xt_kernel_exc:
#if XCHAL_HAVE_DEBUG
break 1, 0 /* unhandled kernel exception */
#endif
call0 user_fatal_exception_handler /* does not return */
rfe /* make a0 point here not there */
/*
--------------------------------------------------------------------------------
User Exception (including Level 1 Interrupt from user mode).
--------------------------------------------------------------------------------
*/
.begin literal_prefix .UserExceptionVector
.section .UserExceptionVector.text, "ax"
.global _UserExceptionVector
.type _UserExceptionVector,@function
.align 4
.literal_position
_UserExceptionVector:
wsr a0, EXCSAVE_1 /* preserve a0 */
call0 _xt_user_exc /* user exception handler */
/* never returns here - call0 is used as a jump (see note at top) */
.end literal_prefix
// .section .iram.text
.section .text
/*
Insert some waypoints for jumping beyond the signed 8-bit range
of conditional branch instructions, so the conditional branchces
to specific-cause exception handlers are not taken in the mainline.
Saves some cycles in the mainline.
*/
#if XCHAL_HAVE_WINDOWED
.align 4
_xt_to_alloca_exc:
call0 _xt_alloca_exc /* in window vectors section */
/* never returns here - call0 is used as a jump (see note at top) */
#endif
.align 4
.literal_position
_xt_to_syscall_exc:
call0 _xt_syscall_exc
/* never returns here - call0 is used as a jump (see note at top) */
/* User exception handler begins here. */
.type _xt_user_exc,@function
.align 4
_xt_user_exc:
/*
Handle alloca and syscall exceptions before allocating stack frame and
interacting with RTOS.
*/
rsr a0, EXCCAUSE
#if XCHAL_HAVE_WINDOWED
beqi a0, EXCCAUSE_ALLOCA, _xt_to_alloca_exc
#endif
beqi a0, EXCCAUSE_SYSCALL, _xt_to_syscall_exc
/* Allocate interrupt stack frame and save minimal context. */
mov a0, sp /* sp == a1 */
addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */
s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */
rsr a0, PS /* save interruptee's PS */
s32i a0, sp, XT_STK_PS
rsr a0, EPC_1 /* save interruptee's PC */
s32i a0, sp, XT_STK_PC
rsr a0, EXCSAVE_1 /* save interruptee's a0 */
s32i a0, sp, XT_STK_A0
movi a0, _xt_user_exit /* save exit point for dispatch */
s32i a0, sp, XT_STK_EXIT
/*
Handle co-processor exceptions after allocating stack frame and before
interacting with RTOS.
*/
#if XCHAL_CP_NUM > 0
rsr a0, EXCCAUSE
bgeui a0, EXCCAUSE_CP0_DISABLED, _xt_to_coproc_exc
.L_xt_user_exc_not_coproc:
#endif
/* Save rest of interrupt context and enter RTOS. */
call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
/* !! We are now on the RTOS system stack !! */
/* Set up PS for C, reenable hi-pri interrupts, and clear EXCM. */
#ifdef __XTENSA_CALL0_ABI__
movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM
#else
movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE
#endif
wsr a0, PS
rsync
/* !! It is OK to call C handlers after this point. !! */
/* Handle exceptions per EXCCAUSE. */
rsr a2, EXCCAUSE /* a2 = exception cause */
beqi a2, EXCCAUSE_LEVEL1INTERRUPT, .L_xt_user_int /* level 3 int */
#ifdef XT_INTEXC_HOOKS
/*
Call exception hook to pre-handle exceptions (if installed).
Pass EXCCAUSE in a2, and check result in a2 (if -1, skip default handling).
*/
movi a0, _xt_intexc_hooks
l32i a0, a0, 0 /* user exception hook index 0 */
beqz a0, 1f
.Ln_xt_user_exc_call_hook:
#ifdef __XTENSA_CALL0_ABI__
callx0 a0
beqi a2, -1, .L_xt_user_done
#else
mov a6, a2
callx4 a0
beqi a6, -1, .L_xt_user_done
mov a2, a6
#endif
1:
#endif
/* USER_EDIT:
ADD ANY CUSTOM EXCEPTION HANDLER CODE HERE, OR CALL C HANDLER.
The exeption cause is in A2. After handling, jump to .L_xt_user_int .
Note on Call0 ABI: Callee-saved regs (a12-15) have not yet been saved,
so should not be corrupted here. A C handler will not corrupt them.
*/
/* If we get here, the exception has not been handled. */
.Ln_xt_user_unhandled:
#if XCHAL_HAVE_DEBUG
break 1, 1 /* unhandled user exception */
#endif
call0 user_fatal_exception_handler
/* Handle level 1 interrupts. OK to enable med-pri interrupts now. */
.L_xt_user_int:
rsil a0, 1 /* reenable ints above level 1 */
/*
Get mask of pending, enabled interrupts at this level into a2.
Comment this out if there is only one interrupt at this level.
*/
rsr a2, INTENABLE
rsr a3, INTERRUPT
movi a4, XCHAL_INTLEVEL1_MASK
and a2, a2, a3
and a2, a2, a4
#ifdef XT_INTEXC_HOOKS
/* Call interrupt hook if present to (pre)handle interrupts. */
movi a0, _xt_intexc_hooks
l32i a0, a0, 1<<2
beqz a0, 2f
.Ln_xt_user_int_call_hook:
#ifdef __XTENSA_CALL0_ABI__
callx0 a0
beqz a2, .L_xt_user_done
#else
mov a6, a2
callx4 a0
beqz a6, .L_xt_user_done
mov a2, a6
#endif
2:
#endif
/* USER_EDIT:
ADD LOW PRIORITY LEVEL 1 INTERRUPT HANDLER CODE HERE, OR CALL C HANDLER.
At this point, a2 contains a mask of pending, enabled ints at this level.
Note on Call0 ABI: Callee-saved regs (a12-15) have not yet been saved,
so should not be corrupted here. A C handler will not corrupt them.
HANDLER MUST CAUSE LEVEL TRIGGERED INTERRUPT REQUESTS TO BE DEASSERTED.
When done, ensure a2 contains a mask of unhandled (still pending)
enabled ints at this level, and fall through.
*/
#if XT_TIMER_INTPRI == 1
.Ln_xt_user_int_timer:
movi a3, 0xFFBF
and a3, a2, a3
bnez a3, 3f
/* Interrupt handler for the RTOS tick timer if at this level. */
movi a3, XT_TIMER_INTEN /* timer interrupt bit */
/*bnone a2, a3, 3f*/
#ifdef __XTENSA_CALL0_ABI__
sub a12, a2, a3 /* clear timer int and save mask */
call0 XT_RTOS_TIMER_INT
mov a2, a12 /* recover mask of remaining ints */
beqz a2, 4f
#else
call4 XT_RTOS_TIMER_INT /* a2 automatically preserved */
sub a2, a2, a3 /* clear timer int from mask */
#endif
3:
call0 _xt_isr_handler
bnez a2, .Ln_xt_user_int_timer
#endif
4:
/* All interrupts at this level should have been handled now. */
beqz a2, .L_xt_user_done
/* If we get here, we have an unhandled interrupt. */
#if XCHAL_HAVE_DEBUG
break 1, 1 /* unhandled user exception */
/* EXCCAUSE == 4 (level 1 int) */
#endif
call0 user_fatal_exception_handler
/* Done handling after XT_RTOS_INT_ENTER. Give control to RTOS. */
.L_xt_user_done:
call0 XT_RTOS_INT_EXIT /* does not return directly here */
/*
Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT
on entry and used to return to a thread or interrupted interrupt handler.
*/
.global _xt_user_exit
.type _xt_user_exit,@function
.align 4
_xt_user_exit:
l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */
wsr a0, PS
l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */
wsr a0, EPC_1
l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */
l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */
rsync /* ensure PS and EPC written */
rfe /* PS.EXCM is cleared */
/*
--------------------------------------------------------------------------------
Syscall Exception Handler (jumped to from User Exception Handler).
Syscall 0 is required to spill the register windows (no-op in Call 0 ABI).
Only syscall 0 is handled here. Other syscalls return -1 to caller in a2.
--------------------------------------------------------------------------------
*/
// .section .iram.text
.section .text
.type _xt_syscall_exc,@function
.align 4
_xt_syscall_exc:
#ifdef __XTENSA_CALL0_ABI__
/*
Save minimal regs for scratch. Syscall 0 does nothing in Call0 ABI.
Use a minimal stack frame (16B) to save A2 & A3 for scratch.
PS.EXCM could be cleared here, but unlikely to improve worst-case latency.
rsr a0, PS
addi a0, a0, -PS_EXCM_MASK
wsr a0, PS
*/
addi sp, sp, -16
s32i a2, sp, 8
s32i a3, sp, 12
#else /* Windowed ABI */
/*
Save necessary context and spill the register windows.
PS.EXCM is still set and must remain set until after the spill.
Reuse context save function though it saves more than necessary.
For this reason, a full interrupt stack frame is allocated.
*/
addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */
s32i a12, sp, XT_STK_A12 /* _xt_context_save requires A12- */
s32i a13, sp, XT_STK_A13 /* A13 to have already been saved */
call0 _xt_context_save
#endif
/*
Grab the interruptee's PC and skip over the 'syscall' instruction.
If it's at the end of a zero-overhead loop and it's not on the last
iteration, decrement loop counter and skip to beginning of loop.
*/
rsr a2, EPC_1 /* a2 = PC of 'syscall' */
addi a3, a2, 3 /* ++PC */
#if XCHAL_HAVE_LOOPS
rsr a0, LEND /* if (PC == LEND */
bne a3, a0, 1f
rsr a0, LCOUNT /* && LCOUNT != 0) */
beqz a0, 1f /* { */
addi a0, a0, -1 /* --LCOUNT */
rsr a3, LBEG /* PC = LBEG */
wsr a0, LCOUNT /* } */
#endif
1: wsr a3, EPC_1 /* update PC */
/* Restore interruptee's context and return from exception. */
#ifdef __XTENSA_CALL0_ABI__
l32i a2, sp, 8
l32i a3, sp, 12
addi sp, sp, 16
#else
call0 _xt_context_restore
addi sp, sp, XT_STK_FRMSZ
#endif
movi a0, -1
movnez a2, a0, a2 /* return -1 if not syscall 0 */
rsr a0, EXCSAVE_1
rfe
/*
Currently only shells for high priority interrupt handlers are provided
here. However a template and example can be found in the Tensilica tools
documentation: "Microprocessor Programmer's Guide".
*/
#if XCHAL_HAVE_NMI
.begin literal_prefix .NMIExceptionVector
.section .NMIExceptionVector.text, "ax"
.global _NMIExceptionVector
.type _NMIExceptionVector,@function
.align 4
.literal_position
_NMIExceptionVector:
wsr a0, EXCSAVE + XCHAL_NMILEVEL _ /* preserve a0 */
call0 _xt_nmi /* load interrupt handler */
/* never returns here - call0 is used as a jump (see note at top) */
.end literal_prefix
// .section .iram.text
.section .text
.type _xt_nmi,@function
.align 4
_xt_nmi:
#ifdef XT_INTEXC_HOOKS
/* Call interrupt hook if present to (pre)handle interrupts. */
movi a0, _xt_intexc_hooks
l32i a0, a0, XCHAL_NMILEVEL<<2
beqz a0, 1f
.Ln_xt_nmi_call_hook:
callx0 a0 /* must NOT disturb stack! */
1:
#endif
/* USER_EDIT:
ADD HIGH PRIORITY NON-MASKABLE INTERRUPT (NMI) HANDLER CODE HERE.
*/
movi a0, LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE // get ptr to save area
// interlock
// Save a few registers so we can do some work:
s32i a2, a0, HESF_AR(2)
#if HAVE_XSR
//movi a0, LABEL(_Level,FromVector) // this dispatcher's address
movi a2, LABEL(_Pri_,_HandlerAddress) // dispatcher address var.
s32i a1, a0, HESF_AR(1)
l32i a2, a2, 0 // get dispatcher address
s32i a3, a0, HESF_AR(3)
xsr a2, EXCSAVE_LEVEL // get saved a0, restore dispatcher address
#else
rsr a2, EXCSAVE_LEVEL // get saved a0
s32i a1, a0, HESF_AR(1)
s32i a3, a0, HESF_AR(3)
#endif
s32i a4, a0, HESF_AR(4)
s32i a2, a0, HESF_AR(0)
// Save/restore all exception state
// (IMPORTANT: this code assumes no general exceptions occur
// during the execution of this dispatcher until this state
// is completely saved and from the point it is restored.)
//
// Exceptions that may normally occur within the C handler
// include window exceptions (affecting EPC1), alloca exceptions
// (affecting EPC1/EXCCAUSE and its handling uses EXCSAVE1),
// and possibly others depending on the particular C handler
// (possibly needing save/restore of EXCVADDR; and EXCVADDR
// is also possibly corrupted by any access thru an auto-refill
// way on a processor with a full MMU).
//
rsr a3, EPC1
rsr a4, EXCCAUSE
s32i a3, a0, HESF_EPC1
s32i a4, a0, HESF_EXCCAUSE
#if !XCHAL_HAVE_XEA1
rsr a3, EXCVADDR
s32i a3, a0, HESF_EXCVADDR
#endif
rsr a4, EXCSAVE1
s32i a4, a0, HESF_EXCSAVE1
#ifdef __XTENSA_WINDOWED_ABI__
// Save remainder of entire address register file (!):
movi a2, XCHAL_NUM_AREGS - 8 // how many saved so far
#endif
s32i a5, a0, HESF_AR(5)
s32i a6, a0, HESF_AR(6)
s32i a7, a0, HESF_AR(7)
1: s32i a8, a0, HESF_AR(8)
s32i a9, a0, HESF_AR(9)
s32i a10, a0, HESF_AR(10)
s32i a11, a0, HESF_AR(11)
s32i a12, a0, HESF_AR(12)
s32i a13, a0, HESF_AR(13)
s32i a14, a0, HESF_AR(14)
s32i a15, a0, HESF_AR(15)
#ifdef __XTENSA_WINDOWED_ABI__
addi a8, a2, -8
addi a10, a0, 8*4
rotw 2
bnez a2, 1b // loop until done
rotw 2
// back to original a2 ...
// Save a few other registers required for C:
rsr a3, WINDOWSTART
rsr a4, WINDOWBASE
s32i a3, a0, HESF_WINDOWSTART
s32i a4, a0, HESF_WINDOWBASE
// Setup window registers for first caller:
movi a3, 1
movi a4, 0
wsr a3, WINDOWSTART
wsr a4, WINDOWBASE
rsync
// Note: register window has rotated, ie. a0..a15 clobbered.
#endif /* __XTENSA_WINDOWED_ABI__ */
movi a1, LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE // get ptr to save area (is also initial stack ptr)
movi a0, 0 // mark start of call frames in stack
// Critical state saved, a bit more to do to allow window exceptions...
// We now have a C-coherent stack and window state.
// Still have to fix PS while making sure interrupts stay disabled
// at the appropriate level (ie. level 2 and below are disabled in this case).
#if XCHAL_HAVE_XEA1
movi a7, _xtos_intstruct // address of interrupt management globals
rsilft a3, _INTERRUPT_LEVEL, XTOS_LOCKLEVEL // lockout
movi a4, ~INTLEVEL_N_BELOW_MASK // mask out all interrupts at this level or lower
l32i a3, a7, XTOS_VPRI_ENABLED_OFS // read previous _xtos_vpri_enabled
l32i a5, a7, XTOS_ENABLED_OFS // read _xtos_enabled
s32i a4, a7, XTOS_VPRI_ENABLED_OFS // set new _xtos_vpri_enabled (mask interrupts as if at _INTERRUPT_LEVEL)
s32i a3, a1, HESF_VPRI // save previous vpri
movi a2, 0x50020 // WOE=1, UM=1, INTLEVEL=0
and a3, a5, a4 // mask out selected interrupts
wsr a3, INTENABLE // disable all low-priority interrupts
#else
// Load PS for C code, clear EXCM (NOTE: this step is different for XEA1):
# ifdef __XTENSA_CALL0_ABI__
movi a2, 0x00020 + _INTERRUPT_LEVEL // WOE=0, CALLINC=0, UM=1, INTLEVEL=N, EXCM=0, RING=0
# else
movi a2, 0x50020 + _INTERRUPT_LEVEL // WOE=1, CALLINC=1, UM=1, INTLEVEL=N, EXCM=0, RING=0
# endif
#endif
wsr a2, PS // update PS to enable window exceptions, etc as per above
rsync
// Okay, window exceptions can now happen (although we have to call
// deep before any will happen because we've reset WINDOWSTART).
// Save other state that might get clobbered by C code:
////////////////// COMMON DISPATCH CODE BEGIN
rsr a14, SAR
s32i a14, a1, HESF_SAR
#if XCHAL_HAVE_LOOPS
rsr a14, LCOUNT
s32i a14, a1, HESF_LCOUNT
rsr a14, LBEG
s32i a14, a1, HESF_LBEG
rsr a14, LEND
s32i a14, a1, HESF_LEND
#endif
#if XCHAL_HAVE_MAC16
rsr a14, ACCLO
s32i a14, a1, HESF_ACCLO
rsr a14, ACCHI
s32i a14, a1, HESF_ACCHI
#endif
#ifdef __XTENSA_CALL0_ABI__
#ifdef FOR_BAOFENG
movi a13, NMI_Handler
#else
movi a13, wDev_ProcessFiq
#endif
callx0 a13 // call interrupt's C handler
#else
movi a13, NMI_Handler
callx4 a13 // call interrupt's C handler
#endif
// Restore everything, and return.
// Three temp registers are required for this code to be optimal (no interlocks) in
// T2xxx microarchitectures with 7-stage pipe; otherwise only two
// registers would be needed.
//
#if XCHAL_HAVE_LOOPS
l32i a13, a1, HESF_LCOUNT
l32i a14, a1, HESF_LBEG
l32i a15, a1, HESF_LEND
wsr a13, LCOUNT
wsr a14, LBEG
wsr a15, LEND
#endif
#if XCHAL_HAVE_MAC16
l32i a13, a1, HESF_ACCLO
l32i a14, a1, HESF_ACCHI
wsr a13, ACCLO
wsr a14, ACCHI
#endif
l32i a15, a1, HESF_SAR
wsr a15, SAR
////////////////// COMMON DISPATCH CODE END
#if XCHAL_HAVE_XEA1
// Here, a7 = address of interrupt management globals
l32i a4, a1, HESF_VPRI // restore previous vpri
rsil a3, XTOS_LOCKLEVEL // lockout
l32i a5, a7, XTOS_ENABLED_OFS // read _xtos_enabled
s32i a4, a7, XTOS_VPRI_ENABLED_OFS // set new _xtos_vpri_enabled
movi a2, 0x00020 + _INTERRUPT_LEVEL // WOE=0, UM=1, INTLEVEL=N
/* movi a2, 0x00020 + 0 // WOE=0, UM=1, INTLEVEL=N */
and a3, a5, a4 // mask out selected interrupts
wsr a3, INTENABLE // disable all low-priority interrupts
#else
// Load PS for interrupt exit, set EXCM:
movi a2, 0x00030 + _INTERRUPT_LEVEL // WOE=0, CALLINC=0, UM=1, INTLEVEL=N, EXCM=1, RING=0
/* movi a2, 0x00030 + 0 // WOE=0, CALLINC=0, UM=1, INTLEVEL=N, EXCM=1, RING=0 */
#endif
wsr a2, PS // update PS to disable window exceptions, etc as per above
rsync
// NOTE: here for XEA1, restore INTENABLE etc...
#ifdef __XTENSA_WINDOWED_ABI__
// Restore window registers:
l32i a2, a1, HESF_WINDOWSTART
l32i a3, a1, HESF_WINDOWBASE
wsr a2, WINDOWSTART
wsr a3, WINDOWBASE
rsync
// Note: register window has rotated, ie. a0..a15 clobbered.
// Reload initial stack pointer:
movi a1, LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE // - 16
movi a6, XCHAL_NUM_AREGS - 8 // how many saved so far
addi a7, a1, -8*4
// Restore entire register file (!):
1:
addi a14, a6, -8
addi a15, a7, 8*4
l32i a4, a15, HESF_AR(4)
l32i a5, a15, HESF_AR(5)
l32i a6, a15, HESF_AR(6)
l32i a7, a15, HESF_AR(7)
l32i a8, a15, HESF_AR(8)
l32i a9, a15, HESF_AR(9)
l32i a10,a15, HESF_AR(10)
l32i a11,a15, HESF_AR(11)
rotw 2
bnez a6, 1b // loop until done
l32i a4, a7, HESF_AR(12)
l32i a5, a7, HESF_AR(13)
l32i a6, a7, HESF_AR(14)
l32i a7, a7, HESF_AR(15)
rotw 2
// back to original a1 ...
#else /* Call0 ABI: */
l32i a4, a1, HESF_AR(4) // restore general registers
l32i a5, a1, HESF_AR(5)
l32i a6, a1, HESF_AR(6)
l32i a7, a1, HESF_AR(7)
l32i a8, a1, HESF_AR(8)
l32i a9, a1, HESF_AR(9)
l32i a10, a1, HESF_AR(10)
l32i a11, a1, HESF_AR(11)
l32i a12, a1, HESF_AR(12)
l32i a13, a1, HESF_AR(13)
l32i a14, a1, HESF_AR(14)
l32i a15, a1, HESF_AR(15)
#endif /* __XTENSA_WINDOWED_ABI__ */
// Restore exception state:
l32i a2, a1, HESF_EPC1
l32i a3, a1, HESF_EXCCAUSE
wsr a2, EPC1
wsr a3, EXCCAUSE
#if !XCHAL_HAVE_XEA1
l32i a2, a1, HESF_EXCVADDR
wsr a2, EXCVADDR
#endif
l32i a3, a1, HESF_EXCSAVE1
wsr a3, EXCSAVE1
l32i a0, a1, HESF_AR(0)
l32i a2, a1, HESF_AR(2)
l32i a3, a1, HESF_AR(3)
l32i a1, a1, HESF_AR(1)
rfi XCHAL_NMILEVEL
#if 0
.align 4
.L_xt_nmi_exit:
rsr a0, EXCSAVE + XCHAL_NMILEVEL /* restore a0 */
rfi XCHAL_NMILEVEL
#endif
#endif /* NMI */
#else /*********************Seperate from BAOFENG and NORMAL********************/
#define EXCSAVE_LEVEL _JOIN2(EXCSAVE_, 3)
/*******************************************************************************/
#define _INTERRUPT_LEVEL 3
@ -1374,9 +538,10 @@ LoadStoreErrorHandler:
.type call_user_start,@function
.align 4
.literal_position
vector_entr:
.word 0x40100000
call_user_start:
movi a2, 0x40100000 /* note: absolute symbol, not a ptr */
l32r a2, 0x40100000
wsr a2, vecbase
call0 user_start /* user exception handler */
@ -2230,9 +1395,3 @@ nmi_rfi:
rfi XCHAL_NMILEVEL
#endif
#endif /* NMI */
#endif