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

📄 pci.py

📁 xen虚拟机源代码安装包
💻 PY
📖 第 1 页 / 共 3 页
字号:
#!/usr/bin/env python## PCI Device Information Class# - Helps obtain information about which I/O resources a PCI device needs##   Author: Ryan Wilson <hap9@epoch.ncsc.mil>import sysimport os, os.pathimport resourceimport reimport typesimport structimport timePROC_MNT_PATH = '/proc/mounts'PROC_PCI_PATH = '/proc/bus/pci/devices'PROC_PCI_NUM_RESOURCES = 7SYSFS_PCI_DEVS_PATH = '/bus/pci/devices'SYSFS_PCI_DEV_RESOURCE_PATH = '/resource'SYSFS_PCI_DEV_CONFIG_PATH = '/config'SYSFS_PCI_DEV_IRQ_PATH = '/irq'SYSFS_PCI_DEV_DRIVER_DIR_PATH = '/driver'SYSFS_PCI_DEV_VENDOR_PATH = '/vendor'SYSFS_PCI_DEV_DEVICE_PATH = '/device'SYSFS_PCI_DEV_SUBVENDOR_PATH = '/subsystem_vendor'SYSFS_PCI_DEV_SUBDEVICE_PATH = '/subsystem_device'SYSFS_PCI_DEV_CLASS_PATH = '/class'SYSFS_PCIBACK_PATH = '/bus/pci/drivers/pciback/'LSPCI_CMD = 'lspci'PCI_DEV_REG_EXPRESS_STR = r"[0-9a-fA-F]{4}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}."+ \            r"[0-9a-fA-F]{1}"PCI_DEV_FORMAT_STR = '%04x:%02x:%02x.%01x'DEV_TYPE_PCIe_ENDPOINT  = 0DEV_TYPE_PCIe_BRIDGE    = 1DEV_TYPE_PCI_BRIDGE     = 2DEV_TYPE_PCI            = 3    PCI_STATUS = 0x6PCI_CLASS_DEVICE = 0x0aPCI_CLASS_BRIDGE_PCI = 0x0604PCI_HEADER_TYPE = 0x0ePCI_HEADER_TYPE_MASK = 0x7fPCI_HEADER_TYPE_NORMAL  = 0PCI_HEADER_TYPE_BRIDGE  = 1PCI_HEADER_TYPE_CARDBUS = 2PCI_CAPABILITY_LIST = 0x34PCI_CB_BRIDGE_CONTROL = 0x3ePCI_BRIDGE_CTL_BUS_RESET= 0x40PCI_CAP_ID_EXP = 0x10PCI_EXP_FLAGS  = 0x2PCI_EXP_FLAGS_TYPE = 0x00f0PCI_EXP_TYPE_PCI_BRIDGE = 0x7PCI_EXP_DEVCAP = 0x4PCI_EXP_DEVCAP_FLR = (0x1 << 28)PCI_EXP_DEVCTL = 0x8PCI_EXP_DEVCTL_FLR = (0x1 << 15)PCI_CAP_ID_PM = 0x01PCI_PM_CTRL = 4PCI_PM_CTRL_NO_SOFT_RESET = 0x0004PCI_PM_CTRL_STATE_MASK = 0x0003PCI_D3hot = 3PCI_CAP_ID_AF = 0x13PCI_AF_CAPs   = 0x3PCI_AF_CAPs_TP_FLR = 0x3PCI_AF_CTL = 0x4PCI_AF_CTL_FLR = 0x1PCI_BAR_0 = 0x10PCI_BAR_5 = 0x24PCI_BAR_SPACE = 0x01PCI_BAR_IO = 0x01PCI_BAR_IO_MASK = ~0x03PCI_BAR_MEM = 0x00PCI_BAR_MEM_MASK = ~0x0fPCI_STATUS_CAP_MASK = 0x10PCI_STATUS_OFFSET = 0x6PCI_CAP_OFFSET = 0x34MSIX_BIR_MASK = 0x7MSIX_SIZE_MASK = 0x7ff# Global variable to store information from lspcilspci_info = None# Global variable to store the sysfs mount pointsysfs_mnt_point = None#Calculate PAGE_SHIFT: number of bits to shift an address to get the page numberPAGE_SIZE = resource.getpagesize()PAGE_SHIFT = 0t = PAGE_SIZEwhile not (t&1):    t>>=1    PAGE_SHIFT+=1PAGE_MASK=~(PAGE_SIZE - 1)# Definitions from Linux: include/linux/pci.hdef PCI_DEVFN(slot, func):    return ((((slot) & 0x1f) << 3) | ((func) & 0x07))def parse_hex(val):    try:        if isinstance(val, types.StringTypes):            return int(val, 16)        else:            return val    except ValueError:        return Nonedef parse_pci_name(pci_name_string):    pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" + \            r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + \            r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" + \            r"(?P<func>[0-7])$", pci_name_string)    if pci_match is None:        raise PciDeviceParseError(('Failed to parse pci device name: %s' %            pci_name_string))    pci_dev_info = pci_match.groupdict('0')    domain = parse_hex(pci_dev_info['domain'])    bus = parse_hex(pci_dev_info['bus'])    slot = parse_hex(pci_dev_info['slot'])    func = parse_hex(pci_dev_info['func'])    return (domain, bus, slot, func) def find_sysfs_mnt():    global sysfs_mnt_point    if not sysfs_mnt_point is None:        return sysfs_mnt_point    try:        mounts_file = open(PROC_MNT_PATH,'r')        for line in mounts_file:            sline = line.split()            if len(sline)<3:                continue            if sline[2]=='sysfs':                sysfs_mnt_point= sline[1]                return sysfs_mnt_point    except IOError, (errno, strerr):        raise PciDeviceParseError(('Failed to locate sysfs mount: %s: %s (%d)'%            (PROC_PCI_PATH, strerr, errno)))    return Nonedef get_all_pci_names():    sysfs_mnt = find_sysfs_mnt()    pci_names = os.popen('ls ' + sysfs_mnt + SYSFS_PCI_DEVS_PATH).read().split()    return pci_namesdef get_all_pci_devices():    pci_devs = []    for pci_name in get_all_pci_names():        pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" + \                r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + \                r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" + \                r"(?P<func>[0-7])$", pci_name)        if pci_match is None:            raise PciDeviceParseError(('Failed to parse pci device name: %s' %                pci_name))        pci_dev_info = pci_match.groupdict('0')        domain = parse_hex(pci_dev_info['domain'])        bus = parse_hex(pci_dev_info['bus'])        slot = parse_hex(pci_dev_info['slot'])        func = parse_hex(pci_dev_info['func'])        try:            pci_dev = PciDevice(domain, bus, slot, func)        except:            continue        pci_devs.append(pci_dev)    return pci_devsdef create_lspci_info():    global lspci_info    lspci_info = {}    # Execute 'lspci' command and parse the result.    # If the command does not exist, lspci_info will be kept blank ({}).    for paragraph in os.popen(LSPCI_CMD + ' -vmm').read().split('\n\n'):        device_name = None        device_info = {}        for line in paragraph.split('\n'):            try:                (opt, value) = line.split(':\t')                if opt == 'Slot':                    device_name = PCI_DEV_FORMAT_STR % parse_pci_name(value)                else:                    device_info[opt] = value            except:                pass        if device_name is not None:            lspci_info[device_name] = device_infodef save_pci_conf_space(devs_string):    pci_list = []    cfg_list = []    sysfs_mnt = find_sysfs_mnt()    for pci_str in devs_string:        pci_path = sysfs_mnt + SYSFS_PCI_DEVS_PATH + '/' + pci_str + \                SYSFS_PCI_DEV_CONFIG_PATH        fd = os.open(pci_path, os.O_RDONLY)        configs = []        for i in range(0, 256, 4):            configs = configs + [os.read(fd,4)]        os.close(fd)        pci_list = pci_list + [pci_path]        cfg_list = cfg_list + [configs]    return (pci_list, cfg_list)def restore_pci_conf_space(pci_cfg_list):    pci_list = pci_cfg_list[0]    cfg_list = pci_cfg_list[1]    for i in range(0, len(pci_list)):        pci_path = pci_list[i]        configs  = cfg_list[i]        fd = os.open(pci_path, os.O_WRONLY)        for dw in configs:            os.write(fd, dw)        os.close(fd) def find_all_devices_owned_by_pciback():    sysfs_mnt = find_sysfs_mnt()    pciback_path = sysfs_mnt + SYSFS_PCIBACK_PATH    pci_names = os.popen('ls ' + pciback_path).read()    pci_list = re.findall(PCI_DEV_REG_EXPRESS_STR, pci_names)    dev_list = []    for pci in pci_list:        (dom, b, d, f) = parse_pci_name(pci)        dev = PciDevice(dom, b, d, f)        dev_list = dev_list + [dev]    return dev_listdef transform_list(target, src):    ''' src: its element is pci string (Format: xxxx:xx:xx:x).        target: its element is pci string, or a list of pci string.        If all the elements in src are in target, we remove them from target        and add src into target; otherwise, we remove from target all the        elements that also appear in src.    '''    result = []    target_contains_src = True    for e in src:        if not e in target:            target_contains_src = False            break    if target_contains_src:        result = result + [src]    for e in target:        if not e in src:             result = result + [e]    return  resultdef check_FLR_capability(dev_list):    if len(dev_list) == 0:        return []    pci_list = []    pci_dev_dict = {}    for dev in dev_list:        pci_list = pci_list + [dev.name]        pci_dev_dict[dev.name] = dev    while True:        need_transform = False        for pci in pci_list:            if isinstance(pci, types.StringTypes):                dev = pci_dev_dict[pci]                if dev.bus == 0:                    continue                if dev.dev_type == DEV_TYPE_PCIe_ENDPOINT and not dev.pcie_flr:                    coassigned_pci_list = dev.find_all_the_multi_functions()                    need_transform = True                elif dev.dev_type == DEV_TYPE_PCI and not dev.pci_af_flr:                    coassigned_pci_list = dev.find_coassigned_devices(True)                    del coassigned_pci_list[0]                    need_transform = True                if need_transform:                    pci_list = transform_list(pci_list, coassigned_pci_list)        if not need_transform:            break    if len(pci_list) == 0:        return []    for i in range(0, len(pci_list)):        if isinstance(pci_list[i], types.StringTypes):            pci_list[i] = [pci_list[i]]        # Now every element in pci_list is a list of pci string.    result = []

⌨️ 快捷键说明

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