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 14 .text 15 .set noat 16 .cfi_sections .debug_frame 17 18/* Stack offsets. */ 19#define SP_OFF 184 20#define SWITCH_STACK_SIZE 320 21 22.macro CFI_START_OSF_FRAME func 23 .align 4 24 .globl \func 25 .type \func,@function 26\func: 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 41 42/* 43 * This defines the normal kernel pt-regs layout. 44 * 45 * regs 9-15 preserved by C code 46 * regs 16-18 saved by PAL-code 47 * regs 29-30 saved and set up by PAL-code 48 * JRP - Save regs 16-18 in a special area of the stack, so that 49 * the palcode-provided values are available to the signal handler. 50 */ 51 52.macro SAVE_ALL 53 subq $sp, SP_OFF, $sp 54 .cfi_adjust_cfa_offset SP_OFF 55 stq $0, 0($sp) 56 stq $1, 8($sp) 57 stq $2, 16($sp) 58 stq $3, 24($sp) 59 stq $4, 32($sp) 60 stq $28, 144($sp) 61 .cfi_rel_offset $0, 0 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) 11999: 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 /* We don't really care about the FP registers for debugging. */ 163.endm 164 165.macro UNDO_SWITCH_STACK 166 bsr $1, undo_switch_stack 167 .cfi_restore $9 168 .cfi_restore $10 169 .cfi_restore $11 170 .cfi_restore $12 171 .cfi_restore $13 172 .cfi_restore $14 173 .cfi_restore $15 174 .cfi_adjust_cfa_offset -SWITCH_STACK_SIZE 175.endm 176 177/* 178 * Non-syscall kernel entry points. 179 */ 180 181CFI_START_OSF_FRAME entInt 182 SAVE_ALL 183 lda $8, 0x3fff 184 lda $26, ret_from_sys_call 185 bic $sp, $8, $8 186 mov $sp, $19 187 jsr $31, do_entInt 188CFI_END_OSF_FRAME entInt 189 190CFI_START_OSF_FRAME entArith 191 SAVE_ALL 192 lda $8, 0x3fff 193 lda $26, ret_from_sys_call 194 bic $sp, $8, $8 195 mov $sp, $18 196 jsr $31, do_entArith 197CFI_END_OSF_FRAME entArith 198 199CFI_START_OSF_FRAME entMM 200 SAVE_ALL 201/* save $9 - $15 so the inline exception code can manipulate them. */ 202 subq $sp, 56, $sp 203 .cfi_adjust_cfa_offset 56 204 stq $9, 0($sp) 205 stq $10, 8($sp) 206 stq $11, 16($sp) 207 stq $12, 24($sp) 208 stq $13, 32($sp) 209 stq $14, 40($sp) 210 stq $15, 48($sp) 211 .cfi_rel_offset $9, 0 212 .cfi_rel_offset $10, 8 213 .cfi_rel_offset $11, 16 214 .cfi_rel_offset $12, 24 215 .cfi_rel_offset $13, 32 216 .cfi_rel_offset $14, 40 217 .cfi_rel_offset $15, 48 218 addq $sp, 56, $19 219/* handle the fault */ 220 lda $8, 0x3fff 221 bic $sp, $8, $8 222 jsr $26, do_page_fault 223/* reload the registers after the exception code played. */ 224 ldq $9, 0($sp) 225 ldq $10, 8($sp) 226 ldq $11, 16($sp) 227 ldq $12, 24($sp) 228 ldq $13, 32($sp) 229 ldq $14, 40($sp) 230 ldq $15, 48($sp) 231 addq $sp, 56, $sp 232 .cfi_restore $9 233 .cfi_restore $10 234 .cfi_restore $11 235 .cfi_restore $12 236 .cfi_restore $13 237 .cfi_restore $14 238 .cfi_restore $15 239 .cfi_adjust_cfa_offset -56 240/* finish up the syscall as normal. */ 241 br ret_from_sys_call 242CFI_END_OSF_FRAME entMM 243 244CFI_START_OSF_FRAME entIF 245 SAVE_ALL 246 lda $8, 0x3fff 247 lda $26, ret_from_sys_call 248 bic $sp, $8, $8 249 mov $sp, $17 250 jsr $31, do_entIF 251CFI_END_OSF_FRAME entIF 252 253CFI_START_OSF_FRAME entUna 254 lda $sp, -256($sp) 255 .cfi_adjust_cfa_offset 256 256 stq $0, 0($sp) 257 .cfi_rel_offset $0, 0 258 .cfi_remember_state 259 ldq $0, 256($sp) /* get PS */ 260 stq $1, 8($sp) 261 stq $2, 16($sp) 262 stq $3, 24($sp) 263 and $0, 8, $0 /* user mode? */ 264 stq $4, 32($sp) 265 bne $0, entUnaUser /* yup -> do user-level unaligned fault */ 266 stq $5, 40($sp) 267 stq $6, 48($sp) 268 stq $7, 56($sp) 269 stq $8, 64($sp) 270 stq $9, 72($sp) 271 stq $10, 80($sp) 272 stq $11, 88($sp) 273 stq $12, 96($sp) 274 stq $13, 104($sp) 275 stq $14, 112($sp) 276 stq $15, 120($sp) 277 /* 16-18 PAL-saved */ 278 stq $19, 152($sp) 279 stq $20, 160($sp) 280 stq $21, 168($sp) 281 stq $22, 176($sp) 282 stq $23, 184($sp) 283 stq $24, 192($sp) 284 stq $25, 200($sp) 285 stq $26, 208($sp) 286 stq $27, 216($sp) 287 stq $28, 224($sp) 288 mov $sp, $19 289 stq $gp, 232($sp) 290 .cfi_rel_offset $1, 1*8 291 .cfi_rel_offset $2, 2*8 292 .cfi_rel_offset $3, 3*8 293 .cfi_rel_offset $4, 4*8 294 .cfi_rel_offset $5, 5*8 295 .cfi_rel_offset $6, 6*8 296 .cfi_rel_offset $7, 7*8 297 .cfi_rel_offset $8, 8*8 298 .cfi_rel_offset $9, 9*8 299 .cfi_rel_offset $10, 10*8 300 .cfi_rel_offset $11, 11*8 301 .cfi_rel_offset $12, 12*8 302 .cfi_rel_offset $13, 13*8 303 .cfi_rel_offset $14, 14*8 304 .cfi_rel_offset $15, 15*8 305 .cfi_rel_offset $19, 19*8 306 .cfi_rel_offset $20, 20*8 307 .cfi_rel_offset $21, 21*8 308 .cfi_rel_offset $22, 22*8 309 .cfi_rel_offset $23, 23*8 310 .cfi_rel_offset $24, 24*8 311 .cfi_rel_offset $25, 25*8 312 .cfi_rel_offset $26, 26*8 313 .cfi_rel_offset $27, 27*8 314 .cfi_rel_offset $28, 28*8 315 .cfi_rel_offset $29, 29*8 316 lda $8, 0x3fff 317 stq $31, 248($sp) 318 bic $sp, $8, $8 319 jsr $26, do_entUna 320 ldq $0, 0($sp) 321 ldq $1, 8($sp) 322 ldq $2, 16($sp) 323 ldq $3, 24($sp) 324 ldq $4, 32($sp) 325 ldq $5, 40($sp) 326 ldq $6, 48($sp) 327 ldq $7, 56($sp) 328 ldq $8, 64($sp) 329 ldq $9, 72($sp) 330 ldq $10, 80($sp) 331 ldq $11, 88($sp) 332 ldq $12, 96($sp) 333 ldq $13, 104($sp) 334 ldq $14, 112($sp) 335 ldq $15, 120($sp) 336 /* 16-18 PAL-saved */ 337 ldq $19, 152($sp) 338 ldq $20, 160($sp) 339 ldq $21, 168($sp) 340 ldq $22, 176($sp) 341 ldq $23, 184($sp) 342 ldq $24, 192($sp) 343 ldq $25, 200($sp) 344 ldq $26, 208($sp) 345 ldq $27, 216($sp) 346 ldq $28, 224($sp) 347 ldq $gp, 232($sp) 348 lda $sp, 256($sp) 349 .cfi_restore $1 350 .cfi_restore $2 351 .cfi_restore $3 352 .cfi_restore $4 353 .cfi_restore $5 354 .cfi_restore $6 355 .cfi_restore $7 356 .cfi_restore $8 357 .cfi_restore $9 358 .cfi_restore $10 359 .cfi_restore $11 360 .cfi_restore $12 361 .cfi_restore $13 362 .cfi_restore $14 363 .cfi_restore $15 364 .cfi_restore $19 365 .cfi_restore $20 366 .cfi_restore $21 367 .cfi_restore $22 368 .cfi_restore $23 369 .cfi_restore $24 370 .cfi_restore $25 371 .cfi_restore $26 372 .cfi_restore $27 373 .cfi_restore $28 374 .cfi_restore $29 375 .cfi_adjust_cfa_offset -256 376 call_pal PAL_rti 377 378 .align 4 379entUnaUser: 380 .cfi_restore_state 381 ldq $0, 0($sp) /* restore original $0 */ 382 lda $sp, 256($sp) /* pop entUna's stack frame */ 383 .cfi_restore $0 384 .cfi_adjust_cfa_offset -256 385 SAVE_ALL /* setup normal kernel stack */ 386 lda $sp, -56($sp) 387 .cfi_adjust_cfa_offset 56 388 stq $9, 0($sp) 389 stq $10, 8($sp) 390 stq $11, 16($sp) 391 stq $12, 24($sp) 392 stq $13, 32($sp) 393 stq $14, 40($sp) 394 stq $15, 48($sp) 395 .cfi_rel_offset $9, 0 396 .cfi_rel_offset $10, 8 397 .cfi_rel_offset $11, 16 398 .cfi_rel_offset $12, 24 399 .cfi_rel_offset $13, 32 400 .cfi_rel_offset $14, 40 401 .cfi_rel_offset $15, 48 402 lda $8, 0x3fff 403 addq $sp, 56, $19 404 bic $sp, $8, $8 405 jsr $26, do_entUnaUser 406 ldq $9, 0($sp) 407 ldq $10, 8($sp) 408 ldq $11, 16($sp) 409 ldq $12, 24($sp) 410 ldq $13, 32($sp) 411 ldq $14, 40($sp) 412 ldq $15, 48($sp) 413 lda $sp, 56($sp) 414 .cfi_restore $9 415 .cfi_restore $10 416 .cfi_restore $11 417 .cfi_restore $12 418 .cfi_restore $13 419 .cfi_restore $14 420 .cfi_restore $15 421 .cfi_adjust_cfa_offset -56 422 br ret_from_sys_call 423CFI_END_OSF_FRAME entUna 424 425CFI_START_OSF_FRAME entDbg 426 SAVE_ALL 427 lda $8, 0x3fff 428 lda $26, ret_from_sys_call 429 bic $sp, $8, $8 430 mov $sp, $16 431 jsr $31, do_entDbg 432CFI_END_OSF_FRAME entDbg 433 434/* 435 * The system call entry point is special. Most importantly, it looks 436 * like a function call to userspace as far as clobbered registers. We 437 * do preserve the argument registers (for syscall restarts) and $26 438 * (for leaf syscall functions). 439 * 440 * So much for theory. We don't take advantage of this yet. 441 * 442 * Note that a0-a2 are not saved by PALcode as with the other entry points. 443 */ 444 445 .align 4 446 .globl entSys 447 .type entSys, @function 448 .cfi_startproc simple 449 .cfi_return_column 64 450 .cfi_def_cfa $sp, 48 451 .cfi_rel_offset 64, 8 452 .cfi_rel_offset $gp, 16 453entSys: 454 SAVE_ALL 455 lda $8, 0x3fff 456 bic $sp, $8, $8 457 lda $4, NR_SYSCALLS($31) 458 stq $16, SP_OFF+24($sp) 459 lda $5, sys_call_table 460 lda $27, sys_ni_syscall 461 cmpult $0, $4, $4 462 ldl $3, TI_FLAGS($8) 463 stq $17, SP_OFF+32($sp) 464 s8addq $0, $5, $5 465 stq $18, SP_OFF+40($sp) 466 .cfi_rel_offset $16, SP_OFF+24 467 .cfi_rel_offset $17, SP_OFF+32 468 .cfi_rel_offset $18, SP_OFF+40 469#ifdef CONFIG_AUDITSYSCALL 470 lda $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT 471 and $3, $6, $3 472 bne $3, strace 473#else 474 blbs $3, strace /* check for SYSCALL_TRACE in disguise */ 475#endif 476 beq $4, 1f 477 ldq $27, 0($5) 4781: jsr $26, ($27), sys_ni_syscall 479 ldgp $gp, 0($26) 480 blt $0, $syscall_error /* the call failed */ 481 stq $0, 0($sp) 482 stq $31, 72($sp) /* a3=0 => no error */ 483 484 .align 4 485 .globl ret_from_sys_call 486ret_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 491ret_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 499restore_all: 500 .cfi_remember_state 501 RESTORE_ALL 502 call_pal PAL_rti 503 504ret_to_kernel: 505 .cfi_restore_state 506 lda $16, 7 507 call_pal PAL_swpipl 508 br restore_all 509 510 .align 3 511$syscall_error: 512 /* 513 * Some system calls (e.g., ptrace) can return arbitrary 514 * values which might normally be mistaken as error numbers. 515 * Those functions must zero $0 (v0) directly in the stack 516 * frame to indicate that a negative return value wasn't an 517 * error number.. 518 */ 519 ldq $18, 0($sp) /* old syscall nr (zero if success) */ 520 beq $18, $ret_success 521 522 ldq $19, 72($sp) /* .. and this a3 */ 523 subq $31, $0, $0 /* with error in v0 */ 524 addq $31, 1, $1 /* set a3 for errno return */ 525 stq $0, 0($sp) 526 mov $31, $26 /* tell "ret_from_sys_call" we can restart */ 527 stq $1, 72($sp) /* a3 for return */ 528 br ret_from_sys_call 529 530$ret_success: 531 stq $0, 0($sp) 532 stq $31, 72($sp) /* a3=0 => no error */ 533 br ret_from_sys_call 534 535/* 536 * Do all cleanup when returning from all interrupts and system calls. 537 * 538 * Arguments: 539 * $8: current. 540 * $17: TI_FLAGS. 541 * $18: The old syscall number, or zero if this is not a return 542 * from a syscall that errored and is possibly restartable. 543 * $19: The old a3 value 544 */ 545 546 .align 4 547 .type work_pending, @function 548work_pending: 549 and $17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL, $2 550 bne $2, $work_notifysig 551 552$work_resched: 553 /* 554 * We can get here only if we returned from syscall without SIGPENDING 555 * or got through work_notifysig already. Either case means no syscall 556 * restarts for us, so let $18 and $19 burn. 557 */ 558 jsr $26, schedule 559 mov 0, $18 560 br ret_to_user 561 562$work_notifysig: 563 mov $sp, $16 564 DO_SWITCH_STACK 565 jsr $26, do_work_pending 566 UNDO_SWITCH_STACK 567 br restore_all 568 569/* 570 * PTRACE syscall handler 571 */ 572 573 .align 4 574 .type strace, @function 575strace: 576 /* set up signal stack, call syscall_trace */ 577 DO_SWITCH_STACK 578 jsr $26, syscall_trace_enter /* returns the syscall number */ 579 UNDO_SWITCH_STACK 580 581 /* get the arguments back.. */ 582 ldq $16, SP_OFF+24($sp) 583 ldq $17, SP_OFF+32($sp) 584 ldq $18, SP_OFF+40($sp) 585 ldq $19, 72($sp) 586 ldq $20, 80($sp) 587 ldq $21, 88($sp) 588 589 /* get the system call pointer.. */ 590 lda $1, NR_SYSCALLS($31) 591 lda $2, sys_call_table 592 lda $27, sys_ni_syscall 593 cmpult $0, $1, $1 594 s8addq $0, $2, $2 595 beq $1, 1f 596 ldq $27, 0($2) 5971: jsr $26, ($27), sys_gettimeofday 598ret_from_straced: 599 ldgp $gp, 0($26) 600 601 /* check return.. */ 602 blt $0, $strace_error /* the call failed */ 603 stq $31, 72($sp) /* a3=0 => no error */ 604$strace_success: 605 stq $0, 0($sp) /* save return value */ 606 607 DO_SWITCH_STACK 608 jsr $26, syscall_trace_leave 609 UNDO_SWITCH_STACK 610 br $31, ret_from_sys_call 611 612 .align 3 613$strace_error: 614 ldq $18, 0($sp) /* old syscall nr (zero if success) */ 615 beq $18, $strace_success 616 ldq $19, 72($sp) /* .. and this a3 */ 617 618 subq $31, $0, $0 /* with error in v0 */ 619 addq $31, 1, $1 /* set a3 for errno return */ 620 stq $0, 0($sp) 621 stq $1, 72($sp) /* a3 for return */ 622 623 DO_SWITCH_STACK 624 mov $18, $9 /* save old syscall number */ 625 mov $19, $10 /* save old a3 */ 626 jsr $26, syscall_trace_leave 627 mov $9, $18 628 mov $10, $19 629 UNDO_SWITCH_STACK 630 631 mov $31, $26 /* tell "ret_from_sys_call" we can restart */ 632 br ret_from_sys_call 633CFI_END_OSF_FRAME entSys 634 635/* 636 * Save and restore the switch stack -- aka the balance of the user context. 637 */ 638 639 .align 4 640 .type do_switch_stack, @function 641 .cfi_startproc simple 642 .cfi_return_column 64 643 .cfi_def_cfa $sp, 0 644 .cfi_register 64, $1 645do_switch_stack: 646 lda $sp, -SWITCH_STACK_SIZE($sp) 647 .cfi_adjust_cfa_offset SWITCH_STACK_SIZE 648 stq $9, 0($sp) 649 stq $10, 8($sp) 650 stq $11, 16($sp) 651 stq $12, 24($sp) 652 stq $13, 32($sp) 653 stq $14, 40($sp) 654 stq $15, 48($sp) 655 stq $26, 56($sp) 656 stt $f0, 64($sp) 657 stt $f1, 72($sp) 658 stt $f2, 80($sp) 659 stt $f3, 88($sp) 660 stt $f4, 96($sp) 661 stt $f5, 104($sp) 662 stt $f6, 112($sp) 663 stt $f7, 120($sp) 664 stt $f8, 128($sp) 665 stt $f9, 136($sp) 666 stt $f10, 144($sp) 667 stt $f11, 152($sp) 668 stt $f12, 160($sp) 669 stt $f13, 168($sp) 670 stt $f14, 176($sp) 671 stt $f15, 184($sp) 672 stt $f16, 192($sp) 673 stt $f17, 200($sp) 674 stt $f18, 208($sp) 675 stt $f19, 216($sp) 676 stt $f20, 224($sp) 677 stt $f21, 232($sp) 678 stt $f22, 240($sp) 679 stt $f23, 248($sp) 680 stt $f24, 256($sp) 681 stt $f25, 264($sp) 682 stt $f26, 272($sp) 683 stt $f27, 280($sp) 684 mf_fpcr $f0 # get fpcr 685 stt $f28, 288($sp) 686 stt $f29, 296($sp) 687 stt $f30, 304($sp) 688 stt $f0, 312($sp) # save fpcr in slot of $f31 689 ldt $f0, 64($sp) # dont let "do_switch_stack" change fp state. 690 ret $31, ($1), 1 691 .cfi_endproc 692 .size do_switch_stack, .-do_switch_stack 693 694 .align 4 695 .type undo_switch_stack, @function 696 .cfi_startproc simple 697 .cfi_def_cfa $sp, 0 698 .cfi_register 64, $1 699undo_switch_stack: 700 ldq $9, 0($sp) 701 ldq $10, 8($sp) 702 ldq $11, 16($sp) 703 ldq $12, 24($sp) 704 ldq $13, 32($sp) 705 ldq $14, 40($sp) 706 ldq $15, 48($sp) 707 ldq $26, 56($sp) 708 ldt $f30, 312($sp) # get saved fpcr 709 ldt $f0, 64($sp) 710 ldt $f1, 72($sp) 711 ldt $f2, 80($sp) 712 ldt $f3, 88($sp) 713 mt_fpcr $f30 # install saved fpcr 714 ldt $f4, 96($sp) 715 ldt $f5, 104($sp) 716 ldt $f6, 112($sp) 717 ldt $f7, 120($sp) 718 ldt $f8, 128($sp) 719 ldt $f9, 136($sp) 720 ldt $f10, 144($sp) 721 ldt $f11, 152($sp) 722 ldt $f12, 160($sp) 723 ldt $f13, 168($sp) 724 ldt $f14, 176($sp) 725 ldt $f15, 184($sp) 726 ldt $f16, 192($sp) 727 ldt $f17, 200($sp) 728 ldt $f18, 208($sp) 729 ldt $f19, 216($sp) 730 ldt $f20, 224($sp) 731 ldt $f21, 232($sp) 732 ldt $f22, 240($sp) 733 ldt $f23, 248($sp) 734 ldt $f24, 256($sp) 735 ldt $f25, 264($sp) 736 ldt $f26, 272($sp) 737 ldt $f27, 280($sp) 738 ldt $f28, 288($sp) 739 ldt $f29, 296($sp) 740 ldt $f30, 304($sp) 741 lda $sp, SWITCH_STACK_SIZE($sp) 742 ret $31, ($1), 1 743 .cfi_endproc 744 .size undo_switch_stack, .-undo_switch_stack 745 746/* 747 * The meat of the context switch code. 748 */ 749 750 .align 4 751 .globl alpha_switch_to 752 .type alpha_switch_to, @function 753 .cfi_startproc 754alpha_switch_to: 755 DO_SWITCH_STACK 756 call_pal PAL_swpctx 757 lda $8, 0x3fff 758 UNDO_SWITCH_STACK 759 bic $sp, $8, $8 760 mov $17, $0 761 ret 762 .cfi_endproc 763 .size alpha_switch_to, .-alpha_switch_to 764 765/* 766 * New processes begin life here. 767 */ 768 769 .globl ret_from_fork 770 .align 4 771 .ent ret_from_fork 772ret_from_fork: 773 lda $26, ret_from_sys_call 774 mov $17, $16 775 jmp $31, schedule_tail 776.end ret_from_fork 777 778/* 779 * ... and new kernel threads - here 780 */ 781 .align 4 782 .globl ret_from_kernel_thread 783 .ent ret_from_kernel_thread 784ret_from_kernel_thread: 785 mov $17, $16 786 jsr $26, schedule_tail 787 mov $9, $27 788 mov $10, $16 789 jsr $26, ($9) 790 br $31, ret_to_user 791.end ret_from_kernel_thread 792 793 794/* 795 * Special system calls. Most of these are special in that they either 796 * have to play switch_stack games. 797 */ 798 799.macro fork_like name 800 .align 4 801 .globl alpha_\name 802 .ent alpha_\name 803alpha_\name: 804 .prologue 0 805 bsr $1, do_switch_stack 806 jsr $26, sys_\name 807 ldq $26, 56($sp) 808 lda $sp, SWITCH_STACK_SIZE($sp) 809 ret 810.end alpha_\name 811.endm 812 813fork_like fork 814fork_like vfork 815fork_like clone 816 817.macro sigreturn_like name 818 .align 4 819 .globl sys_\name 820 .ent sys_\name 821sys_\name: 822 .prologue 0 823 lda $9, ret_from_straced 824 cmpult $26, $9, $9 825 lda $sp, -SWITCH_STACK_SIZE($sp) 826 jsr $26, do_\name 827 bne $9, 1f 828 jsr $26, syscall_trace_leave 8291: br $1, undo_switch_stack 830 br ret_from_sys_call 831.end sys_\name 832.endm 833 834sigreturn_like sigreturn 835sigreturn_like rt_sigreturn 836 837 .align 4 838 .globl alpha_syscall_zero 839 .ent alpha_syscall_zero 840alpha_syscall_zero: 841 .prologue 0 842 /* Special because it needs to do something opposite to 843 force_successful_syscall_return(). We use the saved 844 syscall number for that, zero meaning "not an error". 845 That works nicely, but for real syscall 0 we need to 846 make sure that this logics doesn't get confused. 847 Store a non-zero there - -ENOSYS we need in register 848 for our return value will do just fine. 849 */ 850 lda $0, -ENOSYS 851 unop 852 stq $0, 0($sp) 853 ret 854.end alpha_syscall_zero 855