Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Aug 2013 01:10:51 +0000 (UTC)
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r254983 - head/sys/mips/malta
Message-ID:  <201308280110.r7S1ApeB002191@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201308280110.r7S1ApeB002191>