Author: jhibbits
Date: Wed Jun 26 01:14:39 2019
New Revision: 349402
URL: https://svnweb.freebsd.org/changeset/base/349402

Log:
  powerpc/booke: Handle misaligned floating point loads/stores as on AIM
  
  Misaligned floating point loads and stores are already handled for AIM, but
  use the DSISR to obtain the necessary data.  Book-E does not have the DSISR,
  so these fixups are not performed, leading to a SIGBUS on misaligned FP
  loads or stores.  Obtain the necessary data on the Book-E side, similar to
  how is done for SPE.
  
  MFC after:    1 week

Modified:
  head/sys/powerpc/include/trap.h
  head/sys/powerpc/powerpc/trap.c

Modified: head/sys/powerpc/include/trap.h
==============================================================================
--- head/sys/powerpc/include/trap.h     Wed Jun 26 00:53:49 2019        
(r349401)
+++ head/sys/powerpc/include/trap.h     Wed Jun 26 01:14:39 2019        
(r349402)
@@ -130,7 +130,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)
+#define        EXC_ALI_INST_RST(instr) ((instr >> 21) & 0x1f)
 
 /*
  * SRR1 bits for program exception traps. These identify what caused

Modified: head/sys/powerpc/powerpc/trap.c
==============================================================================
--- head/sys/powerpc/powerpc/trap.c     Wed Jun 26 00:53:49 2019        
(r349401)
+++ head/sys/powerpc/powerpc/trap.c     Wed Jun 26 01:14:39 2019        
(r349402)
@@ -788,7 +788,7 @@ static int
 fix_unaligned(struct thread *td, struct trapframe *frame)
 {
        struct thread   *fputhread;
-#ifdef __SPE__
+#ifdef BOOKE
        uint32_t        inst;
 #endif
        int             indicator, reg;
@@ -799,7 +799,7 @@ fix_unaligned(struct thread *td, struct trapframe *fra
        if (indicator & ESR_SPE) {
                if (copyin((void *)frame->srr0, &inst, sizeof(inst)) != 0)
                        return (-1);
-               reg = EXC_ALI_SPE_REG(inst);
+               reg = EXC_ALI_INST_RST(inst);
                fpr = (double *)td->td_pcb->pcb_vec.vr[reg];
                fputhread = PCPU_GET(vecthread);
 
@@ -829,12 +829,22 @@ fix_unaligned(struct thread *td, struct trapframe *fra
                return (0);
        }
 #else
+#ifdef BOOKE
+       indicator = (frame->cpu.booke.esr & ESR_ST) ? EXC_ALI_STFD : 
EXC_ALI_LFD;
+#else
        indicator = EXC_ALI_OPCODE_INDICATOR(frame->cpu.aim.dsisr);
+#endif
 
        switch (indicator) {
        case EXC_ALI_LFD:
        case EXC_ALI_STFD:
+#ifdef BOOKE
+               if (copyin((void *)frame->srr0, &inst, sizeof(inst)) != 0)
+                       return (-1);
+               reg = EXC_ALI_INST_RST(inst);
+#else
                reg = EXC_ALI_RST(frame->cpu.aim.dsisr);
+#endif
                fpr = &td->td_pcb->pcb_fpu.fpr[reg].fpr;
                fputhread = PCPU_GET(fputhread);
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to