From: Dmitry R <rdmitry0911@gmail.com>
To: qemu-devel@nongnu.org
Cc: Dmitry R <rdmitry0911@gmail.com>,
"Michael S . Tsirkin" <mst@redhat.com>,
Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>,
Fabiano Rosas <farosas@suse.de>,
Laurent Vivier <lvivier@redhat.com>,
Paolo Bonzini <pbonzini@redhat.com>
Subject: [RFC PATCH v2 1/5] hw/pci-bridge: add Thunderbolt root port
Date: Sat, 11 Jul 2026 12:47:57 +0300 [thread overview]
Message-ID: <20260711094803.3589239-2-rdmitry0911@gmail.com> (raw)
In-Reply-To: <20260711094803.3589239-1-rdmitry0911@gmail.com>
Add thunderbolt-root-port and its secondary thunderbolt-bus type. This is
the core Thunderbolt PCIe modelling piece. Devices behind the root port
remain normal QEMU PCI devices, while the root port controls
guest-visible link presence and hotplug signalling.
The connected QOM property allows the whole Thunderbolt port to be
disconnected or reconnected without changing endpoint device
implementations.
Signed-off-by: Dmitry R <rdmitry0911@gmail.com>
---
hw/pci-bridge/meson.build | 1 +
hw/pci-bridge/thunderbolt_root_port.c | 565 ++++++++++++++++++++++++++
2 files changed, 566 insertions(+)
create mode 100644 hw/pci-bridge/thunderbolt_root_port.c
diff --git a/hw/pci-bridge/meson.build b/hw/pci-bridge/meson.build
index 2e0eb0d233..fd0698fb33 100644
--- a/hw/pci-bridge/meson.build
+++ b/hw/pci-bridge/meson.build
@@ -3,6 +3,7 @@ pci_ss.add(when: 'CONFIG_PCI_BRIDGE', if_true: files('pci_bridge_dev.c'))
pci_ss.add(when: 'CONFIG_I82801B11', if_true: files('i82801b11.c'))
pci_ss.add(when: 'CONFIG_IOH3420', if_true: files('ioh3420.c'))
pci_ss.add(when: 'CONFIG_PCIE_PORT', if_true: files('pcie_root_port.c', 'gen_pcie_root_port.c'))
+pci_ss.add(when: 'CONFIG_PCIE_PORT', if_true: files('thunderbolt_root_port.c'))
pci_ss.add(when: 'CONFIG_PCIE_PCI_BRIDGE', if_true: files('pcie_pci_bridge.c'))
pci_ss.add(when: 'CONFIG_PXB', if_true: files('pci_expander_bridge.c'),
if_false: files('pci_expander_bridge_stubs.c'))
diff --git a/hw/pci-bridge/thunderbolt_root_port.c b/hw/pci-bridge/thunderbolt_root_port.c
new file mode 100644
index 0000000000..625a5dba7e
--- /dev/null
+++ b/hw/pci-bridge/thunderbolt_root_port.c
@@ -0,0 +1,565 @@
+/*
+ * Thunderbolt PCI Express Root Port
+ *
+ * This root port creates a Thunderbolt-flavoured PCIe bus. Devices on that
+ * bus remain regular QEMU PCI devices; the Thunderbolt layer controls their
+ * guest-visible connection state.
+ *
+ * Copyright (C) 2026
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "hw/acpi/aml-build.h"
+#include "hw/acpi/pci.h"
+#include "hw/acpi/acpi_aml_interface.h"
+#include "hw/core/hotplug.h"
+#include "hw/core/qdev-properties.h"
+#include "hw/core/qdev-properties-system.h"
+#include "hw/pci/msix.h"
+#include "hw/pci/pci_bridge.h"
+#include "hw/pci/pcie_port.h"
+#include "migration/vmstate.h"
+#include "system/system.h"
+#include "qom/object.h"
+
+#define TYPE_THUNDERBOLT_ROOT_PORT "thunderbolt-root-port"
+#define TYPE_THUNDERBOLT_BUS "thunderbolt-bus"
+
+OBJECT_DECLARE_SIMPLE_TYPE(ThunderboltRootPort, THUNDERBOLT_ROOT_PORT)
+
+#define THUNDERBOLT_ROOT_PORT_AER_OFFSET 0x100
+#define THUNDERBOLT_ROOT_PORT_ACS_OFFSET \
+ (THUNDERBOLT_ROOT_PORT_AER_OFFSET + PCI_ERR_SIZEOF)
+#define THUNDERBOLT_ROOT_PORT_MSIX_NR_VECTOR 1
+#define THUNDERBOLT_ROOT_DEFAULT_IO_RANGE 4096
+
+struct ThunderboltRootPort {
+ PCIESlot parent_obj;
+
+ bool migrate_msix;
+ PCIResReserve res_reserve;
+ bool connected;
+ DeviceListener listener;
+ Notifier machine_done;
+};
+
+static void thunderbolt_root_port_set_presence(PCIDevice *dev, bool present,
+ bool notify);
+static void thunderbolt_root_port_sync_connected(ThunderboltRootPort *trp,
+ bool notify);
+
+static Aml *build_device_properties_dsd(Aml *properties)
+{
+ Aml *dsd;
+
+ dsd = aml_package(2);
+ aml_append(dsd, aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301"));
+ aml_append(dsd, properties);
+
+ return aml_name_decl("_DSD", dsd);
+}
+
+static void append_bool_property(Aml *properties, const char *name)
+{
+ Aml *property = aml_package(2);
+
+ aml_append(property, aml_string("%s", name));
+ aml_append(property, aml_int(1));
+ aml_append(properties, property);
+}
+
+static void build_thunderbolt_root_port_dsd(Aml *scope)
+{
+ Aml *properties;
+
+ properties = aml_package(2);
+ append_bool_property(properties, "PCI-Thunderbolt");
+ append_bool_property(properties, "pci-supports-link-change");
+
+ aml_append(scope, build_device_properties_dsd(properties));
+}
+
+static void build_thunderbolt_root_port_aml(AcpiDevAmlIf *adev, Aml *scope)
+{
+ build_thunderbolt_root_port_dsd(scope);
+ build_pci_bridge_aml(adev, scope);
+}
+
+static bool thunderbolt_root_port_get_connected(Object *obj, Error **errp)
+{
+ return THUNDERBOLT_ROOT_PORT(obj)->connected;
+}
+
+static void thunderbolt_root_port_set_connected(Object *obj, bool value,
+ Error **errp)
+{
+ ThunderboltRootPort *trp = THUNDERBOLT_ROOT_PORT(obj);
+
+ if (trp->connected == value) {
+ return;
+ }
+
+ trp->connected = value;
+
+ if (!qdev_is_realized(DEVICE(obj))) {
+ return;
+ }
+
+ thunderbolt_root_port_sync_connected(trp, true);
+}
+
+static void thunderbolt_root_port_sync_connected(ThunderboltRootPort *trp,
+ bool notify)
+{
+ PCIDevice *rp = PCI_DEVICE(trp);
+ PCIBus *bus = pci_bridge_get_sec_bus(PCI_BRIDGE(rp));
+ bool present = false;
+ int devfn;
+
+ for (devfn = 0; devfn < PCI_DEVFN_MAX; devfn++) {
+ PCIDevice *child = bus->devices[devfn];
+
+ if (!child) {
+ continue;
+ }
+
+ present = true;
+ if (trp->connected) {
+ pci_set_enabled(child, true);
+ }
+ }
+
+ if (trp->connected && present) {
+ thunderbolt_root_port_set_presence(rp, true, notify);
+ } else {
+ thunderbolt_root_port_set_presence(rp, false, notify);
+ for (devfn = 0; devfn < PCI_DEVFN_MAX; devfn++) {
+ PCIDevice *child = bus->devices[devfn];
+
+ if (child) {
+ pci_set_enabled(child, false);
+ }
+ }
+ }
+}
+
+static void thunderbolt_root_port_machine_done(Notifier *notifier, void *data)
+{
+ ThunderboltRootPort *trp = container_of(notifier, ThunderboltRootPort,
+ machine_done);
+
+ thunderbolt_root_port_sync_connected(trp, false);
+}
+
+static void thunderbolt_root_port_device_realize(DeviceListener *listener,
+ DeviceState *dev)
+{
+ ThunderboltRootPort *trp = container_of(listener, ThunderboltRootPort,
+ listener);
+ PCIBus *bus;
+
+ if (!dev->parent_bus ||
+ !object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE) ||
+ !object_dynamic_cast(OBJECT(dev->parent_bus), TYPE_THUNDERBOLT_BUS)) {
+ return;
+ }
+
+ bus = PCI_BUS(dev->parent_bus);
+ if (bus->parent_dev != PCI_DEVICE(trp)) {
+ return;
+ }
+
+ thunderbolt_root_port_sync_connected(trp, false);
+}
+
+static void thunderbolt_root_port_instance_init(Object *obj)
+{
+ ThunderboltRootPort *trp = THUNDERBOLT_ROOT_PORT(obj);
+
+ trp->connected = true;
+ object_property_add_bool(obj, "connected",
+ thunderbolt_root_port_get_connected,
+ thunderbolt_root_port_set_connected);
+}
+
+static void thunderbolt_root_port_set_presence(PCIDevice *dev, bool present,
+ bool notify)
+{
+ uint8_t *exp_cap = dev->config + dev->exp.exp_cap;
+ uint32_t lnkcap = pci_get_long(exp_cap + PCI_EXP_LNKCAP);
+
+ if (present) {
+ pcie_cap_slot_enable_power(dev);
+ pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
+ PCI_EXP_SLTSTA_PDS);
+ if (dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA ||
+ (lnkcap & PCI_EXP_LNKCAP_DLLLARC)) {
+ pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA,
+ PCI_EXP_LNKSTA_DLLLA);
+ }
+ } else {
+ pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTSTA,
+ PCI_EXP_SLTSTA_PDS);
+ if (dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA ||
+ (lnkcap & PCI_EXP_LNKCAP_DLLLARC)) {
+ pci_word_test_and_clear_mask(exp_cap + PCI_EXP_LNKSTA,
+ PCI_EXP_LNKSTA_DLLLA);
+ }
+ }
+
+ if (notify) {
+ pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
+ PCI_EXP_SLTSTA_PDC);
+ pcie_cap_slot_push_attention_button(dev);
+ }
+}
+
+static void thunderbolt_root_port_pre_plug(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ pcie_cap_slot_pre_plug_cb(hotplug_dev, dev, errp);
+}
+
+static void thunderbolt_root_port_plug(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ ThunderboltRootPort *trp = THUNDERBOLT_ROOT_PORT(hotplug_dev);
+
+ if (trp->connected) {
+ pcie_cap_slot_plug_cb(hotplug_dev, dev, errp);
+ return;
+ }
+
+ pci_set_enabled(PCI_DEVICE(dev), false);
+ thunderbolt_root_port_set_presence(PCI_DEVICE(hotplug_dev), false, false);
+}
+
+static void thunderbolt_root_port_unplug_request(HotplugHandler *hotplug_dev,
+ DeviceState *dev,
+ Error **errp)
+{
+ pcie_cap_slot_unplug_request_cb(hotplug_dev, dev, errp);
+}
+
+static void thunderbolt_root_port_unplug(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ pcie_cap_slot_unplug_cb(hotplug_dev, dev, errp);
+}
+
+static uint8_t thunderbolt_root_port_aer_vector(const PCIDevice *dev)
+{
+ return 0;
+}
+
+static void thunderbolt_root_port_aer_vector_update(PCIDevice *dev)
+{
+ PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
+
+ if (rpc->aer_vector) {
+ pcie_aer_root_set_vector(dev, rpc->aer_vector(dev));
+ }
+}
+
+static int thunderbolt_root_port_interrupts_init(PCIDevice *dev, Error **errp)
+{
+ int rc;
+
+ rc = msix_init_exclusive_bar(dev, THUNDERBOLT_ROOT_PORT_MSIX_NR_VECTOR,
+ 0, errp);
+ if (rc < 0) {
+ assert(rc == -ENOTSUP);
+ } else {
+ msix_vector_use(dev, 0);
+ }
+
+ return rc;
+}
+
+static void thunderbolt_root_port_interrupts_uninit(PCIDevice *dev)
+{
+ msix_uninit_exclusive_bar(dev);
+}
+
+static void thunderbolt_root_port_write_config(PCIDevice *dev,
+ uint32_t address,
+ uint32_t val, int len)
+{
+ uint32_t root_cmd =
+ pci_get_long(dev->config + dev->exp.aer_cap + PCI_ERR_ROOT_COMMAND);
+ uint16_t slt_ctl;
+ uint16_t slt_sta;
+
+ pcie_cap_slot_get(dev, &slt_ctl, &slt_sta);
+
+ pci_bridge_write_config(dev, address, val, len);
+ thunderbolt_root_port_aer_vector_update(dev);
+ pcie_cap_slot_write_config(dev, slt_ctl, slt_sta, address, val, len);
+ pcie_aer_write_config(dev, address, val, len);
+ pcie_aer_root_write_config(dev, address, val, len, root_cmd);
+}
+
+static void thunderbolt_root_port_reset_hold(Object *obj, ResetType type)
+{
+ ThunderboltRootPort *trp = THUNDERBOLT_ROOT_PORT(obj);
+ PCIDevice *dev = PCI_DEVICE(obj);
+ DeviceState *qdev = DEVICE(obj);
+
+ thunderbolt_root_port_aer_vector_update(dev);
+ pcie_cap_root_reset(dev);
+ pcie_cap_deverr_reset(dev);
+ pcie_cap_slot_reset(dev);
+ pcie_cap_arifwd_reset(dev);
+ pcie_acs_reset(dev);
+ pcie_aer_root_reset(dev);
+ pci_bridge_reset(qdev);
+ pci_bridge_disable_base_limit(dev);
+ thunderbolt_root_port_sync_connected(trp, false);
+}
+
+static void thunderbolt_root_port_realize_pci(PCIDevice *dev, Error **errp)
+{
+ PCIEPort *p = PCIE_PORT(dev);
+ PCIESlot *s = PCIE_SLOT(dev);
+ PCIDeviceClass *dc = PCI_DEVICE_GET_CLASS(dev);
+ PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
+ int rc;
+
+ pci_config_set_interrupt_pin(dev->config, 1);
+ pci_bridge_initfn(dev, TYPE_THUNDERBOLT_BUS);
+ pcie_port_init_reg(dev);
+
+ rc = pci_bridge_ssvid_init(dev, rpc->ssvid_offset, dc->vendor_id,
+ rpc->ssid, errp);
+ if (rc < 0) {
+ error_append_hint(errp, "Can't init SSV ID, error %d\n", rc);
+ goto err_bridge;
+ }
+
+ if (rpc->interrupts_init) {
+ rc = rpc->interrupts_init(dev, errp);
+ if (rc < 0) {
+ goto err_bridge;
+ }
+ }
+
+ rc = pcie_cap_init(dev, rpc->exp_offset, PCI_EXP_TYPE_ROOT_PORT,
+ p->port, errp);
+ if (rc < 0) {
+ error_append_hint(errp, "Can't add Root Port capability, "
+ "error %d\n", rc);
+ goto err_int;
+ }
+
+ pcie_cap_arifwd_init(dev);
+ pcie_cap_deverr_init(dev);
+ pcie_cap_slot_init(dev, s);
+ qbus_set_hotplug_handler(BUS(pci_bridge_get_sec_bus(PCI_BRIDGE(dev))),
+ OBJECT(dev));
+ pcie_cap_root_init(dev);
+
+ pcie_chassis_create(s->chassis);
+ rc = pcie_chassis_add_slot(s);
+ if (rc < 0) {
+ error_setg(errp, "Can't add chassis slot, error %d", rc);
+ goto err_pcie_cap;
+ }
+
+ rc = pcie_aer_init(dev, PCI_ERR_VER, rpc->aer_offset,
+ PCI_ERR_SIZEOF, errp);
+ if (rc < 0) {
+ goto err;
+ }
+ pcie_aer_root_init(dev);
+ thunderbolt_root_port_aer_vector_update(dev);
+
+ if (rpc->acs_offset) {
+ pcie_acs_init(dev, rpc->acs_offset);
+ }
+
+ THUNDERBOLT_ROOT_PORT(dev)->listener.realize =
+ thunderbolt_root_port_device_realize;
+ device_listener_register(&THUNDERBOLT_ROOT_PORT(dev)->listener);
+
+ THUNDERBOLT_ROOT_PORT(dev)->machine_done.notify =
+ thunderbolt_root_port_machine_done;
+ qemu_add_machine_init_done_notifier(
+ &THUNDERBOLT_ROOT_PORT(dev)->machine_done);
+
+ return;
+
+err:
+ pcie_chassis_del_slot(s);
+err_pcie_cap:
+ pcie_cap_exit(dev);
+err_int:
+ if (rpc->interrupts_uninit) {
+ rpc->interrupts_uninit(dev);
+ }
+err_bridge:
+ pci_bridge_exitfn(dev);
+}
+
+static void thunderbolt_root_port_exit(PCIDevice *dev)
+{
+ PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
+ PCIESlot *s = PCIE_SLOT(dev);
+
+ pcie_aer_exit(dev);
+ pcie_chassis_del_slot(s);
+ pcie_cap_exit(dev);
+ if (rpc->interrupts_uninit) {
+ rpc->interrupts_uninit(dev);
+ }
+ device_listener_unregister(&THUNDERBOLT_ROOT_PORT(dev)->listener);
+ qemu_remove_machine_init_done_notifier(
+ &THUNDERBOLT_ROOT_PORT(dev)->machine_done);
+ pci_bridge_exitfn(dev);
+}
+
+static void thunderbolt_root_port_realize(DeviceState *dev, Error **errp)
+{
+ ThunderboltRootPort *trp = THUNDERBOLT_ROOT_PORT(dev);
+ PCIESlot *slot = PCIE_SLOT(dev);
+ PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
+ Error *local_err = NULL;
+ int rc;
+
+ rpc->parent_realize(dev, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ if (slot->hide_native_hotplug_cap &&
+ trp->res_reserve.io == (uint64_t)-1 && slot->hotplug) {
+ trp->res_reserve.io = THUNDERBOLT_ROOT_DEFAULT_IO_RANGE;
+ }
+
+ rc = pci_bridge_qemu_reserve_cap_init(PCI_DEVICE(dev), 0,
+ trp->res_reserve, errp);
+ if (rc < 0) {
+ rpc->parent_class.exit(PCI_DEVICE(dev));
+ return;
+ }
+
+ if (!trp->res_reserve.io) {
+ PCIDevice *pdev = PCI_DEVICE(dev);
+
+ pci_word_test_and_clear_mask(pdev->wmask + PCI_COMMAND,
+ PCI_COMMAND_IO);
+ pdev->wmask[PCI_IO_BASE] = 0;
+ pdev->wmask[PCI_IO_LIMIT] = 0;
+ }
+}
+
+static bool thunderbolt_root_port_test_migrate_msix(void *opaque,
+ int version_id)
+{
+ ThunderboltRootPort *trp = opaque;
+
+ return trp->migrate_msix;
+}
+
+static const VMStateDescription vmstate_thunderbolt_root_port = {
+ .name = "thunderbolt-root-port",
+ .priority = MIG_PRI_PCI_BUS,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .post_load = pcie_cap_slot_post_load,
+ .fields = (const VMStateField[]) {
+ VMSTATE_PCI_DEVICE(parent_obj.parent_obj.parent_obj.parent_obj,
+ ThunderboltRootPort),
+ VMSTATE_STRUCT(parent_obj.parent_obj.parent_obj.parent_obj.exp.aer_log,
+ ThunderboltRootPort, 0, vmstate_pcie_aer_log,
+ PCIEAERLog),
+ VMSTATE_MSIX_TEST(parent_obj.parent_obj.parent_obj.parent_obj,
+ ThunderboltRootPort,
+ thunderbolt_root_port_test_migrate_msix),
+ VMSTATE_BOOL(connected, ThunderboltRootPort),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const Property thunderbolt_root_port_props[] = {
+ DEFINE_PROP_BOOL("x-migrate-msix", ThunderboltRootPort,
+ migrate_msix, true),
+ DEFINE_PROP_UINT32("bus-reserve", ThunderboltRootPort,
+ res_reserve.bus, -1),
+ DEFINE_PROP_SIZE("io-reserve", ThunderboltRootPort,
+ res_reserve.io, -1),
+ DEFINE_PROP_SIZE("mem-reserve", ThunderboltRootPort,
+ res_reserve.mem_non_pref, -1),
+ DEFINE_PROP_SIZE("pref32-reserve", ThunderboltRootPort,
+ res_reserve.mem_pref_32, -1),
+ DEFINE_PROP_SIZE("pref64-reserve", ThunderboltRootPort,
+ res_reserve.mem_pref_64, -1),
+ DEFINE_PROP_PCIE_LINK_SPEED("x-speed", PCIESlot,
+ speed, PCIE_LINK_SPEED_16),
+ DEFINE_PROP_PCIE_LINK_WIDTH("x-width", PCIESlot,
+ width, PCIE_LINK_WIDTH_32),
+};
+
+static void thunderbolt_root_port_class_init(ObjectClass *klass,
+ const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+ PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass);
+ AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
+
+ k->vendor_id = PCI_VENDOR_ID_REDHAT;
+ k->device_id = PCI_DEVICE_ID_REDHAT_PCIE_RP;
+ k->config_write = thunderbolt_root_port_write_config;
+ k->realize = thunderbolt_root_port_realize_pci;
+ k->exit = thunderbolt_root_port_exit;
+ dc->desc = "Thunderbolt PCI Express Root Port";
+ dc->vmsd = &vmstate_thunderbolt_root_port;
+ device_class_set_props(dc, thunderbolt_root_port_props);
+ device_class_set_parent_realize(dc, thunderbolt_root_port_realize,
+ &rpc->parent_realize);
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+ rc->phases.hold = thunderbolt_root_port_reset_hold;
+
+ hc->pre_plug = thunderbolt_root_port_pre_plug;
+ hc->plug = thunderbolt_root_port_plug;
+ hc->unplug = thunderbolt_root_port_unplug;
+ hc->unplug_request = thunderbolt_root_port_unplug_request;
+
+ rpc->aer_vector = thunderbolt_root_port_aer_vector;
+ rpc->interrupts_init = thunderbolt_root_port_interrupts_init;
+ rpc->interrupts_uninit = thunderbolt_root_port_interrupts_uninit;
+ rpc->aer_offset = THUNDERBOLT_ROOT_PORT_AER_OFFSET;
+ rpc->acs_offset = THUNDERBOLT_ROOT_PORT_ACS_OFFSET;
+ adevc->build_dev_aml = build_thunderbolt_root_port_aml;
+}
+
+static const TypeInfo thunderbolt_root_port_info = {
+ .name = TYPE_THUNDERBOLT_ROOT_PORT,
+ .parent = TYPE_PCIE_ROOT_PORT,
+ .instance_size = sizeof(ThunderboltRootPort),
+ .instance_init = thunderbolt_root_port_instance_init,
+ .class_init = thunderbolt_root_port_class_init,
+ .interfaces = (const InterfaceInfo[]) {
+ { TYPE_ACPI_DEV_AML_IF },
+ { },
+ },
+};
+
+static const TypeInfo thunderbolt_bus_info = {
+ .name = TYPE_THUNDERBOLT_BUS,
+ .parent = TYPE_PCIE_BUS,
+};
+
+static void thunderbolt_root_port_register_types(void)
+{
+ type_register_static(&thunderbolt_bus_info);
+ type_register_static(&thunderbolt_root_port_info);
+}
+
+type_init(thunderbolt_root_port_register_types)
--
2.47.3
next prev parent reply other threads:[~2026-07-11 9:49 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 13:34 [RFC PATCH v1 0/1] Thunderbolt PCIe hotplug layer Dmitry R
2026-07-10 13:34 ` [RFC PATCH v1 1/1] hw/pci-bridge: add " Dmitry R
2026-07-11 9:17 ` [RFC PATCH v1 0/1] " Michael S. Tsirkin
2026-07-11 9:47 ` [RFC PATCH v2 0/5] " Dmitry R
2026-07-11 9:47 ` Dmitry R [this message]
2026-07-11 9:47 ` [RFC PATCH v2 2/5] hw/pci-bridge: add Thunderbolt PCIe-to-PCI bridge Dmitry R
2026-07-11 9:47 ` [RFC PATCH v2 3/5] hw/display: add Thunderbolt VGA endpoint Dmitry R
2026-07-11 9:48 ` [RFC PATCH v2 4/5] tests/qtest: cover Thunderbolt VGA hotplug Dmitry R
2026-07-11 9:48 ` [RFC PATCH v2 5/5] docs: document Thunderbolt PCIe hotplug layer Dmitry R
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260711094803.3589239-2-rdmitry0911@gmail.com \
--to=rdmitry0911@gmail.com \
--cc=farosas@suse.de \
--cc=lvivier@redhat.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.