summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/mvme88k/mvme88k/trap.c428
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);