Commit 0e7c39d5 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://are.twiddle.net/axp-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 083606d2 1c819f89
...@@ -144,7 +144,6 @@ EXPORT_SYMBOL(pci_dac_dma_to_offset); ...@@ -144,7 +144,6 @@ EXPORT_SYMBOL(pci_dac_dma_to_offset);
EXPORT_SYMBOL(dump_thread); EXPORT_SYMBOL(dump_thread);
EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(dump_fpu);
EXPORT_SYMBOL(hwrpb); EXPORT_SYMBOL(hwrpb);
EXPORT_SYMBOL(wrusp);
EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(start_thread);
EXPORT_SYMBOL(alpha_read_fp_reg); EXPORT_SYMBOL(alpha_read_fp_reg);
EXPORT_SYMBOL(alpha_read_fp_reg_s); EXPORT_SYMBOL(alpha_read_fp_reg_s);
......
...@@ -20,11 +20,22 @@ void foo(void) ...@@ -20,11 +20,22 @@ void foo(void)
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
BLANK(); BLANK();
DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
DEFINE(TASK_UID, offsetof(struct task_struct, uid));
DEFINE(TASK_EUID, offsetof(struct task_struct, euid));
DEFINE(TASK_GID, offsetof(struct task_struct, gid));
DEFINE(TASK_EGID, offsetof(struct task_struct, egid));
DEFINE(TASK_REAL_PARENT, offsetof(struct task_struct, real_parent));
DEFINE(TASK_TGID, offsetof(struct task_struct, tgid));
BLANK();
DEFINE(PT_PTRACED, PT_PTRACED); DEFINE(PT_PTRACED, PT_PTRACED);
DEFINE(CLONE_VM, CLONE_VM); DEFINE(CLONE_VM, CLONE_VM);
DEFINE(CLONE_UNTRACED, CLONE_UNTRACED); DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
DEFINE(SIGCHLD, SIGCHLD); DEFINE(SIGCHLD, SIGCHLD);
BLANK(); BLANK();
DEFINE(HAE_CACHE, offsetof(struct alpha_machine_vector, hae_cache)); DEFINE(HAE_CACHE, offsetof(struct alpha_machine_vector, hae_cache));
DEFINE(HAE_REG, offsetof(struct alpha_machine_vector, hae_register)); DEFINE(HAE_REG, offsetof(struct alpha_machine_vector, hae_register));
} }
/* /*
* alpha/entry.S * arch/alpha/kernel/entry.S
* *
* kernel entry-points * Kernel entry-points.
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <asm/system.h>
#include <asm/cache.h>
#include <asm/asm_offsets.h> #include <asm/asm_offsets.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
#include <asm/pal.h>
#include <asm/errno.h>
#include <asm/unistd.h> #include <asm/unistd.h>
/* .text
* stack offsets .set noat
*/
/* Stack offsets. */
#define SP_OFF 184 #define SP_OFF 184
#define SWITCH_STACK_SIZE 320 #define SWITCH_STACK_SIZE 320
...@@ -28,145 +29,578 @@ ...@@ -28,145 +29,578 @@
*/ */
#define SAVE_ALL \ #define SAVE_ALL \
subq $30,SP_OFF,$30; \ subq $sp, SP_OFF, $sp; \
stq $0,0($30); \ stq $0, 0($sp); \
stq $1,8($30); \ stq $1, 8($sp); \
stq $2,16($30); \ stq $2, 16($sp); \
stq $3,24($30); \ stq $3, 24($sp); \
stq $4,32($30); \ stq $4, 32($sp); \
stq $28,144($30); \ stq $28, 144($sp); \
lda $2,alpha_mv; \ lda $2, alpha_mv; \
stq $5,40($30); \ stq $5, 40($sp); \
stq $6,48($30); \ stq $6, 48($sp); \
stq $7,56($30); \ stq $7, 56($sp); \
stq $8,64($30); \ stq $8, 64($sp); \
stq $19,72($30); \ stq $19, 72($sp); \
stq $20,80($30); \ stq $20, 80($sp); \
stq $21,88($30); \ stq $21, 88($sp); \
ldq $2,HAE_CACHE($2); \ ldq $2, HAE_CACHE($2); \
stq $22,96($30); \ stq $22, 96($sp); \
stq $23,104($30); \ stq $23, 104($sp); \
stq $24,112($30); \ stq $24, 112($sp); \
stq $25,120($30); \ stq $25, 120($sp); \
stq $26,128($30); \ stq $26, 128($sp); \
stq $27,136($30); \ stq $27, 136($sp); \
stq $2,152($30); \ stq $2, 152($sp); \
stq $16,160($30); \ stq $16, 160($sp); \
stq $17,168($30); \ stq $17, 168($sp); \
stq $18,176($30) stq $18, 176($sp)
#define RESTORE_ALL \ #define RESTORE_ALL \
lda $19,alpha_mv; \ lda $19, alpha_mv; \
ldq $0,0($30); \ ldq $0, 0($sp); \
ldq $1,8($30); \ ldq $1, 8($sp); \
ldq $2,16($30); \ ldq $2, 16($sp); \
ldq $3,24($30); \ ldq $3, 24($sp); \
ldq $21,152($30); \ ldq $21, 152($sp); \
ldq $20,HAE_CACHE($19); \ ldq $20, HAE_CACHE($19); \
ldq $4,32($30); \ ldq $4, 32($sp); \
ldq $5,40($30); \ ldq $5, 40($sp); \
ldq $6,48($30); \ ldq $6, 48($sp); \
ldq $7,56($30); \ ldq $7, 56($sp); \
subq $20,$21,$20; \ subq $20, $21, $20; \
ldq $8,64($30); \ ldq $8, 64($sp); \
beq $20,99f; \ beq $20, 99f; \
ldq $20,HAE_REG($19); \ ldq $20, HAE_REG($19); \
stq $21,HAE_CACHE($19); \ stq $21, HAE_CACHE($19); \
stq $21,0($20); \ stq $21, 0($20); \
ldq $0,0($30); \ ldq $0, 0($sp); \
ldq $1,8($30); \ ldq $1, 8($sp); \
99:; \ 99:; \
ldq $19,72($30); \ ldq $19, 72($sp); \
ldq $20,80($30); \ ldq $20, 80($sp); \
ldq $21,88($30); \ ldq $21, 88($sp); \
ldq $22,96($30); \ ldq $22, 96($sp); \
ldq $23,104($30); \ ldq $23, 104($sp); \
ldq $24,112($30); \ ldq $24, 112($sp); \
ldq $25,120($30); \ ldq $25, 120($sp); \
ldq $26,128($30); \ ldq $26, 128($sp); \
ldq $27,136($30); \ ldq $27, 136($sp); \
ldq $28,144($30); \ ldq $28, 144($sp); \
addq $30,SP_OFF,$30 addq $sp, SP_OFF, $sp
.text /*
.set noat * Non-syscall kernel entry points.
*/
.align 3
.globl entInt .align 4
.ent entInt .globl entInt
.ent entInt
entInt: entInt:
SAVE_ALL SAVE_ALL
lda $8,0x3fff lda $8, 0x3fff
lda $26,ret_from_sys_call lda $26, ret_from_sys_call
bic $30,$8,$8 bic $sp, $8, $8
jsr $31,do_entInt mov $sp, $19
jsr $31, do_entInt
.end entInt .end entInt
.align 3 .align 4
.globl entMM .globl entArith
.ent entMM .ent entArith
entArith:
SAVE_ALL
lda $8, 0x3fff
lda $26, ret_from_sys_call
bic $sp, $8, $8
mov $sp, $18
jsr $31, do_entArith
.end entArith
.align 4
.globl entMM
.ent entMM
entMM: entMM:
SAVE_ALL SAVE_ALL
/* save $9 - $15 so the inline exception code can manipulate them. */ /* save $9 - $15 so the inline exception code can manipulate them. */
subq $30,56,$30 subq $sp, 56, $sp
stq $9,0($30) stq $9, 0($sp)
stq $10,8($30) stq $10, 8($sp)
stq $11,16($30) stq $11, 16($sp)
stq $12,24($30) stq $12, 24($sp)
stq $13,32($30) stq $13, 32($sp)
stq $14,40($30) stq $14, 40($sp)
stq $15,48($30) stq $15, 48($sp)
addq $30,56,$19 addq $sp, 56, $19
/* handle the fault */ /* handle the fault */
lda $8,0x3fff lda $8, 0x3fff
bic $30,$8,$8 bic $sp, $8, $8
jsr $26,do_page_fault jsr $26, do_page_fault
/* reload the registers after the exception code played. */ /* reload the registers after the exception code played. */
ldq $9,0($30) ldq $9, 0($sp)
ldq $10,8($30) ldq $10, 8($sp)
ldq $11,16($30) ldq $11, 16($sp)
ldq $12,24($30) ldq $12, 24($sp)
ldq $13,32($30) ldq $13, 32($sp)
ldq $14,40($30) ldq $14, 40($sp)
ldq $15,48($30) ldq $15, 48($sp)
addq $30,56,$30 addq $sp, 56, $sp
/* finish up the syscall as normal. */ /* finish up the syscall as normal. */
br ret_from_sys_call br ret_from_sys_call
.end entMM .end entMM
.align 3 .align 4
.globl entArith .globl entIF
.ent entArith .ent entIF
entArith:
SAVE_ALL
lda $8,0x3fff
lda $26,ret_from_sys_call
bic $30,$8,$8
jsr $31,do_entArith
.end entArith
.align 3
.globl entIF
.ent entIF
entIF: entIF:
SAVE_ALL SAVE_ALL
lda $8,0x3fff lda $8, 0x3fff
lda $26,ret_from_sys_call lda $26, ret_from_sys_call
bic $30,$8,$8 bic $sp, $8, $8
jsr $31,do_entIF mov $sp, $17
jsr $31, do_entIF
.end entIF .end entIF
.align 3 .align 4
.globl entDbg .globl entUna
.ent entDbg .ent entUna
entUna:
lda $sp, -256($sp)
stq $0, 0($sp)
ldq $0, 256($sp) /* get PS */
stq $1, 8($sp)
stq $2, 16($sp)
stq $3, 24($sp)
and $0, 8, $0 /* user mode? */
stq $4, 32($sp)
bne $0, entUnaUser /* yup -> do user-level unaligned fault */
stq $5, 40($sp)
stq $6, 48($sp)
stq $7, 56($sp)
stq $8, 64($sp)
stq $9, 72($sp)
stq $10, 80($sp)
stq $11, 88($sp)
stq $12, 96($sp)
stq $13, 104($sp)
stq $14, 112($sp)
stq $15, 120($sp)
/* 16-18 PAL-saved */
stq $19, 152($sp)
stq $20, 160($sp)
stq $21, 168($sp)
stq $22, 176($sp)
stq $23, 184($sp)
stq $24, 192($sp)
stq $25, 200($sp)
stq $26, 208($sp)
stq $27, 216($sp)
stq $28, 224($sp)
stq $gp, 232($sp)
lda $8, 0x3fff
stq $31, 248($sp)
bic $sp, $8, $8
jsr $26, do_entUna
ldq $0, 0($sp)
ldq $1, 8($sp)
ldq $2, 16($sp)
ldq $3, 24($sp)
ldq $4, 32($sp)
ldq $5, 40($sp)
ldq $6, 48($sp)
ldq $7, 56($sp)
ldq $8, 64($sp)
ldq $9, 72($sp)
ldq $10, 80($sp)
ldq $11, 88($sp)
ldq $12, 96($sp)
ldq $13, 104($sp)
ldq $14, 112($sp)
ldq $15, 120($sp)
/* 16-18 PAL-saved */
ldq $19, 152($sp)
ldq $20, 160($sp)
ldq $21, 168($sp)
ldq $22, 176($sp)
ldq $23, 184($sp)
ldq $24, 192($sp)
ldq $25, 200($sp)
ldq $26, 208($sp)
ldq $27, 216($sp)
ldq $28, 224($sp)
ldq $gp, 232($sp)
lda $sp, 256($sp)
call_pal PAL_rti
.end entUna
.align 4
.ent entUnaUser
entUnaUser:
ldq $0, 0($sp) /* restore original $0 */
lda $sp, 256($sp) /* pop entUna's stack frame */
SAVE_ALL /* setup normal kernel stack */
lda $sp, -56($sp)
stq $9, 0($sp)
stq $10, 8($sp)
stq $11, 16($sp)
stq $12, 24($sp)
stq $13, 32($sp)
stq $14, 40($sp)
stq $15, 48($sp)
lda $8, 0x3fff
addq $sp, 56, $19
bic $sp, $8, $8
jsr $26, do_entUnaUser
ldq $9, 0($sp)
ldq $10, 8($sp)
ldq $11, 16($sp)
ldq $12, 24($sp)
ldq $13, 32($sp)
ldq $14, 40($sp)
ldq $15, 48($sp)
lda $sp, 56($sp)
br ret_from_sys_call
.end entUnaUser
.align 4
.globl entDbg
.ent entDbg
entDbg: entDbg:
SAVE_ALL SAVE_ALL
lda $8,0x3fff lda $8, 0x3fff
lda $26,ret_from_sys_call lda $26, ret_from_sys_call
bic $30,$8,$8 bic $sp, $8, $8
jsr $31,do_entDbg mov $sp, $16
jsr $31, do_entDbg
.end entDbg .end entDbg
/*
* The system call entry point is special. Most importantly, it looks
* like a function call to userspace as far as clobbered registers. We
* do preserve the argument registers (for syscall restarts) and $26
* (for leaf syscall functions).
*
* So much for theory. We don't take advantage of this yet.
*
* Note that a0-a2 are not saved by PALcode as with the other entry points.
*/
.align 4
.globl entSys
.globl ret_from_sys_call
.ent entSys
entSys:
SAVE_ALL
lda $8, 0x3fff
bic $sp, $8, $8
lda $4, NR_SYSCALLS($31)
stq $16, SP_OFF+24($sp)
lda $5, sys_call_table
lda $27, sys_ni_syscall
cmpult $0, $4, $4
ldl $3, TI_FLAGS($8)
stq $17, SP_OFF+32($sp)
s8addq $0, $5, $5
stq $18, SP_OFF+40($sp)
blbs $3, strace
beq $4, 1f
ldq $27, 0($5)
1: jsr $26, ($27), alpha_ni_syscall
ldgp $gp, 0($26)
blt $0, $syscall_error /* the call failed */
stq $0, 0($sp)
stq $31, 72($sp) /* a3=0 => no error */
.align 4
ret_from_sys_call:
cmovne $26, 0, $19 /* $19 = 0 => non-restartable */
ldq $0, SP_OFF($sp)
and $0, 8, $0
beq $0, restore_all
ret_from_reschedule:
/* Make sure need_resched and sigpending don't change between
sampling and the rti. */
lda $16, 7
call_pal PAL_swpipl
ldl $5, TI_FLAGS($8)
and $5, _TIF_WORK_MASK, $2
bne $5, work_pending
restore_all:
RESTORE_ALL
call_pal PAL_rti
.align 3
$syscall_error:
/*
* Some system calls (e.g., ptrace) can return arbitrary
* values which might normally be mistaken as error numbers.
* Those functions must zero $0 (v0) directly in the stack
* frame to indicate that a negative return value wasn't an
* error number..
*/
ldq $19, 0($sp) /* old syscall nr (zero if success) */
beq $19, $ret_success
ldq $20, 72($sp) /* .. and this a3 */
subq $31, $0, $0 /* with error in v0 */
addq $31, 1, $1 /* set a3 for errno return */
stq $0, 0($sp)
mov $31, $26 /* tell "ret_from_sys_call" we can restart */
stq $1, 72($sp) /* a3 for return */
br ret_from_sys_call
$ret_success:
stq $0, 0($sp)
stq $31, 72($sp) /* a3=0 => no error */
br ret_from_sys_call
.end entSys
/*
* Do all cleanup when returning from all interrupts and system calls.
*
* Arguments:
* $5: TI_FLAGS.
* $8: current.
* $19: The old syscall number, or zero if this is not a return
* from a syscall that errored and is possibly restartable.
* $20: Error indication.
*/
.align 4
.ent work_pending
work_pending:
and $5, _TIF_NEED_RESCHED, $2
beq $2, $work_notifysig
$work_resched:
subq $sp, 16, $sp
stq $19, 0($sp) /* save syscall nr */
stq $20, 8($sp) /* and error indication (a3) */
jsr $26, schedule
ldq $19, 0($sp)
ldq $20, 8($sp)
addq $sp, 16, $sp
/* Make sure need_resched and sigpending don't change between
sampling and the rti. */
lda $16, 7
call_pal PAL_swpipl
ldl $5, TI_FLAGS($8)
and $5, _TIF_WORK_MASK, $2
beq $2, restore_all
and $5, _TIF_NEED_RESCHED, $2
bne $2, $work_resched
$work_notifysig:
mov $sp, $17
br $1, do_switch_stack
mov $5, $21
mov $sp, $18
mov $31, $16
jsr $26, do_notify_resume
bsr $1, undo_switch_stack
br restore_all
.end work_pending
/*
* PTRACE syscall handler
*/
.align 4
.ent strace
strace:
/* set up signal stack, call syscall_trace */
bsr $1, do_switch_stack
jsr $26, syscall_trace
bsr $1, undo_switch_stack
/* get the system call number and the arguments back.. */
ldq $0, 0($sp)
ldq $16, SP_OFF+24($sp)
ldq $17, SP_OFF+32($sp)
ldq $18, SP_OFF+40($sp)
ldq $19, 72($sp)
ldq $20, 80($sp)
ldq $21, 88($sp)
/* get the system call pointer.. */
lda $1, NR_SYSCALLS($31)
lda $2, sys_call_table
lda $27, alpha_ni_syscall
cmpult $0, $1, $1
s8addq $0, $2, $2
beq $1, 1f
ldq $27, 0($2)
1: jsr $26, ($27), sys_gettimeofday
ldgp $gp, 0($26)
/* check return.. */
blt $0, $strace_error /* the call failed */
stq $31, 72($sp) /* a3=0 => no error */
$strace_success:
stq $0, 0($sp) /* save return value */
bsr $1, do_switch_stack
jsr $26, syscall_trace
bsr $1, undo_switch_stack
br $31, ret_from_sys_call
.align 3
$strace_error:
ldq $19, 0($sp) /* old syscall nr (zero if success) */
beq $19, $strace_success
ldq $20, 72($sp) /* .. and this a3 */
subq $31, $0, $0 /* with error in v0 */
addq $31, 1, $1 /* set a3 for errno return */
stq $0, 0($sp)
stq $1, 72($sp) /* a3 for return */
bsr $1, do_switch_stack
mov $19, $9 /* save old syscall number */
mov $20, $10 /* save old a3 */
jsr $26, syscall_trace
mov $9, $19
mov $10, $20
bsr $1, undo_switch_stack
mov $31, $26 /* tell "ret_from_sys_call" we can restart */
br ret_from_sys_call
.end strace
/*
* Save and restore the switch stack -- aka the balance of the user context.
*/
.align 4
.ent do_switch_stack
do_switch_stack:
lda $sp, -SWITCH_STACK_SIZE($sp)
stq $9, 0($sp)
stq $10, 8($sp)
stq $11, 16($sp)
stq $12, 24($sp)
stq $13, 32($sp)
stq $14, 40($sp)
stq $15, 48($sp)
stq $26, 56($sp)
stt $f0, 64($sp)
stt $f1, 72($sp)
stt $f2, 80($sp)
stt $f3, 88($sp)
stt $f4, 96($sp)
stt $f5, 104($sp)
stt $f6, 112($sp)
stt $f7, 120($sp)
stt $f8, 128($sp)
stt $f9, 136($sp)
stt $f10, 144($sp)
stt $f11, 152($sp)
stt $f12, 160($sp)
stt $f13, 168($sp)
stt $f14, 176($sp)
stt $f15, 184($sp)
stt $f16, 192($sp)
stt $f17, 200($sp)
stt $f18, 208($sp)
stt $f19, 216($sp)
stt $f20, 224($sp)
stt $f21, 232($sp)
stt $f22, 240($sp)
stt $f23, 248($sp)
stt $f24, 256($sp)
stt $f25, 264($sp)
stt $f26, 272($sp)
stt $f27, 280($sp)
mf_fpcr $f0 # get fpcr
stt $f28, 288($sp)
stt $f29, 296($sp)
stt $f30, 304($sp)
stt $f0, 312($sp) # save fpcr in slot of $f31
ldt $f0, 64($sp) # dont let "do_switch_stack" change fp state.
ret $31, ($1), 1
.end do_switch_stack
.align 4
.ent undo_switch_stack
undo_switch_stack:
ldq $9, 0($sp)
ldq $10, 8($sp)
ldq $11, 16($sp)
ldq $12, 24($sp)
ldq $13, 32($sp)
ldq $14, 40($sp)
ldq $15, 48($sp)
ldq $26, 56($sp)
ldt $f30, 312($sp) # get saved fpcr
ldt $f0, 64($sp)
ldt $f1, 72($sp)
ldt $f2, 80($sp)
ldt $f3, 88($sp)
mt_fpcr $f30 # install saved fpcr
ldt $f4, 96($sp)
ldt $f5, 104($sp)
ldt $f6, 112($sp)
ldt $f7, 120($sp)
ldt $f8, 128($sp)
ldt $f9, 136($sp)
ldt $f10, 144($sp)
ldt $f11, 152($sp)
ldt $f12, 160($sp)
ldt $f13, 168($sp)
ldt $f14, 176($sp)
ldt $f15, 184($sp)
ldt $f16, 192($sp)
ldt $f17, 200($sp)
ldt $f18, 208($sp)
ldt $f19, 216($sp)
ldt $f20, 224($sp)
ldt $f21, 232($sp)
ldt $f22, 240($sp)
ldt $f23, 248($sp)
ldt $f24, 256($sp)
ldt $f25, 264($sp)
ldt $f26, 272($sp)
ldt $f27, 280($sp)
ldt $f28, 288($sp)
ldt $f29, 296($sp)
ldt $f30, 304($sp)
lda $sp, SWITCH_STACK_SIZE($sp)
ret $31, ($1), 1
.end undo_switch_stack
/*
* The meat of the context switch code.
*/
.align 4
.globl alpha_switch_to
.ent alpha_switch_to
alpha_switch_to:
.prologue 0
bsr $1, do_switch_stack
call_pal PAL_swpctx
lda $8, 0x3fff
bsr $1, undo_switch_stack
bic $sp, $8, $8
ret
.end alpha_switch_to
/*
* New processes begin life here.
*/
.globl ret_from_fork
#if CONFIG_SMP || CONFIG_PREEMPT
.align 4
.ent ret_from_fork
ret_from_fork:
lda $26, ret_from_sys_call
mov $17, $16
jmp $31, schedule_tail
.end ret_from_fork
#else
ret_from_fork = ret_from_sys_call
#endif
/* /*
* kernel_thread(fn, arg, clone_flags) * kernel_thread(fn, arg, clone_flags)
...@@ -175,9 +609,9 @@ entDbg: ...@@ -175,9 +609,9 @@ entDbg:
.globl kernel_thread .globl kernel_thread
.ent kernel_thread .ent kernel_thread
kernel_thread: kernel_thread:
ldgp $29,0($27) /* we can be called from a module */ ldgp $gp, 0($27) /* we can be called from a module */
.prologue 1 .prologue 1
subq $30,SP_OFF+6*8,$30 subq $sp, SP_OFF+6*8, $sp
br $1, 2f /* load start address */ br $1, 2f /* load start address */
/* We've now "returned" from a fake system call. */ /* We've now "returned" from a fake system call. */
...@@ -186,9 +620,9 @@ kernel_thread: ...@@ -186,9 +620,9 @@ kernel_thread:
ldi $1, 0x3fff ldi $1, 0x3fff
beq $20, 1f /* parent or child? */ beq $20, 1f /* parent or child? */
bic $30, $1, $8 /* in child. */ bic $sp, $1, $8 /* in child. */
jsr $26, ($27) jsr $26, ($27)
ldgp $29, 0($26) ldgp $gp, 0($26)
mov $0, $16 mov $0, $16
mov $31, $26 mov $31, $26
jmp $31, sys_exit jmp $31, sys_exit
...@@ -197,19 +631,19 @@ kernel_thread: ...@@ -197,19 +631,19 @@ kernel_thread:
.align 4 .align 4
2: /* Fake a system call stack frame, as we can't do system calls 2: /* Fake a system call stack frame, as we can't do system calls
from kernel space. Note that we store FN and ARG as they from kernel space. Note that we store FN and ARG as they
need to be set up in the child for the call. Also store $8 need to be set up in the child for the call. Also store $8
and $26 for use in the parent. */ and $26 for use in the parent. */
stq $31, SP_OFF($30) /* ps */ stq $31, SP_OFF($sp) /* ps */
stq $1, SP_OFF+8($30) /* pc */ stq $1, SP_OFF+8($sp) /* pc */
stq $29, SP_OFF+16($30) /* gp */ stq $gp, SP_OFF+16($sp) /* gp */
stq $16, 136($30) /* $27; FN for child */ stq $16, 136($sp) /* $27; FN for child */
stq $17, SP_OFF+24($30) /* $16; ARG for child */ stq $17, SP_OFF+24($sp) /* $16; ARG for child */
stq $8, 64($30) /* $8 */ stq $8, 64($sp) /* $8 */
stq $26, 128($30) /* $26 */ stq $26, 128($sp) /* $26 */
/* Avoid the HAE being gratuitously wrong, to avoid restoring it. */ /* Avoid the HAE being gratuitously wrong, to avoid restoring it. */
ldq $2, alpha_mv+HAE_CACHE ldq $2, alpha_mv+HAE_CACHE
stq $2, 152($30) /* HAE */ stq $2, 152($sp) /* HAE */
/* Shuffle FLAGS to the front; add CLONE_VM. */ /* Shuffle FLAGS to the front; add CLONE_VM. */
ldi $1, CLONE_VM|CLONE_UNTRACED ldi $1, CLONE_VM|CLONE_UNTRACED
...@@ -218,515 +652,269 @@ kernel_thread: ...@@ -218,515 +652,269 @@ kernel_thread:
/* We don't actually care for a3 success widgetry in the kernel. /* We don't actually care for a3 success widgetry in the kernel.
Not for positive errno values. */ Not for positive errno values. */
stq $0, 0($30) /* $0 */ stq $0, 0($sp) /* $0 */
br restore_all br restore_all
.end kernel_thread .end kernel_thread
/* /*
* __kernel_execve(path, argv, envp, regs) * __kernel_execve(path, argv, envp, regs)
*/ */
.align 3 .align 4
.globl __kernel_execve .globl __kernel_execve
.ent __kernel_execve .ent __kernel_execve
__kernel_execve: __kernel_execve:
ldgp $29,0($27) /* we can be called from modules. */ ldgp $gp, 0($27) /* we can be called from modules. */
subq $30,16,$30 subq $sp, 16, $sp
.frame $30,16,$26,0 .frame $sp, 16, $26, 0
stq $26,0($30) stq $26, 0($sp)
stq $19,8($30) stq $19, 8($sp)
.prologue 1 .prologue 1
jsr $26,do_execve jsr $26, do_execve
bne $0,1f /* error! */ bne $0, 1f /* error! */
ldq $30,8($30) ldq $sp, 8($sp)
br $31,ret_from_sys_call br $31, ret_from_sys_call
1: ldq $26,0($30) 1: ldq $26, 0($sp)
addq $30,16,$30 addq $sp, 16, $sp
ret ret
.end __kernel_execve .end __kernel_execve
.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)
mf_fpcr $f0 # get fpcr
stt $f28,288($30)
stt $f29,296($30)
stt $f30,304($30)
stt $f0,312($30) # save fpcr in slot of $f31
ldt $f0,64($30) # dont let "do_switch_stack" change fp state.
ret $31,($1),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 $f30,312($30) # get saved fpcr
ldt $f0,64($30)
ldt $f1,72($30)
ldt $f2,80($30)
ldt $f3,88($30)
mt_fpcr $f30 # install saved fpcr
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,($1),1
.end undo_switch_stack
.align 3
.globl entUna
.ent entUna
entUna:
lda $30,-256($30)
stq $0,0($30)
ldq $0,256($30) /* get PS */
stq $1,8($30)
stq $2,16($30)
stq $3,24($30)
and $0,8,$0 /* user mode? */
stq $4,32($30)
bne $0,entUnaUser /* yup -> do user-level unaligned fault */
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)
lda $8,0x3fff
stq $31,248($30)
bic $30,$8,$8
jsr $26,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)
lda $30,256($30)
call_pal PAL_rti
.end entUna
.align 3
.ent entUnaUser
entUnaUser:
ldq $0,0($30) /* restore original $0 */
lda $30,256($30) /* pop entUna's stack frame */
SAVE_ALL /* setup normal kernel stack */
lda $30,-56($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)
lda $8,0x3fff
addq $30,56,$19
bic $30,$8,$8
jsr $26,do_entUnaUser
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)
lda $30,56($30)
br ret_from_sys_call
.end entUnaUser
/* /*
* A fork is the same as clone(SIGCHLD, 0); * Special system calls. Most of these are special in that they either
* have to play switch_stack games or in some way use the pt_regs struct.
*/ */
.align 3 .align 4
.globl sys_fork .globl sys_fork
.ent sys_fork .ent sys_fork
sys_fork: sys_fork:
bsr $1,do_switch_stack .prologue 0
bis $31,SIGCHLD,$16 mov $sp, $19
mov $31,$17 bsr $1, do_switch_stack
mov $31,$18 /* A fork is the same as clone(SIGCHLD, 0); */
mov $30,$19 bis $31, SIGCHLD, $16
jsr $26,alpha_clone mov $31, $17
bsr $1,undo_switch_stack mov $31, $18
ret $31,($26),1 jsr $26, alpha_clone
.end sys_fork bsr $1, undo_switch_stack
ret
.align 3 .end sys_fork
.globl sys_clone
.ent sys_clone .align 4
.globl sys_clone
.ent sys_clone
sys_clone: sys_clone:
bsr $1,do_switch_stack .prologue 0
mov $sp, $19
bsr $1, do_switch_stack
/* $16, $17, $18, $19 come from the user; $19 is used later /* $16, $17, $18, $19 come from the user; $19 is used later
via pt_regs->r19. */ via pt_regs->r19. */
mov $30,$19 jsr $26, alpha_clone
jsr $26,alpha_clone bsr $1, undo_switch_stack
bsr $1,undo_switch_stack ret
ret $31,($26),1 .end sys_clone
.end sys_clone
.align 4
.align 3 .globl sys_vfork
.globl sys_vfork .ent sys_vfork
.ent sys_vfork
sys_vfork: sys_vfork:
bsr $1,do_switch_stack
mov $30,$16
jsr $26,alpha_vfork
bsr $1,undo_switch_stack
ret $31,($26),1
.end sys_vfork
.align 3
.globl alpha_switch_to
.ent alpha_switch_to
alpha_switch_to:
.prologue 0 .prologue 0
bsr $1,do_switch_stack bsr $1, do_switch_stack
call_pal PAL_swpctx mov $sp, $16
lda $8,0x3fff jsr $26, alpha_vfork
bsr $1,undo_switch_stack bsr $1, undo_switch_stack
bic $30,$8,$8 ret
ret $31,($26),1 .end sys_vfork
.end alpha_switch_to
#if CONFIG_SMP || CONFIG_PREEMPT .align 4
.globl ret_from_fork .globl sys_sigreturn
.align 3 .ent sys_sigreturn
.ent ret_from_fork sys_sigreturn:
ret_from_fork: .prologue 0
lda $26,ret_from_sys_call mov $sp, $17
mov $17,$16 lda $18, -SWITCH_STACK_SIZE($sp)
jmp $31,schedule_tail lda $sp, -SWITCH_STACK_SIZE($sp)
.end ret_from_fork jsr $26, do_sigreturn
#endif br $1, undo_switch_stack
br ret_from_sys_call
.end sys_sigreturn
/* .align 4
* Oh, well.. Disassembling OSF/1 binaries to find out how the .globl sys_rt_sigreturn
* system calls work isn't much fun. .ent sys_rt_sigreturn
* sys_rt_sigreturn:
* entSys is special in that the PAL-code doesn't save a0-a2, so .prologue 0
* we start off by doing that by hand. mov $sp, $17
*/ lda $18, -SWITCH_STACK_SIZE($sp)
.align 3 lda $sp, -SWITCH_STACK_SIZE($sp)
.globl entSys jsr $26, do_rt_sigreturn
.globl ret_from_sys_call br $1, undo_switch_stack
.ent entSys br ret_from_sys_call
entSys: .end sys_rt_sigreturn
SAVE_ALL
lda $8,0x3fff
bic $30,$8,$8
lda $4,NR_SYSCALLS($31)
stq $16,SP_OFF+24($30)
lda $5,sys_call_table
lda $27,sys_ni_syscall
cmpult $0,$4,$4
ldl $3,TI_FLAGS($8)
stq $17,SP_OFF+32($30)
s8addq $0,$5,$5
stq $18,SP_OFF+40($30)
blbs $3,strace
beq $4,1f
ldq $27,0($5)
1: jsr $26,($27),alpha_ni_syscall
ldgp $29,0($26)
blt $0,syscall_error /* the call failed */
stq $0,0($30)
stq $31,72($30) /* a3=0 => no error */
.align 3
ret_from_sys_call:
cmovne $26,0,$19 /* $19 = 0 => non-restartable */
ldq $0,SP_OFF($30)
and $0,8,$0
beq $0,restore_all
ret_from_reschedule:
/* Make sure need_resched and sigpending don't change between
sampling and the rti. */
lda $16,7
call_pal PAL_swpipl
ldl $5,TI_FLAGS($8)
and $5,_TIF_WORK_MASK,$2
bne $5,work_pending
restore_all:
RESTORE_ALL
call_pal PAL_rti
work_pending: .align 4
and $5,_TIF_NEED_RESCHED,$2 .globl sys_sigsuspend
beq $2,work_notifysig .ent sys_sigsuspend
sys_sigsuspend:
work_resched: .prologue 0
subq $30,16,$30 mov $sp, $17
stq $19,0($30) /* save syscall nr */ br $1, do_switch_stack
stq $20,8($30) /* and error indication (a3) */ mov $sp, $18
jsr $26,schedule subq $sp, 16, $sp
ldq $19,0($30) stq $26, 0($sp)
ldq $20,8($30) jsr $26, do_sigsuspend
addq $30,16,$30 ldq $26, 0($sp)
/* Make sure need_resched and sigpending don't change between lda $sp, SWITCH_STACK_SIZE+16($sp)
sampling and the rti. */ ret
lda $16,7 .end sys_sigsuspend
call_pal PAL_swpipl
ldl $5,TI_FLAGS($8)
and $5,_TIF_WORK_MASK,$2
beq $2,restore_all
and $5,_TIF_NEED_RESCHED,$2
bne $2,work_resched
work_notifysig:
mov $30,$17
br $1,do_switch_stack
mov $5,$21
mov $30,$18
mov $31,$16
jsr $26,do_notify_resume
bsr $1,undo_switch_stack
br restore_all
/* PTRACE syscall handler */ .align 4
.align 3 .globl sys_rt_sigsuspend
strace: .ent sys_rt_sigsuspend
/* set up signal stack, call syscall_trace */ sys_rt_sigsuspend:
bsr $1,do_switch_stack .prologue 0
jsr $26,syscall_trace mov $sp, $18
bsr $1,undo_switch_stack br $1, do_switch_stack
mov $sp, $19
subq $sp, 16, $sp
stq $26, 0($sp)
jsr $26, do_rt_sigsuspend
ldq $26, 0($sp)
lda $sp, SWITCH_STACK_SIZE+16($sp)
ret
.end sys_rt_sigsuspend
/* get the system call number and the arguments back.. */ .align 4
ldq $0,0($30) .globl sys_sethae
ldq $16,SP_OFF+24($30) .ent sys_sethae
ldq $17,SP_OFF+32($30) sys_sethae:
ldq $18,SP_OFF+40($30) .prologue 0
ldq $19,72($30) stq $16, 152($sp)
ldq $20,80($30) ret
ldq $21,88($30) .end sys_sethae
.align 4
.globl osf_getpriority
.ent osf_getpriority
osf_getpriority:
lda $sp, -16($sp)
stq $26, 0($sp)
.prologue 0
/* get the system call pointer.. */ jsr $26, sys_getpriority
lda $1,NR_SYSCALLS($31)
lda $2,sys_call_table
lda $27,alpha_ni_syscall
cmpult $0,$1,$1
s8addq $0,$2,$2
beq $1,1f
ldq $27,0($2)
1: jsr $26,($27),sys_gettimeofday
ldgp $29,0($26)
/* check return.. */ ldq $26, 0($sp)
blt $0,strace_error /* the call failed */ blt $0, 1f
stq $31,72($30) /* a3=0 => no error */
strace_success:
stq $0,0($30) /* save return value */
bsr $1,do_switch_stack /* Return value is the unbiased priority, i.e. 20 - prio.
jsr $26,syscall_trace This does result in negative return values, so signal
bsr $1,undo_switch_stack no error by writing into the R0 slot. */
br $31,ret_from_sys_call lda $1, 20
stq $31, 16($sp)
subl $1, $0, $0
unop
.align 3 1: lda $sp, 16($sp)
strace_error: ret
ldq $19,0($30) /* old syscall nr (zero if success) */ .end osf_getpriority
beq $19,strace_success
ldq $20,72($30) /* .. and this a3 */
subq $31,$0,$0 /* with error in v0 */
addq $31,1,$1 /* set a3 for errno return */
stq $0,0($30)
stq $1,72($30) /* a3 for return */
bsr $1,do_switch_stack
mov $19,$9 /* save old syscall number */
mov $20,$10 /* save old a3 */
jsr $26,syscall_trace
mov $9,$19
mov $10,$20
bsr $1,undo_switch_stack
mov $31,$26 /* tell "ret_from_sys_call" we can restart */
br ret_from_sys_call
.align 3 .align 4
syscall_error: .globl sys_getxuid
/* .ent sys_getxuid
* Some system calls (e.g., ptrace) can return arbitrary sys_getxuid:
* values which might normally be mistaken as error numbers. .prologue 0
* Those functions must zero $0 (v0) directly in the stack ldq $2, TI_TASK($8)
* frame to indicate that a negative return value wasn't an ldl $0, TASK_UID($2)
* error number.. ldl $1, TASK_EUID($2)
*/ stq $1, 80($sp)
ldq $19,0($30) /* old syscall nr (zero if success) */ ret
beq $19,ret_success .end sys_getxuid
ldq $20,72($30) /* .. and this a3 */
subq $31,$0,$0 /* with error in v0 */
addq $31,1,$1 /* set a3 for errno return */
stq $0,0($30)
mov $31,$26 /* tell "ret_from_sys_call" we can restart */
stq $1,72($30) /* a3 for return */
br ret_from_sys_call
ret_success: .align 4
stq $0,0($30) .globl sys_getxgid
stq $31,72($30) /* a3=0 => no error */ .ent sys_getxgid
br ret_from_sys_call sys_getxgid:
.end entSys .prologue 0
ldq $2, TI_TASK($8)
ldl $0, TASK_GID($2)
ldl $1, TASK_EGID($2)
stq $1, 80($sp)
ret
.end sys_getxgid
.align 3 .align 4
.globl sys_sigreturn .globl sys_getxpid
.ent sys_sigreturn .ent sys_getxpid
sys_sigreturn: sys_getxpid:
mov $30,$17 .prologue 0
lda $18,-SWITCH_STACK_SIZE($30) ldq $2, TI_TASK($8)
lda $30,-SWITCH_STACK_SIZE($30)
jsr $26,do_sigreturn /* See linux/kernel/timer.c sys_getppid for discussion
br $1,undo_switch_stack about this loop. */
br ret_from_sys_call ldq $3, TASK_REAL_PARENT($2)
.end sys_sigreturn 1: ldl $1, TASK_TGID($3)
#if CONFIG_SMP
mov $3, $4
mb
ldq $3, TASK_REAL_PARENT($2)
cmpeq $3, $4, $4
beq $4, 1b
#endif
stq $1, 80($sp)
ldl $0, TASK_TGID($2)
ret
.end sys_getxpid
.align 4
.globl sys_pipe
.ent sys_pipe
sys_pipe:
lda $sp, -16($sp)
stq $26, 0($sp)
.prologue 0
.align 3 lda $16, 8($sp)
.globl sys_rt_sigreturn jsr $26, do_pipe
.ent sys_rt_sigreturn
sys_rt_sigreturn:
mov $30,$17
lda $18,-SWITCH_STACK_SIZE($30)
lda $30,-SWITCH_STACK_SIZE($30)
jsr $26,do_rt_sigreturn
br $1,undo_switch_stack
br ret_from_sys_call
.end sys_rt_sigreturn
.align 3 ldq $26, 0($sp)
.globl sys_sigsuspend bne $0, 1f
.ent sys_sigsuspend
sys_sigsuspend:
mov $30,$17
br $1,do_switch_stack
mov $30,$18
subq $30,16,$30
stq $26,0($30)
jsr $26,do_sigsuspend
ldq $26,0($30)
lda $30,SWITCH_STACK_SIZE+16($30)
ret $31,($26),1
.end sys_sigsuspend
.align 3 /* The return values are in $0 and $20. */
.globl sys_rt_sigsuspend ldl $1, 12($sp)
.ent sys_rt_sigsuspend ldl $0, 8($sp)
sys_rt_sigsuspend:
mov $30,$18 stq $1, 80+16($sp)
br $1,do_switch_stack 1: lda $sp, 16($sp)
mov $30,$19 ret
subq $30,16,$30 .end sys_pipe
stq $26,0($30)
jsr $26,do_rt_sigsuspend .align 4
ldq $26,0($30) .globl alpha_create_module
lda $30,SWITCH_STACK_SIZE+16($30) .ent alpha_create_module
ret $31,($26),1 alpha_create_module:
.end sys_rt_sigsuspend .prologue 0
mov $sp, $18
jmp $31, do_alpha_create_module
.end alpha_create_module
.align 4
.globl sys_ptrace
.ent sys_ptrace
sys_ptrace:
.prologue 0
mov $sp, $20
jmp $31, do_sys_ptrace
.end sys_ptrace
.align 4
.globl alpha_ni_syscall
.ent alpha_ni_syscall
alpha_ni_syscall:
.prologue 0
/* Special because it also implements overflow handling via
syscall number 0. And if you recall, zero is a special
trigger for "not an error". Store large non-zero there. */
lda $0, -ENOSYS
unop
stq $0, 0($sp)
ret
.end alpha_ni_syscall
...@@ -37,14 +37,13 @@ void (*perf_irq)(unsigned long, struct pt_regs *) = dummy_perf; ...@@ -37,14 +37,13 @@ void (*perf_irq)(unsigned long, struct pt_regs *) = dummy_perf;
*/ */
asmlinkage void asmlinkage void
do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr, do_entInt(unsigned long type, unsigned long vector,
unsigned long a3, unsigned long a4, unsigned long a5, unsigned long la_ptr, struct pt_regs *regs)
struct pt_regs regs)
{ {
switch (type) { switch (type) {
case 0: case 0:
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
handle_ipi(&regs); handle_ipi(regs);
return; return;
#else #else
irq_err_count++; irq_err_count++;
...@@ -56,32 +55,32 @@ do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr, ...@@ -56,32 +55,32 @@ do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr,
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
{ {
long cpu; long cpu;
smp_percpu_timer_interrupt(&regs); smp_percpu_timer_interrupt(regs);
cpu = smp_processor_id(); cpu = smp_processor_id();
if (cpu != boot_cpuid) { if (cpu != boot_cpuid) {
kstat_cpu(cpu).irqs[RTC_IRQ]++; kstat_cpu(cpu).irqs[RTC_IRQ]++;
} else { } else {
handle_irq(RTC_IRQ, &regs); handle_irq(RTC_IRQ, regs);
} }
} }
#else #else
handle_irq(RTC_IRQ, &regs); handle_irq(RTC_IRQ, regs);
#endif #endif
return; return;
case 2: case 2:
alpha_mv.machine_check(vector, la_ptr, &regs); alpha_mv.machine_check(vector, la_ptr, regs);
return; return;
case 3: case 3:
alpha_mv.device_interrupt(vector, &regs); alpha_mv.device_interrupt(vector, regs);
return; return;
case 4: case 4:
perf_irq(vector, &regs); perf_irq(vector, regs);
return; return;
default: default:
printk(KERN_CRIT "Hardware intr %ld %lx? Huh?\n", printk(KERN_CRIT "Hardware intr %ld %lx? Huh?\n",
type, vector); type, vector);
} }
printk("PC = %016lx PS=%04lx\n", regs.pc, regs.ps); printk(KERN_CRIT "PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
} }
void __init void __init
...@@ -96,10 +95,8 @@ common_init_isa_dma(void) ...@@ -96,10 +95,8 @@ common_init_isa_dma(void)
void __init void __init
init_IRQ(void) init_IRQ(void)
{ {
/* Uh, this really MUST come first, just in case /* Just in case the platform init_irq() causes interrupts/mchecks
* the platform init_irq() causes interrupts/mchecks (as is the case with RAWHIDE, at least). */
* (as is the case with RAWHIDE, at least).
*/
wrent(entInt, 0); wrent(entInt, 0);
alpha_mv.init_irq(); alpha_mv.init_irq();
......
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
extern int do_pipe(int *); extern int do_pipe(int *);
extern asmlinkage unsigned long sys_brk(unsigned long); extern asmlinkage unsigned long sys_brk(unsigned long);
extern int sys_getpriority(int, int);
extern asmlinkage unsigned long sys_create_module(char *, unsigned long); extern asmlinkage unsigned long sys_create_module(char *, unsigned long);
/* /*
...@@ -172,68 +171,9 @@ osf_getdirentries(unsigned int fd, struct osf_dirent *dirent, ...@@ -172,68 +171,9 @@ osf_getdirentries(unsigned int fd, struct osf_dirent *dirent,
#undef ROUND_UP #undef ROUND_UP
#undef NAME_OFFSET #undef NAME_OFFSET
/*
* Alpha syscall convention has no problem returning negative
* values:
*/
asmlinkage int
osf_getpriority(int which, int who,
int a2, int a3, int a4, int a5, struct pt_regs regs)
{
extern int sys_getpriority(int, int);
int prio;
/*
* We don't need to acquire the kernel lock here, because
* all of these operations are local. sys_getpriority
* will get the lock as required..
*/
prio = sys_getpriority(which, who);
if (prio >= 0) {
regs.r0 = 0; /* special return: no errors */
prio = 20 - prio;
}
return prio;
}
/*
* No need to acquire the kernel lock, we're local..
*/
asmlinkage unsigned long
sys_getxuid(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs)
{
struct task_struct * tsk = current;
(&regs)->r20 = tsk->euid;
return tsk->uid;
}
asmlinkage unsigned long
sys_getxgid(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs)
{
struct task_struct * tsk = current;
(&regs)->r20 = tsk->egid;
return tsk->gid;
}
asmlinkage unsigned long
sys_getxpid(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs)
{
struct task_struct *tsk = current;
/*
* This isn't strictly "local" any more and we should actually
* acquire the kernel lock. The "p_opptr" pointer might change
* if the parent goes away (or due to ptrace). But any race
* isn't actually going to matter, as if the parent happens
* to change we can happily return either of the pids.
*/
(&regs)->r20 = tsk->real_parent->tgid;
return tsk->tgid;
}
asmlinkage unsigned long asmlinkage unsigned long
osf_mmap(unsigned long addr, unsigned long len, unsigned long prot, osf_mmap(unsigned long addr, unsigned long len, unsigned long prot,
unsigned long flags, unsigned long fd, unsigned long off) unsigned long flags, unsigned long fd, unsigned long off)
{ {
struct file *file = NULL; struct file *file = NULL;
unsigned long ret = -EBADF; unsigned long ret = -EBADF;
...@@ -502,19 +442,6 @@ sys_getdtablesize(void) ...@@ -502,19 +442,6 @@ sys_getdtablesize(void)
return NR_OPEN; return NR_OPEN;
} }
asmlinkage int
sys_pipe(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs)
{
int fd[2], error;
error = do_pipe(fd);
if (!error) {
regs.r20 = fd[1];
error = fd[0];
}
return error;
}
/* /*
* For compatibility with OSF/1 only. Use utsname(2) instead. * For compatibility with OSF/1 only. Use utsname(2) instead.
*/ */
...@@ -723,8 +650,8 @@ osf_sigstack(struct sigstack *uss, struct sigstack *uoss) ...@@ -723,8 +650,8 @@ osf_sigstack(struct sigstack *uss, struct sigstack *uoss)
*/ */
asmlinkage unsigned long asmlinkage unsigned long
alpha_create_module(char *module_name, unsigned long size, do_alpha_create_module(char *module_name, unsigned long size,
int a3, int a4, int a5, int a6, struct pt_regs regs) struct pt_regs *regs)
{ {
long retval; long retval;
...@@ -735,7 +662,7 @@ alpha_create_module(char *module_name, unsigned long size, ...@@ -735,7 +662,7 @@ alpha_create_module(char *module_name, unsigned long size,
the error number is a small negative number, while the address the error number is a small negative number, while the address
is always negative but much larger. */ is always negative but much larger. */
if (retval + 1000 < 0) if (retval + 1000 < 0)
regs.r0 = 0; regs->r0 = 0;
unlock_kernel(); unlock_kernel();
return retval; return retval;
......
...@@ -42,18 +42,6 @@ ...@@ -42,18 +42,6 @@
#include "proto.h" #include "proto.h"
#include "pci_impl.h" #include "pci_impl.h"
/*
* No need to acquire the kernel lock, we're entirely local..
*/
asmlinkage int
sys_sethae(unsigned long hae, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs regs)
{
(&regs)->hae = hae;
return 0;
}
void default_idle(void) void default_idle(void)
{ {
barrier(); barrier();
...@@ -227,6 +215,9 @@ flush_thread(void) ...@@ -227,6 +215,9 @@ flush_thread(void)
with respect to the FPU. This is all exceptions disabled. */ with respect to the FPU. This is all exceptions disabled. */
current_thread_info()->ieee_state = 0; current_thread_info()->ieee_state = 0;
wrfpcr(FPCR_DYN_NORMAL | ieee_swcr_to_fpcr(0)); wrfpcr(FPCR_DYN_NORMAL | ieee_swcr_to_fpcr(0));
/* Clean slate for TLS. */
current_thread_info()->pcb.unique = 0;
} }
void void
...@@ -244,16 +235,15 @@ release_thread(struct task_struct *dead_task) ...@@ -244,16 +235,15 @@ release_thread(struct task_struct *dead_task)
* with parameters (SIGCHLD, 0). * with parameters (SIGCHLD, 0).
*/ */
int int
alpha_clone(unsigned long clone_flags, unsigned long usp, alpha_clone(unsigned long clone_flags, unsigned long usp, int *user_tid,
int *user_tid, struct switch_stack * swstack) struct pt_regs *regs)
{ {
struct task_struct *p; struct task_struct *p;
struct pt_regs *u_regs = (struct pt_regs *) (swstack+1);
if (!usp) if (!usp)
usp = rdusp(); usp = rdusp();
p = do_fork(clone_flags & ~CLONE_IDLETASK, usp, u_regs, 0, user_tid); p = do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0, user_tid);
return IS_ERR(p) ? PTR_ERR(p) : p->pid; return IS_ERR(p) ? PTR_ERR(p) : p->pid;
} }
...@@ -282,7 +272,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, ...@@ -282,7 +272,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
unsigned long unused, unsigned long unused,
struct task_struct * p, struct pt_regs * regs) struct task_struct * p, struct pt_regs * regs)
{ {
extern void ret_from_sys_call(void);
extern void ret_from_fork(void); extern void ret_from_fork(void);
struct thread_info *childti = p->thread_info; struct thread_info *childti = p->thread_info;
...@@ -304,11 +293,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, ...@@ -304,11 +293,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
stack = ((struct switch_stack *) regs) - 1; stack = ((struct switch_stack *) regs) - 1;
childstack = ((struct switch_stack *) childregs) - 1; childstack = ((struct switch_stack *) childregs) - 1;
*childstack = *stack; *childstack = *stack;
#ifdef CONFIG_SMP
childstack->r26 = (unsigned long) ret_from_fork; childstack->r26 = (unsigned long) ret_from_fork;
#else
childstack->r26 = (unsigned long) ret_from_sys_call;
#endif
childti->pcb.usp = usp; childti->pcb.usp = usp;
childti->pcb.ksp = (unsigned long) childstack; childti->pcb.ksp = (unsigned long) childstack;
childti->pcb.flags = 1; /* set FEN, clear everything else */ childti->pcb.flags = 1; /* set FEN, clear everything else */
......
...@@ -249,8 +249,8 @@ void ptrace_disable(struct task_struct *child) ...@@ -249,8 +249,8 @@ void ptrace_disable(struct task_struct *child)
} }
asmlinkage long asmlinkage long
sys_ptrace(long request, long pid, long addr, long data, do_sys_ptrace(long request, long pid, long addr, long data,
int a4, int a5, struct pt_regs regs) struct pt_regs *regs)
{ {
struct task_struct *child; struct task_struct *child;
long ret; long ret;
...@@ -307,14 +307,14 @@ sys_ptrace(long request, long pid, long addr, long data, ...@@ -307,14 +307,14 @@ sys_ptrace(long request, long pid, long addr, long data,
if (copied != sizeof(tmp)) if (copied != sizeof(tmp))
goto out; goto out;
regs.r0 = 0; /* special return: no errors */ regs->r0 = 0; /* special return: no errors */
ret = tmp; ret = tmp;
goto out; goto out;
} }
/* Read register number ADDR. */ /* Read register number ADDR. */
case PTRACE_PEEKUSR: case PTRACE_PEEKUSR:
regs.r0 = 0; /* special return: no errors */ regs->r0 = 0; /* special return: no errors */
ret = get_reg(child, addr); ret = get_reg(child, addr);
DBG(DBG_MEM, ("peek $%ld->%#lx\n", addr, ret)); DBG(DBG_MEM, ("peek $%ld->%#lx\n", addr, ret));
goto out; goto out;
......
...@@ -210,8 +210,7 @@ long alpha_fp_emul (unsigned long pc); ...@@ -210,8 +210,7 @@ long alpha_fp_emul (unsigned long pc);
asmlinkage void asmlinkage void
do_entArith(unsigned long summary, unsigned long write_mask, do_entArith(unsigned long summary, unsigned long write_mask,
unsigned long a2, unsigned long a3, unsigned long a4, struct pt_regs *regs)
unsigned long a5, struct pt_regs regs)
{ {
long si_code = FPE_FLTINV; long si_code = FPE_FLTINV;
siginfo_t info; siginfo_t info;
...@@ -221,23 +220,23 @@ do_entArith(unsigned long summary, unsigned long write_mask, ...@@ -221,23 +220,23 @@ do_entArith(unsigned long summary, unsigned long write_mask,
emulate the instruction. If the processor supports emulate the instruction. If the processor supports
precise exceptions, we don't have to search. */ precise exceptions, we don't have to search. */
if (!amask(AMASK_PRECISE_TRAP)) if (!amask(AMASK_PRECISE_TRAP))
si_code = alpha_fp_emul(regs.pc - 4); si_code = alpha_fp_emul(regs->pc - 4);
else else
si_code = alpha_fp_emul_imprecise(&regs, write_mask); si_code = alpha_fp_emul_imprecise(regs, write_mask);
if (si_code == 0)
return;
} }
die_if_kernel("Arithmetic fault", &regs, 0, 0); die_if_kernel("Arithmetic fault", regs, 0, 0);
info.si_signo = SIGFPE; info.si_signo = SIGFPE;
info.si_errno = 0; info.si_errno = 0;
info.si_code = si_code; info.si_code = si_code;
info.si_addr = (void *) regs.pc; info.si_addr = (void *) regs->pc;
send_sig_info(SIGFPE, &info, current); send_sig_info(SIGFPE, &info, current);
} }
asmlinkage void asmlinkage void
do_entIF(unsigned long type, unsigned long a1, do_entIF(unsigned long type, struct pt_regs *regs)
unsigned long a2, unsigned long a3, unsigned long a4,
unsigned long a5, struct pt_regs regs)
{ {
siginfo_t info; siginfo_t info;
int signo, code; int signo, code;
...@@ -245,13 +244,13 @@ do_entIF(unsigned long type, unsigned long a1, ...@@ -245,13 +244,13 @@ do_entIF(unsigned long type, unsigned long a1,
if (!opDEC_testing || type != 4) { if (!opDEC_testing || type != 4) {
if (type == 1) { if (type == 1) {
const unsigned int *data const unsigned int *data
= (const unsigned int *) regs.pc; = (const unsigned int *) regs->pc;
printk("Kernel bug at %s:%d\n", printk("Kernel bug at %s:%d\n",
(const char *)(data[1] | (long)data[2] << 32), (const char *)(data[1] | (long)data[2] << 32),
data[0]); data[0]);
} }
die_if_kernel((type == 1 ? "Kernel Bug" : "Instruction fault"), die_if_kernel((type == 1 ? "Kernel Bug" : "Instruction fault"),
&regs, type, 0); regs, type, 0);
} }
switch (type) { switch (type) {
...@@ -260,10 +259,10 @@ do_entIF(unsigned long type, unsigned long a1, ...@@ -260,10 +259,10 @@ do_entIF(unsigned long type, unsigned long a1,
info.si_errno = 0; info.si_errno = 0;
info.si_code = TRAP_BRKPT; info.si_code = TRAP_BRKPT;
info.si_trapno = 0; info.si_trapno = 0;
info.si_addr = (void *) regs.pc; info.si_addr = (void *) regs->pc;
if (ptrace_cancel_bpt(current)) { if (ptrace_cancel_bpt(current)) {
regs.pc -= 4; /* make pc point to former bpt */ regs->pc -= 4; /* make pc point to former bpt */
} }
send_sig_info(SIGTRAP, &info, current); send_sig_info(SIGTRAP, &info, current);
...@@ -273,15 +272,15 @@ do_entIF(unsigned long type, unsigned long a1, ...@@ -273,15 +272,15 @@ do_entIF(unsigned long type, unsigned long a1,
info.si_signo = SIGTRAP; info.si_signo = SIGTRAP;
info.si_errno = 0; info.si_errno = 0;
info.si_code = __SI_FAULT; info.si_code = __SI_FAULT;
info.si_addr = (void *) regs.pc; info.si_addr = (void *) regs->pc;
info.si_trapno = 0; info.si_trapno = 0;
send_sig_info(SIGTRAP, &info, current); send_sig_info(SIGTRAP, &info, current);
return; return;
case 2: /* gentrap */ case 2: /* gentrap */
info.si_addr = (void *) regs.pc; info.si_addr = (void *) regs->pc;
info.si_trapno = regs.r16; info.si_trapno = regs->r16;
switch ((long) regs.r16) { switch ((long) regs->r16) {
case GEN_INTOVF: case GEN_INTOVF:
signo = SIGFPE; signo = SIGFPE;
code = FPE_INTOVF; code = FPE_INTOVF;
...@@ -341,7 +340,7 @@ do_entIF(unsigned long type, unsigned long a1, ...@@ -341,7 +340,7 @@ do_entIF(unsigned long type, unsigned long a1,
info.si_signo = signo; info.si_signo = signo;
info.si_errno = 0; info.si_errno = 0;
info.si_code = code; info.si_code = code;
info.si_addr = (void *) regs.pc; info.si_addr = (void *) regs->pc;
send_sig_info(signo, &info, current); send_sig_info(signo, &info, current);
return; return;
...@@ -358,26 +357,26 @@ do_entIF(unsigned long type, unsigned long a1, ...@@ -358,26 +357,26 @@ do_entIF(unsigned long type, unsigned long a1,
we get the correct PC. If not, we set a flag we get the correct PC. If not, we set a flag
to correct it every time through. */ to correct it every time through. */
if (opDEC_testing) { if (opDEC_testing) {
if (regs.pc == opDEC_test_pc) { if (regs->pc == opDEC_test_pc) {
opDEC_fix = 4; opDEC_fix = 4;
regs.pc += 4; regs->pc += 4;
printk("opDEC fixup enabled.\n"); printk("opDEC fixup enabled.\n");
} }
return; return;
} }
regs.pc += opDEC_fix; regs->pc += opDEC_fix;
/* EV4 does not implement anything except normal /* EV4 does not implement anything except normal
rounding. Everything else will come here as rounding. Everything else will come here as
an illegal instruction. Emulate them. */ an illegal instruction. Emulate them. */
si_code = alpha_fp_emul(regs.pc - 4); si_code = alpha_fp_emul(regs->pc - 4);
if (si_code == 0) if (si_code == 0)
return; return;
if (si_code > 0) { if (si_code > 0) {
info.si_signo = SIGFPE; info.si_signo = SIGFPE;
info.si_errno = 0; info.si_errno = 0;
info.si_code = si_code; info.si_code = si_code;
info.si_addr = (void *) regs.pc; info.si_addr = (void *) regs->pc;
send_sig_info(SIGFPE, &info, current); send_sig_info(SIGFPE, &info, current);
return; return;
} }
...@@ -406,7 +405,7 @@ do_entIF(unsigned long type, unsigned long a1, ...@@ -406,7 +405,7 @@ do_entIF(unsigned long type, unsigned long a1,
info.si_signo = SIGILL; info.si_signo = SIGILL;
info.si_errno = 0; info.si_errno = 0;
info.si_code = ILL_ILLOPC; info.si_code = ILL_ILLOPC;
info.si_addr = regs.pc; info.si_addr = (void *) regs->pc;
send_sig_info(SIGILL, &info, current); send_sig_info(SIGILL, &info, current);
} }
...@@ -418,18 +417,16 @@ do_entIF(unsigned long type, unsigned long a1, ...@@ -418,18 +417,16 @@ do_entIF(unsigned long type, unsigned long a1,
and if we don't put something on the entry point we'll oops. */ and if we don't put something on the entry point we'll oops. */
asmlinkage void asmlinkage void
do_entDbg(unsigned long type, unsigned long a1, do_entDbg(struct pt_regs *regs)
unsigned long a2, unsigned long a3, unsigned long a4,
unsigned long a5, struct pt_regs regs)
{ {
siginfo_t info; siginfo_t info;
die_if_kernel("Instruction fault", &regs, type, 0); die_if_kernel("Instruction fault", regs, 0, 0);
info.si_signo = SIGILL; info.si_signo = SIGILL;
info.si_errno = 0; info.si_errno = 0;
info.si_code = ILL_ILLOPC; info.si_code = ILL_ILLOPC;
info.si_addr = regs.pc; info.si_addr = (void *) regs->pc;
force_sig_info(SIGILL, &info, current); force_sig_info(SIGILL, &info, current);
} }
...@@ -1083,22 +1080,6 @@ do_entUnaUser(void * va, unsigned long opcode, ...@@ -1083,22 +1080,6 @@ do_entUnaUser(void * va, unsigned long opcode,
return; return;
} }
/*
* Unimplemented system calls.
*/
asmlinkage long
alpha_ni_syscall(unsigned long a0, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs regs)
{
/* We only get here for OSF system calls, minus #112;
the rest go to sys_ni_syscall. */
#if 0
printk("<sc %ld(%lx,%lx,%lx)>", regs.r0, a0, a1, a2);
#endif
return -ENOSYS;
}
void void
trap_init(void) trap_init(void)
{ {
...@@ -1114,9 +1095,7 @@ trap_init(void) ...@@ -1114,9 +1095,7 @@ trap_init(void)
wrent(entDbg, 6); wrent(entDbg, 6);
/* Hack for Multia (UDB) and JENSEN: some of their SRMs have /* Hack for Multia (UDB) and JENSEN: some of their SRMs have
* a bug in the handling of the opDEC fault. Fix it up if so. a bug in the handling of the opDEC fault. Fix it up if so. */
*/ if (implver() == IMPLVER_EV4)
if (implver() == IMPLVER_EV4) {
opDEC_check(); opDEC_check();
}
} }
...@@ -223,12 +223,12 @@ alpha_fp_emul (unsigned long pc) ...@@ -223,12 +223,12 @@ alpha_fp_emul (unsigned long pc)
FP_CONV(S,D,1,1,SR,DB); FP_CONV(S,D,1,1,SR,DB);
goto pack_s; goto pack_s;
} else { } else {
/* CVTST need do nothing else but copy the vb = alpha_read_fp_reg_s(fb);
bits and repack. */ FP_UNPACK_SP(SB, &vb);
DR_c = DB_c; DR_c = DB_c;
DR_s = DB_s; DR_s = DB_s;
DR_e = DB_e; DR_e = DB_e;
DR_f = DB_f; DR_f = SB_f << (52 - 23);
goto pack_d; goto pack_d;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment