svn commit: r296820 - in projects/powerpcspe/sys/powerpc: include powerpc
Justin Hibbits
jhibbits at FreeBSD.org
Mon Mar 14 01:07:36 UTC 2016
Author: jhibbits
Date: Mon Mar 14 01:07:34 2016
New Revision: 296820
URL: https://svnweb.freebsd.org/changeset/base/296820
Log:
Trap SPE Alignment faults.
With this, a mpc8544 based system (RB800) boots to multiuser.
Modified:
projects/powerpcspe/sys/powerpc/include/trap.h
projects/powerpcspe/sys/powerpc/powerpc/trap.c
Modified: projects/powerpcspe/sys/powerpc/include/trap.h
==============================================================================
--- projects/powerpcspe/sys/powerpc/include/trap.h Mon Mar 14 00:51:45 2016 (r296819)
+++ projects/powerpcspe/sys/powerpc/include/trap.h Mon Mar 14 01:07:34 2016 (r296820)
@@ -112,6 +112,7 @@
/* Macros to extract register information */
#define EXC_ALI_RST(dsisr) ((dsisr >> 5) & 0x1f) /* source or target */
#define EXC_ALI_RA(dsisr) (dsisr & 0x1f)
+#define EXC_ALI_SPE_REG(instr) ((instr >> 21) & 0x1f)
/*
* SRR1 bits for program exception traps. These identify what caused
Modified: projects/powerpcspe/sys/powerpc/powerpc/trap.c
==============================================================================
--- projects/powerpcspe/sys/powerpc/powerpc/trap.c Mon Mar 14 00:51:45 2016 (r296819)
+++ projects/powerpcspe/sys/powerpc/powerpc/trap.c Mon Mar 14 01:07:34 2016 (r296820)
@@ -750,9 +750,47 @@ static int
fix_unaligned(struct thread *td, struct trapframe *frame)
{
struct thread *fputhread;
+#ifdef __SPE__
+ uint32_t inst;
+#endif
int indicator, reg;
double *fpr;
+#ifdef __SPE__
+ indicator = (frame->cpu.booke.esr & (ESR_ST|ESR_SPE));
+ if (indicator & ESR_SPE) {
+ if (copyin((void *)frame->srr0, &inst, sizeof(inst)) != 0)
+ return (-1);
+ reg = EXC_ALI_SPE_REG(inst);
+ fpr = (double *)td->td_pcb->pcb_vec.vr[reg];
+ fputhread = PCPU_GET(vecthread);
+
+ /* Juggle the FPU to ensure that we've initialized
+ * the FPRs, and that their current state is in
+ * the PCB.
+ */
+ if (fputhread != td) {
+ if (fputhread)
+ save_vec(fputhread);
+ enable_vec(td);
+ }
+ save_vec(td);
+
+ if (!(indicator & ESR_ST)) {
+ if (copyin((void *)frame->dar, fpr,
+ sizeof(double)) != 0)
+ return (-1);
+ frame->fixreg[reg] = td->td_pcb->pcb_vec.vr[reg][1];
+ enable_vec(td);
+ } else {
+ td->td_pcb->pcb_vec.vr[reg][1] = frame->fixreg[reg];
+ if (copyout(fpr, (void *)frame->dar,
+ sizeof(double)) != 0)
+ return (-1);
+ }
+ return (0);
+ }
+#else
indicator = EXC_ALI_OPCODE_INDICATOR(frame->cpu.aim.dsisr);
switch (indicator) {
@@ -786,6 +824,7 @@ fix_unaligned(struct thread *td, struct
return (0);
break;
}
+#endif
return (-1);
}
More information about the svn-src-projects
mailing list