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 */