|
@@ -25,6 +25,7 @@
|
|
|
#include "hw/nvram/fw_cfg.h"
|
|
|
#include "hw/qdev-properties.h"
|
|
|
#include "pci.h"
|
|
|
+#include "pci-quirks.h"
|
|
|
#include "trace.h"
|
|
|
|
|
|
/*
|
|
@@ -66,40 +67,6 @@ bool vfio_opt_rom_in_denylist(VFIOPCIDevice *vdev)
|
|
|
* Device specific region quirks (mostly backdoors to PCI config space)
|
|
|
*/
|
|
|
|
|
|
-/*
|
|
|
- * The generic window quirks operate on an address and data register,
|
|
|
- * vfio_generic_window_address_quirk handles the address register and
|
|
|
- * vfio_generic_window_data_quirk handles the data register. These ops
|
|
|
- * pass reads and writes through to hardware until a value matching the
|
|
|
- * stored address match/mask is written. When this occurs, the data
|
|
|
- * register access emulated PCI config space for the device rather than
|
|
|
- * passing through accesses. This enables devices where PCI config space
|
|
|
- * is accessible behind a window register to maintain the virtualization
|
|
|
- * provided through vfio.
|
|
|
- */
|
|
|
-typedef struct VFIOConfigWindowMatch {
|
|
|
- uint32_t match;
|
|
|
- uint32_t mask;
|
|
|
-} VFIOConfigWindowMatch;
|
|
|
-
|
|
|
-typedef struct VFIOConfigWindowQuirk {
|
|
|
- struct VFIOPCIDevice *vdev;
|
|
|
-
|
|
|
- uint32_t address_val;
|
|
|
-
|
|
|
- uint32_t address_offset;
|
|
|
- uint32_t data_offset;
|
|
|
-
|
|
|
- bool window_enabled;
|
|
|
- uint8_t bar;
|
|
|
-
|
|
|
- MemoryRegion *addr_mem;
|
|
|
- MemoryRegion *data_mem;
|
|
|
-
|
|
|
- uint32_t nr_matches;
|
|
|
- VFIOConfigWindowMatch matches[];
|
|
|
-} VFIOConfigWindowQuirk;
|
|
|
-
|
|
|
static uint64_t vfio_generic_window_quirk_address_read(void *opaque,
|
|
|
hwaddr addr,
|
|
|
unsigned size)
|
|
@@ -135,7 +102,7 @@ static void vfio_generic_window_quirk_address_write(void *opaque, hwaddr addr,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static const MemoryRegionOps vfio_generic_window_address_quirk = {
|
|
|
+const MemoryRegionOps vfio_generic_window_address_quirk = {
|
|
|
.read = vfio_generic_window_quirk_address_read,
|
|
|
.write = vfio_generic_window_quirk_address_write,
|
|
|
.endianness = DEVICE_LITTLE_ENDIAN,
|
|
@@ -178,26 +145,12 @@ static void vfio_generic_window_quirk_data_write(void *opaque, hwaddr addr,
|
|
|
addr + window->data_offset, data, size);
|
|
|
}
|
|
|
|
|
|
-static const MemoryRegionOps vfio_generic_window_data_quirk = {
|
|
|
+const MemoryRegionOps vfio_generic_window_data_quirk = {
|
|
|
.read = vfio_generic_window_quirk_data_read,
|
|
|
.write = vfio_generic_window_quirk_data_write,
|
|
|
.endianness = DEVICE_LITTLE_ENDIAN,
|
|
|
};
|
|
|
|
|
|
-/*
|
|
|
- * The generic mirror quirk handles devices which expose PCI config space
|
|
|
- * through a region within a BAR. When enabled, reads and writes are
|
|
|
- * redirected through to emulated PCI config space. XXX if PCI config space
|
|
|
- * used memory regions, this could just be an alias.
|
|
|
- */
|
|
|
-typedef struct VFIOConfigMirrorQuirk {
|
|
|
- struct VFIOPCIDevice *vdev;
|
|
|
- uint32_t offset;
|
|
|
- uint8_t bar;
|
|
|
- MemoryRegion *mem;
|
|
|
- uint8_t data[];
|
|
|
-} VFIOConfigMirrorQuirk;
|
|
|
-
|
|
|
static uint64_t vfio_generic_quirk_mirror_read(void *opaque,
|
|
|
hwaddr addr, unsigned size)
|
|
|
{
|
|
@@ -228,7 +181,7 @@ static void vfio_generic_quirk_mirror_write(void *opaque, hwaddr addr,
|
|
|
addr, data);
|
|
|
}
|
|
|
|
|
|
-static const MemoryRegionOps vfio_generic_mirror_quirk = {
|
|
|
+const MemoryRegionOps vfio_generic_mirror_quirk = {
|
|
|
.read = vfio_generic_quirk_mirror_read,
|
|
|
.write = vfio_generic_quirk_mirror_write,
|
|
|
.endianness = DEVICE_LITTLE_ENDIAN,
|