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

📄 pci.py

📁 xen虚拟机源代码安装包
💻 PY
📖 第 1 页 / 共 3 页
字号:
    for pci_names in pci_list:        devs = []        for pci in pci_names:            devs = devs + [pci_dev_dict[pci]]        result = result + [devs]    return resultdef check_mmio_bar(devs_list):    result = []    for dev_list in devs_list:        non_aligned_bar_found = False        for dev in dev_list:            if dev.has_non_page_aligned_bar:                non_aligned_bar_found = True                break        if not non_aligned_bar_found:            result = result + [dev_list]    return resultclass PciDeviceNotFoundError(Exception):    def __init__(self,domain,bus,slot,func):        self.domain = domain        self.bus = bus        self.slot = slot        self.func = func        self.name = PCI_DEV_FORMAT_STR %(domain, bus, slot, func)        def __str__(self):        return ('PCI Device %s Not Found' % (self.name))class PciDeviceParseError(Exception):    def __init__(self,msg):        self.message = msg    def __str__(self):        return 'Error Parsing PCI Device Info: '+self.messageclass PciDeviceAssignmentError(Exception):    def __init__(self,msg):        self.message = msg    def __str__(self):        return 'pci: impproper device assignment spcified: ' + \            self.messageclass PciDevice:    def __init__(self, domain, bus, slot, func):        self.domain = domain        self.bus = bus        self.slot = slot        self.func = func        self.name = PCI_DEV_FORMAT_STR % (domain, bus, slot, func)        self.cfg_space_path = find_sysfs_mnt()+SYSFS_PCI_DEVS_PATH+'/'+ \            self.name + SYSFS_PCI_DEV_CONFIG_PATH         self.irq = 0        self.iomem = []        self.ioports = []        self.driver = None        self.vendor = None        self.device = None        self.subvendor = None        self.subdevice = None        self.msix = 0        self.msix_iomem = []        self.revision = 0        self.classcode = None        self.vendorname = ""        self.devicename = ""        self.classname = ""        self.subvendorname = ""        self.subdevicename = ""        self.dev_type = None        self.has_non_page_aligned_bar = False        self.pcie_flr = False        self.pci_af_flr = False        self.detect_dev_info()        self.get_info_from_sysfs()        self.get_info_from_lspci()    def find_parent(self):        # i.e.,  /sys/bus/pci/devices/0000:00:19.0 or        #        /sys/bus/pci/devices/0000:03:04.0        path = find_sysfs_mnt()+SYSFS_PCI_DEVS_PATH+'/'+ self.name        # i.e., ../../../devices/pci0000:00/0000:00:19.0        #  ../../../devices/pci0000:00/0000:00:02.0/0000:01:00.2/0000:03:04.0        try:            target = os.readlink(path)            lst = target.split('/')            parent = lst[len(lst)-2]            if parent[0:3] == 'pci':                parent = parent[3:]                lst = parent.split(':')                dom = int(lst[0], 16)                bus = int(lst[1], 16)                dev = 0                func = 0            else:                lst = parent.split(':')                dom = int(lst[0], 16)                bus = int(lst[1], 16)                lst = lst[2]                lst = lst.split('.')                dev =  int(lst[0], 16)                func =  int(lst[1], 16)            return (dom, bus, dev, func)        except OSError, (errno, strerr):            raise PciDeviceParseError('Can not locate the parent of %s',                self.name)    def find_the_uppermost_pci_bridge(self):        # Find the uppermost PCI/PCI-X bridge        (dom, b, d, f) = self.find_parent()        dev = dev_parent = PciDevice(dom, b, d, f)        while dev_parent.dev_type != DEV_TYPE_PCIe_BRIDGE:            (dom, b, d, f) = dev_parent.find_parent()            dev = dev_parent            dev_parent = PciDevice(dom, b, d, f)        return dev    def find_all_devices_behind_the_bridge(self, ignore_bridge):        sysfs_mnt = find_sysfs_mnt()        self_path = sysfs_mnt + SYSFS_PCI_DEVS_PATH + '/' + self.name        pci_names = os.popen('ls ' + self_path).read()        dev_list = re.findall(PCI_DEV_REG_EXPRESS_STR, pci_names)        list = [self.name]        for pci_str in dev_list:            (dom, b, d, f) = parse_pci_name(pci_str)            dev = PciDevice(dom, b, d, f)            if dev.dev_type == DEV_TYPE_PCI_BRIDGE or \                dev.dev_type == DEV_TYPE_PCIe_BRIDGE:                sub_list_including_self = \                    dev.find_all_devices_behind_the_bridge(ignore_bridge)                if ignore_bridge:                    del sub_list_including_self[0]                list = list + [sub_list_including_self]            else:                list = list + [dev.name]        return list            def find_coassigned_devices(self, ignore_bridge = True):        ''' Here'self' is a PCI device, we need find the uppermost PCI/PCI-X            bridge, and all devices behind it must be co-assigned to the same            guest.                    Parameter:                [ignore_bridge]: if set, the returned result doesn't include            any bridge behind the uppermost PCI/PCI-X bridge.                    Note: The first element of the return value is the uppermost                PCI/PCI-X bridge. If the caller doesn't need the first                element,  the caller itself can remove it explicitly.        '''        dev = self.find_the_uppermost_pci_bridge()        dev_list = dev.find_all_devices_behind_the_bridge(ignore_bridge)        dev_list = re.findall(PCI_DEV_REG_EXPRESS_STR, '%s' % dev_list)        return dev_list    def do_secondary_bus_reset(self, target_bus, devs):        # Save the config spaces of all the devices behind the bus.        (pci_list, cfg_list) = save_pci_conf_space(devs)                #Do the Secondary Bus Reset        sysfs_mnt = find_sysfs_mnt()        parent_path = sysfs_mnt + SYSFS_PCI_DEVS_PATH + '/' + \            target_bus + SYSFS_PCI_DEV_CONFIG_PATH        fd = os.open(parent_path, os.O_WRONLY)        # Assert Secondary Bus Reset        os.lseek(fd, PCI_CB_BRIDGE_CONTROL, 0)        os.write(fd, struct.pack('I', PCI_BRIDGE_CTL_BUS_RESET))        time.sleep(0.200)        # De-assert Secondary Bus Reset        os.lseek(fd, 0x3e, 0)        os.write(fd, struct.pack('I', 0x00))        time.sleep(0.200)        os.close(fd)        # Restore the config spaces        restore_pci_conf_space((pci_list, cfg_list))            def do_Dstate_transition(self):        pos = self.find_cap_offset(PCI_CAP_ID_PM)        if pos == 0:            return                 (pci_list, cfg_list) = save_pci_conf_space([self.name])                # Enter D3hot without soft reset        pm_ctl = self.pci_conf_read32(pos + PCI_PM_CTRL)        pm_ctl |= PCI_PM_CTRL_NO_SOFT_RESET        pm_ctl &= ~PCI_PM_CTRL_STATE_MASK        pm_ctl |= PCI_D3hot        self.pci_conf_write32(pos + PCI_PM_CTRL, pm_ctl)        time.sleep(0.010)        # From D3hot to D0        self.pci_conf_write32(pos + PCI_PM_CTRL, 0)        time.sleep(0.010)        restore_pci_conf_space((pci_list, cfg_list))    def find_all_the_multi_functions(self):        sysfs_mnt = find_sysfs_mnt()        pci_names = os.popen('ls ' + sysfs_mnt + SYSFS_PCI_DEVS_PATH).read()        p = self.name        p = p[0 : p.rfind('.')] + '.[0-7]'        funcs = re.findall(p, pci_names)        return funcs    def find_cap_offset(self, cap):        path = find_sysfs_mnt()+SYSFS_PCI_DEVS_PATH+'/'+ \               self.name+SYSFS_PCI_DEV_CONFIG_PATH        pos = PCI_CAPABILITY_LIST        try:            fd = os.open(path, os.O_RDONLY)            os.lseek(fd, PCI_STATUS, 0)            status = struct.unpack('H', os.read(fd, 2))[0]            if (status & 0x10) == 0:                # The device doesn't support PCI_STATUS_CAP_LIST                return 0            max_cap = 48            while max_cap > 0:                os.lseek(fd, pos, 0)                pos = ord(os.read(fd, 1))                if pos < 0x40:                    pos = 0                    break;                os.lseek(fd, pos + 0, 0)                id = ord(os.read(fd, 1))                if id == 0xff:                    pos = 0                    break;                # Found the capability                if id == cap:                    break;                # Test the next one                pos = pos + 1                max_cap = max_cap - 1;            os.close(fd)        except OSError, (errno, strerr):            raise PciDeviceParseError(('Error when accessing sysfs: %s (%d)' %                (strerr, errno)))        return pos    def pci_conf_read8(self, pos):        fd = os.open(self.cfg_space_path, os.O_RDONLY)        os.lseek(fd, pos, 0)        str = os.read(fd, 1)        os.close(fd)        val = struct.unpack('B', str)[0]        return val    def pci_conf_read16(self, pos):        fd = os.open(self.cfg_space_path, os.O_RDONLY)        os.lseek(fd, pos, 0)        str = os.read(fd, 2)        os.close(fd)        val = struct.unpack('H', str)[0]        return val    def pci_conf_read32(self, pos):        fd = os.open(self.cfg_space_path, os.O_RDONLY)        os.lseek(fd, pos, 0)        str = os.read(fd, 4)        os.close(fd)        val = struct.unpack('I', str)[0]        return val    def pci_conf_write8(self, pos, val):        str = struct.pack('B', val)        fd = os.open(self.cfg_space_path, os.O_WRONLY)        os.lseek(fd, pos, 0)        os.write(fd, str)        os.close(fd)    def pci_conf_write16(self, pos, val):        str = struct.pack('H', val)        fd = os.open(self.cfg_space_path, os.O_WRONLY)        os.lseek(fd, pos, 0)        os.write(fd, str)        os.close(fd)    def pci_conf_write32(self, pos, val):        str = struct.pack('I', val)        fd = os.open(self.cfg_space_path, os.O_WRONLY)        os.lseek(fd, pos, 0)        os.write(fd, str)        os.close(fd)    def detect_dev_info(self):        class_dev = self.pci_conf_read16(PCI_CLASS_DEVICE)        pos = self.find_cap_offset(PCI_CAP_ID_EXP)        if class_dev == PCI_CLASS_BRIDGE_PCI:            if pos == 0:                self.dev_type = DEV_TYPE_PCI_BRIDGE            else:                creg = self.pci_conf_read16(pos + PCI_EXP_FLAGS)                if ((creg & PCI_EXP_TYPE_PCI_BRIDGE) >> 4) == \                    PCI_EXP_TYPE_PCI_BRIDGE:                    self.dev_type = DEV_TYPE_PCI_BRIDGE

⌨️ 快捷键说明

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