move sboot to the root directory
[open-ath9k-htc-firmware.git] / sboot / magpie_1_1 / sboot / athos / src / xtos / int-highpri-template.S
diff --git a/sboot/magpie_1_1/sboot/athos/src/xtos/int-highpri-template.S b/sboot/magpie_1_1/sboot/athos/src/xtos/int-highpri-template.S
new file mode 100755 (executable)
index 0000000..1f16b47
--- /dev/null
@@ -0,0 +1,154 @@
+// 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 */