Setting up repository
[linux-libre-firmware.git] / ath9k_htc / sboot / magpie_1_1 / sboot / athos / src / xtos / interrupt-pri.h
1 /* interrupt-pri.h - Definitions and macros related to interrupt prioritization */
2 /*
3  * Copyright (c) 2002-2004, 2006 Tensilica Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 #if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
26 # error "The interrupt-pri.h header file is meant for inclusion by assembly source code only."
27 #endif
28
29 #include <xtensa/coreasm.h>
30 #include <xtensa/config/specreg.h>
31 #include "xtos-internal.h"
32
33 /*
34  *  The following macros are used by int-lowpri-dispatcher.S to
35  *  implement prioritized interrupt dispatching and fairness.
36  *  The prioritization scheme is set by XTOS parameters in xtos-params.h .
37  */
38
39
40 #if XCHAL_HAVE_INTERRUPTS
41
42         //  msindex_int
43         //
44         //  Return in register \aindex the index of the first (most significant) bit set
45         //  in register \amask.
46         //  Register \amask is clobbered (modified) by this macro.
47         //
48         //  Note: this code is similar to the find_ms_setbit macro in <xtensa/coreasm.h>.
49         //
50         .macro  msindex_int             aindex, amask
51 # if XCHAL_HAVE_NSA
52         nsau    \aindex, \amask         // \aindex = interrupt index, from 0 to 31, from left to right
53         //movi  \amask, 31
54         //sub   \aindex, \amask, \aindex
55 # else
56         movi    \aindex, 0              // start with result of 0 (point to lsbit of 32)
57 #  if XCHAL_NUM_INTERRUPTS > 16
58         bltui   \amask, 0x10000, 2f     // is it one of the 16 lsbits? (if so, check lower 16 bits)
59         addi    \aindex, \aindex, 16    // no, increment result to upper 16 bits (of 32)
60         extui   \amask, \amask, 16, 16  // check upper half (shift right 16 bits)
61 2:
62 #  endif
63 #  if XCHAL_NUM_INTERRUPTS > 8
64         bltui   \amask, 0x100, 2f       // is it one of the 8 lsbits? (if so, check lower 8 bits)
65         addi    \aindex, \aindex, 8     // no, increment result to upper 8 bits (of 16)
66         srli    \amask, \amask, 8       // shift right to check upper 8 bits
67 2:
68 #  endif
69 #  if XCHAL_NUM_INTERRUPTS > 4
70         bltui   \amask, 0x10, 2f        // is it one of the 4 lsbits? (if so, check lower 4 bits)
71         addi    \aindex, \aindex, 4     // no, increment result to upper 4 bits (of 8)
72         srli    \amask, \amask, 4       // shift right 4 bits to check upper half
73 2:
74 #  endif
75         bltui   \amask, 0x4, 2f         // is it one of the 2 lsbits? (if so, check lower 2 bits)
76         addi    \aindex, \aindex, 2     // no, increment result to upper 2 bits (of 4)
77         srli    \amask, \amask, 2       // shift right 2 bits to check upper half
78 2:
79         bltui   \amask, 0x2, 2f         // is it the lsbit?
80         addi    \aindex, \aindex, 1     // no, increment result to upper bit (of 2)
81 2:                                      // done! 
82 # endif /*!NSA*/
83         //  HERE:  \aindex = index of interrupt to handle
84         //         \amask is available
85         .endm
86
87
88         //  msindex_int_nc
89         //
90         //  Same as msindex_int, but does not clobber \amask.
91         //  Uses extra register \atmp (a temporary register) if needed.
92         //
93         .macro  msindex_int_nc  aindex, amask, atmp
94 # if XCHAL_HAVE_NSA
95         msindex_int     \aindex, \amask         // does not clobber \amask in this case
96 # else
97         mov             \atmp, \amask
98         msindex_int     \aindex, \atmp
99 # endif
100         .endm
101
102
103         //  indexmask_int
104         //
105         //  Compute index of highest priority interrupt in given mask,
106         //  and trim mask to single bit corresponding to that interrupt.
107         //  This is used for interrupt dispatching.
108         //
109         //  Entry:
110         //      \index  = (undefined)
111         //      \mask   = non-zero mask of interrupt bits to consider handling
112         //      \intptr = &_xtos_intstruct if INTENABLE virtualized, else undefined
113         //      \tmp    = (undefined)
114         //  Exit:
115         //      \index  = index of interrupt (reversed if NSA present)
116         //      \mask   = single bit corresponding to index
117         //      \intptr = (preserved)
118         //      \tmp    = (clobbered)
119         //
120         .macro  indexmask_int   index, mask, intptr, tmp
121 # if XTOS_SUBPRI_ORDER == XTOS_SPO_ZERO_LO
122
123         msindex_int     \index, \mask   // \index = index of msbit set in \mask (\tmp is tmp, \mask clobbered)
124         //  \index now contains the index of the highest priority pending+enabled interrupt.
125 #  if XCHAL_HAVE_NSA
126         movi            \mask, 0x80000000
127         ssr             \index
128         srl             \mask, \mask    //  \mask = single bit set corresponding to interrupt to be processed...
129 #  else
130         movi            \mask, 1
131         ssl             \index
132         sll             \mask, \mask    //  \mask = single bit set corresponding to interrupt to be processed...
133 #  endif
134
135 # elif XTOS_SUBPRI_ORDER == XTOS_SPO_ZERO_HI
136
137         neg             \index, \mask           // find lsbit in \mask ...
138         and             \mask, \index, \mask    // ...
139         msindex_int_nc  \index, \mask, \tmp     // \index = index of msbit set in \mask (\tmp is tmp, \mask not clobbered)
140
141 # else
142 #  error Unsupported priority ordering.
143 # endif /*SUBPRI_ORDER*/
144         .endm
145
146
147         //  index_int
148         //
149         //  Compute index of highest priority interrupt in given mask.
150         //  This is used for fairness computations.
151         //
152         //  Entry:
153         //      \index  = (undefined)
154         //      \mask   = non-zero mask of interrupt bits to consider handling
155         //      \intptr = &_xtos_intptr
156         //      \tmp    = (undefined)
157         //  Exit:
158         //      \index  = index of interrupt (reversed if NSA present)
159         //      \mask   = (preserved)
160         //      \intptr = (preserved)
161         //      \tmp    = (clobbered)
162         //
163         .macro  index_int       index, mask, intptr, tmp
164 # if XTOS_SUBPRI_ORDER == XTOS_SPO_ZERO_LO
165         msindex_int_nc  \index, \mask, \tmp     // \index = index of msbit set in \mask (\mask not clobbered)
166 # elif XTOS_SUBPRI_ORDER == XTOS_SPO_ZERO_HI
167         neg             \tmp, \mask             // find lsbit in \mask ...
168         and             \tmp, \tmp, \mask       // ...
169         msindex_int     \index, \tmp            // \index = index of msbit set in \tmp (\tmp is clobbered)
170 # else
171 #  error oops
172 # endif
173         .endm   // index_int
174
175
176 #endif /* XCHAL_HAVE_INTERRUPTS */
177
178