debuggers.hg
changeset 20941:729b32b17440
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@intel.com>
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@intel.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Thu Feb 04 09:08:05 2010 +0000 (2010-02-04) |
parents | 9fc37faa25a0 |
children | ece60564af6f |
files | tools/python/xen/util/pci.py |
line diff
1.1 --- a/tools/python/xen/util/pci.py Thu Feb 04 09:04:33 2010 +0000 1.2 +++ b/tools/python/xen/util/pci.py Thu Feb 04 09:08:05 2010 +0000 1.3 @@ -19,6 +19,7 @@ from xen.xend import uuid 1.4 from xen.xend import sxp 1.5 from xen.xend.XendConstants import AUTO_PHP_SLOT 1.6 from xen.xend.XendSXPDev import dev_dict_to_sxp 1.7 +from xen.xend.XendLogging import log 1.8 1.9 # for 2.3 compatibility 1.10 try: 1.11 @@ -94,6 +95,21 @@ PCI_CAP_ID_VENDOR_SPECIFIC_CAP = 0x09 1.12 PCI_CLASS_ID_USB = 0x0c03 1.13 PCI_USB_FLRCTRL = 0x4 1.14 1.15 +PCI_DEVICE_ID = 0x02 1.16 +PCI_COMMAND = 0x04 1.17 +PCI_CLASS_ID_VGA = 0x0300 1.18 + 1.19 +PCI_DEVICE_ID_IGFX_GM45 = 0x2a42 1.20 +PCI_DEVICE_ID_IGFX_EAGLELAKE = 0x2e02 1.21 +PCI_DEVICE_ID_IGFX_Q45 = 0x2e12 1.22 +PCI_DEVICE_ID_IGFX_G45 = 0x2e22 1.23 +PCI_DEVICE_ID_IGFX_G41 = 0x2e32 1.24 + 1.25 +PCI_CAP_IGFX_CAP09_OFFSET = 0xa4 1.26 +PCI_CAP_IGFX_CAP13_OFFSET = 0xa4 1.27 +PCI_CAP_IGFX_GDRST = 0X0d 1.28 +PCI_CAP_IGFX_GDRST_OFFSET = 0xc0 1.29 + 1.30 # The VF of Intel 82599 10GbE Controller 1.31 # See http://download.intel.com/design/network/datashts/82599_datasheet.pdf 1.32 # For 'VF PCIe Configuration Space', see its Table 9.7. 1.33 @@ -831,6 +847,45 @@ class PciDevice: 1.34 if not self.do_Dstate_transition(): 1.35 self.do_vendor_specific_FLR_method() 1.36 1.37 + def do_AF_FLR(self, af_pos): 1.38 + ''' use PCI Advanced Capability to do FLR 1.39 + ''' 1.40 + (pci_list, cfg_list) = save_pci_conf_space([self.name]) 1.41 + self.pci_conf_write8(af_pos + PCI_AF_CTL, PCI_AF_CTL_FLR) 1.42 + time.sleep(0.100) 1.43 + restore_pci_conf_space((pci_list, cfg_list)) 1.44 + 1.45 + def do_FLR_for_intel_4Series_iGFX(self): 1.46 + af_pos = PCI_CAP_IGFX_CAP13_OFFSET 1.47 + self.do_AF_FLR(af_pos) 1.48 + log.debug("Intel 4 Series iGFX FLR done") 1.49 + 1.50 + def do_FLR_for_GM45_iGFX(self): 1.51 + reg32 = self.pci_conf_read32(PCI_CAP_IGFX_CAP09_OFFSET) 1.52 + if ((reg32 >> 16) & 0x000000FF) != 0x06 or \ 1.53 + ((reg32 >> 24) & 0x000000F0) != 0x20: 1.54 + return 1.55 + 1.56 + self.pci_conf_write8(PCI_CAP_IGFX_GDRST_OFFSET, PCI_CAP_IGFX_GDRST) 1.57 + for i in range(0, 10): 1.58 + time.sleep(0.100) 1.59 + reg8 = self.pci_conf_read8(PCI_CAP_IGFX_GDRST_OFFSET) 1.60 + if (reg8 & 0x01) == 0: 1.61 + break 1.62 + if i == 10: 1.63 + log.debug("Intel iGFX FLR fail on GM45") 1.64 + return 1.65 + 1.66 + # This specific reset will hang if the command register does not have 1.67 + # memory space access enabled 1.68 + cmd = self.pci_conf_read16(PCI_COMMAND) 1.69 + self.pci_conf_write16(PCI_COMMAND, (cmd | 0x02)) 1.70 + af_pos = PCI_CAP_IGFX_CAP09_OFFSET 1.71 + self.do_AF_FLR(af_pos) 1.72 + self.pci_conf_write16(PCI_COMMAND, cmd) 1.73 + 1.74 + log.debug("Intel iGFX FLR on GM45 done") 1.75 + 1.76 def find_all_the_multi_functions(self): 1.77 sysfs_mnt = find_sysfs_mnt() 1.78 parentdict = self.find_parent() 1.79 @@ -1104,15 +1159,29 @@ class PciDevice: 1.80 else: 1.81 # For PCI device on host bus, we test "PCI Advanced Capabilities". 1.82 if self.bus == 0 and self.pci_af_flr: 1.83 - (pci_list, cfg_list) = save_pci_conf_space([self.name]) 1.84 - # We use Advanced Capability to do FLR. 1.85 - pos = self.find_cap_offset(PCI_CAP_ID_AF) 1.86 - self.pci_conf_write8(pos + PCI_AF_CTL, PCI_AF_CTL_FLR) 1.87 - time.sleep(0.100) 1.88 - restore_pci_conf_space((pci_list, cfg_list)) 1.89 + af_pos = self.find_cap_offset(PCI_CAP_ID_AF) 1.90 + self.do_AF_FLR(af_pos) 1.91 else: 1.92 if self.bus == 0: 1.93 - self.do_FLR_for_integrated_device() 1.94 + if self.slot == 0x02 and self.func == 0x0: 1.95 + vendor_id = self.pci_conf_read16(PCI_VENDOR_ID) 1.96 + if vendor_id != VENDOR_INTEL: 1.97 + return 1.98 + class_id = self.pci_conf_read16(PCI_CLASS_DEVICE) 1.99 + if class_id != PCI_CLASS_ID_VGA: 1.100 + return 1.101 + device_id = self.pci_conf_read16(PCI_DEVICE_ID) 1.102 + if device_id == PCI_DEVICE_ID_IGFX_GM45: 1.103 + self.do_FLR_for_GM45_iGFX() 1.104 + elif device_id == PCI_DEVICE_ID_IGFX_EAGLELAKE or \ 1.105 + device_id == PCI_DEVICE_ID_IGFX_Q45 or \ 1.106 + device_id == PCI_DEVICE_ID_IGFX_G45 or \ 1.107 + device_id == PCI_DEVICE_ID_IGFX_G41: 1.108 + self.do_FLR_for_intel_4Series_iGFX() 1.109 + else: 1.110 + log.debug("Unknown iGFX device_id:%x", device_id) 1.111 + else: 1.112 + self.do_FLR_for_integrated_device() 1.113 else: 1.114 devs = self.find_coassigned_pci_devices(False) 1.115 # Remove the element 0 which is a bridge