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:
bjh21 2001-03-08 21:30:35 +00:00
parent c0aee693f5
commit f6c36838ae
7 changed files with 84 additions and 31 deletions

View File

@ -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.

View File

@ -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

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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 $")

View File

@ -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 */
};
/*