[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 3/3] vfio/igd: use VFIOConfigMirrorQuirk for mirrored registers
From: |
Tomita Moeko |
Subject: |
[PATCH 3/3] vfio/igd: use VFIOConfigMirrorQuirk for mirrored registers |
Date: |
Tue, 31 Dec 2024 23:19:53 +0800 |
With the introduction of config_offset field, VFIOConfigMirrorQuirk can
now be used for those mirrored register in igd bar0. This eliminates
the need for the macro intoduced in 1a2623b5c9e7 ("vfio/igd: add macro
for declaring mirrored registers").
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
---
hw/vfio/igd.c | 128 ++++++++++++++------------------------------------
1 file changed, 36 insertions(+), 92 deletions(-)
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index f5414b0f8d..28a1d17f01 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -18,6 +18,7 @@
#include "hw/hw.h"
#include "hw/nvram/fw_cfg.h"
#include "pci.h"
+#include "pci-quirks.h"
#include "trace.h"
/*
@@ -422,84 +423,21 @@ static const MemoryRegionOps vfio_igd_index_quirk = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
-static uint64_t vfio_igd_pci_config_read(VFIOPCIDevice *vdev, uint64_t offset,
- unsigned size)
-{
- switch (size) {
- case 1:
- return pci_get_byte(vdev->pdev.config + offset);
- case 2:
- return pci_get_word(vdev->pdev.config + offset);
- case 4:
- return pci_get_long(vdev->pdev.config + offset);
- case 8:
- return pci_get_quad(vdev->pdev.config + offset);
- default:
- hw_error("igd: unsupported pci config read at %"PRIx64", size %u",
- offset, size);
- break;
- }
-
- return 0;
-}
-
-static void vfio_igd_pci_config_write(VFIOPCIDevice *vdev, uint64_t offset,
- uint64_t data, unsigned size)
-{
- switch (size) {
- case 1:
- pci_set_byte(vdev->pdev.config + offset, data);
- break;
- case 2:
- pci_set_word(vdev->pdev.config + offset, data);
- break;
- case 4:
- pci_set_long(vdev->pdev.config + offset, data);
- break;
- case 8:
- pci_set_quad(vdev->pdev.config + offset, data);
- break;
- default:
- hw_error("igd: unsupported pci config write at %"PRIx64", size %u",
- offset, size);
- break;
- }
-}
-
-#define VFIO_IGD_QUIRK_MIRROR_REG(reg, name) \
-static uint64_t vfio_igd_quirk_read_##name(void *opaque, \
- hwaddr addr, unsigned size) \
-{ \
- VFIOPCIDevice *vdev = opaque; \
- \
- return vfio_igd_pci_config_read(vdev, reg + addr, size); \
-} \
- \
-static void vfio_igd_quirk_write_##name(void *opaque, hwaddr addr, \
- uint64_t data, unsigned size) \
-{ \
- VFIOPCIDevice *vdev = opaque; \
- \
- vfio_igd_pci_config_write(vdev, reg + addr, data, size); \
-} \
- \
-static const MemoryRegionOps vfio_igd_quirk_mirror_##name = { \
- .read = vfio_igd_quirk_read_##name, \
- .write = vfio_igd_quirk_write_##name, \
- .endianness = DEVICE_LITTLE_ENDIAN, \
-};
-
-VFIO_IGD_QUIRK_MIRROR_REG(IGD_GMCH, ggc)
-VFIO_IGD_QUIRK_MIRROR_REG(IGD_BDSM, bdsm)
-VFIO_IGD_QUIRK_MIRROR_REG(IGD_BDSM_GEN11, bdsm64)
-
#define IGD_GGC_MMIO_OFFSET 0x108040
#define IGD_BDSM_MMIO_OFFSET 0x1080C0
+typedef struct VFIOIGDBAR0Quirk {
+ VFIOConfigMirrorQuirk ggc_mirror;
+ VFIOConfigMirrorQuirk bdsm_mirror;
+} VFIOIGDBAR0Quirk;
+
void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
{
VFIOQuirk *quirk;
+ VFIOIGDBAR0Quirk *bar0;
+ VFIOConfigMirrorQuirk *ggc_mirror, *bdsm_mirror;
int gen;
+ uint32_t bdsm_reg_size;
/*
* This must be an Intel VGA device at address 00:02.0 for us to even
@@ -523,30 +461,36 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int
nr)
}
quirk = vfio_quirk_alloc(2);
- quirk->data = vdev;
-
- memory_region_init_io(&quirk->mem[0], OBJECT(vdev),
- &vfio_igd_quirk_mirror_ggc, vdev,
+ bar0 = quirk->data = g_malloc0(sizeof(*bar0));
+
+ ggc_mirror = &bar0->ggc_mirror;
+ ggc_mirror->vdev = vdev;
+ ggc_mirror->mem = &quirk->mem[0];
+ ggc_mirror->bar = nr;
+ ggc_mirror->offset = IGD_GGC_MMIO_OFFSET;
+ ggc_mirror->config_offset = IGD_GMCH;
+
+ bdsm_mirror = &bar0->bdsm_mirror;
+ bdsm_mirror->mem = &quirk->mem[1];
+ bdsm_mirror->vdev = vdev;
+ bdsm_mirror->offset = IGD_BDSM_MMIO_OFFSET;
+ bdsm_mirror->config_offset = (gen < 11) ? IGD_BDSM : IGD_BDSM_GEN11;
+ bdsm_mirror->bar = nr;
+ bdsm_reg_size = (gen < 11) ? 4 : 8;
+
+ memory_region_init_io(ggc_mirror->mem, OBJECT(vdev),
+ &vfio_generic_mirror_quirk, ggc_mirror,
"vfio-igd-ggc-quirk", 2);
- memory_region_add_subregion_overlap(vdev->bars[0].region.mem,
- IGD_GGC_MMIO_OFFSET, &quirk->mem[0],
+ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem,
+ ggc_mirror->offset, ggc_mirror->mem,
1);
- if (gen < 11) {
- memory_region_init_io(&quirk->mem[1], OBJECT(vdev),
- &vfio_igd_quirk_mirror_bdsm, vdev,
- "vfio-igd-bdsm-quirk", 4);
- memory_region_add_subregion_overlap(vdev->bars[0].region.mem,
- IGD_BDSM_MMIO_OFFSET,
- &quirk->mem[1], 1);
- } else {
- memory_region_init_io(&quirk->mem[1], OBJECT(vdev),
- &vfio_igd_quirk_mirror_bdsm64, vdev,
- "vfio-igd-bdsm-quirk", 8);
- memory_region_add_subregion_overlap(vdev->bars[0].region.mem,
- IGD_BDSM_MMIO_OFFSET,
- &quirk->mem[1], 1);
- }
+ memory_region_init_io(bdsm_mirror->mem, OBJECT(vdev),
+ &vfio_generic_mirror_quirk, bdsm_mirror,
+ "vfio-igd-bdsm-quirk", bdsm_reg_size);
+ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem,
+ bdsm_mirror->offset, bdsm_mirror->mem,
+ 1);
QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
}
--
2.45.2