summaryrefslogtreecommitdiff
path: root/sys/arch/arm
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2006-12-27 17:49:27 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2006-12-27 17:49:27 +0000
commit29b4fcf82a58a5db7b26c0b17ce40da8e3176389 (patch)
treefd01755da487224f7802dfbefa311fdc2482a195 /sys/arch/arm
parent41f0c1c851fb06df70df4b1bccc0b29ce4c378cc (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.S3
-rw-r--r--sys/arch/arm/arm/syscall.c129
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);