summaryrefslogtreecommitdiff
path: root/sys/arch/hppa
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>1999-11-25 18:36:30 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>1999-11-25 18:36:30 +0000
commit3b5ade97eea1f23f371fc0a299c1bbc6a3113fe4 (patch)
treea632e00ee9fef0bf17f541bf3ea91d9254454837 /sys/arch/hppa
parent6b1969b6efead519554c1642a176590642add6af (diff)
many traps, syscall nad other stuff
Diffstat (limited to 'sys/arch/hppa')
-rw-r--r--sys/arch/hppa/hppa/trap.c238
1 files changed, 138 insertions, 100 deletions
diff --git a/sys/arch/hppa/hppa/trap.c b/sys/arch/hppa/hppa/trap.c
index 68981a9eeac..95e5c9b5673 100644
--- a/sys/arch/hppa/hppa/trap.c
+++ b/sys/arch/hppa/hppa/trap.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: trap.c,v 1.10 1999/08/16 04:05:38 mickey Exp $ */
+/* $OpenBSD: trap.c,v 1.11 1999/11/25 18:36:29 mickey Exp $ */
/*
- * Copyright (c) 1998 Michael Shalayeff
+ * Copyright (c) 1998,1999 Michael Shalayeff
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -52,43 +52,48 @@
#include <machine/iomod.h>
#include <machine/cpufunc.h>
#include <machine/reg.h>
-#include <machine/db_machdep.h>
#include <machine/autoconf.h>
-#define FAULT_TYPE(op) (VM_PROT_READ|(inst_load(op) ? 0 : VM_PROT_WRITE))
+#ifdef DDB
+#include <machine/db_machdep.h>
+#endif
+
+#if defined(INTRDEBUG) || defined(TRAPDEBUG)
+#include <ddb/db_output.h>
+#endif
+
+#define FAULT_TYPE(op) (VM_PROT_READ|(inst_store(op) ? VM_PROT_WRITE : 0))
const char *trap_type[] = {
"invalid interrupt vector",
"high priority machine check",
"power failure",
- "recovery counter trap",
+ "recovery counter",
"external interrupt",
"low-priority machine check",
"instruction TLB miss fault",
- "instruction protection trap",
- "Illegal instruction trap",
- "break instruction trap",
- "privileged operation trap",
- "privileged register trap",
- "overflow trap",
- "conditional trap",
- "assist exception trap",
- "data TLB miss fault",
- "ITLB non-access miss fault",
- "DTLB non-access miss fault",
- "data protection trap/unalligned data reference trap",
- "data break trap",
- "TLB dirty bit trap",
- "page reference trap",
- "assist emulation trap",
- "higher-privelege transfer trap",
- "lower-privilege transfer trap",
- "taken branch trap",
- "data access rights trap",
- "data protection ID trap",
- "unaligned data ref trap",
- "reserved",
- "reserved 2"
+ "instruction protection",
+ "Illegal instruction",
+ "break instruction",
+ "privileged operation",
+ "privileged register",
+ "overflow",
+ "conditional",
+ "assist exception",
+ "data TLB miss",
+ "ITLB non-access miss",
+ "DTLB non-access miss",
+ "data protection/rights/alignment",
+ "data break",
+ "TLB dirty bit",
+ "page reference",
+ "assist emulation",
+ "higher-privelege transfer",
+ "lower-privilege transfer",
+ "taken branch",
+ "data access rights",
+ "data protection ID",
+ "unaligned data ref",
};
int trap_types = sizeof(trap_type)/sizeof(trap_type[0]);
@@ -146,7 +151,8 @@ trap(type, frame)
struct trapframe *frame;
{
struct proc *p = curproc;
- register vm_offset_t va;
+ struct pcb *pcbp;
+ register vaddr_t va;
register vm_map_t map;
register vm_prot_t vftype;
register pa_space_t space;
@@ -154,57 +160,53 @@ trap(type, frame)
int ret;
union sigval sv;
int s, si;
+ const char *tts;
+ opcode = frame->tf_iir;
if (type == T_ITLBMISS || type == T_ITLBMISSNA) {
va = frame->tf_iioq_head;
space = frame->tf_iisq_head;
+ vftype = VM_PROT_EXECUTE;
} else {
va = frame->tf_ior;
space = frame->tf_isr;
+ vftype = FAULT_TYPE(opcode);
}
- opcode = frame->tf_iir;
- vftype = FAULT_TYPE(opcode);
- if (USERMODE(frame->tf_iioq_head)) {
- type |= T_USER;
+ if (frame->tf_flags & TFF_LAST)
p->p_md.md_regs = frame;
- }
+
#ifdef TRAPDEBUG
+ if ((type & ~T_USER) > trap_types)
+ tts = "reserved";
+ else
+ tts = trap_type[type & ~T_USER];
+
if ((type & ~T_USER) != T_INTERRUPT &&
(type & ~T_USER) != T_IBREAK)
- printf ("trap: %d, %s for %x:%x at %x:%x\n",
- type, trap_type[type & ~T_USER], space, va,
- frame->tf_iisq_head, frame->tf_iioq_head);
+ db_printf("trap: %d, %s for %x:%x at %x:%x, fl=%x, fp=%p\n",
+ type, tts, space, va, frame->tf_iisq_head,
+ frame->tf_iioq_head, frame->tf_flags, frame);
else if ((type & ~T_USER) == T_IBREAK)
- printf ("trap: break instruction %x:%x at %x:%x\n",
- break5(opcode), break13(opcode),
- frame->tf_iisq_head, frame->tf_iioq_head);
+ db_printf("trap: break instruction %x:%x at %x:%x, fp=%p\n",
+ break5(opcode), break13(opcode),
+ frame->tf_iisq_head, frame->tf_iioq_head, frame);
#endif
switch (type) {
case T_NONEXIST:
case T_NONEXIST|T_USER:
+#ifndef DDB
/* we've got screwed up by the central scrutinizer */
- panic ("trap: zombie's on the bridge!!!");
+ panic ("trap: elvis has just left the building!");
break;
-
+#endif
case T_RECOVERY:
case T_RECOVERY|T_USER:
+#ifndef DDB
/* XXX will implement later */
printf ("trap: handicapped");
break;
-
-#ifdef DIAGNOSTIC
- case T_HPMC:
- case T_HPMC | T_USER:
- case T_EXCEPTION:
- case T_EMULATION:
- case T_TLB_DIRTY:
- case T_TLB_DIRTY | T_USER:
- panic ("trap: impossible \'%s\' (%d)",
- trap_type[type & ~T_USER], type);
- break;
#endif
-
case T_IBREAK:
case T_DATALIGN:
case T_DBREAK:
@@ -217,10 +219,30 @@ trap(type, frame)
}
return;
}
+#else
+ if (type == T_DATALIGN)
+ panic ("trap: %s at 0x%x", tts, va);
+ else
+ panic ("trap: no debugger for \"%s\" (%d)", tts, type);
#endif
- /* probably panic otherwise */
break;
+#ifdef DIAGNOSTIC
+ /* these just can't happen ever */
+ case T_PRIV_OP:
+ case T_PRIV_REG:
+ panic ("loss of mind");
+ break;
+
+ /* these just can't make it to the trap() ever */
+ case T_HPMC: case T_HPMC | T_USER:
+ case T_EXCEPTION:
+ case T_EMULATION:
+ case T_TLB_DIRTY: case T_TLB_DIRTY | T_USER:
+ panic ("trap: impossible \'%s\' (%d)", tts, type);
+ break;
+#endif
+
case T_IBREAK | T_USER:
case T_DBREAK | T_USER:
/* pass to user debugger */
@@ -228,12 +250,12 @@ trap(type, frame)
case T_EMULATION | T_USER:
case T_EXCEPTION | T_USER: /* co-proc assist trap */
- sv.sival_int = frame->tf_ior;
+ sv.sival_int = va;
trapsignal(p, SIGFPE, type &~ T_USER, FPE_FLTINV, sv);
break;
case T_OVERFLOW | T_USER:
- sv.sival_int = frame->tf_ior;
+ sv.sival_int = va;
trapsignal(p, SIGFPE, type &~ T_USER, FPE_INTOVF, sv);
break;
@@ -241,24 +263,24 @@ trap(type, frame)
break;
case T_ILLEGAL | T_USER:
- sv.sival_int = frame->tf_ior;
+ sv.sival_int = va;
trapsignal(p, SIGILL, type &~ T_USER, ILL_ILLOPC, sv);
break;
case T_PRIV_OP | T_USER:
- sv.sival_int = frame->tf_ior;
+ sv.sival_int = va;
trapsignal(p, SIGILL, type &~ T_USER, ILL_PRVOPC, sv);
break;
case T_PRIV_REG | T_USER:
- sv.sival_int = frame->tf_ior;
+ sv.sival_int = va;
trapsignal(p, SIGILL, type &~ T_USER, ILL_PRVREG, sv);
break;
/* these should never got here */
case T_HIGHERPL | T_USER:
case T_LOWERPL | T_USER:
- sv.sival_int = frame->tf_ior;
+ sv.sival_int = va;
trapsignal(p, SIGSEGV, type &~ T_USER, SEGV_ACCERR, sv);
break;
@@ -268,43 +290,59 @@ trap(type, frame)
trapsignal(p, SIGSEGV, vftype, SEGV_ACCERR, sv);
break;
- case T_IPROT:
case T_DPROT:
- case T_ITLBMISS:
- case T_ITLBMISS | T_USER:
- case T_ITLBMISSNA:
- case T_ITLBMISSNA | T_USER:
- case T_DTLBMISS:
- case T_DTLBMISS | T_USER:
- case T_DTLBMISSNA:
- case T_DTLBMISSNA | T_USER:
-#if 0
-if (kdb_trap (type, 0, frame))
-return;
-break;
-#endif
+ case T_IPROT:
+ case T_DATACC: case T_DATACC | T_USER:
+ case T_ITLBMISS: case T_ITLBMISS | T_USER:
+ case T_DTLBMISS: case T_DTLBMISS | T_USER:
+ case T_ITLBMISSNA: case T_ITLBMISSNA | T_USER:
+ case T_DTLBMISSNA: case T_DTLBMISSNA | T_USER:
va = trunc_page(va);
map = &p->p_vmspace->vm_map;
- ret = uvm_fault(map, va, vftype, FALSE);
+ ret = uvm_fault(map, va, 0, vftype);
if (ret != KERN_SUCCESS) {
if (type & T_USER) {
+printf("trapsignal: uvm_fault\n");
sv.sival_int = frame->tf_ior;
trapsignal(p, SIGSEGV, vftype, SEGV_MAPERR, sv);
- } else
- panic ("trap: uvm_fault(%p, %x, %d, %d): %d",
- map, frame->tf_ior, vftype, 0, ret);
+ } else {
+ pcbp = &p->p_addr->u_pcb;
+ if (p && pcbp->pcb_onfault) {
+#if PMAPDEBUG
+ printf("trap: copyin/copyout\n");
+#endif
+ frame->tf_iioq_tail =
+ frame->tf_iioq_head =
+ pcbp->pcb_onfault;
+ pcbp->pcb_onfault = 0;
+ break;
+ }
+#if 1
+if (kdb_trap (type, 0, frame))
+ return;
+#else
+ panic("trap: uvm_fault(%p, %x, %d, %d): %d",
+ map, va, vftype, FALSE, ret);
+#endif
+ }
}
+if (type == (T_DATACC|T_USER) && kdb_trap (type, 0, frame))
+ return;
break;
case T_DATALIGN | T_USER:
- sv.sival_int = frame->tf_ior;
+ sv.sival_int = va;
trapsignal(p, SIGBUS, vftype, BUS_ADRALN, sv);
break;
case T_INTERRUPT:
case T_INTERRUPT|T_USER:
cpu_intr(frame);
+#if 0
+if (kdb_trap (type, 0, frame))
+return;
+#endif
/* FALLTHROUGH */
case T_LOWERPL:
__asm __volatile ("ldcws 0(%1), %0"
@@ -369,22 +407,22 @@ break;
case T_OVERFLOW:
case T_CONDITION:
case T_ILLEGAL:
- case T_PRIV_OP:
- case T_PRIV_REG:
case T_HIGHERPL:
case T_TAKENBR:
case T_POWERFAIL:
case T_LPMC:
case T_PAGEREF:
- case T_DATACC: case T_DATACC | T_USER:
- case T_DATAPID: case T_DATAPID | T_USER:
+ case T_DATAPID: case T_DATAPID | T_USER:
if (0 /* T-chip */) {
break;
}
/* FALLTHROUGH to unimplemented */
default:
- panic ("trap: unimplemented \'%s\' (%d)",
- trap_type[type & ~T_USER], type);
+#if 1
+if (kdb_trap (type, 0, frame))
+ return;
+#endif
+ panic ("trap: unimplemented \'%s\' (%d)", tts, type);
}
if (type & T_USER)
@@ -425,18 +463,19 @@ syscall(frame, args)
panic("syscall");
p = curproc;
+ p->p_md.md_regs = frame;
nsys = p->p_emul->e_nsysent;
callp = p->p_emul->e_sysent;
- code = frame->tf_arg0;
+ code = frame->tf_t1;
switch (code) {
case SYS_syscall:
- code = frame->tf_arg1;
+ code = frame->tf_arg0;
args += 1;
break;
case SYS___syscall:
if (callp != sysent)
break;
- code = frame->tf_arg1; /* XXX or arg2? */
+ code = frame->tf_arg0; /* XXX or arg1? */
args += 2;
}
@@ -458,10 +497,10 @@ syscall(frame, args)
rval[1] = 0;
switch (error = (*callp->sy_call)(p, args, rval)) {
case 0:
- /* curproc may change iside the fork() */
- p = curproc;
+ /* curproc may change inside the fork() */
frame->tf_ret0 = rval[0];
frame->tf_ret1 = rval[1];
+ frame->tf_t1 = 0;
break;
case ERESTART:
frame->tf_iioq_head -= 4; /* right? XXX */
@@ -471,14 +510,14 @@ syscall(frame, args)
default:
if (p->p_emul->e_errno)
error = p->p_emul->e_errno[error];
- frame->tf_ret0 = error;
+ frame->tf_t1 = error;
break;
}
-
+ p = curproc;
#ifdef SYSCALL_DEBUG
scdebug_ret(p, code, error, rval);
#endif
- userret(p, p->p_md.md_regs->tf_rp, 0);
+ userret(p, p->p_md.md_regs->tf_iioq_head, 0);
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSRET))
ktrsysret(p->p_tracep, code, error, rval[0]);
@@ -532,7 +571,7 @@ cpu_intr(frame)
/* ((struct iomod *)cpu_gethpa(0))->io_eir = 0; */
#ifdef INTRDEBUG
if (bit != 31)
- printf ("cpu_intr: 0x%08x\n", (1 << bit));
+ db_printf ("cpu_intr: 0x%08x\n", (1 << bit));
#endif
iv = &cpu_intr_vectors[bit];
if (iv->handler) {
@@ -545,12 +584,11 @@ cpu_intr(frame)
splx(s);
#ifdef DEBUG
if (!r)
- printf ("%s: can't handle interrupt\n",
- iv->evcnt.ev_name);
+ db_printf ("%s: can't handle interrupt\n",
+ iv->evcnt.ev_name);
#endif
} else
- printf ("cpu_intr: stray interrupt %d\n", bit);
+ db_printf ("cpu_intr: stray interrupt %d\n", bit);
}
} while (eirr);
}
-