mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-29 21:33:53 -06:00
vfio/igd: canonicalize memory size calculations
Add helper functions igd_gtt_memory_size() and igd_stolen_size() for calculating GTT stolen memory and Data stolen memory size in bytes, and use macros to replace the hardware-related magic numbers for better readability. Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com> Reviewed-by: Alex Williamson <alex.williamson@redhat.com> Link: https://lore.kernel.org/r/20241206122749.9893-5-tomitamoeko@gmail.com Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
parent
0bb758e97a
commit
1e1eac5f3d
1 changed files with 57 additions and 44 deletions
101
hw/vfio/igd.c
101
hw/vfio/igd.c
|
@ -107,6 +107,53 @@ typedef struct VFIOIGDQuirk {
|
|||
#define IGD_BDSM 0x5c /* Base Data of Stolen Memory */
|
||||
#define IGD_BDSM_GEN11 0xc0 /* Base Data of Stolen Memory of gen 11 and later */
|
||||
|
||||
#define IGD_GMCH_GEN6_GMS_SHIFT 3 /* SNB_GMCH in i915 */
|
||||
#define IGD_GMCH_GEN6_GMS_MASK 0x1f
|
||||
#define IGD_GMCH_GEN6_GGMS_SHIFT 8
|
||||
#define IGD_GMCH_GEN6_GGMS_MASK 0x3
|
||||
#define IGD_GMCH_GEN8_GMS_SHIFT 8 /* BDW_GMCH in i915 */
|
||||
#define IGD_GMCH_GEN8_GMS_MASK 0xff
|
||||
#define IGD_GMCH_GEN8_GGMS_SHIFT 6
|
||||
#define IGD_GMCH_GEN8_GGMS_MASK 0x3
|
||||
|
||||
static uint64_t igd_gtt_memory_size(int gen, uint16_t gmch)
|
||||
{
|
||||
uint64_t ggms;
|
||||
|
||||
if (gen < 8) {
|
||||
ggms = (gmch >> IGD_GMCH_GEN6_GGMS_SHIFT) & IGD_GMCH_GEN6_GGMS_MASK;
|
||||
} else {
|
||||
ggms = (gmch >> IGD_GMCH_GEN8_GGMS_SHIFT) & IGD_GMCH_GEN8_GGMS_MASK;
|
||||
if (ggms != 0) {
|
||||
ggms = 1 << ggms;
|
||||
}
|
||||
}
|
||||
|
||||
return ggms * MiB;
|
||||
}
|
||||
|
||||
static uint64_t igd_stolen_memory_size(int gen, uint32_t gmch)
|
||||
{
|
||||
uint64_t gms;
|
||||
|
||||
if (gen < 8) {
|
||||
gms = (gmch >> IGD_GMCH_GEN6_GMS_SHIFT) & IGD_GMCH_GEN6_GMS_MASK;
|
||||
} else {
|
||||
gms = (gmch >> IGD_GMCH_GEN8_GMS_SHIFT) & IGD_GMCH_GEN8_GMS_MASK;
|
||||
}
|
||||
|
||||
if (gen < 9) {
|
||||
return gms * 32 * MiB;
|
||||
} else {
|
||||
if (gms < 0xf0) {
|
||||
return gms * 32 * MiB;
|
||||
} else {
|
||||
return (gms - 0xf0 + 1) * 4 * MiB;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The rather short list of registers that we copy from the host devices.
|
||||
|
@ -255,17 +302,10 @@ static int vfio_pci_igd_lpc_init(VFIOPCIDevice *vdev,
|
|||
static int vfio_igd_gtt_max(VFIOPCIDevice *vdev)
|
||||
{
|
||||
uint32_t gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, sizeof(gmch));
|
||||
int ggms, gen = igd_gen(vdev);
|
||||
int gen = igd_gen(vdev);
|
||||
uint64_t ggms_size = igd_gtt_memory_size(gen, gmch);
|
||||
|
||||
gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, sizeof(gmch));
|
||||
ggms = (gmch >> (gen < 8 ? 8 : 6)) & 0x3;
|
||||
if (gen >= 8 && ggms != 0) {
|
||||
ggms = 1 << ggms;
|
||||
}
|
||||
|
||||
ggms *= MiB;
|
||||
|
||||
return (ggms / (4 * KiB)) * (gen < 8 ? 4 : 8);
|
||||
return (ggms_size / (4 * KiB)) * (gen < 8 ? 4 : 8);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -472,30 +512,6 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
|
|||
QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
|
||||
}
|
||||
|
||||
static int igd_get_stolen_mb(int gen, uint32_t gmch)
|
||||
{
|
||||
int gms;
|
||||
|
||||
if (gen < 8) {
|
||||
gms = (gmch >> 3) & 0x1f;
|
||||
} else {
|
||||
gms = (gmch >> 8) & 0xff;
|
||||
}
|
||||
|
||||
if (gen < 9) {
|
||||
if (gms > 0x10) {
|
||||
error_report("Unsupported IGD GMS value 0x%x", gms);
|
||||
return 0;
|
||||
}
|
||||
return gms * 32;
|
||||
} else {
|
||||
if (gms < 0xf0)
|
||||
return gms * 32;
|
||||
else
|
||||
return (gms - 0xf0) * 4 + 4;
|
||||
}
|
||||
}
|
||||
|
||||
void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
|
||||
{
|
||||
g_autofree struct vfio_region_info *rom = NULL;
|
||||
|
@ -505,7 +521,8 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
|
|||
VFIOQuirk *quirk;
|
||||
VFIOIGDQuirk *igd;
|
||||
PCIDevice *lpc_bridge;
|
||||
int i, ret, ggms_mb, gms_mb = 0, gen;
|
||||
int i, ret, gen;
|
||||
uint64_t ggms_size, gms_size;
|
||||
uint64_t *bdsm_size;
|
||||
uint32_t gmch;
|
||||
uint16_t cmd_orig, cmd;
|
||||
|
@ -667,13 +684,8 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
|
|||
|
||||
QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
|
||||
|
||||
/* Determine the size of stolen memory needed for GTT */
|
||||
ggms_mb = (gmch >> (gen < 8 ? 8 : 6)) & 0x3;
|
||||
if (gen >= 8 && ggms_mb != 0) {
|
||||
ggms_mb = 1 << ggms_mb;
|
||||
}
|
||||
|
||||
gms_mb = igd_get_stolen_mb(gen, gmch);
|
||||
ggms_size = igd_gtt_memory_size(gen, gmch);
|
||||
gms_size = igd_stolen_memory_size(gen, gmch);
|
||||
|
||||
/*
|
||||
* Request reserved memory for stolen memory via fw_cfg. VM firmware
|
||||
|
@ -684,7 +696,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
|
|||
* config offset 0x5C.
|
||||
*/
|
||||
bdsm_size = g_malloc(sizeof(*bdsm_size));
|
||||
*bdsm_size = cpu_to_le64((ggms_mb + gms_mb) * MiB);
|
||||
*bdsm_size = cpu_to_le64(ggms_size + gms_size);
|
||||
fw_cfg_add_file(fw_cfg_find(), "etc/igd-bdsm-size",
|
||||
bdsm_size, sizeof(*bdsm_size));
|
||||
|
||||
|
@ -735,5 +747,6 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
|
|||
vdev->vbasedev.name);
|
||||
}
|
||||
|
||||
trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, ggms_mb + gms_mb);
|
||||
trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name,
|
||||
(ggms_size + gms_size) / MiB);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue