linux/arch/alpha/kernel/entry.S
<<
>>
Prefs
   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
  16/* Stack offsets.  */
  17#define SP_OFF                  184
  18#define SWITCH_STACK_SIZE       320
  19
  20/*
  21 * This defines the normal kernel pt-regs layout.
  22 *
  23 * regs 9-15 preserved by C code
  24 * regs 16-18 saved by PAL-code
  25 * regs 29-30 saved and set up by PAL-code
  26 * JRP - Save regs 16-18 in a special area of the stack, so that
  27 * the palcode-provided values are available to the signal handler.
  28 */
  29
  30#define SAVE_ALL                        \
  31        subq    $sp, SP_OFF, $sp;       \
  32        stq     $0, 0($sp);             \
  33        stq     $1, 8($sp);             \
  34        stq     $2, 16($sp);            \
  35        stq     $3, 24($sp);            \
  36        stq     $4, 32($sp);            \
  37        stq     $28, 144($sp);          \
  38        lda     $2, alpha_mv;           \
  39        stq     $5, 40($sp);            \
  40        stq     $6, 48($sp);            \
  41        stq     $7, 56($sp);            \
  42        stq     $8, 64($sp);            \
  43        stq     $19, 72($sp);           \
  44        stq     $20, 80($sp);           \
  45        stq     $21, 88($sp);           \
  46        ldq     $2, HAE_CACHE($2);      \
  47        stq     $22, 96($sp);           \
  48        stq     $23, 104($sp);          \
  49        stq     $24, 112($sp);          \
  50        stq     $25, 120($sp);          \
  51        stq     $26, 128($sp);          \
  52        stq     $27, 136($sp);          \
  53        stq     $2, 152($sp);           \
  54        stq     $16, 160($sp);          \
  55        stq     $17, 168($sp);          \
  56        stq     $18, 176($sp)
  57
  58#define RESTORE_ALL                     \
  59        lda     $19, alpha_mv;          \
  60        ldq     $0, 0($sp);             \
  61        ldq     $1, 8($sp);             \
  62        ldq     $2, 16($sp);            \
  63        ldq     $3, 24($sp);            \
  64        ldq     $21, 152($sp);          \
  65        ldq     $20, HAE_CACHE($19);    \
  66        ldq     $4, 32($sp);            \
  67        ldq     $5, 40($sp);            \
  68        ldq     $6, 48($sp);            \
  69        ldq     $7, 56($sp);            \
  70        subq    $20, $21, $20;          \
  71        ldq     $8, 64($sp);            \
  72        beq     $20, 99f;               \
  73        ldq     $20, HAE_REG($19);      \
  74        stq     $21, HAE_CACHE($19);    \
  75        stq     $21, 0($20);            \
  76        ldq     $0, 0($sp);             \
  77        ldq     $1, 8($sp);             \
  7899:;                                    \
  79        ldq     $19, 72($sp);           \
  80        ldq     $20, 80($sp);           \
  81        ldq     $21, 88($sp);           \
  82        ldq     $22, 96($sp);           \
  83        ldq     $23, 104($sp);          \
  84        ldq     $24, 112($sp);          \
  85        ldq     $25, 120($sp);          \
  86        ldq     $26, 128($sp);          \
  87        ldq     $27, 136($sp);          \
  88        ldq     $28, 144($sp);          \
  89        addq    $sp, SP_OFF, $sp
  90
  91/*
  92 * Non-syscall kernel entry points.
  93 */
  94
  95        .align  4
  96        .globl  entInt
  97        .ent    entInt
  98entInt:
  99        SAVE_ALL
 100        lda     $8, 0x3fff
 101        lda     $26, ret_from_sys_call
 102        bic     $sp, $8, $8
 103        mov     $sp, $19
 104        jsr     $31, do_entInt
 105.end entInt
 106
 107        .align  4
 108        .globl  entArith
 109        .ent    entArith
 110entArith:
 111        SAVE_ALL
 112        lda     $8, 0x3fff
 113        lda     $26, ret_from_sys_call
 114        bic     $sp, $8, $8
 115        mov     $sp, $18
 116        jsr     $31, do_entArith
 117.end entArith
 118
 119        .align  4
 120        .globl  entMM
 121        .ent    entMM
 122entMM:
 123        SAVE_ALL
 124/* save $9 - $15 so the inline exception code can manipulate them.  */
 125        subq    $sp, 56, $sp
 126        stq     $9, 0($sp)
 127        stq     $10, 8($sp)
 128        stq     $11, 16($sp)
 129        stq     $12, 24($sp)
 130        stq     $13, 32($sp)
 131        stq     $14, 40($sp)
 132        stq     $15, 48($sp)
 133        addq    $sp, 56, $19
 134/* handle the fault */
 135        lda     $8, 0x3fff
 136        bic     $sp, $8, $8
 137        jsr     $26, do_page_fault
 138/* reload the registers after the exception code played.  */
 139        ldq     $9, 0($sp)
 140        ldq     $10, 8($sp)
 141        ldq     $11, 16($sp)
 142        ldq     $12, 24($sp)
 143        ldq     $13, 32($sp)
 144        ldq     $14, 40($sp)
 145        ldq     $15, 48($sp)
 146        addq    $sp, 56, $sp
 147/* finish up the syscall as normal.  */
 148        br      ret_from_sys_call
 149.end entMM
 150
 151        .align  4
 152        .globl  entIF
 153        .ent    entIF
 154entIF:
 155        SAVE_ALL
 156        lda     $8, 0x3fff
 157        lda     $26, ret_from_sys_call
 158        bic     $sp, $8, $8
 159        mov     $sp, $17
 160        jsr     $31, do_entIF
 161.end entIF
 162
 163        .align  4
 164        .globl  entUna
 165        .ent    entUna
 166entUna:
 167        lda     $sp, -256($sp)
 168        stq     $0, 0($sp)
 169        ldq     $0, 256($sp)    /* get PS */
 170        stq     $1, 8($sp)
 171        stq     $2, 16($sp)
 172        stq     $3, 24($sp)
 173        and     $0, 8, $0               /* user mode? */
 174        stq     $4, 32($sp)
 175        bne     $0, entUnaUser  /* yup -> do user-level unaligned fault */
 176        stq     $5, 40($sp)
 177        stq     $6, 48($sp)
 178        stq     $7, 56($sp)
 179        stq     $8, 64($sp)
 180        stq     $9, 72($sp)
 181        stq     $10, 80($sp)
 182        stq     $11, 88($sp)
 183        stq     $12, 96($sp)
 184        stq     $13, 104($sp)
 185        stq     $14, 112($sp)
 186        stq     $15, 120($sp)
 187        /* 16-18 PAL-saved */
 188        stq     $19, 152($sp)
 189        stq     $20, 160($sp)
 190        stq     $21, 168($sp)
 191        stq     $22, 176($sp)
 192        stq     $23, 184($sp)
 193        stq     $24, 192($sp)
 194        stq     $25, 200($sp)
 195        stq     $26, 208($sp)
 196        stq     $27, 216($sp)
 197        stq     $28, 224($sp)
 198        mov     $sp, $19
 199        stq     $gp, 232($sp)
 200        lda     $8, 0x3fff
 201        stq     $31, 248($sp)
 202        bic     $sp, $8, $8
 203        jsr     $26, do_entUna
 204        ldq     $0, 0($sp)
 205        ldq     $1, 8($sp)
 206        ldq     $2, 16($sp)
 207        ldq     $3, 24($sp)
 208        ldq     $4, 32($sp)
 209        ldq     $5, 40($sp)
 210        ldq     $6, 48($sp)
 211        ldq     $7, 56($sp)
 212        ldq     $8, 64($sp)
 213        ldq     $9, 72($sp)
 214        ldq     $10, 80($sp)
 215        ldq     $11, 88($sp)
 216        ldq     $12, 96($sp)
 217        ldq     $13, 104($sp)
 218        ldq     $14, 112($sp)
 219        ldq     $15, 120($sp)
 220        /* 16-18 PAL-saved */
 221        ldq     $19, 152($sp)
 222        ldq     $20, 160($sp)
 223        ldq     $21, 168($sp)
 224        ldq     $22, 176($sp)
 225        ldq     $23, 184($sp)
 226        ldq     $24, 192($sp)
 227        ldq     $25, 200($sp)
 228        ldq     $26, 208($sp)
 229        ldq     $27, 216($sp)
 230        ldq     $28, 224($sp)
 231        ldq     $gp, 232($sp)
 232        lda     $sp, 256($sp)
 233        call_pal PAL_rti
 234.end entUna
 235
 236        .align  4
 237        .ent    entUnaUser
 238entUnaUser:
 239        ldq     $0, 0($sp)      /* restore original $0 */
 240        lda     $sp, 256($sp)   /* pop entUna's stack frame */
 241        SAVE_ALL                /* setup normal kernel stack */
 242        lda     $sp, -56($sp)
 243        stq     $9, 0($sp)
 244        stq     $10, 8($sp)
 245        stq     $11, 16($sp)
 246        stq     $12, 24($sp)
 247        stq     $13, 32($sp)
 248        stq     $14, 40($sp)
 249        stq     $15, 48($sp)
 250        lda     $8, 0x3fff
 251        addq    $sp, 56, $19
 252        bic     $sp, $8, $8
 253        jsr     $26, do_entUnaUser
 254        ldq     $9, 0($sp)
 255        ldq     $10, 8($sp)
 256        ldq     $11, 16($sp)
 257        ldq     $12, 24($sp)
 258        ldq     $13, 32($sp)
 259        ldq     $14, 40($sp)
 260        ldq     $15, 48($sp)
 261        lda     $sp, 56($sp)
 262        br      ret_from_sys_call
 263.end entUnaUser
 264
 265        .align  4
 266        .globl  entDbg
 267        .ent    entDbg
 268entDbg:
 269        SAVE_ALL
 270        lda     $8, 0x3fff
 271        lda     $26, ret_from_sys_call
 272        bic     $sp, $8, $8
 273        mov     $sp, $16
 274        jsr     $31, do_entDbg
 275.end entDbg
 276
 277/*
 278 * The system call entry point is special.  Most importantly, it looks
 279 * like a function call to userspace as far as clobbered registers.  We
 280 * do preserve the argument registers (for syscall restarts) and $26
 281 * (for leaf syscall functions).
 282 *
 283 * So much for theory.  We don't take advantage of this yet.
 284 *
 285 * Note that a0-a2 are not saved by PALcode as with the other entry points.
 286 */
 287
 288        .align  4
 289        .globl  entSys
 290        .globl  ret_from_sys_call
 291        .ent    entSys
 292entSys:
 293        SAVE_ALL
 294        lda     $8, 0x3fff
 295        bic     $sp, $8, $8
 296        lda     $4, NR_SYSCALLS($31)
 297        stq     $16, SP_OFF+24($sp)
 298        lda     $5, sys_call_table
 299        lda     $27, sys_ni_syscall
 300        cmpult  $0, $4, $4
 301        ldl     $3, TI_FLAGS($8)
 302        stq     $17, SP_OFF+32($sp)
 303        s8addq  $0, $5, $5
 304        stq     $18, SP_OFF+40($sp)
 305        blbs    $3, strace
 306        beq     $4, 1f
 307        ldq     $27, 0($5)
 3081:      jsr     $26, ($27), alpha_ni_syscall
 309        ldgp    $gp, 0($26)
 310        blt     $0, $syscall_error      /* the call failed */
 311        stq     $0, 0($sp)
 312        stq     $31, 72($sp)            /* a3=0 => no error */
 313
 314        .align  4
 315ret_from_sys_call:
 316        cmovne  $26, 0, $19             /* $19 = 0 => non-restartable */
 317        ldq     $0, SP_OFF($sp)
 318        and     $0, 8, $0
 319        beq     $0, restore_all
 320ret_from_reschedule:
 321        /* Make sure need_resched and sigpending don't change between
 322                sampling and the rti.  */
 323        lda     $16, 7
 324        call_pal PAL_swpipl
 325        ldl     $5, TI_FLAGS($8)
 326        and     $5, _TIF_WORK_MASK, $2
 327        bne     $5, work_pending
 328restore_all:
 329        RESTORE_ALL
 330        call_pal PAL_rti
 331
 332        .align 3
 333$syscall_error:
 334        /*
 335         * Some system calls (e.g., ptrace) can return arbitrary
 336         * values which might normally be mistaken as error numbers.
 337         * Those functions must zero $0 (v0) directly in the stack
 338         * frame to indicate that a negative return value wasn't an
 339         * error number..
 340         */
 341        ldq     $19, 0($sp)     /* old syscall nr (zero if success) */
 342        beq     $19, $ret_success
 343
 344        ldq     $20, 72($sp)    /* .. and this a3 */
 345        subq    $31, $0, $0     /* with error in v0 */
 346        addq    $31, 1, $1      /* set a3 for errno return */
 347        stq     $0, 0($sp)
 348        mov     $31, $26        /* tell "ret_from_sys_call" we can restart */
 349        stq     $1, 72($sp)     /* a3 for return */
 350        br      ret_from_sys_call
 351
 352$ret_success:
 353        stq     $0, 0($sp)
 354        stq     $31, 72($sp)    /* a3=0 => no error */
 355        br      ret_from_sys_call
 356.end entSys
 357
 358/*
 359 * Do all cleanup when returning from all interrupts and system calls.
 360 *
 361 * Arguments:
 362 *       $5: TI_FLAGS.
 363 *       $8: current.
 364 *      $19: The old syscall number, or zero if this is not a return
 365 *           from a syscall that errored and is possibly restartable.
 366 *      $20: Error indication.
 367 */
 368
 369        .align  4
 370        .ent    work_pending
 371work_pending:
 372        and     $5, _TIF_NEED_RESCHED, $2
 373        beq     $2, $work_notifysig
 374
 375$work_resched:
 376        subq    $sp, 16, $sp
 377        stq     $19, 0($sp)              /* save syscall nr */
 378        stq     $20, 8($sp)              /* and error indication (a3) */
 379        jsr     $26, schedule
 380        ldq     $19, 0($sp)
 381        ldq     $20, 8($sp)
 382        addq    $sp, 16, $sp
 383        /* Make sure need_resched and sigpending don't change between
 384                sampling and the rti.  */
 385        lda     $16, 7
 386        call_pal PAL_swpipl
 387        ldl     $5, TI_FLAGS($8)
 388        and     $5, _TIF_WORK_MASK, $2
 389        beq     $2, restore_all
 390        and     $5, _TIF_NEED_RESCHED, $2
 391        bne     $2, $work_resched
 392
 393$work_notifysig:
 394        mov     $sp, $16
 395        br      $1, do_switch_stack
 396        mov     $sp, $17
 397        mov     $5, $18
 398        jsr     $26, do_notify_resume
 399        bsr     $1, undo_switch_stack
 400        br      restore_all
 401.end work_pending
 402
 403/*
 404 * PTRACE syscall handler
 405 */
 406
 407        .align  4
 408        .ent    strace
 409strace:
 410        /* set up signal stack, call syscall_trace */
 411        bsr     $1, do_switch_stack
 412        jsr     $26, syscall_trace
 413        bsr     $1, undo_switch_stack
 414
 415        /* get the system call number and the arguments back.. */
 416        ldq     $0, 0($sp)
 417        ldq     $16, SP_OFF+24($sp)
 418        ldq     $17, SP_OFF+32($sp)
 419        ldq     $18, SP_OFF+40($sp)
 420        ldq     $19, 72($sp)
 421        ldq     $20, 80($sp)
 422        ldq     $21, 88($sp)
 423
 424        /* get the system call pointer.. */
 425        lda     $1, NR_SYSCALLS($31)
 426        lda     $2, sys_call_table
 427        lda     $27, alpha_ni_syscall
 428        cmpult  $0, $1, $1
 429        s8addq  $0, $2, $2
 430        beq     $1, 1f
 431        ldq     $27, 0($2)
 4321:      jsr     $26, ($27), sys_gettimeofday
 433        ldgp    $gp, 0($26)
 434
 435        /* check return.. */
 436        blt     $0, $strace_error       /* the call failed */
 437        stq     $31, 72($sp)            /* a3=0 => no error */
 438$strace_success:
 439        stq     $0, 0($sp)              /* save return value */
 440
 441        bsr     $1, do_switch_stack
 442        jsr     $26, syscall_trace
 443        bsr     $1, undo_switch_stack
 444        br      $31, ret_from_sys_call
 445
 446        .align  3
 447$strace_error:
 448        ldq     $19, 0($sp)     /* old syscall nr (zero if success) */
 449        beq     $19, $strace_success
 450        ldq     $20, 72($sp)    /* .. and this a3 */
 451
 452        subq    $31, $0, $0     /* with error in v0 */
 453        addq    $31, 1, $1      /* set a3 for errno return */
 454        stq     $0, 0($sp)
 455        stq     $1, 72($sp)     /* a3 for return */
 456
 457        bsr     $1, do_switch_stack
 458        mov     $19, $9         /* save old syscall number */
 459        mov     $20, $10        /* save old a3 */
 460        jsr     $26, syscall_trace
 461        mov     $9, $19
 462        mov     $10, $20
 463        bsr     $1, undo_switch_stack
 464
 465        mov     $31, $26        /* tell "ret_from_sys_call" we can restart */
 466        br      ret_from_sys_call
 467.end strace
 468
 469/*
 470 * Save and restore the switch stack -- aka the balance of the user context.
 471 */
 472
 473        .align  4
 474        .ent    do_switch_stack
 475do_switch_stack:
 476        lda     $sp, -SWITCH_STACK_SIZE($sp)
 477        stq     $9, 0($sp)
 478        stq     $10, 8($sp)
 479        stq     $11, 16($sp)
 480        stq     $12, 24($sp)
 481        stq     $13, 32($sp)
 482        stq     $14, 40($sp)
 483        stq     $15, 48($sp)
 484        stq     $26, 56($sp)
 485        stt     $f0, 64($sp)
 486        stt     $f1, 72($sp)
 487        stt     $f2, 80($sp)
 488        stt     $f3, 88($sp)
 489        stt     $f4, 96($sp)
 490        stt     $f5, 104($sp)
 491        stt     $f6, 112($sp)
 492        stt     $f7, 120($sp)
 493        stt     $f8, 128($sp)
 494        stt     $f9, 136($sp)
 495        stt     $f10, 144($sp)
 496        stt     $f11, 152($sp)
 497        stt     $f12, 160($sp)
 498        stt     $f13, 168($sp)
 499        stt     $f14, 176($sp)
 500        stt     $f15, 184($sp)
 501        stt     $f16, 192($sp)
 502        stt     $f17, 200($sp)
 503        stt     $f18, 208($sp)
 504        stt     $f19, 216($sp)
 505        stt     $f20, 224($sp)
 506        stt     $f21, 232($sp)
 507        stt     $f22, 240($sp)
 508        stt     $f23, 248($sp)
 509        stt     $f24, 256($sp)
 510        stt     $f25, 264($sp)
 511        stt     $f26, 272($sp)
 512        stt     $f27, 280($sp)
 513        mf_fpcr $f0             # get fpcr
 514        stt     $f28, 288($sp)
 515        stt     $f29, 296($sp)
 516        stt     $f30, 304($sp)
 517        stt     $f0, 312($sp)   # save fpcr in slot of $f31
 518        ldt     $f0, 64($sp)    # dont let "do_switch_stack" change fp state.
 519        ret     $31, ($1), 1
 520.end do_switch_stack
 521
 522        .align  4
 523        .ent    undo_switch_stack
 524undo_switch_stack:
 525        ldq     $9, 0($sp)
 526        ldq     $10, 8($sp)
 527        ldq     $11, 16($sp)
 528        ldq     $12, 24($sp)
 529        ldq     $13, 32($sp)
 530        ldq     $14, 40($sp)
 531        ldq     $15, 48($sp)
 532        ldq     $26, 56($sp)
 533        ldt     $f30, 312($sp)  # get saved fpcr
 534        ldt     $f0, 64($sp)
 535        ldt     $f1, 72($sp)
 536        ldt     $f2, 80($sp)
 537        ldt     $f3, 88($sp)
 538        mt_fpcr $f30            # install saved fpcr
 539        ldt     $f4, 96($sp)
 540        ldt     $f5, 104($sp)
 541        ldt     $f6, 112($sp)
 542        ldt     $f7, 120($sp)
 543        ldt     $f8, 128($sp)
 544        ldt     $f9, 136($sp)
 545        ldt     $f10, 144($sp)
 546        ldt     $f11, 152($sp)
 547        ldt     $f12, 160($sp)
 548        ldt     $f13, 168($sp)
 549        ldt     $f14, 176($sp)
 550        ldt     $f15, 184($sp)
 551        ldt     $f16, 192($sp)
 552        ldt     $f17, 200($sp)
 553        ldt     $f18, 208($sp)
 554        ldt     $f19, 216($sp)
 555        ldt     $f20, 224($sp)
 556        ldt     $f21, 232($sp)
 557        ldt     $f22, 240($sp)
 558        ldt     $f23, 248($sp)
 559        ldt     $f24, 256($sp)
 560        ldt     $f25, 264($sp)
 561        ldt     $f26, 272($sp)
 562        ldt     $f27, 280($sp)
 563        ldt     $f28, 288($sp)
 564        ldt     $f29, 296($sp)
 565        ldt     $f30, 304($sp)
 566        lda     $sp, SWITCH_STACK_SIZE($sp)
 567        ret     $31, ($1), 1
 568.end undo_switch_stack
 569
 570/*
 571 * The meat of the context switch code.
 572 */
 573
 574        .align  4
 575        .globl  alpha_switch_to
 576        .ent    alpha_switch_to
 577alpha_switch_to:
 578        .prologue 0
 579        bsr     $1, do_switch_stack
 580        call_pal PAL_swpctx
 581        lda     $8, 0x3fff
 582        bsr     $1, undo_switch_stack
 583        bic     $sp, $8, $8
 584        mov     $17, $0
 585        ret
 586.end alpha_switch_to
 587
 588/*
 589 * New processes begin life here.
 590 */
 591
 592        .globl  ret_from_fork
 593        .align  4
 594        .ent    ret_from_fork
 595ret_from_fork:
 596        lda     $26, ret_from_sys_call
 597        mov     $17, $16
 598        jmp     $31, schedule_tail
 599.end ret_from_fork
 600
 601/*
 602 * kernel_thread(fn, arg, clone_flags)
 603 */
 604        .align 4
 605        .globl  kernel_thread
 606        .ent    kernel_thread
 607kernel_thread:
 608        /* We can be called from a module.  */
 609        ldgp    $gp, 0($27)
 610        .prologue 1
 611        subq    $sp, SP_OFF+6*8, $sp
 612        br      $1, 2f          /* load start address */
 613
 614        /* We've now "returned" from a fake system call.  */
 615        unop
 616        blt     $0, 1f          /* error?  */
 617        ldi     $1, 0x3fff
 618        beq     $20, 1f         /* parent or child?  */
 619
 620        bic     $sp, $1, $8     /* in child.  */
 621        jsr     $26, ($27)
 622        ldgp    $gp, 0($26)
 623        mov     $0, $16
 624        mov     $31, $26
 625        jmp     $31, sys_exit
 626
 6271:      ret                     /* in parent.  */
 628
 629        .align 4
 6302:      /* Fake a system call stack frame, as we can't do system calls
 631           from kernel space.  Note that we store FN and ARG as they
 632           need to be set up in the child for the call.  Also store $8
 633           and $26 for use in the parent.  */
 634        stq     $31, SP_OFF($sp)        /* ps */
 635        stq     $1, SP_OFF+8($sp)       /* pc */
 636        stq     $gp, SP_OFF+16($sp)     /* gp */
 637        stq     $16, 136($sp)           /* $27; FN for child */
 638        stq     $17, SP_OFF+24($sp)     /* $16; ARG for child */
 639        stq     $8, 64($sp)             /* $8 */
 640        stq     $26, 128($sp)           /* $26 */
 641        /* Avoid the HAE being gratuitously wrong, to avoid restoring it.  */
 642        ldq     $2, alpha_mv+HAE_CACHE
 643        stq     $2, 152($sp)            /* HAE */
 644
 645        /* Shuffle FLAGS to the front; add CLONE_VM.  */
 646        ldi     $1, CLONE_VM|CLONE_UNTRACED
 647        or      $18, $1, $16
 648        bsr     $26, sys_clone
 649
 650        /* We don't actually care for a3 success widgetry in the kernel.
 651           Not for positive errno values.  */
 652        stq     $0, 0($sp)              /* $0 */
 653        br      restore_all
 654.end kernel_thread
 655
 656/*
 657 * kernel_execve(path, argv, envp)
 658 */
 659        .align  4
 660        .globl  kernel_execve
 661        .ent    kernel_execve
 662kernel_execve:
 663        /* We can be called from a module.  */
 664        ldgp    $gp, 0($27)
 665        lda     $sp, -(32+SIZEOF_PT_REGS+8)($sp)
 666        .frame  $sp, 32+SIZEOF_PT_REGS+8, $26, 0
 667        stq     $26, 0($sp)
 668        stq     $16, 8($sp)
 669        stq     $17, 16($sp)
 670        stq     $18, 24($sp)
 671        .prologue 1
 672
 673        lda     $16, 32($sp)
 674        lda     $17, 0
 675        lda     $18, SIZEOF_PT_REGS
 676        bsr     $26, memset             !samegp
 677
 678        /* Avoid the HAE being gratuitously wrong, which would cause us
 679           to do the whole turn off interrupts thing and restore it.  */
 680        ldq     $2, alpha_mv+HAE_CACHE
 681        stq     $2, 152+32($sp)
 682
 683        ldq     $16, 8($sp)
 684        ldq     $17, 16($sp)
 685        ldq     $18, 24($sp)
 686        lda     $19, 32($sp)
 687        bsr     $26, do_execve          !samegp
 688
 689        ldq     $26, 0($sp)
 690        bne     $0, 1f                  /* error! */
 691
 692        /* Move the temporary pt_regs struct from its current location
 693           to the top of the kernel stack frame.  See copy_thread for
 694           details for a normal process.  */
 695        lda     $16, 0x4000 - SIZEOF_PT_REGS($8)
 696        lda     $17, 32($sp)
 697        lda     $18, SIZEOF_PT_REGS
 698        bsr     $26, memmove            !samegp
 699
 700        /* Take that over as our new stack frame and visit userland!  */
 701        lda     $sp, 0x4000 - SIZEOF_PT_REGS($8)
 702        br      $31, ret_from_sys_call
 703
 7041:      lda     $sp, 32+SIZEOF_PT_REGS+8($sp)
 705        ret
 706.end kernel_execve
 707
 708
 709/*
 710 * Special system calls.  Most of these are special in that they either
 711 * have to play switch_stack games or in some way use the pt_regs struct.
 712 */
 713        .align  4
 714        .globl  sys_fork
 715        .ent    sys_fork
 716sys_fork:
 717        .prologue 0
 718        mov     $sp, $21
 719        bsr     $1, do_switch_stack
 720        bis     $31, SIGCHLD, $16
 721        mov     $31, $17
 722        mov     $31, $18
 723        mov     $31, $19
 724        mov     $31, $20
 725        jsr     $26, alpha_clone
 726        bsr     $1, undo_switch_stack
 727        ret
 728.end sys_fork
 729
 730        .align  4
 731        .globl  sys_clone
 732        .ent    sys_clone
 733sys_clone:
 734        .prologue 0
 735        mov     $sp, $21
 736        bsr     $1, do_switch_stack
 737        /* $16, $17, $18, $19, $20 come from the user.  */
 738        jsr     $26, alpha_clone
 739        bsr     $1, undo_switch_stack
 740        ret
 741.end sys_clone
 742
 743        .align  4
 744        .globl  sys_vfork
 745        .ent    sys_vfork
 746sys_vfork:
 747        .prologue 0
 748        mov     $sp, $16
 749        bsr     $1, do_switch_stack
 750        jsr     $26, alpha_vfork
 751        bsr     $1, undo_switch_stack
 752        ret
 753.end sys_vfork
 754
 755        .align  4
 756        .globl  sys_sigreturn
 757        .ent    sys_sigreturn
 758sys_sigreturn:
 759        .prologue 0
 760        mov     $sp, $17
 761        lda     $18, -SWITCH_STACK_SIZE($sp)
 762        lda     $sp, -SWITCH_STACK_SIZE($sp)
 763        jsr     $26, do_sigreturn
 764        br      $1, undo_switch_stack
 765        br      ret_from_sys_call
 766.end sys_sigreturn
 767
 768        .align  4
 769        .globl  sys_rt_sigreturn
 770        .ent    sys_rt_sigreturn
 771sys_rt_sigreturn:
 772        .prologue 0
 773        mov     $sp, $17
 774        lda     $18, -SWITCH_STACK_SIZE($sp)
 775        lda     $sp, -SWITCH_STACK_SIZE($sp)
 776        jsr     $26, do_rt_sigreturn
 777        br      $1, undo_switch_stack
 778        br      ret_from_sys_call
 779.end sys_rt_sigreturn
 780
 781        .align  4
 782        .globl  sys_sigsuspend
 783        .ent    sys_sigsuspend
 784sys_sigsuspend:
 785        .prologue 0
 786        mov     $sp, $17
 787        br      $1, do_switch_stack
 788        mov     $sp, $18
 789        subq    $sp, 16, $sp
 790        stq     $26, 0($sp)
 791        jsr     $26, do_sigsuspend
 792        ldq     $26, 0($sp)
 793        lda     $sp, SWITCH_STACK_SIZE+16($sp)
 794        ret
 795.end sys_sigsuspend
 796
 797        .align  4
 798        .globl  sys_rt_sigsuspend
 799        .ent    sys_rt_sigsuspend
 800sys_rt_sigsuspend:
 801        .prologue 0
 802        mov     $sp, $18
 803        br      $1, do_switch_stack
 804        mov     $sp, $19
 805        subq    $sp, 16, $sp
 806        stq     $26, 0($sp)
 807        jsr     $26, do_rt_sigsuspend
 808        ldq     $26, 0($sp)
 809        lda     $sp, SWITCH_STACK_SIZE+16($sp)
 810        ret
 811.end sys_rt_sigsuspend
 812
 813        .align  4
 814        .globl  sys_sethae
 815        .ent    sys_sethae
 816sys_sethae:
 817        .prologue 0
 818        stq     $16, 152($sp)
 819        ret
 820.end sys_sethae
 821
 822        .align  4
 823        .globl  osf_getpriority
 824        .ent    osf_getpriority
 825osf_getpriority:
 826        lda     $sp, -16($sp)
 827        stq     $26, 0($sp)
 828        .prologue 0
 829
 830        jsr     $26, sys_getpriority
 831
 832        ldq     $26, 0($sp)
 833        blt     $0, 1f
 834
 835        /* Return value is the unbiased priority, i.e. 20 - prio.
 836           This does result in negative return values, so signal
 837           no error by writing into the R0 slot.  */
 838        lda     $1, 20
 839        stq     $31, 16($sp)
 840        subl    $1, $0, $0
 841        unop
 842
 8431:      lda     $sp, 16($sp)
 844        ret
 845.end osf_getpriority
 846
 847        .align  4
 848        .globl  sys_getxuid
 849        .ent    sys_getxuid
 850sys_getxuid:
 851        .prologue 0
 852        ldq     $2, TI_TASK($8)
 853        ldq     $3, TASK_CRED($2)
 854        ldl     $0, CRED_UID($3)
 855        ldl     $1, CRED_EUID($3)
 856        stq     $1, 80($sp)
 857        ret
 858.end sys_getxuid
 859
 860        .align  4
 861        .globl  sys_getxgid
 862        .ent    sys_getxgid
 863sys_getxgid:
 864        .prologue 0
 865        ldq     $2, TI_TASK($8)
 866        ldq     $3, TASK_CRED($2)
 867        ldl     $0, CRED_GID($3)
 868        ldl     $1, CRED_EGID($3)
 869        stq     $1, 80($sp)
 870        ret
 871.end sys_getxgid
 872
 873        .align  4
 874        .globl  sys_getxpid
 875        .ent    sys_getxpid
 876sys_getxpid:
 877        .prologue 0
 878        ldq     $2, TI_TASK($8)
 879
 880        /* See linux/kernel/timer.c sys_getppid for discussion
 881           about this loop.  */
 882        ldq     $3, TASK_GROUP_LEADER($2)
 883        ldq     $4, TASK_REAL_PARENT($3)
 884        ldl     $0, TASK_TGID($2)
 8851:      ldl     $1, TASK_TGID($4)
 886#ifdef CONFIG_SMP
 887        mov     $4, $5
 888        mb
 889        ldq     $3, TASK_GROUP_LEADER($2)
 890        ldq     $4, TASK_REAL_PARENT($3)
 891        cmpeq   $4, $5, $5
 892        beq     $5, 1b
 893#endif
 894        stq     $1, 80($sp)
 895        ret
 896.end sys_getxpid
 897
 898        .align  4
 899        .globl  sys_alpha_pipe
 900        .ent    sys_alpha_pipe
 901sys_alpha_pipe:
 902        lda     $sp, -16($sp)
 903        stq     $26, 0($sp)
 904        .prologue 0
 905
 906        mov     $31, $17
 907        lda     $16, 8($sp)
 908        jsr     $26, do_pipe_flags
 909
 910        ldq     $26, 0($sp)
 911        bne     $0, 1f
 912
 913        /* The return values are in $0 and $20.  */
 914        ldl     $1, 12($sp)
 915        ldl     $0, 8($sp)
 916
 917        stq     $1, 80+16($sp)
 9181:      lda     $sp, 16($sp)
 919        ret
 920.end sys_alpha_pipe
 921
 922        .align  4
 923        .globl  sys_execve
 924        .ent    sys_execve
 925sys_execve:
 926        .prologue 0
 927        mov     $sp, $19
 928        jmp     $31, do_sys_execve
 929.end sys_execve
 930
 931        .align  4
 932        .globl  osf_sigprocmask
 933        .ent    osf_sigprocmask
 934osf_sigprocmask:
 935        .prologue 0
 936        mov     $sp, $18
 937        jmp     $31, sys_osf_sigprocmask
 938.end osf_sigprocmask
 939
 940        .align  4
 941        .globl  alpha_ni_syscall
 942        .ent    alpha_ni_syscall
 943alpha_ni_syscall:
 944        .prologue 0
 945        /* Special because it also implements overflow handling via
 946           syscall number 0.  And if you recall, zero is a special
 947           trigger for "not an error".  Store large non-zero there.  */
 948        lda     $0, -ENOSYS
 949        unop
 950        stq     $0, 0($sp)
 951        ret
 952.end alpha_ni_syscall
 953
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.