1/* 2 * arch/alpha/kernel/entry.S 3 * 4 * Kernel entry-points. 5 */ 6 7#include <asm/asm-offsets.h> 8#include <asm/thread_info.h> 9#include <asm/pal.h> 10#include <asm/errno.h> 11#include <asm/unistd.h> 12 13 .text 14 .set noat 15 .cfi_sections .debug_frame 16 17/* Stack offsets. */ 18#define SP_OFF 184 19#define SWITCH_STACK_SIZE 320 20 21.macro CFI_START_OSF_FRAME func 22 .align 4 23 .globl \func 24 .type \func,@function 25\func: 26 .cfi_startproc simple 27 .cfi_return_column 64 28 .cfi_def_cfa $sp, 48 29 .cfi_rel_offset 64, 8 30 .cfi_rel_offset $gp, 16 31 .cfi_rel_offset $16, 24 32 .cfi_rel_offset $17, 32 33 .cfi_rel_offset $18, 40 34.endm 35 36.macro CFI_END_OSF_FRAME func 37 .cfi_endproc 38 .size \func, . - \func 39.endm 40 41/* 42 * This defines the normal kernel pt-regs layout. 43 * 44 * regs 9-15 preserved by C code 45 * regs 16-18 saved by PAL-code 46 * regs 29-30 saved and set up by PAL-code 47 * JRP - Save regs 16-18 in a special area of the stack, so that 48 * the palcode-provided values are available to the signal handler. 49 */ 50 51.macro SAVE_ALL 52 subq $sp, SP_OFF, $sp 53 .cfi_adjust_cfa_offset SP_OFF 54 stq $0, 0($sp) 55 stq $1, 8($sp) 56 stq $2, 16($sp) 57 stq $3, 24($sp) 58 stq $4, 32($sp) 59 stq $28, 144($sp) 60 .cfi_rel_offset $0, 0 61 .cfi_rel_offset $1, 8 62 .cfi_rel_offset $2, 16 63 .cfi_rel_offset $3, 24 64 .cfi_rel_offset $4, 32 65 .cfi_rel_offset $28, 144 66 lda $2, alpha_mv 67 stq $5, 40($sp) 68 stq $6, 48($sp) 69 stq $7, 56($sp) 70 stq $8, 64($sp) 71 stq $19, 72($sp) 72 stq $20, 80($sp) 73 stq $21, 88($sp) 74 ldq $2, HAE_CACHE($2) 75 stq $22, 96($sp) 76 stq $23, 104($sp) 77 stq $24, 112($sp) 78 stq $25, 120($sp) 79 stq $26, 128($sp) 80 stq $27, 136($sp) 81 stq $2, 152($sp) 82 stq $16, 160($sp) 83 stq $17, 168($sp) 84 stq $18, 176($sp) 85 .cfi_rel_offset $5, 40 86 .cfi_rel_offset $6, 48 87 .cfi_rel_offset $7, 56 88 .cfi_rel_offset $8, 64 89 .cfi_rel_offset $19, 72 90 .cfi_rel_offset $20, 80 91 .cfi_rel_offset $21, 88 92 .cfi_rel_offset $22, 96 93 .cfi_rel_offset $23, 104 94 .cfi_rel_offset $24, 112 95 .cfi_rel_offset $25, 120 96 .cfi_rel_offset $26, 128 97 .cfi_rel_offset $27, 136 98.endm 99 100.macro RESTORE_ALL 101 lda $19, alpha_mv 102 ldq $0, 0($sp) 103 ldq $1, 8($sp) 104 ldq $2, 16($sp) 105 ldq $3, 24($sp) 106 ldq $21, 152($sp) 107 ldq $20, HAE_CACHE($19) 108 ldq $4, 32($sp) 109 ldq $5, 40($sp) 110 ldq $6, 48($sp) 111 ldq $7, 56($sp) 112 subq $20, $21, $20 113 ldq $8, 64($sp) 114 beq $20, 99f 115 ldq $20, HAE_REG($19) 116 stq $21, HAE_CACHE($19) 117 stq $21, 0($20) 11899: ldq $19, 72($sp) 119 ldq $20, 80($sp) 120 ldq $21, 88($sp) 121 ldq $22, 96($sp) 122 ldq $23, 104($sp) 123 ldq $24, 112($sp) 124 ldq $25, 120($sp) 125 ldq $26, 128($sp) 126 ldq $27, 136($sp) 127 ldq $28, 144($sp) 128 addq $sp, SP_OFF, $sp 129 .cfi_restore $0 130 .cfi_restore $1 131 .cfi_restore $2 132 .cfi_restore $3 133 .cfi_restore $4 134 .cfi_restore $5 135 .cfi_restore $6 136 .cfi_restore $7 137 .cfi_restore $8 138 .cfi_restore $19 139 .cfi_restore $20 140 .cfi_restore $21 141 .cfi_restore $22 142 .cfi_restore $23 143 .cfi_restore $24 144 .cfi_restore $25 145 .cfi_restore $26 146 .cfi_restore $27 147 .cfi_restore $28 148 .cfi_adjust_cfa_offset -SP_OFF 149.endm 150 151.macro DO_SWITCH_STACK 152 bsr $1, do_switch_stack 153 .cfi_adjust_cfa_offset SWITCH_STACK_SIZE 154 .cfi_rel_offset $9, 0 155 .cfi_rel_offset $10, 8 156 .cfi_rel_offset $11, 16 157 .cfi_rel_offset $12, 24 158 .cfi_rel_offset $13, 32 159 .cfi_rel_offset $14, 40 160 .cfi_rel_offset $15, 48 161 /* We don't really care about the FP registers for debugging. */ 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 175 176/* 177 * Non-syscall kernel entry points. 178 */ 179 180CFI_START_OSF_FRAME entInt 181 SAVE_ALL 182 lda $8, 0x3fff 183 lda $26, ret_from_sys_call 184 bic $sp, $8, $8 185 mov $sp, $19 186 jsr $31, do_entInt 187CFI_END_OSF_FRAME entInt 188 189CFI_START_OSF_FRAME entArith 190 SAVE_ALL 191 lda $8, 0x3fff 192 lda $26, ret_from_sys_call 193 bic $sp, $8, $8 194 mov $sp, $18 195 jsr $31, do_entArith 196CFI_END_OSF_FRAME entArith 197 198CFI_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 241CFI_END_OSF_FRAME entMM 242 243CFI_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 250CFI_END_OSF_FRAME entIF 251 252CFI_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 378entUnaUser: 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 422CFI_END_OSF_FRAME entUna 423 424CFI_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 431CFI_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. 442 */ 443 444 .align 4 445 .globl entSys 446 .type entSys, @function 447 .cfi_startproc simple 448 .cfi_return_column 64 449 .cfi_def_cfa $sp, 48 450 .cfi_rel_offset 64, 8 451 .cfi_rel_offset $gp, 16 452entSys: 453 SAVE_ALL 454 lda $8, 0x3fff 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#endif 472 bne $3, strace 473 beq $4, 1f 474 ldq $27, 0($5) 4751: jsr $26, ($27), alpha_ni_syscall 476 ldgp $gp, 0($26) 477 blt $0, $syscall_error /* the call failed */ 478 stq $0, 0($sp) 479 stq $31, 72($sp) /* a3=0 => no error */ 480 481 .align 4 482 .globl ret_from_sys_call 483ret_from_sys_call: 484 cmovne $26, 0, $18 /* $18 = 0 => non-restartable */ 485 ldq $0, SP_OFF($sp) 486 and $0, 8, $0 487 beq $0, ret_to_kernel 488ret_to_user: 489 /* Make sure need_resched and sigpending don't change between 490 sampling and the rti. */ 491 lda $16, 7 492 call_pal PAL_swpipl 493 ldl $17, TI_FLAGS($8) 494 and $17, _TIF_WORK_MASK, $2 495 bne $2, work_pending 496restore_all: 497 .cfi_remember_state 498 RESTORE_ALL 499 call_pal PAL_rti 500 501ret_to_kernel: 502 .cfi_restore_state 503 lda $16, 7 504 call_pal PAL_swpipl 505 br restore_all 506 507 .align 3 508$syscall_error: 509 /* 510 * Some system calls (e.g., ptrace) can return arbitrary 511 * values which might normally be mistaken as error numbers. 512 * Those functions must zero $0 (v0) directly in the stack 513 * frame to indicate that a negative return value wasn't an 514 * error number.. 515 */ 516 ldq $18, 0($sp) /* old syscall nr (zero if success) */ 517 beq $18, $ret_success 518 519 ldq $19, 72($sp) /* .. and this a3 */ 520 subq $31, $0, $0 /* with error in v0 */ 521 addq $31, 1, $1 /* set a3 for errno return */ 522 stq $0, 0($sp) 523 mov $31, $26 /* tell "ret_from_sys_call" we can restart */ 524 stq $1, 72($sp) /* a3 for return */ 525 br ret_from_sys_call 526 527$ret_success: 528 stq $0, 0($sp) 529 stq $31, 72($sp) /* a3=0 => no error */ 530 br ret_from_sys_call 531 532/* 533 * Do all cleanup when returning from all interrupts and system calls. 534 * 535 * Arguments: 536 * $8: current. 537 * $17: TI_FLAGS. 538 * $18: The old syscall number, or zero if this is not a return 539 * from a syscall that errored and is possibly restartable. 540 * $19: The old a3 value 541 */ 542 543 .align 4 544 .type work_pending, @function 545work_pending: 546 and $17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING, $2 547 bne $2, $work_notifysig 548 549$work_resched: 550 /* 551 * We can get here only if we returned from syscall without SIGPENDING 552 * or got through work_notifysig already. Either case means no syscall 553 * restarts for us, so let $18 and $19 burn. 554 */ 555 jsr $26, schedule 556 mov 0, $18 557 br ret_to_user 558 559$work_notifysig: 560 mov $sp, $16 561 DO_SWITCH_STACK 562 jsr $26, do_work_pending 563 UNDO_SWITCH_STACK 564 br restore_all 565 566/* 567 * PTRACE syscall handler 568 */ 569 570 .align 4 571 .type strace, @function 572strace: 573 /* set up signal stack, call syscall_trace */ 574 DO_SWITCH_STACK 575 jsr $26, syscall_trace_enter /* returns the syscall number */ 576 UNDO_SWITCH_STACK 577 578 /* get the arguments back.. */ 579 ldq $16, SP_OFF+24($sp) 580 ldq $17, SP_OFF+32($sp) 581 ldq $18, SP_OFF+40($sp) 582 ldq $19, 72($sp) 583 ldq $20, 80($sp) 584 ldq $21, 88($sp) 585 586 /* get the system call pointer.. */ 587 lda $1, NR_SYSCALLS($31) 588 lda $2, sys_call_table 589 lda $27, alpha_ni_syscall 590 cmpult $0, $1, $1 591 s8addq $0, $2, $2 592 beq $1, 1f 593 ldq $27, 0($2) 5941: jsr $26, ($27), sys_gettimeofday 595ret_from_straced: 596 ldgp $gp, 0($26) 597 598 /* check return.. */ 599 blt $0, $strace_error /* the call failed */ 600 stq $31, 72($sp) /* a3=0 => no error */ 601$strace_success: 602 stq $0, 0($sp) /* save return value */ 603 604 DO_SWITCH_STACK 605 jsr $26, syscall_trace_leave 606 UNDO_SWITCH_STACK 607 br $31, ret_from_sys_call 608 609 .align 3 610$strace_error: 611 ldq $18, 0($sp) /* old syscall nr (zero if success) */ 612 beq $18, $strace_success 613 ldq $19, 72($sp) /* .. and this a3 */ 614 615 subq $31, $0, $0 /* with error in v0 */ 616 addq $31, 1, $1 /* set a3 for errno return */ 617 stq $0, 0($sp) 618 stq $1, 72($sp) /* a3 for return */ 619 620 DO_SWITCH_STACK 621 mov $18, $9 /* save old syscall number */ 622 mov $19, $10 /* save old a3 */ 623 jsr $26, syscall_trace_leave 624 mov $9, $18 625 mov $10, $19 626 UNDO_SWITCH_STACK 627 628 mov $31, $26 /* tell "ret_from_sys_call" we can restart */ 629 br ret_from_sys_call 630CFI_END_OSF_FRAME entSys 631 632/* 633 * Save and restore the switch stack -- aka the balance of the user context. 634 */ 635 636 .align 4 637 .type do_switch_stack, @function 638 .cfi_startproc simple 639 .cfi_return_column 64 640 .cfi_def_cfa $sp, 0 641 .cfi_register 64, $1 642do_switch_stack: 643 lda $sp, -SWITCH_STACK_SIZE($sp) 644 .cfi_adjust_cfa_offset SWITCH_STACK_SIZE 645 stq $9, 0($sp) 646 stq $10, 8($sp) 647 stq $11, 16($sp) 648 stq $12, 24($sp) 649 stq $13, 32($sp) 650 stq $14, 40($sp) 651 stq $15, 48($sp) 652 stq $26, 56($sp) 653 stt $f0, 64($sp) 654 stt $f1, 72($sp) 655 stt $f2, 80($sp) 656 stt $f3, 88($sp) 657 stt $f4, 96($sp) 658 stt $f5, 104($sp) 659 stt $f6, 112($sp) 660 stt $f7, 120($sp) 661 stt $f8, 128($sp) 662 stt $f9, 136($sp) 663 stt $f10, 144($sp) 664 stt $f11, 152($sp) 665 stt $f12, 160($sp) 666 stt $f13, 168($sp) 667 stt $f14, 176($sp) 668 stt $f15, 184($sp) 669 stt $f16, 192($sp) 670 stt $f17, 200($sp) 671 stt $f18, 208($sp) 672 stt $f19, 216($sp) 673 stt $f20, 224($sp) 674 stt $f21, 232($sp) 675 stt $f22, 240($sp) 676 stt $f23, 248($sp) 677 stt $f24, 256($sp) 678 stt $f25, 264($sp) 679 stt $f26, 272($sp) 680 stt $f27, 280($sp) 681 mf_fpcr $f0 # get fpcr 682 stt $f28, 288($sp) 683 stt $f29, 296($sp) 684 stt $f30, 304($sp) 685 stt $f0, 312($sp) # save fpcr in slot of $f31 686 ldt $f0, 64($sp) # dont let "do_switch_stack" change fp state. 687 ret $31, ($1), 1 688 .cfi_endproc 689 .size do_switch_stack, .-do_switch_stack 690 691 .align 4 692 .type undo_switch_stack, @function 693 .cfi_startproc simple 694 .cfi_def_cfa $sp, 0 695 .cfi_register 64, $1 696undo_switch_stack: 697 ldq $9, 0($sp) 698 ldq $10, 8($sp) 699 ldq $11, 16($sp) 700 ldq $12, 24($sp) 701 ldq $13, 32($sp) 702 ldq $14, 40($sp) 703 ldq $15, 48($sp) 704 ldq $26, 56($sp) 705 ldt $f30, 312($sp) # get saved fpcr 706 ldt $f0, 64($sp) 707 ldt $f1, 72($sp) 708 ldt $f2, 80($sp) 709 ldt $f3, 88($sp) 710 mt_fpcr $f30 # install saved fpcr 711 ldt $f4, 96($sp) 712 ldt $f5, 104($sp) 713 ldt $f6, 112($sp) 714 ldt $f7, 120($sp) 715 ldt $f8, 128($sp) 716 ldt $f9, 136($sp) 717 ldt $f10, 144($sp) 718 ldt $f11, 152($sp) 719 ldt $f12, 160($sp) 720 ldt $f13, 168($sp) 721 ldt $f14, 176($sp) 722 ldt $f15, 184($sp) 723 ldt $f16, 192($sp) 724 ldt $f17, 200($sp) 725 ldt $f18, 208($sp) 726 ldt $f19, 216($sp) 727 ldt $f20, 224($sp) 728 ldt $f21, 232($sp) 729 ldt $f22, 240($sp) 730 ldt $f23, 248($sp) 731 ldt $f24, 256($sp) 732 ldt $f25, 264($sp) 733 ldt $f26, 272($sp) 734 ldt $f27, 280($sp) 735 ldt $f28, 288($sp) 736 ldt $f29, 296($sp) 737 ldt $f30, 304($sp) 738 lda $sp, SWITCH_STACK_SIZE($sp) 739 ret $31, ($1), 1 740 .cfi_endproc 741 .size undo_switch_stack, .-undo_switch_stack 742 743/* 744 * The meat of the context switch code. 745 */ 746 747 .align 4 748 .globl alpha_switch_to 749 .type alpha_switch_to, @function 750 .cfi_startproc 751alpha_switch_to: 752 DO_SWITCH_STACK 753 call_pal PAL_swpctx 754 lda $8, 0x3fff 755 UNDO_SWITCH_STACK 756 bic $sp, $8, $8 757 mov $17, $0 758 ret 759 .cfi_endproc 760 .size alpha_switch_to, .-alpha_switch_to 761 762/* 763 * New processes begin life here. 764 */ 765 766 .globl ret_from_fork 767 .align 4 768 .ent ret_from_fork 769ret_from_fork: 770 lda $26, ret_from_sys_call 771 mov $17, $16 772 jmp $31, schedule_tail 773.end ret_from_fork 774 775/* 776 * ... and new kernel threads - here 777 */ 778 .align 4 779 .globl ret_from_kernel_thread 780 .ent ret_from_kernel_thread 781ret_from_kernel_thread: 782 mov $17, $16 783 jsr $26, schedule_tail 784 mov $9, $27 785 mov $10, $16 786 jsr $26, ($9) 787 mov $31, $19 /* to disable syscall restarts */ 788 br $31, ret_to_user 789.end ret_from_kernel_thread 790 791 792/* 793 * Special system calls. Most of these are special in that they either 794 * have to play switch_stack games or in some way use the pt_regs struct. 795 */ 796 797.macro fork_like name 798 .align 4 799 .globl alpha_\name 800 .ent alpha_\name 801alpha_\name: 802 .prologue 0 803 bsr $1, do_switch_stack 804 jsr $26, sys_\name 805 ldq $26, 56($sp) 806 lda $sp, SWITCH_STACK_SIZE($sp) 807 ret 808.end alpha_\name 809.endm 810 811fork_like fork 812fork_like vfork 813fork_like clone 814 815 .align 4 816 .globl sys_sigreturn 817 .ent sys_sigreturn 818sys_sigreturn: 819 .prologue 0 820 lda $9, ret_from_straced 821 cmpult $26, $9, $9 822 lda $sp, -SWITCH_STACK_SIZE($sp) 823 jsr $26, do_sigreturn 824 bne $9, 1f 825 jsr $26, syscall_trace_leave 8261: br $1, undo_switch_stack 827 br ret_from_sys_call 828.end sys_sigreturn 829 830 .align 4 831 .globl sys_rt_sigreturn 832 .ent sys_rt_sigreturn 833sys_rt_sigreturn: 834 .prologue 0 835 lda $9, ret_from_straced 836 cmpult $26, $9, $9 837 lda $sp, -SWITCH_STACK_SIZE($sp) 838 jsr $26, do_rt_sigreturn 839 bne $9, 1f 840 jsr $26, syscall_trace_leave 8411: br $1, undo_switch_stack 842 br ret_from_sys_call 843.end sys_rt_sigreturn 844 845 .align 4 846 .globl alpha_ni_syscall 847 .ent alpha_ni_syscall 848alpha_ni_syscall: 849 .prologue 0 850 /* Special because it also implements overflow handling via 851 syscall number 0. And if you recall, zero is a special 852 trigger for "not an error". Store large non-zero there. */ 853 lda $0, -ENOSYS 854 unop 855 stq $0, 0($sp) 856 ret 857.end alpha_ni_syscall 858