Use the same undefined-instuction handler on both arm26 and arm32. The handler
is derived mostly from the arm32 version, but with a check for an obscure ARM2 bug thrown in. arm26 fpu and cpu drivers use the new interface for catching undefined instructions.
This commit is contained in:
parent
c0aee693f5
commit
f6c36838ae
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: undefined.c,v 1.3 2001/03/05 23:29:32 bjh21 Exp $ */
|
||||
/* $NetBSD: undefined.c,v 1.4 2001/03/08 21:30:35 bjh21 Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Mark Brinicombe.
|
||||
|
@ -45,11 +45,13 @@
|
|||
|
||||
#define FAST_FPE
|
||||
|
||||
#include "opt_cputypes.h"
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_progmode.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: undefined.c,v 1.3 2001/03/05 23:29:32 bjh21 Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: undefined.c,v 1.4 2001/03/08 21:30:35 bjh21 Exp $");
|
||||
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
|
@ -64,12 +66,15 @@ __KERNEL_RCSID(0, "$NetBSD: undefined.c,v 1.3 2001/03/05 23:29:32 bjh21 Exp $");
|
|||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/katelib.h>
|
||||
#include <machine/undefined.h>
|
||||
#include <machine/trap.h>
|
||||
|
||||
#include <arch/arm/arm/disassem.h>
|
||||
|
||||
#ifdef arm26
|
||||
#include <machine/machdep.h>
|
||||
#endif
|
||||
|
||||
#ifdef FAST_FPE
|
||||
extern int want_resched;
|
||||
#endif
|
||||
|
@ -127,13 +132,19 @@ undefinedinstruction(trapframe_t *frame)
|
|||
int coprocessor;
|
||||
|
||||
/* Enable interrupts if they were enabled before the exception. */
|
||||
#ifdef arm26
|
||||
if ((frame->tf_r15 & R15_IRQ_DISABLE) == 0)
|
||||
int_on();
|
||||
#else
|
||||
if (!(frame->tf_spsr & I32_bit))
|
||||
enable_interrupts(I32_bit);
|
||||
#endif
|
||||
|
||||
/* Update vmmeter statistics */
|
||||
uvmexp.traps++;
|
||||
|
||||
#ifdef arm26
|
||||
fault_pc = frame->tf_r15 & R15_PC;
|
||||
#else
|
||||
fault_pc = frame->tf_pc - INSN_SIZE;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Should use fuword() here .. but in the interests of squeezing every
|
||||
|
@ -143,7 +154,21 @@ undefinedinstruction(trapframe_t *frame)
|
|||
* it ?
|
||||
*/
|
||||
|
||||
fault_instruction = ReadWord(fault_pc);
|
||||
fault_instruction = *(u_int32_t *)fault_pc;
|
||||
|
||||
#ifdef CPU_ARM2
|
||||
/*
|
||||
* Check if the aborted instruction was a SWI (ARM2 bug --
|
||||
* ARM3 data sheet p87) and call SWI handler if so.
|
||||
*/
|
||||
if ((fault_instruction & 0x0f000000) == 0x0f000000) {
|
||||
swi_handler(frame);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Update vmmeter statistics */
|
||||
uvmexp.traps++;
|
||||
|
||||
/* Check for coprocessor instruction */
|
||||
|
||||
|
@ -158,13 +183,17 @@ undefinedinstruction(trapframe_t *frame)
|
|||
coprocessor = (fault_instruction >> 8) & 0x0f;
|
||||
else
|
||||
coprocessor = 0;
|
||||
|
||||
|
||||
/* Get the current proc structure or proc0 if there is none. */
|
||||
|
||||
if ((p = curproc) == 0)
|
||||
p = &proc0;
|
||||
|
||||
#ifdef PROG26
|
||||
if ((frame->tf_r15 & R15_MODE) == R15_MODE_USR) {
|
||||
#else
|
||||
if ((frame->tf_spsr & PSR_MODE) == PSR_USR32_MODE) {
|
||||
#endif
|
||||
/*
|
||||
* Modify the fault_code to reflect the USR/SVC state at
|
||||
* time of fault.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.arm,v 1.19 2001/03/06 07:52:36 matt Exp $
|
||||
# $NetBSD: files.arm,v 1.20 2001/03/08 21:30:35 bjh21 Exp $
|
||||
|
||||
# temporary define to allow easy moving to ../arch/arm/arm32
|
||||
defopt ARM32
|
||||
|
@ -47,7 +47,7 @@ file arch/arm/arm/compat_13_machdep.c compat_13
|
|||
file arch/arm/arm/process_machdep.c
|
||||
file arch/arm/arm/sig_machdep.c
|
||||
file arch/arm/arm/sigcode.S
|
||||
file arch/arm/arm/undefined.c arm32
|
||||
file arch/arm/arm/undefined.c
|
||||
file arch/arm/arm/vm_machdep_arm.c
|
||||
|
||||
file arch/arm/arm/disksubr.c disk
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: cpu.c,v 1.7 2001/02/25 15:33:34 bjh21 Exp $ */
|
||||
/* $NetBSD: cpu.c,v 1.8 2001/03/08 21:30:35 bjh21 Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 Ben Harris
|
||||
* Copyright (c) 2000, 2001 Ben Harris
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -33,7 +33,7 @@
|
|||
|
||||
#include <sys/param.h>
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.7 2001/02/25 15:33:34 bjh21 Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.8 2001/03/08 21:30:35 bjh21 Exp $");
|
||||
|
||||
#include <sys/device.h>
|
||||
#include <sys/proc.h>
|
||||
|
@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.7 2001/02/25 15:33:34 bjh21 Exp $");
|
|||
#include <sys/time.h>
|
||||
#include <sys/user.h>
|
||||
#include <arm/armreg.h>
|
||||
#include <arm/undefined.h>
|
||||
#include <machine/machdep.h>
|
||||
#include <machine/pcb.h>
|
||||
|
||||
|
@ -132,15 +133,24 @@ cpu_search(struct device *parent, struct cfdata *cf, void *aux)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static label_t undef_jmp;
|
||||
|
||||
static int
|
||||
cpu_undef_handler(u_int addr, u_int insn, struct trapframe *tf, int fault_code)
|
||||
{
|
||||
|
||||
longjmp(&undef_jmp);
|
||||
}
|
||||
|
||||
static register_t
|
||||
cpu_identify()
|
||||
{
|
||||
label_t here;
|
||||
register_t dummy;
|
||||
volatile register_t id;
|
||||
|
||||
if (setjmp(&here) == 0) {
|
||||
curproc->p_addr->u_pcb.pcb_onundef_lj = &here;
|
||||
if (setjmp(&undef_jmp) == 0) {
|
||||
install_coproc_handler(0, cpu_undef_handler);
|
||||
install_coproc_handler(15, cpu_undef_handler);
|
||||
id = CPU_ID_ARM2;
|
||||
/* ARM250 and ARM3 support SWP. */
|
||||
asm volatile ("swp r0, r0, [%0]" : : "r" (&dummy) : "r0");
|
||||
|
@ -148,7 +158,8 @@ cpu_identify()
|
|||
/* ARM3 has an internal coprocessor 15 with an ID register. */
|
||||
asm volatile ("mrc 15, 0, %0, cr0, cr0" : "=r" (id));
|
||||
}
|
||||
curproc->p_addr->u_pcb.pcb_onundef_lj = NULL;
|
||||
install_coproc_handler(0, NULL);
|
||||
install_coproc_handler(15, NULL);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: except.c,v 1.28 2001/02/27 23:57:30 bjh21 Exp $ */
|
||||
/* $NetBSD: except.c,v 1.29 2001/03/08 21:30:35 bjh21 Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999, 2000 Ben Harris
|
||||
* All rights reserved.
|
||||
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include <sys/param.h>
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: except.c,v 1.28 2001/02/27 23:57:30 bjh21 Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: except.c,v 1.29 2001/03/08 21:30:35 bjh21 Exp $");
|
||||
|
||||
#include "opt_cputypes.h"
|
||||
#include "opt_ddb.h"
|
||||
|
@ -134,6 +134,7 @@ checkvectors()
|
|||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
void
|
||||
undefined_handler(struct trapframe *tf)
|
||||
{
|
||||
|
@ -184,6 +185,8 @@ undefined_handler(struct trapframe *tf)
|
|||
userret(p, pc, sticks);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
swi_handler(struct trapframe *tf)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fpu.c,v 1.2 2001/01/12 13:23:49 bjh21 Exp $ */
|
||||
/* $NetBSD: fpu.c,v 1.3 2001/03/08 21:30:35 bjh21 Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000, 2001 Ben Harris
|
||||
|
@ -33,14 +33,17 @@
|
|||
|
||||
#include <sys/param.h>
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.2 2001/01/12 13:23:49 bjh21 Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.3 2001/03/08 21:30:35 bjh21 Exp $");
|
||||
|
||||
#include <sys/device.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/user.h>
|
||||
#include <arm/undefined.h>
|
||||
#include <machine/fpureg.h>
|
||||
#include <machine/pcb.h>
|
||||
|
||||
|
||||
#include <arch/arm26/arm26/fpuvar.h>
|
||||
|
||||
#include "opt_fputypes.h"
|
||||
|
@ -104,19 +107,27 @@ fpu_attach(struct device *parent, struct device *self, void *aux)
|
|||
printf("%s: WARNING: FPU type not supported by kernel\n",
|
||||
self->dv_xname);
|
||||
}
|
||||
|
||||
|
||||
static label_t undef_jmp;
|
||||
|
||||
static int
|
||||
fpu_undef_handler(u_int addr, u_int insn, struct trapframe *tf, int fault_code)
|
||||
{
|
||||
|
||||
longjmp(&undef_jmp);
|
||||
}
|
||||
|
||||
static register_t
|
||||
fpu_identify()
|
||||
{
|
||||
label_t here;
|
||||
volatile register_t fpsr;
|
||||
|
||||
if (setjmp(&here) == 0) {
|
||||
curproc->p_addr->u_pcb.pcb_onundef_lj = &here;
|
||||
if (setjmp(&undef_jmp) == 0) {
|
||||
install_coproc_handler(1, fpu_undef_handler);
|
||||
fpsr = 0;
|
||||
asm volatile ("rfs %0" : "=r" (fpsr));
|
||||
}
|
||||
curproc->p_addr->u_pcb.pcb_onundef_lj = NULL;
|
||||
install_coproc_handler(1, NULL);
|
||||
return fpsr & FPSR_SYSID_MASK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: locore.S,v 1.12 2001/01/23 22:41:16 bjh21 Exp $ */
|
||||
/* $NetBSD: locore.S,v 1.13 2001/03/08 21:30:35 bjh21 Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1998, 1999, 2000 Ben Harris
|
||||
* Copyright (C) 1994-1997 Mark Brinicombe
|
||||
|
@ -226,7 +226,7 @@ Lreset_panicmsg:
|
|||
|
||||
.global undefined_entry
|
||||
undefined_entry:
|
||||
HANDLER _C_LABEL(undefined_handler), 4
|
||||
HANDLER _C_LABEL(undefinedinstruction), 4
|
||||
|
||||
.global swi_entry
|
||||
swi_entry:
|
||||
|
@ -450,4 +450,4 @@ _C_LABEL(intrcnt):
|
|||
.global _C_LABEL(eintrcnt)
|
||||
_C_LABEL(eintrcnt):
|
||||
|
||||
RCSID("$NetBSD: locore.S,v 1.12 2001/01/23 22:41:16 bjh21 Exp $")
|
||||
RCSID("$NetBSD: locore.S,v 1.13 2001/03/08 21:30:35 bjh21 Exp $")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pcb.h,v 1.2 2001/01/11 22:03:52 bjh21 Exp $ */
|
||||
/* $NetBSD: pcb.h,v 1.3 2001/03/08 21:30:35 bjh21 Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 Ben Harris
|
||||
|
@ -44,7 +44,6 @@ struct pcb {
|
|||
struct fpframe pcb_ff;
|
||||
void *pcb_onfault; /* return here after failed page fault */
|
||||
label_t *pcb_onfault_lj; /* longjmp here ditto */
|
||||
label_t *pcb_onundef_lj; /* longjmp here on undefined instruction */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue