Add git attributes (#245)

* Add .gitattributes configured to normailze line endings to LF

* replace crlf with lf, per .gitattributes
This commit is contained in:
David Chalco 2021-01-15 11:04:31 -08:00 committed by GitHub
parent 23f641850d
commit 578d040659
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 5771 additions and 5666 deletions

105
.gitattributes vendored Normal file
View file

@ -0,0 +1,105 @@
# Line ending normalization
* text=auto
# Documents
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
*.md text
*.adoc text
*.textile text
*.mustache text
*.csv text
*.tab text
*.tsv text
*.sql text
*.html text
*.css text
# Graphics
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.tif binary
*.tiff binary
*.ico binary
*.svg binary
*.eps binary
#sources
*.c text
*.cc text
*.cxx text
*.cpp text
*.c++ text
*.hpp text
*.h text
*.h++ text
*.hh text
*.s text
*.S text
*.asm text
# Compiled Object files
*.slo binary
*.lo binary
*.o binary
*.obj binary
# Precompiled Headers
*.gch binary
*.pch binary
# Compiled Dynamic libraries
*.so binary
*.dylib binary
*.dll binary
# Compiled Static libraries
*.lai binary
*.la binary
*.a binary
*.lib binary
# Executables
*.exe binary
*.out binary
*.app binary
# Basic .gitattributes for a python repo.
# Source files
# ============
*.pxd text
*.py text
*.py3 text
*.pyw text
*.pyx text
# Binary files
# ============
*.db binary
*.p binary
*.pkl binary
*.pyc binary
*.pyd binary
*.pyo binary
# Note: .db, .p, and .pkl files are associated
# with the python modules ``pickle``, ``dbm.*``,
# ``shelve``, ``marshal``, ``anydbm``, & ``bsddb``
# (among others).
*.sh text
make text
makefile text
*.mk text

File diff suppressed because it is too large Load diff

View file

@ -1,390 +1,390 @@
/******************************************************************************* /*******************************************************************************
Copyright (c) 2006-2015 Cadence Design Systems Inc. Copyright (c) 2006-2015 Cadence Design Systems Inc.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to permit persons to whom the Software is furnished to do so, subject to
the following conditions: the following conditions:
The above copyright notice and this permission notice shall be included The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software. in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
XTENSA CONTEXT FRAMES AND MACROS FOR RTOS ASSEMBLER SOURCES XTENSA CONTEXT FRAMES AND MACROS FOR RTOS ASSEMBLER SOURCES
This header contains definitions and macros for use primarily by Xtensa This header contains definitions and macros for use primarily by Xtensa
RTOS assembly coded source files. It includes and uses the Xtensa hardware RTOS assembly coded source files. It includes and uses the Xtensa hardware
abstraction layer (HAL) to deal with config specifics. It may also be abstraction layer (HAL) to deal with config specifics. It may also be
included in C source files. included in C source files.
!! Supports only Xtensa Exception Architecture 2 (XEA2). XEA1 not supported. !! !! Supports only Xtensa Exception Architecture 2 (XEA2). XEA1 not supported. !!
NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes. NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes.
*******************************************************************************/ *******************************************************************************/
#ifndef XTENSA_CONTEXT_H #ifndef XTENSA_CONTEXT_H
#define XTENSA_CONTEXT_H #define XTENSA_CONTEXT_H
#ifdef __ASSEMBLER__ #ifdef __ASSEMBLER__
#include <xtensa/coreasm.h> #include <xtensa/coreasm.h>
#endif #endif
#include <xtensa/config/tie.h> #include <xtensa/config/tie.h>
#include <xtensa/corebits.h> #include <xtensa/corebits.h>
#include <xtensa/config/system.h> #include <xtensa/config/system.h>
#include <xtensa/xtruntime-frames.h> #include <xtensa/xtruntime-frames.h>
#include <esp_idf_version.h> #include <esp_idf_version.h>
/* Align a value up to nearest n-byte boundary, where n is a power of 2. */ /* Align a value up to nearest n-byte boundary, where n is a power of 2. */
#define ALIGNUP(n, val) (((val) + (n)-1) & -(n)) #define ALIGNUP(n, val) (((val) + (n)-1) & -(n))
/* /*
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Macros that help define structures for both C and assembler. Macros that help define structures for both C and assembler.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
*/ */
#ifdef STRUCT_BEGIN #ifdef STRUCT_BEGIN
#undef STRUCT_BEGIN #undef STRUCT_BEGIN
#undef STRUCT_FIELD #undef STRUCT_FIELD
#undef STRUCT_AFIELD #undef STRUCT_AFIELD
#undef STRUCT_END #undef STRUCT_END
#endif #endif
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) #if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
#define STRUCT_BEGIN .pushsection .text; .struct 0 #define STRUCT_BEGIN .pushsection .text; .struct 0
#define STRUCT_FIELD(ctype,size,asname,name) asname: .space size #define STRUCT_FIELD(ctype,size,asname,name) asname: .space size
#define STRUCT_AFIELD(ctype,size,asname,name,n) asname: .space (size)*(n) #define STRUCT_AFIELD(ctype,size,asname,name,n) asname: .space (size)*(n)
#define STRUCT_END(sname) sname##Size:; .popsection #define STRUCT_END(sname) sname##Size:; .popsection
#else #else
#define STRUCT_BEGIN typedef struct { #define STRUCT_BEGIN typedef struct {
#define STRUCT_FIELD(ctype,size,asname,name) ctype name; #define STRUCT_FIELD(ctype,size,asname,name) ctype name;
#define STRUCT_AFIELD(ctype,size,asname,name,n) ctype name[n]; #define STRUCT_AFIELD(ctype,size,asname,name,n) ctype name[n];
#define STRUCT_END(sname) } sname; #define STRUCT_END(sname) } sname;
#endif //_ASMLANGUAGE || __ASSEMBLER__ #endif //_ASMLANGUAGE || __ASSEMBLER__
/* /*
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
INTERRUPT/EXCEPTION STACK FRAME FOR A THREAD OR NESTED INTERRUPT INTERRUPT/EXCEPTION STACK FRAME FOR A THREAD OR NESTED INTERRUPT
A stack frame of this structure is allocated for any interrupt or exception. 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 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 interrupts, every thread stack must allow space for just one interrupt stack
frame, then nested interrupt stack frames go on the system stack. frame, then nested interrupt stack frames go on the system stack.
The frame includes basic registers (explicit) and "extra" registers introduced 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. 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. 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, 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 another base save area to manage gcc nested functions, and a little temporary
space to help manage the spilling of the register windows. space to help manage the spilling of the register windows.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
*/ */
STRUCT_BEGIN STRUCT_BEGIN
STRUCT_FIELD (long, 4, XT_STK_EXIT, exit) /* exit point for dispatch */ 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_PC, pc) /* return PC */
STRUCT_FIELD (long, 4, XT_STK_PS, ps) /* return PS */ STRUCT_FIELD (long, 4, XT_STK_PS, ps) /* return PS */
STRUCT_FIELD (long, 4, XT_STK_A0, a0) 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_A1, a1) /* stack pointer before interrupt */
STRUCT_FIELD (long, 4, XT_STK_A2, a2) STRUCT_FIELD (long, 4, XT_STK_A2, a2)
STRUCT_FIELD (long, 4, XT_STK_A3, a3) STRUCT_FIELD (long, 4, XT_STK_A3, a3)
STRUCT_FIELD (long, 4, XT_STK_A4, a4) STRUCT_FIELD (long, 4, XT_STK_A4, a4)
STRUCT_FIELD (long, 4, XT_STK_A5, a5) STRUCT_FIELD (long, 4, XT_STK_A5, a5)
STRUCT_FIELD (long, 4, XT_STK_A6, a6) STRUCT_FIELD (long, 4, XT_STK_A6, a6)
STRUCT_FIELD (long, 4, XT_STK_A7, a7) STRUCT_FIELD (long, 4, XT_STK_A7, a7)
STRUCT_FIELD (long, 4, XT_STK_A8, a8) STRUCT_FIELD (long, 4, XT_STK_A8, a8)
STRUCT_FIELD (long, 4, XT_STK_A9, a9) STRUCT_FIELD (long, 4, XT_STK_A9, a9)
STRUCT_FIELD (long, 4, XT_STK_A10, a10) STRUCT_FIELD (long, 4, XT_STK_A10, a10)
STRUCT_FIELD (long, 4, XT_STK_A11, a11) STRUCT_FIELD (long, 4, XT_STK_A11, a11)
STRUCT_FIELD (long, 4, XT_STK_A12, a12) STRUCT_FIELD (long, 4, XT_STK_A12, a12)
STRUCT_FIELD (long, 4, XT_STK_A13, a13) STRUCT_FIELD (long, 4, XT_STK_A13, a13)
STRUCT_FIELD (long, 4, XT_STK_A14, a14) STRUCT_FIELD (long, 4, XT_STK_A14, a14)
STRUCT_FIELD (long, 4, XT_STK_A15, a15) STRUCT_FIELD (long, 4, XT_STK_A15, a15)
STRUCT_FIELD (long, 4, XT_STK_SAR, sar) STRUCT_FIELD (long, 4, XT_STK_SAR, sar)
STRUCT_FIELD (long, 4, XT_STK_EXCCAUSE, exccause) STRUCT_FIELD (long, 4, XT_STK_EXCCAUSE, exccause)
STRUCT_FIELD (long, 4, XT_STK_EXCVADDR, excvaddr) STRUCT_FIELD (long, 4, XT_STK_EXCVADDR, excvaddr)
#if XCHAL_HAVE_LOOPS #if XCHAL_HAVE_LOOPS
STRUCT_FIELD (long, 4, XT_STK_LBEG, lbeg) STRUCT_FIELD (long, 4, XT_STK_LBEG, lbeg)
STRUCT_FIELD (long, 4, XT_STK_LEND, lend) STRUCT_FIELD (long, 4, XT_STK_LEND, lend)
STRUCT_FIELD (long, 4, XT_STK_LCOUNT, lcount) STRUCT_FIELD (long, 4, XT_STK_LCOUNT, lcount)
#endif #endif
#ifndef __XTENSA_CALL0_ABI__ #ifndef __XTENSA_CALL0_ABI__
/* Temporary space for saving stuff during window spill */ /* Temporary space for saving stuff during window spill */
STRUCT_FIELD (long, 4, XT_STK_TMP0, tmp0) STRUCT_FIELD (long, 4, XT_STK_TMP0, tmp0)
STRUCT_FIELD (long, 4, XT_STK_TMP1, tmp1) STRUCT_FIELD (long, 4, XT_STK_TMP1, tmp1)
STRUCT_FIELD (long, 4, XT_STK_TMP2, tmp2) STRUCT_FIELD (long, 4, XT_STK_TMP2, tmp2)
#endif #endif
#ifdef XT_USE_SWPRI #ifdef XT_USE_SWPRI
/* Storage for virtual priority mask */ /* Storage for virtual priority mask */
STRUCT_FIELD (long, 4, XT_STK_VPRI, vpri) STRUCT_FIELD (long, 4, XT_STK_VPRI, vpri)
#endif #endif
#ifdef XT_USE_OVLY #ifdef XT_USE_OVLY
/* Storage for overlay state */ /* Storage for overlay state */
STRUCT_FIELD (long, 4, XT_STK_OVLY, ovly) STRUCT_FIELD (long, 4, XT_STK_OVLY, ovly)
#endif #endif
STRUCT_END(XtExcFrame) STRUCT_END(XtExcFrame)
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) #if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
#define XT_STK_NEXT1 XtExcFrameSize #define XT_STK_NEXT1 XtExcFrameSize
#else #else
#define XT_STK_NEXT1 sizeof(XtExcFrame) #define XT_STK_NEXT1 sizeof(XtExcFrame)
#endif #endif
/* Allocate extra storage if needed */ /* Allocate extra storage if needed */
#if XCHAL_EXTRA_SA_SIZE != 0 #if XCHAL_EXTRA_SA_SIZE != 0
#if XCHAL_EXTRA_SA_ALIGN <= 16 #if XCHAL_EXTRA_SA_ALIGN <= 16
#define XT_STK_EXTRA ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1) #define XT_STK_EXTRA ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1)
#else #else
/* If need more alignment than stack, add space for dynamic alignment */ /* 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) #define XT_STK_EXTRA (ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1) + XCHAL_EXTRA_SA_ALIGN)
#endif #endif
#define XT_STK_NEXT2 (XT_STK_EXTRA + XCHAL_EXTRA_SA_SIZE) #define XT_STK_NEXT2 (XT_STK_EXTRA + XCHAL_EXTRA_SA_SIZE)
#else #else
#define XT_STK_NEXT2 XT_STK_NEXT1 #define XT_STK_NEXT2 XT_STK_NEXT1
#endif #endif
/* /*
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
This is the frame size. Add space for 4 registers (interruptee's base save This is the frame size. Add space for 4 registers (interruptee's base save
area) and some space for gcc nested functions if any. area) and some space for gcc nested functions if any.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
*/ */
#define XT_STK_FRMSZ (ALIGNUP(0x10, XT_STK_NEXT2) + 0x20) #define XT_STK_FRMSZ (ALIGNUP(0x10, XT_STK_NEXT2) + 0x20)
/* /*
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
SOLICITED STACK FRAME FOR A THREAD SOLICITED STACK FRAME FOR A THREAD
A stack frame of this structure is allocated whenever a thread enters the A stack frame of this structure is allocated whenever a thread enters the
RTOS kernel intentionally (and synchronously) to submit to thread scheduling. RTOS kernel intentionally (and synchronously) to submit to thread scheduling.
It goes on the current thread's stack. It goes on the current thread's stack.
The solicited frame only includes registers that are required to be preserved 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 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. 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. For Windowed ABI, this stack frame includes the caller's base save area.
Note on XT_SOL_EXIT field: Note on XT_SOL_EXIT field:
It is necessary to distinguish a solicited from an interrupt stack frame. 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 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) 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 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. opt to ignore this field if it has another way of distinguishing frames.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
*/ */
STRUCT_BEGIN STRUCT_BEGIN
#ifdef __XTENSA_CALL0_ABI__ #ifdef __XTENSA_CALL0_ABI__
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit) STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
STRUCT_FIELD (long, 4, XT_SOL_PC, pc) STRUCT_FIELD (long, 4, XT_SOL_PC, pc)
STRUCT_FIELD (long, 4, XT_SOL_PS, ps) STRUCT_FIELD (long, 4, XT_SOL_PS, ps)
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next) 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_A12, a12) /* should be on 16-byte alignment */
STRUCT_FIELD (long, 4, XT_SOL_A13, a13) STRUCT_FIELD (long, 4, XT_SOL_A13, a13)
STRUCT_FIELD (long, 4, XT_SOL_A14, a14) STRUCT_FIELD (long, 4, XT_SOL_A14, a14)
STRUCT_FIELD (long, 4, XT_SOL_A15, a15) STRUCT_FIELD (long, 4, XT_SOL_A15, a15)
#else #else
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit) STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
STRUCT_FIELD (long, 4, XT_SOL_PC, pc) STRUCT_FIELD (long, 4, XT_SOL_PC, pc)
STRUCT_FIELD (long, 4, XT_SOL_PS, ps) STRUCT_FIELD (long, 4, XT_SOL_PS, ps)
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next) 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_A0, a0) /* should be on 16-byte alignment */
STRUCT_FIELD (long, 4, XT_SOL_A1, a1) STRUCT_FIELD (long, 4, XT_SOL_A1, a1)
STRUCT_FIELD (long, 4, XT_SOL_A2, a2) STRUCT_FIELD (long, 4, XT_SOL_A2, a2)
STRUCT_FIELD (long, 4, XT_SOL_A3, a3) STRUCT_FIELD (long, 4, XT_SOL_A3, a3)
#endif #endif
STRUCT_END(XtSolFrame) STRUCT_END(XtSolFrame)
/* Size of solicited stack frame */ /* Size of solicited stack frame */
#define XT_SOL_FRMSZ ALIGNUP(0x10, XtSolFrameSize) #define XT_SOL_FRMSZ ALIGNUP(0x10, XtSolFrameSize)
/* /*
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
CO-PROCESSOR STATE SAVE AREA FOR A THREAD CO-PROCESSOR STATE SAVE AREA FOR A THREAD
The RTOS must provide an area per thread to save the state of co-processors 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 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, 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 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 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, 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. 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. 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-processors may not be used by interrupt or exception handlers. If an
co-processor instruction is executed by an interrupt or exception handler, co-processor instruction is executed by an interrupt or exception handler,
the co-processor exception handler will trigger a kernel panic and freeze. the co-processor exception handler will trigger a kernel panic and freeze.
This restriction is introduced to reduce the overhead of saving and restoring 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 co-processor state (which can be quite large) and in particular remove that
overhead from interrupt handlers. overhead from interrupt handlers.
The co-processor state save area may be in any convenient per-thread location 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 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. 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 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-processor (laid out as in the CPENABLE reg) help manage context-switching
co-processors as efficiently as possible: co-processors as efficiently as possible:
XT_CPENABLE XT_CPENABLE
The contents of a non-running thread's CPENABLE register. The contents of a non-running thread's CPENABLE register.
It represents the co-processors owned (and whose state is still needed) 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. 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 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. 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 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. 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. Avoids co-processor exceptions when no change of ownership is needed.
XT_CPSTORED XT_CPSTORED
A bitmask with the same layout as CPENABLE, a bit per co-processor. 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 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 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 still enabled in CPENABLE is saved. When the co-processor exception
handler assigns ownership of a co-processor to a thread, it restores 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. the saved state only if this bit is set, and clears this bit.
XT_CP_CS_ST XT_CP_CS_ST
A bitmask with the same layout as CPENABLE, a bit per co-processor. 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. Indicates whether callee-saved state is saved in the state save area.
Callee-saved state is saved by itself on a solicited context switch, Callee-saved state is saved by itself on a solicited context switch,
and restored when needed by the coprocessor exception handler. and restored when needed by the coprocessor exception handler.
Unsolicited switches will cause the entire coprocessor to be saved Unsolicited switches will cause the entire coprocessor to be saved
when necessary. when necessary.
XT_CP_ASA XT_CP_ASA
Pointer to the aligned save area. Allows it to be aligned more than 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). the overall save area (which might only be stack-aligned or TCB-aligned).
Especially relevant for Xtensa cores configured with a very large data Especially relevant for Xtensa cores configured with a very large data
path that requires alignment greater than 16 bytes (ABI stack alignment). path that requires alignment greater than 16 bytes (ABI stack alignment).
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
*/ */
#if XCHAL_CP_NUM > 0 #if XCHAL_CP_NUM > 0
/* Offsets of each coprocessor save area within the 'aligned save area': */ /* Offsets of each coprocessor save area within the 'aligned save area': */
#define XT_CP0_SA 0 #define XT_CP0_SA 0
#define XT_CP1_SA ALIGNUP(XCHAL_CP1_SA_ALIGN, XT_CP0_SA + XCHAL_CP0_SA_SIZE) #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_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_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_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_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_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_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) #define XT_CP_SA_SIZE ALIGNUP(16, XT_CP7_SA + XCHAL_CP7_SA_SIZE)
/* Offsets within the overall save area: */ /* Offsets within the overall save area: */
#define XT_CPENABLE 0 /* (2 bytes) coprocessors active for this thread */ #define XT_CPENABLE 0 /* (2 bytes) coprocessors active for this thread */
#define XT_CPSTORED 2 /* (2 bytes) coprocessors saved 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_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 */ #define XT_CP_ASA 8 /* (4 bytes) ptr to aligned save area */
/* Overall size allows for dynamic alignment: */ /* Overall size allows for dynamic alignment: */
#define XT_CP_SIZE (12 + XT_CP_SA_SIZE + XCHAL_TOTAL_SA_ALIGN) #define XT_CP_SIZE (12 + XT_CP_SA_SIZE + XCHAL_TOTAL_SA_ALIGN)
#else #else
#define XT_CP_SIZE 0 #define XT_CP_SIZE 0
#endif #endif
/* /*
Macro to get the current core ID. Only uses the reg given as an argument. Macro to get the current core ID. Only uses the reg given as an argument.
Reading PRID on the ESP32 gives us 0xCDCD on the PRO processor (0) Reading PRID on the ESP32 gives us 0xCDCD on the PRO processor (0)
and 0xABAB on the APP CPU (1). We can distinguish between the two by checking and 0xABAB on the APP CPU (1). We can distinguish between the two by checking
bit 13: it's 1 on the APP and 0 on the PRO processor. bit 13: it's 1 on the APP and 0 on the PRO processor.
*/ */
#ifdef __ASSEMBLER__ #ifdef __ASSEMBLER__
.macro getcoreid reg .macro getcoreid reg
rsr.prid \reg rsr.prid \reg
extui \reg,\reg,13,1 extui \reg,\reg,13,1
.endm .endm
#endif #endif
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0)) #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
#define CORE_ID_PRO 0xCDCD #define CORE_ID_PRO 0xCDCD
#define CORE_ID_APP 0xABAB #define CORE_ID_APP 0xABAB
#else #else
#define CORE_ID_REGVAL_PRO 0xCDCD #define CORE_ID_REGVAL_PRO 0xCDCD
#define CORE_ID_REGVAL_APP 0xABAB #define CORE_ID_REGVAL_APP 0xABAB
/* Included for compatibility, recommend using CORE_ID_REGVAL_PRO instead */ /* Included for compatibility, recommend using CORE_ID_REGVAL_PRO instead */
#define CORE_ID_PRO CORE_ID_REGVAL_PRO #define CORE_ID_PRO CORE_ID_REGVAL_PRO
/* Included for compatibility, recommend using CORE_ID_REGVAL_APP instead */ /* Included for compatibility, recommend using CORE_ID_REGVAL_APP instead */
#define CORE_ID_APP CORE_ID_REGVAL_APP #define CORE_ID_APP CORE_ID_REGVAL_APP
#endif #endif
/* /*
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN
Convenient where the frame size requirements are the same for both ABIs. 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). ENTRY(sz), RET(sz) are for framed functions (have locals or make calls).
ENTRY0, RET0 are for frameless functions (no locals, no 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). 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 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). 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. 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 Note: Because CPP macros expand to a single line, macros requiring multi-line
expansions are implemented as assembler macros. expansions are implemented as assembler macros.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
*/ */
#ifdef __ASSEMBLER__ #ifdef __ASSEMBLER__
#ifdef __XTENSA_CALL0_ABI__ #ifdef __XTENSA_CALL0_ABI__
/* Call0 */ /* Call0 */
#define ENTRY(sz) entry1 sz #define ENTRY(sz) entry1 sz
.macro entry1 size=0x10 .macro entry1 size=0x10
addi sp, sp, -\size addi sp, sp, -\size
s32i a0, sp, 0 s32i a0, sp, 0
.endm .endm
#define ENTRY0 #define ENTRY0
#define RET(sz) ret1 sz #define RET(sz) ret1 sz
.macro ret1 size=0x10 .macro ret1 size=0x10
l32i a0, sp, 0 l32i a0, sp, 0
addi sp, sp, \size addi sp, sp, \size
ret ret
.endm .endm
#define RET0 ret #define RET0 ret
#else #else
/* Windowed */ /* Windowed */
#define ENTRY(sz) entry sp, sz #define ENTRY(sz) entry sp, sz
#define ENTRY0 entry sp, 0x10 #define ENTRY0 entry sp, 0x10
#define RET(sz) retw #define RET(sz) retw
#define RET0 retw #define RET0 retw
#endif #endif
#endif #endif
#endif /* XTENSA_CONTEXT_H */ #endif /* XTENSA_CONTEXT_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,117 +1,117 @@
/* /*
* Copyright (C) 2016-2017 Espressif Shanghai PTE LTD * Copyright (C) 2016-2017 Espressif Shanghai PTE LTD
* Copyright (C) 2015 Real Time Engineers Ltd. * Copyright (C) 2015 Real Time Engineers Ltd.
* *
* All rights reserved * All rights reserved
* *
* FreeRTOS is free software; you can redistribute it and/or modify it under * FreeRTOS is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License (version 2) as published by the * the terms of the GNU General Public License (version 2) as published by the
* Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. * Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
* *
*************************************************************************** ***************************************************************************
* >>! NOTE: The modification to the GPL is included to allow you to !<< * >>! NOTE: The modification to the GPL is included to allow you to !<<
* >>! distribute a combined work that includes FreeRTOS without being !<< * >>! distribute a combined work that includes FreeRTOS without being !<<
* >>! obliged to provide the source code for proprietary components !<< * >>! obliged to provide the source code for proprietary components !<<
* >>! outside of the FreeRTOS kernel. !<< * >>! outside of the FreeRTOS kernel. !<<
*************************************************************************** ***************************************************************************
* *
* FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. Full license text is available on the following * FOR A PARTICULAR PURPOSE. Full license text is available on the following
* link: https://www.FreeRTOS.org/a00114.html * link: https://www.FreeRTOS.org/a00114.html
*/ */
/* This header exists for performance reasons, in order to inline the /* This header exists for performance reasons, in order to inline the
* implementation of vPortCPUAcquireMutexIntsDisabled and * implementation of vPortCPUAcquireMutexIntsDisabled and
* vPortCPUReleaseMutexIntsDisabled into the * vPortCPUReleaseMutexIntsDisabled into the
* vTaskEnterCritical/vTaskExitCritical functions in task.c as well as the * vTaskEnterCritical/vTaskExitCritical functions in task.c as well as the
* vPortCPUAcquireMutex/vPortCPUReleaseMutex implementations. * vPortCPUAcquireMutex/vPortCPUReleaseMutex implementations.
* *
* Normally this kind of performance hack is over the top, but * Normally this kind of performance hack is over the top, but
* vTaskEnterCritical/vTaskExitCritical is called a great * vTaskEnterCritical/vTaskExitCritical is called a great
* deal by FreeRTOS internals. * deal by FreeRTOS internals.
* *
* It should be #included by freertos port.c or tasks.c, in esp-idf. * It should be #included by freertos port.c or tasks.c, in esp-idf.
* *
* The way it works is that it essentially uses portmux_impl.inc.h as a * The way it works is that it essentially uses portmux_impl.inc.h as a
* generator template of sorts. When no external memory is used, this * generator template of sorts. When no external memory is used, this
* template is only used to generate the vPortCPUAcquireMutexIntsDisabledInternal * template is only used to generate the vPortCPUAcquireMutexIntsDisabledInternal
* and vPortCPUReleaseMutexIntsDisabledInternal functions, which use S32C1 to * and vPortCPUReleaseMutexIntsDisabledInternal functions, which use S32C1 to
* do an atomic compare & swap. When external memory is used the functions * do an atomic compare & swap. When external memory is used the functions
* vPortCPUAcquireMutexIntsDisabledExtram and vPortCPUReleaseMutexIntsDisabledExtram * vPortCPUAcquireMutexIntsDisabledExtram and vPortCPUReleaseMutexIntsDisabledExtram
* are also generated, which use uxPortCompareSetExtram to fake the S32C1 instruction. * are also generated, which use uxPortCompareSetExtram to fake the S32C1 instruction.
* The wrapper functions vPortCPUAcquireMutexIntsDisabled and * The wrapper functions vPortCPUAcquireMutexIntsDisabled and
* vPortCPUReleaseMutexIntsDisabled will then use the appropriate function to do the * vPortCPUReleaseMutexIntsDisabled will then use the appropriate function to do the
* actual lock/unlock. * actual lock/unlock.
*/ */
#include "soc/cpu.h" #include "soc/cpu.h"
#include "portable.h" #include "portable.h"
/* XOR one core ID with this value to get the other core ID */ /* XOR one core ID with this value to get the other core ID */
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0)) #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
#define CORE_ID_XOR_SWAP ( CORE_ID_PRO ^ CORE_ID_APP ) #define CORE_ID_XOR_SWAP ( CORE_ID_PRO ^ CORE_ID_APP )
#else #else
#define CORE_ID_REGVAL_XOR_SWAP (CORE_ID_REGVAL_PRO ^ CORE_ID_REGVAL_APP) #define CORE_ID_REGVAL_XOR_SWAP (CORE_ID_REGVAL_PRO ^ CORE_ID_REGVAL_APP)
#endif #endif
/*Define the mux routines for use with muxes in internal RAM */ /*Define the mux routines for use with muxes in internal RAM */
#define PORTMUX_AQUIRE_MUX_FN_NAME vPortCPUAcquireMutexIntsDisabledInternal #define PORTMUX_AQUIRE_MUX_FN_NAME vPortCPUAcquireMutexIntsDisabledInternal
#define PORTMUX_RELEASE_MUX_FN_NAME vPortCPUReleaseMutexIntsDisabledInternal #define PORTMUX_RELEASE_MUX_FN_NAME vPortCPUReleaseMutexIntsDisabledInternal
#define PORTMUX_COMPARE_SET_FN_NAME uxPortCompareSet #define PORTMUX_COMPARE_SET_FN_NAME uxPortCompareSet
#include "portmux_impl.inc.h" #include "portmux_impl.inc.h"
#undef PORTMUX_AQUIRE_MUX_FN_NAME #undef PORTMUX_AQUIRE_MUX_FN_NAME
#undef PORTMUX_RELEASE_MUX_FN_NAME #undef PORTMUX_RELEASE_MUX_FN_NAME
#undef PORTMUX_COMPARE_SET_FN_NAME #undef PORTMUX_COMPARE_SET_FN_NAME
#if defined( CONFIG_SPIRAM_SUPPORT ) #if defined( CONFIG_SPIRAM_SUPPORT )
#define PORTMUX_AQUIRE_MUX_FN_NAME vPortCPUAcquireMutexIntsDisabledExtram #define PORTMUX_AQUIRE_MUX_FN_NAME vPortCPUAcquireMutexIntsDisabledExtram
#define PORTMUX_RELEASE_MUX_FN_NAME vPortCPUReleaseMutexIntsDisabledExtram #define PORTMUX_RELEASE_MUX_FN_NAME vPortCPUReleaseMutexIntsDisabledExtram
#define PORTMUX_COMPARE_SET_FN_NAME uxPortCompareSetExtram #define PORTMUX_COMPARE_SET_FN_NAME uxPortCompareSetExtram
#include "portmux_impl.inc.h" #include "portmux_impl.inc.h"
#undef PORTMUX_AQUIRE_MUX_FN_NAME #undef PORTMUX_AQUIRE_MUX_FN_NAME
#undef PORTMUX_RELEASE_MUX_FN_NAME #undef PORTMUX_RELEASE_MUX_FN_NAME
#undef PORTMUX_COMPARE_SET_FN_NAME #undef PORTMUX_COMPARE_SET_FN_NAME
#endif #endif
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
#define PORTMUX_AQUIRE_MUX_FN_ARGS portMUX_TYPE * mux, int timeout_cycles, const char * fnName, int line #define PORTMUX_AQUIRE_MUX_FN_ARGS portMUX_TYPE * mux, int timeout_cycles, const char * fnName, int line
#define PORTMUX_RELEASE_MUX_FN_ARGS portMUX_TYPE * mux, const char * fnName, int line #define PORTMUX_RELEASE_MUX_FN_ARGS portMUX_TYPE * mux, const char * fnName, int line
#define PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( x ) x, timeout_cycles, fnName, line #define PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( x ) x, timeout_cycles, fnName, line
#define PORTMUX_RELEASE_MUX_FN_CALL_ARGS( x ) x, fnName, line #define PORTMUX_RELEASE_MUX_FN_CALL_ARGS( x ) x, fnName, line
#else #else
#define PORTMUX_AQUIRE_MUX_FN_ARGS portMUX_TYPE * mux, int timeout_cycles #define PORTMUX_AQUIRE_MUX_FN_ARGS portMUX_TYPE * mux, int timeout_cycles
#define PORTMUX_RELEASE_MUX_FN_ARGS portMUX_TYPE * mux #define PORTMUX_RELEASE_MUX_FN_ARGS portMUX_TYPE * mux
#define PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( x ) x, timeout_cycles #define PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( x ) x, timeout_cycles
#define PORTMUX_RELEASE_MUX_FN_CALL_ARGS( x ) x #define PORTMUX_RELEASE_MUX_FN_CALL_ARGS( x ) x
#endif #endif
static inline bool __attribute__( ( always_inline ) ) vPortCPUAcquireMutexIntsDisabled( PORTMUX_AQUIRE_MUX_FN_ARGS ) static inline bool __attribute__( ( always_inline ) ) vPortCPUAcquireMutexIntsDisabled( PORTMUX_AQUIRE_MUX_FN_ARGS )
{ {
#if defined( CONFIG_SPIRAM_SUPPORT ) #if defined( CONFIG_SPIRAM_SUPPORT )
if( esp_ptr_external_ram( mux ) ) if( esp_ptr_external_ram( mux ) )
{ {
return vPortCPUAcquireMutexIntsDisabledExtram( PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( mux ) ); return vPortCPUAcquireMutexIntsDisabledExtram( PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( mux ) );
} }
#endif #endif
return vPortCPUAcquireMutexIntsDisabledInternal( PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( mux ) ); return vPortCPUAcquireMutexIntsDisabledInternal( PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( mux ) );
} }
static inline void vPortCPUReleaseMutexIntsDisabled( PORTMUX_RELEASE_MUX_FN_ARGS ) static inline void vPortCPUReleaseMutexIntsDisabled( PORTMUX_RELEASE_MUX_FN_ARGS )
{ {
#if defined( CONFIG_SPIRAM_SUPPORT ) #if defined( CONFIG_SPIRAM_SUPPORT )
if( esp_ptr_external_ram( mux ) ) if( esp_ptr_external_ram( mux ) )
{ {
vPortCPUReleaseMutexIntsDisabledExtram( PORTMUX_RELEASE_MUX_FN_CALL_ARGS( mux ) ); vPortCPUReleaseMutexIntsDisabledExtram( PORTMUX_RELEASE_MUX_FN_CALL_ARGS( mux ) );
return; return;
} }
#endif #endif
vPortCPUReleaseMutexIntsDisabledInternal( PORTMUX_RELEASE_MUX_FN_CALL_ARGS( mux ) ); vPortCPUReleaseMutexIntsDisabledInternal( PORTMUX_RELEASE_MUX_FN_CALL_ARGS( mux ) );
} }

View file

@ -1,212 +1,212 @@
/* /*
* Copyright (C) 2016-2017 Espressif Shanghai PTE LTD * Copyright (C) 2016-2017 Espressif Shanghai PTE LTD
* Copyright (C) 2015 Real Time Engineers Ltd. * Copyright (C) 2015 Real Time Engineers Ltd.
* *
* All rights reserved * All rights reserved
* *
* FreeRTOS is free software; you can redistribute it and/or modify it under * FreeRTOS is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License (version 2) as published by the * the terms of the GNU General Public License (version 2) as published by the
* Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. * Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
* *
*************************************************************************** ***************************************************************************
* >>! NOTE: The modification to the GPL is included to allow you to !<< * >>! NOTE: The modification to the GPL is included to allow you to !<<
* >>! distribute a combined work that includes FreeRTOS without being !<< * >>! distribute a combined work that includes FreeRTOS without being !<<
* >>! obliged to provide the source code for proprietary components !<< * >>! obliged to provide the source code for proprietary components !<<
* >>! outside of the FreeRTOS kernel. !<< * >>! outside of the FreeRTOS kernel. !<<
*************************************************************************** ***************************************************************************
* *
* FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. Full license text is available on the following * FOR A PARTICULAR PURPOSE. Full license text is available on the following
* link: https://www.FreeRTOS.org/a00114.html * link: https://www.FreeRTOS.org/a00114.html
*/ */
/* /*
* Warning: funky preprocessor hackery ahead. Including these headers will generate two * Warning: funky preprocessor hackery ahead. Including these headers will generate two
* functions, which names are defined by the preprocessor macros * functions, which names are defined by the preprocessor macros
* PORTMUX_AQUIRE_MUX_FN_NAME and PORTMUX_RELEASE_MUX_FN_NAME. In order to do the compare * PORTMUX_AQUIRE_MUX_FN_NAME and PORTMUX_RELEASE_MUX_FN_NAME. In order to do the compare
* and exchange function, they will use whatever PORTMUX_COMPARE_SET_FN_NAME resolves to. * and exchange function, they will use whatever PORTMUX_COMPARE_SET_FN_NAME resolves to.
* *
* In some scenarios, this header is included *twice* in portmux_impl.h: one time * In some scenarios, this header is included *twice* in portmux_impl.h: one time
* for the 'normal' mux code which uses a compare&exchange routine, another time * for the 'normal' mux code which uses a compare&exchange routine, another time
* to generate code for a second set of these routines that use a second mux * to generate code for a second set of these routines that use a second mux
* (in internal ram) to fake a compare&exchange on a variable in external memory. * (in internal ram) to fake a compare&exchange on a variable in external memory.
*/ */
static inline bool __attribute__( ( always_inline ) ) static inline bool __attribute__( ( always_inline ) )
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
PORTMUX_AQUIRE_MUX_FN_NAME( portMUX_TYPE * mux, PORTMUX_AQUIRE_MUX_FN_NAME( portMUX_TYPE * mux,
int timeout_cycles, int timeout_cycles,
const char * fnName, const char * fnName,
int line ) int line )
{ {
#else #else
PORTMUX_AQUIRE_MUX_FN_NAME( portMUX_TYPE * mux, int timeout_cycles ) PORTMUX_AQUIRE_MUX_FN_NAME( portMUX_TYPE * mux, int timeout_cycles )
{ {
#endif #endif
#if !CONFIG_FREERTOS_UNICORE #if !CONFIG_FREERTOS_UNICORE
uint32_t res; uint32_t res;
portBASE_TYPE coreID, otherCoreID; portBASE_TYPE coreID, otherCoreID;
uint32_t ccount_start; uint32_t ccount_start;
bool set_timeout = timeout_cycles > portMUX_NO_TIMEOUT; bool set_timeout = timeout_cycles > portMUX_NO_TIMEOUT;
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
if( !set_timeout ) if( !set_timeout )
{ {
timeout_cycles = 10000; /* Always set a timeout in debug mode */ timeout_cycles = 10000; /* Always set a timeout in debug mode */
set_timeout = true; set_timeout = true;
} }
#endif #endif
if( set_timeout ) /* Timeout */ if( set_timeout ) /* Timeout */
{ {
RSR( CCOUNT, ccount_start ); RSR( CCOUNT, ccount_start );
} }
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
uint32_t owner = mux->owner; uint32_t owner = mux->owner;
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0)) #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
if( ( owner != portMUX_FREE_VAL ) && ( owner != CORE_ID_PRO ) && ( owner != CORE_ID_APP ) ) if( ( owner != portMUX_FREE_VAL ) && ( owner != CORE_ID_PRO ) && ( owner != CORE_ID_APP ) )
#else #else
if (owner != portMUX_FREE_VAL && owner != CORE_ID_REGVAL_PRO && owner != CORE_ID_REGVAL_APP) if (owner != portMUX_FREE_VAL && owner != CORE_ID_REGVAL_PRO && owner != CORE_ID_REGVAL_APP)
#endif #endif
{ {
ets_printf( "ERROR: vPortCPUAcquireMutex: mux %p is uninitialized (0x%X)! Called from %s line %d.\n", mux, owner, fnName, line ); ets_printf( "ERROR: vPortCPUAcquireMutex: mux %p is uninitialized (0x%X)! Called from %s line %d.\n", mux, owner, fnName, line );
mux->owner = portMUX_FREE_VAL; mux->owner = portMUX_FREE_VAL;
} }
#endif #endif
/* Spin until we own the core */ /* Spin until we own the core */
RSR( PRID, coreID ); RSR( PRID, coreID );
/* Note: coreID is the full 32 bit core ID (CORE_ID_PRO/CORE_ID_APP), /* Note: coreID is the full 32 bit core ID (CORE_ID_PRO/CORE_ID_APP),
* not the 0/1 value returned by xPortGetCoreID() * not the 0/1 value returned by xPortGetCoreID()
*/ */
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0)) #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
otherCoreID = CORE_ID_XOR_SWAP ^ coreID; otherCoreID = CORE_ID_XOR_SWAP ^ coreID;
#else #else
otherCoreID = CORE_ID_REGVAL_XOR_SWAP ^ coreID; otherCoreID = CORE_ID_REGVAL_XOR_SWAP ^ coreID;
#endif #endif
do do
{ {
/* mux->owner should be one of portMUX_FREE_VAL, CORE_ID_PRO, /* mux->owner should be one of portMUX_FREE_VAL, CORE_ID_PRO,
* CORE_ID_APP: * CORE_ID_APP:
* *
* - If portMUX_FREE_VAL, we want to atomically set to 'coreID'. * - If portMUX_FREE_VAL, we want to atomically set to 'coreID'.
* - If "our" coreID, we can drop through immediately. * - If "our" coreID, we can drop through immediately.
* - If "otherCoreID", we spin here. * - If "otherCoreID", we spin here.
*/ */
res = coreID; res = coreID;
PORTMUX_COMPARE_SET_FN_NAME( &mux->owner, portMUX_FREE_VAL, &res ); PORTMUX_COMPARE_SET_FN_NAME( &mux->owner, portMUX_FREE_VAL, &res );
if( res != otherCoreID ) if( res != otherCoreID )
{ {
break; /* mux->owner is "our" coreID */ break; /* mux->owner is "our" coreID */
} }
if( set_timeout ) if( set_timeout )
{ {
uint32_t ccount_now; uint32_t ccount_now;
RSR( CCOUNT, ccount_now ); RSR( CCOUNT, ccount_now );
if( ccount_now - ccount_start > ( unsigned ) timeout_cycles ) if( ccount_now - ccount_start > ( unsigned ) timeout_cycles )
{ {
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
ets_printf( "Timeout on mux! last non-recursive lock %s line %d, curr %s line %d\n", mux->lastLockedFn, mux->lastLockedLine, fnName, line ); ets_printf( "Timeout on mux! last non-recursive lock %s line %d, curr %s line %d\n", mux->lastLockedFn, mux->lastLockedLine, fnName, line );
ets_printf( "Owner 0x%x count %d\n", mux->owner, mux->count ); ets_printf( "Owner 0x%x count %d\n", mux->owner, mux->count );
#endif #endif
return false; return false;
} }
} }
} while( 1 ); } while( 1 );
assert( res == coreID || res == portMUX_FREE_VAL ); /* any other value implies memory corruption or uninitialized mux */ assert( res == coreID || res == portMUX_FREE_VAL ); /* any other value implies memory corruption or uninitialized mux */
assert( ( res == portMUX_FREE_VAL ) == ( mux->count == 0 ) ); /* we're first to lock iff count is zero */ assert( ( res == portMUX_FREE_VAL ) == ( mux->count == 0 ) ); /* we're first to lock iff count is zero */
assert( mux->count < 0xFF ); /* Bad count value implies memory corruption */ assert( mux->count < 0xFF ); /* Bad count value implies memory corruption */
/* now we own it, we can increment the refcount */ /* now we own it, we can increment the refcount */
mux->count++; mux->count++;
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
if( res == portMUX_FREE_VAL ) /*initial lock */ if( res == portMUX_FREE_VAL ) /*initial lock */
{ {
mux->lastLockedFn = fnName; mux->lastLockedFn = fnName;
mux->lastLockedLine = line; mux->lastLockedLine = line;
} }
else else
{ {
ets_printf( "Recursive lock: count=%d last non-recursive lock %s line %d, curr %s line %d\n", mux->count - 1, ets_printf( "Recursive lock: count=%d last non-recursive lock %s line %d, curr %s line %d\n", mux->count - 1,
mux->lastLockedFn, mux->lastLockedLine, fnName, line ); mux->lastLockedFn, mux->lastLockedLine, fnName, line );
} }
#endif /* CONFIG_FREERTOS_PORTMUX_DEBUG */ #endif /* CONFIG_FREERTOS_PORTMUX_DEBUG */
#endif /* CONFIG_FREERTOS_UNICORE */ #endif /* CONFIG_FREERTOS_UNICORE */
return true; return true;
} }
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
static inline void PORTMUX_RELEASE_MUX_FN_NAME( portMUX_TYPE * mux, static inline void PORTMUX_RELEASE_MUX_FN_NAME( portMUX_TYPE * mux,
const char * fnName, const char * fnName,
int line ) int line )
{ {
#else #else
static inline void PORTMUX_RELEASE_MUX_FN_NAME( portMUX_TYPE * mux ) static inline void PORTMUX_RELEASE_MUX_FN_NAME( portMUX_TYPE * mux )
{ {
#endif #endif
#if !CONFIG_FREERTOS_UNICORE #if !CONFIG_FREERTOS_UNICORE
portBASE_TYPE coreID; portBASE_TYPE coreID;
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
const char * lastLockedFn = mux->lastLockedFn; const char * lastLockedFn = mux->lastLockedFn;
int lastLockedLine = mux->lastLockedLine; int lastLockedLine = mux->lastLockedLine;
mux->lastLockedFn = fnName; mux->lastLockedFn = fnName;
mux->lastLockedLine = line; mux->lastLockedLine = line;
uint32_t owner = mux->owner; uint32_t owner = mux->owner;
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0)) #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
if( ( owner != portMUX_FREE_VAL ) && ( owner != CORE_ID_PRO ) && ( owner != CORE_ID_APP ) ) if( ( owner != portMUX_FREE_VAL ) && ( owner != CORE_ID_PRO ) && ( owner != CORE_ID_APP ) )
#else #else
if (owner != portMUX_FREE_VAL && owner != CORE_ID_REGVAL_PRO && owner != CORE_ID_REGVAL_APP) if (owner != portMUX_FREE_VAL && owner != CORE_ID_REGVAL_PRO && owner != CORE_ID_REGVAL_APP)
#endif #endif
{ {
ets_printf( "ERROR: vPortCPUReleaseMutex: mux %p is invalid (0x%x)!\n", mux, mux->owner ); ets_printf( "ERROR: vPortCPUReleaseMutex: mux %p is invalid (0x%x)!\n", mux, mux->owner );
} }
#endif /* ifdef CONFIG_FREERTOS_PORTMUX_DEBUG */ #endif /* ifdef CONFIG_FREERTOS_PORTMUX_DEBUG */
#if CONFIG_FREERTOS_PORTMUX_DEBUG || !defined( NDEBUG ) #if CONFIG_FREERTOS_PORTMUX_DEBUG || !defined( NDEBUG )
RSR( PRID, coreID ); RSR( PRID, coreID );
#endif #endif
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
if( coreID != mux->owner ) if( coreID != mux->owner )
{ {
ets_printf( "ERROR: vPortCPUReleaseMutex: mux %p was already unlocked!\n", mux ); ets_printf( "ERROR: vPortCPUReleaseMutex: mux %p was already unlocked!\n", mux );
ets_printf( "Last non-recursive unlock %s line %d, curr unlock %s line %d\n", lastLockedFn, lastLockedLine, fnName, line ); ets_printf( "Last non-recursive unlock %s line %d, curr unlock %s line %d\n", lastLockedFn, lastLockedLine, fnName, line );
} }
#endif #endif
assert( coreID == mux->owner ); /* This is a mutex we didn't lock, or it's corrupt */ assert( coreID == mux->owner ); /* This is a mutex we didn't lock, or it's corrupt */
mux->count--; mux->count--;
if( mux->count == 0 ) if( mux->count == 0 )
{ {
mux->owner = portMUX_FREE_VAL; mux->owner = portMUX_FREE_VAL;
} }
else else
{ {
assert( mux->count < 0x100 ); /* Indicates memory corruption */ assert( mux->count < 0x100 ); /* Indicates memory corruption */
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG_RECURSIVE #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG_RECURSIVE
ets_printf( "Recursive unlock: count=%d last locked %s line %d, curr %s line %d\n", mux->count, lastLockedFn, lastLockedLine, fnName, line ); ets_printf( "Recursive unlock: count=%d last locked %s line %d, curr %s line %d\n", mux->count, lastLockedFn, lastLockedLine, fnName, line );
#endif #endif
} }
#endif //!CONFIG_FREERTOS_UNICORE #endif //!CONFIG_FREERTOS_UNICORE
} }

File diff suppressed because it is too large Load diff

View file

@ -1,63 +1,63 @@
/******************************************************************************* /*******************************************************************************
* // Copyright (c) 2003-2015 Cadence Design Systems, Inc. * // Copyright (c) 2003-2015 Cadence Design Systems, Inc.
* // * //
* // Permission is hereby granted, free of charge, to any person obtaining * // Permission is hereby granted, free of charge, to any person obtaining
* // a copy of this software and associated documentation files (the * // a copy of this software and associated documentation files (the
* // "Software"), to deal in the Software without restriction, including * // "Software"), to deal in the Software without restriction, including
* // without limitation the rights to use, copy, modify, merge, publish, * // without limitation the rights to use, copy, modify, merge, publish,
* // distribute, sublicense, and/or sell copies of the Software, and to * // distribute, sublicense, and/or sell copies of the Software, and to
* // permit persons to whom the Software is furnished to do so, subject to * // permit persons to whom the Software is furnished to do so, subject to
* // the following conditions: * // the following conditions:
* // * //
* // The above copyright notice and this permission notice shall be included * // The above copyright notice and this permission notice shall be included
* // in all copies or substantial portions of the Software. * // in all copies or substantial portions of the Software.
* // * //
* // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* -------------------------------------------------------------------------------- * --------------------------------------------------------------------------------
* *
* XTENSA INITIALIZATION ROUTINES CODED IN C * XTENSA INITIALIZATION ROUTINES CODED IN C
* *
* This file contains miscellaneous Xtensa RTOS-generic initialization functions * This file contains miscellaneous Xtensa RTOS-generic initialization functions
* that are implemented in C. * that are implemented in C.
* *
*******************************************************************************/ *******************************************************************************/
#ifdef XT_BOARD #ifdef XT_BOARD
#include <xtensa/xtbsp.h> #include <xtensa/xtbsp.h>
#endif #endif
#include "xtensa_rtos.h" #include "xtensa_rtos.h"
#include "esp_idf_version.h" #include "esp_idf_version.h"
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0)) #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
#include "esp_clk.h" #include "esp_clk.h"
#else #else
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/clk.h" #include "esp32s2/clk.h"
#elif CONFIG_IDF_TARGET_ESP32 #elif CONFIG_IDF_TARGET_ESP32
#include "esp32/clk.h" #include "esp32/clk.h"
#endif #endif
#endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0) */ #endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0) */
#ifdef XT_RTOS_TIMER_INT #ifdef XT_RTOS_TIMER_INT
unsigned _xt_tick_divisor = 0; /* cached number of cycles per tick */ unsigned _xt_tick_divisor = 0; /* cached number of cycles per tick */
void _xt_tick_divisor_init( void ) void _xt_tick_divisor_init( void )
{ {
_xt_tick_divisor = esp_clk_cpu_freq() / XT_TICK_PER_SEC; _xt_tick_divisor = esp_clk_cpu_freq() / XT_TICK_PER_SEC;
} }
/* Deprecated, to be removed */ /* Deprecated, to be removed */
int xt_clock_freq( void ) int xt_clock_freq( void )
{ {
return esp_clk_cpu_freq(); return esp_clk_cpu_freq();
} }
#endif /* XT_RTOS_TIMER_INT */ #endif /* XT_RTOS_TIMER_INT */

View file

@ -1,183 +1,183 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2006-2015 Cadence Design Systems Inc. * Copyright (c) 2006-2015 Cadence Design Systems Inc.
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/ ******************************************************************************/
/****************************************************************************** /******************************************************************************
* Xtensa-specific interrupt and exception functions for RTOS ports. * Xtensa-specific interrupt and exception functions for RTOS ports.
* Also see xtensa_intr_asm.S. * Also see xtensa_intr_asm.S.
******************************************************************************/ ******************************************************************************/
#include <stdlib.h> #include <stdlib.h>
#include <xtensa/config/core.h> #include <xtensa/config/core.h>
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/xtensa_api.h" #include "freertos/xtensa_api.h"
#include "freertos/portable.h" #include "freertos/portable.h"
#include "esp_idf_version.h" #include "esp_idf_version.h"
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0)) #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
#include "rom/ets_sys.h" #include "rom/ets_sys.h"
#else #else
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/ets_sys.h" #include "esp32s2/rom/ets_sys.h"
#elif CONFIG_IDF_TARGET_ESP32 #elif CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/ets_sys.h" #include "esp32/rom/ets_sys.h"
#endif #endif
#endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0) */ #endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0) */
#if XCHAL_HAVE_EXCEPTIONS #if XCHAL_HAVE_EXCEPTIONS
/* Handler table is in xtensa_intr_asm.S */ /* Handler table is in xtensa_intr_asm.S */
extern xt_exc_handler _xt_exception_table[ XCHAL_EXCCAUSE_NUM * portNUM_PROCESSORS ]; extern xt_exc_handler _xt_exception_table[ XCHAL_EXCCAUSE_NUM * portNUM_PROCESSORS ];
/* /*
* Default handler for unhandled exceptions. * Default handler for unhandled exceptions.
* CHANGED: We do this in panic.c now * CHANGED: We do this in panic.c now
*/ */
/*void xt_unhandled_exception(XtExcFrame *frame) */ /*void xt_unhandled_exception(XtExcFrame *frame) */
/*{ */ /*{ */
/*exit(-1); */ /*exit(-1); */
/*} */ /*} */
extern void xt_unhandled_exception( XtExcFrame * frame ); extern void xt_unhandled_exception( XtExcFrame * frame );
/* /*
* This function registers a handler for the specified exception. * This function registers a handler for the specified exception.
* The function returns the address of the previous handler. * The function returns the address of the previous handler.
* On error, it returns 0. * On error, it returns 0.
*/ */
xt_exc_handler xt_set_exception_handler( int n, xt_exc_handler xt_set_exception_handler( int n,
xt_exc_handler f ) xt_exc_handler f )
{ {
xt_exc_handler old; xt_exc_handler old;
if( ( n < 0 ) || ( n >= XCHAL_EXCCAUSE_NUM ) ) if( ( n < 0 ) || ( n >= XCHAL_EXCCAUSE_NUM ) )
{ {
return 0; /* invalid exception number */ return 0; /* invalid exception number */
} }
/* Convert exception number to _xt_exception_table name */ /* Convert exception number to _xt_exception_table name */
n = n * portNUM_PROCESSORS + xPortGetCoreID(); n = n * portNUM_PROCESSORS + xPortGetCoreID();
old = _xt_exception_table[ n ]; old = _xt_exception_table[ n ];
if( f ) if( f )
{ {
_xt_exception_table[ n ] = f; _xt_exception_table[ n ] = f;
} }
else else
{ {
_xt_exception_table[ n ] = &xt_unhandled_exception; _xt_exception_table[ n ] = &xt_unhandled_exception;
} }
return( ( old == &xt_unhandled_exception ) ? 0 : old ); return( ( old == &xt_unhandled_exception ) ? 0 : old );
} }
#endif /* if XCHAL_HAVE_EXCEPTIONS */ #endif /* if XCHAL_HAVE_EXCEPTIONS */
#if XCHAL_HAVE_INTERRUPTS #if XCHAL_HAVE_INTERRUPTS
/* Handler table is in xtensa_intr_asm.S */ /* Handler table is in xtensa_intr_asm.S */
typedef struct xt_handler_table_entry typedef struct xt_handler_table_entry
{ {
void * handler; void * handler;
void * arg; void * arg;
} xt_handler_table_entry; } xt_handler_table_entry;
extern xt_handler_table_entry _xt_interrupt_table[ XCHAL_NUM_INTERRUPTS * portNUM_PROCESSORS ]; extern xt_handler_table_entry _xt_interrupt_table[ XCHAL_NUM_INTERRUPTS * portNUM_PROCESSORS ];
/* /*
* Default handler for unhandled interrupts. * Default handler for unhandled interrupts.
*/ */
void xt_unhandled_interrupt( void * arg ) void xt_unhandled_interrupt( void * arg )
{ {
ets_printf( "Unhandled interrupt %d on cpu %d!\n", ( int ) arg, xPortGetCoreID() ); ets_printf( "Unhandled interrupt %d on cpu %d!\n", ( int ) arg, xPortGetCoreID() );
} }
/* /*
* This function registers a handler for the specified interrupt. The "arg" * This function registers a handler for the specified interrupt. The "arg"
* parameter specifies the argument to be passed to the handler when it is * parameter specifies the argument to be passed to the handler when it is
* invoked. The function returns the address of the previous handler. * invoked. The function returns the address of the previous handler.
* On error, it returns 0. * On error, it returns 0.
*/ */
xt_handler xt_set_interrupt_handler( int n, xt_handler xt_set_interrupt_handler( int n,
xt_handler f, xt_handler f,
void * arg ) void * arg )
{ {
xt_handler_table_entry * entry; xt_handler_table_entry * entry;
xt_handler old; xt_handler old;
if( ( n < 0 ) || ( n >= XCHAL_NUM_INTERRUPTS ) ) if( ( n < 0 ) || ( n >= XCHAL_NUM_INTERRUPTS ) )
{ {
return 0; /* invalid interrupt number */ return 0; /* invalid interrupt number */
} }
if( Xthal_intlevel[ n ] > XCHAL_EXCM_LEVEL ) if( Xthal_intlevel[ n ] > XCHAL_EXCM_LEVEL )
{ {
return 0; /* priority level too high to safely handle in C */ return 0; /* priority level too high to safely handle in C */
} }
/* Convert exception number to _xt_exception_table name */ /* Convert exception number to _xt_exception_table name */
n = n * portNUM_PROCESSORS + xPortGetCoreID(); n = n * portNUM_PROCESSORS + xPortGetCoreID();
entry = _xt_interrupt_table + n; entry = _xt_interrupt_table + n;
old = entry->handler; old = entry->handler;
if( f ) if( f )
{ {
entry->handler = f; entry->handler = f;
entry->arg = arg; entry->arg = arg;
} }
else else
{ {
entry->handler = &xt_unhandled_interrupt; entry->handler = &xt_unhandled_interrupt;
entry->arg = ( void * ) n; entry->arg = ( void * ) n;
} }
return( ( old == &xt_unhandled_interrupt ) ? 0 : old ); return( ( old == &xt_unhandled_interrupt ) ? 0 : old );
} }
#if CONFIG_SYSVIEW_ENABLE #if CONFIG_SYSVIEW_ENABLE
void * xt_get_interrupt_handler_arg( int n ) void * xt_get_interrupt_handler_arg( int n )
{ {
xt_handler_table_entry * entry; xt_handler_table_entry * entry;
if( ( n < 0 ) || ( n >= XCHAL_NUM_INTERRUPTS ) ) if( ( n < 0 ) || ( n >= XCHAL_NUM_INTERRUPTS ) )
{ {
return 0; /* invalid interrupt number */ return 0; /* invalid interrupt number */
} }
/* Convert exception number to _xt_exception_table name */ /* Convert exception number to _xt_exception_table name */
n = n * portNUM_PROCESSORS + xPortGetCoreID(); n = n * portNUM_PROCESSORS + xPortGetCoreID();
entry = _xt_interrupt_table + n; entry = _xt_interrupt_table + n;
return entry->arg; return entry->arg;
} }
#endif /* if CONFIG_SYSVIEW_ENABLE */ #endif /* if CONFIG_SYSVIEW_ENABLE */
#endif /* XCHAL_HAVE_INTERRUPTS */ #endif /* XCHAL_HAVE_INTERRUPTS */

View file

@ -1,169 +1,169 @@
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD // Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "xtensa_rtos.h" #include "xtensa_rtos.h"
#include "esp_idf_version.h" #include "esp_idf_version.h"
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0)) #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
#include "esp_panic.h" #include "esp_panic.h"
#else #else
#include "esp_private/panic_reason.h" #include "esp_private/panic_reason.h"
#endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0) */ #endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0) */
#include "sdkconfig.h" #include "sdkconfig.h"
#include "soc/soc.h" #include "soc/soc.h"
/* /*
This file contains the default handlers for the high interrupt levels as well as some specialized exceptions. This file contains the default handlers for the high interrupt levels as well as some specialized exceptions.
The default behaviour is to just exit the interrupt or call the panic handler on the exceptions The default behaviour is to just exit the interrupt or call the panic handler on the exceptions
*/ */
#if XCHAL_HAVE_DEBUG #if XCHAL_HAVE_DEBUG
.global xt_debugexception .global xt_debugexception
.weak xt_debugexception .weak xt_debugexception
.set xt_debugexception, _xt_debugexception .set xt_debugexception, _xt_debugexception
.section .iram1,"ax" .section .iram1,"ax"
.type _xt_debugexception,@function .type _xt_debugexception,@function
.align 4 .align 4
_xt_debugexception: _xt_debugexception:
movi a0,PANIC_RSN_DEBUGEXCEPTION movi a0,PANIC_RSN_DEBUGEXCEPTION
wsr a0,EXCCAUSE wsr a0,EXCCAUSE
/* _xt_panic assumes a level 1 exception. As we're /* _xt_panic assumes a level 1 exception. As we're
crashing anyhow, copy EPC & EXCSAVE from DEBUGLEVEL crashing anyhow, copy EPC & EXCSAVE from DEBUGLEVEL
to level 1. */ to level 1. */
rsr a0,(EPC + XCHAL_DEBUGLEVEL) rsr a0,(EPC + XCHAL_DEBUGLEVEL)
wsr a0,EPC_1 wsr a0,EPC_1
rsr a0,(EXCSAVE + XCHAL_DEBUGLEVEL) rsr a0,(EXCSAVE + XCHAL_DEBUGLEVEL)
wsr a0,EXCSAVE_1 wsr a0,EXCSAVE_1
call0 _xt_panic /* does not return */ call0 _xt_panic /* does not return */
rfi XCHAL_DEBUGLEVEL rfi XCHAL_DEBUGLEVEL
#endif /* Debug exception */ #endif /* Debug exception */
#if XCHAL_NUM_INTLEVELS >=2 && XCHAL_EXCM_LEVEL <2 && XCHAL_DEBUGLEVEL !=2 #if XCHAL_NUM_INTLEVELS >=2 && XCHAL_EXCM_LEVEL <2 && XCHAL_DEBUGLEVEL !=2
.global xt_highint2 .global xt_highint2
.weak xt_highint2 .weak xt_highint2
.set xt_highint2, _xt_highint2 .set xt_highint2, _xt_highint2
.section .iram1,"ax" .section .iram1,"ax"
.type _xt_highint2,@function .type _xt_highint2,@function
.align 4 .align 4
_xt_highint2: _xt_highint2:
/* Default handler does nothing; just returns */ /* Default handler does nothing; just returns */
.align 4 .align 4
.L_xt_highint2_exit: .L_xt_highint2_exit:
rsr a0, EXCSAVE_2 /* restore a0 */ rsr a0, EXCSAVE_2 /* restore a0 */
rfi 2 rfi 2
#endif /* Level 2 */ #endif /* Level 2 */
#if XCHAL_NUM_INTLEVELS >=3 && XCHAL_EXCM_LEVEL <3 && XCHAL_DEBUGLEVEL !=3 #if XCHAL_NUM_INTLEVELS >=3 && XCHAL_EXCM_LEVEL <3 && XCHAL_DEBUGLEVEL !=3
.global xt_highint3 .global xt_highint3
.weak xt_highint3 .weak xt_highint3
.set xt_highint3, _xt_highint3 .set xt_highint3, _xt_highint3
.section .iram1,"ax" .section .iram1,"ax"
.type _xt_highint3,@function .type _xt_highint3,@function
.align 4 .align 4
_xt_highint3: _xt_highint3:
/* Default handler does nothing; just returns */ /* Default handler does nothing; just returns */
.align 4 .align 4
.L_xt_highint3_exit: .L_xt_highint3_exit:
rsr a0, EXCSAVE_3 /* restore a0 */ rsr a0, EXCSAVE_3 /* restore a0 */
rfi 3 rfi 3
#endif /* Level 3 */ #endif /* Level 3 */
#if XCHAL_NUM_INTLEVELS >=4 && XCHAL_EXCM_LEVEL <4 && XCHAL_DEBUGLEVEL !=4 #if XCHAL_NUM_INTLEVELS >=4 && XCHAL_EXCM_LEVEL <4 && XCHAL_DEBUGLEVEL !=4
.global xt_highint4 .global xt_highint4
.weak xt_highint4 .weak xt_highint4
.set xt_highint4, _xt_highint4 .set xt_highint4, _xt_highint4
.section .iram1,"ax" .section .iram1,"ax"
.type _xt_highint4,@function .type _xt_highint4,@function
.align 4 .align 4
_xt_highint4: _xt_highint4:
/* Default handler does nothing; just returns */ /* Default handler does nothing; just returns */
.align 4 .align 4
.L_xt_highint4_exit: .L_xt_highint4_exit:
rsr a0, EXCSAVE_4 /* restore a0 */ rsr a0, EXCSAVE_4 /* restore a0 */
rfi 4 rfi 4
#endif /* Level 4 */ #endif /* Level 4 */
#if XCHAL_NUM_INTLEVELS >=5 && XCHAL_EXCM_LEVEL <5 && XCHAL_DEBUGLEVEL !=5 #if XCHAL_NUM_INTLEVELS >=5 && XCHAL_EXCM_LEVEL <5 && XCHAL_DEBUGLEVEL !=5
.global xt_highint5 .global xt_highint5
.weak xt_highint5 .weak xt_highint5
.set xt_highint5, _xt_highint5 .set xt_highint5, _xt_highint5
.section .iram1,"ax" .section .iram1,"ax"
.type _xt_highint5,@function .type _xt_highint5,@function
.align 4 .align 4
_xt_highint5: _xt_highint5:
/* Default handler does nothing; just returns */ /* Default handler does nothing; just returns */
.align 4 .align 4
.L_xt_highint5_exit: .L_xt_highint5_exit:
rsr a0, EXCSAVE_5 /* restore a0 */ rsr a0, EXCSAVE_5 /* restore a0 */
rfi 5 rfi 5
#endif /* Level 5 */ #endif /* Level 5 */
#if XCHAL_NUM_INTLEVELS >=6 && XCHAL_EXCM_LEVEL <6 && XCHAL_DEBUGLEVEL !=6 #if XCHAL_NUM_INTLEVELS >=6 && XCHAL_EXCM_LEVEL <6 && XCHAL_DEBUGLEVEL !=6
.global _xt_highint6 .global _xt_highint6
.global xt_highint6 .global xt_highint6
.weak xt_highint6 .weak xt_highint6
.set xt_highint6, _xt_highint6 .set xt_highint6, _xt_highint6
.section .iram1,"ax" .section .iram1,"ax"
.type _xt_highint6,@function .type _xt_highint6,@function
.align 4 .align 4
_xt_highint6: _xt_highint6:
/* Default handler does nothing; just returns */ /* Default handler does nothing; just returns */
.align 4 .align 4
.L_xt_highint6_exit: .L_xt_highint6_exit:
rsr a0, EXCSAVE_6 /* restore a0 */ rsr a0, EXCSAVE_6 /* restore a0 */
rfi 6 rfi 6
#endif /* Level 6 */ #endif /* Level 6 */
#if XCHAL_HAVE_NMI #if XCHAL_HAVE_NMI
.global _xt_nmi .global _xt_nmi
.global xt_nmi .global xt_nmi
.weak xt_nmi .weak xt_nmi
.set xt_nmi, _xt_nmi .set xt_nmi, _xt_nmi
.section .iram1,"ax" .section .iram1,"ax"
.type _xt_nmi,@function .type _xt_nmi,@function
.align 4 .align 4
_xt_nmi: _xt_nmi:
/* Default handler does nothing; just returns */ /* Default handler does nothing; just returns */
.align 4 .align 4
.L_xt_nmi_exit: .L_xt_nmi_exit:
rsr a0, EXCSAVE + XCHAL_NMILEVEL /* restore a0 */ rsr a0, EXCSAVE + XCHAL_NMILEVEL /* restore a0 */
rfi XCHAL_NMILEVEL rfi XCHAL_NMILEVEL
#endif /* NMI */ #endif /* NMI */

File diff suppressed because it is too large Load diff