root/arch/alpha/kernel/entry.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 /*
   2  * alpha/entry.S
   3  *
   4  * kernel entry-points
   5  */
   6 
   7 #include <asm/system.h>
   8 
   9 #define halt    .long PAL_halt
  10 #define rti     .long PAL_rti
  11 
  12 #define NR_SYSCALLS 320
  13 #define osf_vfork sys_fork
  14 
  15 /*
  16  * These offsets must match with "struct hae" in io.h:  
  17  */
  18 #define HAE_CACHE       0
  19 #define HAE_REG         8
  20 
  21 /*
  22  * stack offsets
  23  */
  24 #define SP_OFF          160
  25 
  26 #define SWITCH_STACK_SIZE 320
  27 
  28 /*
  29  * task structure offsets
  30  */
  31 #define TASK_STATE      0
  32 #define TASK_COUNTER    8
  33 #define TASK_PRIORITY   16
  34 #define TASK_SIGNAL     24
  35 #define TASK_BLOCKED    32
  36 #define TASK_FLAGS      40
  37 
  38 /*
  39  * This defines the normal kernel pt-regs layout.
  40  *
  41  * regs 9-15 preserved by C code
  42  * regs 16-18 saved by PAL-code
  43  * regs 29-30 saved and set up by PAL-code
  44  */
  45 #define SAVE_ALL                        \
  46         subq    $30,160,$30;            \
  47         stq     $0,0($30);              \
  48         stq     $1,8($30);              \
  49         stq     $2,16($30);             \
  50         stq     $3,24($30);             \
  51         stq     $4,32($30);             \
  52         stq     $5,40($30);             \
  53         stq     $6,48($30);             \
  54         stq     $7,56($30);             \
  55         stq     $8,64($30);             \
  56         stq     $19,72($30);            \
  57         stq     $20,80($30);            \
  58         stq     $21,88($30);            \
  59         stq     $22,96($30);            \
  60         stq     $23,104($30);           \
  61         stq     $24,112($30);           \
  62         stq     $25,120($30);           \
  63         stq     $26,128($30);           \
  64         stq     $27,136($30);           \
  65         stq     $28,144($30);           \
  66         lda     $2,hae;                 \
  67         ldq     $2,HAE_CACHE($2);       \
  68         stq     $2,152($30)
  69 
  70 #define RESTORE_ALL                     \
  71         lda     $8,hae;                 \
  72         ldq     $7,HAE_CACHE($8);       \
  73         ldq     $6,152($30);            \
  74         subq    $7,$6,$5;               \
  75         beq     $5,99f;                 \
  76         ldq     $7,HAE_REG($8);         \
  77         addq    $31,7,$16;              \
  78         call_pal PAL_swpipl;            \
  79         stq     $6,HAE_CACHE($8);       \
  80         stq     $6,0($7);               \
  81         mb;                             \
  82         bis     $0,$0,$16;              \
  83         call_pal PAL_swpipl;            \
  84 99:;                                    \
  85         ldq     $0,0($30);              \
  86         ldq     $1,8($30);              \
  87         ldq     $2,16($30);             \
  88         ldq     $3,24($30);             \
  89         ldq     $4,32($30);             \
  90         ldq     $5,40($30);             \
  91         ldq     $6,48($30);             \
  92         ldq     $7,56($30);             \
  93         ldq     $8,64($30);             \
  94         ldq     $19,72($30);            \
  95         ldq     $20,80($30);            \
  96         ldq     $21,88($30);            \
  97         ldq     $22,96($30);            \
  98         ldq     $23,104($30);           \
  99         ldq     $24,112($30);           \
 100         ldq     $25,120($30);           \
 101         ldq     $26,128($30);           \
 102         ldq     $27,136($30);           \
 103         ldq     $28,144($30);           \
 104         addq    $30,160,$30
 105 
 106 .text
 107 .set noat
 108 #ifdef __linux__
 109   .set singlegp
 110 #endif
 111 
 112 .align 3
 113 .globl  entInt
 114 .ent    entInt
 115 entInt:
 116         SAVE_ALL
 117 /* start atomic operation with respect to software interrupts */
 118         lda     $0,intr_count
 119         ldq     $1,0($0)
 120         addq    $1,1,$1
 121         stq     $1,0($0)
 122 /* set up the arguments to the C interrupt handler */
 123         lda     $27,do_entInt
 124         jsr     $26,($27),do_entInt
 125 /* ok, check if we need to do software interrupts */
 126 1:      lda     $0,intr_count
 127         ldq     $1,0($0)
 128         subq    $1,1,$1
 129         bne     $1,2f           /* interrupt within interrupt: return now */
 130         lda     $2,bh_active
 131         ldq     $3,0($2)
 132         lda     $2,bh_mask
 133         ldq     $2,0($2)
 134         and     $2,$3,$2
 135         bne     $2,3f
 136         stq     $1,0($0)
 137         br      $31,ret_from_sys_call
 138 .align 3
 139 2:      stq     $1,0($0)
 140         br      $31,restore_all
 141 .align 3
 142 3:      lda     $27,do_bottom_half
 143         jsr     $26,($27),do_bottom_half
 144         br      $31,1b
 145 .end entInt
 146 
 147 .align 3
 148 .globl  entMM
 149 .ent    entMM
 150 entMM:
 151         SAVE_ALL
 152         lda     $27,do_page_fault
 153         lda     $26,ret_from_sys_call
 154         jsr     $31,($27),do_page_fault
 155 .end entMM
 156 
 157 .align 3
 158 .globl  entArith
 159 .ent    entArith
 160 entArith:
 161         SAVE_ALL
 162         lda     $27,do_entArith
 163         lda     $26,ret_from_sys_call
 164         jsr     $31,($27),do_entArith
 165 .end entArith
 166 
 167 .align 3
 168 .globl  entIF
 169 .ent    entIF
 170 entIF:
 171         SAVE_ALL
 172         lda     $27,do_entIF
 173         lda     $26,ret_from_sys_call
 174         jsr     $31,($27),do_entIF
 175 .end entIF
 176 
 177 /*
 178  * Fork() is one of the special system calls: it needs to
 179  * save the callee-saved regs so that the regs can be found
 180  * for the new process.. We save them in the "context switch"
 181  * stack format (see arch/alpha/kernel/process.c).
 182  *
 183  * Also, for the kernel fork, we need to fake the system call
 184  * stack buildup, as we can't do system calls from kernel space.
 185  */
 186 .align 3
 187 .globl  kernel_fork
 188 .ent    kernel_fork
 189 kernel_fork:
 190         subq $30,6*8,$30
 191         stq $31,0($30)
 192         stq $26,8($30)
 193         stq $29,16($30)
 194         stq $16,24($30)
 195         stq $17,32($30)
 196         stq $18,40($30)
 197         bis $31,2,$0    /* Register v0: syscall nr for fork() */
 198         SAVE_ALL
 199         lda $27,sys_fork
 200         jsr $26,($27),sys_fork
 201         stq $0,0($30)   
 202         br ret_from_sys_call
 203 .end    kernel_fork
 204 
 205 .align 3
 206 .ent    do_switch_stack
 207 do_switch_stack:
 208         lda $30,-SWITCH_STACK_SIZE($30)
 209         stq  $9,0($30)
 210         stq $10,8($30)
 211         stq $11,16($30)
 212         stq $12,24($30)
 213         stq $13,32($30)
 214         stq $14,40($30)
 215         stq $15,48($30)
 216         stq $26,56($30)
 217         stt $f0,64($30)
 218         stt $f1,72($30)
 219         stt $f2,80($30)
 220         stt $f3,88($30)
 221         stt $f4,96($30)
 222         stt $f5,104($30)
 223         stt $f6,112($30)
 224         stt $f7,120($30)
 225         stt $f8,128($30)
 226         stt $f9,136($30)
 227         stt $f10,144($30)
 228         stt $f11,152($30)
 229         stt $f12,160($30)
 230         stt $f13,168($30)
 231         stt $f14,176($30)
 232         stt $f15,184($30)
 233         stt $f16,192($30)
 234         stt $f17,200($30)
 235         stt $f18,208($30)
 236         stt $f19,216($30)
 237         stt $f20,224($30)
 238         stt $f21,232($30)
 239         stt $f22,240($30)
 240         stt $f23,248($30)
 241         stt $f24,256($30)
 242         stt $f25,264($30)
 243         stt $f26,272($30)
 244         stt $f27,280($30)
 245         stt $f28,288($30)
 246         stt $f29,296($30)
 247         stt $f30,304($30)
 248         ret $31,($1),1
 249 .end do_switch_stack
 250 
 251 .align 3
 252 .ent    undo_switch_stack
 253 undo_switch_stack:
 254         ldq  $9,0($30)
 255         ldq $10,8($30)
 256         ldq $11,16($30)
 257         ldq $12,24($30)
 258         ldq $13,32($30)
 259         ldq $14,40($30)
 260         ldq $15,48($30)
 261         ldq $26,56($30)
 262         ldt $f0,64($30)
 263         ldt $f1,72($30)
 264         ldt $f2,80($30)
 265         ldt $f3,88($30)
 266         ldt $f4,96($30)
 267         ldt $f5,104($30)
 268         ldt $f6,112($30)
 269         ldt $f7,120($30)
 270         ldt $f8,128($30)
 271         ldt $f9,136($30)
 272         ldt $f10,144($30)
 273         ldt $f11,152($30)
 274         ldt $f12,160($30)
 275         ldt $f13,168($30)
 276         ldt $f14,176($30)
 277         ldt $f15,184($30)
 278         ldt $f16,192($30)
 279         ldt $f17,200($30)
 280         ldt $f18,208($30)
 281         ldt $f19,216($30)
 282         ldt $f20,224($30)
 283         ldt $f21,232($30)
 284         ldt $f22,240($30)
 285         ldt $f23,248($30)
 286         ldt $f24,256($30)
 287         ldt $f25,264($30)
 288         ldt $f26,272($30)
 289         ldt $f27,280($30)
 290         ldt $f28,288($30)
 291         ldt $f29,296($30)
 292         ldt $f30,304($30)
 293         lda $30,SWITCH_STACK_SIZE($30)
 294         ret $31,($1),1
 295 .end undo_switch_stack
 296 
 297 .align 3
 298 .globl  entUna
 299 .ent    entUna
 300 entUna:
 301         lda $30,-256($30)
 302         stq $0,0($30)
 303         ldq $0,256($30)         /* get PS */
 304         stq $1,8($30)
 305         stq $2,16($30)
 306         stq $3,24($30)
 307         and $0,8,$0             /* user mode? */
 308         stq $4,32($30)
 309         bne $0,entUnaUser       /* yup -> do user-level unaligned fault */
 310         stq $5,40($30)
 311         stq $6,48($30)
 312         stq $7,56($30)
 313         stq $8,64($30)
 314         stq $9,72($30)
 315         stq $10,80($30)
 316         stq $11,88($30)
 317         stq $12,96($30)
 318         stq $13,104($30)
 319         stq $14,112($30)
 320         stq $15,120($30)
 321         /* 16-18 PAL-saved */
 322         stq $19,152($30)
 323         stq $20,160($30)
 324         stq $21,168($30)
 325         stq $22,176($30)
 326         stq $23,184($30)
 327         stq $24,192($30)
 328         stq $25,200($30)
 329         stq $26,208($30)
 330         stq $27,216($30)
 331         stq $28,224($30)
 332         stq $29,232($30)
 333         stq $30,240($30)
 334         stq $31,248($30)
 335         lda $27,do_entUna
 336         jsr $26,($27),do_entUna
 337         ldq $0,0($30)
 338         ldq $1,8($30)
 339         ldq $2,16($30)
 340         ldq $3,24($30)
 341         ldq $4,32($30)
 342         ldq $5,40($30)
 343         ldq $6,48($30)
 344         ldq $7,56($30)
 345         ldq $8,64($30)
 346         ldq $9,72($30)
 347         ldq $10,80($30)
 348         ldq $11,88($30)
 349         ldq $12,96($30)
 350         ldq $13,104($30)
 351         ldq $14,112($30)
 352         ldq $15,120($30)
 353         /* 16-18 PAL-saved */
 354         ldq $19,152($30)
 355         ldq $20,160($30)
 356         ldq $21,168($30)
 357         ldq $22,176($30)
 358         ldq $23,184($30)
 359         ldq $24,192($30)
 360         ldq $25,200($30)
 361         ldq $26,208($30)
 362         ldq $27,216($30)
 363         ldq $28,224($30)
 364         ldq $29,232($30)
 365         ldq $30,240($30)
 366         lda $30,256($30)
 367         rti
 368 .end entUna
 369 
 370 .align 3
 371 .ent    entUnaUser
 372 entUnaUser:
 373         ldq $0,0($30)                   /* restore original $0 */
 374         lda $30,256($30)                /* pop entUna's stack frame */
 375         SAVE_ALL                        /* setup normal kernel stack */
 376         lda $27,do_entUnaUser
 377         lda $26,ret_from_sys_call
 378         jsr $31,($27),do_entUnaUser
 379 .end    entUnaUser
 380 
 381 .align 3
 382 .globl  sys_fork
 383 .ent    sys_fork
 384 sys_fork:
 385         br $1,do_switch_stack
 386         bis $30,$30,$16
 387         lda $27,alpha_fork
 388         jsr $26,($27),alpha_fork
 389         br $1,undo_switch_stack
 390         ret $31,($26),1
 391 .end    sys_fork
 392 
 393 .align 3
 394 .globl  alpha_switch_to
 395 .ent    alpha_switch_to
 396 alpha_switch_to:
 397         br $1,do_switch_stack
 398         call_pal PAL_swpctx
 399         br $1,undo_switch_stack
 400         ret $31,($26),1
 401 .end alpha_switch_to
 402 
 403 /*
 404  * Oh, well.. Disassembling OSF/1 binaries to find out how the
 405  * system calls work isn't much fun.
 406  *
 407  * entSys is special in that the PAL-code doesn't save a0-a2, so
 408  * we start off by doing that by hand.
 409  */
 410 .align 3
 411 .globl  entSys
 412 .globl  ret_from_sys_call
 413 .ent    entSys
 414 entSys:
 415         stq     $16,24($30)
 416         stq     $17,32($30)
 417         stq     $18,40($30)
 418         SAVE_ALL
 419         lda     $1,NR_SYSCALLS($31)
 420         lda     $2,sys_call_table
 421         lda     $27,do_entSys
 422         cmpult  $0,$1,$1
 423         s8addq  $0,$2,$2
 424         beq     $1,1f
 425         ldq     $27,0($2)
 426 1:      jsr     $26,($27),do_entSys
 427         ldq     $1,0($30)       /* We have to handle ptrace specially */
 428         subq    $1,26,$1        /* since it returns a pointer value it will*/
 429         bne     $1,3f           /* set up a3 and v0 in the return frame */
 430         ldq     $1,72($30)
 431         stq     $1,0($30)
 432         stq     $0,72($30)
 433         bis     $31,$31,$1
 434         br      $31,ret_from_sys_call
 435 3:      bis     $31,$31,$1
 436         bge     $0,2f           /* the call succeeded */
 437         bis     $31,$31,$26     /* tell "ret_from_sys_call" that we can restart */
 438         ldq     $19,0($30)      /* .. with this syscall nr */
 439         ldq     $20,72($30)     /* .. and this a3 */
 440         addq    $31,1,$1        /* set a3 for errno return */
 441         subq    $31,$0,$0       /* with error in v0 */
 442 2:      stq     $0,0($30)
 443         stq     $1,72($30)      /* a3 for return */
 444 .align 3
 445 ret_from_sys_call:
 446         ldq     $0,SP_OFF($30)
 447         cmovne  $26,0,$19
 448         and     $0,8,$0
 449         beq     $0,restore_all
 450 ret_from_reschedule:
 451         lda     $0,need_resched
 452         lda     $1,current
 453         ldl     $2,0($0)
 454         lda     $4,init_task
 455         ldq     $3,0($1)
 456         bne     $2,reschedule
 457         subq    $4,$3,$4
 458         beq     $4,restore_all
 459         ldq     $4,TASK_SIGNAL($3)
 460         ldq     $16,TASK_BLOCKED($3)
 461         bic     $4,$16,$4
 462         bne     $4,signal_return
 463 restore_all:
 464         RESTORE_ALL
 465         rti
 466 .align 3
 467 signal_return:
 468         bis     $30,$30,$17
 469         br      $1,do_switch_stack
 470         bis     $30,$30,$18
 471         lda     $27,do_signal
 472         jsr     $26,($27),do_signal
 473         lda     $30,SWITCH_STACK_SIZE($30)
 474         br      $31,restore_all
 475 .end entSys
 476 
 477 .align 3
 478 .ent reschedule
 479 reschedule:
 480         subq    $30,16,$30
 481         stq     $19,0($30)
 482         stq     $20,8($30)
 483         lda     $27,schedule
 484         jsr     $26,($27),schedule
 485         ldq     $19,0($30)
 486         ldq     $20,8($30)
 487         addq    $30,16,$30
 488         br      $31,ret_from_reschedule
 489 .end reschedule
 490 
 491 .align 3
 492 .ent sys_sigreturn
 493 sys_sigreturn:
 494         bis     $30,$30,$17
 495         lda     $30,-SWITCH_STACK_SIZE($30)
 496         bis     $30,$30,$18
 497         lda     $27,do_sigreturn
 498         jsr     $26,($27),do_sigreturn
 499         br      $1,undo_switch_stack
 500         br      $31,ret_from_sys_call
 501 .end sys_sigreturn
 502 
 503 .align 3
 504 .ent sys_sigsuspend
 505 sys_sigsuspend:
 506         bis     $30,$30,$17
 507         br      $1,do_switch_stack
 508         bis     $30,$30,$18
 509         lda     $27,do_sigsuspend
 510         jsr     $26,($27),do_sigsuspend
 511         lda     $30,SWITCH_STACK_SIZE($30)
 512         br      $31,ret_from_sys_call
 513 .end sys_sigreturn
 514 
 515         .align 3
 516         .globl sys_call_table
 517 sys_call_table:
 518 /*0*/   .quad do_entSys, sys_exit, sys_fork, sys_read, sys_write
 519         .quad do_entSys, sys_close, sys_wait4, do_entSys, sys_link
 520         .quad sys_unlink, do_entSys, sys_chdir, sys_fchdir, sys_mknod
 521         .quad sys_chmod, sys_chown, sys_brk, do_entSys, sys_lseek
 522         .quad sys_getxpid, osf_mount, osf_umount, sys_setuid, sys_getxuid
 523         .quad do_entSys, sys_ptrace, do_entSys, do_entSys, do_entSys
 524         .quad do_entSys, do_entSys, do_entSys, sys_access, do_entSys
 525         .quad do_entSys, sys_sync, sys_kill, do_entSys, sys_setpgid
 526         .quad do_entSys, sys_dup, sys_pipe, do_entSys, do_entSys
 527         .quad sys_open, do_entSys, sys_getxgid, osf_sigprocmask, do_entSys
 528 /*50*/  .quad do_entSys, do_entSys, do_entSys, do_entSys, sys_ioctl
 529         .quad do_entSys, do_entSys, sys_symlink, sys_readlink, sys_execve
 530         .quad sys_umask, do_entSys, do_entSys, sys_getpgrp, sys_getpagesize
 531         .quad do_entSys, osf_vfork, sys_newstat, sys_newlstat, do_entSys
 532         .quad do_entSys, osf_mmap, do_entSys, sys_munmap, sys_mprotect
 533         .quad sys_madvise, sys_vhangup, do_entSys, do_entSys, sys_getgroups
 534         /* map BSD's setpgrp to sys_setpgid for binary compatibility: */
 535         .quad sys_setgroups, do_entSys, sys_setpgid, sys_setitimer, do_entSys
 536         .quad do_entSys, sys_getitimer, sys_gethostname, sys_sethostname, sys_getdtablesize
 537         .quad sys_dup2, sys_newfstat, sys_fcntl, sys_select, do_entSys
 538         .quad sys_fsync, sys_setpriority, sys_socket, sys_connect, sys_accept
 539 /*100*/ .quad sys_getpriority, sys_send, sys_recv, sys_sigreturn, sys_bind
 540         .quad sys_setsockopt, sys_listen, do_entSys, do_entSys, do_entSys
 541         .quad do_entSys, sys_sigsuspend, do_entSys, do_entSys, do_entSys
 542         .quad do_entSys, sys_gettimeofday, sys_getrusage, sys_getsockopt, do_entSys
 543         .quad do_entSys, do_entSys, sys_settimeofday, sys_fchown, sys_fchmod
 544         .quad sys_recvfrom, sys_setreuid, sys_setregid, sys_rename, sys_truncate
 545         .quad sys_ftruncate, do_entSys, sys_setgid, sys_sendto, sys_shutdown
 546         .quad sys_socketpair, sys_mkdir, sys_rmdir, sys_utimes, do_entSys
 547         .quad do_entSys, sys_getpeername, do_entSys, do_entSys, sys_getrlimit
 548         .quad sys_setrlimit, do_entSys, sys_setsid, do_entSys, do_entSys
 549 /*150*/ .quad sys_getsockname, do_entSys, do_entSys, do_entSys, do_entSys
 550         .quad do_entSys, sys_sigaction, do_entSys, do_entSys, osf_getdirentries
 551         .quad osf_statfs, osf_fstatfs, do_entSys, do_entSys, do_entSys
 552         .quad osf_getdomainname, do_entSys, do_entSys, do_entSys, do_entSys
 553         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 554         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 555         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 556         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 557         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 558         .quad do_entSys, do_entSys, do_entSys, do_entSys, osf_swapon
 559 /*200*/ .quad sys_msgctl, sys_msgget, sys_msgrcv, sys_msgsnd, sys_semctl
 560         .quad sys_semget, sys_semop, osf_utsname, do_entSys, osf_shmat
 561         .quad sys_shmctl, sys_shmdt, sys_shmget, do_entSys, do_entSys
 562         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 563         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 564         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 565         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 566         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 567         .quad do_entSys, do_entSys, do_entSys, do_entSys, osf_proplist_syscall
 568         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 569 /*250*/ .quad do_entSys, osf_usleep_thread, do_entSys, do_entSys, do_entSys
 570         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 571         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 572         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 573         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 574         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 575         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 576         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 577         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 578         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 579 /* linux-specific system calls start at 300 */
 580 /*300*/ .quad sys_bdflush, sys_sethae, sys_mount, sys_adjtimex, sys_swapoff
 581         .quad sys_getdents, sys_create_module, sys_init_module, sys_delete_module, sys_get_kernel_syms
 582         .quad sys_syslog, do_entSys, do_entSys, do_entSys, do_entSys
 583         .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
 584 

/* [previous][next][first][last][top][bottom][index][help] */