1 /* SPDX-License-Identifier: GPL-2.0 */ 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* arch/sparc/kernel/entry.S: Sparc trap low- !! 2 /* >> 3 * arch/alpha/kernel/entry.S 3 * 4 * 4 * Copyright (C) 1995, 2007 David S. Miller (d !! 5 * Kernel entry-points. 5 * Copyright (C) 1996 Eddie C. Dost (ecd@sky << 6 * Copyright (C) 1996 Miguel de Icaza (miguel@ << 7 * Copyright (C) 1996-1999 Jakub Jelinek (jj << 8 * Copyright (C) 1997 Anton Blanchard (anton@p << 9 */ 6 */ 10 7 11 #include <linux/export.h> << 12 #include <linux/linkage.h> << 13 #include <linux/errno.h> << 14 #include <linux/pgtable.h> << 15 << 16 #include <asm/head.h> << 17 #include <asm/asi.h> << 18 #include <asm/smp.h> << 19 #include <asm/contregs.h> << 20 #include <asm/ptrace.h> << 21 #include <asm/asm-offsets.h> 8 #include <asm/asm-offsets.h> 22 #include <asm/psr.h> << 23 #include <asm/vaddrs.h> << 24 #include <asm/page.h> << 25 #include <asm/winmacro.h> << 26 #include <asm/signal.h> << 27 #include <asm/obio.h> << 28 #include <asm/mxcc.h> << 29 #include <asm/thread_info.h> 9 #include <asm/thread_info.h> 30 #include <asm/param.h> !! 10 #include <asm/pal.h> >> 11 #include <asm/errno.h> 31 #include <asm/unistd.h> 12 #include <asm/unistd.h> 32 13 33 #include <asm/asmmacro.h> << 34 << 35 #define curptr g6 << 36 << 37 /* These are just handy. */ << 38 #define _SV save %sp, -STACKFRAME_SZ, % << 39 #define _RS restore << 40 << 41 #define FLUSH_ALL_KERNEL_WINDOWS \ << 42 _SV; _SV; _SV; _SV; _SV; _SV; _SV; \ << 43 _RS; _RS; _RS; _RS; _RS; _RS; _RS; << 44 << 45 .text 14 .text >> 15 .set noat >> 16 .cfi_sections .debug_frame 46 17 47 #ifdef CONFIG_KGDB !! 18 /* Stack offsets. */ 48 .align 4 !! 19 #define SP_OFF 184 49 .globl arch_kgdb_breakpoint !! 20 #define SWITCH_STACK_SIZE 64 50 .type arch_kgdb_breakpoint,# !! 21 51 arch_kgdb_breakpoint: !! 22 .macro CFI_START_OSF_FRAME func 52 ta 0x7d !! 23 .align 4 53 retl !! 24 .globl \func 54 nop !! 25 .type \func,@function 55 .size arch_kgdb_breakpoint,. !! 26 \func: 56 #endif !! 27 .cfi_startproc simple >> 28 .cfi_return_column 64 >> 29 .cfi_def_cfa $sp, 48 >> 30 .cfi_rel_offset 64, 8 >> 31 .cfi_rel_offset $gp, 16 >> 32 .cfi_rel_offset $16, 24 >> 33 .cfi_rel_offset $17, 32 >> 34 .cfi_rel_offset $18, 40 >> 35 .endm >> 36 >> 37 .macro CFI_END_OSF_FRAME func >> 38 .cfi_endproc >> 39 .size \func, . - \func >> 40 .endm 57 41 58 #if defined(CONFIG_BLK_DEV_FD) || defined(CONF !! 42 /* 59 .align 4 !! 43 * This defines the normal kernel pt-regs layout. 60 .globl floppy_hardint !! 44 * 61 floppy_hardint: !! 45 * regs 9-15 preserved by C code 62 /* !! 46 * regs 16-18 saved by PAL-code 63 * This code cannot touch registers %l !! 47 * regs 29-30 saved and set up by PAL-code 64 * because SAVE_ALL depends on their v !! 48 * JRP - Save regs 16-18 in a special area of the stack, so that 65 * on %l3 also, but we regenerate it b !! 49 * the palcode-provided values are available to the signal handler. 66 * Other registers are: !! 50 */ 67 * %l3 -- base address of fdc register << 68 * %l4 -- pdma_vaddr << 69 * %l5 -- scratch for ld/st address << 70 * %l6 -- pdma_size << 71 * %l7 -- scratch [floppy byte, ld/st << 72 */ << 73 << 74 /* Do we have work to do? */ << 75 sethi %hi(doing_pdma), %l7 << 76 ld [%l7 + %lo(doing_pdma)], %l7 << 77 cmp %l7, 0 << 78 be floppy_dosoftint << 79 nop << 80 << 81 /* Load fdc register base */ << 82 sethi %hi(fdc_status), %l3 << 83 ld [%l3 + %lo(fdc_status)], %l3 << 84 << 85 /* Setup register addresses */ << 86 sethi %hi(pdma_vaddr), %l5 ! tran << 87 ld [%l5 + %lo(pdma_vaddr)], %l4 << 88 sethi %hi(pdma_size), %l5 ! byte << 89 ld [%l5 + %lo(pdma_size)], %l6 << 90 next_byte: << 91 ldub [%l3], %l7 << 92 << 93 andcc %l7, 0x80, %g0 ! Does << 94 bz floppy_fifo_emptied ! fifo << 95 andcc %l7, 0x20, %g0 ! in n << 96 bz floppy_overrun ! nope << 97 andcc %l7, 0x40, %g0 ! 0=wr << 98 bz floppy_write << 99 sub %l6, 0x1, %l6 << 100 << 101 /* Ok, actually read this byte */ << 102 ldub [%l3 + 1], %l7 << 103 orcc %g0, %l6, %g0 << 104 stb %l7, [%l4] << 105 bne next_byte << 106 add %l4, 0x1, %l4 << 107 << 108 b floppy_tdone << 109 nop << 110 << 111 floppy_write: << 112 /* Ok, actually write this byte */ << 113 ldub [%l4], %l7 << 114 orcc %g0, %l6, %g0 << 115 stb %l7, [%l3 + 1] << 116 bne next_byte << 117 add %l4, 0x1, %l4 << 118 << 119 /* fall through... */ << 120 floppy_tdone: << 121 sethi %hi(pdma_vaddr), %l5 << 122 st %l4, [%l5 + %lo(pdma_vaddr)] << 123 sethi %hi(pdma_size), %l5 << 124 st %l6, [%l5 + %lo(pdma_size)] << 125 /* Flip terminal count pin */ << 126 set auxio_register, %l7 << 127 ld [%l7], %l7 << 128 << 129 ldub [%l7], %l5 << 130 << 131 or %l5, 0xc2, %l5 << 132 stb %l5, [%l7] << 133 andn %l5, 0x02, %l5 << 134 << 135 2: << 136 /* Kill some time so the bits set */ << 137 WRITE_PAUSE << 138 WRITE_PAUSE << 139 << 140 stb %l5, [%l7] << 141 << 142 /* Prevent recursion */ << 143 sethi %hi(doing_pdma), %l7 << 144 b floppy_dosoftint << 145 st %g0, [%l7 + %lo(doing_pdma)] << 146 << 147 /* We emptied the FIFO, but we haven't << 148 * as of yet. Store the current trans << 149 * bytes left to read so we can contin << 150 * fast IRQ comes in. << 151 */ << 152 floppy_fifo_emptied: << 153 sethi %hi(pdma_vaddr), %l5 << 154 st %l4, [%l5 + %lo(pdma_vaddr)] << 155 sethi %hi(pdma_size), %l7 << 156 st %l6, [%l7 + %lo(pdma_size)] << 157 << 158 /* Restore condition codes */ << 159 wr %l0, 0x0, %psr << 160 WRITE_PAUSE << 161 << 162 jmp %l1 << 163 rett %l2 << 164 << 165 floppy_overrun: << 166 sethi %hi(pdma_vaddr), %l5 << 167 st %l4, [%l5 + %lo(pdma_vaddr)] << 168 sethi %hi(pdma_size), %l5 << 169 st %l6, [%l5 + %lo(pdma_size)] << 170 /* Prevent recursion */ << 171 sethi %hi(doing_pdma), %l7 << 172 st %g0, [%l7 + %lo(doing_pdma)] << 173 << 174 /* fall through... */ << 175 floppy_dosoftint: << 176 rd %wim, %l3 << 177 SAVE_ALL << 178 51 179 /* Set all IRQs off. */ !! 52 .macro SAVE_ALL 180 or %l0, PSR_PIL, %l4 !! 53 subq $sp, SP_OFF, $sp 181 wr %l4, 0x0, %psr !! 54 .cfi_adjust_cfa_offset SP_OFF 182 WRITE_PAUSE !! 55 stq $0, 0($sp) 183 wr %l4, PSR_ET, %psr !! 56 stq $1, 8($sp) 184 WRITE_PAUSE !! 57 stq $2, 16($sp) 185 !! 58 stq $3, 24($sp) 186 mov 11, %o0 ! flop !! 59 stq $4, 32($sp) 187 mov %g0, %o1 ! devi !! 60 stq $28, 144($sp) 188 call sparc_floppy_irq !! 61 .cfi_rel_offset $0, 0 189 add %sp, STACKFRAME_SZ, %o2 ! stru !! 62 .cfi_rel_offset $1, 8 >> 63 .cfi_rel_offset $2, 16 >> 64 .cfi_rel_offset $3, 24 >> 65 .cfi_rel_offset $4, 32 >> 66 .cfi_rel_offset $28, 144 >> 67 lda $2, alpha_mv >> 68 stq $5, 40($sp) >> 69 stq $6, 48($sp) >> 70 stq $7, 56($sp) >> 71 stq $8, 64($sp) >> 72 stq $19, 72($sp) >> 73 stq $20, 80($sp) >> 74 stq $21, 88($sp) >> 75 ldq $2, HAE_CACHE($2) >> 76 stq $22, 96($sp) >> 77 stq $23, 104($sp) >> 78 stq $24, 112($sp) >> 79 stq $25, 120($sp) >> 80 stq $26, 128($sp) >> 81 stq $27, 136($sp) >> 82 stq $2, 152($sp) >> 83 stq $16, 160($sp) >> 84 stq $17, 168($sp) >> 85 stq $18, 176($sp) >> 86 .cfi_rel_offset $5, 40 >> 87 .cfi_rel_offset $6, 48 >> 88 .cfi_rel_offset $7, 56 >> 89 .cfi_rel_offset $8, 64 >> 90 .cfi_rel_offset $19, 72 >> 91 .cfi_rel_offset $20, 80 >> 92 .cfi_rel_offset $21, 88 >> 93 .cfi_rel_offset $22, 96 >> 94 .cfi_rel_offset $23, 104 >> 95 .cfi_rel_offset $24, 112 >> 96 .cfi_rel_offset $25, 120 >> 97 .cfi_rel_offset $26, 128 >> 98 .cfi_rel_offset $27, 136 >> 99 .endm >> 100 >> 101 .macro RESTORE_ALL >> 102 lda $19, alpha_mv >> 103 ldq $0, 0($sp) >> 104 ldq $1, 8($sp) >> 105 ldq $2, 16($sp) >> 106 ldq $3, 24($sp) >> 107 ldq $21, 152($sp) >> 108 ldq $20, HAE_CACHE($19) >> 109 ldq $4, 32($sp) >> 110 ldq $5, 40($sp) >> 111 ldq $6, 48($sp) >> 112 ldq $7, 56($sp) >> 113 subq $20, $21, $20 >> 114 ldq $8, 64($sp) >> 115 beq $20, 99f >> 116 ldq $20, HAE_REG($19) >> 117 stq $21, HAE_CACHE($19) >> 118 stq $21, 0($20) >> 119 99: ldq $19, 72($sp) >> 120 ldq $20, 80($sp) >> 121 ldq $21, 88($sp) >> 122 ldq $22, 96($sp) >> 123 ldq $23, 104($sp) >> 124 ldq $24, 112($sp) >> 125 ldq $25, 120($sp) >> 126 ldq $26, 128($sp) >> 127 ldq $27, 136($sp) >> 128 ldq $28, 144($sp) >> 129 addq $sp, SP_OFF, $sp >> 130 .cfi_restore $0 >> 131 .cfi_restore $1 >> 132 .cfi_restore $2 >> 133 .cfi_restore $3 >> 134 .cfi_restore $4 >> 135 .cfi_restore $5 >> 136 .cfi_restore $6 >> 137 .cfi_restore $7 >> 138 .cfi_restore $8 >> 139 .cfi_restore $19 >> 140 .cfi_restore $20 >> 141 .cfi_restore $21 >> 142 .cfi_restore $22 >> 143 .cfi_restore $23 >> 144 .cfi_restore $24 >> 145 .cfi_restore $25 >> 146 .cfi_restore $26 >> 147 .cfi_restore $27 >> 148 .cfi_restore $28 >> 149 .cfi_adjust_cfa_offset -SP_OFF >> 150 .endm >> 151 >> 152 .macro DO_SWITCH_STACK >> 153 bsr $1, do_switch_stack >> 154 .cfi_adjust_cfa_offset SWITCH_STACK_SIZE >> 155 .cfi_rel_offset $9, 0 >> 156 .cfi_rel_offset $10, 8 >> 157 .cfi_rel_offset $11, 16 >> 158 .cfi_rel_offset $12, 24 >> 159 .cfi_rel_offset $13, 32 >> 160 .cfi_rel_offset $14, 40 >> 161 .cfi_rel_offset $15, 48 >> 162 .endm >> 163 >> 164 .macro UNDO_SWITCH_STACK >> 165 bsr $1, undo_switch_stack >> 166 .cfi_restore $9 >> 167 .cfi_restore $10 >> 168 .cfi_restore $11 >> 169 .cfi_restore $12 >> 170 .cfi_restore $13 >> 171 .cfi_restore $14 >> 172 .cfi_restore $15 >> 173 .cfi_adjust_cfa_offset -SWITCH_STACK_SIZE >> 174 .endm 190 175 191 RESTORE_ALL !! 176 /* 192 !! 177 * Non-syscall kernel entry points. 193 #endif /* (CONFIG_BLK_DEV_FD) */ !! 178 */ 194 179 195 /* Bad trap handler */ !! 180 CFI_START_OSF_FRAME entInt 196 .globl bad_trap_handler << 197 bad_trap_handler: << 198 SAVE_ALL 181 SAVE_ALL 199 !! 182 lda $8, 0x3fff 200 wr %l0, PSR_ET, %psr !! 183 lda $26, ret_from_sys_call 201 WRITE_PAUSE !! 184 bic $sp, $8, $8 202 !! 185 mov $sp, $19 203 add %sp, STACKFRAME_SZ, %o0 ! pt_r !! 186 jsr $31, do_entInt 204 call do_hw_interrupt !! 187 CFI_END_OSF_FRAME entInt 205 mov %l7, %o1 ! trap !! 188 206 !! 189 CFI_START_OSF_FRAME entArith 207 RESTORE_ALL !! 190 SAVE_ALL 208 !! 191 lda $8, 0x3fff 209 /* For now all IRQ's not registered get sent h !! 192 lda $26, ret_from_sys_call 210 * see if a routine is registered to handle th !! 193 bic $sp, $8, $8 211 * it will say so on the console. !! 194 mov $sp, $18 >> 195 jsr $31, do_entArith >> 196 CFI_END_OSF_FRAME entArith >> 197 >> 198 CFI_START_OSF_FRAME entMM >> 199 SAVE_ALL >> 200 /* save $9 - $15 so the inline exception code can manipulate them. */ >> 201 subq $sp, 56, $sp >> 202 .cfi_adjust_cfa_offset 56 >> 203 stq $9, 0($sp) >> 204 stq $10, 8($sp) >> 205 stq $11, 16($sp) >> 206 stq $12, 24($sp) >> 207 stq $13, 32($sp) >> 208 stq $14, 40($sp) >> 209 stq $15, 48($sp) >> 210 .cfi_rel_offset $9, 0 >> 211 .cfi_rel_offset $10, 8 >> 212 .cfi_rel_offset $11, 16 >> 213 .cfi_rel_offset $12, 24 >> 214 .cfi_rel_offset $13, 32 >> 215 .cfi_rel_offset $14, 40 >> 216 .cfi_rel_offset $15, 48 >> 217 addq $sp, 56, $19 >> 218 /* handle the fault */ >> 219 lda $8, 0x3fff >> 220 bic $sp, $8, $8 >> 221 jsr $26, do_page_fault >> 222 /* reload the registers after the exception code played. */ >> 223 ldq $9, 0($sp) >> 224 ldq $10, 8($sp) >> 225 ldq $11, 16($sp) >> 226 ldq $12, 24($sp) >> 227 ldq $13, 32($sp) >> 228 ldq $14, 40($sp) >> 229 ldq $15, 48($sp) >> 230 addq $sp, 56, $sp >> 231 .cfi_restore $9 >> 232 .cfi_restore $10 >> 233 .cfi_restore $11 >> 234 .cfi_restore $12 >> 235 .cfi_restore $13 >> 236 .cfi_restore $14 >> 237 .cfi_restore $15 >> 238 .cfi_adjust_cfa_offset -56 >> 239 /* finish up the syscall as normal. */ >> 240 br ret_from_sys_call >> 241 CFI_END_OSF_FRAME entMM >> 242 >> 243 CFI_START_OSF_FRAME entIF >> 244 SAVE_ALL >> 245 lda $8, 0x3fff >> 246 lda $26, ret_from_sys_call >> 247 bic $sp, $8, $8 >> 248 mov $sp, $17 >> 249 jsr $31, do_entIF >> 250 CFI_END_OSF_FRAME entIF >> 251 >> 252 CFI_START_OSF_FRAME entUna >> 253 lda $sp, -256($sp) >> 254 .cfi_adjust_cfa_offset 256 >> 255 stq $0, 0($sp) >> 256 .cfi_rel_offset $0, 0 >> 257 .cfi_remember_state >> 258 ldq $0, 256($sp) /* get PS */ >> 259 stq $1, 8($sp) >> 260 stq $2, 16($sp) >> 261 stq $3, 24($sp) >> 262 and $0, 8, $0 /* user mode? */ >> 263 stq $4, 32($sp) >> 264 bne $0, entUnaUser /* yup -> do user-level unaligned fault */ >> 265 stq $5, 40($sp) >> 266 stq $6, 48($sp) >> 267 stq $7, 56($sp) >> 268 stq $8, 64($sp) >> 269 stq $9, 72($sp) >> 270 stq $10, 80($sp) >> 271 stq $11, 88($sp) >> 272 stq $12, 96($sp) >> 273 stq $13, 104($sp) >> 274 stq $14, 112($sp) >> 275 stq $15, 120($sp) >> 276 /* 16-18 PAL-saved */ >> 277 stq $19, 152($sp) >> 278 stq $20, 160($sp) >> 279 stq $21, 168($sp) >> 280 stq $22, 176($sp) >> 281 stq $23, 184($sp) >> 282 stq $24, 192($sp) >> 283 stq $25, 200($sp) >> 284 stq $26, 208($sp) >> 285 stq $27, 216($sp) >> 286 stq $28, 224($sp) >> 287 mov $sp, $19 >> 288 stq $gp, 232($sp) >> 289 .cfi_rel_offset $1, 1*8 >> 290 .cfi_rel_offset $2, 2*8 >> 291 .cfi_rel_offset $3, 3*8 >> 292 .cfi_rel_offset $4, 4*8 >> 293 .cfi_rel_offset $5, 5*8 >> 294 .cfi_rel_offset $6, 6*8 >> 295 .cfi_rel_offset $7, 7*8 >> 296 .cfi_rel_offset $8, 8*8 >> 297 .cfi_rel_offset $9, 9*8 >> 298 .cfi_rel_offset $10, 10*8 >> 299 .cfi_rel_offset $11, 11*8 >> 300 .cfi_rel_offset $12, 12*8 >> 301 .cfi_rel_offset $13, 13*8 >> 302 .cfi_rel_offset $14, 14*8 >> 303 .cfi_rel_offset $15, 15*8 >> 304 .cfi_rel_offset $19, 19*8 >> 305 .cfi_rel_offset $20, 20*8 >> 306 .cfi_rel_offset $21, 21*8 >> 307 .cfi_rel_offset $22, 22*8 >> 308 .cfi_rel_offset $23, 23*8 >> 309 .cfi_rel_offset $24, 24*8 >> 310 .cfi_rel_offset $25, 25*8 >> 311 .cfi_rel_offset $26, 26*8 >> 312 .cfi_rel_offset $27, 27*8 >> 313 .cfi_rel_offset $28, 28*8 >> 314 .cfi_rel_offset $29, 29*8 >> 315 lda $8, 0x3fff >> 316 stq $31, 248($sp) >> 317 bic $sp, $8, $8 >> 318 jsr $26, do_entUna >> 319 ldq $0, 0($sp) >> 320 ldq $1, 8($sp) >> 321 ldq $2, 16($sp) >> 322 ldq $3, 24($sp) >> 323 ldq $4, 32($sp) >> 324 ldq $5, 40($sp) >> 325 ldq $6, 48($sp) >> 326 ldq $7, 56($sp) >> 327 ldq $8, 64($sp) >> 328 ldq $9, 72($sp) >> 329 ldq $10, 80($sp) >> 330 ldq $11, 88($sp) >> 331 ldq $12, 96($sp) >> 332 ldq $13, 104($sp) >> 333 ldq $14, 112($sp) >> 334 ldq $15, 120($sp) >> 335 /* 16-18 PAL-saved */ >> 336 ldq $19, 152($sp) >> 337 ldq $20, 160($sp) >> 338 ldq $21, 168($sp) >> 339 ldq $22, 176($sp) >> 340 ldq $23, 184($sp) >> 341 ldq $24, 192($sp) >> 342 ldq $25, 200($sp) >> 343 ldq $26, 208($sp) >> 344 ldq $27, 216($sp) >> 345 ldq $28, 224($sp) >> 346 ldq $gp, 232($sp) >> 347 lda $sp, 256($sp) >> 348 .cfi_restore $1 >> 349 .cfi_restore $2 >> 350 .cfi_restore $3 >> 351 .cfi_restore $4 >> 352 .cfi_restore $5 >> 353 .cfi_restore $6 >> 354 .cfi_restore $7 >> 355 .cfi_restore $8 >> 356 .cfi_restore $9 >> 357 .cfi_restore $10 >> 358 .cfi_restore $11 >> 359 .cfi_restore $12 >> 360 .cfi_restore $13 >> 361 .cfi_restore $14 >> 362 .cfi_restore $15 >> 363 .cfi_restore $19 >> 364 .cfi_restore $20 >> 365 .cfi_restore $21 >> 366 .cfi_restore $22 >> 367 .cfi_restore $23 >> 368 .cfi_restore $24 >> 369 .cfi_restore $25 >> 370 .cfi_restore $26 >> 371 .cfi_restore $27 >> 372 .cfi_restore $28 >> 373 .cfi_restore $29 >> 374 .cfi_adjust_cfa_offset -256 >> 375 call_pal PAL_rti >> 376 >> 377 .align 4 >> 378 entUnaUser: >> 379 .cfi_restore_state >> 380 ldq $0, 0($sp) /* restore original $0 */ >> 381 lda $sp, 256($sp) /* pop entUna's stack frame */ >> 382 .cfi_restore $0 >> 383 .cfi_adjust_cfa_offset -256 >> 384 SAVE_ALL /* setup normal kernel stack */ >> 385 lda $sp, -56($sp) >> 386 .cfi_adjust_cfa_offset 56 >> 387 stq $9, 0($sp) >> 388 stq $10, 8($sp) >> 389 stq $11, 16($sp) >> 390 stq $12, 24($sp) >> 391 stq $13, 32($sp) >> 392 stq $14, 40($sp) >> 393 stq $15, 48($sp) >> 394 .cfi_rel_offset $9, 0 >> 395 .cfi_rel_offset $10, 8 >> 396 .cfi_rel_offset $11, 16 >> 397 .cfi_rel_offset $12, 24 >> 398 .cfi_rel_offset $13, 32 >> 399 .cfi_rel_offset $14, 40 >> 400 .cfi_rel_offset $15, 48 >> 401 lda $8, 0x3fff >> 402 addq $sp, 56, $19 >> 403 bic $sp, $8, $8 >> 404 jsr $26, do_entUnaUser >> 405 ldq $9, 0($sp) >> 406 ldq $10, 8($sp) >> 407 ldq $11, 16($sp) >> 408 ldq $12, 24($sp) >> 409 ldq $13, 32($sp) >> 410 ldq $14, 40($sp) >> 411 ldq $15, 48($sp) >> 412 lda $sp, 56($sp) >> 413 .cfi_restore $9 >> 414 .cfi_restore $10 >> 415 .cfi_restore $11 >> 416 .cfi_restore $12 >> 417 .cfi_restore $13 >> 418 .cfi_restore $14 >> 419 .cfi_restore $15 >> 420 .cfi_adjust_cfa_offset -56 >> 421 br ret_from_sys_call >> 422 CFI_END_OSF_FRAME entUna >> 423 >> 424 CFI_START_OSF_FRAME entDbg >> 425 SAVE_ALL >> 426 lda $8, 0x3fff >> 427 lda $26, ret_from_sys_call >> 428 bic $sp, $8, $8 >> 429 mov $sp, $16 >> 430 jsr $31, do_entDbg >> 431 CFI_END_OSF_FRAME entDbg >> 432 >> 433 /* >> 434 * The system call entry point is special. Most importantly, it looks >> 435 * like a function call to userspace as far as clobbered registers. We >> 436 * do preserve the argument registers (for syscall restarts) and $26 >> 437 * (for leaf syscall functions). >> 438 * >> 439 * So much for theory. We don't take advantage of this yet. >> 440 * >> 441 * Note that a0-a2 are not saved by PALcode as with the other entry points. 212 */ 442 */ 213 443 214 .align 4 444 .align 4 215 .globl real_irq_entry, patch_handler_ !! 445 .globl entSys 216 real_irq_entry: !! 446 .type entSys, @function 217 SAVE_ALL !! 447 .cfi_startproc simple 218 !! 448 .cfi_return_column 64 219 #ifdef CONFIG_SMP !! 449 .cfi_def_cfa $sp, 48 220 .globl patchme_maybe_smp_msg !! 450 .cfi_rel_offset 64, 8 221 !! 451 .cfi_rel_offset $gp, 16 222 cmp %l7, 11 !! 452 entSys: 223 patchme_maybe_smp_msg: !! 453 SAVE_ALL 224 bgu maybe_smp4m_msg !! 454 lda $8, 0x3fff 225 nop !! 455 bic $sp, $8, $8 >> 456 lda $4, NR_syscalls($31) >> 457 stq $16, SP_OFF+24($sp) >> 458 lda $5, sys_call_table >> 459 lda $27, sys_ni_syscall >> 460 cmpult $0, $4, $4 >> 461 ldl $3, TI_FLAGS($8) >> 462 stq $17, SP_OFF+32($sp) >> 463 s8addq $0, $5, $5 >> 464 stq $18, SP_OFF+40($sp) >> 465 .cfi_rel_offset $16, SP_OFF+24 >> 466 .cfi_rel_offset $17, SP_OFF+32 >> 467 .cfi_rel_offset $18, SP_OFF+40 >> 468 #ifdef CONFIG_AUDITSYSCALL >> 469 lda $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT >> 470 and $3, $6, $3 >> 471 bne $3, strace >> 472 #else >> 473 blbs $3, strace /* check for SYSCALL_TRACE in disguise */ 226 #endif 474 #endif >> 475 beq $4, 1f >> 476 ldq $27, 0($5) >> 477 1: jsr $26, ($27), sys_ni_syscall >> 478 ldgp $gp, 0($26) >> 479 blt $0, $syscall_error /* the call failed */ >> 480 $ret_success: >> 481 stq $0, 0($sp) >> 482 stq $31, 72($sp) /* a3=0 => no error */ >> 483 >> 484 .align 4 >> 485 .globl ret_from_sys_call >> 486 ret_from_sys_call: >> 487 cmovne $26, 0, $18 /* $18 = 0 => non-restartable */ >> 488 ldq $0, SP_OFF($sp) >> 489 and $0, 8, $0 >> 490 beq $0, ret_to_kernel >> 491 ret_to_user: >> 492 /* Make sure need_resched and sigpending don't change between >> 493 sampling and the rti. */ >> 494 lda $16, 7 >> 495 call_pal PAL_swpipl >> 496 ldl $17, TI_FLAGS($8) >> 497 and $17, _TIF_WORK_MASK, $2 >> 498 bne $2, work_pending >> 499 restore_all: >> 500 ldl $2, TI_STATUS($8) >> 501 and $2, TS_SAVED_FP | TS_RESTORE_FP, $3 >> 502 bne $3, restore_fpu >> 503 restore_other: >> 504 .cfi_remember_state >> 505 RESTORE_ALL >> 506 call_pal PAL_rti >> 507 >> 508 ret_to_kernel: >> 509 .cfi_restore_state >> 510 lda $16, 7 >> 511 call_pal PAL_swpipl >> 512 br restore_other 227 513 228 real_irq_continue: !! 514 .align 3 229 or %l0, PSR_PIL, %g2 !! 515 $syscall_error: 230 wr %g2, 0x0, %psr !! 516 /* 231 WRITE_PAUSE !! 517 * Some system calls (e.g., ptrace) can return arbitrary 232 wr %g2, PSR_ET, %psr !! 518 * values which might normally be mistaken as error numbers. 233 WRITE_PAUSE !! 519 * Those functions must zero $0 (v0) directly in the stack 234 mov %l7, %o0 ! irq !! 520 * frame to indicate that a negative return value wasn't an 235 patch_handler_irq: !! 521 * error number.. 236 call handler_irq !! 522 */ 237 add %sp, STACKFRAME_SZ, %o1 ! pt_r !! 523 ldq $18, 0($sp) /* old syscall nr (zero if success) */ 238 or %l0, PSR_PIL, %g2 ! rest !! 524 beq $18, $ret_success 239 wr %g2, PSR_ET, %psr ! keep !! 525 240 WRITE_PAUSE !! 526 ldq $19, 72($sp) /* .. and this a3 */ 241 !! 527 subq $31, $0, $0 /* with error in v0 */ 242 RESTORE_ALL !! 528 addq $31, 1, $1 /* set a3 for errno return */ 243 !! 529 stq $0, 0($sp) 244 #ifdef CONFIG_SMP !! 530 mov $31, $26 /* tell "ret_from_sys_call" we can restart */ 245 /* SMP per-cpu ticker interrupts are h !! 531 stq $1, 72($sp) /* a3 for return */ 246 smp4m_ticker: !! 532 br ret_from_sys_call 247 bne real_irq_continue+4 << 248 or %l0, PSR_PIL, %g2 << 249 wr %g2, 0x0, %psr << 250 WRITE_PAUSE << 251 wr %g2, PSR_ET, %psr << 252 WRITE_PAUSE << 253 call smp4m_percpu_timer_interrupt << 254 add %sp, STACKFRAME_SZ, %o0 << 255 wr %l0, PSR_ET, %psr << 256 WRITE_PAUSE << 257 RESTORE_ALL << 258 << 259 #define GET_PROCESSOR4M_ID(reg) \ << 260 rd %tbr, %reg; \ << 261 srl %reg, 12, %reg; \ << 262 and %reg, 3, %reg; << 263 << 264 /* Here is where we check for possible << 265 * on some level other than 15 which i << 266 * for cross calls. That has a separa << 267 * << 268 * IPIs are sent on Level 12, 13 and 1 << 269 */ << 270 maybe_smp4m_msg: << 271 GET_PROCESSOR4M_ID(o3) << 272 sethi %hi(sun4m_irq_percpu), %l5 << 273 sll %o3, 2, %o3 << 274 or %l5, %lo(sun4m_irq_percpu), %o << 275 sethi %hi(0x70000000), %o2 ! Chec << 276 ld [%o5 + %o3], %o1 << 277 ld [%o1 + 0x00], %o3 ! sun4 << 278 andcc %o3, %o2, %g0 << 279 be,a smp4m_ticker << 280 cmp %l7, 14 << 281 /* Soft-IRQ IPI */ << 282 st %o2, [%o1 + 0x04] ! sun4 << 283 WRITE_PAUSE << 284 ld [%o1 + 0x00], %g0 ! sun4 << 285 WRITE_PAUSE << 286 or %l0, PSR_PIL, %l4 << 287 wr %l4, 0x0, %psr << 288 WRITE_PAUSE << 289 wr %l4, PSR_ET, %psr << 290 WRITE_PAUSE << 291 srl %o3, 28, %o2 ! shif << 292 maybe_smp4m_msg_check_single: << 293 andcc %o2, 0x1, %g0 << 294 beq,a maybe_smp4m_msg_check_mask << 295 andcc %o2, 0x2, %g0 << 296 call smp_call_function_single_inter << 297 nop << 298 andcc %o2, 0x2, %g0 << 299 maybe_smp4m_msg_check_mask: << 300 beq,a maybe_smp4m_msg_check_resched << 301 andcc %o2, 0x4, %g0 << 302 call smp_call_function_interrupt << 303 nop << 304 andcc %o2, 0x4, %g0 << 305 maybe_smp4m_msg_check_resched: << 306 /* rescheduling is done in RESTORE_ALL << 307 beq,a maybe_smp4m_msg_out << 308 nop << 309 call smp_resched_interrupt << 310 nop << 311 maybe_smp4m_msg_out: << 312 RESTORE_ALL << 313 << 314 .align 4 << 315 .globl linux_trap_ipi15_sun4m << 316 linux_trap_ipi15_sun4m: << 317 SAVE_ALL << 318 sethi %hi(0x80000000), %o2 << 319 GET_PROCESSOR4M_ID(o0) << 320 sethi %hi(sun4m_irq_percpu), %l5 << 321 or %l5, %lo(sun4m_irq_percpu), %o << 322 sll %o0, 2, %o0 << 323 ld [%o5 + %o0], %o5 << 324 ld [%o5 + 0x00], %o3 ! sun4 << 325 andcc %o3, %o2, %g0 << 326 be sun4m_nmi_error ! Must << 327 st %o2, [%o5 + 0x04] ! sun4 << 328 WRITE_PAUSE << 329 ld [%o5 + 0x00], %g0 ! sun4 << 330 WRITE_PAUSE << 331 or %l0, PSR_PIL, %l4 << 332 wr %l4, 0x0, %psr << 333 WRITE_PAUSE << 334 wr %l4, PSR_ET, %psr << 335 WRITE_PAUSE << 336 call smp4m_cross_call_irq << 337 nop << 338 b ret_trap_lockless_ipi << 339 clr %l6 << 340 << 341 .globl smp4d_ticker << 342 /* SMP per-cpu ticker interrupts are h << 343 smp4d_ticker: << 344 SAVE_ALL << 345 or %l0, PSR_PIL, %g2 << 346 sethi %hi(CC_ICLR), %o0 << 347 sethi %hi(1 << 14), %o1 << 348 or %o0, %lo(CC_ICLR), %o0 << 349 stha %o1, [%o0] ASI_M_MXCC /* Cle << 350 wr %g2, 0x0, %psr << 351 WRITE_PAUSE << 352 wr %g2, PSR_ET, %psr << 353 WRITE_PAUSE << 354 call smp4d_percpu_timer_interrupt << 355 add %sp, STACKFRAME_SZ, %o0 << 356 wr %l0, PSR_ET, %psr << 357 WRITE_PAUSE << 358 RESTORE_ALL << 359 << 360 .align 4 << 361 .globl linux_trap_ipi15_sun4d << 362 linux_trap_ipi15_sun4d: << 363 SAVE_ALL << 364 sethi %hi(CC_BASE), %o4 << 365 sethi %hi(MXCC_ERR_ME|MXCC_ERR_PEW|M << 366 or %o4, (CC_EREG - CC_BASE), %o0 << 367 ldda [%o0] ASI_M_MXCC, %o0 << 368 andcc %o0, %o2, %g0 << 369 bne 1f << 370 sethi %hi(BB_STAT2), %o2 << 371 lduba [%o2] ASI_M_CTL, %o2 << 372 andcc %o2, BB_STAT2_MASK, %g0 << 373 bne 2f << 374 or %o4, (CC_ICLR - CC_BASE), %o0 << 375 sethi %hi(1 << 15), %o1 << 376 stha %o1, [%o0] ASI_M_MXCC /* Cle << 377 or %l0, PSR_PIL, %l4 << 378 wr %l4, 0x0, %psr << 379 WRITE_PAUSE << 380 wr %l4, PSR_ET, %psr << 381 WRITE_PAUSE << 382 call smp4d_cross_call_irq << 383 nop << 384 b ret_trap_lockless_ipi << 385 clr %l6 << 386 << 387 1: /* MXCC error */ << 388 2: /* BB error */ << 389 /* Disable PIL 15 */ << 390 set CC_IMSK, %l4 << 391 lduha [%l4] ASI_M_MXCC, %l5 << 392 sethi %hi(1 << 15), %l7 << 393 or %l5, %l7, %l5 << 394 stha %l5, [%l4] ASI_M_MXCC << 395 /* FIXME */ << 396 1: b,a 1b << 397 << 398 .globl smpleon_ipi << 399 .extern leon_ipi_interrupt << 400 /* SMP per-cpu IPI interrupts are hand << 401 smpleon_ipi: << 402 SAVE_ALL << 403 or %l0, PSR_PIL, %g2 << 404 wr %g2, 0x0, %psr << 405 WRITE_PAUSE << 406 wr %g2, PSR_ET, %psr << 407 WRITE_PAUSE << 408 call leonsmp_ipi_interrupt << 409 add %sp, STACKFRAME_SZ, %o1 ! pt_r << 410 wr %l0, PSR_ET, %psr << 411 WRITE_PAUSE << 412 RESTORE_ALL << 413 << 414 .align 4 << 415 .globl linux_trap_ipi15_leon << 416 linux_trap_ipi15_leon: << 417 SAVE_ALL << 418 or %l0, PSR_PIL, %l4 << 419 wr %l4, 0x0, %psr << 420 WRITE_PAUSE << 421 wr %l4, PSR_ET, %psr << 422 WRITE_PAUSE << 423 call leon_cross_call_irq << 424 nop << 425 b ret_trap_lockless_ipi << 426 clr %l6 << 427 << 428 #endif /* CONFIG_SMP */ << 429 << 430 /* This routine handles illegal instru << 431 * instruction attempts from user code << 432 */ << 433 .align 4 << 434 .globl bad_instruction << 435 bad_instruction: << 436 sethi %hi(0xc1f80000), %l4 << 437 ld [%l1], %l5 << 438 sethi %hi(0x81d80000), %l7 << 439 and %l5, %l4, %l5 << 440 cmp %l5, %l7 << 441 be 1f << 442 SAVE_ALL << 443 << 444 wr %l0, PSR_ET, %psr << 445 WRITE_PAUSE << 446 << 447 add %sp, STACKFRAME_SZ, %o0 << 448 mov %l1, %o1 << 449 mov %l2, %o2 << 450 call do_illegal_instruction << 451 mov %l0, %o3 << 452 << 453 RESTORE_ALL << 454 << 455 1: /* unimplemented flush - just skip */ << 456 jmpl %l2, %g0 << 457 rett %l2 + 4 << 458 << 459 .align 4 << 460 .globl priv_instruction << 461 priv_instruction: << 462 SAVE_ALL << 463 << 464 wr %l0, PSR_ET, %psr << 465 WRITE_PAUSE << 466 << 467 add %sp, STACKFRAME_SZ, %o0 << 468 mov %l1, %o1 << 469 mov %l2, %o2 << 470 call do_priv_instruction << 471 mov %l0, %o3 << 472 << 473 RESTORE_ALL << 474 << 475 /* This routine handles unaligned data << 476 .align 4 << 477 .globl mna_handler << 478 mna_handler: << 479 andcc %l0, PSR_PS, %g0 << 480 be mna_fromuser << 481 nop << 482 << 483 SAVE_ALL << 484 << 485 wr %l0, PSR_ET, %psr << 486 WRITE_PAUSE << 487 << 488 ld [%l1], %o1 << 489 call kernel_unaligned_trap << 490 add %sp, STACKFRAME_SZ, %o0 << 491 << 492 RESTORE_ALL << 493 << 494 mna_fromuser: << 495 SAVE_ALL << 496 << 497 wr %l0, PSR_ET, %psr << 498 WRITE_PAUSE << 499 << 500 ld [%l1], %o1 << 501 call user_unaligned_trap << 502 add %sp, STACKFRAME_SZ, %o0 << 503 << 504 RESTORE_ALL << 505 << 506 /* This routine handles floating point << 507 .align 4 << 508 .globl fpd_trap_handler << 509 fpd_trap_handler: << 510 SAVE_ALL << 511 << 512 wr %l0, PSR_ET, %psr << 513 WRITE_PAUSE << 514 << 515 add %sp, STACKFRAME_SZ, %o0 << 516 mov %l1, %o1 << 517 mov %l2, %o2 << 518 call do_fpd_trap << 519 mov %l0, %o3 << 520 << 521 RESTORE_ALL << 522 << 523 /* This routine handles Floating Point << 524 .align 4 << 525 .globl fpe_trap_handler << 526 fpe_trap_handler: << 527 set fpsave_magic, %l5 << 528 cmp %l1, %l5 << 529 be 1f << 530 sethi %hi(fpsave), %l5 << 531 or %l5, %lo(fpsave), %l5 << 532 cmp %l1, %l5 << 533 bne 2f << 534 sethi %hi(fpsave_catch2), %l5 << 535 or %l5, %lo(fpsave_catch2), %l5 << 536 wr %l0, 0x0, %psr << 537 WRITE_PAUSE << 538 jmp %l5 << 539 rett %l5 + 4 << 540 1: << 541 sethi %hi(fpsave_catch), %l5 << 542 or %l5, %lo(fpsave_catch), %l5 << 543 wr %l0, 0x0, %psr << 544 WRITE_PAUSE << 545 jmp %l5 << 546 rett %l5 + 4 << 547 << 548 2: << 549 SAVE_ALL << 550 << 551 wr %l0, PSR_ET, %psr << 552 WRITE_PAUSE << 553 << 554 add %sp, STACKFRAME_SZ, %o0 << 555 mov %l1, %o1 << 556 mov %l2, %o2 << 557 call do_fpe_trap << 558 mov %l0, %o3 << 559 << 560 RESTORE_ALL << 561 << 562 /* This routine handles Tag Overflow E << 563 .align 4 << 564 .globl do_tag_overflow << 565 do_tag_overflow: << 566 SAVE_ALL << 567 << 568 wr %l0, PSR_ET, %psr << 569 WRITE_PAUSE << 570 << 571 add %sp, STACKFRAME_SZ, %o0 << 572 mov %l1, %o1 << 573 mov %l2, %o2 << 574 call handle_tag_overflow << 575 mov %l0, %o3 << 576 << 577 RESTORE_ALL << 578 << 579 /* This routine handles Watchpoint Exc << 580 .align 4 << 581 .globl do_watchpoint << 582 do_watchpoint: << 583 SAVE_ALL << 584 << 585 wr %l0, PSR_ET, %psr << 586 WRITE_PAUSE << 587 << 588 add %sp, STACKFRAME_SZ, %o0 << 589 mov %l1, %o1 << 590 mov %l2, %o2 << 591 call handle_watchpoint << 592 mov %l0, %o3 << 593 << 594 RESTORE_ALL << 595 << 596 /* This routine handles Register Acces << 597 .align 4 << 598 .globl do_reg_access << 599 do_reg_access: << 600 SAVE_ALL << 601 << 602 wr %l0, PSR_ET, %psr << 603 WRITE_PAUSE << 604 << 605 add %sp, STACKFRAME_SZ, %o0 << 606 mov %l1, %o1 << 607 mov %l2, %o2 << 608 call handle_reg_access << 609 mov %l0, %o3 << 610 << 611 RESTORE_ALL << 612 << 613 /* This routine handles Co-Processor D << 614 .align 4 << 615 .globl do_cp_disabled << 616 do_cp_disabled: << 617 SAVE_ALL << 618 << 619 wr %l0, PSR_ET, %psr << 620 WRITE_PAUSE << 621 << 622 add %sp, STACKFRAME_SZ, %o0 << 623 mov %l1, %o1 << 624 mov %l2, %o2 << 625 call handle_cp_disabled << 626 mov %l0, %o3 << 627 << 628 RESTORE_ALL << 629 << 630 /* This routine handles Co-Processor E << 631 .align 4 << 632 .globl do_cp_exception << 633 do_cp_exception: << 634 SAVE_ALL << 635 << 636 wr %l0, PSR_ET, %psr << 637 WRITE_PAUSE << 638 << 639 add %sp, STACKFRAME_SZ, %o0 << 640 mov %l1, %o1 << 641 mov %l2, %o2 << 642 call handle_cp_exception << 643 mov %l0, %o3 << 644 << 645 RESTORE_ALL << 646 << 647 /* This routine handles Hardware Divid << 648 .align 4 << 649 .globl do_hw_divzero << 650 do_hw_divzero: << 651 SAVE_ALL << 652 << 653 wr %l0, PSR_ET, %psr << 654 WRITE_PAUSE << 655 << 656 add %sp, STACKFRAME_SZ, %o0 << 657 mov %l1, %o1 << 658 mov %l2, %o2 << 659 call handle_hw_divzero << 660 mov %l0, %o3 << 661 << 662 RESTORE_ALL << 663 << 664 .align 4 << 665 .globl do_flush_windows << 666 do_flush_windows: << 667 SAVE_ALL << 668 << 669 wr %l0, PSR_ET, %psr << 670 WRITE_PAUSE << 671 << 672 andcc %l0, PSR_PS, %g0 << 673 bne dfw_kernel << 674 nop << 675 << 676 call flush_user_windows << 677 nop << 678 << 679 /* Advance over the trap instruction. << 680 ld [%sp + STACKFRAME_SZ + PT_NPC] << 681 add %l1, 0x4, %l2 << 682 st %l1, [%sp + STACKFRAME_SZ + PT << 683 st %l2, [%sp + STACKFRAME_SZ + PT << 684 << 685 RESTORE_ALL << 686 << 687 .globl flush_patch_one << 688 << 689 /* We get these for debugging routines << 690 dfw_kernel: << 691 flush_patch_one: << 692 FLUSH_ALL_KERNEL_WINDOWS << 693 << 694 /* Advance over the trap instruction. << 695 ld [%sp + STACKFRAME_SZ + PT_NPC] << 696 add %l1, 0x4, %l2 << 697 st %l1, [%sp + STACKFRAME_SZ + PT << 698 st %l2, [%sp + STACKFRAME_SZ + PT << 699 << 700 RESTORE_ALL << 701 << 702 /* The getcc software trap. The user << 703 * the %psr in register %g1. << 704 */ << 705 << 706 .align 4 << 707 .globl getcc_trap_handler << 708 getcc_trap_handler: << 709 srl %l0, 20, %g1 ! give user << 710 and %g1, 0xf, %g1 ! only ICC bit << 711 jmp %l2 ! advance over << 712 rett %l2 + 0x4 ! like this... << 713 << 714 /* The setcc software trap. The user << 715 * that it would like placed in the %p << 716 * any unintentional bits! << 717 */ << 718 << 719 .align 4 << 720 .globl setcc_trap_handler << 721 setcc_trap_handler: << 722 sll %g1, 0x14, %l4 << 723 set PSR_ICC, %l5 << 724 andn %l0, %l5, %l0 ! clear ICC bi << 725 and %l4, %l5, %l4 ! clear non-IC << 726 or %l4, %l0, %l4 ! or them in.. << 727 << 728 wr %l4, 0x0, %psr ! set new %psr << 729 WRITE_PAUSE ! TI scumbags. << 730 << 731 jmp %l2 ! advance over << 732 rett %l2 + 0x4 ! like this... << 733 << 734 sun4m_nmi_error: << 735 /* NMI async memory error handling. */ << 736 sethi %hi(0x80000000), %l4 << 737 sethi %hi(sun4m_irq_global), %o5 << 738 ld [%o5 + %lo(sun4m_irq_global)], << 739 st %l4, [%l5 + 0x0c] ! sun4 << 740 WRITE_PAUSE << 741 ld [%l5 + 0x00], %g0 ! sun4 << 742 WRITE_PAUSE << 743 or %l0, PSR_PIL, %l4 << 744 wr %l4, 0x0, %psr << 745 WRITE_PAUSE << 746 wr %l4, PSR_ET, %psr << 747 WRITE_PAUSE << 748 call sun4m_nmi << 749 nop << 750 st %l4, [%l5 + 0x08] ! sun4 << 751 WRITE_PAUSE << 752 ld [%l5 + 0x00], %g0 ! sun4 << 753 WRITE_PAUSE << 754 RESTORE_ALL << 755 << 756 #ifndef CONFIG_SMP << 757 .align 4 << 758 .globl linux_trap_ipi15_sun4m << 759 linux_trap_ipi15_sun4m: << 760 SAVE_ALL << 761 533 762 ba sun4m_nmi_error !! 534 /* 763 nop !! 535 * Do all cleanup when returning from all interrupts and system calls. 764 #endif /* CONFIG_SMP */ !! 536 * >> 537 * Arguments: >> 538 * $8: current. >> 539 * $17: TI_FLAGS. >> 540 * $18: The old syscall number, or zero if this is not a return >> 541 * from a syscall that errored and is possibly restartable. >> 542 * $19: The old a3 value >> 543 */ 765 544 766 .align 4 545 .align 4 767 .globl srmmu_fault !! 546 .type work_pending, @function 768 srmmu_fault: !! 547 work_pending: 769 mov 0x400, %l5 !! 548 and $17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL, $2 770 mov 0x300, %l4 !! 549 bne $2, $work_notifysig 771 << 772 LEON_PI(lda [%l5] ASI_LEON_MMUREGS, %l6) << 773 SUN_PI_(lda [%l5] ASI_M_MMUREGS, %l6) << 774 << 775 LEON_PI(lda [%l4] ASI_LEON_MMUREGS, %l5) << 776 SUN_PI_(lda [%l4] ASI_M_MMUREGS, %l5) << 777 << 778 andn %l6, 0xfff, %l6 << 779 srl %l5, 6, %l5 << 780 550 781 and %l5, 2, %l5 !! 551 $work_resched: 782 or %l5, %l6, %l6 !! 552 /* 783 !! 553 * We can get here only if we returned from syscall without SIGPENDING 784 or %l6, %l7, %l7 !! 554 * or got through work_notifysig already. Either case means no syscall 785 !! 555 * restarts for us, so let $18 and $19 burn. 786 SAVE_ALL !! 556 */ 787 !! 557 jsr $26, schedule 788 mov %l7, %o1 !! 558 mov 0, $18 789 mov %l7, %o2 !! 559 br ret_to_user 790 and %o1, 1, %o1 ! arg2 !! 560 791 mov %l7, %o3 !! 561 $work_notifysig: 792 and %o2, 2, %o2 ! arg3 !! 562 mov $sp, $16 793 andn %o3, 0xfff, %o3 ! arg4 !! 563 DO_SWITCH_STACK 794 !! 564 jsr $26, do_work_pending 795 wr %l0, PSR_ET, %psr !! 565 UNDO_SWITCH_STACK 796 WRITE_PAUSE !! 566 br restore_all 797 << 798 call do_sparc_fault << 799 add %sp, STACKFRAME_SZ, %o0 ! arg1 << 800 567 801 RESTORE_ALL !! 568 /* >> 569 * PTRACE syscall handler >> 570 */ 802 571 803 .align 4 572 .align 4 804 sunos_execv: !! 573 .type strace, @function 805 .globl sunos_execv !! 574 strace: 806 b sys_execve !! 575 /* set up signal stack, call syscall_trace */ 807 clr %i2 !! 576 // NB: if anyone adds preemption, this block will need to be protected >> 577 ldl $1, TI_STATUS($8) >> 578 and $1, TS_SAVED_FP, $3 >> 579 or $1, TS_SAVED_FP, $2 >> 580 bne $3, 1f >> 581 stl $2, TI_STATUS($8) >> 582 bsr $26, __save_fpu >> 583 1: >> 584 DO_SWITCH_STACK >> 585 jsr $26, syscall_trace_enter /* returns the syscall number */ >> 586 UNDO_SWITCH_STACK >> 587 >> 588 /* get the arguments back.. */ >> 589 ldq $16, SP_OFF+24($sp) >> 590 ldq $17, SP_OFF+32($sp) >> 591 ldq $18, SP_OFF+40($sp) >> 592 ldq $19, 72($sp) >> 593 ldq $20, 80($sp) >> 594 ldq $21, 88($sp) >> 595 >> 596 /* get the system call pointer.. */ >> 597 lda $1, NR_syscalls($31) >> 598 lda $2, sys_call_table >> 599 lda $27, sys_ni_syscall >> 600 cmpult $0, $1, $1 >> 601 s8addq $0, $2, $2 >> 602 beq $1, 1f >> 603 ldq $27, 0($2) >> 604 1: jsr $26, ($27), sys_gettimeofday >> 605 ret_from_straced: >> 606 ldgp $gp, 0($26) >> 607 >> 608 /* check return.. */ >> 609 blt $0, $strace_error /* the call failed */ >> 610 $strace_success: >> 611 stq $31, 72($sp) /* a3=0 => no error */ >> 612 stq $0, 0($sp) /* save return value */ >> 613 >> 614 DO_SWITCH_STACK >> 615 jsr $26, syscall_trace_leave >> 616 UNDO_SWITCH_STACK >> 617 br $31, ret_from_sys_call >> 618 >> 619 .align 3 >> 620 $strace_error: >> 621 ldq $18, 0($sp) /* old syscall nr (zero if success) */ >> 622 beq $18, $strace_success >> 623 ldq $19, 72($sp) /* .. and this a3 */ >> 624 >> 625 subq $31, $0, $0 /* with error in v0 */ >> 626 addq $31, 1, $1 /* set a3 for errno return */ >> 627 stq $0, 0($sp) >> 628 stq $1, 72($sp) /* a3 for return */ >> 629 >> 630 DO_SWITCH_STACK >> 631 mov $18, $9 /* save old syscall number */ >> 632 mov $19, $10 /* save old a3 */ >> 633 jsr $26, syscall_trace_leave >> 634 mov $9, $18 >> 635 mov $10, $19 >> 636 UNDO_SWITCH_STACK >> 637 >> 638 mov $31, $26 /* tell "ret_from_sys_call" we can restart */ >> 639 br ret_from_sys_call >> 640 CFI_END_OSF_FRAME entSys >> 641 >> 642 /* >> 643 * Save and restore the switch stack -- aka the balance of the user context. >> 644 */ 808 645 809 .align 4 646 .align 4 810 .globl sys_sigstack !! 647 .type do_switch_stack, @function 811 sys_sigstack: !! 648 .cfi_startproc simple 812 mov %o7, %l5 !! 649 .cfi_return_column 64 813 mov %fp, %o2 !! 650 .cfi_def_cfa $sp, 0 814 call do_sys_sigstack !! 651 .cfi_register 64, $1 815 mov %l5, %o7 !! 652 do_switch_stack: >> 653 lda $sp, -SWITCH_STACK_SIZE($sp) >> 654 .cfi_adjust_cfa_offset SWITCH_STACK_SIZE >> 655 stq $9, 0($sp) >> 656 stq $10, 8($sp) >> 657 stq $11, 16($sp) >> 658 stq $12, 24($sp) >> 659 stq $13, 32($sp) >> 660 stq $14, 40($sp) >> 661 stq $15, 48($sp) >> 662 stq $26, 56($sp) >> 663 ret $31, ($1), 1 >> 664 .cfi_endproc >> 665 .size do_switch_stack, .-do_switch_stack >> 666 >> 667 .align 4 >> 668 .type undo_switch_stack, @function >> 669 .cfi_startproc simple >> 670 .cfi_def_cfa $sp, 0 >> 671 .cfi_register 64, $1 >> 672 undo_switch_stack: >> 673 ldq $9, 0($sp) >> 674 ldq $10, 8($sp) >> 675 ldq $11, 16($sp) >> 676 ldq $12, 24($sp) >> 677 ldq $13, 32($sp) >> 678 ldq $14, 40($sp) >> 679 ldq $15, 48($sp) >> 680 ldq $26, 56($sp) >> 681 lda $sp, SWITCH_STACK_SIZE($sp) >> 682 ret $31, ($1), 1 >> 683 .cfi_endproc >> 684 .size undo_switch_stack, .-undo_switch_stack >> 685 >> 686 #define FR(n) n * 8 + TI_FP($8) >> 687 .align 4 >> 688 .globl __save_fpu >> 689 .type __save_fpu, @function >> 690 __save_fpu: >> 691 #define V(n) stt $f##n, FR(n) >> 692 V( 0); V( 1); V( 2); V( 3) >> 693 V( 4); V( 5); V( 6); V( 7) >> 694 V( 8); V( 9); V(10); V(11) >> 695 V(12); V(13); V(14); V(15) >> 696 V(16); V(17); V(18); V(19) >> 697 V(20); V(21); V(22); V(23) >> 698 V(24); V(25); V(26); V(27) >> 699 mf_fpcr $f0 # get fpcr >> 700 V(28); V(29); V(30) >> 701 stt $f0, FR(31) # save fpcr in slot of $f31 >> 702 ldt $f0, FR(0) # don't let "__save_fpu" change fp state. >> 703 ret >> 704 #undef V >> 705 .size __save_fpu, .-__save_fpu 816 706 817 .align 4 707 .align 4 818 .globl sys_sigreturn !! 708 restore_fpu: 819 sys_sigreturn: !! 709 and $3, TS_RESTORE_FP, $3 820 call do_sigreturn !! 710 bic $2, TS_SAVED_FP | TS_RESTORE_FP, $2 821 add %sp, STACKFRAME_SZ, %o0 !! 711 beq $3, 1f 822 !! 712 #define V(n) ldt $f##n, FR(n) 823 ld [%curptr + TI_FLAGS], %l5 !! 713 ldt $f30, FR(31) # get saved fpcr 824 andcc %l5, _TIF_SYSCALL_TRACE, %g0 !! 714 V( 0); V( 1); V( 2); V( 3) 825 be 1f !! 715 mt_fpcr $f30 # install saved fpcr 826 nop !! 716 V( 4); V( 5); V( 6); V( 7) 827 !! 717 V( 8); V( 9); V(10); V(11) 828 call syscall_trace !! 718 V(12); V(13); V(14); V(15) 829 mov 1, %o1 !! 719 V(16); V(17); V(18); V(19) 830 !! 720 V(20); V(21); V(22); V(23) 831 1: !! 721 V(24); V(25); V(26); V(27) 832 /* We don't want to muck with user reg !! 722 V(28); V(29); V(30) 833 * normal syscall, just return. !! 723 1: stl $2, TI_STATUS($8) 834 */ !! 724 br restore_other 835 RESTORE_ALL !! 725 #undef V 836 !! 726 >> 727 >> 728 /* >> 729 * The meat of the context switch code. >> 730 */ 837 .align 4 731 .align 4 838 .globl sys_rt_sigreturn !! 732 .globl alpha_switch_to 839 sys_rt_sigreturn: !! 733 .type alpha_switch_to, @function 840 call do_rt_sigreturn !! 734 .cfi_startproc 841 add %sp, STACKFRAME_SZ, %o0 !! 735 alpha_switch_to: 842 !! 736 DO_SWITCH_STACK 843 ld [%curptr + TI_FLAGS], %l5 !! 737 ldl $1, TI_STATUS($8) 844 andcc %l5, _TIF_SYSCALL_TRACE, %g0 !! 738 and $1, TS_RESTORE_FP, $3 845 be 1f !! 739 bne $3, 1f 846 nop !! 740 or $1, TS_RESTORE_FP | TS_SAVED_FP, $2 847 !! 741 and $1, TS_SAVED_FP, $3 848 add %sp, STACKFRAME_SZ, %o0 !! 742 stl $2, TI_STATUS($8) 849 call syscall_trace !! 743 bne $3, 1f 850 mov 1, %o1 !! 744 bsr $26, __save_fpu 851 << 852 1: 745 1: 853 /* We are returning to a signal handle !! 746 call_pal PAL_swpctx 854 RESTORE_ALL !! 747 lda $8, 0x3fff >> 748 UNDO_SWITCH_STACK >> 749 bic $sp, $8, $8 >> 750 mov $17, $0 >> 751 ret >> 752 .cfi_endproc >> 753 .size alpha_switch_to, .-alpha_switch_to 855 754 856 /* Now that we have a real sys_clone, !! 755 /* 857 * implemented in terms of it. Our _r !! 756 * New processes begin life here. 858 * of SunOS vfork() will use sys_vfork !! 757 */ 859 * << 860 * XXX These three should be consolida << 861 * XXX code just like on sparc64... -D << 862 */ << 863 .align 4 << 864 .globl sys_fork, flush_patch_two << 865 sys_fork: << 866 mov %o7, %l5 << 867 flush_patch_two: << 868 FLUSH_ALL_KERNEL_WINDOWS; << 869 ld [%curptr + TI_TASK], %o4 << 870 rd %psr, %g4 << 871 WRITE_PAUSE << 872 rd %wim, %g5 << 873 WRITE_PAUSE << 874 std %g4, [%o4 + AOFF_task_thread + << 875 add %sp, STACKFRAME_SZ, %o0 << 876 call sparc_fork << 877 mov %l5, %o7 << 878 << 879 /* Whee, kernel threads! */ << 880 .globl sys_clone, flush_patch_three << 881 sys_clone: << 882 mov %o7, %l5 << 883 flush_patch_three: << 884 FLUSH_ALL_KERNEL_WINDOWS; << 885 ld [%curptr + TI_TASK], %o4 << 886 rd %psr, %g4 << 887 WRITE_PAUSE << 888 rd %wim, %g5 << 889 WRITE_PAUSE << 890 std %g4, [%o4 + AOFF_task_thread + << 891 add %sp, STACKFRAME_SZ, %o0 << 892 call sparc_clone << 893 mov %l5, %o7 << 894 << 895 /* Whee, real vfork! */ << 896 .globl sys_vfork, flush_patch_four << 897 sys_vfork: << 898 flush_patch_four: << 899 FLUSH_ALL_KERNEL_WINDOWS; << 900 ld [%curptr + TI_TASK], %o4 << 901 rd %psr, %g4 << 902 WRITE_PAUSE << 903 rd %wim, %g5 << 904 WRITE_PAUSE << 905 std %g4, [%o4 + AOFF_task_thread + << 906 sethi %hi(sparc_vfork), %l1 << 907 jmpl %l1 + %lo(sparc_vfork), %g0 << 908 add %sp, STACKFRAME_SZ, %o0 << 909 << 910 .align 4 << 911 linux_sparc_ni_syscall: << 912 sethi %hi(sys_ni_syscall), %l7 << 913 b do_syscall << 914 or %l7, %lo(sys_ni_syscall), %l7 << 915 << 916 linux_syscall_trace: << 917 add %sp, STACKFRAME_SZ, %o0 << 918 call syscall_trace << 919 mov 0, %o1 << 920 cmp %o0, 0 << 921 bne 3f << 922 mov -ENOSYS, %o0 << 923 << 924 /* Syscall tracing can modify the regi << 925 ld [%sp + STACKFRAME_SZ + PT_G1], << 926 sethi %hi(sys_call_table), %l7 << 927 ld [%sp + STACKFRAME_SZ + PT_I0], << 928 or %l7, %lo(sys_call_table), %l7 << 929 ld [%sp + STACKFRAME_SZ + PT_I1], << 930 ld [%sp + STACKFRAME_SZ + PT_I2], << 931 ld [%sp + STACKFRAME_SZ + PT_I3], << 932 ld [%sp + STACKFRAME_SZ + PT_I4], << 933 ld [%sp + STACKFRAME_SZ + PT_I5], << 934 cmp %g1, NR_syscalls << 935 bgeu 3f << 936 mov -ENOSYS, %o0 << 937 << 938 sll %g1, 2, %l4 << 939 mov %i0, %o0 << 940 ld [%l7 + %l4], %l7 << 941 mov %i1, %o1 << 942 mov %i2, %o2 << 943 mov %i3, %o3 << 944 b 2f << 945 mov %i4, %o4 << 946 758 947 .globl ret_from_fork 759 .globl ret_from_fork >> 760 .align 4 >> 761 .ent ret_from_fork 948 ret_from_fork: 762 ret_from_fork: 949 call schedule_tail !! 763 lda $26, ret_to_user 950 ld [%g3 + TI_TASK], %o0 !! 764 mov $17, $16 951 b ret_sys_call !! 765 jmp $31, schedule_tail 952 ld [%sp + STACKFRAME_SZ + PT_I0], !! 766 .end ret_from_fork 953 767 >> 768 /* >> 769 * ... and new kernel threads - here >> 770 */ >> 771 .align 4 954 .globl ret_from_kernel_thread 772 .globl ret_from_kernel_thread >> 773 .ent ret_from_kernel_thread 955 ret_from_kernel_thread: 774 ret_from_kernel_thread: 956 call schedule_tail !! 775 mov $17, $16 957 ld [%g3 + TI_TASK], %o0 !! 776 jsr $26, schedule_tail 958 ld [%sp + STACKFRAME_SZ + PT_G1], !! 777 mov $9, $27 959 call %l0 !! 778 mov $10, $16 960 ld [%sp + STACKFRAME_SZ + PT_G2], !! 779 jsr $26, ($9) 961 rd %psr, %l1 !! 780 br $31, ret_to_user 962 ld [%sp + STACKFRAME_SZ + PT_PSR] !! 781 .end ret_from_kernel_thread 963 andn %l0, PSR_CWP, %l0 !! 782 964 nop !! 783 965 and %l1, PSR_CWP, %l1 !! 784 /* 966 or %l0, %l1, %l0 !! 785 * Special system calls. Most of these are special in that they either 967 st %l0, [%sp + STACKFRAME_SZ + PT !! 786 * have to play switch_stack games. 968 b ret_sys_call << 969 mov 0, %o0 << 970 << 971 /* Linux native system calls enter her << 972 .align 4 << 973 .globl linux_sparc_syscall << 974 linux_sparc_syscall: << 975 sethi %hi(PSR_SYSCALL), %l4 << 976 or %l0, %l4, %l0 << 977 /* Direct access to user regs, must fa << 978 cmp %g1, NR_syscalls << 979 bgeu linux_sparc_ni_syscall << 980 sll %g1, 2, %l4 << 981 ld [%l7 + %l4], %l7 << 982 << 983 do_syscall: << 984 SAVE_ALL_HEAD << 985 rd %wim, %l3 << 986 << 987 wr %l0, PSR_ET, %psr << 988 mov %i0, %o0 << 989 mov %i1, %o1 << 990 mov %i2, %o2 << 991 << 992 ld [%curptr + TI_FLAGS], %l5 << 993 mov %i3, %o3 << 994 andcc %l5, _TIF_SYSCALL_TRACE, %g0 << 995 mov %i4, %o4 << 996 bne linux_syscall_trace << 997 mov %i0, %l6 << 998 2: << 999 call %l7 << 1000 mov %i5, %o5 << 1001 << 1002 3: << 1003 st %o0, [%sp + STACKFRAME_SZ + P << 1004 << 1005 ret_sys_call: << 1006 ld [%curptr + TI_FLAGS], %l5 << 1007 cmp %o0, -ERESTART_RESTARTBLOCK << 1008 ld [%sp + STACKFRAME_SZ + PT_PSR << 1009 set PSR_C, %g2 << 1010 bgeu 1f << 1011 andcc %l5, _TIF_SYSCALL_TRACE, %g0 << 1012 << 1013 /* System call success, clear Carry c << 1014 andn %g3, %g2, %g3 << 1015 st %g3, [%sp + STACKFRAME_SZ + P << 1016 bne linux_syscall_trace2 << 1017 ld [%sp + STACKFRAME_SZ + PT_NPC << 1018 add %l1, 0x4, %l2 << 1019 st %l1, [%sp + STACKFRAME_SZ + P << 1020 b ret_trap_entry << 1021 st %l2, [%sp + STACKFRAME_SZ + P << 1022 1: << 1023 /* System call failure, set Carry con << 1024 * Also, get abs(errno) to return to << 1025 */ << 1026 sub %g0, %o0, %o0 << 1027 or %g3, %g2, %g3 << 1028 st %o0, [%sp + STACKFRAME_SZ + P << 1029 st %g3, [%sp + STACKFRAME_SZ + P << 1030 bne linux_syscall_trace2 << 1031 ld [%sp + STACKFRAME_SZ + PT_NPC << 1032 add %l1, 0x4, %l2 << 1033 st %l1, [%sp + STACKFRAME_SZ + P << 1034 b ret_trap_entry << 1035 st %l2, [%sp + STACKFRAME_SZ + P << 1036 << 1037 linux_syscall_trace2: << 1038 add %sp, STACKFRAME_SZ, %o0 << 1039 mov 1, %o1 << 1040 call syscall_trace << 1041 add %l1, 0x4, %l2 << 1042 st %l1, [%sp + STACKFRAME_SZ + P << 1043 b ret_trap_entry << 1044 st %l2, [%sp + STACKFRAME_SZ + P << 1045 << 1046 << 1047 /* Saving and restoring the FPU state is best << 1048 * << 1049 * void fpsave(unsigned long *fpregs, unsigne << 1050 * void *fpqueue, unsigned long * << 1051 */ 787 */ 1052 788 1053 .globl fpsave !! 789 .macro fork_like name 1054 fpsave: << 1055 st %fsr, [%o1] ! this can tr << 1056 ld [%o1], %g1 << 1057 set 0x2000, %g4 << 1058 andcc %g1, %g4, %g0 << 1059 be 2f << 1060 mov 0, %g2 << 1061 << 1062 /* We have an fpqueue to save. */ << 1063 1: << 1064 std %fq, [%o2] << 1065 fpsave_magic: << 1066 st %fsr, [%o1] << 1067 ld [%o1], %g3 << 1068 andcc %g3, %g4, %g0 << 1069 add %g2, 1, %g2 << 1070 bne 1b << 1071 add %o2, 8, %o2 << 1072 << 1073 2: << 1074 st %g2, [%o3] << 1075 << 1076 std %f0, [%o0 + 0x00] << 1077 std %f2, [%o0 + 0x08] << 1078 std %f4, [%o0 + 0x10] << 1079 std %f6, [%o0 + 0x18] << 1080 std %f8, [%o0 + 0x20] << 1081 std %f10, [%o0 + 0x28] << 1082 std %f12, [%o0 + 0x30] << 1083 std %f14, [%o0 + 0x38] << 1084 std %f16, [%o0 + 0x40] << 1085 std %f18, [%o0 + 0x48] << 1086 std %f20, [%o0 + 0x50] << 1087 std %f22, [%o0 + 0x58] << 1088 std %f24, [%o0 + 0x60] << 1089 std %f26, [%o0 + 0x68] << 1090 std %f28, [%o0 + 0x70] << 1091 retl << 1092 std %f30, [%o0 + 0x78] << 1093 << 1094 /* Thanks for Theo Deraadt and the au << 1095 * code for pointing out this possibl << 1096 * above we could trap on the fsr sto << 1097 * code has to know how to deal with << 1098 */ << 1099 fpsave_catch: << 1100 b fpsave_magic + 4 << 1101 st %fsr, [%o1] << 1102 << 1103 fpsave_catch2: << 1104 b fpsave + 4 << 1105 st %fsr, [%o1] << 1106 << 1107 /* void fpload(unsigned long *fpregs, << 1108 << 1109 .globl fpload << 1110 fpload: << 1111 ldd [%o0 + 0x00], %f0 << 1112 ldd [%o0 + 0x08], %f2 << 1113 ldd [%o0 + 0x10], %f4 << 1114 ldd [%o0 + 0x18], %f6 << 1115 ldd [%o0 + 0x20], %f8 << 1116 ldd [%o0 + 0x28], %f10 << 1117 ldd [%o0 + 0x30], %f12 << 1118 ldd [%o0 + 0x38], %f14 << 1119 ldd [%o0 + 0x40], %f16 << 1120 ldd [%o0 + 0x48], %f18 << 1121 ldd [%o0 + 0x50], %f20 << 1122 ldd [%o0 + 0x58], %f22 << 1123 ldd [%o0 + 0x60], %f24 << 1124 ldd [%o0 + 0x68], %f26 << 1125 ldd [%o0 + 0x70], %f28 << 1126 ldd [%o0 + 0x78], %f30 << 1127 ld [%o1], %fsr << 1128 retl << 1129 nop << 1130 << 1131 /* __ndelay and __udelay take two arg << 1132 * 0 - nsecs or usecs to delay << 1133 * 1 - per_cpu udelay_val (loops per << 1134 * << 1135 * Note that ndelay gives HZ times hi << 1136 * limit. udelay can handle up to 1s << 1137 */ << 1138 .globl __ndelay << 1139 __ndelay: << 1140 save %sp, -STACKFRAME_SZ, %sp << 1141 mov %i0, %o0 ! rou << 1142 mov 0x1ae, %o1 ! 2** << 1143 umul %o0, %o1, %o0 << 1144 rd %y, %o1 << 1145 mov %i1, %o1 ! ude << 1146 umul %o0, %o1, %o0 << 1147 rd %y, %o1 << 1148 ba delay_continue << 1149 mov %o1, %o0 ! >>3 << 1150 << 1151 .globl __udelay << 1152 __udelay: << 1153 save %sp, -STACKFRAME_SZ, %sp << 1154 mov %i0, %o0 << 1155 sethi %hi(0x10c7), %o1 ! rou << 1156 or %o1, %lo(0x10c7), %o1 ! 2** << 1157 umul %o0, %o1, %o0 << 1158 rd %y, %o1 << 1159 mov %i1, %o1 ! ude << 1160 umul %o0, %o1, %o0 << 1161 rd %y, %o1 << 1162 sethi %hi(0x028f4b62), %l0 ! Add << 1163 or %g0, %lo(0x028f4b62), %l0 << 1164 addcc %o0, %l0, %o0 ! 2** << 1165 bcs,a 3f << 1166 add %o1, 0x01, %o1 << 1167 3: << 1168 mov HZ, %o0 ! >>3 << 1169 umul %o0, %o1, %o0 << 1170 rd %y, %o1 << 1171 << 1172 delay_continue: << 1173 cmp %o0, 0x0 << 1174 1: << 1175 bne 1b << 1176 subcc %o0, 1, %o0 << 1177 << 1178 ret << 1179 restore << 1180 EXPORT_SYMBOL(__udelay) << 1181 EXPORT_SYMBOL(__ndelay) << 1182 << 1183 /* Handle a software breakpoint */ << 1184 /* We have to inform parent that chil << 1185 .align 4 << 1186 .globl breakpoint_trap << 1187 breakpoint_trap: << 1188 rd %wim,%l3 << 1189 SAVE_ALL << 1190 wr %l0, PSR_ET, %psr << 1191 WRITE_PAUSE << 1192 << 1193 st %i0, [%sp + STACKFRAME_SZ + P << 1194 call sparc_breakpoint << 1195 add %sp, STACKFRAME_SZ, %o0 << 1196 << 1197 RESTORE_ALL << 1198 << 1199 #ifdef CONFIG_KGDB << 1200 ENTRY(kgdb_trap_low) << 1201 rd %wim,%l3 << 1202 SAVE_ALL << 1203 wr %l0, PSR_ET, %psr << 1204 WRITE_PAUSE << 1205 << 1206 mov %l7, %o0 ! tra << 1207 call kgdb_trap << 1208 add %sp, STACKFRAME_SZ, %o1 ! str << 1209 << 1210 RESTORE_ALL << 1211 ENDPROC(kgdb_trap_low) << 1212 #endif << 1213 << 1214 .align 4 790 .align 4 1215 .globl flush_patch_exception !! 791 .globl alpha_\name 1216 flush_patch_exception: !! 792 .ent alpha_\name 1217 FLUSH_ALL_KERNEL_WINDOWS; !! 793 alpha_\name: 1218 ldd [%o0], %o6 !! 794 .prologue 0 1219 jmpl %o7 + 0xc, %g0 !! 795 bsr $1, do_switch_stack 1220 mov 1, %g1 !! 796 // NB: if anyone adds preemption, this block will need to be protected 1221 !! 797 ldl $1, TI_STATUS($8) 1222 .align 4 !! 798 and $1, TS_SAVED_FP, $3 1223 .globl kill_user_windows, kuw_patch1 !! 799 or $1, TS_SAVED_FP, $2 1224 .globl kuw_patch1 !! 800 bne $3, 1f 1225 kuw_patch1_7win: sll %o3, 6, %o3 !! 801 stl $2, TI_STATUS($8) 1226 !! 802 bsr $26, __save_fpu 1227 /* No matter how much overhead this r << 1228 * case scenario, it is several times << 1229 * traps with the old method of just << 1230 */ << 1231 kill_user_windows: << 1232 ld [%g6 + TI_UWINMASK], %o0 << 1233 orcc %g0, %o0, %g0 << 1234 be 3f << 1235 rd %psr, %o5 << 1236 or %o5, PSR_PIL, %o4 << 1237 wr %o4, 0x0, %psr << 1238 WRITE_PAUSE << 1239 1: 803 1: 1240 ld [%g6 + TI_UWINMASK], %o0 !! 804 jsr $26, sys_\name 1241 orcc %g0, %o0, %g0 !! 805 ldq $26, 56($sp) 1242 be 4f !! 806 lda $sp, SWITCH_STACK_SIZE($sp) 1243 rd %wim, %o3 << 1244 srl %o3, 1, %o4 << 1245 kuw_patch1: << 1246 sll %o3, 7, %o3 << 1247 or %o4, %o3, %o3 << 1248 andncc %o0, %o3, %o0 << 1249 bne kuw_patch1 << 1250 srl %o3, 1, %o4 << 1251 wr %o3, 0x0, %wim << 1252 st %g0, [%g6 + TI_UWINMASK] << 1253 4: << 1254 wr %o5, 0x0, %psr << 1255 WRITE_PAUSE << 1256 3: << 1257 retl << 1258 st %g0, [%g6 + TI_W_SAVED] << 1259 << 1260 .align 4 << 1261 .globl restore_current << 1262 restore_current: << 1263 LOAD_CURRENT(g6, o0) << 1264 retl << 1265 nop << 1266 << 1267 #ifdef CONFIG_PCIC_PCI << 1268 #include <asm/pcic.h> << 1269 << 1270 .align 4 << 1271 .globl linux_trap_ipi15_pcic << 1272 linux_trap_ipi15_pcic: << 1273 rd %wim, %l3 << 1274 SAVE_ALL << 1275 << 1276 /* << 1277 * First deactivate NMI << 1278 * or we cannot drop ET, cannot get w << 1279 * The busy loop is necessary because << 1280 * sometimes does not go away quickly << 1281 */ << 1282 sethi %hi(pcic_regs), %o1 << 1283 ld [%o1 + %lo(pcic_regs)], %o2 << 1284 << 1285 ! Get pending status for printouts la << 1286 ld [%o2 + PCI_SYS_INT_PENDING], << 1287 << 1288 mov PCI_SYS_INT_PENDING_CLEAR_ALL << 1289 stb %o1, [%o2 + PCI_SYS_INT_PENDI << 1290 1: << 1291 ld [%o2 + PCI_SYS_INT_PENDING], << 1292 andcc %o1, ((PCI_SYS_INT_PENDING_PI << 1293 bne 1b << 1294 nop << 1295 << 1296 or %l0, PSR_PIL, %l4 << 1297 wr %l4, 0x0, %psr << 1298 WRITE_PAUSE << 1299 wr %l4, PSR_ET, %psr << 1300 WRITE_PAUSE << 1301 << 1302 call pcic_nmi << 1303 add %sp, STACKFRAME_SZ, %o1 ! str << 1304 RESTORE_ALL << 1305 << 1306 .globl pcic_nmi_trap_patch << 1307 pcic_nmi_trap_patch: << 1308 sethi %hi(linux_trap_ipi15_pcic), % << 1309 jmpl %l3 + %lo(linux_trap_ipi15_pc << 1310 rd %psr, %l0 << 1311 .word 0 << 1312 << 1313 #endif /* CONFIG_PCIC_PCI */ << 1314 << 1315 .globl flushw_all << 1316 flushw_all: << 1317 save %sp, -0x40, %sp << 1318 save %sp, -0x40, %sp << 1319 save %sp, -0x40, %sp << 1320 save %sp, -0x40, %sp << 1321 save %sp, -0x40, %sp << 1322 save %sp, -0x40, %sp << 1323 save %sp, -0x40, %sp << 1324 restore << 1325 restore << 1326 restore << 1327 restore << 1328 restore << 1329 restore << 1330 ret 807 ret 1331 restore !! 808 .end alpha_\name >> 809 .endm 1332 810 1333 #ifdef CONFIG_SMP !! 811 fork_like fork 1334 ENTRY(hard_smp_processor_id) !! 812 fork_like vfork 1335 661: rd %tbr, %g1 !! 813 fork_like clone 1336 srl %g1, 12, %o0 !! 814 fork_like clone3 1337 and %o0, 3, %o0 !! 815 1338 .section .cpuid_patch, "ax" !! 816 .macro sigreturn_like name 1339 /* Instruction location. */ !! 817 .align 4 1340 .word 661b !! 818 .globl sys_\name 1341 /* SUN4D implementation. */ !! 819 .ent sys_\name 1342 lda [%g0] ASI_M_VIKING_TM !! 820 sys_\name: 1343 nop !! 821 .prologue 0 1344 nop !! 822 lda $9, ret_from_straced 1345 /* LEON implementation. */ !! 823 cmpult $26, $9, $9 1346 rd %asr17, %o0 !! 824 lda $sp, -SWITCH_STACK_SIZE($sp) 1347 srl %o0, 0x1c, %o0 !! 825 jsr $26, do_\name 1348 nop !! 826 bne $9, 1f 1349 .previous !! 827 jsr $26, syscall_trace_leave 1350 retl !! 828 1: br $1, undo_switch_stack 1351 nop !! 829 br ret_from_sys_call 1352 ENDPROC(hard_smp_processor_id) !! 830 .end sys_\name 1353 #endif !! 831 .endm 1354 !! 832 1355 /* End of entry.S */ !! 833 sigreturn_like sigreturn >> 834 sigreturn_like rt_sigreturn >> 835 >> 836 .align 4 >> 837 .globl alpha_syscall_zero >> 838 .ent alpha_syscall_zero >> 839 alpha_syscall_zero: >> 840 .prologue 0 >> 841 /* Special because it needs to do something opposite to >> 842 force_successful_syscall_return(). We use the saved >> 843 syscall number for that, zero meaning "not an error". >> 844 That works nicely, but for real syscall 0 we need to >> 845 make sure that this logics doesn't get confused. >> 846 Store a non-zero there - -ENOSYS we need in register >> 847 for our return value will do just fine. >> 848 */ >> 849 lda $0, -ENOSYS >> 850 unop >> 851 stq $0, 0($sp) >> 852 ret >> 853 .end alpha_syscall_zero
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.