@@ -60,6 +60,7 @@
#include "xen_pt.h"
#include "qemu/range.h"
#include "exec/address-spaces.h"
+#include "qapi/visitor.h"
#define XEN_PT_NR_IRQS (256)
static uint8_t xen_pt_mapped_machine_irq[XEN_PT_NR_IRQS] = {0};
@@ -829,3 +830,114 @@ static void xen_pci_passthrough_register_types(void)
}
type_init(xen_pci_passthrough_register_types)
+
+typedef struct {
+ uint16_t gpu_device_id;
+ uint16_t pch_device_id;
+} XenIGDDeviceIDInfo;
+
+/* In real world different GPU should have different PCH. But actually
+ * the different PCH DIDs likely map to different PCH SKUs. We do the
+ * same thing for the GPU. For PCH, the different SKUs are going to be
+ * all the same silicon design and implementation, just different
+ * features turn on and off with fuses. The SW interfaces should be
+ * consistent across all SKUs in a given family (eg LPT). But just same
+ * features may not be supported.
+ *
+ * Most of these different PCH features probably don't matter to the
+ * Gfx driver, but obviously any difference in display port connections
+ * will so it should be fine with any PCH in case of passthrough.
+ *
+ * So currently use one PCH version, 0x8c4e, to cover all HSW(Haswell)
+ * scenarios, 0x9cc3 for BDW(Broadwell).
+ */
+static const XenIGDDeviceIDInfo xen_igd_combo_id_infos[] = {
+ /* HSW Classic */
+ {0x0402, 0x8c4e}, /* HSWGT1D, HSWD_w7 */
+ {0x0406, 0x8c4e}, /* HSWGT1M, HSWM_w7 */
+ {0x0412, 0x8c4e}, /* HSWGT2D, HSWD_w7 */
+ {0x0416, 0x8c4e}, /* HSWGT2M, HSWM_w7 */
+ {0x041E, 0x8c4e}, /* HSWGT15D, HSWD_w7 */
+ /* HSW ULT */
+ {0x0A06, 0x8c4e}, /* HSWGT1UT, HSWM_w7 */
+ {0x0A16, 0x8c4e}, /* HSWGT2UT, HSWM_w7 */
+ {0x0A26, 0x8c4e}, /* HSWGT3UT, HSWM_w7 */
+ {0x0A2E, 0x8c4e}, /* HSWGT3UT28W, HSWM_w7 */
+ {0x0A1E, 0x8c4e}, /* HSWGT2UX, HSWM_w7 */
+ {0x0A0E, 0x8c4e}, /* HSWGT1ULX, HSWM_w7 */
+ /* HSW CRW */
+ {0x0D26, 0x8c4e}, /* HSWGT3CW, HSWM_w7 */
+ {0x0D22, 0x8c4e}, /* HSWGT3CWDT, HSWD_w7 */
+ /* HSW Server */
+ {0x041A, 0x8c4e}, /* HSWSVGT2, HSWD_w7 */
+ /* HSW SRVR */
+ {0x040A, 0x8c4e}, /* HSWSVGT1, HSWD_w7 */
+ /* BSW */
+ {0x1606, 0x9cc3}, /* BDWULTGT1, BDWM_w7 */
+ {0x1616, 0x9cc3}, /* BDWULTGT2, BDWM_w7 */
+ {0x1626, 0x9cc3}, /* BDWULTGT3, BDWM_w7 */
+ {0x160E, 0x9cc3}, /* BDWULXGT1, BDWM_w7 */
+ {0x161E, 0x9cc3}, /* BDWULXGT2, BDWM_w7 */
+ {0x1602, 0x9cc3}, /* BDWHALOGT1, BDWM_w7 */
+ {0x1612, 0x9cc3}, /* BDWHALOGT2, BDWM_w7 */
+ {0x1622, 0x9cc3}, /* BDWHALOGT3, BDWM_w7 */
+ {0x162B, 0x9cc3}, /* BDWHALO28W, BDWM_w7 */
+ {0x162A, 0x9cc3}, /* BDWGT3WRKS, BDWM_w7 */
+ {0x162D, 0x9cc3}, /* BDWGT3SRVR, BDWM_w7 */
+};
+
+static void xen_igd_passthrough_pciisabridge_get_pci_device_id(Object *obj,
+ Visitor *v,
+ void *opaque,
+ const char *name,
+ Error **errp)
+{
+ uint32_t gpu_id = 0xffff, pch_id = 0xffff;
+ XenHostPCIDevice hdev;
+ int r = 0, num;
+
+ r = xen_host_pci_device_get(&hdev, 0, 0, 0x02, 0);
+ if (!r) {
+ gpu_id = hdev.device_id;
+
+ num = ARRAY_SIZE(xen_igd_combo_id_infos);
+ for (r = 0; r < num; r++)
+ if (gpu_id == xen_igd_combo_id_infos[r].gpu_device_id)
+ pch_id = xen_igd_combo_id_infos[r].pch_device_id;
+ }
+
+ visit_type_uint32(v, &pch_id, name, errp);
+}
+
+static void xen_igd_passthrough_isa_bridge_initfn(Object *obj)
+{
+ object_property_add(obj, "device-id", "int",
+ xen_igd_passthrough_pciisabridge_get_pci_device_id,
+ NULL, NULL, NULL, NULL);
+}
+
+static void xen_igd_passthrough_isa_bridge_class_init(ObjectClass *klass,
+ void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+ dc->desc = "XEN IGD PASSTHROUGH ISA bridge";
+ k->class_id = PCI_CLASS_BRIDGE_ISA;
+ k->vendor_id = PCI_VENDOR_ID_INTEL;
+};
+
+static TypeInfo xen_igd_passthrough_isa_bridge_info = {
+ .name = "xen-igd-passthrough-isa-bridge",
+ .parent = TYPE_PCI_DEVICE,
+ .instance_size = sizeof(PCIDevice),
+ .instance_init = xen_igd_passthrough_isa_bridge_initfn,
+ .class_init = xen_igd_passthrough_isa_bridge_class_init,
+};
+
+static void xen_igd_passthrough_isa_bridge_register_types(void)
+{
+ type_register_static(&xen_igd_passthrough_isa_bridge_info);
+}
+
+type_init(xen_igd_passthrough_isa_bridge_register_types);
We need this instance to passthrough some config fields of PCH. Signed-off-by: Tiejun Chen <tiejun.chen@intel.com> --- hw/xen/xen_pt.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+)