Author: gonzo
Date: Wed Aug 28 01:10:51 2013
New Revision: 254983
URL: http://svnweb.freebsd.org/changeset/base/254983

Log:
  Fix GT PCI controller driver on big-endian hardware

Modified:
  head/sys/mips/malta/gt_pci.c

Modified: head/sys/mips/malta/gt_pci.c
==============================================================================
--- head/sys/mips/malta/gt_pci.c        Wed Aug 28 00:39:47 2013        
(r254982)
+++ head/sys/mips/malta/gt_pci.c        Wed Aug 28 01:10:51 2013        
(r254983)
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 
 #include <sys/bus.h>
+#include <sys/endian.h>
 #include <sys/interrupt.h>
 #include <sys/malloc.h>
 #include <sys/kernel.h>
@@ -91,6 +92,14 @@ __FBSDID("$FreeBSD$");
 #define OCW3_POLL_IRQ(x) ((x) & 0x7f)
 #define OCW3_POLL_PENDING (1U << 7)
 
+/*
+ * Galileo controller's registers are LE so convert to then
+ * to/from native byte order. We rely on boot loader or emulator
+ * to set "swap bytes" configuration correctly for us
+ */
+#define        GT_PCI_DATA(v)  htole32((v))
+#define        GT_HOST_DATA(v) le32toh((v))
+
 struct gt_pci_softc;
 
 struct gt_pci_intr_cookie {
@@ -437,20 +446,20 @@ gt_pci_read_config(device_t dev, u_int b
                return (uint32_t)(-1);
 
        /* Clear cause register bits. */
-       GT_REGVAL(GT_INTR_CAUSE) = 0;
-
-       GT_REGVAL(GT_PCI0_CFG_ADDR) = (1 << 31) | addr;
-       data = GT_REGVAL(GT_PCI0_CFG_DATA);
+       GT_REGVAL(GT_INTR_CAUSE) = GT_PCI_DATA(0);
+       GT_REGVAL(GT_PCI0_CFG_ADDR) = GT_PCI_DATA((1 << 31) | addr);
+       /* 
+        * Galileo system controller is special
+        */
+       if ((bus == 0) && (slot == 0))
+               data = GT_PCI_DATA(GT_REGVAL(GT_PCI0_CFG_DATA));
+       else
+               data = GT_REGVAL(GT_PCI0_CFG_DATA);
 
        /* Check for master abort. */
-       if (GT_REGVAL(GT_INTR_CAUSE) & (GTIC_MASABORT0 | GTIC_TARABORT0))
+       if (GT_HOST_DATA(GT_REGVAL(GT_INTR_CAUSE)) & (GTIC_MASABORT0 | 
GTIC_TARABORT0))
                data = (uint32_t) -1;
 
-       /*
-        * XXX: We assume that words readed from GT chip are BE.
-        *      Should we set the mode explicitly during chip
-        *      Initialization?
-        */ 
        switch(reg % 4)
        {
        case 3:
@@ -507,11 +516,6 @@ gt_pci_write_config(device_t dev, u_int 
        {
                reg_data = gt_pci_read_config(dev, bus, slot, func, reg, 4);
 
-               /*
-               * XXX: We assume that words readed from GT chip are BE.
-               *       Should we set the mode explicitly during chip
-               *       Initialization?
-               */ 
                shift = 8 * (reg & 3);
 
                switch(bytes)
@@ -548,10 +552,23 @@ gt_pci_write_config(device_t dev, u_int 
                return;
 
        /* Clear cause register bits. */
-       GT_REGVAL(GT_INTR_CAUSE) = 0;
+       GT_REGVAL(GT_INTR_CAUSE) = GT_PCI_DATA(0);
+
+       GT_REGVAL(GT_PCI0_CFG_ADDR) = GT_PCI_DATA((1 << 31) | addr);
+
+       /* 
+        * Galileo system controller is special
+        */
+       if ((bus == 0) && (slot == 0))
+               GT_REGVAL(GT_PCI0_CFG_DATA) = GT_PCI_DATA(data);
+       else
+               GT_REGVAL(GT_PCI0_CFG_DATA) = data;
+
+#if 0
+       printf("PCICONF_WRITE(%02x:%02x.%02x[%04x] -> %02x(%d)\n", 
+         bus, slot, func, reg, data, bytes);
+#endif
 
-       GT_REGVAL(GT_PCI0_CFG_ADDR) = (1 << 31) | addr;
-       GT_REGVAL(GT_PCI0_CFG_DATA) = data;
 }
 
 static int
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to