diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 12:19:02 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 12:19:02 +0000 |
commit | faa2e7b8593c88a15c2f785b07fc1274a1d7ebb2 (patch) | |
tree | 72260ad15e058f2d21a742392017da879a4270a1 /sys/arch | |
parent | e2ee22e36c35aee11cc652e343fe97c652ee7cac (diff) |
SUNOS_SYS_sunos_sigreturn -> SUNOS_SYS_sigreturn
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/mvme68k/mvme68k/trap.c | 171 |
1 files changed, 146 insertions, 25 deletions
diff --git a/sys/arch/mvme68k/mvme68k/trap.c b/sys/arch/mvme68k/mvme68k/trap.c index 3111b80c72c..4ac50ce8d39 100644 --- a/sys/arch/mvme68k/mvme68k/trap.c +++ b/sys/arch/mvme68k/mvme68k/trap.c @@ -1,6 +1,7 @@ -/* $NetBSD: trap.c,v 1.2.2.1 1995/10/12 00:43:38 chuck Exp $ */ +/* $NetBSD: trap.c,v 1.36 1995/05/12 18:24:53 mycroft Exp $ */ /* + * Copyright (c) 1995 Theo de Raadt * Copyright (c) 1988 University of Utah. * Copyright (c) 1982, 1986, 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -61,16 +62,17 @@ #include <machine/cpu.h> #include <machine/reg.h> +#ifdef COMPAT_SUNOS +#include <compat/sunos/sunos_syscall.h> +extern struct emul emul_sunos; +#endif + #include <vm/vm.h> #include <vm/pmap.h> #ifdef COMPAT_HPUX #include <compat/hpux/hpux.h> #endif -#ifdef COMPAT_SUNOS -#include <compat/sunos/sunos_syscall.h> - extern struct emul emul_sunos; -#endif char *trap_type[] = { "Bus error", @@ -128,10 +130,10 @@ int mmupid = -1; #define MDB_ISPID(p) (p) == mmupid #endif -#define NSIR 32 +#define NSIR 8 void (*sir_routines[NSIR])(); void *sir_args[NSIR]; -int next_sir; +u_char next_sir; /* * trap and syscall both need the following work done before returning @@ -225,7 +227,7 @@ trap(type, code, v, frame) { extern char fubail[], subail[]; #ifdef DDB - extern char trap0[], trap1[], trap2[], trap12[], trap15[], illinst[]; + extern int trap0, trap1, trap2, trap12, trap15, illinst; #endif register struct proc *p; register int i; @@ -235,6 +237,9 @@ trap(type, code, v, frame) extern struct emul emul_hpux; #endif int bit; +#ifdef COMPAT_SUNOS + extern struct emul emul_sunos; +#endif cnt.v_trap++; p = curproc; @@ -260,7 +265,7 @@ dopanic: panic("trap"); case T_BUSERR: /* kernel bus error */ - if (!p->p_addr->u_pcb.pcb_onfault) + if (!p || !p->p_addr->u_pcb.pcb_onfault) goto dopanic; /* * If we have arranged to catch this fault in any of the @@ -407,12 +412,9 @@ copyfault: case T_TRAP15: /* SUN trace trap */ #ifdef DDB if (type == T_TRAP15 || - ((caddr_t)frame.f_pc != trap0 && - (caddr_t)frame.f_pc != trap1 && - (caddr_t)frame.f_pc != trap2 && - (caddr_t)frame.f_pc != trap12 && - (caddr_t)frame.f_pc != trap15 && - (caddr_t)frame.f_pc != illinst)) { + (frame.f_pc != trap0 && frame.f_pc != trap1 && + frame.f_pc != trap2 && frame.f_pc != trap12 && + frame.f_pc != trap15 && frame.f_pc != illinst)) { if (kdb_trap(type, &frame)) return; } @@ -423,6 +425,18 @@ copyfault: case T_TRACE|T_USER: /* user trace trap */ case T_TRAP15|T_USER: /* SUN user trace trap */ +#ifdef COMPAT_SUNOS + /* + * XXX This comment/code is not consistent XXX + * SunOS seems to use Trap #2 for some obscure + * fpu operations. So far, just ignore it, but + * DONT trap on it.. + */ + if (p->p_emul == &emul_sunos) { + userret(p, frame.f_pc, sticks); + return; + } +#endif frame.f_sr &= ~PSL_T; i = SIGTRAP; break; @@ -452,7 +466,6 @@ copyfault: if (sir_routines[bit]) sir_routines[bit](sir_args[bit]); } - /* * If this was not an AST trap, we are all done. */ @@ -472,20 +485,24 @@ copyfault: * If we were doing profiling ticks or other user mode * stuff from interrupt code, Just Say No. */ - if (p->p_addr->u_pcb.pcb_onfault == fubail || - p->p_addr->u_pcb.pcb_onfault == subail) + if (p && (p->p_addr->u_pcb.pcb_onfault == fubail || + p->p_addr->u_pcb.pcb_onfault == subail)) goto copyfault; /* fall into ... */ case T_MMUFLT|T_USER: /* page fault */ { register vm_offset_t va; - register struct vmspace *vm = p->p_vmspace; + register struct vmspace *vm = NULL; register vm_map_t map; int rv; vm_prot_t ftype; extern vm_map_t kernel_map; + /* vmspace only significant if T_USER */ + if (p) + vm = p->p_vmspace; + #ifdef DEBUG if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n", @@ -500,7 +517,7 @@ copyfault: * argument space is lazy-allocated. */ if (type == T_MMUFLT && - (!p->p_addr->u_pcb.pcb_onfault || KDFAULT(code))) + ((p && !p->p_addr->u_pcb.pcb_onfault) || KDFAULT(code))) map = kernel_map; else map = &vm->vm_map; @@ -509,12 +526,11 @@ copyfault: else ftype = VM_PROT_READ; va = trunc_page((vm_offset_t)v); -#ifdef DEBUG + if (map == kernel_map && va == 0) { printf("trap: bad kernel access at %x\n", v); goto dopanic; } -#endif #ifdef COMPAT_HPUX if (ISHPMMADDR(va)) { vm_offset_t bva; @@ -562,7 +578,7 @@ copyfault: goto out; } if (type == T_MMUFLT) { - if (p->p_addr->u_pcb.pcb_onfault) + if (p && p->p_addr->u_pcb.pcb_onfault) goto copyfault; printf("vm_fault(%x, %x, %x, 0) -> %x\n", map, va, ftype, rv); @@ -908,6 +924,9 @@ syscall(code, frame) size_t argsize; register_t args[8], rval[2]; u_quad_t sticks; +#ifdef COMPAT_SUNOS + extern struct emul emul_sunos; +#endif cnt.v_syscall++; if (!USERMODE(frame.f_sr)) @@ -1051,7 +1070,7 @@ child_return(p, frame) frame.f_sr &= ~PSL_C; frame.f_format = FMT0; - userret(p, &frame, p->p_sticks, (u_int)0, 0); + userret(p, &frame, 0, (u_int)0, 0); #ifdef KTRACE if (KTRPOINT(p, KTR_SYSRET)) ktrsysret(p->p_tracep, SYS_fork, 0, 0); @@ -1068,7 +1087,7 @@ allocate_sir(proc, arg) { int bit; - if( next_sir >= NSIR ) + if (next_sir >= NSIR) panic("allocate_sir: none left"); bit = next_sir++; sir_routines[bit] = proc; @@ -1085,3 +1104,105 @@ init_sir() sir_routines[1] = softclock; next_sir = 2; } + +struct intrhand *intrs[256]; + +/* + * XXX + * This is an EXTREMELY good candidate for rewriting in assembly!! + */ +#ifndef INTR_ASM +int +hardintr(pc, evec, frame) + int pc; + int evec; + void *frame; +{ + int vec = (evec & 0xfff) >> 2; /* XXX should be m68k macro? */ + extern u_long intrcnt[]; /* XXX from locore */ + struct intrhand *ih; + int r; + + cnt.v_intr++; +/* intrcnt[level]++; */ + for (ih = intrs[vec]; ih; ih = ih->ih_next) { + r = (*ih->ih_fn)(ih->ih_wantframe ? frame : ih->ih_arg); + if (r > 0) + return; + } + return (straytrap(pc, evec)); +} +#endif /* !INTR_ASM */ + +/* + * Chain the interrupt handler in. But first check if the vector + * offset chosen is legal. It either must be a badtrap (not allocated + * for a `system' purpose), or it must be a hardtrap (ie. already + * allocated to deal with chained interrupt handlers). + */ +int +intr_establish(vec, ih) + int vec; + struct intrhand *ih; +{ + extern u_long *vectab[], hardtrap, badtrap; + struct intrhand *ihx; + + if (vectab[vec] != &badtrap && vectab[vec] != &hardtrap) { + printf("intr_establish: vec %d unavailable\n", vec); + return (-1); + } + vectab[vec] = &hardtrap; + + ih->ih_next = NULL; /* just in case */ + + /* attach at tail */ + if (ihx = intrs[vec]) { + while (ihx->ih_next) + ihx = ihx->ih_next; + ihx->ih_next = ih; + } else + intrs[vec] = ih; + return (0); +} + +/* + * find a useable vector for devices that don't specify one + */ +int +intr_freevec() +{ + extern u_long *vectab[], hardtrap, badtrap; + int i; + + for (i = 255; i; --i) + if (vectab[i] == &badtrap) + return (i); + for (i = 255; i; --i) + if (vectab[i] == &hardtrap) + return (i); + return (-1); +} + +#ifdef DDB +#include <sys/reboot.h> +#include <machine/db_machdep.h> +#include <ddb/db_command.h> + +void +db_prom_cmd() +{ + doboot(); +} + +struct db_command db_machine_cmds[] = { + { "prom", db_prom_cmd, 0, 0 }, + { (char *)0, } +}; + +void +db_machine_init() +{ + db_machine_commands_install(db_machine_cmds); +} +#endif /* DDB */ |