summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgonzo <gonzo@FreeBSD.org>2013-08-28 01:10:51 +0000
committergonzo <gonzo@FreeBSD.org>2013-08-28 01:10:51 +0000
commit0dc62eee9d4434460a6c0bec88c1990d8285e5aa (patch)
treed8fca02055693cfb14df177d4f59714a44ba6e6f
parentf30d83113718ef96a9eb0fcbdb4ac60b47dda665 (diff)
downloadFreeBSD-src-0dc62eee9d4434460a6c0bec88c1990d8285e5aa.zip
FreeBSD-src-0dc62eee9d4434460a6c0bec88c1990d8285e5aa.tar.gz
Fix GT PCI controller driver on big-endian hardware
-rw-r--r--sys/mips/malta/gt_pci.c53
1 files changed, 35 insertions, 18 deletions
diff --git a/sys/mips/malta/gt_pci.c b/sys/mips/malta/gt_pci.c
index 37407b2..47c3f6f 100644
--- a/sys/mips/malta/gt_pci.c
+++ b/sys/mips/malta/gt_pci.c
@@ -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 bus, u_int slot, u_int func, u_int reg,
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 bus, u_int slot, u_int func, u_int reg,
{
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 bus, u_int slot, u_int func, u_int reg,
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
OpenPOWER on IntegriCloud