implement ucas_* for arm.

This commit is contained in:
chs 2010-07-07 01:17:26 +00:00
parent 9ea6b6e3f2
commit fb84d42413
6 changed files with 86 additions and 17 deletions

View File

@ -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 @@ do_fault(struct trapframe *tf, struct lwp *l,
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 @@ do_fault(struct trapframe *tf, struct lwp *l,
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 @@ do_fault(struct trapframe *tf, struct lwp *l,
ksi.ksi_code = (error == EPERM) ? SEGV_ACCERR : SEGV_MAPERR;
ksi.ksi_addr = (void *) va;
trapsignal(l, &ksi);
} else if (!user) {
ucas_ras_check(tf);
}
}

View File

@ -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 @@ cpu_intr_p(void)
{
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;
}
}

View File

@ -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 @@ ENTRY_NP(_lock_cas)
strex r3, r2, [ip]
cmp r3, #0
bne 1b
RET
END(_lock_cas)
#else
ldr r3, [r0]
teq r3, r1
@ -88,8 +93,9 @@ _C_LABEL(_lock_cas_end):
#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_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)

View File

@ -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 @@ ENTRY(atomic_set_bit)
msr cpsr_c, r2
mov pc, lr
END(atomic_set_bit)
#undef atomic_clear_bit
ENTRY(atomic_clear_bit)
@ -67,6 +67,7 @@ ENTRY(atomic_clear_bit)
msr cpsr_c, r2
mov pc, lr
END(atomic_clear_bit)
#endif /* ATOMIC_SET_BIT_NONINLINE_REQUIRED */
@ -81,7 +82,7 @@ ENTRY_NP(atomic_##NAME##_32) ;\
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 @@ ENTRY_NP(atomic_##NAME##_32_nv) ;\
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)

View File

@ -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 @@ data_abort_handler(trapframe_t *tf)
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;
}

View File

@ -384,7 +384,7 @@ void savectx(struct pcb *);
/* ast.c */
void userret(register struct lwp *);
/* machdep.h */
/* *_machdep.c */
void bootsync(void);
/* fault.c */
@ -393,6 +393,9 @@ int badaddr_read(void *, size_t, void *);
/* syscall.c */
void swi_handler(trapframe_t *);
/* arm_machdep.c */
void ucas_ras_check(trapframe_t *);
#endif /* !_LOCORE */
#endif /* _KERNEL */