1 /* !! 1 /* arch/sparc/kernel/entry.S: Sparc trap low-level entry points. 2 * This file is subject to the terms and condi << 3 * License. See the file "COPYING" in the mai << 4 * for more details. << 5 * 2 * 6 * Copyright (C) 1994 - 2000, 2001, 2003 Ralf !! 3 * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net) 7 * Copyright (C) 1999, 2000 Silicon Graphics, !! 4 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) 8 * Copyright (C) 2001 MIPS Technologies, Inc. !! 5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) >> 6 * Copyright (C) 1996-1999 Jakub Jelinek (jj@sunsite.mff.cuni.cz) >> 7 * Copyright (C) 1997 Anton Blanchard (anton@progsoc.uts.edu.au) 9 */ 8 */ 10 9 11 #include <asm/asm.h> !! 10 #include <linux/errno.h> 12 #include <asm/asmmacro.h> !! 11 13 #include <asm/compiler.h> !! 12 #include <asm/head.h> 14 #include <asm/irqflags.h> !! 13 #include <asm/asi.h> 15 #include <asm/regdef.h> !! 14 #include <asm/smp.h> 16 #include <asm/mipsregs.h> !! 15 #include <asm/contregs.h> 17 #include <asm/stackframe.h> !! 16 #include <asm/ptrace.h> 18 #include <asm/isadep.h> !! 17 #include <asm/asm-offsets.h> >> 18 #include <asm/psr.h> >> 19 #include <asm/vaddrs.h> >> 20 #include <asm/memreg.h> >> 21 #include <asm/page.h> >> 22 #include <asm/pgtable.h> >> 23 #include <asm/pgtsun4c.h> >> 24 #include <asm/winmacro.h> >> 25 #include <asm/signal.h> >> 26 #include <asm/obio.h> >> 27 #include <asm/mxcc.h> 19 #include <asm/thread_info.h> 28 #include <asm/thread_info.h> >> 29 #include <asm/param.h> >> 30 #include <asm/unistd.h> 20 31 21 #ifndef CONFIG_PREEMPTION !! 32 #include <asm/asmmacro.h> 22 #define resume_kernel restore_all !! 33 23 #else !! 34 #define curptr g6 24 #define __ret_from_irq ret_from_exception !! 35 25 #endif !! 36 /* These are just handy. */ >> 37 #define _SV save %sp, -STACKFRAME_SZ, %sp >> 38 #define _RS restore >> 39 >> 40 #define FLUSH_ALL_KERNEL_WINDOWS \ >> 41 _SV; _SV; _SV; _SV; _SV; _SV; _SV; \ >> 42 _RS; _RS; _RS; _RS; _RS; _RS; _RS; 26 43 27 .text 44 .text 28 .align 5 << 29 #ifndef CONFIG_PREEMPTION << 30 FEXPORT(ret_from_exception) << 31 local_irq_disable << 32 b __ret_from_irq << 33 #endif << 34 FEXPORT(ret_from_irq) << 35 LONG_S s0, TI_REGS($28) << 36 FEXPORT(__ret_from_irq) << 37 /* << 38 * We can be coming here from a syscall done i << 39 * e.g. a failed kernel_execve(). << 40 */ << 41 resume_userspace_check: << 42 LONG_L t0, PT_STATUS(sp) << 43 andi t0, t0, KU_USER << 44 beqz t0, resume_kernel << 45 << 46 resume_userspace: << 47 local_irq_disable # make << 48 # inte << 49 # betw << 50 LONG_L a2, TI_FLAGS($28) # curr << 51 andi t0, a2, _TIF_WORK_MASK # (ign << 52 bnez t0, work_pending << 53 j restore_all << 54 << 55 #ifdef CONFIG_PREEMPTION << 56 resume_kernel: << 57 local_irq_disable << 58 lw t0, TI_PRE_COUNT($28) << 59 bnez t0, restore_all << 60 LONG_L t0, TI_FLAGS($28) << 61 andi t1, t0, _TIF_NEED_RESCHED << 62 beqz t1, restore_all << 63 LONG_L t0, PT_STATUS(sp) << 64 andi t0, 1 << 65 beqz t0, restore_all << 66 PTR_LA ra, restore_all << 67 j preempt_schedule_irq << 68 #endif << 69 45 70 FEXPORT(ret_from_kernel_thread) !! 46 #ifdef CONFIG_KGDB 71 jal schedule_tail # a0 = !! 47 .align 4 72 move a0, s1 !! 48 .globl arch_kgdb_breakpoint 73 jal s0 !! 49 .type arch_kgdb_breakpoint,#function 74 j syscall_exit !! 50 arch_kgdb_breakpoint: 75 !! 51 ta 0x7d 76 FEXPORT(ret_from_fork) !! 52 retl 77 jal schedule_tail # a0 = !! 53 nop 78 !! 54 .size arch_kgdb_breakpoint,.-arch_kgdb_breakpoint 79 FEXPORT(syscall_exit) << 80 #ifdef CONFIG_DEBUG_RSEQ << 81 move a0, sp << 82 jal rseq_syscall << 83 #endif << 84 local_irq_disable # make << 85 # sign << 86 # samp << 87 LONG_L a2, TI_FLAGS($28) # curr << 88 li t0, _TIF_ALLWORK_MASK << 89 and t0, a2, t0 << 90 bnez t0, syscall_exit_work << 91 << 92 restore_all: # rest << 93 .set noat << 94 RESTORE_TEMP << 95 RESTORE_AT << 96 RESTORE_STATIC << 97 restore_partial: # restore part << 98 #ifdef CONFIG_TRACE_IRQFLAGS << 99 SAVE_STATIC << 100 SAVE_AT << 101 SAVE_TEMP << 102 LONG_L v0, PT_STATUS(sp) << 103 #if defined(CONFIG_CPU_R3000) << 104 and v0, ST0_IEP << 105 #else << 106 and v0, ST0_IE << 107 #endif 55 #endif 108 beqz v0, 1f !! 56 109 jal trace_hardirqs_on !! 57 #if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) >> 58 .align 4 >> 59 .globl floppy_hardint >> 60 floppy_hardint: >> 61 /* >> 62 * This code cannot touch registers %l0 %l1 and %l2 >> 63 * because SAVE_ALL depends on their values. It depends >> 64 * on %l3 also, but we regenerate it before a call. >> 65 * Other registers are: >> 66 * %l3 -- base address of fdc registers >> 67 * %l4 -- pdma_vaddr >> 68 * %l5 -- scratch for ld/st address >> 69 * %l6 -- pdma_size >> 70 * %l7 -- scratch [floppy byte, ld/st address, aux. data] >> 71 */ >> 72 >> 73 /* Do we have work to do? */ >> 74 sethi %hi(doing_pdma), %l7 >> 75 ld [%l7 + %lo(doing_pdma)], %l7 >> 76 cmp %l7, 0 >> 77 be floppy_dosoftint >> 78 nop >> 79 >> 80 /* Load fdc register base */ >> 81 sethi %hi(fdc_status), %l3 >> 82 ld [%l3 + %lo(fdc_status)], %l3 >> 83 >> 84 /* Setup register addresses */ >> 85 sethi %hi(pdma_vaddr), %l5 ! transfer buffer >> 86 ld [%l5 + %lo(pdma_vaddr)], %l4 >> 87 sethi %hi(pdma_size), %l5 ! bytes to go >> 88 ld [%l5 + %lo(pdma_size)], %l6 >> 89 next_byte: >> 90 ldub [%l3], %l7 >> 91 >> 92 andcc %l7, 0x80, %g0 ! Does fifo still have data >> 93 bz floppy_fifo_emptied ! fifo has been emptied... >> 94 andcc %l7, 0x20, %g0 ! in non-dma mode still? >> 95 bz floppy_overrun ! nope, overrun >> 96 andcc %l7, 0x40, %g0 ! 0=write 1=read >> 97 bz floppy_write >> 98 sub %l6, 0x1, %l6 >> 99 >> 100 /* Ok, actually read this byte */ >> 101 ldub [%l3 + 1], %l7 >> 102 orcc %g0, %l6, %g0 >> 103 stb %l7, [%l4] >> 104 bne next_byte >> 105 add %l4, 0x1, %l4 >> 106 >> 107 b floppy_tdone >> 108 nop >> 109 >> 110 floppy_write: >> 111 /* Ok, actually write this byte */ >> 112 ldub [%l4], %l7 >> 113 orcc %g0, %l6, %g0 >> 114 stb %l7, [%l3 + 1] >> 115 bne next_byte >> 116 add %l4, 0x1, %l4 >> 117 >> 118 /* fall through... */ >> 119 floppy_tdone: >> 120 sethi %hi(pdma_vaddr), %l5 >> 121 st %l4, [%l5 + %lo(pdma_vaddr)] >> 122 sethi %hi(pdma_size), %l5 >> 123 st %l6, [%l5 + %lo(pdma_size)] >> 124 /* Flip terminal count pin */ >> 125 set auxio_register, %l7 >> 126 ld [%l7], %l7 >> 127 >> 128 set sparc_cpu_model, %l5 >> 129 ld [%l5], %l5 >> 130 subcc %l5, 1, %g0 /* enum { sun4c = 1 }; */ >> 131 be 1f >> 132 ldub [%l7], %l5 >> 133 >> 134 or %l5, 0xc2, %l5 >> 135 stb %l5, [%l7] >> 136 andn %l5, 0x02, %l5 110 b 2f 137 b 2f 111 1: jal trace_hardirqs_off !! 138 nop >> 139 >> 140 1: >> 141 or %l5, 0xf4, %l5 >> 142 stb %l5, [%l7] >> 143 andn %l5, 0x04, %l5 >> 144 112 2: 145 2: 113 RESTORE_TEMP !! 146 /* Kill some time so the bits set */ 114 RESTORE_AT !! 147 WRITE_PAUSE 115 RESTORE_STATIC !! 148 WRITE_PAUSE 116 #endif !! 149 117 RESTORE_SOME !! 150 stb %l5, [%l7] 118 RESTORE_SP_AND_RET !! 151 119 .set at !! 152 /* Prevent recursion */ 120 !! 153 sethi %hi(doing_pdma), %l7 121 work_pending: !! 154 b floppy_dosoftint 122 andi t0, a2, _TIF_NEED_RESCHED # a2 !! 155 st %g0, [%l7 + %lo(doing_pdma)] 123 beqz t0, work_notifysig !! 156 124 work_resched: !! 157 /* We emptied the FIFO, but we haven't read everything 125 TRACE_IRQS_OFF !! 158 * as of yet. Store the current transfer address and 126 jal schedule !! 159 * bytes left to read so we can continue when the next 127 !! 160 * fast IRQ comes in. 128 local_irq_disable # make !! 161 */ 129 # sign !! 162 floppy_fifo_emptied: 130 # samp !! 163 sethi %hi(pdma_vaddr), %l5 131 LONG_L a2, TI_FLAGS($28) !! 164 st %l4, [%l5 + %lo(pdma_vaddr)] 132 andi t0, a2, _TIF_WORK_MASK # is t !! 165 sethi %hi(pdma_size), %l7 133 # othe !! 166 st %l6, [%l7 + %lo(pdma_size)] 134 beqz t0, restore_all !! 167 135 andi t0, a2, _TIF_NEED_RESCHED !! 168 /* Restore condition codes */ 136 bnez t0, work_resched !! 169 wr %l0, 0x0, %psr 137 !! 170 WRITE_PAUSE 138 work_notifysig: # deal !! 171 139 # noti !! 172 jmp %l1 140 move a0, sp !! 173 rett %l2 141 li a1, 0 !! 174 142 jal do_notify_resume # a2 a !! 175 floppy_overrun: 143 j resume_userspace_check !! 176 sethi %hi(pdma_vaddr), %l5 144 !! 177 st %l4, [%l5 + %lo(pdma_vaddr)] 145 FEXPORT(syscall_exit_partial) !! 178 sethi %hi(pdma_size), %l5 146 #ifdef CONFIG_DEBUG_RSEQ !! 179 st %l6, [%l5 + %lo(pdma_size)] 147 move a0, sp !! 180 /* Prevent recursion */ 148 jal rseq_syscall !! 181 sethi %hi(doing_pdma), %l7 >> 182 st %g0, [%l7 + %lo(doing_pdma)] >> 183 >> 184 /* fall through... */ >> 185 floppy_dosoftint: >> 186 rd %wim, %l3 >> 187 SAVE_ALL >> 188 >> 189 /* Set all IRQs off. */ >> 190 or %l0, PSR_PIL, %l4 >> 191 wr %l4, 0x0, %psr >> 192 WRITE_PAUSE >> 193 wr %l4, PSR_ET, %psr >> 194 WRITE_PAUSE >> 195 >> 196 mov 11, %o0 ! floppy irq level (unused anyway) >> 197 mov %g0, %o1 ! devid is not used in fast interrupts >> 198 call sparc_floppy_irq >> 199 add %sp, STACKFRAME_SZ, %o2 ! struct pt_regs *regs >> 200 >> 201 RESTORE_ALL >> 202 >> 203 #endif /* (CONFIG_BLK_DEV_FD) */ >> 204 >> 205 /* Bad trap handler */ >> 206 .globl bad_trap_handler >> 207 bad_trap_handler: >> 208 SAVE_ALL >> 209 >> 210 wr %l0, PSR_ET, %psr >> 211 WRITE_PAUSE >> 212 >> 213 add %sp, STACKFRAME_SZ, %o0 ! pt_regs >> 214 call do_hw_interrupt >> 215 mov %l7, %o1 ! trap number >> 216 >> 217 RESTORE_ALL >> 218 >> 219 /* For now all IRQ's not registered get sent here. handler_irq() will >> 220 * see if a routine is registered to handle this interrupt and if not >> 221 * it will say so on the console. >> 222 */ >> 223 >> 224 .align 4 >> 225 .globl real_irq_entry, patch_handler_irq >> 226 real_irq_entry: >> 227 SAVE_ALL >> 228 >> 229 #ifdef CONFIG_SMP >> 230 .globl patchme_maybe_smp_msg >> 231 >> 232 cmp %l7, 12 >> 233 patchme_maybe_smp_msg: >> 234 bgu maybe_smp4m_msg >> 235 nop 149 #endif 236 #endif 150 local_irq_disable # make << 151 # chan << 152 LONG_L a2, TI_FLAGS($28) # curr << 153 li t0, _TIF_ALLWORK_MASK << 154 and t0, a2 << 155 beqz t0, restore_partial << 156 SAVE_STATIC << 157 syscall_exit_work: << 158 LONG_L t0, PT_STATUS(sp) << 159 andi t0, t0, KU_USER << 160 beqz t0, resume_kernel << 161 li t0, _TIF_WORK_SYSCALL_EXIT << 162 and t0, a2 # a2 i << 163 beqz t0, work_pending # trac << 164 local_irq_enable # coul << 165 # call << 166 TRACE_IRQS_ON << 167 move a0, sp << 168 jal syscall_trace_leave << 169 b resume_userspace << 170 237 171 #if defined(CONFIG_CPU_MIPSR2) || defined(CONF !! 238 real_irq_continue: 172 defined(CONFIG_CPU_MIPSR6) || defined(CONF !! 239 or %l0, PSR_PIL, %g2 >> 240 wr %g2, 0x0, %psr >> 241 WRITE_PAUSE >> 242 wr %g2, PSR_ET, %psr >> 243 WRITE_PAUSE >> 244 mov %l7, %o0 ! irq level >> 245 patch_handler_irq: >> 246 call handler_irq >> 247 add %sp, STACKFRAME_SZ, %o1 ! pt_regs ptr >> 248 or %l0, PSR_PIL, %g2 ! restore PIL after handler_irq >> 249 wr %g2, PSR_ET, %psr ! keep ET up >> 250 WRITE_PAUSE >> 251 >> 252 RESTORE_ALL >> 253 >> 254 #ifdef CONFIG_SMP >> 255 /* SMP per-cpu ticker interrupts are handled specially. */ >> 256 smp4m_ticker: >> 257 bne real_irq_continue+4 >> 258 or %l0, PSR_PIL, %g2 >> 259 wr %g2, 0x0, %psr >> 260 WRITE_PAUSE >> 261 wr %g2, PSR_ET, %psr >> 262 WRITE_PAUSE >> 263 call smp4m_percpu_timer_interrupt >> 264 add %sp, STACKFRAME_SZ, %o0 >> 265 wr %l0, PSR_ET, %psr >> 266 WRITE_PAUSE >> 267 RESTORE_ALL >> 268 >> 269 /* Here is where we check for possible SMP IPI passed to us >> 270 * on some level other than 15 which is the NMI and only used >> 271 * for cross calls. That has a separate entry point below. >> 272 */ >> 273 maybe_smp4m_msg: >> 274 GET_PROCESSOR4M_ID(o3) >> 275 sethi %hi(sun4m_irq_percpu), %l5 >> 276 sll %o3, 2, %o3 >> 277 or %l5, %lo(sun4m_irq_percpu), %o5 >> 278 sethi %hi(0x40000000), %o2 >> 279 ld [%o5 + %o3], %o1 >> 280 ld [%o1 + 0x00], %o3 ! sun4m_irq_percpu[cpu]->pending >> 281 andcc %o3, %o2, %g0 >> 282 be,a smp4m_ticker >> 283 cmp %l7, 14 >> 284 st %o2, [%o1 + 0x04] ! sun4m_irq_percpu[cpu]->clear=0x40000000 >> 285 WRITE_PAUSE >> 286 ld [%o1 + 0x00], %g0 ! sun4m_irq_percpu[cpu]->pending >> 287 WRITE_PAUSE >> 288 or %l0, PSR_PIL, %l4 >> 289 wr %l4, 0x0, %psr >> 290 WRITE_PAUSE >> 291 wr %l4, PSR_ET, %psr >> 292 WRITE_PAUSE >> 293 call smp_reschedule_irq >> 294 nop >> 295 >> 296 RESTORE_ALL >> 297 >> 298 .align 4 >> 299 .globl linux_trap_ipi15_sun4m >> 300 linux_trap_ipi15_sun4m: >> 301 SAVE_ALL >> 302 sethi %hi(0x80000000), %o2 >> 303 GET_PROCESSOR4M_ID(o0) >> 304 sethi %hi(sun4m_irq_percpu), %l5 >> 305 or %l5, %lo(sun4m_irq_percpu), %o5 >> 306 sll %o0, 2, %o0 >> 307 ld [%o5 + %o0], %o5 >> 308 ld [%o5 + 0x00], %o3 ! sun4m_irq_percpu[cpu]->pending >> 309 andcc %o3, %o2, %g0 >> 310 be 1f ! Must be an NMI async memory error >> 311 st %o2, [%o5 + 0x04] ! sun4m_irq_percpu[cpu]->clear=0x80000000 >> 312 WRITE_PAUSE >> 313 ld [%o5 + 0x00], %g0 ! sun4m_irq_percpu[cpu]->pending >> 314 WRITE_PAUSE >> 315 or %l0, PSR_PIL, %l4 >> 316 wr %l4, 0x0, %psr >> 317 WRITE_PAUSE >> 318 wr %l4, PSR_ET, %psr >> 319 WRITE_PAUSE >> 320 call smp4m_cross_call_irq >> 321 nop >> 322 b ret_trap_lockless_ipi >> 323 clr %l6 >> 324 1: >> 325 /* NMI async memory error handling. */ >> 326 sethi %hi(0x80000000), %l4 >> 327 sethi %hi(sun4m_irq_global), %o5 >> 328 ld [%o5 + %lo(sun4m_irq_global)], %l5 >> 329 st %l4, [%l5 + 0x0c] ! sun4m_irq_global->mask_set=0x80000000 >> 330 WRITE_PAUSE >> 331 ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending >> 332 WRITE_PAUSE >> 333 or %l0, PSR_PIL, %l4 >> 334 wr %l4, 0x0, %psr >> 335 WRITE_PAUSE >> 336 wr %l4, PSR_ET, %psr >> 337 WRITE_PAUSE >> 338 call sun4m_nmi >> 339 nop >> 340 st %l4, [%l5 + 0x08] ! sun4m_irq_global->mask_clear=0x80000000 >> 341 WRITE_PAUSE >> 342 ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending >> 343 WRITE_PAUSE >> 344 RESTORE_ALL >> 345 >> 346 .globl smp4d_ticker >> 347 /* SMP per-cpu ticker interrupts are handled specially. */ >> 348 smp4d_ticker: >> 349 SAVE_ALL >> 350 or %l0, PSR_PIL, %g2 >> 351 sethi %hi(CC_ICLR), %o0 >> 352 sethi %hi(1 << 14), %o1 >> 353 or %o0, %lo(CC_ICLR), %o0 >> 354 stha %o1, [%o0] ASI_M_MXCC /* Clear PIL 14 in MXCC's ICLR */ >> 355 wr %g2, 0x0, %psr >> 356 WRITE_PAUSE >> 357 wr %g2, PSR_ET, %psr >> 358 WRITE_PAUSE >> 359 call smp4d_percpu_timer_interrupt >> 360 add %sp, STACKFRAME_SZ, %o0 >> 361 wr %l0, PSR_ET, %psr >> 362 WRITE_PAUSE >> 363 RESTORE_ALL >> 364 >> 365 .align 4 >> 366 .globl linux_trap_ipi15_sun4d >> 367 linux_trap_ipi15_sun4d: >> 368 SAVE_ALL >> 369 sethi %hi(CC_BASE), %o4 >> 370 sethi %hi(MXCC_ERR_ME|MXCC_ERR_PEW|MXCC_ERR_ASE|MXCC_ERR_PEE), %o2 >> 371 or %o4, (CC_EREG - CC_BASE), %o0 >> 372 ldda [%o0] ASI_M_MXCC, %o0 >> 373 andcc %o0, %o2, %g0 >> 374 bne 1f >> 375 sethi %hi(BB_STAT2), %o2 >> 376 lduba [%o2] ASI_M_CTL, %o2 >> 377 andcc %o2, BB_STAT2_MASK, %g0 >> 378 bne 2f >> 379 or %o4, (CC_ICLR - CC_BASE), %o0 >> 380 sethi %hi(1 << 15), %o1 >> 381 stha %o1, [%o0] ASI_M_MXCC /* Clear PIL 15 in MXCC's ICLR */ >> 382 or %l0, PSR_PIL, %l4 >> 383 wr %l4, 0x0, %psr >> 384 WRITE_PAUSE >> 385 wr %l4, PSR_ET, %psr >> 386 WRITE_PAUSE >> 387 call smp4d_cross_call_irq >> 388 nop >> 389 b ret_trap_lockless_ipi >> 390 clr %l6 >> 391 >> 392 1: /* MXCC error */ >> 393 2: /* BB error */ >> 394 /* Disable PIL 15 */ >> 395 set CC_IMSK, %l4 >> 396 lduha [%l4] ASI_M_MXCC, %l5 >> 397 sethi %hi(1 << 15), %l7 >> 398 or %l5, %l7, %l5 >> 399 stha %l5, [%l4] ASI_M_MXCC >> 400 /* FIXME */ >> 401 1: b,a 1b >> 402 >> 403 #endif /* CONFIG_SMP */ >> 404 >> 405 /* This routine handles illegal instructions and privileged >> 406 * instruction attempts from user code. >> 407 */ >> 408 .align 4 >> 409 .globl bad_instruction >> 410 bad_instruction: >> 411 sethi %hi(0xc1f80000), %l4 >> 412 ld [%l1], %l5 >> 413 sethi %hi(0x81d80000), %l7 >> 414 and %l5, %l4, %l5 >> 415 cmp %l5, %l7 >> 416 be 1f >> 417 SAVE_ALL >> 418 >> 419 wr %l0, PSR_ET, %psr ! re-enable traps >> 420 WRITE_PAUSE >> 421 >> 422 add %sp, STACKFRAME_SZ, %o0 >> 423 mov %l1, %o1 >> 424 mov %l2, %o2 >> 425 call do_illegal_instruction >> 426 mov %l0, %o3 >> 427 >> 428 RESTORE_ALL >> 429 >> 430 1: /* unimplemented flush - just skip */ >> 431 jmpl %l2, %g0 >> 432 rett %l2 + 4 >> 433 >> 434 .align 4 >> 435 .globl priv_instruction >> 436 priv_instruction: >> 437 SAVE_ALL >> 438 >> 439 wr %l0, PSR_ET, %psr >> 440 WRITE_PAUSE >> 441 >> 442 add %sp, STACKFRAME_SZ, %o0 >> 443 mov %l1, %o1 >> 444 mov %l2, %o2 >> 445 call do_priv_instruction >> 446 mov %l0, %o3 >> 447 >> 448 RESTORE_ALL >> 449 >> 450 /* This routine handles unaligned data accesses. */ >> 451 .align 4 >> 452 .globl mna_handler >> 453 mna_handler: >> 454 andcc %l0, PSR_PS, %g0 >> 455 be mna_fromuser >> 456 nop >> 457 >> 458 SAVE_ALL >> 459 >> 460 wr %l0, PSR_ET, %psr >> 461 WRITE_PAUSE >> 462 >> 463 ld [%l1], %o1 >> 464 call kernel_unaligned_trap >> 465 add %sp, STACKFRAME_SZ, %o0 >> 466 >> 467 RESTORE_ALL >> 468 >> 469 mna_fromuser: >> 470 SAVE_ALL >> 471 >> 472 wr %l0, PSR_ET, %psr ! re-enable traps >> 473 WRITE_PAUSE >> 474 >> 475 ld [%l1], %o1 >> 476 call user_unaligned_trap >> 477 add %sp, STACKFRAME_SZ, %o0 >> 478 >> 479 RESTORE_ALL >> 480 >> 481 /* This routine handles floating point disabled traps. */ >> 482 .align 4 >> 483 .globl fpd_trap_handler >> 484 fpd_trap_handler: >> 485 SAVE_ALL >> 486 >> 487 wr %l0, PSR_ET, %psr ! re-enable traps >> 488 WRITE_PAUSE >> 489 >> 490 add %sp, STACKFRAME_SZ, %o0 >> 491 mov %l1, %o1 >> 492 mov %l2, %o2 >> 493 call do_fpd_trap >> 494 mov %l0, %o3 >> 495 >> 496 RESTORE_ALL >> 497 >> 498 /* This routine handles Floating Point Exceptions. */ >> 499 .align 4 >> 500 .globl fpe_trap_handler >> 501 fpe_trap_handler: >> 502 set fpsave_magic, %l5 >> 503 cmp %l1, %l5 >> 504 be 1f >> 505 sethi %hi(fpsave), %l5 >> 506 or %l5, %lo(fpsave), %l5 >> 507 cmp %l1, %l5 >> 508 bne 2f >> 509 sethi %hi(fpsave_catch2), %l5 >> 510 or %l5, %lo(fpsave_catch2), %l5 >> 511 wr %l0, 0x0, %psr >> 512 WRITE_PAUSE >> 513 jmp %l5 >> 514 rett %l5 + 4 >> 515 1: >> 516 sethi %hi(fpsave_catch), %l5 >> 517 or %l5, %lo(fpsave_catch), %l5 >> 518 wr %l0, 0x0, %psr >> 519 WRITE_PAUSE >> 520 jmp %l5 >> 521 rett %l5 + 4 >> 522 >> 523 2: >> 524 SAVE_ALL >> 525 >> 526 wr %l0, PSR_ET, %psr ! re-enable traps >> 527 WRITE_PAUSE >> 528 >> 529 add %sp, STACKFRAME_SZ, %o0 >> 530 mov %l1, %o1 >> 531 mov %l2, %o2 >> 532 call do_fpe_trap >> 533 mov %l0, %o3 >> 534 >> 535 RESTORE_ALL >> 536 >> 537 /* This routine handles Tag Overflow Exceptions. */ >> 538 .align 4 >> 539 .globl do_tag_overflow >> 540 do_tag_overflow: >> 541 SAVE_ALL >> 542 >> 543 wr %l0, PSR_ET, %psr ! re-enable traps >> 544 WRITE_PAUSE >> 545 >> 546 add %sp, STACKFRAME_SZ, %o0 >> 547 mov %l1, %o1 >> 548 mov %l2, %o2 >> 549 call handle_tag_overflow >> 550 mov %l0, %o3 >> 551 >> 552 RESTORE_ALL >> 553 >> 554 /* This routine handles Watchpoint Exceptions. */ >> 555 .align 4 >> 556 .globl do_watchpoint >> 557 do_watchpoint: >> 558 SAVE_ALL >> 559 >> 560 wr %l0, PSR_ET, %psr ! re-enable traps >> 561 WRITE_PAUSE >> 562 >> 563 add %sp, STACKFRAME_SZ, %o0 >> 564 mov %l1, %o1 >> 565 mov %l2, %o2 >> 566 call handle_watchpoint >> 567 mov %l0, %o3 >> 568 >> 569 RESTORE_ALL >> 570 >> 571 /* This routine handles Register Access Exceptions. */ >> 572 .align 4 >> 573 .globl do_reg_access >> 574 do_reg_access: >> 575 SAVE_ALL >> 576 >> 577 wr %l0, PSR_ET, %psr ! re-enable traps >> 578 WRITE_PAUSE >> 579 >> 580 add %sp, STACKFRAME_SZ, %o0 >> 581 mov %l1, %o1 >> 582 mov %l2, %o2 >> 583 call handle_reg_access >> 584 mov %l0, %o3 >> 585 >> 586 RESTORE_ALL >> 587 >> 588 /* This routine handles Co-Processor Disabled Exceptions. */ >> 589 .align 4 >> 590 .globl do_cp_disabled >> 591 do_cp_disabled: >> 592 SAVE_ALL >> 593 >> 594 wr %l0, PSR_ET, %psr ! re-enable traps >> 595 WRITE_PAUSE >> 596 >> 597 add %sp, STACKFRAME_SZ, %o0 >> 598 mov %l1, %o1 >> 599 mov %l2, %o2 >> 600 call handle_cp_disabled >> 601 mov %l0, %o3 >> 602 >> 603 RESTORE_ALL >> 604 >> 605 /* This routine handles Co-Processor Exceptions. */ >> 606 .align 4 >> 607 .globl do_cp_exception >> 608 do_cp_exception: >> 609 SAVE_ALL >> 610 >> 611 wr %l0, PSR_ET, %psr ! re-enable traps >> 612 WRITE_PAUSE >> 613 >> 614 add %sp, STACKFRAME_SZ, %o0 >> 615 mov %l1, %o1 >> 616 mov %l2, %o2 >> 617 call handle_cp_exception >> 618 mov %l0, %o3 >> 619 >> 620 RESTORE_ALL >> 621 >> 622 /* This routine handles Hardware Divide By Zero Exceptions. */ >> 623 .align 4 >> 624 .globl do_hw_divzero >> 625 do_hw_divzero: >> 626 SAVE_ALL >> 627 >> 628 wr %l0, PSR_ET, %psr ! re-enable traps >> 629 WRITE_PAUSE >> 630 >> 631 add %sp, STACKFRAME_SZ, %o0 >> 632 mov %l1, %o1 >> 633 mov %l2, %o2 >> 634 call handle_hw_divzero >> 635 mov %l0, %o3 >> 636 >> 637 RESTORE_ALL >> 638 >> 639 .align 4 >> 640 .globl do_flush_windows >> 641 do_flush_windows: >> 642 SAVE_ALL >> 643 >> 644 wr %l0, PSR_ET, %psr >> 645 WRITE_PAUSE >> 646 >> 647 andcc %l0, PSR_PS, %g0 >> 648 bne dfw_kernel >> 649 nop >> 650 >> 651 call flush_user_windows >> 652 nop >> 653 >> 654 /* Advance over the trap instruction. */ >> 655 ld [%sp + STACKFRAME_SZ + PT_NPC], %l1 >> 656 add %l1, 0x4, %l2 >> 657 st %l1, [%sp + STACKFRAME_SZ + PT_PC] >> 658 st %l2, [%sp + STACKFRAME_SZ + PT_NPC] >> 659 >> 660 RESTORE_ALL >> 661 >> 662 .globl flush_patch_one >> 663 >> 664 /* We get these for debugging routines using __builtin_return_address() */ >> 665 dfw_kernel: >> 666 flush_patch_one: >> 667 FLUSH_ALL_KERNEL_WINDOWS >> 668 >> 669 /* Advance over the trap instruction. */ >> 670 ld [%sp + STACKFRAME_SZ + PT_NPC], %l1 >> 671 add %l1, 0x4, %l2 >> 672 st %l1, [%sp + STACKFRAME_SZ + PT_PC] >> 673 st %l2, [%sp + STACKFRAME_SZ + PT_NPC] >> 674 >> 675 RESTORE_ALL >> 676 >> 677 /* The getcc software trap. The user wants the condition codes from >> 678 * the %psr in register %g1. >> 679 */ >> 680 >> 681 .align 4 >> 682 .globl getcc_trap_handler >> 683 getcc_trap_handler: >> 684 srl %l0, 20, %g1 ! give user >> 685 and %g1, 0xf, %g1 ! only ICC bits in %psr >> 686 jmp %l2 ! advance over trap instruction >> 687 rett %l2 + 0x4 ! like this... >> 688 >> 689 /* The setcc software trap. The user has condition codes in %g1 >> 690 * that it would like placed in the %psr. Be careful not to flip >> 691 * any unintentional bits! >> 692 */ >> 693 >> 694 .align 4 >> 695 .globl setcc_trap_handler >> 696 setcc_trap_handler: >> 697 sll %g1, 0x14, %l4 >> 698 set PSR_ICC, %l5 >> 699 andn %l0, %l5, %l0 ! clear ICC bits in %psr >> 700 and %l4, %l5, %l4 ! clear non-ICC bits in user value >> 701 or %l4, %l0, %l4 ! or them in... mix mix mix >> 702 >> 703 wr %l4, 0x0, %psr ! set new %psr >> 704 WRITE_PAUSE ! TI scumbags... >> 705 >> 706 jmp %l2 ! advance over trap instruction >> 707 rett %l2 + 0x4 ! like this... >> 708 >> 709 .align 4 >> 710 .globl linux_trap_nmi_sun4c >> 711 linux_trap_nmi_sun4c: >> 712 SAVE_ALL >> 713 >> 714 /* Ugh, we need to clear the IRQ line. This is now >> 715 * a very sun4c specific trap handler... >> 716 */ >> 717 sethi %hi(interrupt_enable), %l5 >> 718 ld [%l5 + %lo(interrupt_enable)], %l5 >> 719 ldub [%l5], %l6 >> 720 andn %l6, INTS_ENAB, %l6 >> 721 stb %l6, [%l5] >> 722 >> 723 /* Now it is safe to re-enable traps without recursion. */ >> 724 or %l0, PSR_PIL, %l0 >> 725 wr %l0, PSR_ET, %psr >> 726 WRITE_PAUSE >> 727 >> 728 /* Now call the c-code with the pt_regs frame ptr and the >> 729 * memory error registers as arguments. The ordering chosen >> 730 * here is due to unlatching semantics. >> 731 */ >> 732 sethi %hi(AC_SYNC_ERR), %o0 >> 733 add %o0, 0x4, %o0 >> 734 lda [%o0] ASI_CONTROL, %o2 ! sync vaddr >> 735 sub %o0, 0x4, %o0 >> 736 lda [%o0] ASI_CONTROL, %o1 ! sync error >> 737 add %o0, 0xc, %o0 >> 738 lda [%o0] ASI_CONTROL, %o4 ! async vaddr >> 739 sub %o0, 0x4, %o0 >> 740 lda [%o0] ASI_CONTROL, %o3 ! async error >> 741 call sparc_lvl15_nmi >> 742 add %sp, STACKFRAME_SZ, %o0 >> 743 >> 744 RESTORE_ALL >> 745 >> 746 .align 4 >> 747 .globl invalid_segment_patch1_ff >> 748 .globl invalid_segment_patch2_ff >> 749 invalid_segment_patch1_ff: cmp %l4, 0xff >> 750 invalid_segment_patch2_ff: mov 0xff, %l3 >> 751 >> 752 .align 4 >> 753 .globl invalid_segment_patch1_1ff >> 754 .globl invalid_segment_patch2_1ff >> 755 invalid_segment_patch1_1ff: cmp %l4, 0x1ff >> 756 invalid_segment_patch2_1ff: mov 0x1ff, %l3 >> 757 >> 758 .align 4 >> 759 .globl num_context_patch1_16, num_context_patch2_16 >> 760 num_context_patch1_16: mov 0x10, %l7 >> 761 num_context_patch2_16: mov 0x10, %l7 >> 762 >> 763 .align 4 >> 764 .globl vac_linesize_patch_32 >> 765 vac_linesize_patch_32: subcc %l7, 32, %l7 >> 766 >> 767 .align 4 >> 768 .globl vac_hwflush_patch1_on, vac_hwflush_patch2_on 173 769 174 /* 770 /* 175 * MIPS32R2 Instruction Hazard Barrier - must !! 771 * Ugly, but we cant use hardware flushing on the sun4 and we'd require >> 772 * two instructions (Anton) >> 773 */ >> 774 vac_hwflush_patch1_on: addcc %l7, -PAGE_SIZE, %l7 >> 775 >> 776 vac_hwflush_patch2_on: sta %g0, [%l3 + %l7] ASI_HWFLUSHSEG >> 777 >> 778 .globl invalid_segment_patch1, invalid_segment_patch2 >> 779 .globl num_context_patch1 >> 780 .globl vac_linesize_patch, vac_hwflush_patch1 >> 781 .globl vac_hwflush_patch2 >> 782 >> 783 .align 4 >> 784 .globl sun4c_fault >> 785 >> 786 ! %l0 = %psr >> 787 ! %l1 = %pc >> 788 ! %l2 = %npc >> 789 ! %l3 = %wim >> 790 ! %l7 = 1 for textfault >> 791 ! We want error in %l5, vaddr in %l6 >> 792 sun4c_fault: >> 793 sethi %hi(AC_SYNC_ERR), %l4 >> 794 add %l4, 0x4, %l6 ! AC_SYNC_VA in %l6 >> 795 lda [%l6] ASI_CONTROL, %l5 ! Address >> 796 lda [%l4] ASI_CONTROL, %l6 ! Error, retained for a bit >> 797 >> 798 andn %l5, 0xfff, %l5 ! Encode all info into l7 >> 799 srl %l6, 14, %l4 >> 800 >> 801 and %l4, 2, %l4 >> 802 or %l5, %l4, %l4 >> 803 >> 804 or %l4, %l7, %l7 ! l7 = [addr,write,txtfault] >> 805 >> 806 andcc %l0, PSR_PS, %g0 >> 807 be sun4c_fault_fromuser >> 808 andcc %l7, 1, %g0 ! Text fault? >> 809 >> 810 be 1f >> 811 sethi %hi(KERNBASE), %l4 >> 812 >> 813 mov %l1, %l5 ! PC >> 814 >> 815 1: >> 816 cmp %l5, %l4 >> 817 blu sun4c_fault_fromuser >> 818 sethi %hi(~((1 << SUN4C_REAL_PGDIR_SHIFT) - 1)), %l4 >> 819 >> 820 /* If the kernel references a bum kernel pointer, or a pte which >> 821 * points to a non existant page in ram, we will run this code >> 822 * _forever_ and lock up the machine!!!!! So we must check for >> 823 * this condition, the AC_SYNC_ERR bits are what we must examine. >> 824 * Also a parity error would make this happen as well. So we just >> 825 * check that we are in fact servicing a tlb miss and not some >> 826 * other type of fault for the kernel. >> 827 */ >> 828 andcc %l6, 0x80, %g0 >> 829 be sun4c_fault_fromuser >> 830 and %l5, %l4, %l5 >> 831 >> 832 /* Test for NULL pte_t * in vmalloc area. */ >> 833 sethi %hi(VMALLOC_START), %l4 >> 834 cmp %l5, %l4 >> 835 blu,a invalid_segment_patch1 >> 836 lduXa [%l5] ASI_SEGMAP, %l4 >> 837 >> 838 sethi %hi(swapper_pg_dir), %l4 >> 839 srl %l5, SUN4C_PGDIR_SHIFT, %l6 >> 840 or %l4, %lo(swapper_pg_dir), %l4 >> 841 sll %l6, 2, %l6 >> 842 ld [%l4 + %l6], %l4 >> 843 andcc %l4, PAGE_MASK, %g0 >> 844 be sun4c_fault_fromuser >> 845 lduXa [%l5] ASI_SEGMAP, %l4 >> 846 >> 847 invalid_segment_patch1: >> 848 cmp %l4, 0x7f >> 849 bne 1f >> 850 sethi %hi(sun4c_kfree_ring), %l4 >> 851 or %l4, %lo(sun4c_kfree_ring), %l4 >> 852 ld [%l4 + 0x18], %l3 >> 853 deccc %l3 ! do we have a free entry? >> 854 bcs,a 2f ! no, unmap one. >> 855 sethi %hi(sun4c_kernel_ring), %l4 >> 856 >> 857 st %l3, [%l4 + 0x18] ! sun4c_kfree_ring.num_entries-- >> 858 >> 859 ld [%l4 + 0x00], %l6 ! entry = sun4c_kfree_ring.ringhd.next >> 860 st %l5, [%l6 + 0x08] ! entry->vaddr = address >> 861 >> 862 ld [%l6 + 0x00], %l3 ! next = entry->next >> 863 ld [%l6 + 0x04], %l7 ! entry->prev >> 864 >> 865 st %l7, [%l3 + 0x04] ! next->prev = entry->prev >> 866 st %l3, [%l7 + 0x00] ! entry->prev->next = next >> 867 >> 868 sethi %hi(sun4c_kernel_ring), %l4 >> 869 or %l4, %lo(sun4c_kernel_ring), %l4 >> 870 ! head = &sun4c_kernel_ring.ringhd >> 871 >> 872 ld [%l4 + 0x00], %l7 ! head->next >> 873 >> 874 st %l4, [%l6 + 0x04] ! entry->prev = head >> 875 st %l7, [%l6 + 0x00] ! entry->next = head->next >> 876 st %l6, [%l7 + 0x04] ! head->next->prev = entry >> 877 >> 878 st %l6, [%l4 + 0x00] ! head->next = entry >> 879 >> 880 ld [%l4 + 0x18], %l3 >> 881 inc %l3 ! sun4c_kernel_ring.num_entries++ >> 882 st %l3, [%l4 + 0x18] >> 883 b 4f >> 884 ld [%l6 + 0x08], %l5 >> 885 >> 886 2: >> 887 or %l4, %lo(sun4c_kernel_ring), %l4 >> 888 ! head = &sun4c_kernel_ring.ringhd >> 889 >> 890 ld [%l4 + 0x04], %l6 ! entry = head->prev >> 891 >> 892 ld [%l6 + 0x08], %l3 ! tmp = entry->vaddr >> 893 >> 894 ! Flush segment from the cache. >> 895 sethi %hi((64 * 1024)), %l7 >> 896 9: >> 897 vac_hwflush_patch1: >> 898 vac_linesize_patch: >> 899 subcc %l7, 16, %l7 >> 900 bne 9b >> 901 vac_hwflush_patch2: >> 902 sta %g0, [%l3 + %l7] ASI_FLUSHSEG >> 903 >> 904 st %l5, [%l6 + 0x08] ! entry->vaddr = address >> 905 >> 906 ld [%l6 + 0x00], %l5 ! next = entry->next >> 907 ld [%l6 + 0x04], %l7 ! entry->prev >> 908 >> 909 st %l7, [%l5 + 0x04] ! next->prev = entry->prev >> 910 st %l5, [%l7 + 0x00] ! entry->prev->next = next >> 911 st %l4, [%l6 + 0x04] ! entry->prev = head >> 912 >> 913 ld [%l4 + 0x00], %l7 ! head->next >> 914 >> 915 st %l7, [%l6 + 0x00] ! entry->next = head->next >> 916 st %l6, [%l7 + 0x04] ! head->next->prev = entry >> 917 st %l6, [%l4 + 0x00] ! head->next = entry >> 918 >> 919 mov %l3, %l5 ! address = tmp >> 920 >> 921 4: >> 922 num_context_patch1: >> 923 mov 0x08, %l7 >> 924 >> 925 ld [%l6 + 0x08], %l4 >> 926 ldub [%l6 + 0x0c], %l3 >> 927 or %l4, %l3, %l4 ! encode new vaddr/pseg into l4 >> 928 >> 929 sethi %hi(AC_CONTEXT), %l3 >> 930 lduba [%l3] ASI_CONTROL, %l6 >> 931 >> 932 /* Invalidate old mapping, instantiate new mapping, >> 933 * for each context. Registers l6/l7 are live across >> 934 * this loop. >> 935 */ >> 936 3: deccc %l7 >> 937 sethi %hi(AC_CONTEXT), %l3 >> 938 stba %l7, [%l3] ASI_CONTROL >> 939 invalid_segment_patch2: >> 940 mov 0x7f, %l3 >> 941 stXa %l3, [%l5] ASI_SEGMAP >> 942 andn %l4, 0x1ff, %l3 >> 943 bne 3b >> 944 stXa %l4, [%l3] ASI_SEGMAP >> 945 >> 946 sethi %hi(AC_CONTEXT), %l3 >> 947 stba %l6, [%l3] ASI_CONTROL >> 948 >> 949 andn %l4, 0x1ff, %l5 >> 950 >> 951 1: >> 952 sethi %hi(VMALLOC_START), %l4 >> 953 cmp %l5, %l4 >> 954 >> 955 bgeu 1f >> 956 mov 1 << (SUN4C_REAL_PGDIR_SHIFT - PAGE_SHIFT), %l7 >> 957 >> 958 sethi %hi(KERNBASE), %l6 >> 959 >> 960 sub %l5, %l6, %l4 >> 961 srl %l4, PAGE_SHIFT, %l4 >> 962 sethi %hi((SUN4C_PAGE_KERNEL & 0xf4000000)), %l3 >> 963 or %l3, %l4, %l3 >> 964 >> 965 sethi %hi(PAGE_SIZE), %l4 >> 966 >> 967 2: >> 968 sta %l3, [%l5] ASI_PTE >> 969 deccc %l7 >> 970 inc %l3 >> 971 bne 2b >> 972 add %l5, %l4, %l5 >> 973 >> 974 b 7f >> 975 sethi %hi(sun4c_kernel_faults), %l4 >> 976 >> 977 1: >> 978 srl %l5, SUN4C_PGDIR_SHIFT, %l3 >> 979 sethi %hi(swapper_pg_dir), %l4 >> 980 or %l4, %lo(swapper_pg_dir), %l4 >> 981 sll %l3, 2, %l3 >> 982 ld [%l4 + %l3], %l4 >> 983 and %l4, PAGE_MASK, %l4 >> 984 >> 985 srl %l5, (PAGE_SHIFT - 2), %l6 >> 986 and %l6, ((SUN4C_PTRS_PER_PTE - 1) << 2), %l6 >> 987 add %l6, %l4, %l6 >> 988 >> 989 sethi %hi(PAGE_SIZE), %l4 >> 990 >> 991 2: >> 992 ld [%l6], %l3 >> 993 deccc %l7 >> 994 sta %l3, [%l5] ASI_PTE >> 995 add %l6, 0x4, %l6 >> 996 bne 2b >> 997 add %l5, %l4, %l5 >> 998 >> 999 sethi %hi(sun4c_kernel_faults), %l4 >> 1000 7: >> 1001 ld [%l4 + %lo(sun4c_kernel_faults)], %l3 >> 1002 inc %l3 >> 1003 st %l3, [%l4 + %lo(sun4c_kernel_faults)] >> 1004 >> 1005 /* Restore condition codes */ >> 1006 wr %l0, 0x0, %psr >> 1007 WRITE_PAUSE >> 1008 jmp %l1 >> 1009 rett %l2 >> 1010 >> 1011 sun4c_fault_fromuser: >> 1012 SAVE_ALL >> 1013 nop >> 1014 >> 1015 mov %l7, %o1 ! Decode the info from %l7 >> 1016 mov %l7, %o2 >> 1017 and %o1, 1, %o1 ! arg2 = text_faultp >> 1018 mov %l7, %o3 >> 1019 and %o2, 2, %o2 ! arg3 = writep >> 1020 andn %o3, 0xfff, %o3 ! arg4 = faulting address >> 1021 >> 1022 wr %l0, PSR_ET, %psr >> 1023 WRITE_PAUSE >> 1024 >> 1025 call do_sun4c_fault >> 1026 add %sp, STACKFRAME_SZ, %o0 ! arg1 = pt_regs ptr >> 1027 >> 1028 RESTORE_ALL >> 1029 >> 1030 .align 4 >> 1031 .globl srmmu_fault >> 1032 srmmu_fault: >> 1033 mov 0x400, %l5 >> 1034 mov 0x300, %l4 >> 1035 >> 1036 lda [%l5] ASI_M_MMUREGS, %l6 ! read sfar first >> 1037 lda [%l4] ASI_M_MMUREGS, %l5 ! read sfsr last >> 1038 >> 1039 andn %l6, 0xfff, %l6 >> 1040 srl %l5, 6, %l5 ! and encode all info into l7 >> 1041 >> 1042 and %l5, 2, %l5 >> 1043 or %l5, %l6, %l6 >> 1044 >> 1045 or %l6, %l7, %l7 ! l7 = [addr,write,txtfault] >> 1046 >> 1047 SAVE_ALL >> 1048 >> 1049 mov %l7, %o1 >> 1050 mov %l7, %o2 >> 1051 and %o1, 1, %o1 ! arg2 = text_faultp >> 1052 mov %l7, %o3 >> 1053 and %o2, 2, %o2 ! arg3 = writep >> 1054 andn %o3, 0xfff, %o3 ! arg4 = faulting address >> 1055 >> 1056 wr %l0, PSR_ET, %psr >> 1057 WRITE_PAUSE >> 1058 >> 1059 call do_sparc_fault >> 1060 add %sp, STACKFRAME_SZ, %o0 ! arg1 = pt_regs ptr >> 1061 >> 1062 RESTORE_ALL >> 1063 >> 1064 .align 4 >> 1065 .globl sys_nis_syscall >> 1066 sys_nis_syscall: >> 1067 mov %o7, %l5 >> 1068 add %sp, STACKFRAME_SZ, %o0 ! pt_regs *regs arg >> 1069 call c_sys_nis_syscall >> 1070 mov %l5, %o7 >> 1071 >> 1072 .align 4 >> 1073 .globl sys_execve >> 1074 sys_execve: >> 1075 mov %o7, %l5 >> 1076 add %sp, STACKFRAME_SZ, %o0 ! pt_regs *regs arg >> 1077 call sparc_execve >> 1078 mov %l5, %o7 >> 1079 >> 1080 .globl sunos_execv >> 1081 sunos_execv: >> 1082 st %g0, [%sp + STACKFRAME_SZ + PT_I2] >> 1083 >> 1084 call sparc_execve >> 1085 add %sp, STACKFRAME_SZ, %o0 >> 1086 >> 1087 b ret_sys_call >> 1088 ld [%sp + STACKFRAME_SZ + PT_I0], %o0 >> 1089 >> 1090 .align 4 >> 1091 .globl sys_sparc_pipe >> 1092 sys_sparc_pipe: >> 1093 mov %o7, %l5 >> 1094 add %sp, STACKFRAME_SZ, %o0 ! pt_regs *regs arg >> 1095 call sparc_pipe >> 1096 mov %l5, %o7 >> 1097 >> 1098 .align 4 >> 1099 .globl sys_sigaltstack >> 1100 sys_sigaltstack: >> 1101 mov %o7, %l5 >> 1102 mov %fp, %o2 >> 1103 call do_sigaltstack >> 1104 mov %l5, %o7 >> 1105 >> 1106 .align 4 >> 1107 .globl sys_sigstack >> 1108 sys_sigstack: >> 1109 mov %o7, %l5 >> 1110 mov %fp, %o2 >> 1111 call do_sys_sigstack >> 1112 mov %l5, %o7 >> 1113 >> 1114 .align 4 >> 1115 .globl sys_sigreturn >> 1116 sys_sigreturn: >> 1117 call do_sigreturn >> 1118 add %sp, STACKFRAME_SZ, %o0 >> 1119 >> 1120 ld [%curptr + TI_FLAGS], %l5 >> 1121 andcc %l5, _TIF_SYSCALL_TRACE, %g0 >> 1122 be 1f >> 1123 nop >> 1124 >> 1125 call syscall_trace >> 1126 nop >> 1127 >> 1128 1: >> 1129 /* We don't want to muck with user registers like a >> 1130 * normal syscall, just return. >> 1131 */ >> 1132 RESTORE_ALL >> 1133 >> 1134 .align 4 >> 1135 .globl sys_rt_sigreturn >> 1136 sys_rt_sigreturn: >> 1137 call do_rt_sigreturn >> 1138 add %sp, STACKFRAME_SZ, %o0 >> 1139 >> 1140 ld [%curptr + TI_FLAGS], %l5 >> 1141 andcc %l5, _TIF_SYSCALL_TRACE, %g0 >> 1142 be 1f >> 1143 nop >> 1144 >> 1145 add %sp, STACKFRAME_SZ, %o0 >> 1146 call syscall_trace >> 1147 mov 1, %o1 >> 1148 >> 1149 1: >> 1150 /* We are returning to a signal handler. */ >> 1151 RESTORE_ALL >> 1152 >> 1153 /* Now that we have a real sys_clone, sys_fork() is >> 1154 * implemented in terms of it. Our _real_ implementation >> 1155 * of SunOS vfork() will use sys_vfork(). >> 1156 * >> 1157 * XXX These three should be consolidated into mostly shared >> 1158 * XXX code just like on sparc64... -DaveM >> 1159 */ >> 1160 .align 4 >> 1161 .globl sys_fork, flush_patch_two >> 1162 sys_fork: >> 1163 mov %o7, %l5 >> 1164 flush_patch_two: >> 1165 FLUSH_ALL_KERNEL_WINDOWS; >> 1166 ld [%curptr + TI_TASK], %o4 >> 1167 rd %psr, %g4 >> 1168 WRITE_PAUSE >> 1169 mov SIGCHLD, %o0 ! arg0: clone flags >> 1170 rd %wim, %g5 >> 1171 WRITE_PAUSE >> 1172 mov %fp, %o1 ! arg1: usp >> 1173 std %g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr] >> 1174 add %sp, STACKFRAME_SZ, %o2 ! arg2: pt_regs ptr >> 1175 mov 0, %o3 >> 1176 call sparc_do_fork >> 1177 mov %l5, %o7 >> 1178 >> 1179 /* Whee, kernel threads! */ >> 1180 .globl sys_clone, flush_patch_three >> 1181 sys_clone: >> 1182 mov %o7, %l5 >> 1183 flush_patch_three: >> 1184 FLUSH_ALL_KERNEL_WINDOWS; >> 1185 ld [%curptr + TI_TASK], %o4 >> 1186 rd %psr, %g4 >> 1187 WRITE_PAUSE >> 1188 >> 1189 /* arg0,1: flags,usp -- loaded already */ >> 1190 cmp %o1, 0x0 ! Is new_usp NULL? >> 1191 rd %wim, %g5 >> 1192 WRITE_PAUSE >> 1193 be,a 1f >> 1194 mov %fp, %o1 ! yes, use callers usp >> 1195 andn %o1, 7, %o1 ! no, align to 8 bytes >> 1196 1: >> 1197 std %g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr] >> 1198 add %sp, STACKFRAME_SZ, %o2 ! arg2: pt_regs ptr >> 1199 mov 0, %o3 >> 1200 call sparc_do_fork >> 1201 mov %l5, %o7 >> 1202 >> 1203 /* Whee, real vfork! */ >> 1204 .globl sys_vfork, flush_patch_four >> 1205 sys_vfork: >> 1206 flush_patch_four: >> 1207 FLUSH_ALL_KERNEL_WINDOWS; >> 1208 ld [%curptr + TI_TASK], %o4 >> 1209 rd %psr, %g4 >> 1210 WRITE_PAUSE >> 1211 rd %wim, %g5 >> 1212 WRITE_PAUSE >> 1213 std %g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr] >> 1214 sethi %hi(0x4000 | 0x0100 | SIGCHLD), %o0 >> 1215 mov %fp, %o1 >> 1216 or %o0, %lo(0x4000 | 0x0100 | SIGCHLD), %o0 >> 1217 sethi %hi(sparc_do_fork), %l1 >> 1218 mov 0, %o3 >> 1219 jmpl %l1 + %lo(sparc_do_fork), %g0 >> 1220 add %sp, STACKFRAME_SZ, %o2 >> 1221 >> 1222 .align 4 >> 1223 linux_sparc_ni_syscall: >> 1224 sethi %hi(sys_ni_syscall), %l7 >> 1225 b syscall_is_too_hard >> 1226 or %l7, %lo(sys_ni_syscall), %l7 >> 1227 >> 1228 linux_fast_syscall: >> 1229 andn %l7, 3, %l7 >> 1230 mov %i0, %o0 >> 1231 mov %i1, %o1 >> 1232 mov %i2, %o2 >> 1233 jmpl %l7 + %g0, %g0 >> 1234 mov %i3, %o3 >> 1235 >> 1236 linux_syscall_trace: >> 1237 add %sp, STACKFRAME_SZ, %o0 >> 1238 call syscall_trace >> 1239 mov 0, %o1 >> 1240 cmp %o0, 0 >> 1241 bne 3f >> 1242 mov -ENOSYS, %o0 >> 1243 mov %i0, %o0 >> 1244 mov %i1, %o1 >> 1245 mov %i2, %o2 >> 1246 mov %i3, %o3 >> 1247 b 2f >> 1248 mov %i4, %o4 >> 1249 >> 1250 .globl ret_from_fork >> 1251 ret_from_fork: >> 1252 call schedule_tail >> 1253 mov %g3, %o0 >> 1254 b ret_sys_call >> 1255 ld [%sp + STACKFRAME_SZ + PT_I0], %o0 >> 1256 >> 1257 /* Linux native system calls enter here... */ >> 1258 .align 4 >> 1259 .globl linux_sparc_syscall >> 1260 linux_sparc_syscall: >> 1261 sethi %hi(PSR_SYSCALL), %l4 >> 1262 or %l0, %l4, %l0 >> 1263 /* Direct access to user regs, must faster. */ >> 1264 cmp %g1, NR_SYSCALLS >> 1265 bgeu linux_sparc_ni_syscall >> 1266 sll %g1, 2, %l4 >> 1267 ld [%l7 + %l4], %l7 >> 1268 andcc %l7, 1, %g0 >> 1269 bne linux_fast_syscall >> 1270 /* Just do first insn from SAVE_ALL in the delay slot */ >> 1271 >> 1272 syscall_is_too_hard: >> 1273 SAVE_ALL_HEAD >> 1274 rd %wim, %l3 >> 1275 >> 1276 wr %l0, PSR_ET, %psr >> 1277 mov %i0, %o0 >> 1278 mov %i1, %o1 >> 1279 mov %i2, %o2 >> 1280 >> 1281 ld [%curptr + TI_FLAGS], %l5 >> 1282 mov %i3, %o3 >> 1283 andcc %l5, _TIF_SYSCALL_TRACE, %g0 >> 1284 mov %i4, %o4 >> 1285 bne linux_syscall_trace >> 1286 mov %i0, %l5 >> 1287 2: >> 1288 call %l7 >> 1289 mov %i5, %o5 >> 1290 >> 1291 3: >> 1292 st %o0, [%sp + STACKFRAME_SZ + PT_I0] >> 1293 >> 1294 ret_sys_call: >> 1295 ld [%curptr + TI_FLAGS], %l6 >> 1296 cmp %o0, -ERESTART_RESTARTBLOCK >> 1297 ld [%sp + STACKFRAME_SZ + PT_PSR], %g3 >> 1298 set PSR_C, %g2 >> 1299 bgeu 1f >> 1300 andcc %l6, _TIF_SYSCALL_TRACE, %g0 >> 1301 >> 1302 /* System call success, clear Carry condition code. */ >> 1303 andn %g3, %g2, %g3 >> 1304 clr %l6 >> 1305 st %g3, [%sp + STACKFRAME_SZ + PT_PSR] >> 1306 bne linux_syscall_trace2 >> 1307 ld [%sp + STACKFRAME_SZ + PT_NPC], %l1 /* pc = npc */ >> 1308 add %l1, 0x4, %l2 /* npc = npc+4 */ >> 1309 st %l1, [%sp + STACKFRAME_SZ + PT_PC] >> 1310 b ret_trap_entry >> 1311 st %l2, [%sp + STACKFRAME_SZ + PT_NPC] >> 1312 1: >> 1313 /* System call failure, set Carry condition code. >> 1314 * Also, get abs(errno) to return to the process. >> 1315 */ >> 1316 sub %g0, %o0, %o0 >> 1317 or %g3, %g2, %g3 >> 1318 st %o0, [%sp + STACKFRAME_SZ + PT_I0] >> 1319 mov 1, %l6 >> 1320 st %g3, [%sp + STACKFRAME_SZ + PT_PSR] >> 1321 bne linux_syscall_trace2 >> 1322 ld [%sp + STACKFRAME_SZ + PT_NPC], %l1 /* pc = npc */ >> 1323 add %l1, 0x4, %l2 /* npc = npc+4 */ >> 1324 st %l1, [%sp + STACKFRAME_SZ + PT_PC] >> 1325 b ret_trap_entry >> 1326 st %l2, [%sp + STACKFRAME_SZ + PT_NPC] >> 1327 >> 1328 linux_syscall_trace2: >> 1329 add %sp, STACKFRAME_SZ, %o0 >> 1330 mov 1, %o1 >> 1331 call syscall_trace >> 1332 add %l1, 0x4, %l2 /* npc = npc+4 */ >> 1333 st %l1, [%sp + STACKFRAME_SZ + PT_PC] >> 1334 b ret_trap_entry >> 1335 st %l2, [%sp + STACKFRAME_SZ + PT_NPC] >> 1336 >> 1337 >> 1338 /* Saving and restoring the FPU state is best done from lowlevel code. 176 * 1339 * 177 * For C code use the inline version named ins !! 1340 * void fpsave(unsigned long *fpregs, unsigned long *fsr, >> 1341 * void *fpqueue, unsigned long *fpqdepth) 178 */ 1342 */ 179 LEAF(mips_ihb) << 180 .set MIPS_ISA_LEVEL_RAW << 181 jr.hb ra << 182 nop << 183 END(mips_ihb) << 184 1343 185 #endif /* CONFIG_CPU_MIPSR2 - CONFIG_CPU_MIPSR !! 1344 .globl fpsave >> 1345 fpsave: >> 1346 st %fsr, [%o1] ! this can trap on us if fpu is in bogon state >> 1347 ld [%o1], %g1 >> 1348 set 0x2000, %g4 >> 1349 andcc %g1, %g4, %g0 >> 1350 be 2f >> 1351 mov 0, %g2 >> 1352 >> 1353 /* We have an fpqueue to save. */ >> 1354 1: >> 1355 std %fq, [%o2] >> 1356 fpsave_magic: >> 1357 st %fsr, [%o1] >> 1358 ld [%o1], %g3 >> 1359 andcc %g3, %g4, %g0 >> 1360 add %g2, 1, %g2 >> 1361 bne 1b >> 1362 add %o2, 8, %o2 >> 1363 >> 1364 2: >> 1365 st %g2, [%o3] >> 1366 >> 1367 std %f0, [%o0 + 0x00] >> 1368 std %f2, [%o0 + 0x08] >> 1369 std %f4, [%o0 + 0x10] >> 1370 std %f6, [%o0 + 0x18] >> 1371 std %f8, [%o0 + 0x20] >> 1372 std %f10, [%o0 + 0x28] >> 1373 std %f12, [%o0 + 0x30] >> 1374 std %f14, [%o0 + 0x38] >> 1375 std %f16, [%o0 + 0x40] >> 1376 std %f18, [%o0 + 0x48] >> 1377 std %f20, [%o0 + 0x50] >> 1378 std %f22, [%o0 + 0x58] >> 1379 std %f24, [%o0 + 0x60] >> 1380 std %f26, [%o0 + 0x68] >> 1381 std %f28, [%o0 + 0x70] >> 1382 retl >> 1383 std %f30, [%o0 + 0x78] >> 1384 >> 1385 /* Thanks for Theo Deraadt and the authors of the Sprite/netbsd/openbsd >> 1386 * code for pointing out this possible deadlock, while we save state >> 1387 * above we could trap on the fsr store so our low level fpu trap >> 1388 * code has to know how to deal with this. >> 1389 */ >> 1390 fpsave_catch: >> 1391 b fpsave_magic + 4 >> 1392 st %fsr, [%o1] >> 1393 >> 1394 fpsave_catch2: >> 1395 b fpsave + 4 >> 1396 st %fsr, [%o1] >> 1397 >> 1398 /* void fpload(unsigned long *fpregs, unsigned long *fsr); */ >> 1399 >> 1400 .globl fpload >> 1401 fpload: >> 1402 ldd [%o0 + 0x00], %f0 >> 1403 ldd [%o0 + 0x08], %f2 >> 1404 ldd [%o0 + 0x10], %f4 >> 1405 ldd [%o0 + 0x18], %f6 >> 1406 ldd [%o0 + 0x20], %f8 >> 1407 ldd [%o0 + 0x28], %f10 >> 1408 ldd [%o0 + 0x30], %f12 >> 1409 ldd [%o0 + 0x38], %f14 >> 1410 ldd [%o0 + 0x40], %f16 >> 1411 ldd [%o0 + 0x48], %f18 >> 1412 ldd [%o0 + 0x50], %f20 >> 1413 ldd [%o0 + 0x58], %f22 >> 1414 ldd [%o0 + 0x60], %f24 >> 1415 ldd [%o0 + 0x68], %f26 >> 1416 ldd [%o0 + 0x70], %f28 >> 1417 ldd [%o0 + 0x78], %f30 >> 1418 ld [%o1], %fsr >> 1419 retl >> 1420 nop >> 1421 >> 1422 /* __ndelay and __udelay take two arguments: >> 1423 * 0 - nsecs or usecs to delay >> 1424 * 1 - per_cpu udelay_val (loops per jiffy) >> 1425 * >> 1426 * Note that ndelay gives HZ times higher resolution but has a 10ms >> 1427 * limit. udelay can handle up to 1s. >> 1428 */ >> 1429 .globl __ndelay >> 1430 __ndelay: >> 1431 save %sp, -STACKFRAME_SZ, %sp >> 1432 mov %i0, %o0 >> 1433 call .umul ! round multiplier up so large ns ok >> 1434 mov 0x1ae, %o1 ! 2**32 / (1 000 000 000 / HZ) >> 1435 call .umul >> 1436 mov %i1, %o1 ! udelay_val >> 1437 ba delay_continue >> 1438 mov %o1, %o0 ! >>32 later for better resolution >> 1439 >> 1440 .globl __udelay >> 1441 __udelay: >> 1442 save %sp, -STACKFRAME_SZ, %sp >> 1443 mov %i0, %o0 >> 1444 sethi %hi(0x10c7), %o1 ! round multiplier up so large us ok >> 1445 call .umul >> 1446 or %o1, %lo(0x10c7), %o1 ! 2**32 / 1 000 000 >> 1447 call .umul >> 1448 mov %i1, %o1 ! udelay_val >> 1449 sethi %hi(0x028f4b62), %l0 ! Add in rounding constant * 2**32, >> 1450 or %g0, %lo(0x028f4b62), %l0 >> 1451 addcc %o0, %l0, %o0 ! 2**32 * 0.009 999 >> 1452 bcs,a 3f >> 1453 add %o1, 0x01, %o1 >> 1454 3: >> 1455 call .umul >> 1456 mov HZ, %o0 ! >>32 earlier for wider range >> 1457 >> 1458 delay_continue: >> 1459 cmp %o0, 0x0 >> 1460 1: >> 1461 bne 1b >> 1462 subcc %o0, 1, %o0 >> 1463 >> 1464 ret >> 1465 restore >> 1466 >> 1467 /* Handle a software breakpoint */ >> 1468 /* We have to inform parent that child has stopped */ >> 1469 .align 4 >> 1470 .globl breakpoint_trap >> 1471 breakpoint_trap: >> 1472 rd %wim,%l3 >> 1473 SAVE_ALL >> 1474 wr %l0, PSR_ET, %psr >> 1475 WRITE_PAUSE >> 1476 >> 1477 st %i0, [%sp + STACKFRAME_SZ + PT_G0] ! for restarting syscalls >> 1478 call sparc_breakpoint >> 1479 add %sp, STACKFRAME_SZ, %o0 >> 1480 >> 1481 RESTORE_ALL >> 1482 >> 1483 #ifdef CONFIG_KGDB >> 1484 .align 4 >> 1485 .globl kgdb_trap_low >> 1486 .type kgdb_trap_low,#function >> 1487 kgdb_trap_low: >> 1488 rd %wim,%l3 >> 1489 SAVE_ALL >> 1490 wr %l0, PSR_ET, %psr >> 1491 WRITE_PAUSE >> 1492 >> 1493 call kgdb_trap >> 1494 add %sp, STACKFRAME_SZ, %o0 >> 1495 >> 1496 RESTORE_ALL >> 1497 .size kgdb_trap_low,.-kgdb_trap_low >> 1498 #endif >> 1499 >> 1500 .align 4 >> 1501 .globl flush_patch_exception >> 1502 flush_patch_exception: >> 1503 FLUSH_ALL_KERNEL_WINDOWS; >> 1504 ldd [%o0], %o6 >> 1505 jmpl %o7 + 0xc, %g0 ! see asm-sparc/processor.h >> 1506 mov 1, %g1 ! signal EFAULT condition >> 1507 >> 1508 .align 4 >> 1509 .globl kill_user_windows, kuw_patch1_7win >> 1510 .globl kuw_patch1 >> 1511 kuw_patch1_7win: sll %o3, 6, %o3 >> 1512 >> 1513 /* No matter how much overhead this routine has in the worst >> 1514 * case scenerio, it is several times better than taking the >> 1515 * traps with the old method of just doing flush_user_windows(). >> 1516 */ >> 1517 kill_user_windows: >> 1518 ld [%g6 + TI_UWINMASK], %o0 ! get current umask >> 1519 orcc %g0, %o0, %g0 ! if no bits set, we are done >> 1520 be 3f ! nothing to do >> 1521 rd %psr, %o5 ! must clear interrupts >> 1522 or %o5, PSR_PIL, %o4 ! or else that could change >> 1523 wr %o4, 0x0, %psr ! the uwinmask state >> 1524 WRITE_PAUSE ! burn them cycles >> 1525 1: >> 1526 ld [%g6 + TI_UWINMASK], %o0 ! get consistent state >> 1527 orcc %g0, %o0, %g0 ! did an interrupt come in? >> 1528 be 4f ! yep, we are done >> 1529 rd %wim, %o3 ! get current wim >> 1530 srl %o3, 1, %o4 ! simulate a save >> 1531 kuw_patch1: >> 1532 sll %o3, 7, %o3 ! compute next wim >> 1533 or %o4, %o3, %o3 ! result >> 1534 andncc %o0, %o3, %o0 ! clean this bit in umask >> 1535 bne kuw_patch1 ! not done yet >> 1536 srl %o3, 1, %o4 ! begin another save simulation >> 1537 wr %o3, 0x0, %wim ! set the new wim >> 1538 st %g0, [%g6 + TI_UWINMASK] ! clear uwinmask >> 1539 4: >> 1540 wr %o5, 0x0, %psr ! re-enable interrupts >> 1541 WRITE_PAUSE ! burn baby burn >> 1542 3: >> 1543 retl ! return >> 1544 st %g0, [%g6 + TI_W_SAVED] ! no windows saved >> 1545 >> 1546 .align 4 >> 1547 .globl restore_current >> 1548 restore_current: >> 1549 LOAD_CURRENT(g6, o0) >> 1550 retl >> 1551 nop >> 1552 >> 1553 #ifdef CONFIG_PCI >> 1554 #include <asm/pcic.h> >> 1555 >> 1556 .align 4 >> 1557 .globl linux_trap_ipi15_pcic >> 1558 linux_trap_ipi15_pcic: >> 1559 rd %wim, %l3 >> 1560 SAVE_ALL >> 1561 >> 1562 /* >> 1563 * First deactivate NMI >> 1564 * or we cannot drop ET, cannot get window spill traps. >> 1565 * The busy loop is necessary because the PIO error >> 1566 * sometimes does not go away quickly and we trap again. >> 1567 */ >> 1568 sethi %hi(pcic_regs), %o1 >> 1569 ld [%o1 + %lo(pcic_regs)], %o2 >> 1570 >> 1571 ! Get pending status for printouts later. >> 1572 ld [%o2 + PCI_SYS_INT_PENDING], %o0 >> 1573 >> 1574 mov PCI_SYS_INT_PENDING_CLEAR_ALL, %o1 >> 1575 stb %o1, [%o2 + PCI_SYS_INT_PENDING_CLEAR] >> 1576 1: >> 1577 ld [%o2 + PCI_SYS_INT_PENDING], %o1 >> 1578 andcc %o1, ((PCI_SYS_INT_PENDING_PIO|PCI_SYS_INT_PENDING_PCI)>>24), %g0 >> 1579 bne 1b >> 1580 nop >> 1581 >> 1582 or %l0, PSR_PIL, %l4 >> 1583 wr %l4, 0x0, %psr >> 1584 WRITE_PAUSE >> 1585 wr %l4, PSR_ET, %psr >> 1586 WRITE_PAUSE >> 1587 >> 1588 call pcic_nmi >> 1589 add %sp, STACKFRAME_SZ, %o1 ! struct pt_regs *regs >> 1590 RESTORE_ALL >> 1591 >> 1592 .globl pcic_nmi_trap_patch >> 1593 pcic_nmi_trap_patch: >> 1594 sethi %hi(linux_trap_ipi15_pcic), %l3 >> 1595 jmpl %l3 + %lo(linux_trap_ipi15_pcic), %g0 >> 1596 rd %psr, %l0 >> 1597 .word 0 >> 1598 >> 1599 #endif /* CONFIG_PCI */ >> 1600 >> 1601 .globl flushw_all >> 1602 flushw_all: >> 1603 save %sp, -0x40, %sp >> 1604 save %sp, -0x40, %sp >> 1605 save %sp, -0x40, %sp >> 1606 save %sp, -0x40, %sp >> 1607 save %sp, -0x40, %sp >> 1608 save %sp, -0x40, %sp >> 1609 save %sp, -0x40, %sp >> 1610 restore >> 1611 restore >> 1612 restore >> 1613 restore >> 1614 restore >> 1615 restore >> 1616 ret >> 1617 restore >> 1618 >> 1619 /* End of entry.S */
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.