diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2006-12-27 17:49:27 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2006-12-27 17:49:27 +0000 |
commit | 29b4fcf82a58a5db7b26c0b17ce40da8e3176389 (patch) | |
tree | fd01755da487224f7802dfbefa311fdc2482a195 /sys/arch/arm | |
parent | 41f0c1c851fb06df70df4b1bccc0b29ce4c378cc (diff) |
Switch new new syscall ABI, now passes the syscall number in r12 instead of
in the swi instruction. elminates an illegal userland reference from the kernel
also elminates a bunch of code. This is a flag day for binaries from
before the middle of November.
Diffstat (limited to 'sys/arch/arm')
-rw-r--r-- | sys/arch/arm/arm/sigcode.S | 3 | ||||
-rw-r--r-- | sys/arch/arm/arm/syscall.c | 129 |
2 files changed, 8 insertions, 124 deletions
diff --git a/sys/arch/arm/arm/sigcode.S b/sys/arch/arm/arm/sigcode.S index c46cc6e12d0..c6c8412fc97 100644 --- a/sys/arch/arm/arm/sigcode.S +++ b/sys/arch/arm/arm/sigcode.S @@ -1,4 +1,4 @@ -/* $OpenBSD: sigcode.S,v 1.1 2004/02/01 05:09:48 drahn Exp $ */ +/* $OpenBSD: sigcode.S,v 1.2 2006/12/27 17:49:26 drahn Exp $ */ /* $NetBSD: sigcode.S,v 1.6 2003/10/05 19:44:58 matt Exp $ */ /* @@ -50,6 +50,7 @@ ENTRY_NP(sigcode) */ /* mov r0, sp */ add r0, sp, #SIGF_SC + ldr r12, =SYS_sigreturn swi SYS_sigreturn /* Well if that failed we better exit quick ! */ diff --git a/sys/arch/arm/arm/syscall.c b/sys/arch/arm/arm/syscall.c index bcbde5ed403..f3a497f2abe 100644 --- a/sys/arch/arm/arm/syscall.c +++ b/sys/arch/arm/arm/syscall.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.c,v 1.7 2006/12/24 20:30:35 miod Exp $ */ +/* $OpenBSD: syscall.c,v 1.8 2006/12/27 17:49:26 drahn Exp $ */ /* $NetBSD: syscall.c,v 1.24 2003/11/14 19:03:17 scw Exp $ */ /*- @@ -107,125 +107,20 @@ #define MAXARGS 8 -void syscall(struct trapframe *, struct proc *, u_int32_t); - void swi_handler(trapframe_t *frame) { struct proc *p = curproc; - u_int32_t insn; - union sigval sv; - - /* - * Enable interrupts if they were enabled before the exception. - * Since all syscalls *should* come from user mode it will always - * be safe to enable them, but check anyway. - */ -#ifdef acorn26 - if ((frame->tf_r15 & R15_IRQ_DISABLE) == 0) - int_on(); -#else - if (!(frame->tf_spsr & I32_bit)) - enable_interrupts(I32_bit); -#endif - -#ifdef acorn26 - frame->tf_pc += INSN_SIZE; -#endif - - p->p_addr->u_pcb.pcb_tf = frame; - - /* - * Make sure the program counter is correctly aligned so we - * don't take an alignment fault trying to read the opcode. - */ - if (__predict_false(((frame->tf_pc - INSN_SIZE) & 3) != 0)) { - /* Give the user an illegal instruction signal. */ - sv.sival_ptr = (u_int32_t *)(u_int32_t)(frame->tf_pc-INSN_SIZE); - trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv); - userret(p); - return; - } - - /* XXX fuword? */ -#ifdef __PROG32 - insn = *(u_int32_t *)(frame->tf_pc - INSN_SIZE); -#else - insn = *(u_int32_t *)((frame->tf_r15 & R15_PC) - INSN_SIZE); -#endif - -#ifdef CPU_ARM7 - /* - * This code is only needed if we are including support for the ARM7 - * core. Other CPUs do not need it but it does not hurt. - */ - - /* - * ARM700/ARM710 match sticks and sellotape job ... - * - * I know this affects GPS/VLSI ARM700/ARM710 + various ARM7500. - * - * On occasion data aborts are mishandled and end up calling - * the swi vector. - * - * If the instruction that caused the exception is not a SWI - * then we hit the bug. - */ - if ((insn & 0x0f000000) != 0x0f000000) { - frame->tf_pc -= INSN_SIZE; - curcpu()->ci_arm700bugcount.ev_count++; - userret(p); - return; - } -#endif /* CPU_ARM7 */ - - uvmexp.syscalls++; - - syscall(frame, p, insn); -} - -void -syscall(struct trapframe *frame, struct proc *p, u_int32_t insn) -{ const struct sysent *callp; int code, error, orig_error; - u_int nap, nargs; + u_int nap = 4, nargs; register_t *ap, *args, copyargs[MAXARGS], rval[2]; - union sigval sv; - switch (insn & SWI_OS_MASK) { /* Which OS is the SWI from? */ - case SWI_OS_ARM: /* ARM-defined SWIs */ - code = insn & 0x00ffffff; - switch (code) { - case SWI_IMB: - case SWI_IMBrange: - /* - * Do nothing as there is no prefetch unit that needs - * flushing - */ - break; - default: - /* Undefined so illegal instruction */ - sv.sival_ptr = (u_int32_t *)(frame->tf_pc - INSN_SIZE); - trapsignal(p, SIGILL, 0, ILL_ILLOPN, sv); - break; - } + uvmexp.syscalls++; - userret(p); - return; - case 0x000000: /* Old unofficial NetBSD range. */ - case SWI_OS_NETBSD: /* New official NetBSD range. */ - nap = 4; - break; - default: - /* Undefined so illegal instruction */ - sv.sival_ptr = (u_int32_t *)(frame->tf_pc - INSN_SIZE); - trapsignal(p, SIGILL, 0, ILL_ILLOPN, sv); - userret(p); - return; - } + p->p_addr->u_pcb.pcb_tf = frame; - code = insn & 0x000fffff; + code = frame->tf_r12; ap = &frame->tf_r0; callp = p->p_emul->e_sysent; @@ -270,7 +165,7 @@ syscall(struct trapframe *frame, struct proc *p, u_int32_t insn) goto bad; rval[0] = 0; - rval[1] = 0; + rval[1] = frame->tf_r1; #if NSYSTRACE > 0 if (ISSET(p->p_flag, P_SYSTRACE)) orig_error = error = systrace_redirect(code, p, args, rval); @@ -283,11 +178,7 @@ syscall(struct trapframe *frame, struct proc *p, u_int32_t insn) frame->tf_r0 = rval[0]; frame->tf_r1 = rval[1]; -#ifdef __PROG32 frame->tf_spsr &= ~PSR_C_bit; /* carry bit */ -#else - frame->tf_r15 &= ~R15_FLAG_C; /* carry bit */ -#endif break; case ERESTART: @@ -304,11 +195,7 @@ syscall(struct trapframe *frame, struct proc *p, u_int32_t insn) default: bad: frame->tf_r0 = error; -#ifdef __PROG32 frame->tf_spsr |= PSR_C_bit; /* carry bit */ -#else - frame->tf_r15 |= R15_FLAG_C; /* carry bit */ -#endif break; } #ifdef SYSCALL_DEBUG @@ -329,11 +216,7 @@ child_return(arg) struct trapframe *frame = p->p_addr->u_pcb.pcb_tf; frame->tf_r0 = 0; -#ifdef __PROG32 frame->tf_spsr &= ~PSR_C_bit; /* carry bit */ -#else - frame->tf_r15 &= ~R15_FLAG_C; /* carry bit */ -#endif userret(p); |