[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] VT-d, tools: Intel IGD passthrough 1/2: vendor-specific FLR



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1265274485 0
# Node ID 729b32b174409a1db9df22493f1d8a29a2ae9d95
# Parent  9fc37faa25a0f816776b968899469aa49ff4a553
VT-d, tools: Intel IGD passthrough 1/2: vendor-specific FLR

Due to FLR capability of IGD is not exposed on some platforms, this
patch uses vendor specific FLR to reset those IGDs.

Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
---
 tools/python/xen/util/pci.py |   83 +++++++++++++++++++++++++++++++++++++++----
 1 files changed, 76 insertions(+), 7 deletions(-)

diff -r 9fc37faa25a0 -r 729b32b17440 tools/python/xen/util/pci.py
--- a/tools/python/xen/util/pci.py      Thu Feb 04 09:04:33 2010 +0000
+++ b/tools/python/xen/util/pci.py      Thu Feb 04 09:08:05 2010 +0000
@@ -19,6 +19,7 @@ from xen.xend import sxp
 from xen.xend import sxp
 from xen.xend.XendConstants import AUTO_PHP_SLOT
 from xen.xend.XendSXPDev import dev_dict_to_sxp
+from xen.xend.XendLogging import log
 
 # for 2.3 compatibility
 try:
@@ -93,6 +94,21 @@ PCI_CAP_ID_VENDOR_SPECIFIC_CAP = 0x09
 PCI_CAP_ID_VENDOR_SPECIFIC_CAP = 0x09
 PCI_CLASS_ID_USB = 0x0c03
 PCI_USB_FLRCTRL = 0x4
+
+PCI_DEVICE_ID = 0x02
+PCI_COMMAND = 0x04
+PCI_CLASS_ID_VGA = 0x0300
+
+PCI_DEVICE_ID_IGFX_GM45 = 0x2a42
+PCI_DEVICE_ID_IGFX_EAGLELAKE = 0x2e02
+PCI_DEVICE_ID_IGFX_Q45 = 0x2e12
+PCI_DEVICE_ID_IGFX_G45 = 0x2e22
+PCI_DEVICE_ID_IGFX_G41 = 0x2e32
+
+PCI_CAP_IGFX_CAP09_OFFSET = 0xa4
+PCI_CAP_IGFX_CAP13_OFFSET = 0xa4
+PCI_CAP_IGFX_GDRST = 0X0d
+PCI_CAP_IGFX_GDRST_OFFSET = 0xc0
 
 # The VF of Intel 82599 10GbE Controller
 # See http://download.intel.com/design/network/datashts/82599_datasheet.pdf
@@ -831,6 +847,45 @@ class PciDevice:
         if not self.do_Dstate_transition():
             self.do_vendor_specific_FLR_method()
 
+    def do_AF_FLR(self, af_pos):
+        ''' use PCI Advanced Capability to do FLR
+        '''
+        (pci_list, cfg_list) = save_pci_conf_space([self.name])
+        self.pci_conf_write8(af_pos + PCI_AF_CTL, PCI_AF_CTL_FLR)
+        time.sleep(0.100)
+        restore_pci_conf_space((pci_list, cfg_list))
+
+    def do_FLR_for_intel_4Series_iGFX(self):
+        af_pos = PCI_CAP_IGFX_CAP13_OFFSET
+        self.do_AF_FLR(af_pos)
+        log.debug("Intel 4 Series iGFX FLR done")
+
+    def do_FLR_for_GM45_iGFX(self):
+        reg32 = self.pci_conf_read32(PCI_CAP_IGFX_CAP09_OFFSET)
+        if ((reg32 >> 16) & 0x000000FF) != 0x06 or \
+            ((reg32 >> 24) & 0x000000F0) != 0x20:
+            return
+
+        self.pci_conf_write8(PCI_CAP_IGFX_GDRST_OFFSET, PCI_CAP_IGFX_GDRST)
+        for i in range(0, 10):
+            time.sleep(0.100)
+            reg8 = self.pci_conf_read8(PCI_CAP_IGFX_GDRST_OFFSET)
+            if (reg8 & 0x01) == 0:
+                break
+            if i == 10:
+                log.debug("Intel iGFX FLR fail on GM45")
+                return
+
+        # This specific reset will hang if the command register does not have
+        # memory space access enabled
+        cmd = self.pci_conf_read16(PCI_COMMAND)
+        self.pci_conf_write16(PCI_COMMAND, (cmd | 0x02))
+        af_pos = PCI_CAP_IGFX_CAP09_OFFSET
+        self.do_AF_FLR(af_pos)
+        self.pci_conf_write16(PCI_COMMAND, cmd)
+
+        log.debug("Intel iGFX FLR on GM45 done")
+
     def find_all_the_multi_functions(self):
         sysfs_mnt = find_sysfs_mnt()
         parentdict = self.find_parent()
@@ -1104,15 +1159,29 @@ class PciDevice:
         else:
             # For PCI device on host bus, we test "PCI Advanced Capabilities".
             if self.bus == 0 and self.pci_af_flr:
-                (pci_list, cfg_list) = save_pci_conf_space([self.name])
-                # We use Advanced Capability to do FLR.
-                pos = self.find_cap_offset(PCI_CAP_ID_AF)
-                self.pci_conf_write8(pos + PCI_AF_CTL, PCI_AF_CTL_FLR)
-                time.sleep(0.100)
-                restore_pci_conf_space((pci_list, cfg_list))
+                af_pos = self.find_cap_offset(PCI_CAP_ID_AF)
+                self.do_AF_FLR(af_pos)
             else:
                 if self.bus == 0:
-                    self.do_FLR_for_integrated_device()
+                    if self.slot == 0x02 and self.func == 0x0:
+                        vendor_id = self.pci_conf_read16(PCI_VENDOR_ID)
+                        if vendor_id != VENDOR_INTEL:
+                            return
+                        class_id = self.pci_conf_read16(PCI_CLASS_DEVICE)
+                        if class_id !=  PCI_CLASS_ID_VGA:
+                            return
+                        device_id = self.pci_conf_read16(PCI_DEVICE_ID)
+                        if device_id == PCI_DEVICE_ID_IGFX_GM45:
+                            self.do_FLR_for_GM45_iGFX()
+                        elif device_id == PCI_DEVICE_ID_IGFX_EAGLELAKE or \
+                             device_id == PCI_DEVICE_ID_IGFX_Q45 or \
+                             device_id == PCI_DEVICE_ID_IGFX_G45 or \
+                             device_id == PCI_DEVICE_ID_IGFX_G41:
+                            self.do_FLR_for_intel_4Series_iGFX()
+                        else:
+                            log.debug("Unknown iGFX device_id:%x", device_id)
+                    else:
+                        self.do_FLR_for_integrated_device()
                 else:
                     devs = self.find_coassigned_pci_devices(False)
                     # Remove the element 0 which is a bridge

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.