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 mov $0, $8 480 call_pal PAL_rdusp 481 stq $0, PT_REGS_USP($sp) 482 mov $8, $0 483 484 lda $8, 0x3fff 485 bic $sp, $8, $8 486 487 stq $16, SP_OFF+24($sp) 488 stq $17, SP_OFF+32($sp) 489 stq $18, SP_OFF+40($sp) 490 491 mov $0, $1 492 lda $16, 7 493 call_pal PAL_swpipl 494 mov $1, $0 495 mov $sp, $16 496 mov $0, $17 /* pv = selected syscall function */ 497 498 DO_SWITCH_STACK 499 jsr $26, alpha_syscall_enter_select 500 ldgp $gp, 0($26) 501 UNDO_SWITCH_STACK 502 503 /* 504 * C returned syscall function pointer in $0. 505 * It also stored SKIP in TI_SYSCALL_META if dispatch is skipped. 506 */ 507 lda $8, 0x3fff 508 bic $sp, $8, $8 509 ldq $3, TI_SYSCALL_META($8) 510 lda $6, ALPHA_SYSCALL_META_SKIP 511 and $3, $6, $6 512 bne $6, skip_dispatch 513 514 515 mov $0, $27 516 ldq $16, SP_OFF+24($sp) 517 ldq $17, SP_OFF+32($sp) 518 ldq $18, SP_OFF+40($sp) 519 ldq $19, 72($sp) 520 ldq $20, 80($sp) 521 ldq $21, 88($sp) 522 523 jsr $26, ($27), sys_ni_syscall 524 ldgp $gp, 0($26) 525 526skip_dispatch: 527 mov $0, $17 /* raw ret; ignored if SKIP is set */ 528 mov $sp, $16 /* regs */ 529 530 DO_SWITCH_STACK 531 jsr $26, alpha_finish_syscall_to_user_mode 532 ldgp $gp, 0($26) 533 UNDO_SWITCH_STACK 534 535restore_all: 536 lda $8, 0x3fff 537 bic $sp, $8, $8 538 ldl $2, TI_STATUS($8) 539 and $2, TS_SAVED_FP | TS_RESTORE_FP, $3 540 bne $3, restore_fpu 541restore_other: 542 .cfi_remember_state 543 RESTORE_ALL 544 call_pal PAL_rti 545 546ret_to_user_from_syscall: 547 lda $8, 0x3fff 548 bic $sp, $8, $8 549 550 mov $sp, $16 551 DO_SWITCH_STACK 552 jsr $26, alpha_syscall_exit_to_user_mode 553 ldgp $gp, 0($26) 554 UNDO_SWITCH_STACK 555 br restore_all 556 557 .align 4 558 .globl ret_from_sys_call 559ret_from_sys_call: 560 ldq $0, SP_OFF($sp) 561 and $0, 8, $0 562 beq $0, ret_to_kernel 563 br ret_to_user_from_syscall 564 565ret_from_exception: 566 ldq $0, SP_OFF($sp) 567 and $0, 8, $0 568 beq $0, ret_to_kernel 569 br ret_to_user_from_exception 570 571ret_to_user_from_exception: 572 573 mov $sp, $16 574 DO_SWITCH_STACK 575 jsr $26, alpha_exit_to_user_mode 576 ldgp $gp, 0($26) 577 UNDO_SWITCH_STACK 578 br restore_all 579 580ret_to_kernel: 581 .cfi_restore_state 582 lda $16, 7 583 call_pal PAL_swpipl 584 LOCKDEP_HARDIRQS_ON_RESTORE SP_OFF($sp) 585 br restore_other 586 587CFI_END_OSF_FRAME entSys 588 589/* 590 * Save and restore the switch stack -- aka the balance of the user context. 591 */ 592 593 .align 4 594 .type do_switch_stack, @function 595 .cfi_startproc simple 596 .cfi_return_column 64 597 .cfi_def_cfa $sp, 0 598 .cfi_register 64, $1 599do_switch_stack: 600 lda $sp, -SWITCH_STACK_SIZE($sp) 601 .cfi_adjust_cfa_offset SWITCH_STACK_SIZE 602 stq $9, 0($sp) 603 stq $10, 8($sp) 604 stq $11, 16($sp) 605 stq $12, 24($sp) 606 stq $13, 32($sp) 607 stq $14, 40($sp) 608 stq $15, 48($sp) 609 stq $26, 56($sp) 610 ret $31, ($1), 1 611 .cfi_endproc 612 .size do_switch_stack, .-do_switch_stack 613 614 .align 4 615 .type undo_switch_stack, @function 616 .cfi_startproc simple 617 .cfi_def_cfa $sp, 0 618 .cfi_register 64, $1 619undo_switch_stack: 620 ldq $9, 0($sp) 621 ldq $10, 8($sp) 622 ldq $11, 16($sp) 623 ldq $12, 24($sp) 624 ldq $13, 32($sp) 625 ldq $14, 40($sp) 626 ldq $15, 48($sp) 627 ldq $26, 56($sp) 628 lda $sp, SWITCH_STACK_SIZE($sp) 629 ret $31, ($1), 1 630 .cfi_endproc 631 .size undo_switch_stack, .-undo_switch_stack 632 633#define FR(n) n * 8 + TI_FP($8) 634 .align 4 635 .globl __save_fpu 636 .type __save_fpu, @function 637__save_fpu: 638#define V(n) stt $f##n, FR(n) 639 V( 0); V( 1); V( 2); V( 3) 640 V( 4); V( 5); V( 6); V( 7) 641 V( 8); V( 9); V(10); V(11) 642 V(12); V(13); V(14); V(15) 643 V(16); V(17); V(18); V(19) 644 V(20); V(21); V(22); V(23) 645 V(24); V(25); V(26); V(27) 646 mf_fpcr $f0 # get fpcr 647 V(28); V(29); V(30) 648 stt $f0, FR(31) # save fpcr in slot of $f31 649 ldt $f0, FR(0) # don't let "__save_fpu" change fp state. 650 ret 651#undef V 652 .size __save_fpu, .-__save_fpu 653 654 .align 4 655restore_fpu: 656 and $3, TS_RESTORE_FP, $3 657 bic $2, TS_SAVED_FP | TS_RESTORE_FP, $2 658 beq $3, 1f 659#define V(n) ldt $f##n, FR(n) 660 ldt $f30, FR(31) # get saved fpcr 661 V( 0); V( 1); V( 2); V( 3) 662 mt_fpcr $f30 # install saved fpcr 663 V( 4); V( 5); V( 6); V( 7) 664 V( 8); V( 9); V(10); V(11) 665 V(12); V(13); V(14); V(15) 666 V(16); V(17); V(18); V(19) 667 V(20); V(21); V(22); V(23) 668 V(24); V(25); V(26); V(27) 669 V(28); V(29); V(30) 6701: stl $2, TI_STATUS($8) 671 br restore_other 672#undef V 673 674/* 675 * The meat of the context switch code. 676 */ 677 .align 4 678 .globl alpha_switch_to 679 .type alpha_switch_to, @function 680 .cfi_startproc 681alpha_switch_to: 682 DO_SWITCH_STACK 683 ldl $1, TI_STATUS($8) 684 and $1, TS_RESTORE_FP, $3 685 bne $3, 1f 686 or $1, TS_RESTORE_FP | TS_SAVED_FP, $2 687 and $1, TS_SAVED_FP, $3 688 stl $2, TI_STATUS($8) 689 bne $3, 1f 690 bsr $26, __save_fpu 6911: 692 call_pal PAL_swpctx 693 lda $8, 0x3fff 694 UNDO_SWITCH_STACK 695 bic $sp, $8, $8 696 mov $17, $0 697 ret 698 .cfi_endproc 699 .size alpha_switch_to, .-alpha_switch_to 700 701/* 702 * New processes begin life here. 703 */ 704 705 .globl ret_from_fork 706 .align 4 707 .ent ret_from_fork 708ret_from_fork: 709 lda $26, ret_to_user_from_exception 710 mov $17, $16 711 jmp $31, schedule_tail 712.end ret_from_fork 713 714/* 715 * ... and new kernel threads - here 716 */ 717 .align 4 718 .globl ret_from_kernel_thread 719 .ent ret_from_kernel_thread 720ret_from_kernel_thread: 721 mov $17, $16 722 jsr $26, schedule_tail 723 mov $9, $27 724 mov $10, $16 725 jsr $26, ($9) 726 br $31, ret_to_user_from_exception 727.end ret_from_kernel_thread 728 729 730/* 731 * Special system calls. Most of these are special in that they either 732 * have to play switch_stack games. 733 */ 734 735.macro fork_like name 736 .align 4 737 .globl alpha_\name 738 .ent alpha_\name 739alpha_\name: 740 .prologue 0 741 bsr $1, do_switch_stack 742 // NB: if anyone adds preemption, this block will need to be protected 743 ldl $1, TI_STATUS($8) 744 and $1, TS_SAVED_FP, $3 745 or $1, TS_SAVED_FP, $2 746 bne $3, 1f 747 stl $2, TI_STATUS($8) 748 bsr $26, __save_fpu 7491: 750 jsr $26, sys_\name 751 ldq $26, 56($sp) 752 lda $sp, SWITCH_STACK_SIZE($sp) 753 ret 754.end alpha_\name 755.endm 756 757fork_like fork 758fork_like vfork 759fork_like clone 760fork_like clone3 761 762.macro sigreturn_like name 763 .align 4 764 .globl sys_\name 765 .ent sys_\name 766sys_\name: 767 .prologue 0 768 mov $sp, $10 769 lda $sp, -SWITCH_STACK_SIZE($sp) 770 jsr $26, do_\name 7711: br $1, undo_switch_stack 772 br ret_from_sys_call 773.end sys_\name 774.endm 775 776sigreturn_like sigreturn 777sigreturn_like rt_sigreturn 778 779 .align 4 780 .globl alpha_syscall_zero 781 .ent alpha_syscall_zero 782alpha_syscall_zero: 783 .prologue 0 784 /* Special because it needs to do something opposite to 785 force_successful_syscall_return(). We use the saved 786 syscall number for that, zero meaning "not an error". 787 That works nicely, but for real syscall 0 we need to 788 make sure that this logics doesn't get confused. 789 Store a non-zero there - -ENOSYS we need in register 790 for our return value will do just fine. 791 */ 792 lda $0, -ENOSYS 793 unop 794 stq $0, 0($sp) 795 ret 796.end alpha_syscall_zero 797