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 1101: 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 1272: 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 2183: 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 2264: 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 2365: 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 2466: 247 subcc %i1, 6, %g0 ! syscall 6, flush windows 248 bne 1f 249 nop 250 251 ba,a _irqcall_flush_windows 252 2531: 254 ta 0 ! halt 2559: ! 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); 263leonbare_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(); 272leonbare_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(); 281leonbare_flush_windows: 282 set 6,%o1 283 retl 284 ta 0x2 285 286