mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-31 14:23:53 -06:00
vfio/igd: add macro for declaring mirrored registers
igd devices have multipe registers mirroring mmio address and pci config space, more than a single BDSM register. To support this, the read/write functions are made common and a macro is defined to simplify the declaration of MemoryRegionOps. Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com> Reviewed-by: Alex Williamson <alex.williamson@redhat.com> Link: https://lore.kernel.org/r/20241206122749.9893-8-tomitamoeko@gmail.com [ clg : Fixed conversion specifier on 32-bit platform ] Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
parent
960f62770a
commit
1a2623b5c9
1 changed files with 36 additions and 24 deletions
|
@ -421,16 +421,9 @@ static const MemoryRegionOps vfio_igd_index_quirk = {
|
||||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IGD_BDSM_MMIO_OFFSET 0x1080C0
|
static uint64_t vfio_igd_pci_config_read(VFIOPCIDevice *vdev, uint64_t offset,
|
||||||
|
unsigned size)
|
||||||
static uint64_t vfio_igd_quirk_bdsm_read(void *opaque,
|
|
||||||
hwaddr addr, unsigned size)
|
|
||||||
{
|
{
|
||||||
VFIOPCIDevice *vdev = opaque;
|
|
||||||
uint64_t offset;
|
|
||||||
|
|
||||||
offset = IGD_BDSM_GEN11 + addr;
|
|
||||||
|
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 1:
|
case 1:
|
||||||
return pci_get_byte(vdev->pdev.config + offset);
|
return pci_get_byte(vdev->pdev.config + offset);
|
||||||
|
@ -441,21 +434,17 @@ static uint64_t vfio_igd_quirk_bdsm_read(void *opaque,
|
||||||
case 8:
|
case 8:
|
||||||
return pci_get_quad(vdev->pdev.config + offset);
|
return pci_get_quad(vdev->pdev.config + offset);
|
||||||
default:
|
default:
|
||||||
hw_error("igd: unsupported read size, %u bytes", size);
|
hw_error("igd: unsupported pci config read at %"PRIx64", size %u",
|
||||||
|
offset, size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vfio_igd_quirk_bdsm_write(void *opaque, hwaddr addr,
|
static void vfio_igd_pci_config_write(VFIOPCIDevice *vdev, uint64_t offset,
|
||||||
uint64_t data, unsigned size)
|
uint64_t data, unsigned size)
|
||||||
{
|
{
|
||||||
VFIOPCIDevice *vdev = opaque;
|
|
||||||
uint64_t offset;
|
|
||||||
|
|
||||||
offset = IGD_BDSM_GEN11 + addr;
|
|
||||||
|
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 1:
|
case 1:
|
||||||
pci_set_byte(vdev->pdev.config + offset, data);
|
pci_set_byte(vdev->pdev.config + offset, data);
|
||||||
|
@ -470,17 +459,39 @@ static void vfio_igd_quirk_bdsm_write(void *opaque, hwaddr addr,
|
||||||
pci_set_quad(vdev->pdev.config + offset, data);
|
pci_set_quad(vdev->pdev.config + offset, data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
hw_error("igd: unsupported read size, %u bytes", size);
|
hw_error("igd: unsupported pci config write at %"PRIx64", size %u",
|
||||||
|
offset, size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const MemoryRegionOps vfio_igd_bdsm_quirk = {
|
#define VFIO_IGD_QUIRK_MIRROR_REG(reg, name) \
|
||||||
.read = vfio_igd_quirk_bdsm_read,
|
static uint64_t vfio_igd_quirk_read_##name(void *opaque, \
|
||||||
.write = vfio_igd_quirk_bdsm_write,
|
hwaddr addr, unsigned size) \
|
||||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
{ \
|
||||||
|
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_BDSM_GEN11, bdsm)
|
||||||
|
|
||||||
|
#define IGD_BDSM_MMIO_OFFSET 0x1080C0
|
||||||
|
|
||||||
void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
|
void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
|
||||||
{
|
{
|
||||||
VFIOQuirk *quirk;
|
VFIOQuirk *quirk;
|
||||||
|
@ -510,8 +521,9 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
|
||||||
quirk = vfio_quirk_alloc(1);
|
quirk = vfio_quirk_alloc(1);
|
||||||
quirk->data = vdev;
|
quirk->data = vdev;
|
||||||
|
|
||||||
memory_region_init_io(&quirk->mem[0], OBJECT(vdev), &vfio_igd_bdsm_quirk,
|
memory_region_init_io(&quirk->mem[0], OBJECT(vdev),
|
||||||
vdev, "vfio-igd-bdsm-quirk", 8);
|
&vfio_igd_quirk_mirror_bdsm, vdev,
|
||||||
|
"vfio-igd-bdsm-quirk", 8);
|
||||||
memory_region_add_subregion_overlap(vdev->bars[0].region.mem,
|
memory_region_add_subregion_overlap(vdev->bars[0].region.mem,
|
||||||
IGD_BDSM_MMIO_OFFSET, &quirk->mem[0],
|
IGD_BDSM_MMIO_OFFSET, &quirk->mem[0],
|
||||||
1);
|
1);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue