+++ /dev/null
-/*
- * 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 */
-