⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci.py

📁 xen虚拟机源代码安装包
💻 PY
📖 第 1 页 / 共 3 页
字号:
                else:                    self.dev_type = DEV_TYPE_PCIe_BRIDGE        else:            if  pos != 0:                self.dev_type = DEV_TYPE_PCIe_ENDPOINT            else:                self.dev_type = DEV_TYPE_PCI                        # Force 0000:00:00.0 to be DEV_TYPE_PCIe_BRIDGE        if self.name == '0000:00:00.0':            self.dev_type = DEV_TYPE_PCIe_BRIDGE        if (self.dev_type == DEV_TYPE_PCI_BRIDGE) or \            (self.dev_type == DEV_TYPE_PCIe_BRIDGE):            return        # Try to findthe PCIe FLR capability        if self.dev_type == DEV_TYPE_PCIe_ENDPOINT:            dev_cap = self.pci_conf_read32(pos + PCI_EXP_DEVCAP)            if dev_cap & PCI_EXP_DEVCAP_FLR:                self.pcie_flr = True        elif self.dev_type == DEV_TYPE_PCI:            # Try to find the "PCI Advanced Capabilities"            pos = self.find_cap_offset(PCI_CAP_ID_AF)            if pos != 0:                af_cap = self.pci_conf_read8(pos + PCI_AF_CAPs)                if (af_cap & PCI_AF_CAPs_TP_FLR) == PCI_AF_CAPs_TP_FLR:                    self.pci_af_flr = True        bar_addr = PCI_BAR_0        while bar_addr <= PCI_BAR_5:            bar = self.pci_conf_read32(bar_addr)            if (bar & PCI_BAR_SPACE) == PCI_BAR_MEM:                bar = bar & PCI_BAR_MEM_MASK                bar = bar & ~PAGE_MASK                if bar != 0:                    self.has_non_page_aligned_bar = True                    break             bar_addr = bar_addr + 4    def devs_check_driver(self, devs):        if len(devs) == 0:            return        for pci_dev in devs:            (dom, b, d, f) = parse_pci_name(pci_dev)            dev = PciDevice(dom, b, d, f)            if dev.driver == 'pciback':                continue            err_msg = 'pci: %s must be co-assigned to the same guest with %s' + \                ', but it is not owned by pciback.'            raise PciDeviceAssignmentError(err_msg % (pci_dev, self.name))    def do_FLR(self):        """ Perform FLR (Functional Level Reset) for the device.        """        if self.dev_type == DEV_TYPE_PCIe_ENDPOINT:            # If PCIe device supports FLR, we use it.            if self.pcie_flr:                (pci_list, cfg_list) = save_pci_conf_space([self.name])                pos = self.find_cap_offset(PCI_CAP_ID_EXP)                self.pci_conf_write32(pos + PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_FLR)                # We must sleep at least 100ms for the completion of FLR                time.sleep(0.200)                restore_pci_conf_space((pci_list, cfg_list))            else:                if self.bus == 0:                    self.do_Dstate_transition()                else:                    funcs = self.find_all_the_multi_functions()                    self.devs_check_driver(funcs)                    parent = '%04x:%02x:%02x.%01x' % self.find_parent()                    # Do Secondary Bus Reset.                    self.do_secondary_bus_reset(parent, funcs)        # PCI devices        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.200)                restore_pci_conf_space((pci_list, cfg_list))            else:                if self.bus == 0:                    self.do_Dstate_transition()                else:                    devs = self.find_coassigned_devices(False)                    # Remove the element 0 which is a bridge                    target_bus = devs[0]                    del devs[0]                    self.devs_check_driver(devs)                    # Do Secondary Bus Reset.                    self.do_secondary_bus_reset(target_bus, devs)    def find_capability(self, type):        sysfs_mnt = find_sysfs_mnt()        if sysfs_mnt == None:            return False        path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \               self.name+SYSFS_PCI_DEV_CONFIG_PATH        try:            conf_file = open(path, 'rb')            conf_file.seek(PCI_HEADER_TYPE)            header_type = ord(conf_file.read(1)) & PCI_HEADER_TYPE_MASK            if header_type == PCI_HEADER_TYPE_CARDBUS:                return            conf_file.seek(PCI_STATUS_OFFSET)            status = ord(conf_file.read(1))            if status&PCI_STATUS_CAP_MASK:                conf_file.seek(PCI_CAP_OFFSET)                capa_pointer = ord(conf_file.read(1))                capa_count = 0                while capa_pointer:                    if capa_pointer < 0x40:                        raise PciDeviceParseError(                            ('Broken capability chain: %s' % self.name))                    capa_count += 1                    if capa_count > 96:                        raise PciDeviceParseError(                            ('Looped capability chain: %s' % self.name))                    conf_file.seek(capa_pointer)                    capa_id = ord(conf_file.read(1))                    capa_pointer = ord(conf_file.read(1))                    if capa_id == type:                        # get the type                        message_cont_lo = ord(conf_file.read(1))                        message_cont_hi = ord(conf_file.read(1))                        self.msix=1                        self.msix_entries = (message_cont_lo + \                                             (message_cont_hi << 8)) \                                             & MSIX_SIZE_MASK                        t_off=conf_file.read(4)                        p_off=conf_file.read(4)                        self.table_offset=ord(t_off[0]) | (ord(t_off[1])<<8) | \                                          (ord(t_off[2])<<16)|  \                                          (ord(t_off[3])<<24)                        self.pba_offset=ord(p_off[0]) | (ord(p_off[1]) << 8)| \                                        (ord(p_off[2])<<16) | \                                        (ord(p_off[3])<<24)                        self.table_index = self.table_offset & MSIX_BIR_MASK                        self.table_offset = self.table_offset & ~MSIX_BIR_MASK                        self.pba_index = self.pba_offset & MSIX_BIR_MASK                        self.pba_offset = self.pba_offset & ~MSIX_BIR_MASK                        break        except IOError, (errno, strerr):            raise PciDeviceParseError(('Failed to locate sysfs mount: %s: %s (%d)' %                (PROC_PCI_PATH, strerr, errno)))    def remove_msix_iomem(self, index, start, size):        if (index == self.table_index):            table_start = start+self.table_offset            table_end = table_start + self.msix_entries * 16            table_start = table_start & PAGE_MASK            table_end = (table_end + PAGE_SIZE) & PAGE_MASK            self.msix_iomem.append((table_start, table_end-table_start))        if (index==self.pba_index):            pba_start = start + self.pba_offset            pba_end = pba_start + self.msix_entries/8            pba_start = pba_start & PAGE_MASK            pba_end = (pba_end + PAGE_SIZE) & PAGE_MASK            self.msix_iomem.append((pba_start, pba_end-pba_start))    def get_info_from_sysfs(self):        self.find_capability(0x11)        sysfs_mnt = find_sysfs_mnt()        if sysfs_mnt == None:            return False        path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \                self.name+SYSFS_PCI_DEV_RESOURCE_PATH        try:            resource_file = open(path,'r')            for i in range(PROC_PCI_NUM_RESOURCES):                line = resource_file.readline()                sline = line.split()                if len(sline)<3:                    continue                start = int(sline[0],16)                end = int(sline[1],16)                flags = int(sline[2],16)                size = end-start+1                if start!=0:                    if flags&PCI_BAR_IO:                        self.ioports.append( (start,size) )                    else:                        self.iomem.append( (start,size) )                    if (self.msix):                        self.remove_msix_iomem(i, start, size)        except IOError, (errno, strerr):            raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %                (path, strerr, errno)))        path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \                self.name+SYSFS_PCI_DEV_IRQ_PATH        try:            self.irq = int(open(path,'r').readline())        except IOError, (errno, strerr):            raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %                (path, strerr, errno)))        path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \                self.name+SYSFS_PCI_DEV_DRIVER_DIR_PATH        try:            self.driver = os.path.basename(os.readlink(path))        except OSError, (errno, strerr):            self.driver = ""        path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \                self.name+SYSFS_PCI_DEV_VENDOR_PATH        try:            self.vendor = int(open(path,'r').readline(), 16)        except IOError, (errno, strerr):            raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %                (path, strerr, errno)))        path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \                self.name+SYSFS_PCI_DEV_DEVICE_PATH        try:            self.device = int(open(path,'r').readline(), 16)        except IOError, (errno, strerr):            raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %                (path, strerr, errno)))        path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \                self.name+SYSFS_PCI_DEV_SUBVENDOR_PATH        try:            self.subvendor = int(open(path,'r').readline(), 16)        except IOError, (errno, strerr):            raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %                (path, strerr, errno)))        path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \                self.name+SYSFS_PCI_DEV_SUBDEVICE_PATH        try:            self.subdevice = int(open(path,'r').readline(), 16)        except IOError, (errno, strerr):            raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %                (path, strerr, errno)))        path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \                self.name+SYSFS_PCI_DEV_CLASS_PATH        try:            self.classcode = int(open(path,'r').readline(), 16)        except IOError, (errno, strerr):            raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %                (path, strerr, errno)))        return True    def get_info_from_lspci(self):        """ Get information such as vendor name, device name, class name, etc.        Since we cannot obtain these data from sysfs, use 'lspci' command.        """        global lspci_info        if lspci_info is None:            create_lspci_info()        try:            device_info = lspci_info[self.name]            self.revision = int(device_info['Rev'], 16)            self.vendorname = device_info['Vendor']            self.devicename = device_info['Device']            self.classname = device_info['Class']            self.subvendorname = device_info['SVendor']            self.subdevicename = device_info['SDevice']        except KeyError:            pass        return True    def __str__(self):        str = "PCI Device %s\n" % (self.name)        for (start,size) in self.ioports:            str = str + "IO Port 0x%02x [size=%d]\n"%(start,size)        for (start,size) in self.iomem:            str = str + "IO Mem 0x%02x [size=%d]\n"%(start,size)        str = str + "IRQ %d\n"%(self.irq)        str = str + "Vendor ID 0x%04x\n"%(self.vendor)        str = str + "Device ID 0x%04x\n"%(self.device)        str = str + "Sybsystem Vendor ID 0x%04x\n"%(self.subvendor)        str = str + "Subsystem Device ID 0x%04x"%(self.subdevice)        return strdef main():    if len(sys.argv)<5:        print "Usage: %s <domain> <bus> <slot> <func>\n" % sys.argv[0]        sys.exit(2)    dev = PciDevice(int(sys.argv[1],16), int(sys.argv[2],16),            int(sys.argv[3],16), int(sys.argv[4],16))    print str(dev)if __name__=='__main__':    main()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -