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>
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