Zhao, Yu
2008-Sep-27 08:59 UTC
[Xen-devel] [PATCH 8/9] qemu: enable HMV guest SR-IOV support
Add SR-IOV support for HVM guest. Signed-off-by: Yu Zhao <yu.zhao@intel.com> diff --git a/hw/pass-through.c b/hw/pass-through.c index 77ab759..da1a86b 100644 --- a/hw/pass-through.c +++ b/hw/pass-through.c @@ -47,6 +47,10 @@ struct dpci_infos { /* prototype */ static uint32_t pt_common_reg_init(struct pt_dev *ptdev, struct pt_reg_info_tbl *reg, uint32_t real_offset); +static uint32_t pt_vendor_reg_init(struct pt_dev *ptdev, + struct pt_reg_info_tbl *reg, uint32_t real_offset); +static uint32_t pt_device_reg_init(struct pt_dev *ptdev, + struct pt_reg_info_tbl *reg, uint32_t real_offset); static uint32_t pt_ptr_reg_init(struct pt_dev *ptdev, struct pt_reg_info_tbl *reg, uint32_t real_offset); static uint32_t pt_status_reg_init(struct pt_dev *ptdev, @@ -90,6 +94,9 @@ static int pt_word_reg_read(struct pt_dev *ptdev, static int pt_long_reg_read(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, uint32_t *value, uint32_t valid_mask); +static int pt_cmd_reg_read(struct pt_dev *ptdev, + struct pt_reg_tbl *cfg_entry, + uint16_t *value, uint16_t valid_mask); static int pt_bar_reg_read(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, uint32_t *value, uint32_t valid_mask); @@ -151,6 +158,28 @@ static int pt_msixctrl_reg_write(struct pt_dev *ptdev, /* Header Type0 reg static infomation table */ static struct pt_reg_info_tbl pt_emu_reg_header0_tbl[] = { + /* Vendor ID reg */ + { + .offset = PCI_VENDOR_ID, + .size = 2, + .init_val = 0x0000, + .ro_mask = 0xFFFF, + .emu_mask = 0xFFFF, + .init = pt_vendor_reg_init, + .u.w.read = pt_word_reg_read, + .u.w.write = pt_word_reg_write, + }, + /* Device ID reg */ + { + .offset = PCI_DEVICE_ID, + .size = 2, + .init_val = 0x0000, + .ro_mask = 0xFFFF, + .emu_mask = 0xFFFF, + .init = pt_device_reg_init, + .u.w.read = pt_word_reg_read, + .u.w.write = pt_word_reg_write, + }, /* Command reg */ { .offset = PCI_COMMAND, @@ -159,7 +188,7 @@ static struct pt_reg_info_tbl pt_emu_reg_header0_tbl[] = { .ro_mask = 0xF880, .emu_mask = 0x0340, .init = pt_common_reg_init, - .u.w.read = pt_word_reg_read, + .u.w.read = pt_cmd_reg_read, .u.w.write = pt_cmd_reg_write, }, /* Capabilities Pointer reg */ @@ -1753,6 +1782,14 @@ static void pt_config_delete(struct pt_dev *ptdev) } } +/* check if the device is a Virtual Function */ +static int pt_is_vf(struct pt_dev *ptdev) +{ + uint32_t head = PT_BAR_ALLF; /* Vendor and Device ID */ + + return !memcmp(&head, ptdev->dev.config, sizeof(head)); +} + /* initialize common register value */ static uint32_t pt_common_reg_init(struct pt_dev *ptdev, struct pt_reg_info_tbl *reg, uint32_t real_offset) @@ -1760,6 +1797,20 @@ static uint32_t pt_common_reg_init(struct pt_dev *ptdev, return reg->init_val; } +/* initialize Vendor ID register value */ +static uint32_t pt_vendor_reg_init(struct pt_dev *ptdev, + struct pt_reg_info_tbl *reg, uint32_t real_offset) +{ + return ptdev->pci_dev->vendor_id; +} + +/* initialize Device ID register value */ +static uint32_t pt_device_reg_init(struct pt_dev *ptdev, + struct pt_reg_info_tbl *reg, uint32_t real_offset) +{ + return ptdev->pci_dev->device_id; +} + /* initialize Capabilities Pointer or Next Pointer register */ static uint32_t pt_ptr_reg_init(struct pt_dev *ptdev, struct pt_reg_info_tbl *reg, uint32_t real_offset) @@ -2218,6 +2269,26 @@ static int pt_long_reg_read(struct pt_dev *ptdev, return 0; } +/* read Command register */ +static int pt_cmd_reg_read(struct pt_dev *ptdev, + struct pt_reg_tbl *cfg_entry, + uint16_t *value, uint16_t valid_mask) +{ + struct pt_reg_info_tbl *reg = cfg_entry->reg; + uint16_t valid_emu_mask = 0; + uint16_t emu_mask = reg->emu_mask; + + if (pt_is_vf(ptdev)) + emu_mask |= PCI_COMMAND_MEMORY; + + /* emulate word register */ + valid_emu_mask = emu_mask & valid_mask; + *value = ((*value & ~valid_emu_mask) | + (cfg_entry->data & valid_emu_mask)); + + return 0; +} + /* read BAR */ static int pt_bar_reg_read(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, @@ -2337,14 +2408,18 @@ static int pt_cmd_reg_write(struct pt_dev *ptdev, uint16_t writable_mask = 0; uint16_t throughable_mask = 0; uint16_t wr_value = *value; + uint16_t emu_mask = reg->emu_mask; + + if (pt_is_vf(ptdev)) + emu_mask |= PCI_COMMAND_MEMORY; /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; + writable_mask = emu_mask & ~reg->ro_mask & valid_mask; cfg_entry->data = ((*value & writable_mask) | (cfg_entry->data & ~writable_mask)); /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; + throughable_mask = ~emu_mask & valid_mask; *value = ((*value & throughable_mask) | (dev_value & ~throughable_mask)); /* mapping BAR */ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Seemingly Similar Threads
- [patch]: qemu-xen: pass-through: pt_reset_interrupt_and_io_mapping(): use hw INTX
- [PATCH] isohybrid: fix overflow on 32 bit system
- [PATCH][ioemu] support the assignment of the VF of Intel 82599 10GbE Controller
- [PATCH][RFC] Support more Capability Structures and Device Specific
- rombios unable to loaded MPT BIOS