[444] | 1 | /* |
---|
| 2 | * Copyright (c) 2011 Aeroflex Gaisler |
---|
| 3 | * |
---|
| 4 | * BSD license: |
---|
| 5 | * |
---|
| 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
---|
| 7 | * of this software and associated documentation files (the "Software"), to deal |
---|
| 8 | * in the Software without restriction, including without limitation the rights |
---|
| 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
---|
| 10 | * copies of the Software, and to permit persons to whom the Software is |
---|
| 11 | * furnished to do so, subject to the following conditions: |
---|
| 12 | * |
---|
| 13 | * The above copyright notice and this permission notice shall be included in |
---|
| 14 | * all copies or substantial portions of the Software. |
---|
| 15 | * |
---|
| 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
---|
| 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
---|
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
---|
| 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
---|
| 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
---|
| 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
---|
| 22 | * THE SOFTWARE. |
---|
| 23 | */ |
---|
| 24 | |
---|
| 25 | |
---|
| 26 | #include <asm-leon/leon.h> |
---|
| 27 | #include <asm-leon/leonstack.h> |
---|
| 28 | #include <asm-leon/asmmacro.h> |
---|
| 29 | |
---|
| 30 | .seg "data" |
---|
| 31 | .global _lb_spillglobals, _lb_issideflush |
---|
| 32 | .align 4 |
---|
| 33 | _lb_spillglobals: |
---|
| 34 | .word 0 |
---|
| 35 | .word 0 |
---|
| 36 | .word 0 |
---|
| 37 | .word 0 |
---|
| 38 | .word 0 |
---|
| 39 | .word 0 |
---|
| 40 | .word 0 |
---|
| 41 | _lb_issideflush: |
---|
| 42 | .word 0 /* off: 28 */ |
---|
| 43 | |
---|
| 44 | .seg "text" |
---|
| 45 | |
---|
| 46 | /* =============================================== */ |
---|
| 47 | |
---|
| 48 | #define _SV save %sp, -SF_REGS_SZ, %sp |
---|
| 49 | #define _RS restore |
---|
| 50 | |
---|
| 51 | /* ------- */ |
---|
| 52 | .weak _flush_windows |
---|
| 53 | .set _flush_windows,__flush_windows |
---|
| 54 | .weak _flush_windows_svt |
---|
| 55 | .set _flush_windows_svt,__flush_windows_svt |
---|
| 56 | /* ------- */ |
---|
| 57 | !.global _flush_windows,_flush_windows_svt |
---|
| 58 | __flush_windows_svt: |
---|
| 59 | rd %wim, %l3 |
---|
| 60 | |
---|
| 61 | __flush_windows: |
---|
| 62 | SAVE_ALL |
---|
| 63 | |
---|
| 64 | #ifndef _FLAT |
---|
| 65 | |
---|
| 66 | set _lb_issideflush, %l3 |
---|
| 67 | st %l0, [%l3] /* mark as inside flush */ |
---|
| 68 | |
---|
| 69 | wr %l0, SPARC_PSR_ET_MASK, %psr |
---|
| 70 | nop; nop; nop |
---|
| 71 | |
---|
| 72 | _SV; _SV; _SV; _SV; _SV; _SV; _SV; |
---|
| 73 | _RS; _RS; _RS; _RS; _RS; _RS; _RS; |
---|
| 74 | |
---|
| 75 | set _lb_issideflush, %l3 |
---|
| 76 | st %g0, [%l3] /* mark as outside flush */ |
---|
| 77 | |
---|
| 78 | /* Advance over the trap instruction. */ |
---|
| 79 | ld [%sp + SF_REGS_SZ + PT_NPC], %l1 |
---|
| 80 | add %l1, 0x4, %l2 |
---|
| 81 | st %l1, [%sp + SF_REGS_SZ + PT_PC] |
---|
| 82 | st %l2, [%sp + SF_REGS_SZ + PT_NPC] |
---|
| 83 | #endif |
---|
| 84 | |
---|
| 85 | RESTORE_ALL |
---|
| 86 | |
---|
| 87 | /* =============================================== */ |
---|
| 88 | |
---|
| 89 | _irqcall_flush_windows: |
---|
| 90 | #ifndef _FLAT |
---|
| 91 | set _lb_spillglobals,%l4 |
---|
| 92 | st %g1,[%l4+0] |
---|
| 93 | st %g4,[%l4+4] |
---|
| 94 | st %l0,[%l4+16] |
---|
| 95 | st %l1,[%l4+20] |
---|
| 96 | st %l2,[%l4+24] |
---|
| 97 | st %l4,[%l4+28] /* mark as inside flush */ |
---|
| 98 | |
---|
| 99 | restore |
---|
| 100 | |
---|
| 101 | mov %psr, %g1 |
---|
| 102 | or %g1, SPARC_PSR_PIL_MASK, %g1 |
---|
| 103 | wr %g1, SPARC_PSR_ET_MASK, %psr /* disable irq, enable traps */ |
---|
| 104 | nop |
---|
| 105 | nop |
---|
| 106 | nop |
---|
| 107 | |
---|
| 108 | sethi %hi(_nwindows_min1), %g4 /* flush registers */ |
---|
| 109 | ld [%g4+%lo(_nwindows_min1)], %g4 |
---|
| 110 | 1: save /* NWINDOWS-1 times */ |
---|
| 111 | sub %g4,1,%g4 |
---|
| 112 | |
---|
| 113 | /*****************/ |
---|
| 114 | andncc %g4,0xff,%g0 |
---|
| 115 | be .lab1 |
---|
| 116 | nop |
---|
| 117 | nop |
---|
| 118 | |
---|
| 119 | .lab1: /*****************/ |
---|
| 120 | |
---|
| 121 | cmp %g4,%g0 |
---|
| 122 | bne 1b |
---|
| 123 | nop |
---|
| 124 | |
---|
| 125 | sethi %hi(_nwindows_min1), %g4 |
---|
| 126 | ld [%g4+%lo(_nwindows_min1)], %g4 |
---|
| 127 | 2: restore /* NWINDOWS-1 times */ |
---|
| 128 | |
---|
| 129 | /*****************/ |
---|
| 130 | andncc %g4,0xff,%g0 |
---|
| 131 | be .lab2 |
---|
| 132 | nop |
---|
| 133 | nop |
---|
| 134 | |
---|
| 135 | .lab2: /*****************/ |
---|
| 136 | |
---|
| 137 | sub %g4,1,%g4 |
---|
| 138 | cmp %g4,%g0 |
---|
| 139 | bne 2b |
---|
| 140 | nop |
---|
| 141 | |
---|
| 142 | save |
---|
| 143 | |
---|
| 144 | set _lb_spillglobals,%l4 |
---|
| 145 | ld [%l4+4], %g4 |
---|
| 146 | ld [%l4+0], %g1 |
---|
| 147 | ld [%l4+16],%l0 |
---|
| 148 | ld [%l4+20],%l1 |
---|
| 149 | ld [%l4+24],%l2 |
---|
| 150 | st %g0,[%l4+28] /* clean inside flush mark */ |
---|
| 151 | |
---|
| 152 | #endif |
---|
| 153 | |
---|
| 154 | wr %l0, 0, %psr /* restore psr */ |
---|
| 155 | nop |
---|
| 156 | nop |
---|
| 157 | nop |
---|
| 158 | |
---|
| 159 | jmpl %l2, %g0 |
---|
| 160 | rett %l2 + 4 |
---|
| 161 | |
---|
| 162 | /* =============================================== */ |
---|
| 163 | |
---|
| 164 | /* ------- */ |
---|
| 165 | .weak _irqcall_disableirq |
---|
| 166 | .set _irqcall_disableirq,__irqcall_disableirq |
---|
| 167 | .weak _irqcall_disableirq_svt |
---|
| 168 | .set _irqcall_disableirq_svt,__irqcall_disableirq_svt |
---|
| 169 | /* ------- */ |
---|
| 170 | |
---|
| 171 | __irqcall_disableirq: |
---|
| 172 | __irqcall_disableirq_svt: |
---|
| 173 | or %l0, SPARC_PSR_PIL_MASK, %l0 |
---|
| 174 | mov %l0, %psr |
---|
| 175 | nop; nop; nop |
---|
| 176 | jmpl %l2, %g0 |
---|
| 177 | rett %l2 + 4 |
---|
| 178 | |
---|
| 179 | /* =============================================== */ |
---|
| 180 | |
---|
| 181 | /* |
---|
| 182 | * system call (ta 0x2): |
---|
| 183 | * 2: irq_disable: |
---|
| 184 | * o1 = 2 |
---|
| 185 | * 3: irq_enable: |
---|
| 186 | * o0 = old_flags |
---|
| 187 | * o1 = 3 |
---|
| 188 | * 4: enter supervisor mode (from user mode): |
---|
| 189 | * o1 = 4 |
---|
| 190 | * 5: enter user mode: |
---|
| 191 | * o1 = 5 |
---|
| 192 | * 6: flush windows |
---|
| 193 | * |
---|
| 194 | * On entry: |
---|
| 195 | * |
---|
| 196 | * l0 = psr (from trap table) |
---|
| 197 | * l1 = pc |
---|
| 198 | * l2 = npc |
---|
| 199 | * i0 = system call id |
---|
| 200 | */ |
---|
| 201 | |
---|
| 202 | /* ------- */ |
---|
| 203 | .weak _irqcall |
---|
| 204 | .set _irqcall,__irqcall |
---|
| 205 | .weak _irqcall_svt |
---|
| 206 | .set _irqcall_svt,__irqcall_svt |
---|
| 207 | /* ------- */ |
---|
| 208 | !.global _irqcall,_irqcall_svt |
---|
| 209 | __irqcall_svt: |
---|
| 210 | __irqcall: |
---|
| 211 | |
---|
| 212 | subcc %i1, 2, %g0 ! syscall 2, disable interrupts |
---|
| 213 | bne 3f |
---|
| 214 | or %l0, 0x0f00, %l4 ! set PIL=15 |
---|
| 215 | mov %l4, %psr |
---|
| 216 | or %l0, SPARC_PSR_ET_MASK, %i0 ! return old psr with ET=1 |
---|
| 217 | ba,a 9f |
---|
| 218 | 3: |
---|
| 219 | subcc %i1, 3, %g0 ! syscall 3, enable interrupts |
---|
| 220 | bne 4f |
---|
| 221 | and %i0, SPARC_PSR_PIL_MASK, %l4 |
---|
| 222 | andn %l0, SPARC_PSR_PIL_MASK, %l5 |
---|
| 223 | or %l5, %l4, %l4 |
---|
| 224 | mov %l4, %psr |
---|
| 225 | ba,a 9f |
---|
| 226 | 4: |
---|
| 227 | subcc %i1, 4, %g0 ! syscall 4, enter supervisor |
---|
| 228 | bne 5f |
---|
| 229 | |
---|
| 230 | mov %psr, %l4 |
---|
| 231 | or %l4,SPARC_PSR_PS_MASK,%l4 |
---|
| 232 | mov %l4, %psr ! set previous supervisor %psr |
---|
| 233 | nop; nop; nop |
---|
| 234 | ba,a 9f |
---|
| 235 | |
---|
| 236 | 5: |
---|
| 237 | subcc %i1, 5, %g0 ! syscall 5, enter user |
---|
| 238 | bne 6f |
---|
| 239 | |
---|
| 240 | mov %psr, %l4 |
---|
| 241 | andn %l4,SPARC_PSR_PS_MASK,%l4 |
---|
| 242 | mov %l4, %psr ! clear previous supervisor %psr, return to user mode |
---|
| 243 | nop; nop; nop |
---|
| 244 | ba,a 9f |
---|
| 245 | |
---|
| 246 | 6: |
---|
| 247 | subcc %i1, 6, %g0 ! syscall 6, flush windows |
---|
| 248 | bne 1f |
---|
| 249 | nop |
---|
| 250 | |
---|
| 251 | ba,a _irqcall_flush_windows |
---|
| 252 | |
---|
| 253 | 1: |
---|
| 254 | ta 0 ! halt |
---|
| 255 | 9: ! leave |
---|
| 256 | jmpl %l2, %g0 |
---|
| 257 | rett %l2 + 4 |
---|
| 258 | |
---|
| 259 | /* =============================================== */ |
---|
| 260 | |
---|
| 261 | /* call _irqcall through trap */ |
---|
| 262 | .global leonbare_enable_traps !void leonbare_enable_traps(unsigned long old_flags); |
---|
| 263 | leonbare_enable_traps: |
---|
| 264 | set 3,%o1 |
---|
| 265 | retl |
---|
| 266 | ta 0x2 |
---|
| 267 | |
---|
| 268 | /* =============================================== */ |
---|
| 269 | |
---|
| 270 | /* call _irqcall through trap */ |
---|
| 271 | .global leonbare_disable_traps !unsigned long leonbare_disable_traps(); |
---|
| 272 | leonbare_disable_traps: |
---|
| 273 | set 2,%o1 |
---|
| 274 | retl |
---|
| 275 | ta 0x2 |
---|
| 276 | |
---|
| 277 | /* =============================================== */ |
---|
| 278 | |
---|
| 279 | /* flush all windows */ |
---|
| 280 | .global leonbare_flush_windows !void leonbare_flush_windows(); |
---|
| 281 | leonbare_flush_windows: |
---|
| 282 | set 6,%o1 |
---|
| 283 | retl |
---|
| 284 | ta 0x2 |
---|
| 285 | |
---|