Jagannathan Raman | 6fbd84d | 2021-01-29 11:46:06 -0500 | [diff] [blame] | 1 | /* |
| 2 | * Remote PCI host device |
| 3 | * |
| 4 | * Unlike PCI host devices that model physical hardware, the purpose |
| 5 | * of this PCI host is to host multi-process QEMU devices. |
| 6 | * |
| 7 | * Multi-process QEMU extends the PCI host of a QEMU machine into a |
| 8 | * remote process. Any PCI device attached to the remote process is |
| 9 | * visible in the QEMU guest. This allows existing QEMU device models |
| 10 | * to be reused in the remote process. |
| 11 | * |
| 12 | * This PCI host is purely a container for PCI devices. It's fake in the |
| 13 | * sense that the guest never sees this PCI host and has no way of |
| 14 | * accessing it. Its job is just to provide the environment that QEMU |
| 15 | * PCI device models need when running in a remote process. |
| 16 | * |
| 17 | * Copyright © 2018, 2021 Oracle and/or its affiliates. |
| 18 | * |
| 19 | * This work is licensed under the terms of the GNU GPL, version 2 or later. |
| 20 | * See the COPYING file in the top-level directory. |
| 21 | * |
| 22 | */ |
| 23 | |
| 24 | #include "qemu/osdep.h" |
Jagannathan Raman | 6fbd84d | 2021-01-29 11:46:06 -0500 | [diff] [blame] | 25 | |
| 26 | #include "hw/pci/pci.h" |
| 27 | #include "hw/pci/pci_host.h" |
| 28 | #include "hw/pci/pcie_host.h" |
| 29 | #include "hw/qdev-properties.h" |
| 30 | #include "hw/pci-host/remote.h" |
| 31 | #include "exec/memory.h" |
| 32 | |
| 33 | static const char *remote_pcihost_root_bus_path(PCIHostState *host_bridge, |
| 34 | PCIBus *rootbus) |
| 35 | { |
| 36 | return "0000:00"; |
| 37 | } |
| 38 | |
| 39 | static void remote_pcihost_realize(DeviceState *dev, Error **errp) |
| 40 | { |
| 41 | PCIHostState *pci = PCI_HOST_BRIDGE(dev); |
| 42 | RemotePCIHost *s = REMOTE_PCIHOST(dev); |
| 43 | |
| 44 | pci->bus = pci_root_bus_new(DEVICE(s), "remote-pci", |
| 45 | s->mr_pci_mem, s->mr_sys_io, |
| 46 | 0, TYPE_PCIE_BUS); |
| 47 | } |
| 48 | |
| 49 | static void remote_pcihost_class_init(ObjectClass *klass, void *data) |
| 50 | { |
| 51 | DeviceClass *dc = DEVICE_CLASS(klass); |
| 52 | PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass); |
| 53 | |
| 54 | hc->root_bus_path = remote_pcihost_root_bus_path; |
| 55 | dc->realize = remote_pcihost_realize; |
| 56 | |
| 57 | dc->user_creatable = false; |
| 58 | set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); |
| 59 | dc->fw_name = "pci"; |
| 60 | } |
| 61 | |
| 62 | static const TypeInfo remote_pcihost_info = { |
| 63 | .name = TYPE_REMOTE_PCIHOST, |
| 64 | .parent = TYPE_PCIE_HOST_BRIDGE, |
| 65 | .instance_size = sizeof(RemotePCIHost), |
| 66 | .class_init = remote_pcihost_class_init, |
| 67 | }; |
| 68 | |
| 69 | static void remote_pcihost_register(void) |
| 70 | { |
| 71 | type_register_static(&remote_pcihost_info); |
| 72 | } |
| 73 | |
| 74 | type_init(remote_pcihost_register) |