[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] ioemu-remote&ioemu: support PCI Express Capability Structure version 1.
This patch adds supporting PCI Express Capability Structure version 1 to ioemu-remote and ioemu. The format of PCI Express Capability Structure is different between version 1 and version 2. Current ioemu-remote and ioemu support only version 2. This might cause conflict with other capability structure if device implement version 1. So I created the patch to support version 1 in addition to version 2. Signed-off-by: Yuji Shimada <shimada-yxb@xxxxxxxxxxxxxxx> diff --git a/hw/pass-through.c b/hw/pass-through.c index 51d0a12..6b08441 100644 --- a/hw/pass-through.c +++ b/hw/pass-through.c @@ -2338,11 +2338,6 @@ static int pt_bar_reg_write(struct pt_dev *ptdev, return -1; } - /* always keep the emulate register value to 0, - * because hvmloader does not support high MMIO for now. - */ - cfg_entry->data = 0; - /* never mapping the 'empty' upper region, * because we'll do it enough for the lower region. */ diff --git a/hw/pass-through.c b/hw/pass-through.c index 51d0a12..9a521c3 100644 --- a/hw/pass-through.c +++ b/hw/pass-through.c @@ -55,6 +55,10 @@ static uint32_t pt_irqpin_reg_init(struct pt_dev *ptdev, struct pt_reg_info_tbl *reg, uint32_t real_offset); static uint32_t pt_bar_reg_init(struct pt_dev *ptdev, struct pt_reg_info_tbl *reg, uint32_t real_offset); +static uint32_t pt_linkctrl_reg_init(struct pt_dev *ptdev, + struct pt_reg_info_tbl *reg, uint32_t real_offset); +static uint32_t pt_devctrl2_reg_init(struct pt_dev *ptdev, + struct pt_reg_info_tbl *reg, uint32_t real_offset); static uint32_t pt_linkctrl2_reg_init(struct pt_dev *ptdev, struct pt_reg_info_tbl *reg, uint32_t real_offset); static uint32_t pt_msgctrl_reg_init(struct pt_dev *ptdev, @@ -75,6 +79,8 @@ static uint8_t pt_msix_size_init(struct pt_dev *ptdev, struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset); static uint8_t pt_vendor_size_init(struct pt_dev *ptdev, struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset); +static uint8_t pt_pcie_size_init(struct pt_dev *ptdev, + struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset); static int pt_byte_reg_read(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, uint8_t *valueu, uint8_t valid_mask); @@ -436,7 +442,7 @@ static struct pt_reg_info_tbl pt_emu_reg_pcie_tbl[] = { .init_val = 0x0000, .ro_mask = 0x0000, .emu_mask = 0xFFFF, - .init = pt_common_reg_init, + .init = pt_linkctrl_reg_init, .u.w.read = pt_word_reg_read, .u.w.write = pt_linkctrl_reg_write, }, @@ -447,7 +453,7 @@ static struct pt_reg_info_tbl pt_emu_reg_pcie_tbl[] = { .init_val = 0x0000, .ro_mask = 0x0000, .emu_mask = 0xFFFF, - .init = pt_common_reg_init, + .init = pt_devctrl2_reg_init, .u.w.read = pt_word_reg_read, .u.w.write = pt_devctrl2_reg_write, }, @@ -664,8 +670,8 @@ static const struct pt_reg_grp_info_tbl pt_emu_reg_grp_tbl[] = { { .grp_id = PCI_CAP_ID_EXP, .grp_type = GRP_TYPE_EMU, - .grp_size = 0x3C, - .size_init = pt_reg_grp_size_init, + .grp_size = 0xFF, + .size_init = pt_pcie_size_init, .emu_reg_tbl= pt_emu_reg_pcie_tbl, }, /* MSI-X Capability Structure reg group */ @@ -1867,12 +1873,57 @@ static uint32_t pt_bar_reg_init(struct pt_dev *ptdev, return reg_field; } +/* initialize Link Control register */ +static uint32_t pt_linkctrl_reg_init(struct pt_dev *ptdev, + struct pt_reg_info_tbl *reg, uint32_t real_offset) +{ + uint8_t cap_ver = 0; + uint8_t dev_type = 0; + + cap_ver = (ptdev->dev.config[(real_offset - reg->offset) + PCI_EXP_FLAGS] & + (uint8_t)PCI_EXP_FLAGS_VERS); + dev_type = (ptdev->dev.config[(real_offset - reg->offset) + PCI_EXP_FLAGS] & + (uint8_t)PCI_EXP_FLAGS_TYPE) >> 4; + + /* no need to initialize in case of Root Complex Integrated Endpoint + * with cap_ver 1.x + */ + if ((dev_type == PCI_EXP_TYPE_ROOT_INT_EP) && (cap_ver == 1)) + return PT_INVALID_REG; + + return reg->init_val; +} + +/* initialize Device Control 2 register */ +static uint32_t pt_devctrl2_reg_init(struct pt_dev *ptdev, + struct pt_reg_info_tbl *reg, uint32_t real_offset) +{ + uint8_t cap_ver = 0; + + cap_ver = (ptdev->dev.config[(real_offset - reg->offset) + PCI_EXP_FLAGS] & + (uint8_t)PCI_EXP_FLAGS_VERS); + + /* no need to initialize in case of cap_ver 1.x */ + if (cap_ver == 1) + return PT_INVALID_REG; + + return reg->init_val; +} + /* initialize Link Control 2 register */ static uint32_t pt_linkctrl2_reg_init(struct pt_dev *ptdev, struct pt_reg_info_tbl *reg, uint32_t real_offset) { int reg_field = 0; + uint8_t cap_ver = 0; + cap_ver = (ptdev->dev.config[(real_offset - reg->offset) + PCI_EXP_FLAGS] & + (uint8_t)PCI_EXP_FLAGS_VERS); + + /* no need to initialize in case of cap_ver 1.x */ + if (cap_ver == 1) + return PT_INVALID_REG; + /* set Supported Link Speed */ reg_field |= (0x0F & @@ -2034,6 +2085,91 @@ static uint8_t pt_vendor_size_init(struct pt_dev *ptdev, return ptdev->dev.config[base_offset + 0x02]; } +/* get PCI Express Capability Structure register group size */ +static uint8_t pt_pcie_size_init(struct pt_dev *ptdev, + struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset) +{ + PCIDevice *d = &ptdev->dev; + uint16_t exp_flag = 0; + uint16_t type = 0; + uint16_t vers = 0; + uint8_t pcie_size = 0; + + exp_flag = *((uint16_t*)(d->config + (base_offset + PCI_EXP_FLAGS))); + type = (exp_flag & PCI_EXP_FLAGS_TYPE) >> 4; + vers = (exp_flag & PCI_EXP_FLAGS_VERS); + + /* calculate size depend on capability version and device/port type */ + /* in case of PCI Express Base Specification Rev 1.x */ + if (vers == 1) + { + /* The PCI Express Capabilities, Device Capabilities, and Device + * Status/Control registers are required for all PCI Express devices. + * The Link Capabilities and Link Status/Control are required for all + * Endpoints that are not Root Complex Integrated Endpoints. Endpoints + * are not required to implement registers other than those listed + * above and terminate the capability structure. + */ + switch (type) { + case PCI_EXP_TYPE_ENDPOINT: + case PCI_EXP_TYPE_LEG_END: + pcie_size = 0x14; + break; + case PCI_EXP_TYPE_ROOT_INT_EP: + /* has no link */ + pcie_size = 0x0C; + break; + /* only EndPoint passthrough is supported */ + case PCI_EXP_TYPE_ROOT_PORT: + case PCI_EXP_TYPE_UPSTREAM: + case PCI_EXP_TYPE_DOWNSTREAM: + case PCI_EXP_TYPE_PCI_BRIDGE: + case PCI_EXP_TYPE_PCIE_BRIDGE: + case PCI_EXP_TYPE_ROOT_EC: + default: + /* exit I/O emulator */ + PT_LOG("Internal error: Unsupported device/port type[%d]. " + "I/O emulator exit.\n", type); + exit(1); + } + } + /* in case of PCI Express Base Specification Rev 2.0 */ + else if (vers == 2) + { + switch (type) { + case PCI_EXP_TYPE_ENDPOINT: + case PCI_EXP_TYPE_LEG_END: + case PCI_EXP_TYPE_ROOT_INT_EP: + /* For Functions that do not implement the registers, + * these spaces must be hardwired to 0b. + */ + pcie_size = 0x3C; + break; + /* only EndPoint passthrough is supported */ + case PCI_EXP_TYPE_ROOT_PORT: + case PCI_EXP_TYPE_UPSTREAM: + case PCI_EXP_TYPE_DOWNSTREAM: + case PCI_EXP_TYPE_PCI_BRIDGE: + case PCI_EXP_TYPE_PCIE_BRIDGE: + case PCI_EXP_TYPE_ROOT_EC: + default: + /* exit I/O emulator */ + PT_LOG("Internal error: Unsupported device/port type[%d]. " + "I/O emulator exit.\n", type); + exit(1); + } + } + else + { + /* exit I/O emulator */ + PT_LOG("Internal error: Unsupported capability version[%d]. " + "I/O emulator exit.\n", vers); + exit(1); + } + + return pcie_size; +} + /* read byte size emulate register */ static int pt_byte_reg_read(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, diff --git a/hw/pass-through.h b/hw/pass-through.h index 2175c93..bc3ef8c 100644 --- a/hw/pass-through.h +++ b/hw/pass-through.h @@ -64,6 +64,21 @@ #define PCI_MSI_FLAGS_MASK_BIT 0x0100 #endif +#ifndef PCI_EXP_TYPE_PCIE_BRIDGE +/* PCI/PCI-X to PCIE Bridge */ +#define PCI_EXP_TYPE_PCIE_BRIDGE 0x8 +#endif + +#ifndef PCI_EXP_TYPE_ROOT_INT_EP +/* Root Complex Integrated Endpoint */ +#define PCI_EXP_TYPE_ROOT_INT_EP 0x9 +#endif + +#ifndef PCI_EXP_TYPE_ROOT_EC +/* Root Complex Event Collector */ +#define PCI_EXP_TYPE_ROOT_EC 0xa +#endif + #define PT_INVALID_REG 0xFFFFFFFF /* invalid register value */ #define PT_BAR_ALLF 0xFFFFFFFF /* BAR ALLF value */ #define PT_BAR_MEM_RO_MASK 0x0000000F /* BAR ReadOnly mask(Memory) * _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |