diff options
author | Steve Murphree <smurph@cvs.openbsd.org> | 2001-12-22 10:34:33 +0000 |
---|---|---|
committer | Steve Murphree <smurph@cvs.openbsd.org> | 2001-12-22 10:34:33 +0000 |
commit | eb78418217a02e517a60da5262664deadd9d4916 (patch) | |
tree | 2f24a195e87c34ef9793ea1fe05ccefb12313109 /sys/arch/mvme88k | |
parent | 249b4abccd246f617da9ef25d49ae789cf442e3e (diff) |
mc88110 modifications.
Diffstat (limited to 'sys/arch/mvme88k')
-rw-r--r-- | sys/arch/mvme88k/mvme88k/trap.c | 428 |
1 files changed, 220 insertions, 208 deletions
diff --git a/sys/arch/mvme88k/mvme88k/trap.c b/sys/arch/mvme88k/mvme88k/trap.c index 606cbe43f41..fdd18259bc8 100644 --- a/sys/arch/mvme88k/mvme88k/trap.c +++ b/sys/arch/mvme88k/mvme88k/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.30 2001/12/20 06:07:28 smurph Exp $ */ +/* $OpenBSD: trap.c,v 1.31 2001/12/22 10:34:32 smurph Exp $ */ /* * Copyright (c) 1998 Steve Murphree, Jr. * Copyright (c) 1996 Nivas Madhur @@ -57,13 +57,13 @@ #include <machine/asm_macro.h> /* enable/disable interrupts */ #include <machine/bugio.h> /* bugreturn() */ -#include <machine/cpu.h> /* DMT_VALID, etc. */ +#include <machine/cpu.h> #include <machine/locore.h> #ifdef M88100 -#include <machine/m88100.h> /* DMT_VALID, etc. */ +#include <machine/m88100.h> #endif #ifdef M88110 -#include <machine/m88110.h> /* DMT_VALID, etc. */ +#include <machine/m88110.h> #endif #include <machine/pcb.h> /* FIP_E, etc. */ #include <machine/psl.h> /* FIP_E, etc. */ @@ -73,8 +73,10 @@ #include <machine/db_machdep.h> #include <ddb/db_output.h> /* db_printf() */ #else -#define PC_REGS(regs) ((regs->sxip & 2) ? regs->sxip & ~3 : \ + #define PC_REGS(regs) cputyp == CPU_88110 ? (regs->exip & ~3) :\ + ((regs->sxip & 2) ? regs->sxip & ~3 : \ (regs->snip & 2 ? regs->snip & ~3 : regs->sfip & ~3)) + #define inst_return(I) (((I)&0xfffffbffU) == 0xf400c001U ? TRUE : FALSE) #define inst_call(I) ({ unsigned i = (I); \ ((((i) & 0xf8000000U) == 0xc8000000U || /*bsr*/ \ @@ -103,6 +105,9 @@ unsigned traptrace = 0; extern int procfs_domem __P((struct proc *, struct proc *, void *, struct uio *)); extern void regdump __P((struct trapframe *f)); +void error_fatal __P((struct m88100_saved_state *frame)); +void error_fault __P((struct m88100_saved_state *frame)); +void error_reset __P((struct m88100_saved_state *frame)); char *trap_type[] = { "Reset", @@ -116,6 +121,7 @@ char *trap_type[] = { "Illegal Integer Divide", "Integer Overflow", "Error Exception", + "Non-Maskable Exception", }; char *pbus_exception_type[] = { @@ -164,6 +170,7 @@ panictrap(int type, struct m88100_saved_state *frame) static int panicing = 0; if (panicing++ == 0) { + if (cputyp != CPU_88110) { if (type == 2) { /* instruction exception */ DEBUG_MSG("\nInstr access fault (%s) v = %x, frame %x\n", pbus_exception_type[(frame->ipfsr >> 16) & 0x7], @@ -174,6 +181,7 @@ panictrap(int type, struct m88100_saved_state *frame) frame->sxip & ~3, frame); } else DEBUG_MSG("\ntrap type %d, v = %x, frame %x\n", type, frame->sxip & ~3, frame); + } regdump(frame); } if ((u_int)type < trap_types) @@ -182,7 +190,7 @@ panictrap(int type, struct m88100_saved_state *frame) /*NOTREACHED*/ } -#if defined(MVME187) || defined(MVME188) +#ifdef M88100 unsigned last_trap[4] = {0,0,0,0}; unsigned last_vector = 0; @@ -200,7 +208,7 @@ trap18x(unsigned type, struct m88100_saved_state *frame) unsigned nss, fault_addr; struct vmspace *vm; union sigval sv; - int result; + int result = 0; int sig = 0; unsigned pc = PC_REGS(frame); /* get program counter (sxip) */ @@ -272,7 +280,7 @@ trap18x(unsigned type, struct m88100_saved_state *frame) case T_INT+T_USER: /* This function pointer is set in machdep.c It calls m188_ext_int or sbc_ext_int depending - on the value of cputyp - smurph */ + on the value of brdtyp - smurph */ (*md.interrupt_func)(T_INT, frame); return; @@ -353,7 +361,7 @@ trap18x(unsigned type, struct m88100_saved_state *frame) (frame->sxip & ~3) >= (unsigned)&guarded_access_start && (frame->sxip & ~3) <= (unsigned)&guarded_access_end) { - frame->snip = ((unsigned)&guarded_access_bad ) | FIP_V; + frame->snip = ((unsigned)&guarded_access_bad ) | NIP_V; frame->sfip = ((unsigned)&guarded_access_bad + 4) | FIP_V; frame->sxip = 0; /* We sort of resolved the fault ourselves because @@ -676,9 +684,9 @@ outtahere: userret(p, frame, sticks); } -#endif /* defined(MVME187) || defined(MVME188) */ +#endif /* m88100 */ -#ifdef MVME197 +#ifdef M88110 /*ARGSUSED*/ void trap197(unsigned type, struct m88100_saved_state *frame) @@ -693,14 +701,16 @@ trap197(unsigned type, struct m88100_saved_state *frame) unsigned nss, fault_addr; struct vmspace *vm; union sigval sv; - int result; + int s; /* IPL */ + int result = 0; /* Assume Success */ int sig = 0; - unsigned pc = PC_REGS(frame); /* get program counter (sxip) */ - unsigned user = 0, write = 0, data = 0; - + unsigned pc = PC_REGS(frame); /* get program counter (exip) */ + unsigned user = 0, data = 0; + pt_entry_t *pte; extern struct vm_map *kernel_map; extern unsigned guarded_access_start; extern unsigned guarded_access_end; + extern pt_entry_t *pmap_pte __P((pmap_t, vm_offset_t)); uvmexp.traps++; @@ -713,147 +723,62 @@ trap197(unsigned type, struct m88100_saved_state *frame) p->p_md.md_tf = frame; /* for ptrace/signals */ fault_type = 0; fault_code = 0; + user = 1; } - printf("m197_trap 0x%x ", type); + switch (type) { default: panictrap(frame->vector, frame); /*NOTREACHED*/ case T_197_READ+T_USER: - user = 1; case T_197_READ: - va = (vm_offset_t) frame->dlar; - /* if it was a user read, handle in context of the user */ - if ((frame->dsr & CMMU_DSR_SU) && !user) { - map = kernel_map; - } else { - vm = p->p_vmspace; - map = &vm->vm_map; - } - result = m197_table_search(map->pmap, va, CMMU_READ, user, CMMU_DATA); - if (result) { - switch (result) { - case 4: /* Seg Fault */ - frame->dsr |= CMMU_DSR_SI | CMMU_DSR_RW; - break; - case 5: /* Page Fault */ - frame->dsr |= CMMU_DSR_PI | CMMU_DSR_RW; - break; - case 6: /* Supervisor Violation */ - frame->dsr |= CMMU_DSR_SP | CMMU_DSR_RW; - break; - } - /* table search failed and we are going to report a data fault */ - if (user) { - type = T_DATAFLT+T_USER; - goto m197_user_fault; - } else { - type = T_DATAFLT; - goto m197_data_fault; - } - } else { - return; /* PATC sucessfully loaded */ - } - break; + DEBUG_MSG("DMMU read miss: Hardware Table Searches should be enabled!\n"); + panictrap(frame->vector, frame); + /*NOTREACHED*/ case T_197_WRITE+T_USER: - user = 1; case T_197_WRITE: - /* if it was a user read, handle in context of the user */ - if ((frame->dsr & CMMU_DSR_SU) && !user) { - map = kernel_map; - } else { - vm = p->p_vmspace; - map = &vm->vm_map; - } - va = (vm_offset_t) frame->dlar; - result = m197_table_search(map->pmap, va, CMMU_WRITE, user, CMMU_DATA); - if (result) { - switch (result) { - case 4: /* Seg Fault */ - frame->dsr |= CMMU_DSR_SI; - break; - case 5: /* Page Fault */ - frame->dsr |= CMMU_DSR_PI; - break; - case 6: /* Supervisor Violation */ - frame->dsr |= CMMU_DSR_SP; - break; - case 7: /* Write Violation */ - frame->dsr |= CMMU_DSR_WE; - break; - } - /* table search failed and we are going to report a data fault */ - if (user) { - type = T_DATAFLT+T_USER; - goto m197_user_fault; - } else { - type = T_DATAFLT; - goto m197_data_fault; - } - } else { - return; /* PATC sucessfully loaded */ - } - break; + DEBUG_MSG("DMMU write miss: Hardware Table Searches should be enabled!\n"); + panictrap(frame->vector, frame); + /*NOTREACHED*/ case T_197_INST+T_USER: - user = 1; case T_197_INST: - /* if it was a user read, handle in context of the user */ - if ((frame->isr & CMMU_ISR_SU) && !user) { - map = kernel_map; - } else { - vm = p->p_vmspace; - map = &vm->vm_map; - } - va = (vm_offset_t) frame->sxip; - result = m197_table_search(map->pmap, va, CMMU_READ, user, CMMU_INST); - if (result) { - switch (result) { - case 4: /* Seg Fault */ - frame->isr |= CMMU_ISR_SI; - break; - case 5: /* Page Fault */ - frame->isr |= CMMU_ISR_PI; - break; - case 6: /* Supervisor Violation */ - frame->isr |= CMMU_ISR_SP; - break; - } - /* table search failed and we are going to report a data fault */ - if (user) { - type = T_INSTFLT+T_USER; - goto m197_user_fault; - } else { - type = T_INSTFLT; - goto m197_inst_fault; - } - } else { - return; /* PATC sucessfully loaded */ - } - break; + DEBUG_MSG("IMMU miss: Hardware Table Searches should be enabled!\n"); + panictrap(frame->vector, frame); + /*NOTREACHED*/ #if defined(DDB) + case T_KDB_TRACE: + frame->mask = spl(); /* get current spl for reg dump */ + s = db_splhigh(); + db_enable_interrupt(); + ddb_break_trap(T_KDB_TRACE,(db_regs_t*)frame); + db_disable_interrupt(); + db_splx(s); + return; case T_KDB_BREAK: /*FALLTHRU*/ case T_KDB_BREAK+T_USER: - { - int s = db_splhigh(); + frame->mask = spl(); /* get current spl for reg dump */ + s = db_splhigh(); db_enable_interrupt(); ddb_break_trap(T_KDB_BREAK,(db_regs_t*)frame); db_disable_interrupt(); db_splx(s); return; - } case T_KDB_ENTRY: /*FALLTHRU*/ case T_KDB_ENTRY+T_USER: - { - int s = db_splhigh(); + frame->mask = spl(); /* get current spl for reg dump */ + s = db_splhigh(); db_enable_interrupt(); ddb_entry_trap(T_KDB_ENTRY,(db_regs_t*)frame); db_disable_interrupt(); + if (frame->enip) { + frame->exip = frame->enip; + } else { + frame->exip += 4; + } db_splx(s); return; - } - #if 0 case T_ILLFLT: { @@ -868,26 +793,33 @@ trap197(unsigned type, struct m88100_saved_state *frame) #endif /* 0 */ #endif /* DDB */ case T_ILLFLT: - DEBUG_MSG("test trap " - "page fault @ 0x%08x\n", frame->sxip); + DEBUG_MSG("Unimplemented opcode!\n"); panictrap(frame->vector, frame); break; - + case T_NON_MASK: + case T_NON_MASK+T_USER: + /* This function pointer is set in machdep.c + It calls m197_ext_int - smurph */ + (*md.interrupt_func)(T_NON_MASK, frame); + return; + case T_INT: + case T_INT+T_USER: + (*md.interrupt_func)(T_INT, frame); + return; case T_MISALGNFLT: - DEBUG_MSG("kernel misaligned " - "access exception @ 0x%08x\n", frame->sxip); + DEBUG_MSG("kernel mode misaligned " + "access exception @ 0x%08x\n", frame->exip); panictrap(frame->vector, frame); - break; + /*NOTREACHED*/ case T_INSTFLT: - m197_inst_fault: /* kernel mode instruction access fault. * Should never, never happen for a non-paged kernel. */ DEBUG_MSG("kernel mode instruction " - "page fault @ 0x%08x\n", frame->sxip); + "page fault @ 0x%08x\n", frame->exip); panictrap(frame->vector, frame); - break; + /*NOTREACHED*/ case T_DATAFLT: /* kernel mode data fault */ @@ -895,7 +827,6 @@ trap197(unsigned type, struct m88100_saved_state *frame) * If the faulting address is in user space, handle it in * the context of the user process. Else, use kernel map. */ - m197_data_fault: if (type == T_DATAFLT) { fault_addr = frame->dlar; if (frame->dsr & CMMU_DSR_RW) { @@ -904,11 +835,10 @@ trap197(unsigned type, struct m88100_saved_state *frame) } else { ftype = VM_PROT_READ|VM_PROT_WRITE; fault_code = VM_PROT_WRITE; - write = 1; } data = 1; } else { - fault_addr = frame->sxip & XIP_ADDR; + fault_addr = frame->exip & XIP_ADDR; ftype = VM_PROT_READ; fault_code = VM_PROT_READ; } @@ -935,12 +865,12 @@ trap197(unsigned type, struct m88100_saved_state *frame) if (p->p_addr->u_pcb.pcb_onfault == (int)fubail || p->p_addr->u_pcb.pcb_onfault == (int)subail) - goto m197_outtahere; + goto m88110_outtahere; /* data fault on the user address */ if (type == T_DATAFLT && (frame->dsr & CMMU_DSR_SU) == 0) { type = T_DATAFLT + T_USER; - goto m197_user_fault; + goto m88110_user_fault; } /* @@ -948,21 +878,14 @@ trap197(unsigned type, struct m88100_saved_state *frame) */ if ((frame->dsr & CMMU_DSR_BE) && /* bus error */ - (frame->sxip & ~3) >= (unsigned)&guarded_access_start && - (frame->sxip & ~3) <= (unsigned)&guarded_access_end) { + (frame->exip & ~3) >= (unsigned)&guarded_access_start && + (frame->exip & ~3) <= (unsigned)&guarded_access_end) { return; } - /* * On a segment or a page fault, call vm_fault() to resolve * the fault. */ - result = m197_table_search(map->pmap, va, write, 1, data); -#ifdef todo - switch (result) { - case : - } -#endif if (type == T_DATAFLT) { if ((frame->dsr & CMMU_DSR_SI) /* seg fault */ || (frame->dsr & CMMU_DSR_PI)) { /* page fault */ @@ -971,6 +894,25 @@ trap197(unsigned type, struct m88100_saved_state *frame) return; } } + if (frame->dsr & CMMU_DSR_WE) { /* write fault */ + /* This could be a write protection fault or an + * exception to set the used and modified bits + * in the pte. Basicly, if we got a write error, + * then we already have a pte entry that faulted + * in from a previous seg fault or page fault. + * Get the pte and check the status of the + * modified and valid bits to determine if this + * indeed a real write fault. XXX smurph + */ + pte = pmap_pte(map->pmap, va); + if (pte == PT_ENTRY_NULL) + panic("NULL pte on write fault??"); + if (!pte->modified && !pte->prot) { + /* Set modified bit and try the write again. */ + pte->modified = 1; + return; + } + } } else { if ((frame->isr & CMMU_ISR_SI) /* seg fault */ || (frame->isr & CMMU_ISR_PI)) { /* page fault */ @@ -986,16 +928,16 @@ trap197(unsigned type, struct m88100_saved_state *frame) if (!p->p_addr->u_pcb.pcb_onfault) panictrap(frame->vector, frame); - m197_outtahere: - frame->sxip = ((unsigned)p->p_addr->u_pcb.pcb_onfault); +m88110_outtahere: + frame->exip = ((unsigned)p->p_addr->u_pcb.pcb_onfault); return; case T_INSTFLT+T_USER: /* User mode instruction access fault */ /*FALLTHRU*/ case T_DATAFLT+T_USER: - m197_user_fault: +m88110_user_fault: if (type == T_INSTFLT+T_USER) { - fault_addr = frame->sxip & XIP_ADDR; + fault_addr = frame->exip & XIP_ADDR; ftype = VM_PROT_READ; fault_code = VM_PROT_READ; } else { @@ -1014,23 +956,54 @@ trap197(unsigned type, struct m88100_saved_state *frame) vm = p->p_vmspace; map = &vm->vm_map; - /* Call vm_fault() to resolve non-bus error faults */ if (type == T_DATAFLT+T_USER) { - if ((frame->dsr & CMMU_DSR_SI) /* seg fault */ - || (frame->dsr & CMMU_DSR_PI)) { /* page fault */ + + if (frame->dsr & (CMMU_DSR_SI | /* seg fault */ + CMMU_DSR_PI)) { /* page fault */ result = uvm_fault(map, va, 0, ftype); - if (result == 0) { + if (result != 0) { + printf("Data Access Error @ 0x%x\n", va); + } + v_fault++; + } else if (frame->dsr & CMMU_DSR_BE) { /* bus error */ + result = EFAULT; + } else if ((frame->dsr & CMMU_DSR_CP) + || (frame->dsr & CMMU_DSR_WA)) { + result = 0; + } else if (frame->dsr & CMMU_DSR_WE) { /* write fault */ + /* This could be a write protection fault or an + * exception to set the used and modified bits + * in the pte. Basicly, if we got a write error, + * then we already have a pte entry that faulted + * in from a previous seg fault or page fault. + * Get the pte and check the status of the + * modified and valid bits to determine if this + * indeed a real write fault. XXX smurph + */ + pte = pmap_pte(vm_map_pmap(map), va); + if (pte == PT_ENTRY_NULL) + panic("NULL pte on write fault??"); + if (!pte->modified && !pte->prot) { + /* Set modified bit and try the write again. */ + pte->modified = 1; + /* invalidate ATCs to force table search */ + set_dcmd(CMMU_DCMD_INV_UATC); return; + } else { + /* This must be a real write protection fault */ + printf("Write protect???? mod = %d, wp = %d\n", pte->modified, pte->prot); + result = uvm_fault(map, va, 0, ftype); } } } else { if ((frame->isr & CMMU_ISR_SI) /* seg fault */ || (frame->isr & CMMU_ISR_PI)) { /* page fault */ result = uvm_fault(map, va, 0, ftype); - if (result == 0) { - return; - } + } else if ((frame->isr & CMMU_ISR_BE) + || (frame->isr & CMMU_ISR_SP) + || (frame->isr & CMMU_ISR_TBE)) { /* bus error */ + result = EACCES; } } @@ -1044,11 +1017,16 @@ trap197(unsigned type, struct m88100_saved_state *frame) } if (result != 0) { +#if 0 + printf("Access failed! result = %d\n\n", result); + frame->mode = v_fault; + regdump(frame); + Debugger(); sig = result == EACCES ? SIGBUS : SIGSEGV; - fault_type = result == EACCES ? BUS_ADRERR - : SEGV_MAPERR; - } else { - return; + fault_type = result == EACCES ? BUS_ADRERR : SEGV_MAPERR; +#else + result = 0; +#endif } break; case T_MISALGNFLT+T_USER: @@ -1137,9 +1115,6 @@ trap197(unsigned type, struct m88100_saved_state *frame) uio.uio_procp = curproc; } - frame->sfip = frame->snip; /* set up next FIP */ - frame->snip = frame->sxip; /* set up next NIP */ - frame->snip |= 2; /* set valid bit */ p->p_md.md_ss_addr = 0; sig = SIGTRAP; fault_type = TRAP_BRKPT; @@ -1151,8 +1126,6 @@ trap197(unsigned type, struct m88100_saved_state *frame) * breakpoint debugging. When we get this trap, we just * return a signal which gets caught by the debugger. */ - frame->sfip = frame->snip; /* set up the next FIP */ - frame->snip = frame->sxip; /* set up the next NIP */ sig = SIGTRAP; fault_type = TRAP_BRKPT; break; @@ -1180,6 +1153,7 @@ trap197(unsigned type, struct m88100_saved_state *frame) * deliver signal. */ frame->dsr = 0; + frame->isr = 0; } userret(p, frame, sticks); } @@ -1195,6 +1169,32 @@ test_trap(struct m88100_saved_state *frame) } void +error_fatal(struct m88100_saved_state *frame) +{ + switch (frame->vector) { + case 0: + DEBUG_MSG("\n[RESET EXCEPTION (Really Bad News[tm]) frame 0x%08x]\n", frame); + DEBUG_MSG("This is usually caused by a branch to a NULL function pointer.\n"); + DEBUG_MSG("e.g. jump to address 0. Use the debugger trace command to track it down.\n"); + break; + default: + DEBUG_MSG("\n[ERROR EXCEPTION (Bad News[tm]) frame 0x%08x]\n", frame); + DEBUG_MSG("This is usually an exception within an exception. The trap\n"); + DEBUG_MSG("frame shadow registers you are about to see are invalid.\n"); + DEBUG_MSG("(read totaly useless) But R1 to R31 might be interesting.\n"); + break; + } + regdump((struct trapframe*)frame); +#if DDB + Debugger(); + DEBUG_MSG("You really can't restart after exception %d!\n", frame->vector); + Debugger(); +#endif /* DDB */ + bugreturn(); /* This gets us to Bug instead of a loop forever */ + +} + +void error_fault(struct m88100_saved_state *frame) { DEBUG_MSG("\n[ERROR EXCEPTION (Bad News[tm]) frame 0x%08x]\n", frame); @@ -1202,7 +1202,7 @@ error_fault(struct m88100_saved_state *frame) DEBUG_MSG("frame shadow registers you are about to see are invalid.\n"); DEBUG_MSG("(read totaly useless) But R1 to R31 might be interesting.\n"); regdump((struct trapframe*)frame); -#if defined(MVME187) || defined(MVME188) +#ifdef M88100 DEBUG_MSG("trap trace %d -> %d -> %d -> %d ", last_trap[0], last_trap[1], last_trap[2], last_trap[3]); DEBUG_MSG("last exception vector = %d\n", last_vector); #endif @@ -1228,6 +1228,7 @@ error_reset(struct m88100_saved_state *frame) bugreturn(); /* This gets us to Bug instead of a loop forever */ } +#ifdef M88100 void syscall(register_t code, struct m88100_saved_state *tf) { @@ -1285,7 +1286,6 @@ syscall(register_t code, struct m88100_saved_state *tf) } /* Callp currently points to syscall, which returns ENOSYS. */ - if (code < 0 || code >= nsys) callp += p->p_emul->e_nosys; else { @@ -1315,9 +1315,9 @@ syscall(register_t code, struct m88100_saved_state *tf) * ld r11, r31, 36 * ld r12, r31, 40 * or r13, r0, <code> - * tb0 0, r0, <128> <- xip - * br err <- nip - * jmp r1 <- fip + * tb0 0, r0, <128> <- sxip + * br err <- snip + * jmp r1 <- sfip * err: or.u r3, r0, hi16(errno) * st r2, r3, lo16(errno) * subu r2, r0, 1 @@ -1354,7 +1354,7 @@ syscall(register_t code, struct m88100_saved_state *tf) tf->r[2] = rval[0]; tf->r[3] = rval[1]; tf->epsr &= ~PSR_C; - tf->snip = tf->sfip & ~FIP_E; + tf->snip = tf->sfip & ~NIP_E; tf->sfip = tf->snip + 4; } else if (error > 0) { /* error != ERESTART && error != EJUSTRETURN*/ @@ -1368,7 +1368,7 @@ syscall(register_t code, struct m88100_saved_state *tf) * will end up reexecuting the trap. */ tf->epsr &= ~PSR_C; - tf->sfip = tf->snip & ~NIP_E; + tf->sfip = tf->snip & ~FIP_E; tf->snip = tf->sxip & ~NIP_E; } else { /* if (error == EJUSTRETURN), leave the ip's alone */ @@ -1383,8 +1383,10 @@ syscall(register_t code, struct m88100_saved_state *tf) ktrsysret(p, code, error, rval[0]); #endif } +#endif /* M88100 */ + +#ifdef M88110 -#ifdef MVME197 /* Instruction pointers opperate differently on mc88110 */ void m197_syscall(register_t code, struct m88100_saved_state *tf) @@ -1473,29 +1475,31 @@ m197_syscall(register_t code, struct m88100_saved_state *tf) * ld r11, r31, 36 * ld r12, r31, 40 * or r13, r0, <code> - * tb0 0, r0, <128> <- sxip - * br err <- snip + * tb0 0, r0, <128> <- exip + * br err <- enip * jmp r1 * err: or.u r3, r0, hi16(errno) * st r2, r3, lo16(errno) * subu r2, r0, 1 * jmp r1 * - * So, when we take syscall trap, sxip/snip will be as + * So, when we take syscall trap, exip/enip will be as * shown above. * Given this, * 1. If the system call returned 0, need to jmp r1. - * sxip += 8 + * exip += 8 * 2. If the system call returned an errno > 0, increment - * sxip += 4 and plug the value in r2. This will have us + * exip += 4 and plug the value in r2. This will have us * executing "br err" on return to user space. * 3. If the system call code returned ERESTART, - * we need to rexecute the trap instruction. leave xip as is. + * we need to rexecute the trap instruction. leave exip as is. * 4. If the system call returned EJUSTRETURN, just return. - * sxip += 8 + * exip += 4 */ - if (error == 0) { + switch (error) { + case 0: + printf("syscall success!\n"); /* * If fork succeeded and we are the child, our stack * has moved and the pointer tf is no longer valid, @@ -1508,26 +1512,37 @@ m197_syscall(register_t code, struct m88100_saved_state *tf) tf->r[2] = rval[0]; tf->r[3] = rval[1]; tf->epsr &= ~PSR_C; - tf->sxip += 8; - tf->sxip &= ~3; - } else if (error > 0) { - /* error != ERESTART && error != EJUSTRETURN*/ - tf->r[2] = error; - tf->epsr |= PSR_C; /* fail */ - tf->sxip += 4; - tf->sxip &= ~3; - } else if (error == ERESTART) { + tf->exip += 8; + tf->exip &= ~3; + break; + case ERESTART: + printf("syscall restart!\n"); /* - * If (error == ERESTART), back up the pipe line. This - * will end up reexecuting the trap. + * Reexecute the trap. + * exip is already at the trap instruction, so + * there is nothing to do. */ tf->epsr &= ~PSR_C; - } else { + break; + case EJUSTRETURN: + printf("syscall just return!\n"); /* if (error == EJUSTRETURN) */ tf->epsr &= ~PSR_C; - tf->sxip += 8; - tf->sxip &= ~3; + tf->exip += 4; + tf->exip &= ~3; + break; + default: + printf("syscall error %d!\n", error); + /* error != ERESTART && error != EJUSTRETURN*/ + if (p->p_emul->e_errno) + error = p->p_emul->e_errno[error]; + tf->r[2] = error; + tf->epsr |= PSR_C; /* fail */ + tf->exip += 4; + tf->exip &= ~3; + break; } + #ifdef SYSCALL_DEBUG scdebug_ret(p, code, error, rval); #endif @@ -1554,15 +1569,12 @@ child_return(arg) tf->r[2] = 0; tf->r[3] = 0; tf->epsr &= ~PSR_C; -#ifdef MVME197 - if (cputyp == CPU_197) { - tf->sxip += 8; - tf->sxip &= ~3; - } else -#endif - { + if (cputyp != CPU_88110) { tf->snip = tf->sfip & ~3; tf->sfip = tf->snip + 4; + } else { + tf->exip += 8; + tf->exip &= ~3; } userret(p, tf, p->p_sticks); |