Skip to content

Commit

Permalink
Merge tag 'gpu-pull-request' of https://gitlab.com/marcandre.lureau/qemu
Browse files Browse the repository at this point in the history
 into staging

GPU pull request

Includes:
- [PATCH] virtio-gpu-rutabaga: Add empty interface to fix arm64 crash
- [PATCH v2 0/4] Misc ati-vga patches
- [PATCH v2 0/5] virtio-gpu: add blob migration support

# -----BEGIN PGP SIGNATURE-----
#
# iQJQBAABCAA6FiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmVI6rYcHG1hcmNhbmRy
# ZS5sdXJlYXVAcmVkaGF0LmNvbQAKCRDa6OEJdZac5VdjEAC6xsnITkX5FgJVjDo2
# XQWGz2MgWIFcqMXYVbz21UgY86KjCE7jVbGL6BkWO8N/XzsP6EUEIcUcHm7KcdwU
# +csMTjgnZUb97Ov/d27Ge9UYr/9rgozyoQRwvvQYXRFfxTur+b+poodcAOn3Ml3Q
# vXBTYb0z2FYd85VcVx59w5lFlonER1z4wnQuF4GLCBNIW/GX+S87+xyv1FZCgWku
# luBhWa7ihVrlrYA2UaoQS7sI2ch/wI9NnfP1p+31Iy/w1wLwQOj9ofTslbehTcvS
# uDU/+WMkhmlB8LOl7mx8bGHeBab9iUvSz5H5MIfTgrk6hRaaMJp3y2lefsc9cWuA
# 5aPvj0qouTEkIZ+2aPClcZk11mIbH5lT9eeEYc16Ztrt5VJHXmR7RwF74hHQbxY3
# LDiRlpvhBfX4muaPw4L1max9kJZdOvo9aQVqKL7hkrTBL/xBmvg40ZRrWDrIvZZg
# 8TZ8woD2ORiic/hTxmI7waG+f3WozH/drStJrOFpJA7+iFefrHgkv2K7ze9LhWmZ
# ookM8K96NV6AnPQ39N2nuvQ/Fndqv7Kg4AiOwzj3epfg/rDscaJw9J2JQuCGEiEF
# KEIt3hyIo/HOXXiwmGqP3BWs90EmMvZTDmAt5e/cT0eQ1jWwJ3Tj8ShVg2S8QW0h
# TMXdPV7bepd49aaynpGFeADhfw==
# =k/gN
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 06 Nov 2023 21:31:34 HKT
# gpg:                using RSA key 87A9BD933F87C606D276F62DDAE8E10975969CE5
# gpg:                issuer "marcandre.lureau@redhat.com"
# gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>" [full]
# gpg:                 aka "Marc-André Lureau <marcandre.lureau@gmail.com>" [full]
# Primary key fingerprint: 87A9 BD93 3F87 C606 D276  F62D DAE8 E109 7596 9CE5

* tag 'gpu-pull-request' of https://gitlab.com/marcandre.lureau/qemu:
  Revert "virtio-gpu: block migration of VMs with blob=true"
  virtio-gpu: add virtio-gpu/blob vmstate subsection
  virtio-gpu: move scanout restoration to post_load
  virtio-gpu: factor out restore mapping
  virtio-gpu: block migration of VMs with blob=true
  ati-vga: Implement fallback for pixman routines
  ati-vga: Add 30 bit palette access register
  ati-vga: Support unaligned access to GPIO DDC registers
  ati-vga: Fix aperture sizes
  virtio-gpu-rutabaga: Add empty interface to fix arm64 crash

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
stefanhaRH committed Nov 7, 2023
2 parents b09627b + 10b9ddb commit 2ca06f8
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 67 deletions.
61 changes: 44 additions & 17 deletions hw/display/ati.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,11 +319,13 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
case DAC_CNTL:
val = s->regs.dac_cntl;
break;
case GPIO_VGA_DDC:
val = s->regs.gpio_vga_ddc;
case GPIO_VGA_DDC ... GPIO_VGA_DDC + 3:
val = ati_reg_read_offs(s->regs.gpio_vga_ddc,
addr - GPIO_VGA_DDC, size);
break;
case GPIO_DVI_DDC:
val = s->regs.gpio_dvi_ddc;
case GPIO_DVI_DDC ... GPIO_DVI_DDC + 3:
val = ati_reg_read_offs(s->regs.gpio_dvi_ddc,
addr - GPIO_DVI_DDC, size);
break;
case GPIO_MONID ... GPIO_MONID + 3:
val = ati_reg_read_offs(s->regs.gpio_monid,
Expand All @@ -337,6 +339,9 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
case PALETTE_DATA:
val = vga_ioport_read(&s->vga, VGA_PEL_D);
break;
case PALETTE_30_DATA:
val = s->regs.palette[vga_ioport_read(&s->vga, VGA_PEL_IR)];
break;
case CNFG_CNTL:
val = s->regs.config_cntl;
break;
Expand All @@ -349,14 +354,17 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
PCI_BASE_ADDRESS_0, size) & 0xfffffff0;
break;
case CONFIG_APER_SIZE:
val = s->vga.vram_size;
val = s->vga.vram_size / 2;
break;
case CONFIG_REG_1_BASE:
val = pci_default_read_config(&s->dev,
PCI_BASE_ADDRESS_2, size) & 0xfffffff0;
break;
case CONFIG_REG_APER_SIZE:
val = memory_region_size(&s->mm);
val = memory_region_size(&s->mm) / 2;
break;
case HOST_PATH_CNTL:
val = BIT(23); /* Radeon HDP_APER_CNTL */
break;
case MC_STATUS:
val = 5;
Expand Down Expand Up @@ -612,29 +620,34 @@ static void ati_mm_write(void *opaque, hwaddr addr,
s->regs.dac_cntl = data & 0xffffe3ff;
s->vga.dac_8bit = !!(data & DAC_8BIT_EN);
break;
case GPIO_VGA_DDC:
/*
* GPIO regs for DDC access. Because some drivers access these via
* multiple byte writes we have to be careful when we send bits to
* avoid spurious changes in bitbang_i2c state. Only do it when either
* the enable bits are changed or output bits changed while enabled.
*/
case GPIO_VGA_DDC ... GPIO_VGA_DDC + 3:
if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) {
/* FIXME: Maybe add a property to select VGA or DVI port? */
}
break;
case GPIO_DVI_DDC:
case GPIO_DVI_DDC ... GPIO_DVI_DDC + 3:
if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) {
s->regs.gpio_dvi_ddc = ati_i2c(&s->bbi2c, data, 0);
ati_reg_write_offs(&s->regs.gpio_dvi_ddc,
addr - GPIO_DVI_DDC, data, size);
if ((addr <= GPIO_DVI_DDC + 2 && addr + size > GPIO_DVI_DDC + 2) ||
(addr == GPIO_DVI_DDC && (s->regs.gpio_dvi_ddc & 0x30000))) {
s->regs.gpio_dvi_ddc = ati_i2c(&s->bbi2c,
s->regs.gpio_dvi_ddc, 0);
}
}
break;
case GPIO_MONID ... GPIO_MONID + 3:
/* FIXME What does Radeon have here? */
if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
/* Rage128p accesses DDC via MONID(1-2) with additional mask bit */
ati_reg_write_offs(&s->regs.gpio_monid,
addr - GPIO_MONID, data, size);
/*
* Rage128p accesses DDC used to get EDID via these bits.
* Because some drivers access this via multiple byte writes
* we have to be careful when we send bits to avoid spurious
* changes in bitbang_i2c state. So only do it when mask is set
* and either the enable bits are changed or output bits changed
* while enabled.
*/
if ((s->regs.gpio_monid & BIT(25)) &&
((addr <= GPIO_MONID + 2 && addr + size > GPIO_MONID + 2) ||
(addr == GPIO_MONID && (s->regs.gpio_monid & 0x60000)))) {
Expand Down Expand Up @@ -663,6 +676,12 @@ static void ati_mm_write(void *opaque, hwaddr addr,
data >>= 8;
vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff);
break;
case PALETTE_30_DATA:
s->regs.palette[vga_ioport_read(&s->vga, VGA_PEL_IW)] = data;
vga_ioport_write(&s->vga, VGA_PEL_D, (data >> 22) & 0xff);
vga_ioport_write(&s->vga, VGA_PEL_D, (data >> 12) & 0xff);
vga_ioport_write(&s->vga, VGA_PEL_D, (data >> 2) & 0xff);
break;
case CNFG_CNTL:
s->regs.config_cntl = data;
break;
Expand Down Expand Up @@ -1014,6 +1033,7 @@ static Property ati_vga_properties[] = {
DEFINE_PROP_UINT16("x-device-id", ATIVGAState, dev_id,
PCI_DEVICE_ID_ATI_RAGE128_PF),
DEFINE_PROP_BOOL("guest_hwcursor", ATIVGAState, cursor_guest_mode, false),
DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, 3),
DEFINE_PROP_END_OF_LIST()
};

Expand All @@ -1035,11 +1055,18 @@ static void ati_vga_class_init(ObjectClass *klass, void *data)
k->exit = ati_vga_exit;
}

static void ati_vga_init(Object *o)
{
object_property_set_description(o, "x-pixman", "Use pixman for: "
"1: fill, 2: blit");
}

static const TypeInfo ati_vga_info = {
.name = TYPE_ATI_VGA,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(ATIVGAState),
.class_init = ati_vga_class_init,
.instance_init = ati_vga_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
Expand Down
75 changes: 53 additions & 22 deletions hw/display/ati_2d.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ void ati_2d_blt(ATIVGAState *s)
switch (s->regs.dp_mix & GMC_ROP3_MASK) {
case ROP3_SRCCOPY:
{
bool fallback = false;
unsigned src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width);
unsigned src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
Expand Down Expand Up @@ -122,27 +123,50 @@ void ati_2d_blt(ATIVGAState *s)
src_bits, dst_bits, src_stride, dst_stride, bpp, bpp,
src_x, src_y, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height);
if (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT &&
if ((s->use_pixman & BIT(1)) &&
s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT &&
s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM) {
pixman_blt((uint32_t *)src_bits, (uint32_t *)dst_bits,
src_stride, dst_stride, bpp, bpp,
src_x, src_y, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height);
} else {
fallback = !pixman_blt((uint32_t *)src_bits, (uint32_t *)dst_bits,
src_stride, dst_stride, bpp, bpp,
src_x, src_y, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height);
} else if (s->use_pixman & BIT(1)) {
/* FIXME: We only really need a temporary if src and dst overlap */
int llb = s->regs.dst_width * (bpp / 8);
int tmp_stride = DIV_ROUND_UP(llb, sizeof(uint32_t));
uint32_t *tmp = g_malloc(tmp_stride * sizeof(uint32_t) *
s->regs.dst_height);
pixman_blt((uint32_t *)src_bits, tmp,
src_stride, tmp_stride, bpp, bpp,
src_x, src_y, 0, 0,
s->regs.dst_width, s->regs.dst_height);
pixman_blt(tmp, (uint32_t *)dst_bits,
tmp_stride, dst_stride, bpp, bpp,
0, 0, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height);
fallback = !pixman_blt((uint32_t *)src_bits, tmp,
src_stride, tmp_stride, bpp, bpp,
src_x, src_y, 0, 0,
s->regs.dst_width, s->regs.dst_height);
if (!fallback) {
fallback = !pixman_blt(tmp, (uint32_t *)dst_bits,
tmp_stride, dst_stride, bpp, bpp,
0, 0, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height);
}
g_free(tmp);
} else {
fallback = true;
}
if (fallback) {
unsigned int y, i, j, bypp = bpp / 8;
unsigned int src_pitch = src_stride * sizeof(uint32_t);
unsigned int dst_pitch = dst_stride * sizeof(uint32_t);

for (y = 0; y < s->regs.dst_height; y++) {
i = dst_x * bypp;
j = src_x * bypp;
if (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM) {
i += (dst_y + y) * dst_pitch;
j += (src_y + y) * src_pitch;
} else {
i += (dst_y + s->regs.dst_height - 1 - y) * dst_pitch;
j += (src_y + s->regs.dst_height - 1 - y) * src_pitch;
}
memmove(&dst_bits[i], &src_bits[j], s->regs.dst_width * bypp);
}
}
if (dst_bits >= s->vga.vram_ptr + s->vga.vbe_start_addr &&
dst_bits < s->vga.vram_ptr + s->vga.vbe_start_addr +
Expand Down Expand Up @@ -180,14 +204,21 @@ void ati_2d_blt(ATIVGAState *s)

dst_stride /= sizeof(uint32_t);
DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n",
dst_bits, dst_stride, bpp,
dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height,
filler);
pixman_fill((uint32_t *)dst_bits, dst_stride, bpp,
dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height,
filler);
dst_bits, dst_stride, bpp, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height, filler);
if (!(s->use_pixman & BIT(0)) ||
!pixman_fill((uint32_t *)dst_bits, dst_stride, bpp, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height, filler)) {
/* fallback when pixman failed or we don't want to call it */
unsigned int x, y, i, bypp = bpp / 8;
unsigned int dst_pitch = dst_stride * sizeof(uint32_t);
for (y = 0; y < s->regs.dst_height; y++) {
i = dst_x * bypp + (dst_y + y) * dst_pitch;
for (x = 0; x < s->regs.dst_width; x++, i += bypp) {
stn_he_p(&dst_bits[i], bypp, filler);
}
}
}
if (dst_bits >= s->vga.vram_ptr + s->vga.vbe_start_addr &&
dst_bits < s->vga.vram_ptr + s->vga.vbe_start_addr +
s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] * s->vga.vbe_line_offset) {
Expand Down
2 changes: 2 additions & 0 deletions hw/display/ati_dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ static struct ati_regdesc ati_reg_names[] = {
{"AMCGPIO_EN_MIR", 0x00a8},
{"PALETTE_INDEX", 0x00b0},
{"PALETTE_DATA", 0x00b4},
{"PALETTE_30_DATA", 0x00b8},
{"CNFG_CNTL", 0x00e0},
{"GEN_RESET_CNTL", 0x00f0},
{"CNFG_MEMSIZE", 0x00f8},
Expand All @@ -38,6 +39,7 @@ static struct ati_regdesc ati_reg_names[] = {
{"CONFIG_APER_SIZE", 0x0108},
{"CONFIG_REG_1_BASE", 0x010c},
{"CONFIG_REG_APER_SIZE", 0x0110},
{"HOST_PATH_CNTL", 0x0130},
{"MEM_CNTL", 0x0140},
{"MC_FB_LOCATION", 0x0148},
{"MC_AGP_LOCATION", 0x014C},
Expand Down
2 changes: 2 additions & 0 deletions hw/display/ati_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ typedef struct ATIVGARegs {
uint32_t gpio_dvi_ddc;
uint32_t gpio_monid;
uint32_t config_cntl;
uint32_t palette[256];
uint32_t crtc_h_total_disp;
uint32_t crtc_h_sync_strt_wid;
uint32_t crtc_v_total_disp;
Expand Down Expand Up @@ -89,6 +90,7 @@ struct ATIVGAState {
char *model;
uint16_t dev_id;
uint8_t mode;
uint8_t use_pixman;
bool cursor_guest_mode;
uint16_t cursor_size;
uint32_t cursor_offset;
Expand Down
2 changes: 2 additions & 0 deletions hw/display/ati_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#define AMCGPIO_EN_MIR 0x00a8
#define PALETTE_INDEX 0x00b0
#define PALETTE_DATA 0x00b4
#define PALETTE_30_DATA 0x00b8
#define CNFG_CNTL 0x00e0
#define GEN_RESET_CNTL 0x00f0
#define CNFG_MEMSIZE 0x00f8
Expand All @@ -56,6 +57,7 @@
#define CONFIG_APER_SIZE 0x0108
#define CONFIG_REG_1_BASE 0x010c
#define CONFIG_REG_APER_SIZE 0x0110
#define HOST_PATH_CNTL 0x0130
#define MEM_CNTL 0x0140
#define MC_FB_LOCATION 0x0148
#define MC_AGP_LOCATION 0x014C
Expand Down
1 change: 1 addition & 0 deletions hw/display/virtio-gpu-pci-rutabaga.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ static const TypeInfo virtio_gpu_rutabaga_pci_info[] = {
.instance_init = virtio_gpu_rutabaga_initfn,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
}
},
};
Expand Down

0 comments on commit 2ca06f8

Please sign in to comment.