From 3b5ade97eea1f23f371fc0a299c1bbc6a3113fe4 Mon Sep 17 00:00:00 2001 From: Michael Shalayeff Date: Thu, 25 Nov 1999 18:36:30 +0000 Subject: many traps, syscall nad other stuff --- sys/arch/hppa/hppa/trap.c | 238 +++++++++++++++++++++++++++------------------- 1 file changed, 138 insertions(+), 100 deletions(-) (limited to 'sys/arch/hppa') 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 #include #include -#include #include -#define FAULT_TYPE(op) (VM_PROT_READ|(inst_load(op) ? 0 : VM_PROT_WRITE)) +#ifdef DDB +#include +#endif + +#if defined(INTRDEBUG) || defined(TRAPDEBUG) +#include +#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); } - -- cgit v1.2.3