1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * arch/alpha/kernel/entry.S 4 * 5 * Kernel entry-points. 6 */ 7 8#include <asm/asm-offsets.h> 9#include <asm/thread_info.h> 10#include <asm/pal.h> 11#include <asm/errno.h> 12#include <asm/unistd.h> 13#include <linux/errno.h> 14 15 .text 16 .set noat 17 .cfi_sections .debug_frame 18 19.macro CFI_START_OSF_FRAME func 20 .align 4 21 .globl \func 22 .type \func,@function 23\func: 24 .cfi_startproc simple 25 .cfi_return_column 64 26 .cfi_def_cfa $sp, 48 27 .cfi_rel_offset 64, 8 28 .cfi_rel_offset $gp, 16 29 .cfi_rel_offset $16, 24 30 .cfi_rel_offset $17, 32 31 .cfi_rel_offset $18, 40 32.endm 33 34.macro CFI_END_OSF_FRAME func 35 .cfi_endproc 36 .size \func, . - \func 37.endm 38 39.macro LOCKDEP_HARDIRQS_ON_RESTORE psreg 40#ifdef CONFIG_PROVE_LOCKING 41 /* a0 = saved PS */ 42 ldq $16, \psreg 43 44 /* a1 = callsite IP for lockdep */ 45 lda $17, 1f 46 47 jsr $26, lockdep_on_restore 48 ldgp $gp, 0($26) 491: 50#endif 51.endm 52 53/* 54 * This defines the normal kernel pt-regs layout. 55 * 56 * regs 9-15 preserved by C code 57 * regs 16-18 saved by PAL-code 58 * regs 29-30 saved and set up by PAL-code 59 * JRP - Save regs 16-18 in a special area of the stack, so that 60 * the palcode-provided values are available to the signal handler. 61 */ 62 63.macro SAVE_ALL 64 subq $sp, SP_OFF, $sp 65 .cfi_adjust_cfa_offset SP_OFF 66 stq $0, 0($sp) 67 stq $1, 8($sp) 68 stq $2, 16($sp) 69 stq $3, 24($sp) 70 stq $4, 32($sp) 71 stq $28, 144($sp) 72 .cfi_rel_offset $0, 0 73 .cfi_rel_offset $1, 8 74 .cfi_rel_offset $2, 16 75 .cfi_rel_offset $3, 24 76 .cfi_rel_offset $4, 32 77 .cfi_rel_offset $28, 144 78 lda $2, alpha_mv 79 stq $5, 40($sp) 80 stq $6, 48($sp) 81 stq $7, 56($sp) 82 stq $8, 64($sp) 83 stq $19, 72($sp) 84 stq $20, 80($sp) 85 stq $21, 88($sp) 86 ldq $2, HAE_CACHE($2) 87 stq $22, 96($sp) 88 stq $23, 104($sp) 89 stq $24, 112($sp) 90 stq $25, 120($sp) 91 stq $26, 128($sp) 92 stq $27, 136($sp) 93 stq $2, 152($sp) 94 stq $16, 160($sp) 95 stq $17, 168($sp) 96 stq $18, 176($sp) 97 .cfi_rel_offset $5, 40 98 .cfi_rel_offset $6, 48 99 .cfi_rel_offset $7, 56 100 .cfi_rel_offset $8, 64 101 .cfi_rel_offset $19, 72 102 .cfi_rel_offset $20, 80 103 .cfi_rel_offset $21, 88 104 .cfi_rel_offset $22, 96 105 .cfi_rel_offset $23, 104 106 .cfi_rel_offset $24, 112 107 .cfi_rel_offset $25, 120 108 .cfi_rel_offset $26, 128 109 .cfi_rel_offset $27, 136 110.endm 111 112.macro RESTORE_ALL 113 lda $19, alpha_mv 114 ldq $0, 0($sp) 115 ldq $1, 8($sp) 116 ldq $2, 16($sp) 117 ldq $3, 24($sp) 118 ldq $21, 152($sp) 119 ldq $20, HAE_CACHE($19) 120 ldq $4, 32($sp) 121 ldq $5, 40($sp) 122 ldq $6, 48($sp) 123 ldq $7, 56($sp) 124 subq $20, $21, $20 125 ldq $8, 64($sp) 126 beq $20, 99f 127 ldq $20, HAE_REG($19) 128 stq $21, HAE_CACHE($19) 129 stq $21, 0($20) 13099: ldq $19, 72($sp) 131 ldq $20, 80($sp) 132 ldq $21, 88($sp) 133 ldq $22, 96($sp) 134 ldq $23, 104($sp) 135 ldq $24, 112($sp) 136 ldq $25, 120($sp) 137 ldq $26, 128($sp) 138 ldq $27, 136($sp) 139 ldq $28, 144($sp) 140 addq $sp, SP_OFF, $sp 141 .cfi_restore $0 142 .cfi_restore $1 143 .cfi_restore $2 144 .cfi_restore $3 145 .cfi_restore $4 146 .cfi_restore $5 147 .cfi_restore $6 148 .cfi_restore $7 149 .cfi_restore $8 150 .cfi_restore $19 151 .cfi_restore $20 152 .cfi_restore $21 153 .cfi_restore $22 154 .cfi_restore $23 155 .cfi_restore $24 156 .cfi_restore $25 157 .cfi_restore $26 158 .cfi_restore $27 159 .cfi_restore $28 160 .cfi_adjust_cfa_offset -SP_OFF 161.endm 162 163.macro DO_SWITCH_STACK 164 bsr $1, do_switch_stack 165 .cfi_adjust_cfa_offset SWITCH_STACK_SIZE 166 .cfi_rel_offset $9, 0 167 .cfi_rel_offset $10, 8 168 .cfi_rel_offset $11, 16 169 .cfi_rel_offset $12, 24 170 .cfi_rel_offset $13, 32 171 .cfi_rel_offset $14, 40 172 .cfi_rel_offset $15, 48 173.endm 174 175.macro UNDO_SWITCH_STACK 176 bsr $1, undo_switch_stack 177 .cfi_restore $9 178 .cfi_restore $10 179 .cfi_restore $11 180 .cfi_restore $12 181 .cfi_restore $13 182 .cfi_restore $14 183 .cfi_restore $15 184 .cfi_adjust_cfa_offset -SWITCH_STACK_SIZE 185.endm 186 187/* 188 * Non-syscall kernel entry points. 189 */ 190 191CFI_START_OSF_FRAME entInt 192 SAVE_ALL 193 lda $8, 0x3fff 194 lda $26, ret_from_exception 195 bic $sp, $8, $8 196 mov $sp, $19 197 jsr $31, do_entInt 198CFI_END_OSF_FRAME entInt 199 200CFI_START_OSF_FRAME entArith 201 SAVE_ALL 202 lda $8, 0x3fff 203 lda $26, ret_from_exception 204 bic $sp, $8, $8 205 mov $sp, $18 206 jsr $31, do_entArith 207CFI_END_OSF_FRAME entArith 208 209CFI_START_OSF_FRAME entMM 210 SAVE_ALL 211/* save $9 - $15 so the inline exception code can manipulate them. */ 212 subq $sp, 64, $sp 213 .cfi_adjust_cfa_offset 64 214 stq $9, 0($sp) 215 stq $10, 8($sp) 216 stq $11, 16($sp) 217 stq $12, 24($sp) 218 stq $13, 32($sp) 219 stq $14, 40($sp) 220 stq $15, 48($sp) 221 .cfi_rel_offset $9, 0 222 .cfi_rel_offset $10, 8 223 .cfi_rel_offset $11, 16 224 .cfi_rel_offset $12, 24 225 .cfi_rel_offset $13, 32 226 .cfi_rel_offset $14, 40 227 .cfi_rel_offset $15, 48 228 addq $sp, 64, $19 229/* handle the fault */ 230 lda $8, 0x3fff 231 bic $sp, $8, $8 232 jsr $26, do_page_fault 233/* reload the registers after the exception code played. */ 234 ldq $9, 0($sp) 235 ldq $10, 8($sp) 236 ldq $11, 16($sp) 237 ldq $12, 24($sp) 238 ldq $13, 32($sp) 239 ldq $14, 40($sp) 240 ldq $15, 48($sp) 241 addq $sp, 64, $sp 242 .cfi_restore $9 243 .cfi_restore $10 244 .cfi_restore $11 245 .cfi_restore $12 246 .cfi_restore $13 247 .cfi_restore $14 248 .cfi_restore $15 249 .cfi_adjust_cfa_offset -64 250/* finish up the syscall as normal. */ 251 br ret_from_exception 252CFI_END_OSF_FRAME entMM 253 254CFI_START_OSF_FRAME entIF 255 SAVE_ALL 256 lda $8, 0x3fff 257 lda $26, ret_from_exception 258 bic $sp, $8, $8 259 mov $sp, $17 260 jsr $31, do_entIF 261CFI_END_OSF_FRAME entIF 262 263CFI_START_OSF_FRAME entUna 264 lda $sp, -256($sp) 265 .cfi_adjust_cfa_offset 256 266 stq $0, 0($sp) 267 .cfi_rel_offset $0, 0 268 .cfi_remember_state 269 ldq $0, 256($sp) /* get PS */ 270 stq $1, 8($sp) 271 stq $2, 16($sp) 272 stq $3, 24($sp) 273 and $0, 8, $0 /* user mode? */ 274 stq $4, 32($sp) 275 bne $0, entUnaUser /* yup -> do user-level unaligned fault */ 276 stq $5, 40($sp) 277 stq $6, 48($sp) 278 stq $7, 56($sp) 279 stq $8, 64($sp) 280 stq $9, 72($sp) 281 stq $10, 80($sp) 282 stq $11, 88($sp) 283 stq $12, 96($sp) 284 stq $13, 104($sp) 285 stq $14, 112($sp) 286 stq $15, 120($sp) 287 /* 16-18 PAL-saved */ 288 stq $19, 152($sp) 289 stq $20, 160($sp) 290 stq $21, 168($sp) 291 stq $22, 176($sp) 292 stq $23, 184($sp) 293 stq $24, 192($sp) 294 stq $25, 200($sp) 295 stq $26, 208($sp) 296 stq $27, 216($sp) 297 stq $28, 224($sp) 298 mov $sp, $19 299 stq $gp, 232($sp) 300 .cfi_rel_offset $1, 1*8 301 .cfi_rel_offset $2, 2*8 302 .cfi_rel_offset $3, 3*8 303 .cfi_rel_offset $4, 4*8 304 .cfi_rel_offset $5, 5*8 305 .cfi_rel_offset $6, 6*8 306 .cfi_rel_offset $7, 7*8 307 .cfi_rel_offset $8, 8*8 308 .cfi_rel_offset $9, 9*8 309 .cfi_rel_offset $10, 10*8 310 .cfi_rel_offset $11, 11*8 311 .cfi_rel_offset $12, 12*8 312 .cfi_rel_offset $13, 13*8 313 .cfi_rel_offset $14, 14*8 314 .cfi_rel_offset $15, 15*8 315 .cfi_rel_offset $19, 19*8 316 .cfi_rel_offset $20, 20*8 317 .cfi_rel_offset $21, 21*8 318 .cfi_rel_offset $22, 22*8 319 .cfi_rel_offset $23, 23*8 320 .cfi_rel_offset $24, 24*8 321 .cfi_rel_offset $25, 25*8 322 .cfi_rel_offset $26, 26*8 323 .cfi_rel_offset $27, 27*8 324 .cfi_rel_offset $28, 28*8 325 .cfi_rel_offset $29, 29*8 326 lda $8, 0x3fff 327 stq $31, 248($sp) 328 bic $sp, $8, $8 329 jsr $26, do_entUna 330 ldq $0, 0($sp) 331 ldq $1, 8($sp) 332 ldq $2, 16($sp) 333 ldq $3, 24($sp) 334 ldq $4, 32($sp) 335 ldq $5, 40($sp) 336 ldq $6, 48($sp) 337 ldq $7, 56($sp) 338 ldq $8, 64($sp) 339 ldq $9, 72($sp) 340 ldq $10, 80($sp) 341 ldq $11, 88($sp) 342 ldq $12, 96($sp) 343 ldq $13, 104($sp) 344 ldq $14, 112($sp) 345 ldq $15, 120($sp) 346 /* 16-18 PAL-saved */ 347 ldq $19, 152($sp) 348 ldq $20, 160($sp) 349 ldq $21, 168($sp) 350 ldq $22, 176($sp) 351 ldq $23, 184($sp) 352 ldq $24, 192($sp) 353 ldq $25, 200($sp) 354 ldq $26, 208($sp) 355 ldq $27, 216($sp) 356 ldq $28, 224($sp) 357 ldq $gp, 232($sp) 358 lda $sp, 256($sp) 359 .cfi_restore $1 360 .cfi_restore $2 361 .cfi_restore $3 362 .cfi_restore $4 363 .cfi_restore $5 364 .cfi_restore $6 365 .cfi_restore $7 366 .cfi_restore $8 367 .cfi_restore $9 368 .cfi_restore $10 369 .cfi_restore $11 370 .cfi_restore $12 371 .cfi_restore $13 372 .cfi_restore $14 373 .cfi_restore $15 374 .cfi_restore $19 375 .cfi_restore $20 376 .cfi_restore $21 377 .cfi_restore $22 378 .cfi_restore $23 379 .cfi_restore $24 380 .cfi_restore $25 381 .cfi_restore $26 382 .cfi_restore $27 383 .cfi_restore $28 384 .cfi_restore $29 385 .cfi_adjust_cfa_offset -256 386 LOCKDEP_HARDIRQS_ON_RESTORE SP_OFF($sp) 387 call_pal PAL_rti 388 389 .align 4 390entUnaUser: 391 .cfi_restore_state 392 ldq $0, 0($sp) /* restore original $0 */ 393 lda $sp, 256($sp) /* pop entUna's stack frame */ 394 .cfi_restore $0 395 .cfi_adjust_cfa_offset -256 396 SAVE_ALL /* setup normal kernel stack */ 397 lda $sp, -64($sp) 398 .cfi_adjust_cfa_offset 64 399 stq $9, 0($sp) 400 stq $10, 8($sp) 401 stq $11, 16($sp) 402 stq $12, 24($sp) 403 stq $13, 32($sp) 404 stq $14, 40($sp) 405 stq $15, 48($sp) 406 .cfi_rel_offset $9, 0 407 .cfi_rel_offset $10, 8 408 .cfi_rel_offset $11, 16 409 .cfi_rel_offset $12, 24 410 .cfi_rel_offset $13, 32 411 .cfi_rel_offset $14, 40 412 .cfi_rel_offset $15, 48 413 lda $8, 0x3fff 414 addq $sp, 64, $19 415 bic $sp, $8, $8 416 jsr $26, do_entUnaUser 417 ldq $9, 0($sp) 418 ldq $10, 8($sp) 419 ldq $11, 16($sp) 420 ldq $12, 24($sp) 421 ldq $13, 32($sp) 422 ldq $14, 40($sp) 423 ldq $15, 48($sp) 424 lda $sp, 64($sp) 425 .cfi_restore $9 426 .cfi_restore $10 427 .cfi_restore $11 428 .cfi_restore $12 429 .cfi_restore $13 430 .cfi_restore $14 431 .cfi_restore $15 432 .cfi_adjust_cfa_offset -64 433 br ret_from_exception 434CFI_END_OSF_FRAME entUna 435 436CFI_START_OSF_FRAME entDbg 437 SAVE_ALL 438 lda $8, 0x3fff 439 lda $26, ret_from_exception 440 bic $sp, $8, $8 441 mov $sp, $16 442 jsr $31, do_entDbg 443CFI_END_OSF_FRAME entDbg 444 445 446/* 447 * The system call entry point is special. Most importantly, it looks 448 * like a function call to userspace as far as clobbered registers. We 449 * do preserve the argument registers (for syscall restarts) and $26 450 * (for leaf syscall functions). 451 * 452 * So much for theory. We don't take advantage of this yet. 453 * 454 * Note that a0-a2 are not saved by PALcode as with the other entry points. 455 * 456 * Alpha syscall ABI uses: 457 * - r0 for return value 458 * - r19 ("a3") as error indicator (0=success, 1=error; r0 holds errno) 459 * 460 * For seccomp/ptrace/generic syscall helpers we track the syscall 461 * number separately: 462 * - regs->r1: current (mutable) syscall number (may be changed or set to -1) 463 * 464 */ 465 466 .align 4 467 .globl entSys 468 .type entSys, @function 469 .cfi_startproc simple 470 .cfi_return_column 64 471 .cfi_def_cfa $sp, 48 472 .cfi_rel_offset 64, 8 473 .cfi_rel_offset $gp, 16 474entSys: 475 SAVE_ALL 476 ldq $1, 0($sp) /* syscall nr from saved r0 */ 477 stq $1, 8($sp) /* regs->r1 = shadow syscall nr */ 478 479 lda $8, 0x3fff 480 bic $sp, $8, $8 481 482 stq $16, SP_OFF+24($sp) 483 stq $17, SP_OFF+32($sp) 484 stq $18, SP_OFF+40($sp) 485 486 mov $0, $1 487 lda $16, 7 488 call_pal PAL_swpipl 489 mov $1, $0 490 mov $sp, $16 491 mov $0, $17 /* pv = selected syscall function */ 492 493 DO_SWITCH_STACK 494 jsr $26, alpha_syscall_enter_select 495 ldgp $gp, 0($26) 496 UNDO_SWITCH_STACK 497 498 /* 499 * C returned syscall function pointer in $0. 500 * It also stored SKIP in TI_SYSCALL_META if dispatch is skipped. 501 */ 502 lda $8, 0x3fff 503 bic $sp, $8, $8 504 ldq $3, TI_SYSCALL_META($8) 505 lda $6, ALPHA_SYSCALL_META_SKIP 506 and $3, $6, $6 507 bne $6, skip_dispatch 508 509 510 mov $0, $27 511 ldq $16, SP_OFF+24($sp) 512 ldq $17, SP_OFF+32($sp) 513 ldq $18, SP_OFF+40($sp) 514 ldq $19, 72($sp) 515 ldq $20, 80($sp) 516 ldq $21, 88($sp) 517 518 jsr $26, ($27), sys_ni_syscall 519 ldgp $gp, 0($26) 520 521skip_dispatch: 522 mov $0, $17 /* raw ret; ignored if SKIP is set */ 523 mov $sp, $16 /* regs */ 524 525 DO_SWITCH_STACK 526 jsr $26, alpha_finish_syscall_to_user_mode 527 ldgp $gp, 0($26) 528 UNDO_SWITCH_STACK 529 530restore_all: 531 lda $8, 0x3fff 532 bic $sp, $8, $8 533 ldl $2, TI_STATUS($8) 534 and $2, TS_SAVED_FP | TS_RESTORE_FP, $3 535 bne $3, restore_fpu 536restore_other: 537 .cfi_remember_state 538 RESTORE_ALL 539 call_pal PAL_rti 540 541ret_to_user_from_syscall: 542 lda $8, 0x3fff 543 bic $sp, $8, $8 544 545 mov $sp, $16 546 DO_SWITCH_STACK 547 jsr $26, alpha_syscall_exit_to_user_mode 548 ldgp $gp, 0($26) 549 UNDO_SWITCH_STACK 550 br restore_all 551 552 .align 4 553 .globl ret_from_sys_call 554ret_from_sys_call: 555 ldq $0, SP_OFF($sp) 556 and $0, 8, $0 557 beq $0, ret_to_kernel 558 br ret_to_user_from_syscall 559 560ret_from_exception: 561 ldq $0, SP_OFF($sp) 562 and $0, 8, $0 563 beq $0, ret_to_kernel 564 br ret_to_user_from_exception 565 566ret_to_user_from_exception: 567 568 mov $sp, $16 569 DO_SWITCH_STACK 570 jsr $26, alpha_exit_to_user_mode 571 ldgp $gp, 0($26) 572 UNDO_SWITCH_STACK 573 br restore_all 574 575ret_to_kernel: 576 .cfi_restore_state 577 lda $16, 7 578 call_pal PAL_swpipl 579 LOCKDEP_HARDIRQS_ON_RESTORE SP_OFF($sp) 580 br restore_other 581 582CFI_END_OSF_FRAME entSys 583 584/* 585 * Save and restore the switch stack -- aka the balance of the user context. 586 */ 587 588 .align 4 589 .type do_switch_stack, @function 590 .cfi_startproc simple 591 .cfi_return_column 64 592 .cfi_def_cfa $sp, 0 593 .cfi_register 64, $1 594do_switch_stack: 595 lda $sp, -SWITCH_STACK_SIZE($sp) 596 .cfi_adjust_cfa_offset SWITCH_STACK_SIZE 597 stq $9, 0($sp) 598 stq $10, 8($sp) 599 stq $11, 16($sp) 600 stq $12, 24($sp) 601 stq $13, 32($sp) 602 stq $14, 40($sp) 603 stq $15, 48($sp) 604 stq $26, 56($sp) 605 ret $31, ($1), 1 606 .cfi_endproc 607 .size do_switch_stack, .-do_switch_stack 608 609 .align 4 610 .type undo_switch_stack, @function 611 .cfi_startproc simple 612 .cfi_def_cfa $sp, 0 613 .cfi_register 64, $1 614undo_switch_stack: 615 ldq $9, 0($sp) 616 ldq $10, 8($sp) 617 ldq $11, 16($sp) 618 ldq $12, 24($sp) 619 ldq $13, 32($sp) 620 ldq $14, 40($sp) 621 ldq $15, 48($sp) 622 ldq $26, 56($sp) 623 lda $sp, SWITCH_STACK_SIZE($sp) 624 ret $31, ($1), 1 625 .cfi_endproc 626 .size undo_switch_stack, .-undo_switch_stack 627 628#define FR(n) n * 8 + TI_FP($8) 629 .align 4 630 .globl __save_fpu 631 .type __save_fpu, @function 632__save_fpu: 633#define V(n) stt $f##n, FR(n) 634 V( 0); V( 1); V( 2); V( 3) 635 V( 4); V( 5); V( 6); V( 7) 636 V( 8); V( 9); V(10); V(11) 637 V(12); V(13); V(14); V(15) 638 V(16); V(17); V(18); V(19) 639 V(20); V(21); V(22); V(23) 640 V(24); V(25); V(26); V(27) 641 mf_fpcr $f0 # get fpcr 642 V(28); V(29); V(30) 643 stt $f0, FR(31) # save fpcr in slot of $f31 644 ldt $f0, FR(0) # don't let "__save_fpu" change fp state. 645 ret 646#undef V 647 .size __save_fpu, .-__save_fpu 648 649 .align 4 650restore_fpu: 651 and $3, TS_RESTORE_FP, $3 652 bic $2, TS_SAVED_FP | TS_RESTORE_FP, $2 653 beq $3, 1f 654#define V(n) ldt $f##n, FR(n) 655 ldt $f30, FR(31) # get saved fpcr 656 V( 0); V( 1); V( 2); V( 3) 657 mt_fpcr $f30 # install saved fpcr 658 V( 4); V( 5); V( 6); V( 7) 659 V( 8); V( 9); V(10); V(11) 660 V(12); V(13); V(14); V(15) 661 V(16); V(17); V(18); V(19) 662 V(20); V(21); V(22); V(23) 663 V(24); V(25); V(26); V(27) 664 V(28); V(29); V(30) 6651: stl $2, TI_STATUS($8) 666 br restore_other 667#undef V 668 669/* 670 * The meat of the context switch code. 671 */ 672 .align 4 673 .globl alpha_switch_to 674 .type alpha_switch_to, @function 675 .cfi_startproc 676alpha_switch_to: 677 DO_SWITCH_STACK 678 ldl $1, TI_STATUS($8) 679 and $1, TS_RESTORE_FP, $3 680 bne $3, 1f 681 or $1, TS_RESTORE_FP | TS_SAVED_FP, $2 682 and $1, TS_SAVED_FP, $3 683 stl $2, TI_STATUS($8) 684 bne $3, 1f 685 bsr $26, __save_fpu 6861: 687 call_pal PAL_swpctx 688 lda $8, 0x3fff 689 UNDO_SWITCH_STACK 690 bic $sp, $8, $8 691 mov $17, $0 692 ret 693 .cfi_endproc 694 .size alpha_switch_to, .-alpha_switch_to 695 696/* 697 * New processes begin life here. 698 */ 699 700 .globl ret_from_fork 701 .align 4 702 .ent ret_from_fork 703ret_from_fork: 704 lda $26, ret_to_user_from_exception 705 mov $17, $16 706 jmp $31, schedule_tail 707.end ret_from_fork 708 709/* 710 * ... and new kernel threads - here 711 */ 712 .align 4 713 .globl ret_from_kernel_thread 714 .ent ret_from_kernel_thread 715ret_from_kernel_thread: 716 mov $17, $16 717 jsr $26, schedule_tail 718 mov $9, $27 719 mov $10, $16 720 jsr $26, ($9) 721 br $31, ret_to_user_from_exception 722.end ret_from_kernel_thread 723 724 725/* 726 * Special system calls. Most of these are special in that they either 727 * have to play switch_stack games. 728 */ 729 730.macro fork_like name 731 .align 4 732 .globl alpha_\name 733 .ent alpha_\name 734alpha_\name: 735 .prologue 0 736 bsr $1, do_switch_stack 737 // NB: if anyone adds preemption, this block will need to be protected 738 ldl $1, TI_STATUS($8) 739 and $1, TS_SAVED_FP, $3 740 or $1, TS_SAVED_FP, $2 741 bne $3, 1f 742 stl $2, TI_STATUS($8) 743 bsr $26, __save_fpu 7441: 745 jsr $26, sys_\name 746 ldq $26, 56($sp) 747 lda $sp, SWITCH_STACK_SIZE($sp) 748 ret 749.end alpha_\name 750.endm 751 752fork_like fork 753fork_like vfork 754fork_like clone 755fork_like clone3 756 757.macro sigreturn_like name 758 .align 4 759 .globl sys_\name 760 .ent sys_\name 761sys_\name: 762 .prologue 0 763 mov $sp, $10 764 lda $sp, -SWITCH_STACK_SIZE($sp) 765 jsr $26, do_\name 7661: br $1, undo_switch_stack 767 br ret_from_sys_call 768.end sys_\name 769.endm 770 771sigreturn_like sigreturn 772sigreturn_like rt_sigreturn 773 774 .align 4 775 .globl alpha_syscall_zero 776 .ent alpha_syscall_zero 777alpha_syscall_zero: 778 .prologue 0 779 /* Special because it needs to do something opposite to 780 force_successful_syscall_return(). We use the saved 781 syscall number for that, zero meaning "not an error". 782 That works nicely, but for real syscall 0 we need to 783 make sure that this logics doesn't get confused. 784 Store a non-zero there - -ENOSYS we need in register 785 for our return value will do just fine. 786 */ 787 lda $0, -ENOSYS 788 unop 789 stq $0, 0($sp) 790 ret 791.end alpha_syscall_zero 792