mirror of
				https://github.com/FreeRTOS/FreeRTOS-Kernel.git
				synced 2025-11-04 02:59:01 +01:00 
			
		
		
		
	Add git attributes (#245)
* Add .gitattributes configured to normailze line endings to LF * replace crlf with lf, per .gitattributes
This commit is contained in:
		
							parent
							
								
									23f641850d
								
							
						
					
					
						commit
						578d040659
					
				
							
								
								
									
										105
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal 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
 | 
			
		||||
							
								
								
									
										1120
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1120
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,390 +1,390 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
Copyright (c) 2006-2015 Cadence Design Systems Inc.
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining
 | 
			
		||||
a copy of this software and associated documentation files (the
 | 
			
		||||
"Software"), to deal in the Software without restriction, including
 | 
			
		||||
without limitation the rights to use, copy, modify, merge, publish,
 | 
			
		||||
distribute, sublicense, and/or sell copies of the Software, and to
 | 
			
		||||
permit persons to whom the Software is furnished to do so, subject to
 | 
			
		||||
the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included
 | 
			
		||||
in all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
			
		||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
			
		||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
			
		||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
			
		||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
--------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        XTENSA CONTEXT FRAMES AND MACROS FOR RTOS ASSEMBLER SOURCES
 | 
			
		||||
 | 
			
		||||
This header contains definitions and macros for use primarily by Xtensa
 | 
			
		||||
RTOS assembly coded source files. It includes and uses the Xtensa hardware
 | 
			
		||||
abstraction layer (HAL) to deal with config specifics. It may also be
 | 
			
		||||
included in C source files.
 | 
			
		||||
 | 
			
		||||
!! Supports only Xtensa Exception Architecture 2 (XEA2). XEA1 not supported. !!
 | 
			
		||||
 | 
			
		||||
NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes.
 | 
			
		||||
 | 
			
		||||
*******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef XTENSA_CONTEXT_H
 | 
			
		||||
#define XTENSA_CONTEXT_H
 | 
			
		||||
 | 
			
		||||
#ifdef __ASSEMBLER__
 | 
			
		||||
#include    <xtensa/coreasm.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include    <xtensa/config/tie.h>
 | 
			
		||||
#include    <xtensa/corebits.h>
 | 
			
		||||
#include    <xtensa/config/system.h>
 | 
			
		||||
#include <xtensa/xtruntime-frames.h>
 | 
			
		||||
#include    <esp_idf_version.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Align a value up to nearest n-byte boundary, where n is a power of 2. */
 | 
			
		||||
#define ALIGNUP(n, val) (((val) + (n)-1) & -(n))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
  Macros that help define structures for both C and assembler.
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifdef STRUCT_BEGIN
 | 
			
		||||
#undef STRUCT_BEGIN
 | 
			
		||||
#undef STRUCT_FIELD
 | 
			
		||||
#undef STRUCT_AFIELD
 | 
			
		||||
#undef STRUCT_END
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
 | 
			
		||||
 | 
			
		||||
#define STRUCT_BEGIN            .pushsection .text; .struct 0
 | 
			
		||||
#define STRUCT_FIELD(ctype,size,asname,name)    asname: .space  size
 | 
			
		||||
#define STRUCT_AFIELD(ctype,size,asname,name,n) asname: .space  (size)*(n)
 | 
			
		||||
#define STRUCT_END(sname)       sname##Size:; .popsection
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#define STRUCT_BEGIN            typedef struct {
 | 
			
		||||
#define STRUCT_FIELD(ctype,size,asname,name)    ctype   name;
 | 
			
		||||
#define STRUCT_AFIELD(ctype,size,asname,name,n) ctype   name[n];
 | 
			
		||||
#define STRUCT_END(sname)       } sname;
 | 
			
		||||
 | 
			
		||||
#endif //_ASMLANGUAGE || __ASSEMBLER__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
  INTERRUPT/EXCEPTION STACK FRAME FOR A THREAD OR NESTED INTERRUPT
 | 
			
		||||
 | 
			
		||||
  A stack frame of this structure is allocated for any interrupt or exception.
 | 
			
		||||
  It goes on the current stack. If the RTOS has a system stack for handling 
 | 
			
		||||
  interrupts, every thread stack must allow space for just one interrupt stack 
 | 
			
		||||
  frame, then nested interrupt stack frames go on the system stack.
 | 
			
		||||
 | 
			
		||||
  The frame includes basic registers (explicit) and "extra" registers introduced 
 | 
			
		||||
  by user TIE or the use of the MAC16 option in the user's Xtensa config.
 | 
			
		||||
  The frame size is minimized by omitting regs not applicable to user's config.
 | 
			
		||||
 | 
			
		||||
  For Windowed ABI, this stack frame includes the interruptee's base save area,
 | 
			
		||||
  another base save area to manage gcc nested functions, and a little temporary 
 | 
			
		||||
  space to help manage the spilling of the register windows.
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
STRUCT_BEGIN
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_EXIT,     exit) /* exit point for dispatch */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_PC,       pc)   /* return PC */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_PS,       ps)   /* return PS */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A0,       a0)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A1,       a1)   /* stack pointer before interrupt */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A2,       a2)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A3,       a3)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A4,       a4)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A5,       a5)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A6,       a6)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A7,       a7)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A8,       a8)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A9,       a9)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A10,      a10)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A11,      a11)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A12,      a12)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A13,      a13)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A14,      a14)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A15,      a15)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_SAR,      sar)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_EXCCAUSE, exccause)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_EXCVADDR, excvaddr)
 | 
			
		||||
#if XCHAL_HAVE_LOOPS
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_LBEG,   lbeg)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_LEND,   lend)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_LCOUNT, lcount)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef __XTENSA_CALL0_ABI__
 | 
			
		||||
/* Temporary space for saving stuff during window spill */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_TMP0,   tmp0)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_TMP1,   tmp1)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_TMP2,   tmp2)
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef XT_USE_SWPRI
 | 
			
		||||
/* Storage for virtual priority mask */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_VPRI,   vpri)
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef XT_USE_OVLY
 | 
			
		||||
/* Storage for overlay state */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_OVLY,   ovly)
 | 
			
		||||
#endif
 | 
			
		||||
STRUCT_END(XtExcFrame)
 | 
			
		||||
 | 
			
		||||
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
 | 
			
		||||
#define XT_STK_NEXT1      XtExcFrameSize
 | 
			
		||||
#else
 | 
			
		||||
#define XT_STK_NEXT1      sizeof(XtExcFrame)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Allocate extra storage if needed */
 | 
			
		||||
#if XCHAL_EXTRA_SA_SIZE != 0
 | 
			
		||||
 | 
			
		||||
#if XCHAL_EXTRA_SA_ALIGN <= 16
 | 
			
		||||
#define XT_STK_EXTRA            ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1)
 | 
			
		||||
#else
 | 
			
		||||
/* If need more alignment than stack, add space for dynamic alignment */
 | 
			
		||||
#define XT_STK_EXTRA            (ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1) + XCHAL_EXTRA_SA_ALIGN)
 | 
			
		||||
#endif
 | 
			
		||||
#define XT_STK_NEXT2            (XT_STK_EXTRA + XCHAL_EXTRA_SA_SIZE)
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#define XT_STK_NEXT2            XT_STK_NEXT1   
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
  This is the frame size. Add space for 4 registers (interruptee's base save
 | 
			
		||||
  area) and some space for gcc nested functions if any.
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
#define XT_STK_FRMSZ            (ALIGNUP(0x10, XT_STK_NEXT2) + 0x20)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
  SOLICITED STACK FRAME FOR A THREAD
 | 
			
		||||
 | 
			
		||||
  A stack frame of this structure is allocated whenever a thread enters the 
 | 
			
		||||
  RTOS kernel intentionally (and synchronously) to submit to thread scheduling.
 | 
			
		||||
  It goes on the current thread's stack.
 | 
			
		||||
 | 
			
		||||
  The solicited frame only includes registers that are required to be preserved
 | 
			
		||||
  by the callee according to the compiler's ABI conventions, some space to save 
 | 
			
		||||
  the return address for returning to the caller, and the caller's PS register.
 | 
			
		||||
 | 
			
		||||
  For Windowed ABI, this stack frame includes the caller's base save area.
 | 
			
		||||
 | 
			
		||||
  Note on XT_SOL_EXIT field:
 | 
			
		||||
      It is necessary to distinguish a solicited from an interrupt stack frame.
 | 
			
		||||
      This field corresponds to XT_STK_EXIT in the interrupt stack frame and is
 | 
			
		||||
      always at the same offset (0). It can be written with a code (usually 0) 
 | 
			
		||||
      to distinguish a solicted frame from an interrupt frame. An RTOS port may
 | 
			
		||||
      opt to ignore this field if it has another way of distinguishing frames.
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
STRUCT_BEGIN
 | 
			
		||||
#ifdef __XTENSA_CALL0_ABI__
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_PC,   pc)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_PS,   ps)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A12,  a12)    /* should be on 16-byte alignment */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A13,  a13)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A14,  a14)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A15,  a15)
 | 
			
		||||
#else
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_PC,   pc)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_PS,   ps)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A0,   a0)    /* should be on 16-byte alignment */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A1,   a1)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A2,   a2)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A3,   a3)
 | 
			
		||||
#endif
 | 
			
		||||
STRUCT_END(XtSolFrame)
 | 
			
		||||
 | 
			
		||||
/* Size of solicited stack frame */
 | 
			
		||||
#define XT_SOL_FRMSZ            ALIGNUP(0x10, XtSolFrameSize)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
  CO-PROCESSOR STATE SAVE AREA FOR A THREAD
 | 
			
		||||
 | 
			
		||||
  The RTOS must provide an area per thread to save the state of co-processors
 | 
			
		||||
  when that thread does not have control. Co-processors are context-switched
 | 
			
		||||
  lazily (on demand) only when a new thread uses a co-processor instruction,
 | 
			
		||||
  otherwise a thread retains ownership of the co-processor even when it loses
 | 
			
		||||
  control of the processor. An Xtensa co-processor exception is triggered when
 | 
			
		||||
  any co-processor instruction is executed by a thread that is not the owner,
 | 
			
		||||
  and the context switch of that co-processor is then peformed by the handler.
 | 
			
		||||
  Ownership represents which thread's state is currently in the co-processor.
 | 
			
		||||
 | 
			
		||||
  Co-processors may not be used by interrupt or exception handlers. If an 
 | 
			
		||||
  co-processor instruction is executed by an interrupt or exception handler,
 | 
			
		||||
  the co-processor exception handler will trigger a kernel panic and freeze.
 | 
			
		||||
  This restriction is introduced to reduce the overhead of saving and restoring
 | 
			
		||||
  co-processor state (which can be quite large) and in particular remove that
 | 
			
		||||
  overhead from interrupt handlers.
 | 
			
		||||
 | 
			
		||||
  The co-processor state save area may be in any convenient per-thread location
 | 
			
		||||
  such as in the thread control block or above the thread stack area. It need
 | 
			
		||||
  not be in the interrupt stack frame since interrupts don't use co-processors.
 | 
			
		||||
 | 
			
		||||
  Along with the save area for each co-processor, two bitmasks with flags per 
 | 
			
		||||
  co-processor (laid out as in the CPENABLE reg) help manage context-switching
 | 
			
		||||
  co-processors as efficiently as possible:
 | 
			
		||||
 | 
			
		||||
  XT_CPENABLE
 | 
			
		||||
    The contents of a non-running thread's CPENABLE register.
 | 
			
		||||
    It represents the co-processors owned (and whose state is still needed)
 | 
			
		||||
    by the thread. When a thread is preempted, its CPENABLE is saved here.
 | 
			
		||||
    When a thread solicits a context-swtich, its CPENABLE is cleared - the
 | 
			
		||||
    compiler has saved the (caller-saved) co-proc state if it needs to.
 | 
			
		||||
    When a non-running thread loses ownership of a CP, its bit is cleared.
 | 
			
		||||
    When a thread runs, it's XT_CPENABLE is loaded into the CPENABLE reg.
 | 
			
		||||
    Avoids co-processor exceptions when no change of ownership is needed.
 | 
			
		||||
 | 
			
		||||
  XT_CPSTORED
 | 
			
		||||
    A bitmask with the same layout as CPENABLE, a bit per co-processor.
 | 
			
		||||
    Indicates whether the state of each co-processor is saved in the state 
 | 
			
		||||
    save area. When a thread enters the kernel, only the state of co-procs
 | 
			
		||||
    still enabled in CPENABLE is saved. When the co-processor exception 
 | 
			
		||||
    handler assigns ownership of a co-processor to a thread, it restores 
 | 
			
		||||
    the saved state only if this bit is set, and clears this bit.
 | 
			
		||||
 | 
			
		||||
  XT_CP_CS_ST
 | 
			
		||||
    A bitmask with the same layout as CPENABLE, a bit per co-processor.
 | 
			
		||||
    Indicates whether callee-saved state is saved in the state save area.
 | 
			
		||||
    Callee-saved state is saved by itself on a solicited context switch,
 | 
			
		||||
    and restored when needed by the coprocessor exception handler.
 | 
			
		||||
    Unsolicited switches will cause the entire coprocessor to be saved
 | 
			
		||||
    when necessary.
 | 
			
		||||
 | 
			
		||||
  XT_CP_ASA
 | 
			
		||||
    Pointer to the aligned save area.  Allows it to be aligned more than
 | 
			
		||||
    the overall save area (which might only be stack-aligned or TCB-aligned).
 | 
			
		||||
    Especially relevant for Xtensa cores configured with a very large data
 | 
			
		||||
    path that requires alignment greater than 16 bytes (ABI stack alignment).
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#if XCHAL_CP_NUM > 0
 | 
			
		||||
 | 
			
		||||
/*  Offsets of each coprocessor save area within the 'aligned save area':  */
 | 
			
		||||
#define XT_CP0_SA   0
 | 
			
		||||
#define XT_CP1_SA   ALIGNUP(XCHAL_CP1_SA_ALIGN, XT_CP0_SA + XCHAL_CP0_SA_SIZE)
 | 
			
		||||
#define XT_CP2_SA   ALIGNUP(XCHAL_CP2_SA_ALIGN, XT_CP1_SA + XCHAL_CP1_SA_SIZE)
 | 
			
		||||
#define XT_CP3_SA   ALIGNUP(XCHAL_CP3_SA_ALIGN, XT_CP2_SA + XCHAL_CP2_SA_SIZE)
 | 
			
		||||
#define XT_CP4_SA   ALIGNUP(XCHAL_CP4_SA_ALIGN, XT_CP3_SA + XCHAL_CP3_SA_SIZE)
 | 
			
		||||
#define XT_CP5_SA   ALIGNUP(XCHAL_CP5_SA_ALIGN, XT_CP4_SA + XCHAL_CP4_SA_SIZE)
 | 
			
		||||
#define XT_CP6_SA   ALIGNUP(XCHAL_CP6_SA_ALIGN, XT_CP5_SA + XCHAL_CP5_SA_SIZE)
 | 
			
		||||
#define XT_CP7_SA   ALIGNUP(XCHAL_CP7_SA_ALIGN, XT_CP6_SA + XCHAL_CP6_SA_SIZE)
 | 
			
		||||
#define XT_CP_SA_SIZE   ALIGNUP(16, XT_CP7_SA + XCHAL_CP7_SA_SIZE)
 | 
			
		||||
 | 
			
		||||
/*  Offsets within the overall save area:  */
 | 
			
		||||
#define XT_CPENABLE 0   /* (2 bytes) coprocessors active for this thread */
 | 
			
		||||
#define XT_CPSTORED 2   /* (2 bytes) coprocessors saved for this thread */
 | 
			
		||||
#define XT_CP_CS_ST 4   /* (2 bytes) coprocessor callee-saved regs stored for this thread */
 | 
			
		||||
#define XT_CP_ASA   8   /* (4 bytes) ptr to aligned save area */
 | 
			
		||||
/*  Overall size allows for dynamic alignment:  */
 | 
			
		||||
#define XT_CP_SIZE  (12 + XT_CP_SA_SIZE + XCHAL_TOTAL_SA_ALIGN)
 | 
			
		||||
#else
 | 
			
		||||
#define XT_CP_SIZE  0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 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)
 | 
			
		||||
 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.
 | 
			
		||||
*/
 | 
			
		||||
#ifdef __ASSEMBLER__
 | 
			
		||||
	.macro getcoreid reg
 | 
			
		||||
	rsr.prid \reg
 | 
			
		||||
	extui \reg,\reg,13,1
 | 
			
		||||
	.endm
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
#define CORE_ID_PRO 0xCDCD
 | 
			
		||||
#define CORE_ID_APP 0xABAB
 | 
			
		||||
#else
 | 
			
		||||
#define CORE_ID_REGVAL_PRO 0xCDCD
 | 
			
		||||
#define CORE_ID_REGVAL_APP 0xABAB
 | 
			
		||||
 | 
			
		||||
/* Included for compatibility, recommend using CORE_ID_REGVAL_PRO instead */
 | 
			
		||||
#define CORE_ID_PRO CORE_ID_REGVAL_PRO
 | 
			
		||||
 | 
			
		||||
/* Included for compatibility, recommend using CORE_ID_REGVAL_APP instead */
 | 
			
		||||
#define CORE_ID_APP CORE_ID_REGVAL_APP
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
  MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN
 | 
			
		||||
 | 
			
		||||
  Convenient where the frame size requirements are the same for both ABIs.
 | 
			
		||||
    ENTRY(sz), RET(sz) are for framed functions (have locals or make calls).
 | 
			
		||||
    ENTRY0,    RET0    are for frameless functions (no locals, no calls).
 | 
			
		||||
 | 
			
		||||
  where size = size of stack frame in bytes (must be >0 and aligned to 16).
 | 
			
		||||
  For framed functions the frame is created and the return address saved at
 | 
			
		||||
  base of frame (Call0 ABI) or as determined by hardware (Windowed ABI).
 | 
			
		||||
  For frameless functions, there is no frame and return address remains in a0.
 | 
			
		||||
  Note: Because CPP macros expand to a single line, macros requiring multi-line 
 | 
			
		||||
  expansions are implemented as assembler macros.
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifdef __ASSEMBLER__
 | 
			
		||||
#ifdef __XTENSA_CALL0_ABI__
 | 
			
		||||
  /* Call0 */
 | 
			
		||||
  #define ENTRY(sz)     entry1  sz
 | 
			
		||||
    .macro  entry1 size=0x10
 | 
			
		||||
    addi    sp, sp, -\size
 | 
			
		||||
    s32i    a0, sp, 0
 | 
			
		||||
    .endm
 | 
			
		||||
  #define ENTRY0      
 | 
			
		||||
  #define RET(sz)       ret1    sz
 | 
			
		||||
    .macro  ret1 size=0x10
 | 
			
		||||
    l32i    a0, sp, 0
 | 
			
		||||
    addi    sp, sp, \size
 | 
			
		||||
    ret
 | 
			
		||||
    .endm
 | 
			
		||||
  #define RET0          ret
 | 
			
		||||
#else
 | 
			
		||||
  /* Windowed */
 | 
			
		||||
  #define ENTRY(sz)     entry   sp, sz
 | 
			
		||||
  #define ENTRY0        entry   sp, 0x10
 | 
			
		||||
  #define RET(sz)       retw
 | 
			
		||||
  #define RET0          retw
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* XTENSA_CONTEXT_H */
 | 
			
		||||
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
Copyright (c) 2006-2015 Cadence Design Systems Inc.
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining
 | 
			
		||||
a copy of this software and associated documentation files (the
 | 
			
		||||
"Software"), to deal in the Software without restriction, including
 | 
			
		||||
without limitation the rights to use, copy, modify, merge, publish,
 | 
			
		||||
distribute, sublicense, and/or sell copies of the Software, and to
 | 
			
		||||
permit persons to whom the Software is furnished to do so, subject to
 | 
			
		||||
the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included
 | 
			
		||||
in all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
			
		||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
			
		||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
			
		||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
			
		||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
--------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        XTENSA CONTEXT FRAMES AND MACROS FOR RTOS ASSEMBLER SOURCES
 | 
			
		||||
 | 
			
		||||
This header contains definitions and macros for use primarily by Xtensa
 | 
			
		||||
RTOS assembly coded source files. It includes and uses the Xtensa hardware
 | 
			
		||||
abstraction layer (HAL) to deal with config specifics. It may also be
 | 
			
		||||
included in C source files.
 | 
			
		||||
 | 
			
		||||
!! Supports only Xtensa Exception Architecture 2 (XEA2). XEA1 not supported. !!
 | 
			
		||||
 | 
			
		||||
NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes.
 | 
			
		||||
 | 
			
		||||
*******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef XTENSA_CONTEXT_H
 | 
			
		||||
#define XTENSA_CONTEXT_H
 | 
			
		||||
 | 
			
		||||
#ifdef __ASSEMBLER__
 | 
			
		||||
#include    <xtensa/coreasm.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include    <xtensa/config/tie.h>
 | 
			
		||||
#include    <xtensa/corebits.h>
 | 
			
		||||
#include    <xtensa/config/system.h>
 | 
			
		||||
#include <xtensa/xtruntime-frames.h>
 | 
			
		||||
#include    <esp_idf_version.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Align a value up to nearest n-byte boundary, where n is a power of 2. */
 | 
			
		||||
#define ALIGNUP(n, val) (((val) + (n)-1) & -(n))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
  Macros that help define structures for both C and assembler.
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifdef STRUCT_BEGIN
 | 
			
		||||
#undef STRUCT_BEGIN
 | 
			
		||||
#undef STRUCT_FIELD
 | 
			
		||||
#undef STRUCT_AFIELD
 | 
			
		||||
#undef STRUCT_END
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
 | 
			
		||||
 | 
			
		||||
#define STRUCT_BEGIN            .pushsection .text; .struct 0
 | 
			
		||||
#define STRUCT_FIELD(ctype,size,asname,name)    asname: .space  size
 | 
			
		||||
#define STRUCT_AFIELD(ctype,size,asname,name,n) asname: .space  (size)*(n)
 | 
			
		||||
#define STRUCT_END(sname)       sname##Size:; .popsection
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#define STRUCT_BEGIN            typedef struct {
 | 
			
		||||
#define STRUCT_FIELD(ctype,size,asname,name)    ctype   name;
 | 
			
		||||
#define STRUCT_AFIELD(ctype,size,asname,name,n) ctype   name[n];
 | 
			
		||||
#define STRUCT_END(sname)       } sname;
 | 
			
		||||
 | 
			
		||||
#endif //_ASMLANGUAGE || __ASSEMBLER__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
  INTERRUPT/EXCEPTION STACK FRAME FOR A THREAD OR NESTED INTERRUPT
 | 
			
		||||
 | 
			
		||||
  A stack frame of this structure is allocated for any interrupt or exception.
 | 
			
		||||
  It goes on the current stack. If the RTOS has a system stack for handling 
 | 
			
		||||
  interrupts, every thread stack must allow space for just one interrupt stack 
 | 
			
		||||
  frame, then nested interrupt stack frames go on the system stack.
 | 
			
		||||
 | 
			
		||||
  The frame includes basic registers (explicit) and "extra" registers introduced 
 | 
			
		||||
  by user TIE or the use of the MAC16 option in the user's Xtensa config.
 | 
			
		||||
  The frame size is minimized by omitting regs not applicable to user's config.
 | 
			
		||||
 | 
			
		||||
  For Windowed ABI, this stack frame includes the interruptee's base save area,
 | 
			
		||||
  another base save area to manage gcc nested functions, and a little temporary 
 | 
			
		||||
  space to help manage the spilling of the register windows.
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
STRUCT_BEGIN
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_EXIT,     exit) /* exit point for dispatch */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_PC,       pc)   /* return PC */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_PS,       ps)   /* return PS */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A0,       a0)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A1,       a1)   /* stack pointer before interrupt */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A2,       a2)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A3,       a3)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A4,       a4)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A5,       a5)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A6,       a6)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A7,       a7)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A8,       a8)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A9,       a9)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A10,      a10)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A11,      a11)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A12,      a12)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A13,      a13)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A14,      a14)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_A15,      a15)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_SAR,      sar)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_EXCCAUSE, exccause)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_EXCVADDR, excvaddr)
 | 
			
		||||
#if XCHAL_HAVE_LOOPS
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_LBEG,   lbeg)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_LEND,   lend)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_LCOUNT, lcount)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef __XTENSA_CALL0_ABI__
 | 
			
		||||
/* Temporary space for saving stuff during window spill */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_TMP0,   tmp0)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_TMP1,   tmp1)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_TMP2,   tmp2)
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef XT_USE_SWPRI
 | 
			
		||||
/* Storage for virtual priority mask */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_VPRI,   vpri)
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef XT_USE_OVLY
 | 
			
		||||
/* Storage for overlay state */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_STK_OVLY,   ovly)
 | 
			
		||||
#endif
 | 
			
		||||
STRUCT_END(XtExcFrame)
 | 
			
		||||
 | 
			
		||||
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
 | 
			
		||||
#define XT_STK_NEXT1      XtExcFrameSize
 | 
			
		||||
#else
 | 
			
		||||
#define XT_STK_NEXT1      sizeof(XtExcFrame)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Allocate extra storage if needed */
 | 
			
		||||
#if XCHAL_EXTRA_SA_SIZE != 0
 | 
			
		||||
 | 
			
		||||
#if XCHAL_EXTRA_SA_ALIGN <= 16
 | 
			
		||||
#define XT_STK_EXTRA            ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1)
 | 
			
		||||
#else
 | 
			
		||||
/* If need more alignment than stack, add space for dynamic alignment */
 | 
			
		||||
#define XT_STK_EXTRA            (ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1) + XCHAL_EXTRA_SA_ALIGN)
 | 
			
		||||
#endif
 | 
			
		||||
#define XT_STK_NEXT2            (XT_STK_EXTRA + XCHAL_EXTRA_SA_SIZE)
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#define XT_STK_NEXT2            XT_STK_NEXT1   
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
  This is the frame size. Add space for 4 registers (interruptee's base save
 | 
			
		||||
  area) and some space for gcc nested functions if any.
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
#define XT_STK_FRMSZ            (ALIGNUP(0x10, XT_STK_NEXT2) + 0x20)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
  SOLICITED STACK FRAME FOR A THREAD
 | 
			
		||||
 | 
			
		||||
  A stack frame of this structure is allocated whenever a thread enters the 
 | 
			
		||||
  RTOS kernel intentionally (and synchronously) to submit to thread scheduling.
 | 
			
		||||
  It goes on the current thread's stack.
 | 
			
		||||
 | 
			
		||||
  The solicited frame only includes registers that are required to be preserved
 | 
			
		||||
  by the callee according to the compiler's ABI conventions, some space to save 
 | 
			
		||||
  the return address for returning to the caller, and the caller's PS register.
 | 
			
		||||
 | 
			
		||||
  For Windowed ABI, this stack frame includes the caller's base save area.
 | 
			
		||||
 | 
			
		||||
  Note on XT_SOL_EXIT field:
 | 
			
		||||
      It is necessary to distinguish a solicited from an interrupt stack frame.
 | 
			
		||||
      This field corresponds to XT_STK_EXIT in the interrupt stack frame and is
 | 
			
		||||
      always at the same offset (0). It can be written with a code (usually 0) 
 | 
			
		||||
      to distinguish a solicted frame from an interrupt frame. An RTOS port may
 | 
			
		||||
      opt to ignore this field if it has another way of distinguishing frames.
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
STRUCT_BEGIN
 | 
			
		||||
#ifdef __XTENSA_CALL0_ABI__
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_PC,   pc)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_PS,   ps)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A12,  a12)    /* should be on 16-byte alignment */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A13,  a13)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A14,  a14)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A15,  a15)
 | 
			
		||||
#else
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_PC,   pc)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_PS,   ps)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A0,   a0)    /* should be on 16-byte alignment */
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A1,   a1)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A2,   a2)
 | 
			
		||||
STRUCT_FIELD (long, 4, XT_SOL_A3,   a3)
 | 
			
		||||
#endif
 | 
			
		||||
STRUCT_END(XtSolFrame)
 | 
			
		||||
 | 
			
		||||
/* Size of solicited stack frame */
 | 
			
		||||
#define XT_SOL_FRMSZ            ALIGNUP(0x10, XtSolFrameSize)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
  CO-PROCESSOR STATE SAVE AREA FOR A THREAD
 | 
			
		||||
 | 
			
		||||
  The RTOS must provide an area per thread to save the state of co-processors
 | 
			
		||||
  when that thread does not have control. Co-processors are context-switched
 | 
			
		||||
  lazily (on demand) only when a new thread uses a co-processor instruction,
 | 
			
		||||
  otherwise a thread retains ownership of the co-processor even when it loses
 | 
			
		||||
  control of the processor. An Xtensa co-processor exception is triggered when
 | 
			
		||||
  any co-processor instruction is executed by a thread that is not the owner,
 | 
			
		||||
  and the context switch of that co-processor is then peformed by the handler.
 | 
			
		||||
  Ownership represents which thread's state is currently in the co-processor.
 | 
			
		||||
 | 
			
		||||
  Co-processors may not be used by interrupt or exception handlers. If an 
 | 
			
		||||
  co-processor instruction is executed by an interrupt or exception handler,
 | 
			
		||||
  the co-processor exception handler will trigger a kernel panic and freeze.
 | 
			
		||||
  This restriction is introduced to reduce the overhead of saving and restoring
 | 
			
		||||
  co-processor state (which can be quite large) and in particular remove that
 | 
			
		||||
  overhead from interrupt handlers.
 | 
			
		||||
 | 
			
		||||
  The co-processor state save area may be in any convenient per-thread location
 | 
			
		||||
  such as in the thread control block or above the thread stack area. It need
 | 
			
		||||
  not be in the interrupt stack frame since interrupts don't use co-processors.
 | 
			
		||||
 | 
			
		||||
  Along with the save area for each co-processor, two bitmasks with flags per 
 | 
			
		||||
  co-processor (laid out as in the CPENABLE reg) help manage context-switching
 | 
			
		||||
  co-processors as efficiently as possible:
 | 
			
		||||
 | 
			
		||||
  XT_CPENABLE
 | 
			
		||||
    The contents of a non-running thread's CPENABLE register.
 | 
			
		||||
    It represents the co-processors owned (and whose state is still needed)
 | 
			
		||||
    by the thread. When a thread is preempted, its CPENABLE is saved here.
 | 
			
		||||
    When a thread solicits a context-swtich, its CPENABLE is cleared - the
 | 
			
		||||
    compiler has saved the (caller-saved) co-proc state if it needs to.
 | 
			
		||||
    When a non-running thread loses ownership of a CP, its bit is cleared.
 | 
			
		||||
    When a thread runs, it's XT_CPENABLE is loaded into the CPENABLE reg.
 | 
			
		||||
    Avoids co-processor exceptions when no change of ownership is needed.
 | 
			
		||||
 | 
			
		||||
  XT_CPSTORED
 | 
			
		||||
    A bitmask with the same layout as CPENABLE, a bit per co-processor.
 | 
			
		||||
    Indicates whether the state of each co-processor is saved in the state 
 | 
			
		||||
    save area. When a thread enters the kernel, only the state of co-procs
 | 
			
		||||
    still enabled in CPENABLE is saved. When the co-processor exception 
 | 
			
		||||
    handler assigns ownership of a co-processor to a thread, it restores 
 | 
			
		||||
    the saved state only if this bit is set, and clears this bit.
 | 
			
		||||
 | 
			
		||||
  XT_CP_CS_ST
 | 
			
		||||
    A bitmask with the same layout as CPENABLE, a bit per co-processor.
 | 
			
		||||
    Indicates whether callee-saved state is saved in the state save area.
 | 
			
		||||
    Callee-saved state is saved by itself on a solicited context switch,
 | 
			
		||||
    and restored when needed by the coprocessor exception handler.
 | 
			
		||||
    Unsolicited switches will cause the entire coprocessor to be saved
 | 
			
		||||
    when necessary.
 | 
			
		||||
 | 
			
		||||
  XT_CP_ASA
 | 
			
		||||
    Pointer to the aligned save area.  Allows it to be aligned more than
 | 
			
		||||
    the overall save area (which might only be stack-aligned or TCB-aligned).
 | 
			
		||||
    Especially relevant for Xtensa cores configured with a very large data
 | 
			
		||||
    path that requires alignment greater than 16 bytes (ABI stack alignment).
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#if XCHAL_CP_NUM > 0
 | 
			
		||||
 | 
			
		||||
/*  Offsets of each coprocessor save area within the 'aligned save area':  */
 | 
			
		||||
#define XT_CP0_SA   0
 | 
			
		||||
#define XT_CP1_SA   ALIGNUP(XCHAL_CP1_SA_ALIGN, XT_CP0_SA + XCHAL_CP0_SA_SIZE)
 | 
			
		||||
#define XT_CP2_SA   ALIGNUP(XCHAL_CP2_SA_ALIGN, XT_CP1_SA + XCHAL_CP1_SA_SIZE)
 | 
			
		||||
#define XT_CP3_SA   ALIGNUP(XCHAL_CP3_SA_ALIGN, XT_CP2_SA + XCHAL_CP2_SA_SIZE)
 | 
			
		||||
#define XT_CP4_SA   ALIGNUP(XCHAL_CP4_SA_ALIGN, XT_CP3_SA + XCHAL_CP3_SA_SIZE)
 | 
			
		||||
#define XT_CP5_SA   ALIGNUP(XCHAL_CP5_SA_ALIGN, XT_CP4_SA + XCHAL_CP4_SA_SIZE)
 | 
			
		||||
#define XT_CP6_SA   ALIGNUP(XCHAL_CP6_SA_ALIGN, XT_CP5_SA + XCHAL_CP5_SA_SIZE)
 | 
			
		||||
#define XT_CP7_SA   ALIGNUP(XCHAL_CP7_SA_ALIGN, XT_CP6_SA + XCHAL_CP6_SA_SIZE)
 | 
			
		||||
#define XT_CP_SA_SIZE   ALIGNUP(16, XT_CP7_SA + XCHAL_CP7_SA_SIZE)
 | 
			
		||||
 | 
			
		||||
/*  Offsets within the overall save area:  */
 | 
			
		||||
#define XT_CPENABLE 0   /* (2 bytes) coprocessors active for this thread */
 | 
			
		||||
#define XT_CPSTORED 2   /* (2 bytes) coprocessors saved for this thread */
 | 
			
		||||
#define XT_CP_CS_ST 4   /* (2 bytes) coprocessor callee-saved regs stored for this thread */
 | 
			
		||||
#define XT_CP_ASA   8   /* (4 bytes) ptr to aligned save area */
 | 
			
		||||
/*  Overall size allows for dynamic alignment:  */
 | 
			
		||||
#define XT_CP_SIZE  (12 + XT_CP_SA_SIZE + XCHAL_TOTAL_SA_ALIGN)
 | 
			
		||||
#else
 | 
			
		||||
#define XT_CP_SIZE  0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 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)
 | 
			
		||||
 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.
 | 
			
		||||
*/
 | 
			
		||||
#ifdef __ASSEMBLER__
 | 
			
		||||
	.macro getcoreid reg
 | 
			
		||||
	rsr.prid \reg
 | 
			
		||||
	extui \reg,\reg,13,1
 | 
			
		||||
	.endm
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
#define CORE_ID_PRO 0xCDCD
 | 
			
		||||
#define CORE_ID_APP 0xABAB
 | 
			
		||||
#else
 | 
			
		||||
#define CORE_ID_REGVAL_PRO 0xCDCD
 | 
			
		||||
#define CORE_ID_REGVAL_APP 0xABAB
 | 
			
		||||
 | 
			
		||||
/* Included for compatibility, recommend using CORE_ID_REGVAL_PRO instead */
 | 
			
		||||
#define CORE_ID_PRO CORE_ID_REGVAL_PRO
 | 
			
		||||
 | 
			
		||||
/* Included for compatibility, recommend using CORE_ID_REGVAL_APP instead */
 | 
			
		||||
#define CORE_ID_APP CORE_ID_REGVAL_APP
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
  MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN
 | 
			
		||||
 | 
			
		||||
  Convenient where the frame size requirements are the same for both ABIs.
 | 
			
		||||
    ENTRY(sz), RET(sz) are for framed functions (have locals or make calls).
 | 
			
		||||
    ENTRY0,    RET0    are for frameless functions (no locals, no calls).
 | 
			
		||||
 | 
			
		||||
  where size = size of stack frame in bytes (must be >0 and aligned to 16).
 | 
			
		||||
  For framed functions the frame is created and the return address saved at
 | 
			
		||||
  base of frame (Call0 ABI) or as determined by hardware (Windowed ABI).
 | 
			
		||||
  For frameless functions, there is no frame and return address remains in a0.
 | 
			
		||||
  Note: Because CPP macros expand to a single line, macros requiring multi-line 
 | 
			
		||||
  expansions are implemented as assembler macros.
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifdef __ASSEMBLER__
 | 
			
		||||
#ifdef __XTENSA_CALL0_ABI__
 | 
			
		||||
  /* Call0 */
 | 
			
		||||
  #define ENTRY(sz)     entry1  sz
 | 
			
		||||
    .macro  entry1 size=0x10
 | 
			
		||||
    addi    sp, sp, -\size
 | 
			
		||||
    s32i    a0, sp, 0
 | 
			
		||||
    .endm
 | 
			
		||||
  #define ENTRY0      
 | 
			
		||||
  #define RET(sz)       ret1    sz
 | 
			
		||||
    .macro  ret1 size=0x10
 | 
			
		||||
    l32i    a0, sp, 0
 | 
			
		||||
    addi    sp, sp, \size
 | 
			
		||||
    ret
 | 
			
		||||
    .endm
 | 
			
		||||
  #define RET0          ret
 | 
			
		||||
#else
 | 
			
		||||
  /* Windowed */
 | 
			
		||||
  #define ENTRY(sz)     entry   sp, sz
 | 
			
		||||
  #define ENTRY0        entry   sp, 0x10
 | 
			
		||||
  #define RET(sz)       retw
 | 
			
		||||
  #define RET0          retw
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* XTENSA_CONTEXT_H */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1056
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/port.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1056
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/port.c
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1368
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/portasm.S
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1368
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/portasm.S
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										234
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/portmux_impl.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										234
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/portmux_impl.h
									
									
									
									
										vendored
									
									
								
							@ -1,117 +1,117 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  Copyright (C) 2016-2017 Espressif Shanghai PTE LTD
 | 
			
		||||
 *  Copyright (C) 2015 Real Time Engineers Ltd.
 | 
			
		||||
 *
 | 
			
		||||
 *  All rights reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  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
 | 
			
		||||
 *  Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 *
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 *  >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
 *  >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
 *  >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
 *  >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 *
 | 
			
		||||
 *  FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 *  FOR A PARTICULAR PURPOSE.  Full license text is available on the following
 | 
			
		||||
 *  link: https://www.FreeRTOS.org/a00114.html
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* This header exists for performance reasons, in order to inline the
 | 
			
		||||
 * implementation of vPortCPUAcquireMutexIntsDisabled and
 | 
			
		||||
 * vPortCPUReleaseMutexIntsDisabled into the
 | 
			
		||||
 * vTaskEnterCritical/vTaskExitCritical functions in task.c as well as the
 | 
			
		||||
 * vPortCPUAcquireMutex/vPortCPUReleaseMutex implementations.
 | 
			
		||||
 *
 | 
			
		||||
 * Normally this kind of performance hack is over the top, but
 | 
			
		||||
 * vTaskEnterCritical/vTaskExitCritical is called a great
 | 
			
		||||
 * deal by FreeRTOS internals.
 | 
			
		||||
 *
 | 
			
		||||
 * 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
 | 
			
		||||
 * generator template of sorts. When no external memory is used, this
 | 
			
		||||
 * template is only used to generate the vPortCPUAcquireMutexIntsDisabledInternal
 | 
			
		||||
 * and vPortCPUReleaseMutexIntsDisabledInternal functions, which use S32C1 to
 | 
			
		||||
 * do an atomic compare & swap. When external memory is used the functions
 | 
			
		||||
 * vPortCPUAcquireMutexIntsDisabledExtram and vPortCPUReleaseMutexIntsDisabledExtram
 | 
			
		||||
 * are also generated, which use uxPortCompareSetExtram to fake the S32C1 instruction.
 | 
			
		||||
 * The wrapper functions vPortCPUAcquireMutexIntsDisabled and
 | 
			
		||||
 * vPortCPUReleaseMutexIntsDisabled will then use the appropriate function to do the
 | 
			
		||||
 * actual lock/unlock.
 | 
			
		||||
 */
 | 
			
		||||
#include "soc/cpu.h"
 | 
			
		||||
#include "portable.h"
 | 
			
		||||
 | 
			
		||||
/* XOR one core ID with this value to get the other core ID */
 | 
			
		||||
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
#define CORE_ID_XOR_SWAP    ( CORE_ID_PRO ^ CORE_ID_APP )
 | 
			
		||||
#else
 | 
			
		||||
#define CORE_ID_REGVAL_XOR_SWAP (CORE_ID_REGVAL_PRO ^ CORE_ID_REGVAL_APP)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*Define the mux routines for use with muxes in internal RAM */
 | 
			
		||||
#define PORTMUX_AQUIRE_MUX_FN_NAME     vPortCPUAcquireMutexIntsDisabledInternal
 | 
			
		||||
#define PORTMUX_RELEASE_MUX_FN_NAME    vPortCPUReleaseMutexIntsDisabledInternal
 | 
			
		||||
#define PORTMUX_COMPARE_SET_FN_NAME    uxPortCompareSet
 | 
			
		||||
#include "portmux_impl.inc.h"
 | 
			
		||||
#undef PORTMUX_AQUIRE_MUX_FN_NAME
 | 
			
		||||
#undef PORTMUX_RELEASE_MUX_FN_NAME
 | 
			
		||||
#undef PORTMUX_COMPARE_SET_FN_NAME
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined( CONFIG_SPIRAM_SUPPORT )
 | 
			
		||||
 | 
			
		||||
    #define PORTMUX_AQUIRE_MUX_FN_NAME     vPortCPUAcquireMutexIntsDisabledExtram
 | 
			
		||||
    #define PORTMUX_RELEASE_MUX_FN_NAME    vPortCPUReleaseMutexIntsDisabledExtram
 | 
			
		||||
    #define PORTMUX_COMPARE_SET_FN_NAME    uxPortCompareSetExtram
 | 
			
		||||
    #include "portmux_impl.inc.h"
 | 
			
		||||
    #undef PORTMUX_AQUIRE_MUX_FN_NAME
 | 
			
		||||
    #undef PORTMUX_RELEASE_MUX_FN_NAME
 | 
			
		||||
    #undef PORTMUX_COMPARE_SET_FN_NAME
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
    #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_AQUIRE_MUX_FN_CALL_ARGS( x )     x, timeout_cycles, fnName, line
 | 
			
		||||
    #define PORTMUX_RELEASE_MUX_FN_CALL_ARGS( x )    x, fnName, line
 | 
			
		||||
#else
 | 
			
		||||
    #define PORTMUX_AQUIRE_MUX_FN_ARGS     portMUX_TYPE * mux, int timeout_cycles
 | 
			
		||||
    #define PORTMUX_RELEASE_MUX_FN_ARGS    portMUX_TYPE * mux
 | 
			
		||||
    #define PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( x )     x, timeout_cycles
 | 
			
		||||
    #define PORTMUX_RELEASE_MUX_FN_CALL_ARGS( x )    x
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline bool __attribute__( ( always_inline ) ) vPortCPUAcquireMutexIntsDisabled( PORTMUX_AQUIRE_MUX_FN_ARGS )
 | 
			
		||||
{
 | 
			
		||||
    #if defined( CONFIG_SPIRAM_SUPPORT )
 | 
			
		||||
        if( esp_ptr_external_ram( mux ) )
 | 
			
		||||
        {
 | 
			
		||||
            return vPortCPUAcquireMutexIntsDisabledExtram( PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( mux ) );
 | 
			
		||||
        }
 | 
			
		||||
    #endif
 | 
			
		||||
    return vPortCPUAcquireMutexIntsDisabledInternal( PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( mux ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline void vPortCPUReleaseMutexIntsDisabled( PORTMUX_RELEASE_MUX_FN_ARGS )
 | 
			
		||||
{
 | 
			
		||||
    #if defined( CONFIG_SPIRAM_SUPPORT )
 | 
			
		||||
        if( esp_ptr_external_ram( mux ) )
 | 
			
		||||
        {
 | 
			
		||||
            vPortCPUReleaseMutexIntsDisabledExtram( PORTMUX_RELEASE_MUX_FN_CALL_ARGS( mux ) );
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    #endif
 | 
			
		||||
    vPortCPUReleaseMutexIntsDisabledInternal( PORTMUX_RELEASE_MUX_FN_CALL_ARGS( mux ) );
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
 *  Copyright (C) 2016-2017 Espressif Shanghai PTE LTD
 | 
			
		||||
 *  Copyright (C) 2015 Real Time Engineers Ltd.
 | 
			
		||||
 *
 | 
			
		||||
 *  All rights reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  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
 | 
			
		||||
 *  Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 *
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 *  >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
 *  >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
 *  >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
 *  >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 *
 | 
			
		||||
 *  FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 *  FOR A PARTICULAR PURPOSE.  Full license text is available on the following
 | 
			
		||||
 *  link: https://www.FreeRTOS.org/a00114.html
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* This header exists for performance reasons, in order to inline the
 | 
			
		||||
 * implementation of vPortCPUAcquireMutexIntsDisabled and
 | 
			
		||||
 * vPortCPUReleaseMutexIntsDisabled into the
 | 
			
		||||
 * vTaskEnterCritical/vTaskExitCritical functions in task.c as well as the
 | 
			
		||||
 * vPortCPUAcquireMutex/vPortCPUReleaseMutex implementations.
 | 
			
		||||
 *
 | 
			
		||||
 * Normally this kind of performance hack is over the top, but
 | 
			
		||||
 * vTaskEnterCritical/vTaskExitCritical is called a great
 | 
			
		||||
 * deal by FreeRTOS internals.
 | 
			
		||||
 *
 | 
			
		||||
 * 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
 | 
			
		||||
 * generator template of sorts. When no external memory is used, this
 | 
			
		||||
 * template is only used to generate the vPortCPUAcquireMutexIntsDisabledInternal
 | 
			
		||||
 * and vPortCPUReleaseMutexIntsDisabledInternal functions, which use S32C1 to
 | 
			
		||||
 * do an atomic compare & swap. When external memory is used the functions
 | 
			
		||||
 * vPortCPUAcquireMutexIntsDisabledExtram and vPortCPUReleaseMutexIntsDisabledExtram
 | 
			
		||||
 * are also generated, which use uxPortCompareSetExtram to fake the S32C1 instruction.
 | 
			
		||||
 * The wrapper functions vPortCPUAcquireMutexIntsDisabled and
 | 
			
		||||
 * vPortCPUReleaseMutexIntsDisabled will then use the appropriate function to do the
 | 
			
		||||
 * actual lock/unlock.
 | 
			
		||||
 */
 | 
			
		||||
#include "soc/cpu.h"
 | 
			
		||||
#include "portable.h"
 | 
			
		||||
 | 
			
		||||
/* XOR one core ID with this value to get the other core ID */
 | 
			
		||||
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
#define CORE_ID_XOR_SWAP    ( CORE_ID_PRO ^ CORE_ID_APP )
 | 
			
		||||
#else
 | 
			
		||||
#define CORE_ID_REGVAL_XOR_SWAP (CORE_ID_REGVAL_PRO ^ CORE_ID_REGVAL_APP)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*Define the mux routines for use with muxes in internal RAM */
 | 
			
		||||
#define PORTMUX_AQUIRE_MUX_FN_NAME     vPortCPUAcquireMutexIntsDisabledInternal
 | 
			
		||||
#define PORTMUX_RELEASE_MUX_FN_NAME    vPortCPUReleaseMutexIntsDisabledInternal
 | 
			
		||||
#define PORTMUX_COMPARE_SET_FN_NAME    uxPortCompareSet
 | 
			
		||||
#include "portmux_impl.inc.h"
 | 
			
		||||
#undef PORTMUX_AQUIRE_MUX_FN_NAME
 | 
			
		||||
#undef PORTMUX_RELEASE_MUX_FN_NAME
 | 
			
		||||
#undef PORTMUX_COMPARE_SET_FN_NAME
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined( CONFIG_SPIRAM_SUPPORT )
 | 
			
		||||
 | 
			
		||||
    #define PORTMUX_AQUIRE_MUX_FN_NAME     vPortCPUAcquireMutexIntsDisabledExtram
 | 
			
		||||
    #define PORTMUX_RELEASE_MUX_FN_NAME    vPortCPUReleaseMutexIntsDisabledExtram
 | 
			
		||||
    #define PORTMUX_COMPARE_SET_FN_NAME    uxPortCompareSetExtram
 | 
			
		||||
    #include "portmux_impl.inc.h"
 | 
			
		||||
    #undef PORTMUX_AQUIRE_MUX_FN_NAME
 | 
			
		||||
    #undef PORTMUX_RELEASE_MUX_FN_NAME
 | 
			
		||||
    #undef PORTMUX_COMPARE_SET_FN_NAME
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
    #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_AQUIRE_MUX_FN_CALL_ARGS( x )     x, timeout_cycles, fnName, line
 | 
			
		||||
    #define PORTMUX_RELEASE_MUX_FN_CALL_ARGS( x )    x, fnName, line
 | 
			
		||||
#else
 | 
			
		||||
    #define PORTMUX_AQUIRE_MUX_FN_ARGS     portMUX_TYPE * mux, int timeout_cycles
 | 
			
		||||
    #define PORTMUX_RELEASE_MUX_FN_ARGS    portMUX_TYPE * mux
 | 
			
		||||
    #define PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( x )     x, timeout_cycles
 | 
			
		||||
    #define PORTMUX_RELEASE_MUX_FN_CALL_ARGS( x )    x
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline bool __attribute__( ( always_inline ) ) vPortCPUAcquireMutexIntsDisabled( PORTMUX_AQUIRE_MUX_FN_ARGS )
 | 
			
		||||
{
 | 
			
		||||
    #if defined( CONFIG_SPIRAM_SUPPORT )
 | 
			
		||||
        if( esp_ptr_external_ram( mux ) )
 | 
			
		||||
        {
 | 
			
		||||
            return vPortCPUAcquireMutexIntsDisabledExtram( PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( mux ) );
 | 
			
		||||
        }
 | 
			
		||||
    #endif
 | 
			
		||||
    return vPortCPUAcquireMutexIntsDisabledInternal( PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( mux ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline void vPortCPUReleaseMutexIntsDisabled( PORTMUX_RELEASE_MUX_FN_ARGS )
 | 
			
		||||
{
 | 
			
		||||
    #if defined( CONFIG_SPIRAM_SUPPORT )
 | 
			
		||||
        if( esp_ptr_external_ram( mux ) )
 | 
			
		||||
        {
 | 
			
		||||
            vPortCPUReleaseMutexIntsDisabledExtram( PORTMUX_RELEASE_MUX_FN_CALL_ARGS( mux ) );
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    #endif
 | 
			
		||||
    vPortCPUReleaseMutexIntsDisabledInternal( PORTMUX_RELEASE_MUX_FN_CALL_ARGS( mux ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,212 +1,212 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  Copyright (C) 2016-2017 Espressif Shanghai PTE LTD
 | 
			
		||||
 *  Copyright (C) 2015 Real Time Engineers Ltd.
 | 
			
		||||
 *
 | 
			
		||||
 *  All rights reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  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
 | 
			
		||||
 *  Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 *
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 *  >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
 *  >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
 *  >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
 *  >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 *
 | 
			
		||||
 *  FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 *  FOR A PARTICULAR PURPOSE.  Full license text is available on the following
 | 
			
		||||
 *  link: https://www.FreeRTOS.org/a00114.html
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Warning: funky preprocessor hackery ahead. Including these headers will generate two
 | 
			
		||||
 * 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
 | 
			
		||||
 * 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
 | 
			
		||||
 * 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
 | 
			
		||||
 * (in internal ram) to fake a compare&exchange on a variable in external memory.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline bool __attribute__( ( always_inline ) )
 | 
			
		||||
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
    PORTMUX_AQUIRE_MUX_FN_NAME( portMUX_TYPE * mux,
 | 
			
		||||
                                int timeout_cycles,
 | 
			
		||||
                                const char * fnName,
 | 
			
		||||
                                int line )
 | 
			
		||||
    {
 | 
			
		||||
#else
 | 
			
		||||
    PORTMUX_AQUIRE_MUX_FN_NAME( portMUX_TYPE * mux, int timeout_cycles )
 | 
			
		||||
    {
 | 
			
		||||
        #endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        #if !CONFIG_FREERTOS_UNICORE
 | 
			
		||||
            uint32_t res;
 | 
			
		||||
            portBASE_TYPE coreID, otherCoreID;
 | 
			
		||||
            uint32_t ccount_start;
 | 
			
		||||
            bool set_timeout = timeout_cycles > portMUX_NO_TIMEOUT;
 | 
			
		||||
            #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
                if( !set_timeout )
 | 
			
		||||
                {
 | 
			
		||||
                    timeout_cycles = 10000; /* Always set a timeout in debug mode */
 | 
			
		||||
                    set_timeout = true;
 | 
			
		||||
                }
 | 
			
		||||
            #endif
 | 
			
		||||
 | 
			
		||||
            if( set_timeout ) /* Timeout */
 | 
			
		||||
            {
 | 
			
		||||
                RSR( CCOUNT, ccount_start );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
                uint32_t owner = mux->owner;
 | 
			
		||||
 | 
			
		||||
                #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
                if( ( owner != portMUX_FREE_VAL ) && ( owner != CORE_ID_PRO ) && ( owner != CORE_ID_APP ) )
 | 
			
		||||
                #else
 | 
			
		||||
                if (owner != portMUX_FREE_VAL && owner != CORE_ID_REGVAL_PRO && owner != CORE_ID_REGVAL_APP)
 | 
			
		||||
                #endif
 | 
			
		||||
                {
 | 
			
		||||
                    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;
 | 
			
		||||
                }
 | 
			
		||||
            #endif
 | 
			
		||||
 | 
			
		||||
            /* Spin until we own the core */
 | 
			
		||||
 | 
			
		||||
            RSR( PRID, coreID );
 | 
			
		||||
 | 
			
		||||
            /* Note: coreID is the full 32 bit core ID (CORE_ID_PRO/CORE_ID_APP),
 | 
			
		||||
             * not the 0/1 value returned by xPortGetCoreID()
 | 
			
		||||
             */
 | 
			
		||||
            #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
            otherCoreID = CORE_ID_XOR_SWAP ^ coreID;
 | 
			
		||||
            #else
 | 
			
		||||
            otherCoreID = CORE_ID_REGVAL_XOR_SWAP ^ coreID;
 | 
			
		||||
            #endif
 | 
			
		||||
 | 
			
		||||
            do
 | 
			
		||||
            {
 | 
			
		||||
                /* mux->owner should be one of portMUX_FREE_VAL, CORE_ID_PRO,
 | 
			
		||||
                 * CORE_ID_APP:
 | 
			
		||||
                 *
 | 
			
		||||
                 * - If portMUX_FREE_VAL, we want to atomically set to 'coreID'.
 | 
			
		||||
                 * - If "our" coreID, we can drop through immediately.
 | 
			
		||||
                 * - If "otherCoreID", we spin here.
 | 
			
		||||
                 */
 | 
			
		||||
                res = coreID;
 | 
			
		||||
                PORTMUX_COMPARE_SET_FN_NAME( &mux->owner, portMUX_FREE_VAL, &res );
 | 
			
		||||
 | 
			
		||||
                if( res != otherCoreID )
 | 
			
		||||
                {
 | 
			
		||||
                    break; /* mux->owner is "our" coreID */
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if( set_timeout )
 | 
			
		||||
                {
 | 
			
		||||
                    uint32_t ccount_now;
 | 
			
		||||
                    RSR( CCOUNT, ccount_now );
 | 
			
		||||
 | 
			
		||||
                    if( ccount_now - ccount_start > ( unsigned ) timeout_cycles )
 | 
			
		||||
                    {
 | 
			
		||||
                        #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( "Owner 0x%x count %d\n", mux->owner, mux->count );
 | 
			
		||||
                        #endif
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } while( 1 );
 | 
			
		||||
 | 
			
		||||
            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( mux->count < 0xFF );                                  /* Bad count value implies memory corruption */
 | 
			
		||||
 | 
			
		||||
            /* now we own it, we can increment the refcount */
 | 
			
		||||
            mux->count++;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
                if( res == portMUX_FREE_VAL ) /*initial lock */
 | 
			
		||||
                {
 | 
			
		||||
                    mux->lastLockedFn = fnName;
 | 
			
		||||
                    mux->lastLockedLine = line;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    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 );
 | 
			
		||||
                }
 | 
			
		||||
            #endif /* CONFIG_FREERTOS_PORTMUX_DEBUG */
 | 
			
		||||
        #endif /* CONFIG_FREERTOS_UNICORE */
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
        static inline void PORTMUX_RELEASE_MUX_FN_NAME( portMUX_TYPE * mux,
 | 
			
		||||
                                                        const char * fnName,
 | 
			
		||||
                                                        int line )
 | 
			
		||||
        {
 | 
			
		||||
#else
 | 
			
		||||
        static inline void PORTMUX_RELEASE_MUX_FN_NAME( portMUX_TYPE * mux )
 | 
			
		||||
        {
 | 
			
		||||
            #endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            #if !CONFIG_FREERTOS_UNICORE
 | 
			
		||||
                portBASE_TYPE coreID;
 | 
			
		||||
                #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
                    const char * lastLockedFn = mux->lastLockedFn;
 | 
			
		||||
                    int lastLockedLine = mux->lastLockedLine;
 | 
			
		||||
                    mux->lastLockedFn = fnName;
 | 
			
		||||
                    mux->lastLockedLine = line;
 | 
			
		||||
                    uint32_t owner = mux->owner;
 | 
			
		||||
 | 
			
		||||
                    #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
                    if( ( owner != portMUX_FREE_VAL ) && ( owner != CORE_ID_PRO ) && ( owner != CORE_ID_APP ) )
 | 
			
		||||
                    #else
 | 
			
		||||
                    if (owner != portMUX_FREE_VAL && owner != CORE_ID_REGVAL_PRO && owner != CORE_ID_REGVAL_APP)
 | 
			
		||||
                    #endif
 | 
			
		||||
                    {
 | 
			
		||||
                        ets_printf( "ERROR: vPortCPUReleaseMutex: mux %p is invalid (0x%x)!\n", mux, mux->owner );
 | 
			
		||||
                    }
 | 
			
		||||
                #endif /* ifdef CONFIG_FREERTOS_PORTMUX_DEBUG */
 | 
			
		||||
 | 
			
		||||
                #if CONFIG_FREERTOS_PORTMUX_DEBUG || !defined( NDEBUG )
 | 
			
		||||
                    RSR( PRID, coreID );
 | 
			
		||||
                #endif
 | 
			
		||||
 | 
			
		||||
                #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
                    if( coreID != mux->owner )
 | 
			
		||||
                    {
 | 
			
		||||
                        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 );
 | 
			
		||||
                    }
 | 
			
		||||
                #endif
 | 
			
		||||
 | 
			
		||||
                assert( coreID == mux->owner ); /* This is a mutex we didn't lock, or it's corrupt */
 | 
			
		||||
 | 
			
		||||
                mux->count--;
 | 
			
		||||
 | 
			
		||||
                if( mux->count == 0 )
 | 
			
		||||
                {
 | 
			
		||||
                    mux->owner = portMUX_FREE_VAL;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    assert( mux->count < 0x100 ); /* Indicates memory corruption */
 | 
			
		||||
                    #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 );
 | 
			
		||||
                    #endif
 | 
			
		||||
                }
 | 
			
		||||
            #endif //!CONFIG_FREERTOS_UNICORE
 | 
			
		||||
        }
 | 
			
		||||
/*
 | 
			
		||||
 *  Copyright (C) 2016-2017 Espressif Shanghai PTE LTD
 | 
			
		||||
 *  Copyright (C) 2015 Real Time Engineers Ltd.
 | 
			
		||||
 *
 | 
			
		||||
 *  All rights reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  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
 | 
			
		||||
 *  Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 *
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 *  >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
 *  >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
 *  >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
 *  >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 *
 | 
			
		||||
 *  FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 *  FOR A PARTICULAR PURPOSE.  Full license text is available on the following
 | 
			
		||||
 *  link: https://www.FreeRTOS.org/a00114.html
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Warning: funky preprocessor hackery ahead. Including these headers will generate two
 | 
			
		||||
 * 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
 | 
			
		||||
 * 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
 | 
			
		||||
 * 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
 | 
			
		||||
 * (in internal ram) to fake a compare&exchange on a variable in external memory.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline bool __attribute__( ( always_inline ) )
 | 
			
		||||
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
    PORTMUX_AQUIRE_MUX_FN_NAME( portMUX_TYPE * mux,
 | 
			
		||||
                                int timeout_cycles,
 | 
			
		||||
                                const char * fnName,
 | 
			
		||||
                                int line )
 | 
			
		||||
    {
 | 
			
		||||
#else
 | 
			
		||||
    PORTMUX_AQUIRE_MUX_FN_NAME( portMUX_TYPE * mux, int timeout_cycles )
 | 
			
		||||
    {
 | 
			
		||||
        #endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        #if !CONFIG_FREERTOS_UNICORE
 | 
			
		||||
            uint32_t res;
 | 
			
		||||
            portBASE_TYPE coreID, otherCoreID;
 | 
			
		||||
            uint32_t ccount_start;
 | 
			
		||||
            bool set_timeout = timeout_cycles > portMUX_NO_TIMEOUT;
 | 
			
		||||
            #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
                if( !set_timeout )
 | 
			
		||||
                {
 | 
			
		||||
                    timeout_cycles = 10000; /* Always set a timeout in debug mode */
 | 
			
		||||
                    set_timeout = true;
 | 
			
		||||
                }
 | 
			
		||||
            #endif
 | 
			
		||||
 | 
			
		||||
            if( set_timeout ) /* Timeout */
 | 
			
		||||
            {
 | 
			
		||||
                RSR( CCOUNT, ccount_start );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
                uint32_t owner = mux->owner;
 | 
			
		||||
 | 
			
		||||
                #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
                if( ( owner != portMUX_FREE_VAL ) && ( owner != CORE_ID_PRO ) && ( owner != CORE_ID_APP ) )
 | 
			
		||||
                #else
 | 
			
		||||
                if (owner != portMUX_FREE_VAL && owner != CORE_ID_REGVAL_PRO && owner != CORE_ID_REGVAL_APP)
 | 
			
		||||
                #endif
 | 
			
		||||
                {
 | 
			
		||||
                    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;
 | 
			
		||||
                }
 | 
			
		||||
            #endif
 | 
			
		||||
 | 
			
		||||
            /* Spin until we own the core */
 | 
			
		||||
 | 
			
		||||
            RSR( PRID, coreID );
 | 
			
		||||
 | 
			
		||||
            /* Note: coreID is the full 32 bit core ID (CORE_ID_PRO/CORE_ID_APP),
 | 
			
		||||
             * not the 0/1 value returned by xPortGetCoreID()
 | 
			
		||||
             */
 | 
			
		||||
            #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
            otherCoreID = CORE_ID_XOR_SWAP ^ coreID;
 | 
			
		||||
            #else
 | 
			
		||||
            otherCoreID = CORE_ID_REGVAL_XOR_SWAP ^ coreID;
 | 
			
		||||
            #endif
 | 
			
		||||
 | 
			
		||||
            do
 | 
			
		||||
            {
 | 
			
		||||
                /* mux->owner should be one of portMUX_FREE_VAL, CORE_ID_PRO,
 | 
			
		||||
                 * CORE_ID_APP:
 | 
			
		||||
                 *
 | 
			
		||||
                 * - If portMUX_FREE_VAL, we want to atomically set to 'coreID'.
 | 
			
		||||
                 * - If "our" coreID, we can drop through immediately.
 | 
			
		||||
                 * - If "otherCoreID", we spin here.
 | 
			
		||||
                 */
 | 
			
		||||
                res = coreID;
 | 
			
		||||
                PORTMUX_COMPARE_SET_FN_NAME( &mux->owner, portMUX_FREE_VAL, &res );
 | 
			
		||||
 | 
			
		||||
                if( res != otherCoreID )
 | 
			
		||||
                {
 | 
			
		||||
                    break; /* mux->owner is "our" coreID */
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if( set_timeout )
 | 
			
		||||
                {
 | 
			
		||||
                    uint32_t ccount_now;
 | 
			
		||||
                    RSR( CCOUNT, ccount_now );
 | 
			
		||||
 | 
			
		||||
                    if( ccount_now - ccount_start > ( unsigned ) timeout_cycles )
 | 
			
		||||
                    {
 | 
			
		||||
                        #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( "Owner 0x%x count %d\n", mux->owner, mux->count );
 | 
			
		||||
                        #endif
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } while( 1 );
 | 
			
		||||
 | 
			
		||||
            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( mux->count < 0xFF );                                  /* Bad count value implies memory corruption */
 | 
			
		||||
 | 
			
		||||
            /* now we own it, we can increment the refcount */
 | 
			
		||||
            mux->count++;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
                if( res == portMUX_FREE_VAL ) /*initial lock */
 | 
			
		||||
                {
 | 
			
		||||
                    mux->lastLockedFn = fnName;
 | 
			
		||||
                    mux->lastLockedLine = line;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    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 );
 | 
			
		||||
                }
 | 
			
		||||
            #endif /* CONFIG_FREERTOS_PORTMUX_DEBUG */
 | 
			
		||||
        #endif /* CONFIG_FREERTOS_UNICORE */
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
        static inline void PORTMUX_RELEASE_MUX_FN_NAME( portMUX_TYPE * mux,
 | 
			
		||||
                                                        const char * fnName,
 | 
			
		||||
                                                        int line )
 | 
			
		||||
        {
 | 
			
		||||
#else
 | 
			
		||||
        static inline void PORTMUX_RELEASE_MUX_FN_NAME( portMUX_TYPE * mux )
 | 
			
		||||
        {
 | 
			
		||||
            #endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            #if !CONFIG_FREERTOS_UNICORE
 | 
			
		||||
                portBASE_TYPE coreID;
 | 
			
		||||
                #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
                    const char * lastLockedFn = mux->lastLockedFn;
 | 
			
		||||
                    int lastLockedLine = mux->lastLockedLine;
 | 
			
		||||
                    mux->lastLockedFn = fnName;
 | 
			
		||||
                    mux->lastLockedLine = line;
 | 
			
		||||
                    uint32_t owner = mux->owner;
 | 
			
		||||
 | 
			
		||||
                    #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
                    if( ( owner != portMUX_FREE_VAL ) && ( owner != CORE_ID_PRO ) && ( owner != CORE_ID_APP ) )
 | 
			
		||||
                    #else
 | 
			
		||||
                    if (owner != portMUX_FREE_VAL && owner != CORE_ID_REGVAL_PRO && owner != CORE_ID_REGVAL_APP)
 | 
			
		||||
                    #endif
 | 
			
		||||
                    {
 | 
			
		||||
                        ets_printf( "ERROR: vPortCPUReleaseMutex: mux %p is invalid (0x%x)!\n", mux, mux->owner );
 | 
			
		||||
                    }
 | 
			
		||||
                #endif /* ifdef CONFIG_FREERTOS_PORTMUX_DEBUG */
 | 
			
		||||
 | 
			
		||||
                #if CONFIG_FREERTOS_PORTMUX_DEBUG || !defined( NDEBUG )
 | 
			
		||||
                    RSR( PRID, coreID );
 | 
			
		||||
                #endif
 | 
			
		||||
 | 
			
		||||
                #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
 | 
			
		||||
                    if( coreID != mux->owner )
 | 
			
		||||
                    {
 | 
			
		||||
                        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 );
 | 
			
		||||
                    }
 | 
			
		||||
                #endif
 | 
			
		||||
 | 
			
		||||
                assert( coreID == mux->owner ); /* This is a mutex we didn't lock, or it's corrupt */
 | 
			
		||||
 | 
			
		||||
                mux->count--;
 | 
			
		||||
 | 
			
		||||
                if( mux->count == 0 )
 | 
			
		||||
                {
 | 
			
		||||
                    mux->owner = portMUX_FREE_VAL;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    assert( mux->count < 0x100 ); /* Indicates memory corruption */
 | 
			
		||||
                    #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 );
 | 
			
		||||
                    #endif
 | 
			
		||||
                }
 | 
			
		||||
            #endif //!CONFIG_FREERTOS_UNICORE
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1406
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/xtensa_context.S
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1406
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/xtensa_context.S
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										126
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/xtensa_init.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										126
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/xtensa_init.c
									
									
									
									
										vendored
									
									
								
							@ -1,63 +1,63 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
*  // Copyright (c) 2003-2015 Cadence Design Systems, Inc.
 | 
			
		||||
*  //
 | 
			
		||||
*  // Permission is hereby granted, free of charge, to any person obtaining
 | 
			
		||||
*  // a copy of this software and associated documentation files (the
 | 
			
		||||
*  // "Software"), to deal in the Software without restriction, including
 | 
			
		||||
*  // without limitation the rights to use, copy, modify, merge, publish,
 | 
			
		||||
*  // distribute, sublicense, and/or sell copies of the Software, and to
 | 
			
		||||
*  // permit persons to whom the Software is furnished to do so, subject to
 | 
			
		||||
*  // the following conditions:
 | 
			
		||||
*  //
 | 
			
		||||
*  // The above copyright notice and this permission notice shall be included
 | 
			
		||||
*  // in all copies or substantial portions of the Software.
 | 
			
		||||
*  //
 | 
			
		||||
*  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
*  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
*  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
			
		||||
*  // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
			
		||||
*  // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
			
		||||
*  // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
			
		||||
*  // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
*  --------------------------------------------------------------------------------
 | 
			
		||||
*
 | 
			
		||||
*       XTENSA INITIALIZATION ROUTINES CODED IN C
 | 
			
		||||
*
 | 
			
		||||
*  This file contains miscellaneous Xtensa RTOS-generic initialization functions
 | 
			
		||||
*  that are implemented in C.
 | 
			
		||||
*
 | 
			
		||||
*******************************************************************************/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef XT_BOARD
 | 
			
		||||
    #include    <xtensa/xtbsp.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include    "xtensa_rtos.h"
 | 
			
		||||
#include "esp_idf_version.h"
 | 
			
		||||
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
#include    "esp_clk.h"
 | 
			
		||||
#else
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S2
 | 
			
		||||
#include    "esp32s2/clk.h"
 | 
			
		||||
#elif CONFIG_IDF_TARGET_ESP32
 | 
			
		||||
#include    "esp32/clk.h"
 | 
			
		||||
#endif
 | 
			
		||||
#endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0) */
 | 
			
		||||
 | 
			
		||||
#ifdef XT_RTOS_TIMER_INT
 | 
			
		||||
 | 
			
		||||
    unsigned _xt_tick_divisor = 0; /* cached number of cycles per tick */
 | 
			
		||||
 | 
			
		||||
    void _xt_tick_divisor_init( void )
 | 
			
		||||
    {
 | 
			
		||||
        _xt_tick_divisor = esp_clk_cpu_freq() / XT_TICK_PER_SEC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
/* Deprecated, to be removed */
 | 
			
		||||
    int xt_clock_freq( void )
 | 
			
		||||
    {
 | 
			
		||||
        return esp_clk_cpu_freq();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif /* XT_RTOS_TIMER_INT */
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
*  // Copyright (c) 2003-2015 Cadence Design Systems, Inc.
 | 
			
		||||
*  //
 | 
			
		||||
*  // Permission is hereby granted, free of charge, to any person obtaining
 | 
			
		||||
*  // a copy of this software and associated documentation files (the
 | 
			
		||||
*  // "Software"), to deal in the Software without restriction, including
 | 
			
		||||
*  // without limitation the rights to use, copy, modify, merge, publish,
 | 
			
		||||
*  // distribute, sublicense, and/or sell copies of the Software, and to
 | 
			
		||||
*  // permit persons to whom the Software is furnished to do so, subject to
 | 
			
		||||
*  // the following conditions:
 | 
			
		||||
*  //
 | 
			
		||||
*  // The above copyright notice and this permission notice shall be included
 | 
			
		||||
*  // in all copies or substantial portions of the Software.
 | 
			
		||||
*  //
 | 
			
		||||
*  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
*  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
*  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
			
		||||
*  // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
			
		||||
*  // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
			
		||||
*  // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
			
		||||
*  // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
*  --------------------------------------------------------------------------------
 | 
			
		||||
*
 | 
			
		||||
*       XTENSA INITIALIZATION ROUTINES CODED IN C
 | 
			
		||||
*
 | 
			
		||||
*  This file contains miscellaneous Xtensa RTOS-generic initialization functions
 | 
			
		||||
*  that are implemented in C.
 | 
			
		||||
*
 | 
			
		||||
*******************************************************************************/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef XT_BOARD
 | 
			
		||||
    #include    <xtensa/xtbsp.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include    "xtensa_rtos.h"
 | 
			
		||||
#include "esp_idf_version.h"
 | 
			
		||||
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
#include    "esp_clk.h"
 | 
			
		||||
#else
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S2
 | 
			
		||||
#include    "esp32s2/clk.h"
 | 
			
		||||
#elif CONFIG_IDF_TARGET_ESP32
 | 
			
		||||
#include    "esp32/clk.h"
 | 
			
		||||
#endif
 | 
			
		||||
#endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0) */
 | 
			
		||||
 | 
			
		||||
#ifdef XT_RTOS_TIMER_INT
 | 
			
		||||
 | 
			
		||||
    unsigned _xt_tick_divisor = 0; /* cached number of cycles per tick */
 | 
			
		||||
 | 
			
		||||
    void _xt_tick_divisor_init( void )
 | 
			
		||||
    {
 | 
			
		||||
        _xt_tick_divisor = esp_clk_cpu_freq() / XT_TICK_PER_SEC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
/* Deprecated, to be removed */
 | 
			
		||||
    int xt_clock_freq( void )
 | 
			
		||||
    {
 | 
			
		||||
        return esp_clk_cpu_freq();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif /* XT_RTOS_TIMER_INT */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										366
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/xtensa_intr.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										366
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/xtensa_intr.c
									
									
									
									
										vendored
									
									
								
							@ -1,183 +1,183 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Copyright (c) 2006-2015 Cadence Design Systems Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining
 | 
			
		||||
 * a copy of this software and associated documentation files (the
 | 
			
		||||
 * "Software"), to deal in the Software without restriction, including
 | 
			
		||||
 * without limitation the rights to use, copy, modify, merge, publish,
 | 
			
		||||
 * distribute, sublicense, and/or sell copies of the Software, and to
 | 
			
		||||
 * permit persons to whom the Software is furnished to do so, subject to
 | 
			
		||||
 * the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included
 | 
			
		||||
 * in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
			
		||||
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
			
		||||
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
			
		||||
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
			
		||||
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
*  Xtensa-specific interrupt and exception functions for RTOS ports.
 | 
			
		||||
*  Also see xtensa_intr_asm.S.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include <xtensa/config/core.h>
 | 
			
		||||
 | 
			
		||||
#include "freertos/FreeRTOS.h"
 | 
			
		||||
#include "freertos/xtensa_api.h"
 | 
			
		||||
#include "freertos/portable.h"
 | 
			
		||||
#include "esp_idf_version.h"
 | 
			
		||||
 | 
			
		||||
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
#include "rom/ets_sys.h"
 | 
			
		||||
#else
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S2
 | 
			
		||||
#include "esp32s2/rom/ets_sys.h"
 | 
			
		||||
#elif CONFIG_IDF_TARGET_ESP32
 | 
			
		||||
#include "esp32/rom/ets_sys.h"
 | 
			
		||||
#endif
 | 
			
		||||
#endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0) */
 | 
			
		||||
 | 
			
		||||
#if XCHAL_HAVE_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
/* Handler table is in xtensa_intr_asm.S */
 | 
			
		||||
 | 
			
		||||
    extern xt_exc_handler _xt_exception_table[ XCHAL_EXCCAUSE_NUM * portNUM_PROCESSORS ];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Default handler for unhandled exceptions.
 | 
			
		||||
 * CHANGED: We do this in panic.c now
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*void xt_unhandled_exception(XtExcFrame *frame) */
 | 
			
		||||
/*{ */
 | 
			
		||||
    /*exit(-1); */
 | 
			
		||||
/*} */
 | 
			
		||||
    extern void xt_unhandled_exception( XtExcFrame * frame );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This function registers a handler for the specified exception.
 | 
			
		||||
 * The function returns the address of the previous handler.
 | 
			
		||||
 * On error, it returns 0.
 | 
			
		||||
 */
 | 
			
		||||
    xt_exc_handler xt_set_exception_handler( int n,
 | 
			
		||||
                                             xt_exc_handler f )
 | 
			
		||||
    {
 | 
			
		||||
        xt_exc_handler old;
 | 
			
		||||
 | 
			
		||||
        if( ( n < 0 ) || ( n >= XCHAL_EXCCAUSE_NUM ) )
 | 
			
		||||
        {
 | 
			
		||||
            return 0; /* invalid exception number */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Convert exception number to _xt_exception_table name */
 | 
			
		||||
        n = n * portNUM_PROCESSORS + xPortGetCoreID();
 | 
			
		||||
        old = _xt_exception_table[ n ];
 | 
			
		||||
 | 
			
		||||
        if( f )
 | 
			
		||||
        {
 | 
			
		||||
            _xt_exception_table[ n ] = f;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            _xt_exception_table[ n ] = &xt_unhandled_exception;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return( ( old == &xt_unhandled_exception ) ? 0 : old );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif /* if XCHAL_HAVE_EXCEPTIONS */
 | 
			
		||||
 | 
			
		||||
#if XCHAL_HAVE_INTERRUPTS
 | 
			
		||||
 | 
			
		||||
/* Handler table is in xtensa_intr_asm.S */
 | 
			
		||||
 | 
			
		||||
    typedef struct xt_handler_table_entry
 | 
			
		||||
    {
 | 
			
		||||
        void * handler;
 | 
			
		||||
        void * arg;
 | 
			
		||||
    } xt_handler_table_entry;
 | 
			
		||||
 | 
			
		||||
    extern xt_handler_table_entry _xt_interrupt_table[ XCHAL_NUM_INTERRUPTS * portNUM_PROCESSORS ];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Default handler for unhandled interrupts.
 | 
			
		||||
 */
 | 
			
		||||
    void xt_unhandled_interrupt( void * arg )
 | 
			
		||||
    {
 | 
			
		||||
        ets_printf( "Unhandled interrupt %d on cpu %d!\n", ( int ) arg, xPortGetCoreID() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This function registers a handler for the specified interrupt. The "arg"
 | 
			
		||||
 * parameter specifies the argument to be passed to the handler when it is
 | 
			
		||||
 * invoked. The function returns the address of the previous handler.
 | 
			
		||||
 * On error, it returns 0.
 | 
			
		||||
 */
 | 
			
		||||
    xt_handler xt_set_interrupt_handler( int n,
 | 
			
		||||
                                         xt_handler f,
 | 
			
		||||
                                         void * arg )
 | 
			
		||||
    {
 | 
			
		||||
        xt_handler_table_entry * entry;
 | 
			
		||||
        xt_handler old;
 | 
			
		||||
 | 
			
		||||
        if( ( n < 0 ) || ( n >= XCHAL_NUM_INTERRUPTS ) )
 | 
			
		||||
        {
 | 
			
		||||
            return 0; /* invalid interrupt number */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( Xthal_intlevel[ n ] > XCHAL_EXCM_LEVEL )
 | 
			
		||||
        {
 | 
			
		||||
            return 0; /* priority level too high to safely handle in C */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Convert exception number to _xt_exception_table name */
 | 
			
		||||
        n = n * portNUM_PROCESSORS + xPortGetCoreID();
 | 
			
		||||
 | 
			
		||||
        entry = _xt_interrupt_table + n;
 | 
			
		||||
        old = entry->handler;
 | 
			
		||||
 | 
			
		||||
        if( f )
 | 
			
		||||
        {
 | 
			
		||||
            entry->handler = f;
 | 
			
		||||
            entry->arg = arg;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            entry->handler = &xt_unhandled_interrupt;
 | 
			
		||||
            entry->arg = ( void * ) n;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return( ( old == &xt_unhandled_interrupt ) ? 0 : old );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #if CONFIG_SYSVIEW_ENABLE
 | 
			
		||||
        void * xt_get_interrupt_handler_arg( int n )
 | 
			
		||||
        {
 | 
			
		||||
            xt_handler_table_entry * entry;
 | 
			
		||||
 | 
			
		||||
            if( ( n < 0 ) || ( n >= XCHAL_NUM_INTERRUPTS ) )
 | 
			
		||||
            {
 | 
			
		||||
                return 0; /* invalid interrupt number */
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Convert exception number to _xt_exception_table name */
 | 
			
		||||
            n = n * portNUM_PROCESSORS + xPortGetCoreID();
 | 
			
		||||
 | 
			
		||||
            entry = _xt_interrupt_table + n;
 | 
			
		||||
            return entry->arg;
 | 
			
		||||
        }
 | 
			
		||||
    #endif /* if CONFIG_SYSVIEW_ENABLE */
 | 
			
		||||
 | 
			
		||||
#endif /* XCHAL_HAVE_INTERRUPTS */
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Copyright (c) 2006-2015 Cadence Design Systems Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining
 | 
			
		||||
 * a copy of this software and associated documentation files (the
 | 
			
		||||
 * "Software"), to deal in the Software without restriction, including
 | 
			
		||||
 * without limitation the rights to use, copy, modify, merge, publish,
 | 
			
		||||
 * distribute, sublicense, and/or sell copies of the Software, and to
 | 
			
		||||
 * permit persons to whom the Software is furnished to do so, subject to
 | 
			
		||||
 * the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included
 | 
			
		||||
 * in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
			
		||||
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
			
		||||
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
			
		||||
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
			
		||||
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
*  Xtensa-specific interrupt and exception functions for RTOS ports.
 | 
			
		||||
*  Also see xtensa_intr_asm.S.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include <xtensa/config/core.h>
 | 
			
		||||
 | 
			
		||||
#include "freertos/FreeRTOS.h"
 | 
			
		||||
#include "freertos/xtensa_api.h"
 | 
			
		||||
#include "freertos/portable.h"
 | 
			
		||||
#include "esp_idf_version.h"
 | 
			
		||||
 | 
			
		||||
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
#include "rom/ets_sys.h"
 | 
			
		||||
#else
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S2
 | 
			
		||||
#include "esp32s2/rom/ets_sys.h"
 | 
			
		||||
#elif CONFIG_IDF_TARGET_ESP32
 | 
			
		||||
#include "esp32/rom/ets_sys.h"
 | 
			
		||||
#endif
 | 
			
		||||
#endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0) */
 | 
			
		||||
 | 
			
		||||
#if XCHAL_HAVE_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
/* Handler table is in xtensa_intr_asm.S */
 | 
			
		||||
 | 
			
		||||
    extern xt_exc_handler _xt_exception_table[ XCHAL_EXCCAUSE_NUM * portNUM_PROCESSORS ];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Default handler for unhandled exceptions.
 | 
			
		||||
 * CHANGED: We do this in panic.c now
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*void xt_unhandled_exception(XtExcFrame *frame) */
 | 
			
		||||
/*{ */
 | 
			
		||||
    /*exit(-1); */
 | 
			
		||||
/*} */
 | 
			
		||||
    extern void xt_unhandled_exception( XtExcFrame * frame );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This function registers a handler for the specified exception.
 | 
			
		||||
 * The function returns the address of the previous handler.
 | 
			
		||||
 * On error, it returns 0.
 | 
			
		||||
 */
 | 
			
		||||
    xt_exc_handler xt_set_exception_handler( int n,
 | 
			
		||||
                                             xt_exc_handler f )
 | 
			
		||||
    {
 | 
			
		||||
        xt_exc_handler old;
 | 
			
		||||
 | 
			
		||||
        if( ( n < 0 ) || ( n >= XCHAL_EXCCAUSE_NUM ) )
 | 
			
		||||
        {
 | 
			
		||||
            return 0; /* invalid exception number */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Convert exception number to _xt_exception_table name */
 | 
			
		||||
        n = n * portNUM_PROCESSORS + xPortGetCoreID();
 | 
			
		||||
        old = _xt_exception_table[ n ];
 | 
			
		||||
 | 
			
		||||
        if( f )
 | 
			
		||||
        {
 | 
			
		||||
            _xt_exception_table[ n ] = f;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            _xt_exception_table[ n ] = &xt_unhandled_exception;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return( ( old == &xt_unhandled_exception ) ? 0 : old );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif /* if XCHAL_HAVE_EXCEPTIONS */
 | 
			
		||||
 | 
			
		||||
#if XCHAL_HAVE_INTERRUPTS
 | 
			
		||||
 | 
			
		||||
/* Handler table is in xtensa_intr_asm.S */
 | 
			
		||||
 | 
			
		||||
    typedef struct xt_handler_table_entry
 | 
			
		||||
    {
 | 
			
		||||
        void * handler;
 | 
			
		||||
        void * arg;
 | 
			
		||||
    } xt_handler_table_entry;
 | 
			
		||||
 | 
			
		||||
    extern xt_handler_table_entry _xt_interrupt_table[ XCHAL_NUM_INTERRUPTS * portNUM_PROCESSORS ];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Default handler for unhandled interrupts.
 | 
			
		||||
 */
 | 
			
		||||
    void xt_unhandled_interrupt( void * arg )
 | 
			
		||||
    {
 | 
			
		||||
        ets_printf( "Unhandled interrupt %d on cpu %d!\n", ( int ) arg, xPortGetCoreID() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This function registers a handler for the specified interrupt. The "arg"
 | 
			
		||||
 * parameter specifies the argument to be passed to the handler when it is
 | 
			
		||||
 * invoked. The function returns the address of the previous handler.
 | 
			
		||||
 * On error, it returns 0.
 | 
			
		||||
 */
 | 
			
		||||
    xt_handler xt_set_interrupt_handler( int n,
 | 
			
		||||
                                         xt_handler f,
 | 
			
		||||
                                         void * arg )
 | 
			
		||||
    {
 | 
			
		||||
        xt_handler_table_entry * entry;
 | 
			
		||||
        xt_handler old;
 | 
			
		||||
 | 
			
		||||
        if( ( n < 0 ) || ( n >= XCHAL_NUM_INTERRUPTS ) )
 | 
			
		||||
        {
 | 
			
		||||
            return 0; /* invalid interrupt number */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( Xthal_intlevel[ n ] > XCHAL_EXCM_LEVEL )
 | 
			
		||||
        {
 | 
			
		||||
            return 0; /* priority level too high to safely handle in C */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Convert exception number to _xt_exception_table name */
 | 
			
		||||
        n = n * portNUM_PROCESSORS + xPortGetCoreID();
 | 
			
		||||
 | 
			
		||||
        entry = _xt_interrupt_table + n;
 | 
			
		||||
        old = entry->handler;
 | 
			
		||||
 | 
			
		||||
        if( f )
 | 
			
		||||
        {
 | 
			
		||||
            entry->handler = f;
 | 
			
		||||
            entry->arg = arg;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            entry->handler = &xt_unhandled_interrupt;
 | 
			
		||||
            entry->arg = ( void * ) n;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return( ( old == &xt_unhandled_interrupt ) ? 0 : old );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #if CONFIG_SYSVIEW_ENABLE
 | 
			
		||||
        void * xt_get_interrupt_handler_arg( int n )
 | 
			
		||||
        {
 | 
			
		||||
            xt_handler_table_entry * entry;
 | 
			
		||||
 | 
			
		||||
            if( ( n < 0 ) || ( n >= XCHAL_NUM_INTERRUPTS ) )
 | 
			
		||||
            {
 | 
			
		||||
                return 0; /* invalid interrupt number */
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Convert exception number to _xt_exception_table name */
 | 
			
		||||
            n = n * portNUM_PROCESSORS + xPortGetCoreID();
 | 
			
		||||
 | 
			
		||||
            entry = _xt_interrupt_table + n;
 | 
			
		||||
            return entry->arg;
 | 
			
		||||
        }
 | 
			
		||||
    #endif /* if CONFIG_SYSVIEW_ENABLE */
 | 
			
		||||
 | 
			
		||||
#endif /* XCHAL_HAVE_INTERRUPTS */
 | 
			
		||||
 | 
			
		||||
@ -1,169 +1,169 @@
 | 
			
		||||
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
#include "xtensa_rtos.h"
 | 
			
		||||
#include "esp_idf_version.h"
 | 
			
		||||
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
#include "esp_panic.h"
 | 
			
		||||
#else
 | 
			
		||||
#include "esp_private/panic_reason.h"
 | 
			
		||||
#endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0) */
 | 
			
		||||
#include "sdkconfig.h"
 | 
			
		||||
#include "soc/soc.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
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
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if XCHAL_HAVE_DEBUG
 | 
			
		||||
    .global    xt_debugexception
 | 
			
		||||
    .weak xt_debugexception
 | 
			
		||||
    .set xt_debugexception, _xt_debugexception
 | 
			
		||||
    .section .iram1,"ax"
 | 
			
		||||
    .type       _xt_debugexception,@function
 | 
			
		||||
    .align      4
 | 
			
		||||
 | 
			
		||||
_xt_debugexception:
 | 
			
		||||
    movi    a0,PANIC_RSN_DEBUGEXCEPTION
 | 
			
		||||
    wsr     a0,EXCCAUSE
 | 
			
		||||
    /* _xt_panic assumes a level 1 exception. As we're
 | 
			
		||||
       crashing anyhow, copy EPC & EXCSAVE from DEBUGLEVEL
 | 
			
		||||
       to level 1. */
 | 
			
		||||
    rsr     a0,(EPC + XCHAL_DEBUGLEVEL)
 | 
			
		||||
    wsr     a0,EPC_1
 | 
			
		||||
    rsr     a0,(EXCSAVE + XCHAL_DEBUGLEVEL)
 | 
			
		||||
    wsr     a0,EXCSAVE_1
 | 
			
		||||
    call0   _xt_panic                       /* does not return */
 | 
			
		||||
    rfi     XCHAL_DEBUGLEVEL
 | 
			
		||||
 | 
			
		||||
#endif /* Debug exception */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if XCHAL_NUM_INTLEVELS >=2 && XCHAL_EXCM_LEVEL <2 && XCHAL_DEBUGLEVEL !=2
 | 
			
		||||
    .global    xt_highint2
 | 
			
		||||
    .weak xt_highint2
 | 
			
		||||
    .set xt_highint2, _xt_highint2
 | 
			
		||||
    .section .iram1,"ax"
 | 
			
		||||
    .type       _xt_highint2,@function
 | 
			
		||||
    .align      4
 | 
			
		||||
_xt_highint2:
 | 
			
		||||
 | 
			
		||||
    /* Default handler does nothing; just returns */
 | 
			
		||||
    .align  4
 | 
			
		||||
.L_xt_highint2_exit:
 | 
			
		||||
    rsr     a0, EXCSAVE_2                   /* restore a0 */
 | 
			
		||||
    rfi     2
 | 
			
		||||
 | 
			
		||||
#endif  /* Level 2 */
 | 
			
		||||
 | 
			
		||||
#if XCHAL_NUM_INTLEVELS >=3 && XCHAL_EXCM_LEVEL <3 && XCHAL_DEBUGLEVEL !=3
 | 
			
		||||
 | 
			
		||||
    .global    xt_highint3
 | 
			
		||||
    .weak xt_highint3
 | 
			
		||||
    .set xt_highint3, _xt_highint3
 | 
			
		||||
    .section .iram1,"ax"
 | 
			
		||||
    .type       _xt_highint3,@function
 | 
			
		||||
    .align      4
 | 
			
		||||
_xt_highint3:
 | 
			
		||||
 | 
			
		||||
    /* Default handler does nothing; just returns */
 | 
			
		||||
 | 
			
		||||
    .align  4
 | 
			
		||||
.L_xt_highint3_exit:
 | 
			
		||||
    rsr     a0, EXCSAVE_3                   /* restore a0 */
 | 
			
		||||
    rfi     3
 | 
			
		||||
 | 
			
		||||
#endif  /* Level 3 */
 | 
			
		||||
 | 
			
		||||
#if XCHAL_NUM_INTLEVELS >=4 && XCHAL_EXCM_LEVEL <4 && XCHAL_DEBUGLEVEL !=4
 | 
			
		||||
 | 
			
		||||
    .global    xt_highint4
 | 
			
		||||
    .weak xt_highint4
 | 
			
		||||
    .set xt_highint4, _xt_highint4
 | 
			
		||||
    .section .iram1,"ax"
 | 
			
		||||
    .type       _xt_highint4,@function
 | 
			
		||||
    .align      4
 | 
			
		||||
_xt_highint4:
 | 
			
		||||
 | 
			
		||||
    /* Default handler does nothing; just returns */
 | 
			
		||||
 | 
			
		||||
    .align  4
 | 
			
		||||
.L_xt_highint4_exit:
 | 
			
		||||
    rsr     a0, EXCSAVE_4                   /* restore a0 */
 | 
			
		||||
    rfi     4
 | 
			
		||||
 | 
			
		||||
#endif  /* Level 4 */
 | 
			
		||||
 | 
			
		||||
#if XCHAL_NUM_INTLEVELS >=5 && XCHAL_EXCM_LEVEL <5 && XCHAL_DEBUGLEVEL !=5
 | 
			
		||||
 | 
			
		||||
    .global    xt_highint5
 | 
			
		||||
    .weak xt_highint5
 | 
			
		||||
    .set xt_highint5, _xt_highint5
 | 
			
		||||
    .section .iram1,"ax"
 | 
			
		||||
    .type       _xt_highint5,@function
 | 
			
		||||
    .align      4
 | 
			
		||||
_xt_highint5:
 | 
			
		||||
 | 
			
		||||
    /* Default handler does nothing; just returns */
 | 
			
		||||
 | 
			
		||||
    .align  4
 | 
			
		||||
.L_xt_highint5_exit:
 | 
			
		||||
    rsr     a0, EXCSAVE_5                   /* restore a0 */
 | 
			
		||||
    rfi     5
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif  /* Level 5 */
 | 
			
		||||
 | 
			
		||||
#if XCHAL_NUM_INTLEVELS >=6 && XCHAL_EXCM_LEVEL <6 && XCHAL_DEBUGLEVEL !=6
 | 
			
		||||
 | 
			
		||||
    .global    _xt_highint6
 | 
			
		||||
    .global    xt_highint6
 | 
			
		||||
    .weak xt_highint6
 | 
			
		||||
    .set xt_highint6, _xt_highint6
 | 
			
		||||
    .section .iram1,"ax"
 | 
			
		||||
    .type       _xt_highint6,@function
 | 
			
		||||
    .align      4
 | 
			
		||||
_xt_highint6:
 | 
			
		||||
 | 
			
		||||
    /* Default handler does nothing; just returns */
 | 
			
		||||
 | 
			
		||||
    .align  4
 | 
			
		||||
.L_xt_highint6_exit:
 | 
			
		||||
    rsr     a0, EXCSAVE_6                   /* restore a0 */
 | 
			
		||||
    rfi     6
 | 
			
		||||
 | 
			
		||||
#endif  /* Level 6 */
 | 
			
		||||
 | 
			
		||||
#if XCHAL_HAVE_NMI
 | 
			
		||||
 | 
			
		||||
    .global    _xt_nmi
 | 
			
		||||
    .global    xt_nmi
 | 
			
		||||
    .weak xt_nmi
 | 
			
		||||
    .set xt_nmi, _xt_nmi
 | 
			
		||||
    .section .iram1,"ax"
 | 
			
		||||
    .type       _xt_nmi,@function
 | 
			
		||||
    .align      4
 | 
			
		||||
_xt_nmi:
 | 
			
		||||
 | 
			
		||||
    /* Default handler does nothing; just returns */
 | 
			
		||||
 | 
			
		||||
    .align  4
 | 
			
		||||
.L_xt_nmi_exit:
 | 
			
		||||
    rsr     a0, EXCSAVE + XCHAL_NMILEVEL    /* restore a0 */
 | 
			
		||||
    rfi     XCHAL_NMILEVEL
 | 
			
		||||
 | 
			
		||||
#endif  /* NMI */
 | 
			
		||||
 | 
			
		||||
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
#include "xtensa_rtos.h"
 | 
			
		||||
#include "esp_idf_version.h"
 | 
			
		||||
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
 | 
			
		||||
#include "esp_panic.h"
 | 
			
		||||
#else
 | 
			
		||||
#include "esp_private/panic_reason.h"
 | 
			
		||||
#endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0) */
 | 
			
		||||
#include "sdkconfig.h"
 | 
			
		||||
#include "soc/soc.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
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
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if XCHAL_HAVE_DEBUG
 | 
			
		||||
    .global    xt_debugexception
 | 
			
		||||
    .weak xt_debugexception
 | 
			
		||||
    .set xt_debugexception, _xt_debugexception
 | 
			
		||||
    .section .iram1,"ax"
 | 
			
		||||
    .type       _xt_debugexception,@function
 | 
			
		||||
    .align      4
 | 
			
		||||
 | 
			
		||||
_xt_debugexception:
 | 
			
		||||
    movi    a0,PANIC_RSN_DEBUGEXCEPTION
 | 
			
		||||
    wsr     a0,EXCCAUSE
 | 
			
		||||
    /* _xt_panic assumes a level 1 exception. As we're
 | 
			
		||||
       crashing anyhow, copy EPC & EXCSAVE from DEBUGLEVEL
 | 
			
		||||
       to level 1. */
 | 
			
		||||
    rsr     a0,(EPC + XCHAL_DEBUGLEVEL)
 | 
			
		||||
    wsr     a0,EPC_1
 | 
			
		||||
    rsr     a0,(EXCSAVE + XCHAL_DEBUGLEVEL)
 | 
			
		||||
    wsr     a0,EXCSAVE_1
 | 
			
		||||
    call0   _xt_panic                       /* does not return */
 | 
			
		||||
    rfi     XCHAL_DEBUGLEVEL
 | 
			
		||||
 | 
			
		||||
#endif /* Debug exception */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if XCHAL_NUM_INTLEVELS >=2 && XCHAL_EXCM_LEVEL <2 && XCHAL_DEBUGLEVEL !=2
 | 
			
		||||
    .global    xt_highint2
 | 
			
		||||
    .weak xt_highint2
 | 
			
		||||
    .set xt_highint2, _xt_highint2
 | 
			
		||||
    .section .iram1,"ax"
 | 
			
		||||
    .type       _xt_highint2,@function
 | 
			
		||||
    .align      4
 | 
			
		||||
_xt_highint2:
 | 
			
		||||
 | 
			
		||||
    /* Default handler does nothing; just returns */
 | 
			
		||||
    .align  4
 | 
			
		||||
.L_xt_highint2_exit:
 | 
			
		||||
    rsr     a0, EXCSAVE_2                   /* restore a0 */
 | 
			
		||||
    rfi     2
 | 
			
		||||
 | 
			
		||||
#endif  /* Level 2 */
 | 
			
		||||
 | 
			
		||||
#if XCHAL_NUM_INTLEVELS >=3 && XCHAL_EXCM_LEVEL <3 && XCHAL_DEBUGLEVEL !=3
 | 
			
		||||
 | 
			
		||||
    .global    xt_highint3
 | 
			
		||||
    .weak xt_highint3
 | 
			
		||||
    .set xt_highint3, _xt_highint3
 | 
			
		||||
    .section .iram1,"ax"
 | 
			
		||||
    .type       _xt_highint3,@function
 | 
			
		||||
    .align      4
 | 
			
		||||
_xt_highint3:
 | 
			
		||||
 | 
			
		||||
    /* Default handler does nothing; just returns */
 | 
			
		||||
 | 
			
		||||
    .align  4
 | 
			
		||||
.L_xt_highint3_exit:
 | 
			
		||||
    rsr     a0, EXCSAVE_3                   /* restore a0 */
 | 
			
		||||
    rfi     3
 | 
			
		||||
 | 
			
		||||
#endif  /* Level 3 */
 | 
			
		||||
 | 
			
		||||
#if XCHAL_NUM_INTLEVELS >=4 && XCHAL_EXCM_LEVEL <4 && XCHAL_DEBUGLEVEL !=4
 | 
			
		||||
 | 
			
		||||
    .global    xt_highint4
 | 
			
		||||
    .weak xt_highint4
 | 
			
		||||
    .set xt_highint4, _xt_highint4
 | 
			
		||||
    .section .iram1,"ax"
 | 
			
		||||
    .type       _xt_highint4,@function
 | 
			
		||||
    .align      4
 | 
			
		||||
_xt_highint4:
 | 
			
		||||
 | 
			
		||||
    /* Default handler does nothing; just returns */
 | 
			
		||||
 | 
			
		||||
    .align  4
 | 
			
		||||
.L_xt_highint4_exit:
 | 
			
		||||
    rsr     a0, EXCSAVE_4                   /* restore a0 */
 | 
			
		||||
    rfi     4
 | 
			
		||||
 | 
			
		||||
#endif  /* Level 4 */
 | 
			
		||||
 | 
			
		||||
#if XCHAL_NUM_INTLEVELS >=5 && XCHAL_EXCM_LEVEL <5 && XCHAL_DEBUGLEVEL !=5
 | 
			
		||||
 | 
			
		||||
    .global    xt_highint5
 | 
			
		||||
    .weak xt_highint5
 | 
			
		||||
    .set xt_highint5, _xt_highint5
 | 
			
		||||
    .section .iram1,"ax"
 | 
			
		||||
    .type       _xt_highint5,@function
 | 
			
		||||
    .align      4
 | 
			
		||||
_xt_highint5:
 | 
			
		||||
 | 
			
		||||
    /* Default handler does nothing; just returns */
 | 
			
		||||
 | 
			
		||||
    .align  4
 | 
			
		||||
.L_xt_highint5_exit:
 | 
			
		||||
    rsr     a0, EXCSAVE_5                   /* restore a0 */
 | 
			
		||||
    rfi     5
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif  /* Level 5 */
 | 
			
		||||
 | 
			
		||||
#if XCHAL_NUM_INTLEVELS >=6 && XCHAL_EXCM_LEVEL <6 && XCHAL_DEBUGLEVEL !=6
 | 
			
		||||
 | 
			
		||||
    .global    _xt_highint6
 | 
			
		||||
    .global    xt_highint6
 | 
			
		||||
    .weak xt_highint6
 | 
			
		||||
    .set xt_highint6, _xt_highint6
 | 
			
		||||
    .section .iram1,"ax"
 | 
			
		||||
    .type       _xt_highint6,@function
 | 
			
		||||
    .align      4
 | 
			
		||||
_xt_highint6:
 | 
			
		||||
 | 
			
		||||
    /* Default handler does nothing; just returns */
 | 
			
		||||
 | 
			
		||||
    .align  4
 | 
			
		||||
.L_xt_highint6_exit:
 | 
			
		||||
    rsr     a0, EXCSAVE_6                   /* restore a0 */
 | 
			
		||||
    rfi     6
 | 
			
		||||
 | 
			
		||||
#endif  /* Level 6 */
 | 
			
		||||
 | 
			
		||||
#if XCHAL_HAVE_NMI
 | 
			
		||||
 | 
			
		||||
    .global    _xt_nmi
 | 
			
		||||
    .global    xt_nmi
 | 
			
		||||
    .weak xt_nmi
 | 
			
		||||
    .set xt_nmi, _xt_nmi
 | 
			
		||||
    .section .iram1,"ax"
 | 
			
		||||
    .type       _xt_nmi,@function
 | 
			
		||||
    .align      4
 | 
			
		||||
_xt_nmi:
 | 
			
		||||
 | 
			
		||||
    /* Default handler does nothing; just returns */
 | 
			
		||||
 | 
			
		||||
    .align  4
 | 
			
		||||
.L_xt_nmi_exit:
 | 
			
		||||
    rsr     a0, EXCSAVE + XCHAL_NMILEVEL    /* restore a0 */
 | 
			
		||||
    rfi     XCHAL_NMILEVEL
 | 
			
		||||
 | 
			
		||||
#endif  /* NMI */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4114
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/xtensa_vectors.S
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4114
									
								
								portable/ThirdParty/GCC/Xtensa_ESP32/xtensa_vectors.S
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user