| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | #ifndef QEMU_PCI_H
 | 
					
						
							|  |  |  | #define QEMU_PCI_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-17 18:19:49 +01:00
										 |  |  | #include "exec/memory.h"
 | 
					
						
							| 
									
										
										
										
											2012-12-17 18:20:04 +01:00
										 |  |  | #include "sysemu/dma.h"
 | 
					
						
							| 
									
										
										
										
											2024-06-05 16:30:39 +08:00
										 |  |  | #include "sysemu/host_iommu_device.h"
 | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | /* PCI includes legacy ISA access.  */ | 
					
						
							| 
									
										
										
										
											2013-02-05 17:06:20 +01:00
										 |  |  | #include "hw/isa/isa.h"
 | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-07 11:45:26 +02:00
										 |  |  | extern bool pci_available; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | /* PCI bus */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 15:19:46 +00:00
										 |  |  | #define PCI_DEVFN(slot, func)   ((((slot) & 0x1f) << 3) | ((func) & 0x07))
 | 
					
						
							| 
									
										
										
										
											2016-09-20 18:42:31 +03:00
										 |  |  | #define PCI_BUS_NUM(x)          (((x) >> 8) & 0xff)
 | 
					
						
							| 
									
										
										
										
											2009-02-11 15:19:46 +00:00
										 |  |  | #define PCI_SLOT(devfn)         (((devfn) >> 3) & 0x1f)
 | 
					
						
							|  |  |  | #define PCI_FUNC(devfn)         ((devfn) & 0x07)
 | 
					
						
							| 
									
										
										
										
											2016-05-17 19:26:10 +08:00
										 |  |  | #define PCI_BUILD_BDF(bus, devfn)     ((bus << 8) | (devfn))
 | 
					
						
							| 
									
										
										
										
											2022-06-13 16:26:33 -04:00
										 |  |  | #define PCI_BDF_TO_DEVFN(x)     ((x) & 0xff)
 | 
					
						
							| 
									
										
										
										
											2016-09-20 18:42:31 +03:00
										 |  |  | #define PCI_BUS_MAX             256
 | 
					
						
							|  |  |  | #define PCI_DEVFN_MAX           256
 | 
					
						
							| 
									
										
										
										
											2011-01-27 15:56:35 +09:00
										 |  |  | #define PCI_SLOT_MAX            32
 | 
					
						
							| 
									
										
										
										
											2010-06-23 16:15:26 +09:00
										 |  |  | #define PCI_FUNC_MAX            8
 | 
					
						
							| 
									
										
										
										
											2009-02-11 15:19:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 15:02:23 +00:00
										 |  |  | /* Class, Vendor and Device IDs from Linux's pci_ids.h */ | 
					
						
							| 
									
										
										
										
											2012-12-12 23:05:42 +02:00
										 |  |  | #include "hw/pci/pci_ids.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-01 19:26:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 15:02:23 +00:00
										 |  |  | /* QEMU-specific Vendor and Device ID definitions */ | 
					
						
							| 
									
										
										
										
											2009-02-11 15:21:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 15:02:23 +00:00
										 |  |  | /* IBM (0x1014) */ | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_IBM_440GX          0x027f
 | 
					
						
							| 
									
										
										
										
											2009-02-01 12:01:04 +00:00
										 |  |  | #define PCI_DEVICE_ID_IBM_OPENPIC2       0xffff
 | 
					
						
							| 
									
										
										
										
											2009-01-26 15:37:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 15:02:23 +00:00
										 |  |  | /* Hitachi (0x1054) */ | 
					
						
							| 
									
										
										
										
											2009-01-26 15:37:35 +00:00
										 |  |  | #define PCI_VENDOR_ID_HITACHI            0x1054
 | 
					
						
							| 
									
										
										
										
											2009-03-13 15:02:23 +00:00
										 |  |  | #define PCI_DEVICE_ID_HITACHI_SH7751R    0x350e
 | 
					
						
							| 
									
										
										
										
											2009-01-26 15:37:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 15:02:23 +00:00
										 |  |  | /* Apple (0x106b) */ | 
					
						
							| 
									
										
										
										
											2009-02-01 12:01:04 +00:00
										 |  |  | #define PCI_DEVICE_ID_APPLE_343S1201     0x0010
 | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_APPLE_UNI_N_I_PCI  0x001e
 | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_APPLE_UNI_N_PCI    0x001f
 | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_APPLE_UNI_N_KEYL   0x0022
 | 
					
						
							| 
									
										
										
										
											2009-03-13 15:02:23 +00:00
										 |  |  | #define PCI_DEVICE_ID_APPLE_IPID_USB     0x003f
 | 
					
						
							| 
									
										
										
										
											2009-01-26 15:37:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 15:02:23 +00:00
										 |  |  | /* Realtek (0x10ec) */ | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_REALTEK_8029       0x8029
 | 
					
						
							| 
									
										
										
										
											2009-01-26 15:37:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 15:02:23 +00:00
										 |  |  | /* Xilinx (0x10ee) */ | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_XILINX_XC2VP30     0x0300
 | 
					
						
							| 
									
										
										
										
											2009-01-26 15:37:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 15:02:23 +00:00
										 |  |  | /* Marvell (0x11ab) */ | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_MARVELL_GT6412X    0x4620
 | 
					
						
							| 
									
										
										
										
											2009-01-26 15:37:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 15:02:23 +00:00
										 |  |  | /* QEMU/Bochs VGA (0x1234) */ | 
					
						
							| 
									
										
										
										
											2009-02-01 12:01:04 +00:00
										 |  |  | #define PCI_VENDOR_ID_QEMU               0x1234
 | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_QEMU_VGA           0x1111
 | 
					
						
							| 
									
										
										
										
											2017-12-06 13:36:21 -06:00
										 |  |  | #define PCI_DEVICE_ID_QEMU_IPMI          0x1112
 | 
					
						
							| 
									
										
										
										
											2009-02-01 12:01:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 15:02:23 +00:00
										 |  |  | /* VMWare (0x15ad) */ | 
					
						
							| 
									
										
										
										
											2009-01-26 15:37:35 +00:00
										 |  |  | #define PCI_VENDOR_ID_VMWARE             0x15ad
 | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_VMWARE_SVGA2       0x0405
 | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_VMWARE_SVGA        0x0710
 | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_VMWARE_NET         0x0720
 | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_VMWARE_SCSI        0x0730
 | 
					
						
							| 
									
										
										
										
											2013-04-19 10:05:46 +03:00
										 |  |  | #define PCI_DEVICE_ID_VMWARE_PVSCSI      0x07C0
 | 
					
						
							| 
									
										
										
										
											2009-01-26 15:37:35 +00:00
										 |  |  | #define PCI_DEVICE_ID_VMWARE_IDE         0x1729
 | 
					
						
							| 
									
										
										
										
											2013-03-09 11:21:06 +02:00
										 |  |  | #define PCI_DEVICE_ID_VMWARE_VMXNET3     0x07B0
 | 
					
						
							| 
									
										
										
										
											2009-01-26 15:37:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-28 17:29:07 +00:00
										 |  |  | /* Intel (0x8086) */ | 
					
						
							| 
									
										
										
										
											2009-03-13 15:02:23 +00:00
										 |  |  | #define PCI_DEVICE_ID_INTEL_82551IT      0x1209
 | 
					
						
							| 
									
										
										
										
											2009-09-01 22:16:10 +02:00
										 |  |  | #define PCI_DEVICE_ID_INTEL_82557        0x1229
 | 
					
						
							| 
									
										
										
										
											2010-12-14 01:34:39 +01:00
										 |  |  | #define PCI_DEVICE_ID_INTEL_82801IR      0x2922
 | 
					
						
							| 
									
										
										
										
											2009-03-02 16:42:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-26 15:37:35 +00:00
										 |  |  | /* Red Hat / Qumranet (for QEMU) -- see pci-ids.txt */ | 
					
						
							| 
									
										
										
										
											2008-12-11 21:15:42 +00:00
										 |  |  | #define PCI_VENDOR_ID_REDHAT_QUMRANET    0x1af4
 | 
					
						
							|  |  |  | #define PCI_SUBVENDOR_ID_REDHAT_QUMRANET 0x1af4
 | 
					
						
							|  |  |  | #define PCI_SUBDEVICE_ID_QEMU            0x1100
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-04 13:21:00 +02:00
										 |  |  | /* legacy virtio-pci devices */ | 
					
						
							| 
									
										
										
										
											2008-12-11 21:15:42 +00:00
										 |  |  | #define PCI_DEVICE_ID_VIRTIO_NET         0x1000
 | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_VIRTIO_BLOCK       0x1001
 | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_VIRTIO_BALLOON     0x1002
 | 
					
						
							| 
									
										
										
										
											2009-01-26 15:22:46 +00:00
										 |  |  | #define PCI_DEVICE_ID_VIRTIO_CONSOLE     0x1003
 | 
					
						
							| 
									
										
										
										
											2011-02-11 08:40:59 +00:00
										 |  |  | #define PCI_DEVICE_ID_VIRTIO_SCSI        0x1004
 | 
					
						
							| 
									
										
										
										
											2012-06-20 12:29:32 +05:30
										 |  |  | #define PCI_DEVICE_ID_VIRTIO_RNG         0x1005
 | 
					
						
							| 
									
										
										
										
											2012-12-13 10:19:36 +01:00
										 |  |  | #define PCI_DEVICE_ID_VIRTIO_9P          0x1009
 | 
					
						
							| 
									
										
										
										
											2016-08-16 13:27:22 +01:00
										 |  |  | #define PCI_DEVICE_ID_VIRTIO_VSOCK       0x1012
 | 
					
						
							| 
									
										
										
										
											2008-12-11 21:15:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-04 13:21:00 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * modern virtio-pci devices get their id assigned automatically, | 
					
						
							|  |  |  |  * there is no need to add #defines here.  It gets calculated as | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PCI_DEVICE_ID = PCI_DEVICE_ID_VIRTIO_10_BASE + | 
					
						
							|  |  |  |  *                 virtio_bus_get_vdev_id(bus) | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_VIRTIO_10_BASE     0x1040
 | 
					
						
							| 
									
										
										
										
											2008-12-11 21:15:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-13 10:19:38 +01:00
										 |  |  | #define PCI_VENDOR_ID_REDHAT             0x1b36
 | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_REDHAT_BRIDGE      0x0001
 | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_REDHAT_SERIAL      0x0002
 | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_REDHAT_SERIAL2     0x0003
 | 
					
						
							|  |  |  | #define PCI_DEVICE_ID_REDHAT_SERIAL4     0x0004
 | 
					
						
							| 
									
										
										
										
											2013-03-31 15:31:14 +03:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_TEST        0x0005
 | 
					
						
							| 
									
										
										
										
											2015-03-13 21:09:28 -07:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_ROCKER      0x0006
 | 
					
						
							| 
									
										
										
										
											2014-12-29 21:14:02 -08:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_SDHCI       0x0007
 | 
					
						
							| 
									
										
										
										
											2015-02-13 05:46:07 +00:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_PCIE_HOST   0x0008
 | 
					
						
							| 
									
										
										
										
											2015-06-02 14:23:06 +03:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_PXB         0x0009
 | 
					
						
							| 
									
										
										
										
											2015-06-18 12:17:29 +02:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_BRIDGE_SEAT 0x000a
 | 
					
						
							| 
									
										
										
										
											2015-11-26 18:00:27 +02:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_PXB_PCIE    0x000b
 | 
					
						
							| 
									
										
										
										
											2017-01-23 21:20:20 +02:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_PCIE_RP     0x000c
 | 
					
						
							| 
									
										
										
										
											2017-02-06 12:55:37 +01:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_XHCI        0x000d
 | 
					
						
							| 
									
										
										
										
											2017-08-18 02:36:47 +03:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_PCIE_BRIDGE 0x000e
 | 
					
						
							| 
									
										
										
										
											2018-04-24 08:38:57 +02:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_MDPY        0x000f
 | 
					
						
							| 
									
										
										
										
											2020-01-13 19:12:50 +01:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_NVME        0x0010
 | 
					
						
							| 
									
										
										
										
											2021-01-27 16:59:28 +02:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_PVPANIC     0x0011
 | 
					
						
							| 
									
										
										
										
											2022-01-28 15:38:02 -05:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_ACPI_ERST   0x0012
 | 
					
						
							| 
									
										
										
										
											2023-09-06 16:43:48 +09:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_UFS         0x0013
 | 
					
						
							| 
									
										
										
										
											2024-10-16 17:40:28 -03:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_RISCV_IOMMU 0x0014
 | 
					
						
							| 
									
										
										
										
											2012-12-13 10:19:38 +01:00
										 |  |  | #define PCI_DEVICE_ID_REDHAT_QXL         0x0100
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-30 21:21:10 +09:00
										 |  |  | #define FMT_PCIBUS                      PRIx64
 | 
					
						
							| 
									
										
										
										
											2009-10-30 21:21:08 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-09 13:44:19 +01:00
										 |  |  | typedef uint64_t pcibus_t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct PCIHostDeviceAddress { | 
					
						
							|  |  |  |     unsigned int domain; | 
					
						
							|  |  |  |     unsigned int bus; | 
					
						
							|  |  |  |     unsigned int slot; | 
					
						
							|  |  |  |     unsigned int function; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | typedef void PCIConfigWriteFunc(PCIDevice *pci_dev, | 
					
						
							|  |  |  |                                 uint32_t address, uint32_t data, int len); | 
					
						
							|  |  |  | typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev, | 
					
						
							|  |  |  |                                    uint32_t address, int len); | 
					
						
							|  |  |  | typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num, | 
					
						
							| 
									
										
										
										
											2009-10-30 21:21:08 +09:00
										 |  |  |                                 pcibus_t addr, pcibus_t size, int type); | 
					
						
							| 
									
										
										
										
											2012-07-03 22:39:27 -06:00
										 |  |  | typedef void PCIUnregisterFunc(PCIDevice *pci_dev); | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-13 16:26:33 -04:00
										 |  |  | typedef void MSITriggerFunc(PCIDevice *dev, MSIMessage msg); | 
					
						
							|  |  |  | typedef MSIMessage MSIPrepareMessageFunc(PCIDevice *dev, unsigned vector); | 
					
						
							|  |  |  | typedef MSIMessage MSIxPrepareMessageFunc(PCIDevice *dev, unsigned vector); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | typedef struct PCIIORegion { | 
					
						
							| 
									
										
										
										
											2009-10-30 21:21:08 +09:00
										 |  |  |     pcibus_t addr; /* current PCI mapping address. -1 means not mapped */ | 
					
						
							|  |  |  | #define PCI_BAR_UNMAPPED (~(pcibus_t)0)
 | 
					
						
							|  |  |  |     pcibus_t size; | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  |     uint8_t type; | 
					
						
							| 
									
										
										
										
											2011-07-26 14:26:20 +03:00
										 |  |  |     MemoryRegion *memory; | 
					
						
							| 
									
										
										
										
											2011-08-08 16:09:05 +03:00
										 |  |  |     MemoryRegion *address_space; | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | } PCIIORegion; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define PCI_ROM_SLOT 6
 | 
					
						
							|  |  |  | #define PCI_NUM_REGIONS 7
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-03 10:21:26 -07:00
										 |  |  | enum { | 
					
						
							|  |  |  |     QEMU_PCI_VGA_MEM, | 
					
						
							|  |  |  |     QEMU_PCI_VGA_IO_LO, | 
					
						
							|  |  |  |     QEMU_PCI_VGA_IO_HI, | 
					
						
							|  |  |  |     QEMU_PCI_VGA_NUM_REGIONS, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define QEMU_PCI_VGA_MEM_BASE 0xa0000
 | 
					
						
							|  |  |  | #define QEMU_PCI_VGA_MEM_SIZE 0x20000
 | 
					
						
							|  |  |  | #define QEMU_PCI_VGA_IO_LO_BASE 0x3b0
 | 
					
						
							|  |  |  | #define QEMU_PCI_VGA_IO_LO_SIZE 0xc
 | 
					
						
							|  |  |  | #define QEMU_PCI_VGA_IO_HI_BASE 0x3c0
 | 
					
						
							|  |  |  | #define QEMU_PCI_VGA_IO_HI_SIZE 0x20
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-12 23:05:42 +02:00
										 |  |  | #include "hw/pci/pci_regs.h"
 | 
					
						
							| 
									
										
										
										
											2009-12-15 20:26:01 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* PCI HEADER_TYPE */ | 
					
						
							| 
									
										
										
										
											2009-05-03 19:03:00 +00:00
										 |  |  | #define  PCI_HEADER_TYPE_MULTI_FUNCTION 0x80
 | 
					
						
							| 
									
										
										
										
											2008-12-18 22:43:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-21 19:45:18 +03:00
										 |  |  | /* Size of the standard PCI config header */ | 
					
						
							|  |  |  | #define PCI_CONFIG_HEADER_SIZE 0x40
 | 
					
						
							|  |  |  | /* Size of the standard PCI config space */ | 
					
						
							|  |  |  | #define PCI_CONFIG_SPACE_SIZE 0x100
 | 
					
						
							| 
									
										
										
										
											2015-03-10 09:52:23 +08:00
										 |  |  | /* Size of the standard PCIe config space: 4KB */ | 
					
						
							| 
									
										
										
										
											2009-10-30 21:21:18 +09:00
										 |  |  | #define PCIE_CONFIG_SPACE_SIZE  0x1000
 | 
					
						
							| 
									
										
										
										
											2009-06-21 19:45:18 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-30 21:20:56 +09:00
										 |  |  | #define PCI_NUM_PINS 4 /* A-D */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-21 19:49:54 +03:00
										 |  |  | /* Bits in cap_present field. */ | 
					
						
							|  |  |  | enum { | 
					
						
							| 
									
										
										
										
											2010-10-19 18:06:32 +09:00
										 |  |  |     QEMU_PCI_CAP_MSI = 0x1, | 
					
						
							|  |  |  |     QEMU_PCI_CAP_MSIX = 0x2, | 
					
						
							|  |  |  |     QEMU_PCI_CAP_EXPRESS = 0x4, | 
					
						
							| 
									
										
										
										
											2010-06-23 16:15:30 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* multifunction capable device */ | 
					
						
							| 
									
										
										
										
											2010-10-19 18:06:32 +09:00
										 |  |  | #define QEMU_PCI_CAP_MULTIFUNCTION_BITNR        3
 | 
					
						
							| 
									
										
										
										
											2010-06-23 16:15:30 +09:00
										 |  |  |     QEMU_PCI_CAP_MULTIFUNCTION = (1 << QEMU_PCI_CAP_MULTIFUNCTION_BITNR), | 
					
						
							| 
									
										
										
										
											2010-11-26 21:01:41 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 13:52:47 +01:00
										 |  |  |     /* command register SERR bit enabled - unused since QEMU v5.0 */ | 
					
						
							| 
									
										
										
										
											2010-11-26 21:01:41 +09:00
										 |  |  | #define QEMU_PCI_CAP_SERR_BITNR 4
 | 
					
						
							|  |  |  |     QEMU_PCI_CAP_SERR = (1 << QEMU_PCI_CAP_SERR_BITNR), | 
					
						
							| 
									
										
										
										
											2012-02-12 14:12:21 +02:00
										 |  |  |     /* Standard hot plug controller. */ | 
					
						
							|  |  |  | #define QEMU_PCI_SHPC_BITNR 5
 | 
					
						
							|  |  |  |     QEMU_PCI_CAP_SHPC = (1 << QEMU_PCI_SHPC_BITNR), | 
					
						
							| 
									
										
										
										
											2012-02-15 19:17:59 +02:00
										 |  |  | #define QEMU_PCI_SLOTID_BITNR 6
 | 
					
						
							|  |  |  |     QEMU_PCI_CAP_SLOTID = (1 << QEMU_PCI_SLOTID_BITNR), | 
					
						
							| 
									
										
										
										
											2014-06-23 17:32:48 +03:00
										 |  |  |     /* PCI Express capability - Power Controller Present */ | 
					
						
							|  |  |  | #define QEMU_PCIE_SLTCAP_PCP_BITNR 7
 | 
					
						
							|  |  |  |     QEMU_PCIE_SLTCAP_PCP = (1 << QEMU_PCIE_SLTCAP_PCP_BITNR), | 
					
						
							| 
									
										
										
										
											2016-07-19 23:16:19 +03:00
										 |  |  |     /* Link active status in endpoint capability is always set */ | 
					
						
							|  |  |  | #define QEMU_PCIE_LNKSTA_DLLLA_BITNR 8
 | 
					
						
							|  |  |  |     QEMU_PCIE_LNKSTA_DLLLA = (1 << QEMU_PCIE_LNKSTA_DLLLA_BITNR), | 
					
						
							| 
									
										
										
										
											2017-02-20 22:43:10 +02:00
										 |  |  | #define QEMU_PCIE_EXTCAP_INIT_BITNR 9
 | 
					
						
							|  |  |  |     QEMU_PCIE_EXTCAP_INIT = (1 << QEMU_PCIE_EXTCAP_INIT_BITNR), | 
					
						
							| 
									
										
										
										
											2022-04-29 15:40:26 +01:00
										 |  |  | #define QEMU_PCIE_CXL_BITNR 10
 | 
					
						
							|  |  |  |     QEMU_PCIE_CAP_CXL = (1 << QEMU_PCIE_CXL_BITNR), | 
					
						
							| 
									
										
										
										
											2023-05-02 21:27:02 -03:00
										 |  |  | #define QEMU_PCIE_ERR_UNC_MASK_BITNR 11
 | 
					
						
							|  |  |  |     QEMU_PCIE_ERR_UNC_MASK = (1 << QEMU_PCIE_ERR_UNC_MASK_BITNR), | 
					
						
							| 
									
										
										
										
											2023-07-11 00:38:36 +09:00
										 |  |  | #define QEMU_PCIE_ARI_NEXTFN_1_BITNR 12
 | 
					
						
							|  |  |  |     QEMU_PCIE_ARI_NEXTFN_1 = (1 << QEMU_PCIE_ARI_NEXTFN_1_BITNR), | 
					
						
							| 
									
										
										
										
											2009-06-21 19:49:54 +03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-19 17:11:47 +03:00
										 |  |  | typedef struct PCIINTxRoute { | 
					
						
							|  |  |  |     enum { | 
					
						
							|  |  |  |         PCI_INTX_ENABLED, | 
					
						
							|  |  |  |         PCI_INTX_INVERTED, | 
					
						
							|  |  |  |         PCI_INTX_DISABLED, | 
					
						
							|  |  |  |     } mode; | 
					
						
							|  |  |  |     int irq; | 
					
						
							|  |  |  | } PCIINTxRoute; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-02 14:38:47 +02:00
										 |  |  | typedef void (*PCIINTxRoutingNotifier)(PCIDevice *dev); | 
					
						
							| 
									
										
										
										
											2012-05-17 10:32:31 -03:00
										 |  |  | typedef int (*MSIVectorUseNotifier)(PCIDevice *dev, unsigned int vector, | 
					
						
							|  |  |  |                                       MSIMessage msg); | 
					
						
							|  |  |  | typedef void (*MSIVectorReleaseNotifier)(PCIDevice *dev, unsigned int vector); | 
					
						
							| 
									
										
										
										
											2012-12-12 16:10:02 +02:00
										 |  |  | typedef void (*MSIVectorPollNotifier)(PCIDevice *dev, | 
					
						
							|  |  |  |                                       unsigned int vector_start, | 
					
						
							|  |  |  |                                       unsigned int vector_end); | 
					
						
							| 
									
										
										
										
											2012-05-17 10:32:31 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-08 16:09:31 +03:00
										 |  |  | void pci_register_bar(PCIDevice *pci_dev, int region_num, | 
					
						
							|  |  |  |                       uint8_t attr, MemoryRegion *memory); | 
					
						
							| 
									
										
										
										
											2013-03-03 10:21:26 -07:00
										 |  |  | void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem, | 
					
						
							|  |  |  |                       MemoryRegion *io_lo, MemoryRegion *io_hi); | 
					
						
							|  |  |  | void pci_unregister_vga(PCIDevice *pci_dev); | 
					
						
							| 
									
										
										
										
											2011-08-08 16:08:55 +03:00
										 |  |  | pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num); | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-06 16:46:16 +09:00
										 |  |  | int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, | 
					
						
							| 
									
										
										
										
											2017-06-27 14:16:50 +08:00
										 |  |  |                        uint8_t offset, uint8_t size, | 
					
						
							|  |  |  |                        Error **errp); | 
					
						
							| 
									
										
										
										
											2009-06-21 19:45:40 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | void pci_del_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint8_t pci_find_capability(PCIDevice *pci_dev, uint8_t cap_id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | uint32_t pci_default_read_config(PCIDevice *d, | 
					
						
							|  |  |  |                                  uint32_t address, int len); | 
					
						
							|  |  |  | void pci_default_write_config(PCIDevice *d, | 
					
						
							|  |  |  |                               uint32_t address, uint32_t val, int len); | 
					
						
							|  |  |  | void pci_device_save(PCIDevice *s, QEMUFile *f); | 
					
						
							|  |  |  | int pci_device_load(PCIDevice *s, QEMUFile *f); | 
					
						
							| 
									
										
										
										
											2011-08-15 17:17:36 +03:00
										 |  |  | MemoryRegion *pci_address_space(PCIDevice *dev); | 
					
						
							| 
									
										
										
										
											2011-08-10 15:28:10 -07:00
										 |  |  | MemoryRegion *pci_address_space_io(PCIDevice *dev); | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-07 15:33:54 +10:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Should not normally be used by devices. For use by sPAPR target | 
					
						
							|  |  |  |  * where QEMU emulates firmware. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | int pci_bar(PCIDevice *d, int reg); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-28 15:28:17 +02:00
										 |  |  | typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level); | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num); | 
					
						
							| 
									
										
										
										
											2012-07-19 17:11:47 +03:00
										 |  |  | typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin); | 
					
						
							| 
									
										
										
										
											2010-11-12 16:21:35 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-14 16:01:05 -06:00
										 |  |  | #define TYPE_PCI_BUS "PCI"
 | 
					
						
							| 
									
										
										
										
											2020-09-16 14:25:18 -04:00
										 |  |  | OBJECT_DECLARE_TYPE(PCIBus, PCIBusClass, PCI_BUS) | 
					
						
							| 
									
										
										
										
											2013-03-14 16:01:05 -06:00
										 |  |  | #define TYPE_PCIE_BUS "PCIE"
 | 
					
						
							| 
									
										
										
										
											2022-04-29 15:40:39 +01:00
										 |  |  | #define TYPE_CXL_BUS "CXL"
 | 
					
						
							| 
									
										
										
										
											2013-03-14 16:01:05 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-28 12:31:25 +08:00
										 |  |  | typedef void (*pci_bus_dev_fn)(PCIBus *b, PCIDevice *d, void *opaque); | 
					
						
							|  |  |  | typedef void (*pci_bus_fn)(PCIBus *b, void *opaque); | 
					
						
							|  |  |  | typedef void *(*pci_bus_ret_fn)(PCIBus *b, void *opaque); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-12 15:03:02 +01:00
										 |  |  | bool pci_bus_is_express(const PCIBus *bus); | 
					
						
							| 
									
										
										
										
											2019-04-01 19:55:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-23 13:11:50 +01:00
										 |  |  | void pci_root_bus_init(PCIBus *bus, size_t bus_size, DeviceState *parent, | 
					
						
							|  |  |  |                        const char *name, | 
					
						
							| 
									
										
										
										
											2023-10-09 09:33:29 +02:00
										 |  |  |                        MemoryRegion *mem, MemoryRegion *io, | 
					
						
							| 
									
										
										
										
											2021-09-23 13:11:50 +01:00
										 |  |  |                        uint8_t devfn_min, const char *typename); | 
					
						
							| 
									
										
										
										
											2017-11-29 19:46:22 +11:00
										 |  |  | PCIBus *pci_root_bus_new(DeviceState *parent, const char *name, | 
					
						
							| 
									
										
										
										
											2023-10-09 09:33:29 +02:00
										 |  |  |                          MemoryRegion *mem, MemoryRegion *io, | 
					
						
							| 
									
										
										
										
											2013-03-14 16:01:11 -06:00
										 |  |  |                          uint8_t devfn_min, const char *typename); | 
					
						
							| 
									
										
										
										
											2018-12-21 01:35:30 +01:00
										 |  |  | void pci_root_bus_cleanup(PCIBus *bus); | 
					
						
							| 
									
										
										
										
											2023-01-09 18:23:17 +01:00
										 |  |  | void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, | 
					
						
							| 
									
										
										
										
											2009-09-16 22:25:31 +02:00
										 |  |  |                   void *irq_opaque, int nirq); | 
					
						
							| 
									
										
										
										
											2023-01-09 18:23:17 +01:00
										 |  |  | void pci_bus_map_irqs(PCIBus *bus, pci_map_irq_fn map_irq); | 
					
						
							| 
									
										
										
										
											2018-12-21 01:35:30 +01:00
										 |  |  | void pci_bus_irqs_cleanup(PCIBus *bus); | 
					
						
							| 
									
										
										
										
											2011-04-01 20:43:21 +09:00
										 |  |  | int pci_bus_get_irq_level(PCIBus *bus, int irq_num); | 
					
						
							| 
									
										
										
										
											2023-03-15 10:26:19 -04:00
										 |  |  | uint32_t pci_bus_get_slot_reserved_mask(PCIBus *bus); | 
					
						
							|  |  |  | void pci_bus_set_slot_reserved_mask(PCIBus *bus, uint32_t mask); | 
					
						
							|  |  |  | void pci_bus_clear_slot_reserved_mask(PCIBus *bus, uint32_t mask); | 
					
						
							| 
									
										
										
										
											2012-10-19 16:43:28 -04:00
										 |  |  | /* 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD */ | 
					
						
							| 
									
										
										
										
											2019-04-05 18:30:48 +02:00
										 |  |  | static inline int pci_swizzle(int slot, int pin) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return (slot + pin) % PCI_NUM_PINS; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-10-19 16:43:28 -04:00
										 |  |  | int pci_swizzle_map_irq_fn(PCIDevice *pci_dev, int pin); | 
					
						
							| 
									
										
										
										
											2017-11-29 19:46:22 +11:00
										 |  |  | PCIBus *pci_register_root_bus(DeviceState *parent, const char *name, | 
					
						
							|  |  |  |                               pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, | 
					
						
							|  |  |  |                               void *irq_opaque, | 
					
						
							| 
									
										
										
										
											2023-10-09 09:33:29 +02:00
										 |  |  |                               MemoryRegion *mem, MemoryRegion *io, | 
					
						
							| 
									
										
										
										
											2017-11-29 19:46:22 +11:00
										 |  |  |                               uint8_t devfn_min, int nirq, | 
					
						
							|  |  |  |                               const char *typename); | 
					
						
							| 
									
										
										
										
											2018-12-21 01:35:30 +01:00
										 |  |  | void pci_unregister_root_bus(PCIBus *bus); | 
					
						
							| 
									
										
										
										
											2012-07-19 17:11:47 +03:00
										 |  |  | void pci_bus_set_route_irq_fn(PCIBus *, pci_route_irq_fn); | 
					
						
							|  |  |  | PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin); | 
					
						
							| 
									
										
										
										
											2012-10-02 13:21:54 -06:00
										 |  |  | bool pci_intx_route_changed(PCIINTxRoute *old, PCIINTxRoute *new); | 
					
						
							| 
									
										
										
										
											2012-07-02 14:38:47 +02:00
										 |  |  | void pci_bus_fire_intx_routing_notifier(PCIBus *bus); | 
					
						
							|  |  |  | void pci_device_set_intx_routing_notifier(PCIDevice *dev, | 
					
						
							|  |  |  |                                           PCIINTxRoutingNotifier notifier); | 
					
						
							| 
									
										
										
										
											2010-12-22 15:14:35 +09:00
										 |  |  | void pci_device_reset(PCIDevice *dev); | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-20 01:05:31 +01:00
										 |  |  | void pci_init_nic_devices(PCIBus *bus, const char *default_model); | 
					
						
							|  |  |  | bool pci_init_nic_in_slot(PCIBus *rootbus, const char *default_model, | 
					
						
							|  |  |  |                           const char *alias, const char *devaddr); | 
					
						
							| 
									
										
										
										
											2012-09-08 11:49:24 +02:00
										 |  |  | PCIDevice *pci_vga_init(PCIBus *bus); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-29 19:46:27 +11:00
										 |  |  | static inline PCIBus *pci_get_bus(const PCIDevice *dev) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return PCI_BUS(qdev_get_parent_bus(DEVICE(dev))); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | int pci_bus_num(PCIBus *s); | 
					
						
							| 
									
										
										
										
											2021-07-08 12:55:15 +00:00
										 |  |  | void pci_bus_range(PCIBus *bus, int *min_bus, int *max_bus); | 
					
						
							| 
									
										
										
										
											2017-11-29 19:46:26 +11:00
										 |  |  | static inline int pci_dev_bus_num(const PCIDevice *dev) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-11-29 19:46:27 +11:00
										 |  |  |     return pci_bus_num(pci_get_bus(dev)); | 
					
						
							| 
									
										
										
										
											2017-11-29 19:46:26 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-02 14:23:09 +03:00
										 |  |  | int pci_bus_numa_node(PCIBus *bus); | 
					
						
							| 
									
										
										
										
											2012-06-21 15:35:28 +00:00
										 |  |  | void pci_for_each_device(PCIBus *bus, int bus_num, | 
					
						
							| 
									
										
										
										
											2021-10-28 12:31:25 +08:00
										 |  |  |                          pci_bus_dev_fn fn, | 
					
						
							| 
									
										
										
										
											2012-06-21 15:35:28 +00:00
										 |  |  |                          void *opaque); | 
					
						
							| 
									
										
										
										
											2017-02-22 11:56:53 +01:00
										 |  |  | void pci_for_each_device_reverse(PCIBus *bus, int bus_num, | 
					
						
							| 
									
										
										
										
											2021-10-28 12:31:25 +08:00
										 |  |  |                                  pci_bus_dev_fn fn, | 
					
						
							| 
									
										
										
										
											2017-02-22 11:56:53 +01:00
										 |  |  |                                  void *opaque); | 
					
						
							| 
									
										
										
										
											2021-10-28 12:31:26 +08:00
										 |  |  | void pci_for_each_device_under_bus(PCIBus *bus, | 
					
						
							|  |  |  |                                    pci_bus_dev_fn fn, void *opaque); | 
					
						
							|  |  |  | void pci_for_each_device_under_bus_reverse(PCIBus *bus, | 
					
						
							|  |  |  |                                            pci_bus_dev_fn fn, | 
					
						
							|  |  |  |                                            void *opaque); | 
					
						
							| 
									
										
										
										
											2021-10-28 12:31:25 +08:00
										 |  |  | void pci_for_each_bus_depth_first(PCIBus *bus, pci_bus_ret_fn begin, | 
					
						
							|  |  |  |                                   pci_bus_fn end, void *parent_state); | 
					
						
							| 
									
										
										
										
											2015-10-28 14:20:31 +08:00
										 |  |  | PCIDevice *pci_get_function_0(PCIDevice *pci_dev); | 
					
						
							| 
									
										
										
										
											2013-10-14 18:01:07 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Use this wrapper when specific scan order is not required. */ | 
					
						
							|  |  |  | static inline | 
					
						
							| 
									
										
										
										
											2021-10-28 12:31:25 +08:00
										 |  |  | void pci_for_each_bus(PCIBus *bus, pci_bus_fn fn, void *opaque) | 
					
						
							| 
									
										
										
										
											2013-10-14 18:01:07 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     pci_for_each_bus_depth_first(bus, NULL, fn, opaque); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-06 18:48:48 +10:00
										 |  |  | PCIBus *pci_device_root_bus(const PCIDevice *d); | 
					
						
							| 
									
										
										
										
											2013-06-06 18:48:49 +10:00
										 |  |  | const char *pci_root_bus_path(PCIDevice *dev); | 
					
						
							| 
									
										
										
										
											2021-07-08 12:55:11 +00:00
										 |  |  | bool pci_bus_bypass_iommu(PCIBus *bus); | 
					
						
							| 
									
										
										
										
											2011-01-27 15:56:36 +09:00
										 |  |  | PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn); | 
					
						
							| 
									
										
										
										
											2010-12-24 12:14:13 +09:00
										 |  |  | int pci_qdev_find_device(const char *id, PCIDevice **pdev); | 
					
						
							| 
									
										
										
										
											2013-09-02 11:37:02 +03:00
										 |  |  | void pci_bus_get_w64_range(PCIBus *bus, Range *range); | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-20 16:21:38 +09:00
										 |  |  | void pci_device_deassert_intx(PCIDevice *dev); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-17 18:14:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * struct PCIIOMMUOps: callbacks structure for specific IOMMU handlers | 
					
						
							|  |  |  |  * of a PCIBus | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Allows to modify the behavior of some IOMMU operations of the PCI | 
					
						
							|  |  |  |  * framework for a set of devices on a PCI bus. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | typedef struct PCIIOMMUOps { | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * @get_address_space: get the address space for a set of devices | 
					
						
							|  |  |  |      * on a PCI bus. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * Mandatory callback which returns a pointer to an #AddressSpace | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @bus: the #PCIBus being accessed. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @opaque: the data passed to pci_setup_iommu(). | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @devfn: device and function number | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2024-06-05 16:30:39 +08:00
										 |  |  |     AddressSpace * (*get_address_space)(PCIBus *bus, void *opaque, int devfn); | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * @set_iommu_device: attach a HostIOMMUDevice to a vIOMMU | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * Optional callback, if not implemented in vIOMMU, then vIOMMU can't | 
					
						
							|  |  |  |      * retrieve host information from the associated HostIOMMUDevice. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @bus: the #PCIBus of the PCI device. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @opaque: the data passed to pci_setup_iommu(). | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @devfn: device and function number of the PCI device. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @dev: the #HostIOMMUDevice to attach. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @errp: pass an Error out only when return false | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * Returns: true if HostIOMMUDevice is attached or else false with errp set. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     bool (*set_iommu_device)(PCIBus *bus, void *opaque, int devfn, | 
					
						
							|  |  |  |                              HostIOMMUDevice *dev, Error **errp); | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * @unset_iommu_device: detach a HostIOMMUDevice from a vIOMMU | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * Optional callback. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @bus: the #PCIBus of the PCI device. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @opaque: the data passed to pci_setup_iommu(). | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @devfn: device and function number of the PCI device. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     void (*unset_iommu_device)(PCIBus *bus, void *opaque, int devfn); | 
					
						
							| 
									
										
										
										
											2023-10-17 18:14:04 +02:00
										 |  |  | } PCIIOMMUOps; | 
					
						
							| 
									
										
										
										
											2012-06-27 14:50:45 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-10 01:09:08 +10:00
										 |  |  | AddressSpace *pci_device_iommu_address_space(PCIDevice *dev); | 
					
						
							| 
									
										
										
										
											2024-06-05 16:30:39 +08:00
										 |  |  | bool pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod, | 
					
						
							|  |  |  |                                  Error **errp); | 
					
						
							|  |  |  | void pci_device_unset_iommu_device(PCIDevice *dev); | 
					
						
							| 
									
										
										
										
											2023-10-17 18:14:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * pci_setup_iommu: Initialize specific IOMMU handlers for a PCIBus | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Let PCI host bridges define specific operations. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @bus: the #PCIBus being updated. | 
					
						
							|  |  |  |  * @ops: the #PCIIOMMUOps | 
					
						
							|  |  |  |  * @opaque: passed to callbacks of the @ops structure. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void pci_setup_iommu(PCIBus *bus, const PCIIOMMUOps *ops, void *opaque); | 
					
						
							| 
									
										
										
										
											2012-06-27 14:50:45 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-17 18:44:50 +01:00
										 |  |  | pcibus_t pci_bar_address(PCIDevice *d, | 
					
						
							|  |  |  |                          int reg, uint8_t type, pcibus_t size); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-21 19:50:57 +03:00
										 |  |  | static inline void | 
					
						
							|  |  |  | pci_set_byte(uint8_t *config, uint8_t val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     *config = val; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline uint8_t | 
					
						
							| 
									
										
										
										
											2010-01-11 21:20:13 +01:00
										 |  |  | pci_get_byte(const uint8_t *config) | 
					
						
							| 
									
										
										
										
											2009-06-21 19:50:57 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     return *config; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-21 19:45:30 +03:00
										 |  |  | static inline void | 
					
						
							|  |  |  | pci_set_word(uint8_t *config, uint16_t val) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-05 16:38:29 +00:00
										 |  |  |     stw_le_p(config, val); | 
					
						
							| 
									
										
										
										
											2009-06-21 19:45:30 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline uint16_t | 
					
						
							| 
									
										
										
										
											2010-01-11 21:20:13 +01:00
										 |  |  | pci_get_word(const uint8_t *config) | 
					
						
							| 
									
										
										
										
											2009-06-21 19:45:30 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-05 16:38:31 +00:00
										 |  |  |     return lduw_le_p(config); | 
					
						
							| 
									
										
										
										
											2009-06-21 19:45:30 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void | 
					
						
							|  |  |  | pci_set_long(uint8_t *config, uint32_t val) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-05 16:38:30 +00:00
										 |  |  |     stl_le_p(config, val); | 
					
						
							| 
									
										
										
										
											2009-06-21 19:45:30 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline uint32_t | 
					
						
							| 
									
										
										
										
											2010-01-11 21:20:13 +01:00
										 |  |  | pci_get_long(const uint8_t *config) | 
					
						
							| 
									
										
										
										
											2009-06-21 19:45:30 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-05 16:38:32 +00:00
										 |  |  |     return ldl_le_p(config); | 
					
						
							| 
									
										
										
										
											2009-06-21 19:45:30 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-01 11:23:30 +03:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * PCI capabilities and/or their fields | 
					
						
							|  |  |  |  * are generally DWORD aligned only so | 
					
						
							|  |  |  |  * mechanism used by pci_set/get_quad() | 
					
						
							|  |  |  |  * must be tolerant to unaligned pointers | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-10-30 21:20:59 +09:00
										 |  |  | static inline void | 
					
						
							|  |  |  | pci_set_quad(uint8_t *config, uint64_t val) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-01 11:23:30 +03:00
										 |  |  |     stq_le_p(config, val); | 
					
						
							| 
									
										
										
										
											2009-10-30 21:20:59 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline uint64_t | 
					
						
							| 
									
										
										
										
											2010-01-11 21:20:13 +01:00
										 |  |  | pci_get_quad(const uint8_t *config) | 
					
						
							| 
									
										
										
										
											2009-10-30 21:20:59 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-01 11:23:30 +03:00
										 |  |  |     return ldq_le_p(config); | 
					
						
							| 
									
										
										
										
											2009-10-30 21:20:59 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-26 15:37:35 +00:00
										 |  |  | static inline void | 
					
						
							|  |  |  | pci_config_set_vendor_id(uint8_t *pci_config, uint16_t val) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-06-21 19:45:30 +03:00
										 |  |  |     pci_set_word(&pci_config[PCI_VENDOR_ID], val); | 
					
						
							| 
									
										
										
										
											2009-01-26 15:37:35 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void | 
					
						
							|  |  |  | pci_config_set_device_id(uint8_t *pci_config, uint16_t val) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-06-21 19:45:30 +03:00
										 |  |  |     pci_set_word(&pci_config[PCI_DEVICE_ID], val); | 
					
						
							| 
									
										
										
										
											2009-01-26 15:37:35 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-25 09:41:25 +01:00
										 |  |  | static inline void | 
					
						
							|  |  |  | pci_config_set_revision(uint8_t *pci_config, uint8_t val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     pci_set_byte(&pci_config[PCI_REVISION_ID], val); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-01 19:26:20 +00:00
										 |  |  | static inline void | 
					
						
							|  |  |  | pci_config_set_class(uint8_t *pci_config, uint16_t val) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-06-21 19:45:30 +03:00
										 |  |  |     pci_set_word(&pci_config[PCI_CLASS_DEVICE], val); | 
					
						
							| 
									
										
										
										
											2009-02-01 19:26:20 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-25 09:41:25 +01:00
										 |  |  | static inline void | 
					
						
							|  |  |  | pci_config_set_prog_interface(uint8_t *pci_config, uint8_t val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     pci_set_byte(&pci_config[PCI_CLASS_PROG], val); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void | 
					
						
							|  |  |  | pci_config_set_interrupt_pin(uint8_t *pci_config, uint8_t val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     pci_set_byte(&pci_config[PCI_INTERRUPT_PIN], val); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 18:06:28 +09:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * helper functions to do bit mask operation on configuration space. | 
					
						
							|  |  |  |  * Just to set bit, use test-and-set and discard returned value. | 
					
						
							|  |  |  |  * Just to clear bit, use test-and-clear and discard returned value. | 
					
						
							|  |  |  |  * NOTE: They aren't atomic. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline uint8_t | 
					
						
							|  |  |  | pci_byte_test_and_clear_mask(uint8_t *config, uint8_t mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint8_t val = pci_get_byte(config); | 
					
						
							|  |  |  |     pci_set_byte(config, val & ~mask); | 
					
						
							|  |  |  |     return val & mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline uint8_t | 
					
						
							|  |  |  | pci_byte_test_and_set_mask(uint8_t *config, uint8_t mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint8_t val = pci_get_byte(config); | 
					
						
							|  |  |  |     pci_set_byte(config, val | mask); | 
					
						
							|  |  |  |     return val & mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline uint16_t | 
					
						
							|  |  |  | pci_word_test_and_clear_mask(uint8_t *config, uint16_t mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint16_t val = pci_get_word(config); | 
					
						
							|  |  |  |     pci_set_word(config, val & ~mask); | 
					
						
							|  |  |  |     return val & mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline uint16_t | 
					
						
							|  |  |  | pci_word_test_and_set_mask(uint8_t *config, uint16_t mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint16_t val = pci_get_word(config); | 
					
						
							|  |  |  |     pci_set_word(config, val | mask); | 
					
						
							|  |  |  |     return val & mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline uint32_t | 
					
						
							|  |  |  | pci_long_test_and_clear_mask(uint8_t *config, uint32_t mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint32_t val = pci_get_long(config); | 
					
						
							|  |  |  |     pci_set_long(config, val & ~mask); | 
					
						
							|  |  |  |     return val & mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline uint32_t | 
					
						
							|  |  |  | pci_long_test_and_set_mask(uint8_t *config, uint32_t mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint32_t val = pci_get_long(config); | 
					
						
							|  |  |  |     pci_set_long(config, val | mask); | 
					
						
							|  |  |  |     return val & mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline uint64_t | 
					
						
							|  |  |  | pci_quad_test_and_clear_mask(uint8_t *config, uint64_t mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint64_t val = pci_get_quad(config); | 
					
						
							|  |  |  |     pci_set_quad(config, val & ~mask); | 
					
						
							|  |  |  |     return val & mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline uint64_t | 
					
						
							|  |  |  | pci_quad_test_and_set_mask(uint8_t *config, uint64_t mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint64_t val = pci_get_quad(config); | 
					
						
							|  |  |  |     pci_set_quad(config, val | mask); | 
					
						
							|  |  |  |     return val & mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-21 15:41:30 +02:00
										 |  |  | /* Access a register specified by a mask */ | 
					
						
							|  |  |  | static inline void | 
					
						
							|  |  |  | pci_set_byte_by_mask(uint8_t *config, uint8_t mask, uint8_t reg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint8_t val = pci_get_byte(config); | 
					
						
							| 
									
										
										
										
											2022-08-18 14:54:21 +01:00
										 |  |  |     uint8_t rval; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert(mask); | 
					
						
							|  |  |  |     rval = reg << ctz32(mask); | 
					
						
							| 
									
										
										
										
											2012-02-21 15:41:30 +02:00
										 |  |  |     pci_set_byte(config, (~mask & val) | (mask & rval)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void | 
					
						
							|  |  |  | pci_set_word_by_mask(uint8_t *config, uint16_t mask, uint16_t reg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint16_t val = pci_get_word(config); | 
					
						
							| 
									
										
										
										
											2022-08-18 14:54:21 +01:00
										 |  |  |     uint16_t rval; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert(mask); | 
					
						
							|  |  |  |     rval = reg << ctz32(mask); | 
					
						
							| 
									
										
										
										
											2012-02-21 15:41:30 +02:00
										 |  |  |     pci_set_word(config, (~mask & val) | (mask & rval)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void | 
					
						
							|  |  |  | pci_set_long_by_mask(uint8_t *config, uint32_t mask, uint32_t reg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint32_t val = pci_get_long(config); | 
					
						
							| 
									
										
										
										
											2022-08-18 14:54:21 +01:00
										 |  |  |     uint32_t rval; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert(mask); | 
					
						
							|  |  |  |     rval = reg << ctz32(mask); | 
					
						
							| 
									
										
										
										
											2012-02-21 15:41:30 +02:00
										 |  |  |     pci_set_long(config, (~mask & val) | (mask & rval)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void | 
					
						
							|  |  |  | pci_set_quad_by_mask(uint8_t *config, uint64_t mask, uint64_t reg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint64_t val = pci_get_quad(config); | 
					
						
							| 
									
										
										
										
											2022-08-18 14:54:21 +01:00
										 |  |  |     uint64_t rval; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert(mask); | 
					
						
							|  |  |  |     rval = reg << ctz32(mask); | 
					
						
							| 
									
										
										
										
											2012-02-21 15:41:30 +02:00
										 |  |  |     pci_set_quad(config, (~mask & val) | (mask & rval)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-04 12:40:43 +01:00
										 |  |  | PCIDevice *pci_new_multifunction(int devfn, const char *name); | 
					
						
							| 
									
										
										
										
											2020-06-10 07:32:02 +02:00
										 |  |  | PCIDevice *pci_new(int devfn, const char *name); | 
					
						
							|  |  |  | bool pci_realize_and_unref(PCIDevice *dev, PCIBus *bus, Error **errp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-23 16:15:30 +09:00
										 |  |  | PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn, | 
					
						
							|  |  |  |                                            const char *name); | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:07 +01:00
										 |  |  | PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-19 18:20:57 +01:00
										 |  |  | void lsi53c8xx_handle_legacy_cmdline(DeviceState *lsi_dev); | 
					
						
							| 
									
										
										
										
											2017-02-15 13:18:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-07 10:36:35 +03:00
										 |  |  | qemu_irq pci_allocate_irq(PCIDevice *pci_dev); | 
					
						
							|  |  |  | void pci_set_irq(PCIDevice *pci_dev, int level); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void pci_irq_assert(PCIDevice *pci_dev) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     pci_set_irq(pci_dev, 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void pci_irq_deassert(PCIDevice *pci_dev) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     pci_set_irq(pci_dev, 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * FIXME: PCI does not work this way. | 
					
						
							|  |  |  |  * All the callers to this method should be fixed. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline void pci_irq_pulse(PCIDevice *pci_dev) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     pci_irq_assert(pci_dev); | 
					
						
							|  |  |  |     pci_irq_deassert(pci_dev); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-14 13:56:32 +08:00
										 |  |  | MSIMessage pci_get_msi_message(PCIDevice *dev, int vector); | 
					
						
							| 
									
										
										
										
											2024-08-01 03:44:50 -04:00
										 |  |  | void pci_set_power(PCIDevice *pci_dev, bool state); | 
					
						
							| 
									
										
										
										
											2024-08-01 03:44:42 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | #endif
 |