Module Name: src
Committed By: chs
Date: Wed Jul 7 01:17:27 UTC 2010
Modified Files:
src/sys/arch/acorn26/acorn26: except.c
src/sys/arch/arm/arm: arm_machdep.c lock_cas.S
src/sys/arch/arm/arm32: atomic.S fault.c
src/sys/arch/arm/include: cpu.h
Log Message:
implement ucas_* for arm.
To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/acorn26/acorn26/except.c
cvs rdiff -u -r1.28 -r1.29 src/sys/arch/arm/arm/arm_machdep.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/arm/lock_cas.S
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/arm32/atomic.S
cvs rdiff -u -r1.76 -r1.77 src/sys/arch/arm/arm32/fault.c
cvs rdiff -u -r1.59 -r1.60 src/sys/arch/arm/include/cpu.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/acorn26/acorn26/except.c
diff -u src/sys/arch/acorn26/acorn26/except.c:1.24 src/sys/arch/acorn26/acorn26/except.c:1.25
--- src/sys/arch/acorn26/acorn26/except.c:1.24 Sat Mar 20 23:31:27 2010
+++ src/sys/arch/acorn26/acorn26/except.c Wed Jul 7 01:17:26 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: except.c,v 1.24 2010/03/20 23:31:27 chs Exp $ */
+/* $NetBSD: except.c,v 1.25 2010/07/07 01:17:26 chs Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 Ben Harris
* All rights reserved.
@@ -31,7 +31,7 @@
#include <sys/param.h>
-__KERNEL_RCSID(0, "$NetBSD: except.c,v 1.24 2010/03/20 23:31:27 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: except.c,v 1.25 2010/07/07 01:17:26 chs Exp $");
#include "opt_ddb.h"
@@ -202,15 +202,17 @@
int error;
struct pcb *pcb;
void *onfault;
+ bool user;
if (pmap_fault(map->pmap, va, atype))
return;
pcb = lwp_getpcb(l);
onfault = pcb->pcb_onfault;
+ user = (tf->tf_r15 & R15_MODE) == R15_MODE_USR;
if (cpu_intr_p()) {
- KASSERT((tf->tf_r15 & R15_MODE) != R15_MODE_USR);
+ KASSERT(!user);
error = EFAULT;
} else {
pcb->pcb_onfault = NULL;
@@ -234,7 +236,7 @@
return;
}
#endif
- if ((tf->tf_r15 & R15_MODE) != R15_MODE_USR) {
+ if (!user) {
#ifdef DDB
db_printf("Unhandled data abort in kernel mode\n");
kdb_trap(T_FAULT, tf);
@@ -260,6 +262,8 @@
ksi.ksi_code = (error == EPERM) ? SEGV_ACCERR : SEGV_MAPERR;
ksi.ksi_addr = (void *) va;
trapsignal(l, &ksi);
+ } else if (!user) {
+ ucas_ras_check(tf);
}
}
Index: src/sys/arch/arm/arm/arm_machdep.c
diff -u src/sys/arch/arm/arm/arm_machdep.c:1.28 src/sys/arch/arm/arm/arm_machdep.c:1.29
--- src/sys/arch/arm/arm/arm_machdep.c:1.28 Fri Apr 23 19:18:09 2010
+++ src/sys/arch/arm/arm/arm_machdep.c Wed Jul 7 01:17:26 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: arm_machdep.c,v 1.28 2010/04/23 19:18:09 rmind Exp $ */
+/* $NetBSD: arm_machdep.c,v 1.29 2010/07/07 01:17:26 chs Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -79,7 +79,7 @@
#include <sys/param.h>
-__KERNEL_RCSID(0, "$NetBSD: arm_machdep.c,v 1.28 2010/04/23 19:18:09 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm_machdep.c,v 1.29 2010/07/07 01:17:26 chs Exp $");
#include <sys/exec.h>
#include <sys/proc.h>
@@ -277,3 +277,15 @@
{
return curcpu()->ci_intr_depth != 0;
}
+
+void
+ucas_ras_check(trapframe_t *tf)
+{
+ extern char ucas_32_ras_start[];
+ extern char ucas_32_ras_end[];
+
+ if (tf->tf_pc > (vaddr_t)ucas_32_ras_start &&
+ tf->tf_pc < (vaddr_t)ucas_32_ras_end) {
+ tf->tf_pc = (vaddr_t)ucas_32_ras_start;
+ }
+}
Index: src/sys/arch/arm/arm/lock_cas.S
diff -u src/sys/arch/arm/arm/lock_cas.S:1.6 src/sys/arch/arm/arm/lock_cas.S:1.7
--- src/sys/arch/arm/arm/lock_cas.S:1.6 Fri Jan 16 10:28:24 2009
+++ src/sys/arch/arm/arm/lock_cas.S Wed Jul 7 01:17:26 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: lock_cas.S,v 1.6 2009/01/16 10:28:24 bjh21 Exp $ */
+/* $NetBSD: lock_cas.S,v 1.7 2010/07/07 01:17:26 chs Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -29,9 +29,16 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include "opt_multiprocessor.h"
+#if defined(MULTIPROCESSOR)
+#error need to write MP support for ucas_* functions
+#endif
+
#include "opt_arm_debug.h"
+#include "assym.h"
#include <machine/asm.h>
+#include <machine/cpu.h>
.text
.align 0
@@ -67,8 +74,6 @@
strex r3, r2, [ip]
cmp r3, #0
bne 1b
- RET
- END(_lock_cas)
#else
ldr r3, [r0]
teq r3, r1
@@ -88,8 +93,9 @@
#endif /* __ARMEB__ */
stmia r3, {r1-r2} /* store ev_count */
#endif /* ARM_LOCK_CAS_DEBUG */
- RET
#endif
+ RET
+END(_lock_cas)
STRONG_ALIAS(_atomic_cas_ulong,_lock_cas)
STRONG_ALIAS(atomic_cas_ulong,_lock_cas)
@@ -108,3 +114,44 @@
STRONG_ALIAS(atomic_cas_uint_ni,_lock_cas)
STRONG_ALIAS(_atomic_cas_ptr_ni,_lock_cas)
STRONG_ALIAS(atomic_cas_ptr_ni,_lock_cas)
+
+#ifdef __PROG32
+#define SAVE_REGS stmfd sp!, {r4-r6}
+#define RESTORE_REGS ldmfd sp!, {r4-r6}
+#else
+/* Need to save R14_svc because it'll get trampled if we take a page fault. */
+#define SAVE_REGS stmfd sp!, {r4-r6, r14}
+#define RESTORE_REGS ldmfd sp!, {r4-r6, r14}
+#endif
+
+/*
+ * int ucas_32(volatile int32_t *uptr, int32_t old, int32_t new, int32_t *ret);
+ */
+ENTRY(ucas_32)
+ SAVE_REGS
+ GET_CURPCB(r4)
+ adr r5, .Lucasfault
+ str r5, [r4, #PCB_ONFAULT]
+
+ .globl _C_LABEL(ucas_32_ras_start)
+_C_LABEL(ucas_32_ras_start):
+ ldrt r5, [r0]
+ cmp r1, r5
+ streqt r2, [r0]
+ .globl _C_LABEL(ucas_32_ras_end)
+_C_LABEL(ucas_32_ras_end):
+
+ str r5, [r3]
+ mov r0, #0
+ str r0, [r4, #PCB_ONFAULT]
+ RESTORE_REGS
+ RET
+
+.Lucasfault:
+ mov r5, #0
+ str r5, [r4, #PCB_ONFAULT]
+ RESTORE_REGS
+ RET
+END(ucas_32)
+STRONG_ALIAS(ucas_int,ucas_32)
+STRONG_ALIAS(ucas_ptr,ucas_32)
Index: src/sys/arch/arm/arm32/atomic.S
diff -u src/sys/arch/arm/arm32/atomic.S:1.4 src/sys/arch/arm/arm32/atomic.S:1.5
--- src/sys/arch/arm/arm32/atomic.S:1.4 Wed Nov 19 06:32:10 2008
+++ src/sys/arch/arm/arm32/atomic.S Wed Jul 7 01:17:27 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: atomic.S,v 1.4 2008/11/19 06:32:10 matt Exp $ */
+/* $NetBSD: atomic.S,v 1.5 2010/07/07 01:17:27 chs Exp $ */
/*
* Copyright (C) 1994-1997 Mark Brinicombe
@@ -53,7 +53,7 @@
msr cpsr_c, r2
mov pc, lr
-
+END(atomic_set_bit)
#undef atomic_clear_bit
ENTRY(atomic_clear_bit)
@@ -67,6 +67,7 @@
msr cpsr_c, r2
mov pc, lr
+END(atomic_clear_bit)
#endif /* ATOMIC_SET_BIT_NONINLINE_REQUIRED */
@@ -81,7 +82,7 @@
cmp r3, #0 ;\
bne 1b ;\
RET ;\
- END(atomic_##NAME##_32)
+END(atomic_##NAME##_32)
ATOMIC_OP(and, and, r1)
ATOMIC_OP(nand, bic, r1)
@@ -101,7 +102,7 @@
cmp r3, #0 ;\
bne 1b ;\
RET ;\
- END(atomic_##NAME##_32_nv)
+END(atomic_##NAME##_32_nv)
ATOMIC_OP_NV(and, and, r1)
ATOMIC_OP_NV(nand, bic, r1)
Index: src/sys/arch/arm/arm32/fault.c
diff -u src/sys/arch/arm/arm32/fault.c:1.76 src/sys/arch/arm/arm32/fault.c:1.77
--- src/sys/arch/arm/arm32/fault.c:1.76 Sun Mar 21 00:10:14 2010
+++ src/sys/arch/arm/arm32/fault.c Wed Jul 7 01:17:27 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: fault.c,v 1.76 2010/03/21 00:10:14 chs Exp $ */
+/* $NetBSD: fault.c,v 1.77 2010/07/07 01:17:27 chs Exp $ */
/*
* Copyright 2003 Wasabi Systems, Inc.
@@ -82,7 +82,7 @@
#include "opt_sa.h"
#include <sys/types.h>
-__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.76 2010/03/21 00:10:14 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.77 2010/07/07 01:17:27 chs Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -480,6 +480,8 @@
if (__predict_true(error == 0)) {
if (user)
uvm_grow(l->l_proc, va); /* Record any stack growth */
+ else
+ ucas_ras_check(tf);
UVMHIST_LOG(maphist, " <- uvm", 0, 0, 0, 0);
goto out;
}
Index: src/sys/arch/arm/include/cpu.h
diff -u src/sys/arch/arm/include/cpu.h:1.59 src/sys/arch/arm/include/cpu.h:1.60
--- src/sys/arch/arm/include/cpu.h:1.59 Thu Dec 10 05:10:01 2009
+++ src/sys/arch/arm/include/cpu.h Wed Jul 7 01:17:27 2010
@@ -384,7 +384,7 @@
/* ast.c */
void userret(register struct lwp *);
-/* machdep.h */
+/* *_machdep.c */
void bootsync(void);
/* fault.c */
@@ -393,6 +393,9 @@
/* syscall.c */
void swi_handler(trapframe_t *);
+/* arm_machdep.c */
+void ucas_ras_check(trapframe_t *);
+
#endif /* !_LOCORE */
#endif /* _KERNEL */