+++ /dev/null
-// High-Priority Interrupt Handler Template
-// $Id: //depot/rel/Cottonwood/Xtensa/OS/xtos/int-highpri-template.S#3 $
-
-// Copyright (c) 2004-2010 Tensilica 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.
-
-//
-// This file provides skeleton code for writing high-priority interrupt
-// handlers in assembler for performance.
-//
-// By default, this file is included by inth-template.S .
-// The default Makefile defines _INTERRUPT_LEVEL when assembling
-// inth-template.S for each medium and high priority interrupt level.
-//
-// To use this template file, define a macro called _INTERRUPT_LEVEL
-// to be the interrupt priority level of the vector, then include this file.
-
-
-#include <xtensa/coreasm.h>
-#include "xtos-internal.h"
-
-
-#if XCHAL_HAVE_INTERRUPTS
-
-#define INTERRUPT_MASK XCHAL_INTLEVEL_MASK(_INTERRUPT_LEVEL)
-#define SINGLE_INTERRUPT (INTERRUPT_MASK & (INTERRUPT_MASK - 1) == 0)
-#define SINGLE_INT_NUM XCHAL_INTLEVEL_NUM(_INTERRUPT_LEVEL)
-
-
-// NOTE: It is strongly recommended that high-priority
-// interrupt handlers be written in assembly.
-//
-// High-priority interrupt handlers can be written in C,
-// but only at the cost of an unreasonable amount of state
-// save and restore (including the entire physical address
-// register file and others, see int-highpri-dispatcher.S)
-// that makes high-priority interrupt dispatching much slower
-// than for low and medium priority interrupts.
-// (Low and medium priority interrupts are masked by atomic
-// register window operations, so they take advantage of a
-// coherent window state for fast entry. High priority
-// interrupts are not masked by window operations so they
-// can interrupt them, leading to a potentially incoherent
-// window state at the time of the interrupt. Given that
-// high priority handlers must save and restore everything
-// they touch, they end up needing to save and restore the
-// entire window state [physical address register file etc.]
-// and all exception state which they can also interrupt.)
-// See also the Microprocessor Programmer's Guide.
-
-// High-priority interrupts are designed to be very fast and with
-// very low latency.
-// Typical high-priority interrupt service routines are kept
-// relatively small and fast. Either there is little to do,
-// or the routine handles only the necessary high priority
-// activities related to a device and leaves the rest
-// (other more complex and time-consuming activities)
-// to be scheduled later, eg. by triggering a level-one
-// (low-priority) or medium-priority software interrupt whose
-// handler can be written in C for the more extensive processing.
-
-// NOTE: The following handler is just skeleton example
-// code. It is NOT a functional handler. For software, edge-
-// triggered and write-error interrupts, it simply does nothing
-// and return. For other types (timer and level-triggered),
-// this code does not clear the source(s) of interrupt,
-// hence if any interrupt at this priority level are both enabled
-// and triggered, the processor repeatedly takes the interrupt
-// in a loop. This is all okay as a default, because
-// XTOS (and other operating systems) clears the INTENABLE
-// register at startup, requiring the application to
-// enable specific interrupts before they can be taken.
-// So as long as you don't enable any interrupt of this
-// priority level, this example handler will never execute.
-
-// Exports
-.global LABEL(_Level,FromVector)
-
- .data
- .align 4
-LABEL(int,save):
- .space 4 // save area
-
- .text
- .align 4
-LABEL(_Level,FromVector):
- // The vectoring code has already saved a2 in EXCSAVEn.
- // Save any other registers we'll use:
- movi a2, LABEL(int,save)
- s32i a1, a2, 0
- // ... add more as needed (increase save area accordingly) ...
-
- // WRITE YOUR INTERRUPT HANDLING CODE HERE...
-
- // If multiple interrupts are mapped to this priority level,
- // you'll probably need to distinguish which interrupt(s)
- // occurred by reading the INTERRUPT (INTREAD) and
- // INTENABLE registers, and'ing them together, and
- // looking at what bits are set in both.
- // If any of the interrupts are level-triggered, be ready
- // to handle the case where no interrupts are to be handled
- // -- this is called a spurious interrupt, and can happen
- // when the level-triggered interrupt line goes inactive
- // after the interrupt is taken but before the INTERRUPT
- // register is read.
-
- // You'll also normally want to clear the source of
- // the interrupt before returning, to avoid getting
- // the same interrupt again immediately. For illustration,
- // this code clears all software, edge-triggered, and
- // write-error interrupts at this priority level (if any).
- // NOTE: Timer interrupts must be cleared by writing to
- // the corresponding CCOMPAREn register; and level-sensitive
- // interrupts can only be cleared externally, usually by
- // requesting the associated device to do so (in a
- // device-specific manner).
- //
- movi a1, INTERRUPT_MASK
- wsr a1, INTCLEAR
-
- // Restore registers:
- l32i a1, a2, 0
-#if HAVE_XSR
- movi a2, LABEL(_Level,FromVector) // restore handler address
- xsr a2, EXCSAVE_LEVEL
-#else
- rsr a2, EXCSAVE_LEVEL
-#endif
- // ... add more if more are saved above ...
-
- // Return:
- rfi _INTERRUPT_LEVEL
-
- .size LABEL(_Level,FromVector), . - LABEL(_Level,FromVector)
-
-#endif /* XCHAL_HAVE_INTERRUPTS */