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

📄 pass-through.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 5 页
字号:
        .init       = pt_common_reg_init,        .u.w.read   = pt_word_reg_read,        .u.w.write  = pt_devctrl_reg_write,    },    /* Link Control reg */    {        .offset     = PCI_EXP_LNKCTL,        .size       = 2,        .init_val   = 0x0000,        .ro_mask    = 0x0000,        .emu_mask   = 0xFFFF,        .init       = pt_common_reg_init,        .u.w.read   = pt_word_reg_read,        .u.w.write  = pt_linkctrl_reg_write,    },    /* Device Control 2 reg */    {        .offset     = 0x28,        .size       = 2,        .init_val   = 0x0000,        .ro_mask    = 0x0000,        .emu_mask   = 0xFFFF,        .init       = pt_common_reg_init,        .u.w.read   = pt_word_reg_read,        .u.w.write  = pt_devctrl2_reg_write,    },    /* Link Control 2 reg */    {        .offset     = 0x30,        .size       = 2,        .init_val   = 0x0000,        .ro_mask    = 0x0000,        .emu_mask   = 0xFFFF,        .init       = pt_linkctrl2_reg_init,        .u.w.read   = pt_word_reg_read,        .u.w.write  = pt_linkctrl2_reg_write,    },    {        .size = 0,    }, };/* MSI Capability Structure reg static infomation table */static struct pt_reg_info_tbl pt_emu_reg_msi_tbl[] = {    /* Next Pointer reg */    {        .offset     = PCI_CAP_LIST_NEXT,        .size       = 1,        .init_val   = 0x00,        .ro_mask    = 0xFF,        .emu_mask   = 0xFF,        .init       = pt_ptr_reg_init,        .u.b.read   = pt_byte_reg_read,        .u.b.write  = pt_byte_reg_write,    },    /* Message Control reg */    {        .offset     = PCI_MSI_FLAGS, // 2        .size       = 2,        .init_val   = 0x0000,        .ro_mask    = 0x018E,        .emu_mask   = 0xFFFE,        .init       = pt_msgctrl_reg_init,        .u.w.read   = pt_word_reg_read,        .u.w.write  = pt_msgctrl_reg_write,    },    /* Message Address reg */    {        .offset     = PCI_MSI_ADDRESS_LO, // 4        .size       = 4,        .init_val   = 0x00000000,        .ro_mask    = 0x00000FF0,    /* bit 4~11 is reserved for MSI in x86 */        .emu_mask   = 0xFFFFFFFF,        .init       = pt_msgaddr32_reg_init,        .u.dw.read  = pt_long_reg_read,        .u.dw.write = pt_msgaddr32_reg_write,    },    /* Message Upper Address reg (if PCI_MSI_FLAGS_64BIT set) */    {        .offset     = PCI_MSI_ADDRESS_HI, // 8        .size       = 4,        .init_val   = 0x00000000,        .ro_mask    = 0x00000000,        .emu_mask   = 0xFFFFFFFF,        .init       = pt_msgaddr64_reg_init,        .u.dw.read  = pt_long_reg_read,        .u.dw.write = pt_msgaddr64_reg_write,    },    /* Message Data reg (16 bits of data for 32-bit devices) */    {        .offset     = PCI_MSI_DATA_32, // 8        .size       = 2,        .init_val   = 0x0000,        .ro_mask    = 0x3800,        .emu_mask   = 0xFFFF,        .init       = pt_msgdata_reg_init,        .u.w.read   = pt_word_reg_read,        .u.w.write  = pt_msgdata_reg_write,    },    /* Message Data reg (16 bits of data for 64-bit devices) */    {        .offset     = PCI_MSI_DATA_64, // 12        .size       = 2,        .init_val   = 0x0000,        .ro_mask    = 0x3800,        .emu_mask   = 0xFFFF,        .init       = pt_msgdata_reg_init,        .u.w.read   = pt_word_reg_read,        .u.w.write  = pt_msgdata_reg_write,    },    {        .size = 0,    }, };/* MSI-X Capability Structure reg static infomation table */static struct pt_reg_info_tbl pt_emu_reg_msix_tbl[] = {    /* Next Pointer reg */    {        .offset     = PCI_CAP_LIST_NEXT,        .size       = 1,        .init_val   = 0x00,        .ro_mask    = 0xFF,        .emu_mask   = 0xFF,        .init       = pt_ptr_reg_init,        .u.b.read   = pt_byte_reg_read,        .u.b.write  = pt_byte_reg_write,    },    /* Message Control reg */    {        .offset     = PCI_MSI_FLAGS, // 2        .size       = 2,        .init_val   = 0x0000,        .ro_mask    = 0x3FFF,        .emu_mask   = 0x0000,        .init       = pt_msixctrl_reg_init,        .u.w.read   = pt_word_reg_read,        .u.w.write  = pt_msixctrl_reg_write,    },    {        .size = 0,    }, };/* pt_reg_grp_info_tbl declaration * - only for emulated or zero-hardwired register group. * - for register group with dynamic size, just set grp_size to 0xFF and  *   specify size_init func properly. * - no need to specify emu_reg_tbl for zero-hardwired type. *//* emul reg group static infomation table */static const struct pt_reg_grp_info_tbl pt_emu_reg_grp_tbl[] = {    /* Header Type0 reg group */    {        .grp_id     = 0xFF,        .grp_type   = GRP_TYPE_EMU,        .grp_size   = 0x40,        .size_init  = pt_reg_grp_size_init,        .emu_reg_tbl= pt_emu_reg_header0_tbl,    },    /* PCI PowerManagement Capability reg group */    {        .grp_id     = PCI_CAP_ID_PM,        .grp_type   = GRP_TYPE_EMU,        .grp_size   = PCI_PM_SIZEOF,        .size_init  = pt_reg_grp_size_init,        .emu_reg_tbl= pt_emu_reg_pm_tbl,    },    /* AGP Capability Structure reg group */    {        .grp_id     = PCI_CAP_ID_AGP,        .grp_type   = GRP_TYPE_HARDWIRED,        .grp_size   = 0x30,        .size_init  = pt_reg_grp_size_init,    },    /* Vital Product Data Capability Structure reg group */    {        .grp_id     = PCI_CAP_ID_VPD,        .grp_type   = GRP_TYPE_EMU,        .grp_size   = 0x08,        .size_init  = pt_reg_grp_size_init,        .emu_reg_tbl= pt_emu_reg_vpd_tbl,    },    /* Slot Identification reg group */    {        .grp_id     = PCI_CAP_ID_SLOTID,        .grp_type   = GRP_TYPE_HARDWIRED,        .grp_size   = 0x04,        .size_init  = pt_reg_grp_size_init,    },    /* MSI Capability Structure reg group */    {        .grp_id     = PCI_CAP_ID_MSI,        .grp_type   = GRP_TYPE_EMU,        .grp_size   = 0xFF,        .size_init  = pt_msi_size_init,        .emu_reg_tbl= pt_emu_reg_msi_tbl,    },    /* PCI-X Capabilities List Item reg group */    {        .grp_id     = PCI_CAP_ID_PCIX,        .grp_type   = GRP_TYPE_HARDWIRED,        .grp_size   = 0x18,        .size_init  = pt_reg_grp_size_init,    },    /* Vendor Specific Capability Structure reg group */    {        .grp_id     = PCI_CAP_ID_VNDR,        .grp_type   = GRP_TYPE_EMU,        .grp_size   = 0xFF,        .size_init  = pt_vendor_size_init,        .emu_reg_tbl= pt_emu_reg_vendor_tbl,    },    /* SHPC Capability List Item reg group */    {        .grp_id     = PCI_CAP_ID_HOTPLUG,        .grp_type   = GRP_TYPE_HARDWIRED,        .grp_size   = 0x08,        .size_init  = pt_reg_grp_size_init,    },    /* Subsystem ID and Subsystem Vendor ID Capability List Item reg group */    {        .grp_id     = PCI_CAP_ID_SSVID,        .grp_type   = GRP_TYPE_HARDWIRED,        .grp_size   = 0x08,        .size_init  = pt_reg_grp_size_init,    },    /* AGP 8x Capability Structure reg group */    {        .grp_id     = PCI_CAP_ID_AGP3,        .grp_type   = GRP_TYPE_HARDWIRED,        .grp_size   = 0x30,        .size_init  = pt_reg_grp_size_init,    },    /* PCI Express Capability Structure reg group */    {        .grp_id     = PCI_CAP_ID_EXP,        .grp_type   = GRP_TYPE_EMU,        .grp_size   = 0x3C,        .size_init  = pt_reg_grp_size_init,        .emu_reg_tbl= pt_emu_reg_pcie_tbl,    },    /* MSI-X Capability Structure reg group */    {        .grp_id     = PCI_CAP_ID_MSIX,        .grp_type   = GRP_TYPE_EMU,        .grp_size   = 0x0C,        .size_init  = pt_msix_size_init,        .emu_reg_tbl= pt_emu_reg_msix_tbl,    },    {        .grp_size = 0,    }, };static int token_value(char *token){    return strtol(token, NULL, 16);}static int next_bdf(char **str, int *seg, int *bus, int *dev, int *func){    char *token, *delim = ":.-";    if ( !(*str) ||          ( !strchr(*str, ':') && !strchr(*str, '.')) )        return 0;    token  = strsep(str, delim);    *seg = token_value(token);    token  = strsep(str, delim);    *bus  = token_value(token);    token  = strsep(str, delim);    *dev  = token_value(token);    token  = strsep(str, delim);    *func  = token_value(token);    return 1;}/* Insert a new pass-through device into a specific pci slot. * input  dom:bus:dev.func@slot, chose free one if slot == 0 * return -1: required slot not available *         0: no free hotplug slots, but normal slot should okay *        >0: the new hotplug slot */static int __insert_to_pci_slot(int bus, int dev, int func, int slot){    int i, php_slot;    /* preferred virt pci slot */    if ( slot >= PHP_SLOT_START && slot < PHP_SLOT_END )    {        php_slot = PCI_TO_PHP_SLOT(slot);        if ( !dpci_infos.php_devs[php_slot].valid )        {            goto found;        }        else            return -1;    }    if ( slot != 0 )        return -1;    /* slot == 0, pick up a free one */    for ( i = 0; i < PHP_SLOT_LEN; i++ )    {        if ( !dpci_infos.php_devs[i].valid )        {            php_slot = i;            goto found;        }    }    /* not found */    return 0;found:    dpci_infos.php_devs[php_slot].valid  = 1;    dpci_infos.php_devs[php_slot].r_bus  = bus;    dpci_infos.php_devs[php_slot].r_dev  = dev;    dpci_infos.php_devs[php_slot].r_func = func;    return PHP_TO_PCI_SLOT(php_slot);}/* Insert a new pass-through device into a specific pci slot. * input  dom:bus:dev.func@slot */int insert_to_pci_slot(char *bdf_slt){    int seg, bus, dev, func, slot;    char *bdf_str, *slt_str, *delim="@";    bdf_str = strsep(&bdf_slt, delim);    slt_str = bdf_slt;    slot = token_value(slt_str);    if ( !next_bdf(&bdf_str, &seg, &bus, &dev, &func))    {        return -1;    }    return __insert_to_pci_slot(bus, dev, func, slot);}/* Test if a pci slot has a device * 1:  present * 0:  not present * -1: invalide pci slot input */int test_pci_slot(int slot){    int php_slot;    if ( slot < PHP_SLOT_START || slot >= PHP_SLOT_END )        return -1;    php_slot = PCI_TO_PHP_SLOT(slot);    if ( dpci_infos.php_devs[php_slot].valid )        return 1;    else        return 0;}/* find the pci slot for pass-through dev with specified BDF */int bdf_to_slot(char *bdf_str){    int seg, bus, dev, func, i;    if ( !next_bdf(&bdf_str, &seg, &bus, &dev, &func))    {        return -1;    }    /* locate the virtual pci slot for this VTd device */    for ( i = 0; i < PHP_SLOT_LEN; i++ )    {        if ( dpci_infos.php_devs[i].valid &&           dpci_infos.php_devs[i].r_bus == bus &&           dpci_infos.php_devs[i].r_dev  == dev &&           dpci_infos.php_devs[i].r_func == func )        {            return PHP_TO_PCI_SLOT(i);        }    }    return -1;}/* Being called each time a mmio region has been updated */void pt_iomem_map(PCIDevice *d, int i, uint32_t e_phys, uint32_t e_size,                  int type){    struct pt_dev *assigned_device  = (struct pt_dev *)d;     uint32_t old_ebase = assigned_device->bases[i].e_physbase;    int first_map = ( assigned_device->bases[i].e_size == 0 );    int ret = 0;    assigned_device->bases[i].e_physbase = e_phys;    assigned_device->bases[i].e_size= e_size;    PT_LOG("e_phys=%08x maddr=%lx type=%d len=%d index=%d first_map=%d\n",        e_phys, (unsigned long)assigned_device->bases[i].access.maddr,         type, e_size, i, first_map);    if ( e_size == 0 )        return;    if ( !first_map && old_ebase != -1 )    {        add_msix_mapping(assigned_device, i);        /* Remove old mapping */        ret = xc_domain_memory_mapping(xc_handle, domid,                old_ebase >> XC_PAGE_SHIFT,                assigned_device->bases[i].access.maddr >> XC_PAGE_SHIFT,                (e_size+XC_PAGE_SIZE-1) >> XC_PAGE_SHIFT,                DPCI_REMOVE_MAPPING);        if ( ret != 0 )        {            PT_LOG("Error: remove old mapping failed!\n");            return;        }    }

⌨️ 快捷键说明

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