summaryrefslogtreecommitdiff
path: root/sys/arch/powerpc
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2019-09-06 13:45:05 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2019-09-06 13:45:05 +0000
commit3caab1ffbcc814667301f49a55012c0dbc6cbcc1 (patch)
treece13724c8a12ac4788eaeec4a12edf163088a1c9 /sys/arch/powerpc
parent4d8f48eaf343b9335abae61f09ca2409c1844e30 (diff)
delete two decades of debugging code and further simplify the main
trap() switch statement ok kettenis
Diffstat (limited to 'sys/arch/powerpc')
-rw-r--r--sys/arch/powerpc/powerpc/trap.c452
1 files changed, 189 insertions, 263 deletions
diff --git a/sys/arch/powerpc/powerpc/trap.c b/sys/arch/powerpc/powerpc/trap.c
index b3781f3a580..64a1ba04329 100644
--- a/sys/arch/powerpc/powerpc/trap.c
+++ b/sys/arch/powerpc/powerpc/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.113 2019/09/06 12:55:26 deraadt Exp $ */
+/* $OpenBSD: trap.c,v 1.114 2019/09/06 13:45:04 deraadt Exp $ */
/* $NetBSD: trap.c,v 1.3 1996/10/13 03:31:37 christos Exp $ */
/*
@@ -232,6 +232,15 @@ trap(struct trapframe *frame)
union sigval sv;
char *name;
db_expr_t offset;
+ faultbuf *fb;
+ struct vm_map *map;
+ vaddr_t va;
+ int ftype, vftype;
+ struct sysent *callp;
+ size_t argsize;
+ register_t code, error;
+ register_t *params, rval[2], args[10];
+ int nsys, n;
if (frame->srr1 & PSL_PR) {
type |= EXC_USER;
@@ -244,130 +253,103 @@ trap(struct trapframe *frame)
switch (type) {
case EXC_TRC|EXC_USER:
- {
- sv.sival_int = frame->srr0;
- KERNEL_LOCK();
- trapsignal(p, SIGTRAP, type, TRAP_TRACE, sv);
- KERNEL_UNLOCK();
- }
+ sv.sival_int = frame->srr0;
+ KERNEL_LOCK();
+ trapsignal(p, SIGTRAP, type, TRAP_TRACE, sv);
+ KERNEL_UNLOCK();
break;
-
case EXC_MCHK:
- {
- faultbuf *fb;
-
- if ((fb = p->p_addr->u_pcb.pcb_onfault)) {
- p->p_addr->u_pcb.pcb_onfault = 0;
- frame->srr0 = fb->pc; /* PC */
- frame->fixreg[1] = fb->sp; /* SP */
- frame->fixreg[3] = 1; /* != 0 */
- frame->cr = fb->cr;
- bcopy(&fb->regs[0], &frame->fixreg[13], 19*4);
- return;
- }
+ if ((fb = p->p_addr->u_pcb.pcb_onfault)) {
+ p->p_addr->u_pcb.pcb_onfault = 0;
+ frame->srr0 = fb->pc; /* PC */
+ frame->fixreg[1] = fb->sp; /* SP */
+ frame->fixreg[3] = 1; /* != 0 */
+ frame->cr = fb->cr;
+ bcopy(&fb->regs[0], &frame->fixreg[13], 19*4);
+ return;
}
goto brain_damage;
case EXC_DSI:
- {
- struct vm_map *map;
- vaddr_t va;
- int ftype;
- faultbuf *fb;
-
- map = kernel_map;
- va = frame->dar;
- if ((va >> ADDR_SR_SHIFT) == PPC_USER_SR) {
- sr_t user_sr;
-
- asm ("mfsr %0, %1"
- : "=r"(user_sr) : "K"(PPC_USER_SR));
- va &= ADDR_PIDX | ADDR_POFF;
- va |= user_sr << ADDR_SR_SHIFT;
- map = &p->p_vmspace->vm_map;
- if (pte_spill_v(map->pmap, va, frame->dsisr, 0))
- return;
- }
- if (frame->dsisr & DSISR_STORE)
- ftype = PROT_READ | PROT_WRITE;
- else
- ftype = PROT_READ;
- KERNEL_LOCK();
- if (uvm_fault(map, trunc_page(va), 0, ftype) == 0) {
- KERNEL_UNLOCK();
+ map = kernel_map;
+ va = frame->dar;
+ if ((va >> ADDR_SR_SHIFT) == PPC_USER_SR) {
+ sr_t user_sr;
+
+ asm ("mfsr %0, %1" : "=r"(user_sr) : "K"(PPC_USER_SR));
+ va &= ADDR_PIDX | ADDR_POFF;
+ va |= user_sr << ADDR_SR_SHIFT;
+ map = &p->p_vmspace->vm_map;
+ if (pte_spill_v(map->pmap, va, frame->dsisr, 0))
return;
- }
+ }
+ if (frame->dsisr & DSISR_STORE)
+ ftype = PROT_READ | PROT_WRITE;
+ else
+ ftype = PROT_READ;
+ KERNEL_LOCK();
+ if (uvm_fault(map, trunc_page(va), 0, ftype) == 0) {
KERNEL_UNLOCK();
+ return;
+ }
+ KERNEL_UNLOCK();
- if ((fb = p->p_addr->u_pcb.pcb_onfault)) {
- p->p_addr->u_pcb.pcb_onfault = 0;
- frame->srr0 = fb->pc; /* PC */
- frame->fixreg[1] = fb->sp; /* SP */
- frame->fixreg[3] = 1; /* != 0 */
- frame->cr = fb->cr;
- bcopy(&fb->regs[0], &frame->fixreg[13], 19*4);
- return;
- }
- map = kernel_map;
+ if ((fb = p->p_addr->u_pcb.pcb_onfault)) {
+ p->p_addr->u_pcb.pcb_onfault = 0;
+ frame->srr0 = fb->pc; /* PC */
+ frame->fixreg[1] = fb->sp; /* SP */
+ frame->fixreg[3] = 1; /* != 0 */
+ frame->cr = fb->cr;
+ bcopy(&fb->regs[0], &frame->fixreg[13], 19*4);
+ return;
}
-printf("kern dsi on addr %x iar %x\n", frame->dar, frame->srr0);
+ map = kernel_map;
goto brain_damage;
- case EXC_DSI|EXC_USER:
- {
- int ftype, vftype;
-
- /* Try spill handler first */
- if (pte_spill_v(p->p_vmspace->vm_map.pmap,
- frame->dar, frame->dsisr, 0))
- break;
- KERNEL_LOCK();
- if (frame->dsisr & DSISR_STORE) {
- ftype = PROT_READ | PROT_WRITE;
- vftype = PROT_WRITE;
- } else
- vftype = ftype = PROT_READ;
- if (uvm_fault(&p->p_vmspace->vm_map,
- trunc_page(frame->dar), 0, ftype) == 0) {
- uvm_grow(p, trunc_page(frame->dar));
- KERNEL_UNLOCK();
- break;
- }
+ case EXC_DSI|EXC_USER:
+ /* Try spill handler first */
+ if (pte_spill_v(p->p_vmspace->vm_map.pmap,
+ frame->dar, frame->dsisr, 0))
+ break;
-#if 0
-printf("dsi on addr %x iar %x lr %x\n", frame->dar, frame->srr0,frame->lr);
-#endif
-/*
- * keep this for later in case we want it later.
-*/
- sv.sival_int = frame->dar;
- trapsignal(p, SIGSEGV, vftype, SEGV_MAPERR, sv);
+ KERNEL_LOCK();
+ if (frame->dsisr & DSISR_STORE) {
+ ftype = PROT_READ | PROT_WRITE;
+ vftype = PROT_WRITE;
+ } else
+ vftype = ftype = PROT_READ;
+ if (uvm_fault(&p->p_vmspace->vm_map,
+ trunc_page(frame->dar), 0, ftype) == 0) {
+ uvm_grow(p, trunc_page(frame->dar));
KERNEL_UNLOCK();
+ break;
}
+
+ /*
+ * keep this for later in case we want it later.
+ */
+ sv.sival_int = frame->dar;
+ trapsignal(p, SIGSEGV, vftype, SEGV_MAPERR, sv);
+ KERNEL_UNLOCK();
break;
+
case EXC_ISI|EXC_USER:
- {
- int ftype;
-
- /* Try spill handler */
- if (pte_spill_v(p->p_vmspace->vm_map.pmap,
- frame->srr0, 0, 1))
- break;
+ /* Try spill handler */
+ if (pte_spill_v(p->p_vmspace->vm_map.pmap,
+ frame->srr0, 0, 1))
+ break;
- KERNEL_LOCK();
- ftype = PROT_READ | PROT_EXEC;
- if (uvm_fault(&p->p_vmspace->vm_map,
- trunc_page(frame->srr0), 0, ftype) == 0) {
- uvm_grow(p, trunc_page(frame->srr0));
- KERNEL_UNLOCK();
- break;
- }
+ KERNEL_LOCK();
+ ftype = PROT_READ | PROT_EXEC;
+ if (uvm_fault(&p->p_vmspace->vm_map,
+ trunc_page(frame->srr0), 0, ftype) == 0) {
+ uvm_grow(p, trunc_page(frame->srr0));
KERNEL_UNLOCK();
+ break;
}
-#if 0
-printf("isi iar %x lr %x\n", frame->srr0, frame->lr);
-#endif
+ KERNEL_UNLOCK();
/* FALLTHROUGH */
+
case EXC_MCHK|EXC_USER:
/* XXX Likely that returning from this trap is bogus... */
/* XXX Have to make sure that sigreturn does the right thing. */
@@ -376,95 +358,86 @@ printf("isi iar %x lr %x\n", frame->srr0, frame->lr);
trapsignal(p, SIGSEGV, PROT_EXEC, SEGV_MAPERR, sv);
KERNEL_UNLOCK();
break;
+
case EXC_SC|EXC_USER:
- {
- struct sysent *callp;
- size_t argsize;
- register_t code, error;
- register_t *params, rval[2];
- int nsys, n;
- register_t args[10];
-
- uvmexp.syscalls++;
-
- nsys = p->p_p->ps_emul->e_nsysent;
- callp = p->p_p->ps_emul->e_sysent;
-
- code = frame->fixreg[0];
- params = frame->fixreg + FIRSTARG;
-
- switch (code) {
- case SYS_syscall:
- /*
- * code is first argument,
- * followed by actual args.
- */
- code = *params++;
- break;
- case SYS___syscall:
- /*
- * Like syscall, but code is a quad,
- * so as to maintain quad alignment
- * for the rest of the args.
- */
- if (callp != sysent)
- break;
- params++;
- code = *params++;
- break;
- default:
- break;
- }
- if (code < 0 || code >= nsys)
- callp += p->p_p->ps_emul->e_nosys;
- else
- callp += code;
- argsize = callp->sy_argsize;
- n = NARGREG - (params - (frame->fixreg + FIRSTARG));
- if (argsize > n * sizeof(register_t)) {
- bcopy(params, args, n * sizeof(register_t));
-
- if ((error = copyin(MOREARGS(frame->fixreg[1]),
- args + n,
- argsize - n * sizeof(register_t))))
- goto bad;
- params = args;
- }
-
- rval[0] = 0;
- rval[1] = frame->fixreg[FIRSTARG + 1];
-
- error = mi_syscall(p, code, callp, params, rval);
-
- switch (error) {
- case 0:
- frame->fixreg[0] = error;
- frame->fixreg[FIRSTARG] = rval[0];
- frame->fixreg[FIRSTARG + 1] = rval[1];
- frame->cr &= ~0x10000000;
- break;
- case ERESTART:
- /*
- * Set user's pc back to redo the system call.
- */
- frame->srr0 -= 4;
- break;
- case EJUSTRETURN:
- /* nothing to do */
- break;
- default:
- bad:
- frame->fixreg[0] = error;
- frame->fixreg[FIRSTARG] = error;
- frame->fixreg[FIRSTARG + 1] = rval[1];
- frame->cr |= 0x10000000;
+ uvmexp.syscalls++;
+
+ nsys = p->p_p->ps_emul->e_nsysent;
+ callp = p->p_p->ps_emul->e_sysent;
+
+ code = frame->fixreg[0];
+ params = frame->fixreg + FIRSTARG;
+
+ switch (code) {
+ case SYS_syscall:
+ /*
+ * code is first argument,
+ * followed by actual args.
+ */
+ code = *params++;
+ break;
+ case SYS___syscall:
+ /*
+ * Like syscall, but code is a quad,
+ * so as to maintain quad alignment
+ * for the rest of the args.
+ */
+ if (callp != sysent)
break;
- }
+ params++;
+ code = *params++;
+ break;
+ default:
+ break;
+ }
+ if (code < 0 || code >= nsys)
+ callp += p->p_p->ps_emul->e_nosys;
+ else
+ callp += code;
+ argsize = callp->sy_argsize;
+ n = NARGREG - (params - (frame->fixreg + FIRSTARG));
+ if (argsize > n * sizeof(register_t)) {
+ bcopy(params, args, n * sizeof(register_t));
+
+ if ((error = copyin(MOREARGS(frame->fixreg[1]),
+ args + n, argsize - n * sizeof(register_t))))
+ goto bad;
+ params = args;
+ }
+
+ rval[0] = 0;
+ rval[1] = frame->fixreg[FIRSTARG + 1];
+
+ error = mi_syscall(p, code, callp, params, rval);
- mi_syscall_return(p, code, error, rval);
- goto finish;
+ switch (error) {
+ case 0:
+ frame->fixreg[0] = error;
+ frame->fixreg[FIRSTARG] = rval[0];
+ frame->fixreg[FIRSTARG + 1] = rval[1];
+ frame->cr &= ~0x10000000;
+ break;
+ case ERESTART:
+ /*
+ * Set user's pc back to redo the system call.
+ */
+ frame->srr0 -= 4;
+ break;
+ case EJUSTRETURN:
+ /* nothing to do */
+ break;
+ default:
+ bad:
+ frame->fixreg[0] = error;
+ frame->fixreg[FIRSTARG] = error;
+ frame->fixreg[FIRSTARG + 1] = rval[1];
+ frame->cr |= 0x10000000;
+ break;
}
+ mi_syscall_return(p, code, error, rval);
+ goto finish;
+
case EXC_FPU|EXC_USER:
if (ci->ci_fpuproc)
save_fpu();
@@ -483,8 +456,7 @@ printf("isi iar %x lr %x\n", frame->srr0, frame->lr);
else {
sv.sival_int = frame->srr0;
KERNEL_LOCK();
- trapsignal(p, SIGBUS, PROT_EXEC, BUS_ADRALN,
- sv);
+ trapsignal(p, SIGBUS, PROT_EXEC, BUS_ADRALN, sv);
KERNEL_UNLOCK();
}
break;
@@ -492,10 +464,6 @@ printf("isi iar %x lr %x\n", frame->srr0, frame->lr);
default:
brain_damage:
-/*
-mpc_print_pci_stat();
-*/
-
#ifdef DDB
/* set up registers */
db_save_regs(frame);
@@ -507,64 +475,23 @@ mpc_print_pci_stat();
name = "0";
offset = frame->srr0;
}
- panic ("trap type %x at %x (%s+0x%lx) lr %lx",
- type, frame->srr0, name, offset, frame->lr);
-
+ panic("trap type %x srr1 %x at %x (%s+0x%lx) lr %lx",
+ type, frame->srr1, frame->srr0, name, offset, frame->lr);
case EXC_PGM|EXC_USER:
- {
-#if 0
- char *errstr[8];
- int errnum = 0;
-
- if (frame->srr1 & (1<<(31-11))) {
- /* floating point enabled program exception */
- errstr[errnum] = "floating point";
- errnum++;
- }
- if (frame->srr1 & (1<<(31-12))) {
- /* illegal instruction program exception */
- errstr[errnum] = "illegal instruction";
- errnum++;
- }
- if (frame->srr1 & (1<<(31-13))) {
- /* privileged instruction exception */
- errstr[errnum] = "privileged instr";
- errnum++;
- }
-#endif
if (frame->srr1 & (1<<(31-14))) {
-#if 0
- errstr[errnum] = "trap instr";
- errnum++;
-#endif
sv.sival_int = frame->srr0;
KERNEL_LOCK();
trapsignal(p, SIGTRAP, type, TRAP_BRKPT, sv);
KERNEL_UNLOCK();
break;
}
-#if 0
- if (frame->srr1 & (1<<(31-15))) {
- errstr[errnum] = "previous address";
- errnum++;
- }
-#endif
-#if 0
-printf("pgm iar %x srr1 %x\n", frame->srr0, frame->srr1);
-{
-int i;
-for (i = 0; i < errnum; i++) {
- printf("\t[%s]\n", errstr[i]);
-}
-}
-#endif
sv.sival_int = frame->srr0;
KERNEL_LOCK();
trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv);
KERNEL_UNLOCK();
break;
- }
+
case EXC_PGM:
/* should check for correct byte here or panic */
#ifdef DDB
@@ -693,38 +620,37 @@ fix_unaligned(struct proc *p, struct trapframe *frame)
{
int indicator = EXC_ALI_OPCODE_INDICATOR(frame->dsisr);
struct cpu_info *ci = curcpu();
+ int reg;
+ double *fpr;
switch (indicator) {
case EXC_ALI_LFD:
case EXC_ALI_STFD:
- {
- int reg = EXC_ALI_RST(frame->dsisr);
- double *fpr = &p->p_addr->u_pcb.pcb_fpu.fpr[reg];
-
- /* Juggle the FPU to ensure that we've initialized
- * the FPRs, and that their current state is in
- * the PCB.
- */
- if (ci->ci_fpuproc != p) {
- if (ci->ci_fpuproc)
- save_fpu();
- enable_fpu(p);
- }
- save_fpu();
+ reg = EXC_ALI_RST(frame->dsisr);
+ fpr = &p->p_addr->u_pcb.pcb_fpu.fpr[reg];
- if (indicator == EXC_ALI_LFD) {
- if (copyin((void *)frame->dar, fpr,
- sizeof(double)) != 0)
- return -1;
- } else {
- if (copyout(fpr, (void *)frame->dar,
- sizeof(double)) != 0)
- return -1;
- }
+ /* Juggle the FPU to ensure that we've initialized
+ * the FPRs, and that their current state is in
+ * the PCB.
+ */
+ if (ci->ci_fpuproc != p) {
+ if (ci->ci_fpuproc)
+ save_fpu();
enable_fpu(p);
- return 0;
}
- break;
+ save_fpu();
+
+ if (indicator == EXC_ALI_LFD) {
+ if (copyin((void *)frame->dar, fpr,
+ sizeof(double)) != 0)
+ return -1;
+ } else {
+ if (copyout(fpr, (void *)frame->dar,
+ sizeof(double)) != 0)
+ return -1;
+ }
+ enable_fpu(p);
+ return 0;
}
return -1;
}