summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'hw/device-assignment.c')
-rw-r--r--hw/device-assignment.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/hw/device-assignment.c b/hw/device-assignment.c
index b9b955b31..da50069d8 100644
--- a/hw/device-assignment.c
+++ b/hw/device-assignment.c
@@ -28,6 +28,7 @@
#include <stdio.h>
#include <unistd.h>
#include <sys/io.h>
+#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "qemu-kvm.h"
@@ -40,6 +41,7 @@
#include "monitor.h"
#include "range.h"
#include "sysemu.h"
+#include "pci.h"
#define MSIX_PAGE_SIZE 0x1000
@@ -61,6 +63,94 @@
#define DEBUG(fmt, ...) do { } while(0)
#endif
+typedef struct PCIHostDevice {
+ int seg;
+ int bus;
+ int dev;
+ int func;
+} PCIHostDevice;
+
+typedef struct {
+ int type; /* Memory or port I/O */
+ int valid;
+ uint32_t base_addr;
+ uint32_t size; /* size of the region */
+ int resource_fd;
+} PCIRegion;
+
+typedef struct {
+ uint8_t bus, dev, func; /* Bus inside domain, device and function */
+ int irq; /* IRQ number */
+ uint16_t region_number; /* number of active regions */
+
+ /* Port I/O or MMIO Regions */
+ PCIRegion regions[PCI_NUM_REGIONS - 1];
+ int config_fd;
+} PCIDevRegions;
+
+typedef struct {
+ MemoryRegion container;
+ MemoryRegion real_iomem;
+ union {
+ void *r_virtbase; /* mmapped access address for memory regions */
+ uint32_t r_baseport; /* the base guest port for I/O regions */
+ } u;
+ int num; /* our index within v_addrs[] */
+ pcibus_t e_size; /* emulated size of region in bytes */
+ pcibus_t r_size; /* real size of region in bytes */
+ PCIRegion *region;
+} AssignedDevRegion;
+
+#define ASSIGNED_DEVICE_PREFER_MSI_BIT 0
+#define ASSIGNED_DEVICE_SHARE_INTX_BIT 1
+
+#define ASSIGNED_DEVICE_PREFER_MSI_MASK (1 << ASSIGNED_DEVICE_PREFER_MSI_BIT)
+#define ASSIGNED_DEVICE_SHARE_INTX_MASK (1 << ASSIGNED_DEVICE_SHARE_INTX_BIT)
+
+typedef struct {
+ uint32_t addr_lo;
+ uint32_t addr_hi;
+ uint32_t data;
+ uint32_t ctrl;
+} MSIXTableEntry;
+
+typedef struct AssignedDevice {
+ PCIDevice dev;
+ PCIHostDevice host;
+ uint32_t features;
+ int intpin;
+ uint8_t debug_flags;
+ AssignedDevRegion v_addrs[PCI_NUM_REGIONS - 1];
+ PCIDevRegions real_device;
+ int run;
+ int girq;
+ uint16_t h_segnr;
+ uint8_t h_busnr;
+ uint8_t h_devfn;
+ int irq_requested_type;
+ int bound;
+ struct {
+#define ASSIGNED_DEVICE_CAP_MSI (1 << 0)
+#define ASSIGNED_DEVICE_CAP_MSIX (1 << 1)
+ uint32_t available;
+#define ASSIGNED_DEVICE_MSI_ENABLED (1 << 0)
+#define ASSIGNED_DEVICE_MSIX_ENABLED (1 << 1)
+#define ASSIGNED_DEVICE_MSIX_MASKED (1 << 2)
+ uint32_t state;
+ } cap;
+ uint8_t emulate_config_read[PCI_CONFIG_SPACE_SIZE];
+ uint8_t emulate_config_write[PCI_CONFIG_SPACE_SIZE];
+ int irq_entries_nr;
+ struct kvm_irq_routing_entry *entry;
+ MSIXTableEntry *msix_table;
+ target_phys_addr_t msix_table_addr;
+ uint16_t msix_max;
+ MemoryRegion mmio;
+ char *configfd_name;
+ int32_t bootindex;
+ QLIST_ENTRY(AssignedDevice) next;
+} AssignedDevice;
+
static void assigned_dev_load_option_rom(AssignedDevice *dev);
static void assigned_dev_unregister_msix_mmio(AssignedDevice *dev);