Yuji Shimada
2008-Sep-03 08:24 UTC
[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@necst.nec.co.jp> 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@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2008-Sep-03 09:41 UTC
[Xen-devel] Re: [PATCH] ioemu-remote&ioemu: support PCI Express Capability Structure version 1.
On 3/9/08 09:24, "Yuji Shimada" <shimada-yxb@necst.nec.co.jp> wrote:> This patch adds supporting PCI Express Capability Structure version 1 > to ioemu-remote and ioemu.Doesn''t apply to ioemu. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Jackson
2008-Sep-03 10:27 UTC
Re: [Xen-devel] [PATCH] ioemu-remote&ioemu: support PCI Express Capability Structure version 1.
Yuji Shimada writes ("[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.I have applied this. But I did notice that ...> diff --git a/hw/pass-through.c b/hw/pass-through.c > diff --git a/hw/pass-through.c b/hw/pass-through.c... there are two separate patches for the same file here. I don''t know how you created that patch but this is a bad idea. patch(1) deals badly with such input and it makes it easy to accidentally drop hunks if the person applying the patch has to fix up minor conflicts. As it happens the first of those two patches was already in my tree but not yet pushed (sorry) so no harm done. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Yuji Shimada
2008-Sep-04 00:40 UTC
Re: [Xen-devel] [PATCH] ioemu-remote&ioemu: support PCI Express Capability Structure version 1.
Sorry for including unnecessary part. I resend the patch. Signed-off-by: Yuji Shimada <shimada-yxb@necst.nec.co.jp> 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@lists.xensource.com http://lists.xensource.com/xen-devel