Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 Aug 2008 23:51:13 +0200
From:      Max Laier <max@love2party.net>
To:        freebsd-hackers@freebsd.org
Subject:   MFC of r180753: ABI problems?
Message-ID:  <200808212351.13464.max@love2party.net>

next in thread | raw e-mail | index | archive | help
--Boundary-00=_RNerIKnCBLsJ5U+
Content-Type: text/plain;
  charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Hi,

I'm wondering how to merge r180753 to stable/7 as luoqi@ has indicated that he 
doesn't have time to take care of it right now.

It seems that changing the size of pcicfgregs (aka struct pcicfg) which is 
part of struct pci_devinfo is out of the question, right?  Ideas where to 
store the HT related state or how to avoid storing the state are welcome.

The merge result is attached for reference.  This fix is essential for many 
nforce based boards from ASUS which are rather common, I'm afraid.  So it 
would be good to have this in 7.1/6.4, I think.

-- 
/"\  Best regards,                      | mlaier@freebsd.org
\ /  Max Laier                          | ICQ #67774661
 X   http://pf4freebsd.love2party.net/  | mlaier@EFnet
/ \  ASCII Ribbon Campaign              | Against HTML Mail and News

--Boundary-00=_RNerIKnCBLsJ5U+
Content-Type: text/x-patch;
  charset="us-ascii";
  name="htfix.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="htfix.diff"

Index: dev/pci/pci_pci.c
===================================================================
--- dev/pci/pci_pci.c	(revision 181970)
+++ dev/pci/pci_pci.c	(working copy)
@@ -607,9 +607,15 @@
     uint32_t *data)
 {
 	device_t bus;
+	int error;
 
 	bus = device_get_parent(pcib);
-	return (PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data));
+	error = PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data);
+	if (error)
+		return (error);
+
+	pci_ht_map_msi(pcib, *addr);
+	return (0);
 }
 
 /*
Index: dev/pci/pci.c
===================================================================
--- dev/pci/pci.c	(revision 181970)
+++ dev/pci/pci.c	(working copy)
@@ -562,11 +562,12 @@
 						    cfg->domain, cfg->bus,
 						    cfg->slot, cfg->func,
 						    (long long)addr);
-				}
+				} else
+					addr = MSI_INTEL_ADDR_BASE;
 
-				/* Enable MSI -> HT mapping. */
-				val |= PCIM_HTCMD_MSI_ENABLE;
-				WREG(ptr + PCIR_HT_COMMAND, val, 2);
+				cfg->ht.ht_msimap = ptr;
+				cfg->ht.ht_msictrl = val;
+				cfg->ht.ht_msiaddr = addr;
 				break;
 			}
 			break;
@@ -1095,6 +1096,9 @@
 	bus_write_4(msix->msix_table_res, offset, address & 0xffffffff);
 	bus_write_4(msix->msix_table_res, offset + 4, address >> 32);
 	bus_write_4(msix->msix_table_res, offset + 8, data);
+
+	/* Enable MSI -> HT mapping. */
+	pci_ht_map_msi(dev, address);
 }
 
 void
@@ -1534,6 +1538,34 @@
 }
 
 /*
+ * HyperTransport MSI mapping control
+ */
+void
+pci_ht_map_msi(device_t dev, uint64_t addr)
+{
+	struct pci_devinfo *dinfo = device_get_ivars(dev);
+	struct pcicfg_ht *ht = &dinfo->cfg.ht;
+
+	if (!ht->ht_msimap)
+		return;
+
+	if (addr && !(ht->ht_msictrl & PCIM_HTCMD_MSI_ENABLE) &&
+	    ht->ht_msiaddr >> 20 == addr >> 20) {
+		/* Enable MSI -> HT mapping. */
+		ht->ht_msictrl |= PCIM_HTCMD_MSI_ENABLE;
+		pci_write_config(dev, ht->ht_msimap + PCIR_HT_COMMAND,
+		    ht->ht_msictrl, 2);
+	}
+
+	if (!addr && ht->ht_msictrl & PCIM_HTCMD_MSI_ENABLE) {
+		/* Disable MSI -> HT mapping. */
+		ht->ht_msictrl &= ~PCIM_HTCMD_MSI_ENABLE;
+		pci_write_config(dev, ht->ht_msimap + PCIR_HT_COMMAND,
+		    ht->ht_msictrl, 2);
+	}
+}
+
+/*
  * Support for MSI message signalled interrupts.
  */
 void
@@ -1558,6 +1590,9 @@
 	msi->msi_ctrl |= PCIM_MSICTRL_MSI_ENABLE;
 	pci_write_config(dev, msi->msi_location + PCIR_MSI_CTRL, msi->msi_ctrl,
 	    2);
+
+	/* Enable MSI -> HT mapping. */
+	pci_ht_map_msi(dev, address);
 }
 
 void
@@ -1566,6 +1601,9 @@
 	struct pci_devinfo *dinfo = device_get_ivars(dev);
 	struct pcicfg_msi *msi = &dinfo->cfg.msi;
 
+	/* Disable MSI -> HT mapping. */
+	pci_ht_map_msi(dev, 0);
+
 	/* Disable MSI in the control register. */
 	msi->msi_ctrl &= ~PCIM_MSICTRL_MSI_ENABLE;
 	pci_write_config(dev, msi->msi_location + PCIR_MSI_CTRL, msi->msi_ctrl,
Index: dev/pci/pcivar.h
===================================================================
--- dev/pci/pcivar.h	(revision 181970)
+++ dev/pci/pcivar.h	(working copy)
@@ -115,6 +115,13 @@
     struct resource *msix_pba_res;	/* Resource containing PBA. */
 };
 
+/* Interesting values for HyperTransport */
+struct pcicfg_ht {
+    uint8_t	ht_msimap;	/* Offset of MSI mapping cap registers. */
+    uint16_t	ht_msictrl;	/* MSI mapping control */
+    uint64_t	ht_msiaddr;	/* MSI mapping base address */
+};
+
 /* config header information common to all header types */
 typedef struct pcicfg {
     struct device *dev;		/* device which owns this */
@@ -156,6 +163,7 @@
     struct pcicfg_vpd vpd;	/* pci vital product data */
     struct pcicfg_msi msi;	/* pci msi */
     struct pcicfg_msix msix;	/* pci msi-x */
+    struct pcicfg_ht ht;	/* HyperTransport */
 } pcicfgregs;
 
 /* additional type 1 device config header information (PCI to PCI bridge) */
@@ -462,6 +470,8 @@
 
 int	pci_msi_device_blacklisted(device_t dev);
 
+void	pci_ht_map_msi(device_t dev, uint64_t addr);
+
 #endif	/* _SYS_BUS_H_ */
 
 /*

--Boundary-00=_RNerIKnCBLsJ5U+--



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