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 "xtos-internal.h" 31 32 /* 33 * The following macros are used by int-lowpri-dispatcher.S to 34 * implement prioritized interrupt dispatching and fairness. 35 * The prioritization scheme is set by XTOS parameters in xtos-params.h . 36 */ 37 38 39 #if XCHAL_HAVE_INTERRUPTS 40 41 // msindex_int 42 // 43 // Return in register \aindex the index of the first (most significant) bit set 44 // in register \amask. 45 // Register \amask is clobbered (modified) by this macro. 46 // 47 // Note: this code is similar to the find_ms_setbit macro in <xtensa/coreasm.h>. 48 // 49 .macro msindex_int aindex, amask 50 # if XCHAL_HAVE_NSA 51 nsau \aindex, \amask // \aindex = interrupt index, from 0 to 31, from left to right 52 //movi \amask, 31 53 //sub \aindex, \amask, \aindex 54 # else 55 movi \aindex, 0 // start with result of 0 (point to lsbit of 32) 56 # if XCHAL_NUM_INTERRUPTS > 16 57 bltui \amask, 0x10000, 2f // is it one of the 16 lsbits? (if so, check lower 16 bits) 58 addi \aindex, \aindex, 16 // no, increment result to upper 16 bits (of 32) 59 extui \amask, \amask, 16, 16 // check upper half (shift right 16 bits) 60 2: 61 # endif 62 # if XCHAL_NUM_INTERRUPTS > 8 63 bltui \amask, 0x100, 2f // is it one of the 8 lsbits? (if so, check lower 8 bits) 64 addi \aindex, \aindex, 8 // no, increment result to upper 8 bits (of 16) 65 srli \amask, \amask, 8 // shift right to check upper 8 bits 66 2: 67 # endif 68 # if XCHAL_NUM_INTERRUPTS > 4 69 bltui \amask, 0x10, 2f // is it one of the 4 lsbits? (if so, check lower 4 bits) 70 addi \aindex, \aindex, 4 // no, increment result to upper 4 bits (of 8) 71 srli \amask, \amask, 4 // shift right 4 bits to check upper half 72 2: 73 # endif 74 bltui \amask, 0x4, 2f // is it one of the 2 lsbits? (if so, check lower 2 bits) 75 addi \aindex, \aindex, 2 // no, increment result to upper 2 bits (of 4) 76 srli \amask, \amask, 2 // shift right 2 bits to check upper half 77 2: 78 bltui \amask, 0x2, 2f // is it the lsbit? 79 addi \aindex, \aindex, 1 // no, increment result to upper bit (of 2) 80 2: // done! 81 # endif /*!NSA*/ 82 // HERE: \aindex = index of interrupt to handle 83 // \amask is available 84 .endm 85 86 87 // msindex_int_nc 88 // 89 // Same as msindex_int, but does not clobber \amask. 90 // Uses extra register \atmp (a temporary register) if needed. 91 // 92 .macro msindex_int_nc aindex, amask, atmp 93 # if XCHAL_HAVE_NSA 94 msindex_int \aindex, \amask // does not clobber \amask in this case 95 # else 96 mov \atmp, \amask 97 msindex_int \aindex, \atmp 98 # endif 99 .endm 100 101 102 // indexmask_int 103 // 104 // Compute index of highest priority interrupt in given mask, 105 // and trim mask to single bit corresponding to that interrupt. 106 // This is used for interrupt dispatching. 107 // 108 // Entry: 109 // \index = (undefined) 110 // \mask = non-zero mask of interrupt bits to consider handling 111 // \intptr = &_xtos_intstruct if INTENABLE virtualized, else undefined 112 // \tmp = (undefined) 113 // Exit: 114 // \index = index of interrupt (reversed if NSA present) 115 // \mask = single bit corresponding to index 116 // \intptr = (preserved) 117 // \tmp = (clobbered) 118 // 119 .macro indexmask_int index, mask, intptr, tmp 120 # if XTOS_SUBPRI_ORDER == XTOS_SPO_ZERO_LO 121 122 msindex_int \index, \mask // \index = index of msbit set in \mask (\tmp is tmp, \mask clobbered) 123 // \index now contains the index of the highest priority pending+enabled interrupt. 124 # if XCHAL_HAVE_NSA 125 movi \mask, 0x80000000 126 ssr \index 127 srl \mask, \mask // \mask = single bit set corresponding to interrupt to be processed... 128 # else 129 movi \mask, 1 130 ssl \index 131 sll \mask, \mask // \mask = single bit set corresponding to interrupt to be processed... 132 # endif 133 134 # elif XTOS_SUBPRI_ORDER == XTOS_SPO_ZERO_HI 135 136 neg \index, \mask // find lsbit in \mask ... 137 and \mask, \index, \mask // ... 138 msindex_int_nc \index, \mask, \tmp // \index = index of msbit set in \mask (\tmp is tmp, \mask not clobbered) 139 140 # else 141 # error Unsupported priority ordering. 142 # endif /*SUBPRI_ORDER*/ 143 .endm 144 145 146 // index_int 147 // 148 // Compute index of highest priority interrupt in given mask. 149 // This is used for fairness computations. 150 // 151 // Entry: 152 // \index = (undefined) 153 // \mask = non-zero mask of interrupt bits to consider handling 154 // \intptr = &_xtos_intptr 155 // \tmp = (undefined) 156 // Exit: 157 // \index = index of interrupt (reversed if NSA present) 158 // \mask = (preserved) 159 // \intptr = (preserved) 160 // \tmp = (clobbered) 161 // 162 .macro index_int index, mask, intptr, tmp 163 # if XTOS_SUBPRI_ORDER == XTOS_SPO_ZERO_LO 164 msindex_int_nc \index, \mask, \tmp // \index = index of msbit set in \mask (\mask not clobbered) 165 # elif XTOS_SUBPRI_ORDER == XTOS_SPO_ZERO_HI 166 neg \tmp, \mask // find lsbit in \mask ... 167 and \tmp, \tmp, \mask // ... 168 msindex_int \index, \tmp // \index = index of msbit set in \tmp (\tmp is clobbered) 169 # else 170 # error oops 171 # endif 172 .endm // index_int 173 174 175 #endif /* XCHAL_HAVE_INTERRUPTS */ 176 177 178