move sboot to the root directory
[open-ath9k-htc-firmware.git] / sboot / magpie_1_1 / sboot / athos / src / xtos / xtos-internal.h
diff --git a/sboot/magpie_1_1/sboot/athos/src/xtos/xtos-internal.h b/sboot/magpie_1_1/sboot/athos/src/xtos/xtos-internal.h
new file mode 100755 (executable)
index 0000000..c6f1185
--- /dev/null
@@ -0,0 +1,401 @@
+/*
+ * xtos-internal.h  --  internal definitions for single-threaded run-time
+ *
+ * Copyright (c) 2003-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.
+ */
+
+#ifndef XTOS_INTERNAL_H
+#define XTOS_INTERNAL_H
+
+#include <xtensa/config/core.h>
+#include <xtensa/xtruntime.h>
+#include <xtensa/xtruntime-frames.h>
+#include <xtensa/xtensa-versions.h>
+#ifndef XTOS_PARAMS_H  /* this to allow indirect inclusion of this header from the outside */
+#include "xtos-params.h"
+#endif
+
+/*  Relative ordering of subpriorities within an interrupt level (or vector):  */
+#define XTOS_SPO_ZERO_LO       0       /* lower (eg. zero) numbered interrupts are lower  priority than higher numbered interrupts */
+#define XTOS_SPO_ZERO_HI       1       /* lower (eg. zero) numbered interrupts are higher priority than higher numbered interrupts */
+
+
+/*  Sanity check some parameters from xtos-params.h:  */
+#if XTOS_LOCKLEVEL < XCHAL_EXCM_LEVEL || XTOS_LOCKLEVEL > 15
+# error Invalid XTOS_LOCKLEVEL value, must be >= EXCM_LEVEL and <= 15, please fix xtos-params.h
+#endif
+
+/*  Mask of interrupts locked out at XTOS_LOCKLEVEL:  */
+#define XTOS_LOCKOUT_MASK      XCHAL_INTLEVEL_ANDBELOW_MASK(XTOS_LOCKLEVEL)
+/*  Mask of interrupts that can still be enabled at XTOS_LOCKLEVEL:  */
+#define XTOS_UNLOCKABLE_MASK   (0xFFFFFFFF-XTOS_LOCKOUT_MASK)
+
+/*  Don't set this:  */
+#define XTOS_HIGHINT_TRAMP     0       /* mapping high-pri ints to low-pri not auto-supported */
+#define XTOS_VIRTUAL_INTERRUPT XTOS_HIGHINT_TRAMP      /* partially-virtualized INTERRUPT register not currently supported */
+#if XTOS_HIGHINT_TRAMP
+# error Automatically-generated high-level interrupt trampolines are not presently supported.
+#endif
+
+/*
+ *  If single interrupt at level-one, sub-prioritization is irrelevant:
+ */
+#if defined(XCHAL_INTLEVEL1_NUM)
+# undef XTOS_SUBPRI
+# define XTOS_SUBPRI 0                 /* override - only one interrupt */
+#endif
+
+/*
+ *  In XEA1, the INTENABLE special register must be virtualized to provide
+ *  standard XTOS functionality.
+ *  In XEA2, this is only needed for software interrupt prioritization.
+ */
+#if XTOS_SUBPRI || XCHAL_HAVE_XEA1
+#define XTOS_VIRTUAL_INTENABLE 1
+#else
+#define XTOS_VIRTUAL_INTENABLE 0
+#endif
+
+/*
+ *  If single interrupt per priority, then fairness is irrelevant:
+ */
+#if (XTOS_SUBPRI && !XTOS_SUBPRI_GROUPS) || defined(XCHAL_INTLEVEL1_NUM)
+# undef XTOS_INT_FAIRNESS
+# define XTOS_INT_FAIRNESS     0
+#endif
+
+/*  Identify special case interrupt handling code in int-lowpri-dispatcher.S:  */
+#define XTOS_INT_SPECIALCASE   (XTOS_SUBPRI_ORDER == XTOS_SPO_ZERO_HI && XTOS_INT_FAIRNESS == 0 && XTOS_SUBPRI_GROUPS == 0)
+
+/*
+ *  Determine whether to extend the interrupt entry array:
+ */
+#define XIE_EXTEND             (XTOS_VIRTUAL_INTENABLE && !XTOS_INT_SPECIALCASE)
+
+/*  If we have the NSAU instruction, ordering of interrupts is reversed in _xtos_interrupt_table[]:  */
+#if XCHAL_HAVE_NSA
+# define MAPINT(n)     ((XCHAL_NUM_INTERRUPTS-1)-(n))
+# ifdef _ASMLANGUAGE
+       .macro  mapint  an
+       neg     \an, \an
+       addi    \an, \an, XCHAL_NUM_INTERRUPTS-1
+       .endm
+# endif
+#else /* no NSA */
+# define MAPINT(n)     (n)
+# ifdef _ASMLANGUAGE
+       .macro  mapint  an
+       .endm
+# endif
+#endif
+
+
+#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
+
+/***********   Useful macros   ***********/
+
+/*
+ *  A useful looping macro:
+ *  'iterate' invokes 'what' (an instruction, pseudo-op or other macro)
+ *  multiple times, passing it a numbered parameter from 'from' to 'to'
+ *  inclusively.  Does not invoke 'what' at all if from > to.
+ *  Maximum difference between 'from' and 'to' is 99 minus nesting depth
+ *  (GNU 'as' doesn't allow nesting deeper than 100).
+ */
+       .macro  iterate         from, to, what
+       .ifeq   ((\to-\from) & ~0xFFF)
+       \what   \from
+       iterate "(\from+1)", \to, \what
+       .endif
+       .endm   // iterate
+
+
+
+       //  rsilft
+       //
+       //  Execute RSIL \ar, \tolevel if \tolevel is different than \fromlevel.
+       //  This way the RSIL is avoided if we know at assembly time that
+       //  it will not change the level.  Typically, this means the \ar register
+       //  is ignored, ie. RSIL is used only to change PS.INTLEVEL.
+       //
+       .macro  rsilft  ar, fromlevel, tolevel
+#if XCHAL_HAVE_INTERRUPTS
+       .if \fromlevel - \tolevel
+       rsil    \ar, \tolevel
+       .endif
+#endif
+       .endm
+
+
+       //  Save LOOP and MAC16 registers, if configured, to the exception stack
+       //  frame pointed to by address register \esf, using \aa and \ab as temporaries.
+       //
+       //  This macro essentially saves optional registers that the compiler uses by
+       //  default when present.
+       //  Note that the acclo/acchi subset of MAC16 may be used even if others
+       //  multipliers are present (e.g. mul16, mul32).
+       //
+       //  Only two temp registers required for this code to be optimal (no interlocks) in both
+       //  T10xx (Athens) and Xtensa LX microarchitectures (both 5 and 7 stage pipes):
+       //
+       .macro  save_loops_mac16        esf, aa, ab
+#if XCHAL_HAVE_LOOPS
+       rsr     \aa, LCOUNT
+       rsr     \ab, LBEG
+       s32i    \aa, \esf, UEXC_lcount
+       rsr     \aa, LEND
+       s32i    \ab, \esf, UEXC_lbeg
+       s32i    \aa, \esf, UEXC_lend
+#endif
+#if XCHAL_HAVE_MAC16
+       rsr     \aa, ACCLO
+       rsr     \ab, ACCHI
+       s32i    \aa, \esf, UEXC_acclo
+       s32i    \ab, \esf, UEXC_acchi
+# if XTOS_SAVE_ALL_MAC16
+       rsr     \aa, M0
+       rsr     \ab, M1
+       s32i    \aa, \esf, UEXC_mr + 0
+       s32i    \ab, \esf, UEXC_mr + 4
+       rsr     \aa, M2
+       rsr     \ab, M3
+       s32i    \aa, \esf, UEXC_mr + 8
+       s32i    \ab, \esf, UEXC_mr + 12
+# endif
+#endif
+       .endm
+
+       //  Restore LOOP and MAC16 registers, if configured, from the exception stack
+       //  frame pointed to by address register \esf, using \aa, \ab and \ac as temporaries.
+       //
+       //  Three temp registers are required for this code to be optimal (no interlocks) in
+       //  Xtensa LX microarchitectures with 7-stage pipe; otherwise only two
+       //  registers would be needed.
+       //
+       .macro  restore_loops_mac16     esf, aa, ab, ac
+#if XCHAL_HAVE_LOOPS
+       l32i    \aa, \esf, UEXC_lcount
+       l32i    \ab, \esf, UEXC_lbeg
+       l32i    \ac, \esf, UEXC_lend
+       wsr     \aa, LCOUNT
+       wsr     \ab, LBEG
+       wsr     \ac, LEND
+#endif
+#if XCHAL_HAVE_MAC16
+       l32i    \aa, \esf, UEXC_acclo
+       l32i    \ab, \esf, UEXC_acchi
+# if XTOS_SAVE_ALL_MAC16
+       l32i    \ac, \esf, UEXC_mr + 0
+       wsr     \aa, ACCLO
+       wsr     \ab, ACCHI
+       wsr     \ac, M0
+       l32i    \aa, \esf, UEXC_mr + 4
+       l32i    \ab, \esf, UEXC_mr + 8
+       l32i    \ac, \esf, UEXC_mr + 12
+       wsr     \aa, M1
+       wsr     \ab, M2
+       wsr     \ac, M3
+# else
+       wsr     \aa, ACCLO
+       wsr     \ab, ACCHI
+# endif
+#endif
+       .endm
+
+
+/*  Offsets from _xtos_intstruct structure:  */
+       .struct 0
+#if XTOS_VIRTUAL_INTENABLE
+XTOS_ENABLED_OFS:      .space  4       /* _xtos_enabled variable */
+XTOS_VPRI_ENABLED_OFS: .space  4       /* _xtos_vpri_enabled variable */
+#endif
+#if XTOS_VIRTUAL_INTERRUPT
+XTOS_PENDING_OFS:      .space  4       /* _xtos_pending variable */
+#endif
+       .text
+
+
+#if XTOS_VIRTUAL_INTENABLE
+       // Update INTENABLE register, computing it as follows:
+       //      INTENABLE = _xtos_enabled & _xtos_vpri_enabled
+       //                      [ & ~_xtos_pending ]
+       //
+       // Entry:
+       //      register ax = &_xtos_intstruct
+       //      register ay, az undefined (temporaries)
+       //      PS.INTLEVEL set to XTOS_LOCKLEVEL or higher (eg. via xtos_lock)
+       //      window overflows prevented (PS.WOE=0, PS.EXCM=1, or overflows
+       //              already done for registers ax, ay, az)
+       //
+       // Exit:
+       //      registers ax, ay, az clobbered
+       //      PS unchanged
+       //      caller needs to SYNC (?) for INTENABLE changes to take effect
+       //
+       // Note: in other software prioritization schemes/implementations,
+       // the term <_xtos_vpri_enabled> in the above expression is often
+       // replaced with another expression that computes the set of
+       // interrupts allowed to be enabled at the current software virtualized
+       // interrupt priority.
+       //
+       // For example, a simple alternative implementation of software
+       // prioritization for XTOS might have been the following:
+       //      INTENABLE = _xtos_enabled & (vpri_enabled | UNLOCKABLE_MASK)
+       // which removes the need for the interrupt dispatcher to 'or' the
+       // UNLOCKABLE_MASK bits into _xtos_vpri_enabled, and lets other code
+       // disable all lockout level interrupts by just clearing _xtos_vpri_enabled
+       // rather than setting it to UNLOCKABLE_MASK.
+       // Other implementations sometimes use a table, eg:
+       //      INTENABLE = _xtos_enabled & enable_table[current_vpri]
+       // The HAL (used by some 3rd party OSes) uses essentially a table-driven
+       // version, with other tables enabling run-time changing of priorities.
+       //
+       .macro  xtos_update_intenable   ax, ay, az
+       //movi  \ax, _xtos_intstruct
+       l32i    \ay, \ax, XTOS_VPRI_ENABLED_OFS         // ay = _xtos_vpri_enabled
+       l32i    \az, \ax, XTOS_ENABLED_OFS              // az = _xtos_enabled
+       //interlock
+       and     \az, \az, \ay           // az = _xtos_enabled & _xtos_vpri_enabled
+# if XTOS_VIRTUAL_INTERRUPT
+       l32i    \ay, \ax, XTOS_PENDING_OFS              // ay = _xtos_pending
+       movi    \ax, -1
+       xor     \ay, \ay, \ax           // ay = ~_xtos_pending
+       and     \az, \az, \ay           // az &= ~_xtos_pending
+# endif
+       wsr     \az, INTENABLE
+       .endm
+#endif /* VIRTUAL_INTENABLE */
+
+       .macro  xtos_lock       ax
+       rsil    \ax, XTOS_LOCKLEVEL     // lockout
+       .endm
+
+       .macro  xtos_unlock     ax
+       wsr     \ax, PS                 // unlock
+       rsync
+       .endm
+
+/*  Offsets to XtosIntHandlerEntry structure fields (see below):  */
+# define XIE_HANDLER   0
+# define XIE_ARG       4
+# define XIE_SIZE      8
+# if XIE_EXTEND
+#  define XIE_VPRIMASK (XIE_SIZE*XCHAL_NUM_INTERRUPTS+0)       /* if VIRTUAL_INTENABLE [SUBPRI||XEA1] && !SPECIALCASE */
+#  define XIE_LEVELMASK        (XIE_SIZE*XCHAL_NUM_INTERRUPTS+4)       /* [fairness preloop]  if FAIRNESS && SUBPRI [&& SUBPRI_GROUPS] */
+# endif
+
+/*  To simplify code:  */
+# if XCHAL_HAVE_NSA
+#  define IFNSA(a,b)   a
+# else
+#  define IFNSA(a,b)   b
+# endif
+
+#else /* !_ASMLANGUAGE && !__ASSEMBLER__ */
+
+/*
+ *  Interrupt handler table entry.
+ *  Unregistered entries have 'handler' point to _xtos_unhandled_interrupt().
+ */
+typedef struct XtosIntHandlerEntry {
+    _xtos_handler      handler;
+    void *             arg;
+} XtosIntHandlerEntry;
+# if XIE_EXTEND
+typedef struct XtosIntMaskEntry {
+    unsigned           vpri_mask;      /* mask of interrupts enabled when this interrupt is taken */
+    unsigned           level_mask;     /* mask of interrupts at this interrupt's level */
+} XtosIntMaskEntry;
+# endif
+
+#endif /* !_ASMLANGUAGE && !__ASSEMBLER__ */
+
+/*
+ *  Notes...
+ *
+ *  XEA1 and interrupt-SUBPRIoritization both imply virtualization of INTENABLE.
+ *  Synchronous trampoloines imply partial virtualization of the INTERRUPT
+ *  register, which in turn also implies virtualization of INTENABLE register.
+ *  High-level interrupts manipulating the set of enabled interrupts implies
+ *  at least a high XTOS_LOCK_LEVEL, although not necessarily INTENABLE virtualization.
+ *
+ *  With INTENABLE register virtualization, at all times the INTENABLE
+ *  register reflects the expression:
+ *     (set of interrupts enabled) & (set of interrupts enabled by current
+ *                                     virtual priority)
+ *
+ *  Unrelated (DBREAK semantics):
+ *
+ *     A[31-6] = DBA[3-6]
+ *     ---------------------
+ *     A[5-0] & DBC[5-C] & szmask
+ *
+ *     = DBA[5-0] & szmask
+ *                     ^___  ???
+ */
+
+
+/*  Report whether the XSR instruction is available (conservative):  */
+#define HAVE_XSR       (XCHAL_HAVE_XEA2 || !XCHAL_HAVE_EXCEPTIONS)
+/*
+ *  This is more accurate, but not a reliable test in software releases prior to 6.0
+ *  (where the targeted hardware parameter was not explicit in the XPG):
+ *
+ *#define HAVE_XSR     (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_T1040_0)
+ */
+
+
+
+/* Macros for supporting hi-level and medium-level interrupt handling. */
+
+#if XCHAL_NUM_INTLEVELS > 6
+#error Template files (*-template.S) limit support to interrupt levels <= 6
+#endif
+
+#if  defined(__XTENSA_WINDOWED_ABI__) && XCHAL_HAVE_CALL4AND12 == 0
+#error CALL8-only is not supported!
+#endif
+
+#define INTERRUPT_IS_HI(level)  \
+       ( XCHAL_HAVE_INTERRUPTS && \
+        (XCHAL_EXCM_LEVEL < level) && \
+        (XCHAL_NUM_INTLEVELS >= level) && \
+        (XCHAL_HAVE_DEBUG ? XCHAL_DEBUGLEVEL != level : 1))
+
+#define INTERRUPT_IS_MED(level) \
+       (XCHAL_HAVE_INTERRUPTS && (XCHAL_EXCM_LEVEL >= level))
+
+
+#define _JOIN(x,y)     x ## y
+#define JOIN(x,y)      _JOIN(x,y)
+
+#define _JOIN3(a,b,c)  a ## b ## c
+#define JOIN3(a,b,c)   _JOIN3(a,b,c)
+
+#define LABEL(x,y)             JOIN3(x,_INTERRUPT_LEVEL,y)
+#define EXCSAVE_LEVEL          JOIN(EXCSAVE_,_INTERRUPT_LEVEL)
+#define INTLEVEL_VSIZE         JOIN3(XSHAL_INTLEVEL,_INTERRUPT_LEVEL,_VECTOR_SIZE)
+
+
+
+#endif /* XTOS_INTERNAL_H */
+