kopia lustrzana https://github.com/espressif/esp-idf
226 wiersze
7.0 KiB
ArmAsm
226 wiersze
7.0 KiB
ArmAsm
![]() |
/*******************************************************************************
|
||
|
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/xtensa_context.h"
|
||
|
#include "freertos/FreeRTOSConfig.h"
|
||
![]() |
|
||
|
#if XCHAL_HAVE_INTERRUPTS
|
||
|
|
||
|
/*
|
||
|
-------------------------------------------------------------------------------
|
||
|
INTENABLE virtualization information.
|
||
|
-------------------------------------------------------------------------------
|
||
|
*/
|
||
|
|
||
![]() |
|
||
|
#if XT_USE_SWPRI
|
||
|
/* Warning - this is not multicore-compatible. */
|
||
![]() |
.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 */
|
||
![]() |
#endif
|
||
![]() |
|
||
|
/*
|
||
|
-------------------------------------------------------------------------------
|
||
|
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.
|
||
![]() |
|
||
|
Stored as:
|
||
|
int 0 cpu 0
|
||
|
int 0 cpu 1
|
||
|
...
|
||
|
int 0 cpu n
|
||
|
int 1 cpu 0
|
||
|
int 1 cpu 1
|
||
|
etc
|
||
![]() |
-------------------------------------------------------------------------------
|
||
|
*/
|
||
|
|
||
|
.data
|
||
|
.global _xt_interrupt_table
|
||
|
.align 8
|
||
|
|
||
|
_xt_interrupt_table:
|
||
|
|
||
|
.set i, 0
|
||
![]() |
.rept XCHAL_NUM_INTERRUPTS*portNUM_PROCESSORS
|
||
![]() |
.word xt_unhandled_interrupt /* handler address */
|
||
|
.word i /* handler arg (default: intnum) */
|
||
|
.set i, i+1
|
||
|
.endr
|
||
|
|
||
|
#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.
|
||
![]() |
|
||
|
Stored as:
|
||
|
exc 0 cpu 0
|
||
|
exc 0 cpu 1
|
||
|
...
|
||
|
exc 0 cpu n
|
||
|
exc 1 cpu 0
|
||
|
exc 1 cpu 1
|
||
|
etc
|
||
![]() |
-------------------------------------------------------------------------------
|
||
|
*/
|
||
|
|
||
|
.data
|
||
|
.global _xt_exception_table
|
||
|
.align 4
|
||
|
|
||
|
_xt_exception_table:
|
||
![]() |
.rept XCHAL_EXCCAUSE_NUM * portNUM_PROCESSORS
|
||
![]() |
.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 if XT_USE_SWPRI is
|
||
|
enabled.
|
||
![]() |
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
|
||
![]() |
#if XT_USE_SWPRI
|
||
![]() |
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 a3, 0
|
||
|
xsr a3, INTENABLE /* Disables all interrupts */
|
||
![]() |
rsync
|
||
![]() |
or a2, a3, a2 /* set bits in mask */
|
||
|
wsr a2, INTENABLE /* Re-enable ints */
|
||
![]() |
rsync
|
||
![]() |
mov a2, a3 /* return prev mask */
|
||
|
#endif
|
||
![]() |
#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 if XT_USE_SWPRI is
|
||
|
enabled.
|
||
![]() |
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
|
||
![]() |
#if XT_USE_SWPRI
|
||
![]() |
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 a4, 0
|
||
|
xsr a4, INTENABLE /* Disables all interrupts */
|
||
![]() |
rsync
|
||
![]() |
or a3, a4, a2 /* set bits in mask */
|
||
|
xor a3, a3, a2 /* invert bits in mask set in mask, essentially clearing them */
|
||
|
wsr a3, INTENABLE /* Re-enable ints */
|
||
![]() |
rsync
|
||
![]() |
mov a2, a4 /* return prev mask */
|
||
![]() |
#endif
|
||
![]() |
#else
|
||
|
movi a2, 0 /* return zero */
|
||
|
#endif
|
||
|
RET0
|
||
|
|
||
|
.size xt_ints_off, . - xt_ints_off
|
||
|
|
||
|
|