diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1995-11-14 08:00:00 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1995-11-14 08:00:00 +0000 |
commit | e7c2a72e2680827d6a733931273a93461c0d8d1b (patch) | |
tree | c9abeda78ef7504062bb2e816bcf3e3c9d680112 /arch/alpha/kernel/entry.S | |
parent | ec6044459060a8c9ce7f64405c465d141898548c (diff) |
Import of Linux/MIPS 1.3.0
Diffstat (limited to 'arch/alpha/kernel/entry.S')
-rw-r--r-- | arch/alpha/kernel/entry.S | 554 |
1 files changed, 554 insertions, 0 deletions
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S new file mode 100644 index 000000000..b54ea220b --- /dev/null +++ b/arch/alpha/kernel/entry.S @@ -0,0 +1,554 @@ +/* + * alpha/entry.S + * + * kernel entry-points + */ + +#include <asm/system.h> + +#define halt .long PAL_halt +#define rti .long PAL_rti + +#define NR_SYSCALLS 310 +#define osf_vfork sys_fork + +/* + * These offsets must match with "struct hae" in io.h: + */ +#define HAE_CACHE 0 +#define HAE_REG 8 + +/* + * stack offsets + */ +#define SP_OFF 160 + +#define SWITCH_STACK_SIZE 320 + +/* + * task structure offsets + */ +#define TASK_STATE 0 +#define TASK_COUNTER 8 +#define TASK_PRIORITY 16 +#define TASK_SIGNAL 24 +#define TASK_BLOCKED 32 +#define TASK_FLAGS 40 + +/* + * This defines the normal kernel pt-regs layout. + * + * regs 9-15 preserved by C code + * regs 16-18 saved by PAL-code + * regs 29-30 saved and set up by PAL-code + */ +#define SAVE_ALL \ + subq $30,160,$30; \ + stq $0,0($30); \ + stq $1,8($30); \ + stq $2,16($30); \ + stq $3,24($30); \ + stq $4,32($30); \ + stq $5,40($30); \ + stq $6,48($30); \ + stq $7,56($30); \ + stq $8,64($30); \ + stq $19,72($30); \ + stq $20,80($30); \ + stq $21,88($30); \ + stq $22,96($30); \ + stq $23,104($30); \ + stq $24,112($30); \ + stq $25,120($30); \ + stq $26,128($30); \ + stq $27,136($30); \ + stq $28,144($30); \ + lda $2,hae; \ + ldq $2,HAE_CACHE($2); \ + stq $2,152($30) + +#define RESTORE_ALL \ + lda $8,hae; \ + ldq $7,HAE_CACHE($8); \ + ldq $6,152($30); \ + subq $7,$6,$5; \ + beq $5,99f; \ + ldq $7,HAE_REG($8); \ + addq $31,7,$16; \ + call_pal PAL_swpipl; \ + stq $6,HAE_CACHE($8); \ + stq $6,0($7); \ + mb; \ + bis $0,$0,$16; \ + call_pal PAL_swpipl; \ +99:; \ + ldq $0,0($30); \ + ldq $1,8($30); \ + ldq $2,16($30); \ + ldq $3,24($30); \ + ldq $4,32($30); \ + ldq $5,40($30); \ + ldq $6,48($30); \ + ldq $7,56($30); \ + ldq $8,64($30); \ + ldq $19,72($30); \ + ldq $20,80($30); \ + ldq $21,88($30); \ + ldq $22,96($30); \ + ldq $23,104($30); \ + ldq $24,112($30); \ + ldq $25,120($30); \ + ldq $26,128($30); \ + ldq $27,136($30); \ + ldq $28,144($30); \ + addq $30,160,$30 + +.text +.set noat + +.align 3 +.globl entInt +.ent entInt +entInt: + SAVE_ALL +/* start atomic operation with respect to software interrupts */ + lda $0,intr_count + ldq $1,0($0) + addq $1,1,$1 + stq $1,0($0) +/* set up the arguments to the C interrupt handler */ + lda $27,do_entInt + jsr $26,($27),do_entInt +/* ok, check if we need to do software interrupts */ +1: lda $0,intr_count + ldq $1,0($0) + subq $1,1,$1 + bne $1,2f /* interrupt within interrupt: return now */ + lda $2,bh_active + ldq $3,0($2) + lda $2,bh_mask + ldq $2,0($2) + and $2,$3,$2 + bne $2,3f + stq $1,0($0) + br $31,ret_from_sys_call +.align 3 +2: stq $1,0($0) + br $31,restore_all +.align 3 +3: lda $27,do_bottom_half + jsr $26,($27),do_bottom_half + br $31,1b +.end entInt + +.align 3 +.globl entMM +.ent entMM +entMM: + SAVE_ALL + lda $27,do_page_fault + lda $26,ret_from_sys_call + jsr $31,($27),do_page_fault +.end entMM + +.align 3 +.globl entArith +.ent entArith +entArith: + SAVE_ALL + lda $27,do_entArith + lda $26,ret_from_sys_call + jsr $31,($27),do_entArith +.end entArith + +.align 3 +.globl entIF +.ent entIF +entIF: + SAVE_ALL + lda $27,do_entIF + lda $26,ret_from_sys_call + jsr $31,($27),do_entIF +.end entIF + +/* + * Fork() is one of the special system calls: it needs to + * save the callee-saved regs so that the regs can be found + * for the new process.. We save them in the "context switch" + * stack format (see arch/alpha/kernel/process.c). + * + * Also, for the kernel fork, we need to fake the system call + * stack buildup, as we can't do system calls from kernel space. + */ +.align 3 +.globl kernel_fork +.ent kernel_fork +kernel_fork: + subq $30,6*8,$30 + stq $31,0($30) + stq $26,8($30) + stq $29,16($30) + stq $16,24($30) + stq $17,32($30) + stq $18,40($30) + SAVE_ALL + lda $27,sys_fork + jsr $26,($27),sys_fork + br ret_from_sys_call +.end kernel_fork + +.align 3 +.ent do_switch_stack +do_switch_stack: + lda $30,-SWITCH_STACK_SIZE($30) + stq $9,0($30) + stq $10,8($30) + stq $11,16($30) + stq $12,24($30) + stq $13,32($30) + stq $14,40($30) + stq $15,48($30) + stq $26,56($30) + stt $f0,64($30) + stt $f1,72($30) + stt $f2,80($30) + stt $f3,88($30) + stt $f4,96($30) + stt $f5,104($30) + stt $f6,112($30) + stt $f7,120($30) + stt $f8,128($30) + stt $f9,136($30) + stt $f10,144($30) + stt $f11,152($30) + stt $f12,160($30) + stt $f13,168($30) + stt $f14,176($30) + stt $f15,184($30) + stt $f16,192($30) + stt $f17,200($30) + stt $f18,208($30) + stt $f19,216($30) + stt $f20,224($30) + stt $f21,232($30) + stt $f22,240($30) + stt $f23,248($30) + stt $f24,256($30) + stt $f25,264($30) + stt $f26,272($30) + stt $f27,280($30) + stt $f28,288($30) + stt $f29,296($30) + stt $f30,304($30) + ret $31,($0),1 +.end do_switch_stack + +.align 3 +.ent undo_switch_stack +undo_switch_stack: + ldq $9,0($30) + ldq $10,8($30) + ldq $11,16($30) + ldq $12,24($30) + ldq $13,32($30) + ldq $14,40($30) + ldq $15,48($30) + ldq $26,56($30) + ldt $f0,64($30) + ldt $f1,72($30) + ldt $f2,80($30) + ldt $f3,88($30) + ldt $f4,96($30) + ldt $f5,104($30) + ldt $f6,112($30) + ldt $f7,120($30) + ldt $f8,128($30) + ldt $f9,136($30) + ldt $f10,144($30) + ldt $f11,152($30) + ldt $f12,160($30) + ldt $f13,168($30) + ldt $f14,176($30) + ldt $f15,184($30) + ldt $f16,192($30) + ldt $f17,200($30) + ldt $f18,208($30) + ldt $f19,216($30) + ldt $f20,224($30) + ldt $f21,232($30) + ldt $f22,240($30) + ldt $f23,248($30) + ldt $f24,256($30) + ldt $f25,264($30) + ldt $f26,272($30) + ldt $f27,280($30) + ldt $f28,288($30) + ldt $f29,296($30) + ldt $f30,304($30) + lda $30,SWITCH_STACK_SIZE($30) + ret $31,($0),1 +.end undo_switch_stack + +.align 3 +.globl entUna +.ent entUna +entUna: + lda $30,-256($30) + stq $0,0($30) + stq $1,8($30) + stq $2,16($30) + stq $3,24($30) + stq $4,32($30) + stq $5,40($30) + stq $6,48($30) + stq $7,56($30) + stq $8,64($30) + stq $9,72($30) + stq $10,80($30) + stq $11,88($30) + stq $12,96($30) + stq $13,104($30) + stq $14,112($30) + stq $15,120($30) + /* 16-18 PAL-saved */ + stq $19,152($30) + stq $20,160($30) + stq $21,168($30) + stq $22,176($30) + stq $23,184($30) + stq $24,192($30) + stq $25,200($30) + stq $26,208($30) + stq $27,216($30) + stq $28,224($30) + stq $29,232($30) + stq $30,240($30) + stq $31,248($30) + lda $27,do_entUna + jsr $26,($27),do_entUna + ldq $0,0($30) + ldq $1,8($30) + ldq $2,16($30) + ldq $3,24($30) + ldq $4,32($30) + ldq $5,40($30) + ldq $6,48($30) + ldq $7,56($30) + ldq $8,64($30) + ldq $9,72($30) + ldq $10,80($30) + ldq $11,88($30) + ldq $12,96($30) + ldq $13,104($30) + ldq $14,112($30) + ldq $15,120($30) + /* 16-18 PAL-saved */ + ldq $19,152($30) + ldq $20,160($30) + ldq $21,168($30) + ldq $22,176($30) + ldq $23,184($30) + ldq $24,192($30) + ldq $25,200($30) + ldq $26,208($30) + ldq $27,216($30) + ldq $28,224($30) + ldq $29,232($30) + ldq $30,240($30) + lda $30,256($30) + rti +.end entUna + +.align 3 +.globl sys_fork +.ent sys_fork +sys_fork: + br $0,do_switch_stack + bis $30,$30,$16 + lda $27,alpha_fork + jsr $26,($27),alpha_fork + br $0,undo_switch_stack + ldq $0,0($30) + ret $31,($26),1 +.end sys_fork + +.align 3 +.globl alpha_switch_to +.ent alpha_switch_to +alpha_switch_to: + br $0,do_switch_stack + call_pal PAL_swpctx + br $0,undo_switch_stack + ret $31,($26),1 +.end alpha_switch_to + +/* + * Oh, well.. Disassembling OSF/1 binaries to find out how the + * system calls work isn't much fun. + * + * entSys is special in that the PAL-code doesn't save a0-a2, so + * we start off by doing that by hand. + */ +.align 3 +.globl entSys +.globl ret_from_sys_call +.ent entSys +entSys: + stq $16,24($30) + stq $17,32($30) + stq $18,40($30) + SAVE_ALL + lda $1,NR_SYSCALLS($31) + lda $2,sys_call_table + lda $27,do_entSys + cmpult $0,$1,$1 + s8addq $0,$2,$2 + beq $1,1f + ldq $27,0($2) +1: jsr $26,($27),do_entSys + bis $31,$31,$1 + bge $0,2f + bis $31,$31,$26 /* tell "ret_from_sys_call" that we can restart */ + ldq $19,0($30) /* .. with this syscall nr */ + ldq $20,72($30) /* .. and this a3 */ + addq $31,1,$1 /* set a3 for errno return */ + subq $31,$0,$0 /* with error in v0 */ +2: stq $0,0($30) + stq $1,72($30) /* a3 for return */ +.align 3 +ret_from_sys_call: + ldq $0,SP_OFF($30) + cmovne $26,0,$19 + and $0,8,$0 + beq $0,restore_all +ret_from_reschedule: + lda $0,need_resched + lda $1,current + ldl $2,0($0) + lda $4,init_task + ldq $3,0($1) + bne $2,reschedule + subq $4,$3,$4 + beq $4,restore_all + ldq $4,TASK_SIGNAL($3) + ldq $16,TASK_BLOCKED($3) + bic $4,$16,$4 + bne $4,signal_return +restore_all: + RESTORE_ALL + rti +.align 3 +signal_return: + bis $30,$30,$17 + br $0,do_switch_stack + bis $30,$30,$18 + lda $27,do_signal + jsr $26,($27),do_signal + lda $30,SWITCH_STACK_SIZE($30) + br $31,restore_all +.end entSys + +.align 3 +.ent reschedule +reschedule: + subq $30,16,$30 + stq $19,0($30) + stq $20,8($30) + lda $27,schedule + jsr $26,($27),schedule + ldq $19,0($30) + ldq $20,8($30) + addq $30,16,$30 + br $31,ret_from_reschedule +.end reschedule + +.align 3 +.ent sys_sigreturn +sys_sigreturn: + bis $30,$30,$17 + lda $30,-SWITCH_STACK_SIZE($30) + bis $30,$30,$18 + lda $27,do_sigreturn + jsr $26,($27),do_sigreturn + br $0,undo_switch_stack + br $31,ret_from_sys_call +.end sys_sigreturn + +.align 3 +.ent sys_sigsuspend +sys_sigsuspend: + bis $30,$30,$17 + br $0,do_switch_stack + bis $30,$30,$18 + lda $27,do_sigsuspend + jsr $26,($27),do_sigsuspend + lda $30,SWITCH_STACK_SIZE($30) + br $31,ret_from_sys_call +.end sys_sigreturn + + .align 3 + .globl sys_call_table +sys_call_table: +/*0*/ .quad do_entSys, sys_exit, sys_fork, sys_read, sys_write + .quad do_entSys, sys_close, sys_wait4, do_entSys, sys_link + .quad sys_unlink, do_entSys, sys_chdir, sys_fchdir, sys_mknod + .quad sys_chmod, sys_chown, sys_brk, do_entSys, sys_lseek + .quad sys_getxpid, osf_mount, osf_umount, sys_setuid, sys_getxuid + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, sys_access, do_entSys + .quad do_entSys, sys_sync, sys_kill, do_entSys, sys_setpgid + .quad do_entSys, sys_dup, sys_pipe, do_entSys, do_entSys + .quad sys_open, do_entSys, sys_getxgid, osf_sigprocmask, do_entSys +/*50*/ .quad do_entSys, do_entSys, do_entSys, do_entSys, sys_ioctl + .quad do_entSys, do_entSys, sys_symlink, sys_readlink, sys_execve + .quad sys_umask, do_entSys, do_entSys, sys_getpgrp, sys_getpagesize + .quad do_entSys, osf_vfork, sys_newstat, sys_newlstat, do_entSys + .quad do_entSys, osf_mmap, do_entSys, sys_munmap, sys_mprotect + .quad sys_madvise, do_entSys, do_entSys, do_entSys, sys_getgroups + .quad do_entSys, do_entSys, do_entSys, sys_setitimer, do_entSys + .quad do_entSys, sys_getitimer, sys_gethostname, do_entSys, sys_getdtablesize + .quad sys_dup2, sys_newfstat, sys_fcntl, sys_select, do_entSys + .quad sys_fsync, do_entSys, sys_socket, do_entSys, do_entSys +/*100*/ .quad do_entSys, do_entSys, do_entSys, sys_sigreturn, sys_bind + .quad do_entSys, sys_listen, do_entSys, do_entSys, do_entSys + .quad do_entSys, sys_sigsuspend, do_entSys, do_entSys, do_entSys + .quad do_entSys, sys_gettimeofday, sys_getrusage, do_entSys, do_entSys + .quad do_entSys, do_entSys, sys_settimeofday, sys_fchown, sys_fchmod + .quad do_entSys, sys_setreuid, sys_setregid, sys_rename, sys_truncate + .quad sys_ftruncate, do_entSys, sys_setgid, do_entSys, do_entSys + .quad do_entSys, sys_mkdir, sys_rmdir, sys_utimes, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, sys_getrlimit + .quad sys_setrlimit, do_entSys, sys_setsid, do_entSys, do_entSys +/*150*/ .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, sys_sigaction, do_entSys, do_entSys, osf_getdirentries + .quad osf_statfs, osf_fstatfs, do_entSys, do_entSys, do_entSys + .quad osf_getdomainname, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, osf_swapon +/*200*/ .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, osf_utsname, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys +/*250*/ .quad do_entSys, osf_usleep_thread, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys +/* linux-specific system calls start at 300 */ +/*300*/ .quad sys_bdflush, sys_sethae, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys |