1 /* $Id: ttable.h,v 1.17 2001/11/28 23:32:16 davem Exp $ */ 2 #ifndef _SPARC64_TTABLE_H 3 #define _SPARC64_TTABLE_H 4 5 #include <linux/config.h> 6 #include <asm/asm_offsets.h> 7 #include <asm/utrap.h> 8 9 #define BOOT_KERNEL b sparc64_boot; nop; nop; nop; nop; nop; nop; nop; 10 11 /* We need a "cleaned" instruction... */ 12 #define CLEAN_WINDOW \ 13 rdpr %cleanwin, %l0; add %l0, 1, %l0; \ 14 wrpr %l0, 0x0, %cleanwin; \ 15 clr %o0; clr %o1; clr %o2; clr %o3; \ 16 clr %o4; clr %o5; clr %o6; clr %o7; \ 17 clr %l0; clr %l1; clr %l2; clr %l3; \ 18 clr %l4; clr %l5; clr %l6; clr %l7; \ 19 retry; \ 20 nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; 21 22 #define TRAP(routine) \ 23 sethi %hi(109f), %g7; \ 24 ba,pt %xcc, etrap; \ 25 109: or %g7, %lo(109b), %g7; \ 26 call routine; \ 27 add %sp, PTREGS_OFF, %o0; \ 28 ba,pt %xcc, rtrap; \ 29 clr %l6; \ 30 nop; 31 32 #define TRAP_7INSNS(routine) \ 33 sethi %hi(109f), %g7; \ 34 ba,pt %xcc, etrap; \ 35 109: or %g7, %lo(109b), %g7; \ 36 call routine; \ 37 add %sp, PTREGS_OFF, %o0; \ 38 ba,pt %xcc, rtrap; \ 39 clr %l6; 40 41 #define TRAP_SAVEFPU(routine) \ 42 sethi %hi(109f), %g7; \ 43 ba,pt %xcc, do_fptrap; \ 44 109: or %g7, %lo(109b), %g7; \ 45 call routine; \ 46 add %sp, PTREGS_OFF, %o0; \ 47 ba,pt %xcc, rtrap; \ 48 clr %l6; \ 49 nop; 50 51 #define TRAP_NOSAVE(routine) \ 52 ba,pt %xcc, routine; \ 53 nop; \ 54 nop; nop; nop; nop; nop; nop; 55 56 #define TRAP_NOSAVE_7INSNS(routine) \ 57 ba,pt %xcc, routine; \ 58 nop; \ 59 nop; nop; nop; nop; nop; 60 61 #define TRAPTL1(routine) \ 62 sethi %hi(109f), %g7; \ 63 ba,pt %xcc, etraptl1; \ 64 109: or %g7, %lo(109b), %g7; \ 65 call routine; \ 66 add %sp, PTREGS_OFF, %o0; \ 67 ba,pt %xcc, rtrap; \ 68 clr %l6; \ 69 nop; 70 71 #define TRAP_ARG(routine, arg) \ 72 sethi %hi(109f), %g7; \ 73 ba,pt %xcc, etrap; \ 74 109: or %g7, %lo(109b), %g7; \ 75 add %sp, PTREGS_OFF, %o0; \ 76 call routine; \ 77 mov arg, %o1; \ 78 ba,pt %xcc, rtrap; \ 79 clr %l6; 80 81 #define TRAPTL1_ARG(routine, arg) \ 82 sethi %hi(109f), %g7; \ 83 ba,pt %xcc, etraptl1; \ 84 109: or %g7, %lo(109b), %g7; \ 85 add %sp, PTREGS_OFF, %o0; \ 86 call routine; \ 87 mov arg, %o1; \ 88 ba,pt %xcc, rtrap; \ 89 clr %l6; 90 91 #define SYSCALL_TRAP(routine, systbl) \ 92 sethi %hi(109f), %g7; \ 93 ba,pt %xcc, scetrap; \ 94 109: or %g7, %lo(109b), %g7; \ 95 ba,pt %xcc, routine; \ 96 sethi %hi(systbl), %l7; \ 97 nop; nop; nop; 98 99 #define INDIRECT_SOLARIS_SYSCALL(num) \ 100 sethi %hi(109f), %g7; \ 101 ba,pt %xcc, etrap; \ 102 109: or %g7, %lo(109b), %g7; \ 103 ba,pt %xcc, tl0_solaris + 0xc; \ 104 mov num, %g1; \ 105 nop;nop;nop; 106 107 #define TRAP_UTRAP(handler,lvl) \ 108 ldx [%g6 + AOFF_task_thread + AOFF_thread_utraps], %g1; \ 109 sethi %hi(109f), %g7; \ 110 brz,pn %g1, utrap; \ 111 or %g7, %lo(109f), %g7; \ 112 ba,pt %xcc, utrap; \ 113 109: ldx [%g1 + handler*8], %g1; \ 114 ba,pt %xcc, utrap_ill; \ 115 mov lvl, %o1; 116 117 #ifdef CONFIG_SUNOS_EMUL 118 #define SUNOS_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sunos_sys_table) 119 #else 120 #define SUNOS_SYSCALL_TRAP TRAP(sunos_syscall) 121 #endif 122 #define LINUX_32BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sys_call_table32) 123 #define LINUX_64BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall, sys_call_table64) 124 #define GETCC_TRAP TRAP(getcc) 125 #define SETCC_TRAP TRAP(setcc) 126 #ifdef CONFIG_SOLARIS_EMUL 127 #define SOLARIS_SYSCALL_TRAP TRAP(solaris_sparc_syscall) 128 #else 129 #define SOLARIS_SYSCALL_TRAP TRAP(solaris_syscall) 130 #endif 131 /* FIXME: Write these actually */ 132 #define NETBSD_SYSCALL_TRAP TRAP(netbsd_syscall) 133 #define BREAKPOINT_TRAP TRAP(breakpoint_trap) 134 135 #define TRAP_IRQ(routine, level) \ 136 rdpr %pil, %g2; \ 137 wrpr %g0, 15, %pil; \ 138 b,pt %xcc, etrap_irq; \ 139 rd %pc, %g7; \ 140 mov level, %o0; \ 141 call routine; \ 142 add %sp, PTREGS_OFF, %o1; \ 143 ba,a,pt %xcc, rtrap_clr_l6; 144 145 #define TICK_SMP_IRQ \ 146 rdpr %pil, %g2; \ 147 wrpr %g0, 15, %pil; \ 148 sethi %hi(109f), %g7; \ 149 b,pt %xcc, etrap_irq; \ 150 109: or %g7, %lo(109b), %g7; \ 151 call smp_percpu_timer_interrupt; \ 152 add %sp, PTREGS_OFF, %o0; \ 153 ba,a,pt %xcc, rtrap_clr_l6; 154 155 #define TRAP_IVEC TRAP_NOSAVE(do_ivec) 156 157 #define BTRAP(lvl) TRAP_ARG(bad_trap, lvl) 158 159 #define BTRAPTL1(lvl) TRAPTL1_ARG(bad_trap_tl1, lvl) 160 161 #define FLUSH_WINDOW_TRAP \ 162 ba,pt %xcc, etrap; \ 163 rd %pc, %g7; \ 164 flushw; \ 165 ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1; \ 166 add %l1, 4, %l2; \ 167 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]; \ 168 ba,pt %xcc, rtrap_clr_l6; \ 169 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]; 170 171 /* Before touching these macros, you owe it to yourself to go and 172 * see how arch/sparc64/kernel/winfixup.S works... -DaveM 173 * 174 * For the user cases we used to use the %asi register, but 175 * it turns out that the "wr xxx, %asi" costs ~5 cycles, so 176 * now we use immediate ASI loads and stores instead. Kudos 177 * to Greg Onufer for pointing out this performance anomaly. 178 * 179 * Further note that we cannot use the g2, g4, g5, and g7 alternate 180 * globals in the spill routines, check out the save instruction in 181 * arch/sparc64/kernel/etrap.S to see what I mean about g2, and 182 * g4/g5 are the globals which are preserved by etrap processing 183 * for the caller of it. The g7 register is the return pc for 184 * etrap. Finally, g6 is the current thread register so we cannot 185 * us it in the spill handlers either. Most of these rules do not 186 * apply to fill processing, only g6 is not usable. 187 */ 188 189 /* Normal kernel spill */ 190 #define SPILL_0_NORMAL \ 191 stx %l0, [%sp + STACK_BIAS + 0x00]; \ 192 stx %l1, [%sp + STACK_BIAS + 0x08]; \ 193 stx %l2, [%sp + STACK_BIAS + 0x10]; \ 194 stx %l3, [%sp + STACK_BIAS + 0x18]; \ 195 stx %l4, [%sp + STACK_BIAS + 0x20]; \ 196 stx %l5, [%sp + STACK_BIAS + 0x28]; \ 197 stx %l6, [%sp + STACK_BIAS + 0x30]; \ 198 stx %l7, [%sp + STACK_BIAS + 0x38]; \ 199 stx %i0, [%sp + STACK_BIAS + 0x40]; \ 200 stx %i1, [%sp + STACK_BIAS + 0x48]; \ 201 stx %i2, [%sp + STACK_BIAS + 0x50]; \ 202 stx %i3, [%sp + STACK_BIAS + 0x58]; \ 203 stx %i4, [%sp + STACK_BIAS + 0x60]; \ 204 stx %i5, [%sp + STACK_BIAS + 0x68]; \ 205 stx %i6, [%sp + STACK_BIAS + 0x70]; \ 206 stx %i7, [%sp + STACK_BIAS + 0x78]; \ 207 saved; retry; nop; nop; nop; nop; nop; nop; \ 208 nop; nop; nop; nop; nop; nop; nop; nop; 209 210 /* Normal 64bit spill */ 211 #define SPILL_1_GENERIC(ASI) \ 212 add %sp, STACK_BIAS + 0x00, %g1; \ 213 stxa %l0, [%g1 + %g0] ASI; \ 214 mov 0x08, %g3; \ 215 stxa %l1, [%g1 + %g3] ASI; \ 216 add %g1, 0x10, %g1; \ 217 stxa %l2, [%g1 + %g0] ASI; \ 218 stxa %l3, [%g1 + %g3] ASI; \ 219 add %g1, 0x10, %g1; \ 220 stxa %l4, [%g1 + %g0] ASI; \ 221 stxa %l5, [%g1 + %g3] ASI; \ 222 add %g1, 0x10, %g1; \ 223 stxa %l6, [%g1 + %g0] ASI; \ 224 stxa %l7, [%g1 + %g3] ASI; \ 225 add %g1, 0x10, %g1; \ 226 stxa %i0, [%g1 + %g0] ASI; \ 227 stxa %i1, [%g1 + %g3] ASI; \ 228 add %g1, 0x10, %g1; \ 229 stxa %i2, [%g1 + %g0] ASI; \ 230 stxa %i3, [%g1 + %g3] ASI; \ 231 add %g1, 0x10, %g1; \ 232 stxa %i4, [%g1 + %g0] ASI; \ 233 stxa %i5, [%g1 + %g3] ASI; \ 234 add %g1, 0x10, %g1; \ 235 stxa %i6, [%g1 + %g0] ASI; \ 236 stxa %i7, [%g1 + %g3] ASI; \ 237 saved; \ 238 retry; nop; nop; \ 239 b,a,pt %xcc, spill_fixup_dax; \ 240 b,a,pt %xcc, spill_fixup_mna; \ 241 b,a,pt %xcc, spill_fixup; 242 243 /* Normal 32bit spill */ 244 #define SPILL_2_GENERIC(ASI) \ 245 srl %sp, 0, %sp; \ 246 stwa %l0, [%sp + %g0] ASI; \ 247 mov 0x04, %g3; \ 248 stwa %l1, [%sp + %g3] ASI; \ 249 add %sp, 0x08, %g1; \ 250 stwa %l2, [%g1 + %g0] ASI; \ 251 stwa %l3, [%g1 + %g3] ASI; \ 252 add %g1, 0x08, %g1; \ 253 stwa %l4, [%g1 + %g0] ASI; \ 254 stwa %l5, [%g1 + %g3] ASI; \ 255 add %g1, 0x08, %g1; \ 256 stwa %l6, [%g1 + %g0] ASI; \ 257 stwa %l7, [%g1 + %g3] ASI; \ 258 add %g1, 0x08, %g1; \ 259 stwa %i0, [%g1 + %g0] ASI; \ 260 stwa %i1, [%g1 + %g3] ASI; \ 261 add %g1, 0x08, %g1; \ 262 stwa %i2, [%g1 + %g0] ASI; \ 263 stwa %i3, [%g1 + %g3] ASI; \ 264 add %g1, 0x08, %g1; \ 265 stwa %i4, [%g1 + %g0] ASI; \ 266 stwa %i5, [%g1 + %g3] ASI; \ 267 add %g1, 0x08, %g1; \ 268 stwa %i6, [%g1 + %g0] ASI; \ 269 stwa %i7, [%g1 + %g3] ASI; \ 270 saved; \ 271 retry; nop; nop; \ 272 b,a,pt %xcc, spill_fixup_dax; \ 273 b,a,pt %xcc, spill_fixup_mna; \ 274 b,a,pt %xcc, spill_fixup; 275 276 #define SPILL_1_NORMAL SPILL_1_GENERIC(ASI_AIUP) 277 #define SPILL_2_NORMAL SPILL_2_GENERIC(ASI_AIUP) 278 #define SPILL_3_NORMAL SPILL_0_NORMAL 279 #define SPILL_4_NORMAL SPILL_0_NORMAL 280 #define SPILL_5_NORMAL SPILL_0_NORMAL 281 #define SPILL_6_NORMAL SPILL_0_NORMAL 282 #define SPILL_7_NORMAL SPILL_0_NORMAL 283 284 #define SPILL_0_OTHER SPILL_0_NORMAL 285 #define SPILL_1_OTHER SPILL_1_GENERIC(ASI_AIUS) 286 #define SPILL_2_OTHER SPILL_2_GENERIC(ASI_AIUS) 287 #define SPILL_3_OTHER SPILL_3_NORMAL 288 #define SPILL_4_OTHER SPILL_4_NORMAL 289 #define SPILL_5_OTHER SPILL_5_NORMAL 290 #define SPILL_6_OTHER SPILL_6_NORMAL 291 #define SPILL_7_OTHER SPILL_7_NORMAL 292 293 /* Normal kernel fill */ 294 #define FILL_0_NORMAL \ 295 ldx [%sp + STACK_BIAS + 0x00], %l0; \ 296 ldx [%sp + STACK_BIAS + 0x08], %l1; \ 297 ldx [%sp + STACK_BIAS + 0x10], %l2; \ 298 ldx [%sp + STACK_BIAS + 0x18], %l3; \ 299 ldx [%sp + STACK_BIAS + 0x20], %l4; \ 300 ldx [%sp + STACK_BIAS + 0x28], %l5; \ 301 ldx [%sp + STACK_BIAS + 0x30], %l6; \ 302 ldx [%sp + STACK_BIAS + 0x38], %l7; \ 303 ldx [%sp + STACK_BIAS + 0x40], %i0; \ 304 ldx [%sp + STACK_BIAS + 0x48], %i1; \ 305 ldx [%sp + STACK_BIAS + 0x50], %i2; \ 306 ldx [%sp + STACK_BIAS + 0x58], %i3; \ 307 ldx [%sp + STACK_BIAS + 0x60], %i4; \ 308 ldx [%sp + STACK_BIAS + 0x68], %i5; \ 309 ldx [%sp + STACK_BIAS + 0x70], %i6; \ 310 ldx [%sp + STACK_BIAS + 0x78], %i7; \ 311 restored; retry; nop; nop; nop; nop; nop; nop; \ 312 nop; nop; nop; nop; nop; nop; nop; nop; 313 314 /* Normal 64bit fill */ 315 #define FILL_1_GENERIC(ASI) \ 316 add %sp, STACK_BIAS + 0x00, %g1; \ 317 ldxa [%g1 + %g0] ASI, %l0; \ 318 mov 0x08, %g2; \ 319 mov 0x10, %g3; \ 320 ldxa [%g1 + %g2] ASI, %l1; \ 321 mov 0x18, %g5; \ 322 ldxa [%g1 + %g3] ASI, %l2; \ 323 ldxa [%g1 + %g5] ASI, %l3; \ 324 add %g1, 0x20, %g1; \ 325 ldxa [%g1 + %g0] ASI, %l4; \ 326 ldxa [%g1 + %g2] ASI, %l5; \ 327 ldxa [%g1 + %g3] ASI, %l6; \ 328 ldxa [%g1 + %g5] ASI, %l7; \ 329 add %g1, 0x20, %g1; \ 330 ldxa [%g1 + %g0] ASI, %i0; \ 331 ldxa [%g1 + %g2] ASI, %i1; \ 332 ldxa [%g1 + %g3] ASI, %i2; \ 333 ldxa [%g1 + %g5] ASI, %i3; \ 334 add %g1, 0x20, %g1; \ 335 ldxa [%g1 + %g0] ASI, %i4; \ 336 ldxa [%g1 + %g2] ASI, %i5; \ 337 ldxa [%g1 + %g3] ASI, %i6; \ 338 ldxa [%g1 + %g5] ASI, %i7; \ 339 restored; \ 340 retry; nop; nop; nop; nop; \ 341 b,a,pt %xcc, fill_fixup_dax; \ 342 b,a,pt %xcc, fill_fixup_mna; \ 343 b,a,pt %xcc, fill_fixup; 344 345 /* Normal 32bit fill */ 346 #define FILL_2_GENERIC(ASI) \ 347 srl %sp, 0, %sp; \ 348 lduwa [%sp + %g0] ASI, %l0; \ 349 mov 0x04, %g2; \ 350 mov 0x08, %g3; \ 351 lduwa [%sp + %g2] ASI, %l1; \ 352 mov 0x0c, %g5; \ 353 lduwa [%sp + %g3] ASI, %l2; \ 354 lduwa [%sp + %g5] ASI, %l3; \ 355 add %sp, 0x10, %g1; \ 356 lduwa [%g1 + %g0] ASI, %l4; \ 357 lduwa [%g1 + %g2] ASI, %l5; \ 358 lduwa [%g1 + %g3] ASI, %l6; \ 359 lduwa [%g1 + %g5] ASI, %l7; \ 360 add %g1, 0x10, %g1; \ 361 lduwa [%g1 + %g0] ASI, %i0; \ 362 lduwa [%g1 + %g2] ASI, %i1; \ 363 lduwa [%g1 + %g3] ASI, %i2; \ 364 lduwa [%g1 + %g5] ASI, %i3; \ 365 add %g1, 0x10, %g1; \ 366 lduwa [%g1 + %g0] ASI, %i4; \ 367 lduwa [%g1 + %g2] ASI, %i5; \ 368 lduwa [%g1 + %g3] ASI, %i6; \ 369 lduwa [%g1 + %g5] ASI, %i7; \ 370 restored; \ 371 retry; nop; nop; nop; nop; \ 372 b,a,pt %xcc, fill_fixup_dax; \ 373 b,a,pt %xcc, fill_fixup_mna; \ 374 b,a,pt %xcc, fill_fixup; 375 376 #define FILL_1_NORMAL FILL_1_GENERIC(ASI_AIUP) 377 #define FILL_2_NORMAL FILL_2_GENERIC(ASI_AIUP) 378 #define FILL_3_NORMAL FILL_0_NORMAL 379 #define FILL_4_NORMAL FILL_0_NORMAL 380 #define FILL_5_NORMAL FILL_0_NORMAL 381 #define FILL_6_NORMAL FILL_0_NORMAL 382 #define FILL_7_NORMAL FILL_0_NORMAL 383 384 #define FILL_0_OTHER FILL_0_NORMAL 385 #define FILL_1_OTHER FILL_1_GENERIC(ASI_AIUS) 386 #define FILL_2_OTHER FILL_2_GENERIC(ASI_AIUS) 387 #define FILL_3_OTHER FILL_3_NORMAL 388 #define FILL_4_OTHER FILL_4_NORMAL 389 #define FILL_5_OTHER FILL_5_NORMAL 390 #define FILL_6_OTHER FILL_6_NORMAL 391 #define FILL_7_OTHER FILL_7_NORMAL 392 393 #endif /* !(_SPARC64_TTABLE_H) */ 394