virtio-gpu: pci support bits and virtio-vga.

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJVfss3AAoJEEy22O7T6HE4gw8P/Az+6M0I6RRGoavyfC+Um1sy
 hD1VVFI34eLKxAgUupuwDMxnyXuZBbV0BZvyz46GucfcpsC038WCclIAQU50coF+
 CiVlFY2pAlwp1/wS0k+MeDa5cypsCik9Jl1vaDhgNsDlRhLgztOrgTk+fe+AFVoH
 iiLb0baENGWrgMDd8ZN9hcNbJCzBBUQ7MMkuFHZkdRx829L8yuTbCoP0tNXAuQDz
 DCcAtdt6Xm4h0NUDLFSf7CnpaWzV5WgpSPkGCYaWtmJNpxNshrkm+vFRdBHvWnhN
 Vz/2E9q1aMoSbfmnj36RhGeS37g1gAO73souDJd/LRtrk5aF1aPeWN9DGEMTTYWn
 6FNIo63v86V4kcuYxNzup5+d0A+t0aqkTFHcNrKAIvtGNTDmaCIBso1HGJud3rcA
 Rujgytbr3PpxZcJFxIzXZtTlNAHE+wwzzbdS9zaQy1l//oNIXswboJBMTHbJq6Ql
 eit+MDVrILiRcd+DviRmsTQBMRs/VlW2bHHfmgw3DvgxreyTGbR8qZKKzvGuF8Dn
 b6ODQ7Y12uUZJaytiB2SyiPNx/u7Axg1IP1w+9TVrtNONx1VSKn2aGpILYqmH1CG
 zTdgTTlWtYwLEs/tZxKHxeVZK6wlzKkc+jT259Ah57bJchzndoKCrnQ80GirdZfL
 bnMgCL2ju6Xv3A3Yn3wY
 =jnEv
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kraxel/tags/pull-vga-20150615-1' into staging

virtio-gpu: pci support bits and virtio-vga.

# gpg: Signature made Mon Jun 15 13:55:19 2015 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-vga-20150615-1:
  virtio-vga: add vgabios configuration
  virtio-vga: add '-vga virtio' support
  virtio-vga: add virtio gpu device with vga compatibility
  virtio-gpu-pci: add virtio pci support
  virtio-gpu: fix error message

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2015-06-16 10:35:43 +01:00
commit 93f6d1c160
16 changed files with 301 additions and 9 deletions

View File

@ -342,7 +342,7 @@ bepo cz
ifdef INSTALL_BLOBS ifdef INSTALL_BLOBS
BLOBS=bios.bin bios-256k.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \ BLOBS=bios.bin bios-256k.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \
vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin \ vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin vgabios-virtio.bin \
acpi-dsdt.aml q35-acpi-dsdt.aml \ acpi-dsdt.aml q35-acpi-dsdt.aml \
ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc QEMU,tcx.bin QEMU,cgthree.bin \ ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc QEMU,tcx.bin QEMU,cgthree.bin \
pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \ pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \

View File

@ -7,6 +7,7 @@ CONFIG_QXL=$(CONFIG_SPICE)
CONFIG_VGA_ISA=y CONFIG_VGA_ISA=y
CONFIG_VGA_CIRRUS=y CONFIG_VGA_CIRRUS=y
CONFIG_VMWARE_VGA=y CONFIG_VMWARE_VGA=y
CONFIG_VIRTIO_VGA=y
CONFIG_VMMOUSE=y CONFIG_VMMOUSE=y
CONFIG_SERIAL=y CONFIG_SERIAL=y
CONFIG_PARALLEL=y CONFIG_PARALLEL=y

View File

@ -36,3 +36,5 @@ obj-$(CONFIG_VGA) += vga.o
common-obj-$(CONFIG_QXL) += qxl.o qxl-logger.o qxl-render.o common-obj-$(CONFIG_QXL) += qxl.o qxl-logger.o qxl-render.o
obj-$(CONFIG_VIRTIO) += virtio-gpu.o obj-$(CONFIG_VIRTIO) += virtio-gpu.o
obj-$(CONFIG_VIRTIO_PCI) += virtio-gpu-pci.o
obj-$(CONFIG_VIRTIO_VGA) += virtio-vga.o

View File

@ -204,10 +204,10 @@ static const MemoryRegionOps pci_vga_qext_ops = {
.endianness = DEVICE_LITTLE_ENDIAN, .endianness = DEVICE_LITTLE_ENDIAN,
}; };
static void pci_std_vga_mmio_region_init(VGACommonState *s, void pci_std_vga_mmio_region_init(VGACommonState *s,
MemoryRegion *parent, MemoryRegion *parent,
MemoryRegion *subs, MemoryRegion *subs,
bool qext) bool qext)
{ {
memory_region_init_io(&subs[0], NULL, &pci_vga_ioport_ops, s, memory_region_init_io(&subs[0], NULL, &pci_vga_ioport_ops, s,
"vga ioports remapped", PCI_VGA_IOPORT_SIZE); "vga ioports remapped", PCI_VGA_IOPORT_SIZE);

View File

@ -219,4 +219,10 @@ extern const uint8_t gr_mask[16];
extern const MemoryRegionOps vga_mem_ops; extern const MemoryRegionOps vga_mem_ops;
/* vga-pci.c */
void pci_std_vga_mmio_region_init(VGACommonState *s,
MemoryRegion *parent,
MemoryRegion *subs,
bool qext);
#endif #endif

View File

@ -0,0 +1,68 @@
/*
* Virtio video device
*
* Copyright Red Hat
*
* Authors:
* Dave Airlie
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*
*/
#include "hw/pci/pci.h"
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-bus.h"
#include "hw/virtio/virtio-pci.h"
#include "hw/virtio/virtio-gpu.h"
static Property virtio_gpu_pci_properties[] = {
DEFINE_VIRTIO_GPU_PROPERTIES(VirtIOGPUPCI, vdev.conf),
DEFINE_VIRTIO_GPU_PCI_PROPERTIES(VirtIOPCIProxy),
DEFINE_PROP_END_OF_LIST(),
};
static void virtio_gpu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
{
VirtIOGPUPCI *vgpu = VIRTIO_GPU_PCI(vpci_dev);
DeviceState *vdev = DEVICE(&vgpu->vdev);
qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
/* force virtio-1.0 */
vpci_dev->flags &= ~VIRTIO_PCI_FLAG_DISABLE_MODERN;
vpci_dev->flags |= VIRTIO_PCI_FLAG_DISABLE_LEGACY;
object_property_set_bool(OBJECT(vdev), true, "realized", errp);
}
static void virtio_gpu_pci_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
dc->props = virtio_gpu_pci_properties;
k->realize = virtio_gpu_pci_realize;
pcidev_k->class_id = PCI_CLASS_DISPLAY_OTHER;
}
static void virtio_gpu_initfn(Object *obj)
{
VirtIOGPUPCI *dev = VIRTIO_GPU_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_GPU);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
static const TypeInfo virtio_gpu_pci_info = {
.name = TYPE_VIRTIO_GPU_PCI,
.parent = TYPE_VIRTIO_PCI,
.instance_size = sizeof(VirtIOGPUPCI),
.instance_init = virtio_gpu_initfn,
.class_init = virtio_gpu_pci_class_init,
};
static void virtio_gpu_pci_register_types(void)
{
type_register_static(&virtio_gpu_pci_info);
}
type_init(virtio_gpu_pci_register_types)

View File

@ -534,7 +534,7 @@ int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab,
if (ab->nr_entries > 16384) { if (ab->nr_entries > 16384) {
qemu_log_mask(LOG_GUEST_ERROR, qemu_log_mask(LOG_GUEST_ERROR,
"%s: nr_entries is too big (%d > 1024)\n", "%s: nr_entries is too big (%d > 16384)\n",
__func__, ab->nr_entries); __func__, ab->nr_entries);
return -1; return -1;
} }

175
hw/display/virtio-vga.c Normal file
View File

@ -0,0 +1,175 @@
#include "hw/hw.h"
#include "hw/pci/pci.h"
#include "ui/console.h"
#include "vga_int.h"
#include "hw/virtio/virtio-pci.h"
/*
* virtio-vga: This extends VirtioPCIProxy.
*/
#define TYPE_VIRTIO_VGA "virtio-vga"
#define VIRTIO_VGA(obj) \
OBJECT_CHECK(VirtIOVGA, (obj), TYPE_VIRTIO_VGA)
typedef struct VirtIOVGA {
VirtIOPCIProxy parent_obj;
VirtIOGPU vdev;
VGACommonState vga;
MemoryRegion vga_mrs[3];
} VirtIOVGA;
static void virtio_vga_invalidate_display(void *opaque)
{
VirtIOVGA *vvga = opaque;
if (vvga->vdev.enable) {
virtio_gpu_ops.invalidate(&vvga->vdev);
} else {
vvga->vga.hw_ops->invalidate(&vvga->vga);
}
}
static void virtio_vga_update_display(void *opaque)
{
VirtIOVGA *vvga = opaque;
if (vvga->vdev.enable) {
virtio_gpu_ops.gfx_update(&vvga->vdev);
} else {
vvga->vga.hw_ops->gfx_update(&vvga->vga);
}
}
static void virtio_vga_text_update(void *opaque, console_ch_t *chardata)
{
VirtIOVGA *vvga = opaque;
if (vvga->vdev.enable) {
if (virtio_gpu_ops.text_update) {
virtio_gpu_ops.text_update(&vvga->vdev, chardata);
}
} else {
if (vvga->vga.hw_ops->text_update) {
vvga->vga.hw_ops->text_update(&vvga->vga, chardata);
}
}
}
static int virtio_vga_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)
{
VirtIOVGA *vvga = opaque;
if (virtio_gpu_ops.ui_info) {
return virtio_gpu_ops.ui_info(&vvga->vdev, idx, info);
}
return -1;
}
static const GraphicHwOps virtio_vga_ops = {
.invalidate = virtio_vga_invalidate_display,
.gfx_update = virtio_vga_update_display,
.text_update = virtio_vga_text_update,
.ui_info = virtio_vga_ui_info,
};
/* VGA device wrapper around PCI device around virtio GPU */
static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
{
VirtIOVGA *vvga = VIRTIO_VGA(vpci_dev);
VirtIOGPU *g = &vvga->vdev;
VGACommonState *vga = &vvga->vga;
uint32_t offset;
/* init vga compat bits */
vga->vram_size_mb = 8;
vga_common_init(vga, OBJECT(vpci_dev), false);
vga_init(vga, OBJECT(vpci_dev), pci_address_space(&vpci_dev->pci_dev),
pci_address_space_io(&vpci_dev->pci_dev), true);
pci_register_bar(&vpci_dev->pci_dev, 0,
PCI_BASE_ADDRESS_MEM_PREFETCH, &vga->vram);
/*
* Configure virtio bar and regions
*
* We use bar #2 for the mmio regions, to be compatible with stdvga.
* virtio regions are moved to the end of bar #2, to make room for
* the stdvga mmio registers at the start of bar #2.
*/
vpci_dev->modern_mem_bar = 2;
vpci_dev->msix_bar = 4;
offset = memory_region_size(&vpci_dev->modern_bar);
offset -= vpci_dev->notify.size;
vpci_dev->notify.offset = offset;
offset -= vpci_dev->device.size;
vpci_dev->device.offset = offset;
offset -= vpci_dev->isr.size;
vpci_dev->isr.offset = offset;
offset -= vpci_dev->common.size;
vpci_dev->common.offset = offset;
/* init virtio bits */
qdev_set_parent_bus(DEVICE(g), BUS(&vpci_dev->bus));
/* force virtio-1.0 */
vpci_dev->flags &= ~VIRTIO_PCI_FLAG_DISABLE_MODERN;
vpci_dev->flags |= VIRTIO_PCI_FLAG_DISABLE_LEGACY;
object_property_set_bool(OBJECT(g), true, "realized", errp);
/* add stdvga mmio regions */
pci_std_vga_mmio_region_init(vga, &vpci_dev->modern_bar,
vvga->vga_mrs, true);
vga->con = g->scanout[0].con;
graphic_console_set_hwops(vga->con, &virtio_vga_ops, vvga);
}
static void virtio_vga_reset(DeviceState *dev)
{
VirtIOVGA *vvga = VIRTIO_VGA(dev);
vvga->vdev.enable = 0;
vga_dirty_log_start(&vvga->vga);
}
static Property virtio_vga_properties[] = {
DEFINE_VIRTIO_GPU_PROPERTIES(VirtIOVGA, vdev.conf),
DEFINE_VIRTIO_GPU_PCI_PROPERTIES(VirtIOPCIProxy),
DEFINE_PROP_END_OF_LIST(),
};
static void virtio_vga_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
dc->props = virtio_vga_properties;
dc->reset = virtio_vga_reset;
dc->hotpluggable = false;
k->realize = virtio_vga_realize;
pcidev_k->romfile = "vgabios-virtio.bin";
pcidev_k->class_id = PCI_CLASS_DISPLAY_VGA;
}
static void virtio_vga_inst_initfn(Object *obj)
{
VirtIOVGA *dev = VIRTIO_VGA(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_GPU);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
static TypeInfo virtio_vga_info = {
.name = TYPE_VIRTIO_VGA,
.parent = TYPE_VIRTIO_PCI,
.instance_size = sizeof(struct VirtIOVGA),
.instance_init = virtio_vga_inst_initfn,
.class_init = virtio_vga_class_init,
};
static void virtio_vga_register_types(void)
{
type_register_static(&virtio_vga_info);
}
type_init(virtio_vga_register_types)

View File

@ -179,6 +179,9 @@ ISADevice *isa_vga_init(ISABus *bus)
case VGA_VMWARE: case VGA_VMWARE:
fprintf(stderr, "%s: vmware_vga: no PCI bus\n", __func__); fprintf(stderr, "%s: vmware_vga: no PCI bus\n", __func__);
return NULL; return NULL;
case VGA_VIRTIO:
fprintf(stderr, "%s: virtio-vga: no PCI bus\n", __func__);
return NULL;
case VGA_NONE: case VGA_NONE:
default: default:
return NULL; return NULL;

View File

@ -1698,6 +1698,8 @@ PCIDevice *pci_vga_init(PCIBus *bus)
return pci_create_simple(bus, -1, "VGA"); return pci_create_simple(bus, -1, "VGA");
case VGA_VMWARE: case VGA_VMWARE:
return pci_create_simple(bus, -1, "vmware-svga"); return pci_create_simple(bus, -1, "vmware-svga");
case VGA_VIRTIO:
return pci_create_simple(bus, -1, "virtio-vga");
case VGA_NONE: case VGA_NONE:
default: /* Other non-PCI types. Checking for unsupported types is already default: /* Other non-PCI types. Checking for unsupported types is already
done in vl.c. */ done in vl.c. */

View File

@ -25,6 +25,7 @@
#include "hw/virtio/virtio-bus.h" #include "hw/virtio/virtio-bus.h"
#include "hw/virtio/virtio-9p.h" #include "hw/virtio/virtio-9p.h"
#include "hw/virtio/virtio-input.h" #include "hw/virtio/virtio-input.h"
#include "hw/virtio/virtio-gpu.h"
#ifdef CONFIG_VIRTFS #ifdef CONFIG_VIRTFS
#include "hw/9pfs/virtio-9p.h" #include "hw/9pfs/virtio-9p.h"
#endif #endif
@ -42,6 +43,7 @@ typedef struct VHostSCSIPCI VHostSCSIPCI;
typedef struct VirtIORngPCI VirtIORngPCI; typedef struct VirtIORngPCI VirtIORngPCI;
typedef struct VirtIOInputPCI VirtIOInputPCI; typedef struct VirtIOInputPCI VirtIOInputPCI;
typedef struct VirtIOInputHIDPCI VirtIOInputHIDPCI; typedef struct VirtIOInputHIDPCI VirtIOInputHIDPCI;
typedef struct VirtIOGPUPCI VirtIOGPUPCI;
/* virtio-pci-bus */ /* virtio-pci-bus */
@ -261,6 +263,18 @@ struct VirtIOInputHIDPCI {
VirtIOInputHID vdev; VirtIOInputHID vdev;
}; };
/*
* virtio-gpu-pci: This extends VirtioPCIProxy.
*/
#define TYPE_VIRTIO_GPU_PCI "virtio-gpu-pci"
#define VIRTIO_GPU_PCI(obj) \
OBJECT_CHECK(VirtIOGPUPCI, (obj), TYPE_VIRTIO_GPU_PCI)
struct VirtIOGPUPCI {
VirtIOPCIProxy parent_obj;
VirtIOGPU vdev;
};
/* Virtio ABI version, if we increment this, we break the guest driver. */ /* Virtio ABI version, if we increment this, we break the guest driver. */
#define VIRTIO_PCI_ABI_VERSION 0 #define VIRTIO_PCI_ABI_VERSION 0

View File

@ -105,7 +105,7 @@ extern int autostart;
typedef enum { typedef enum {
VGA_NONE, VGA_STD, VGA_CIRRUS, VGA_VMWARE, VGA_XENFB, VGA_QXL, VGA_NONE, VGA_STD, VGA_CIRRUS, VGA_VMWARE, VGA_XENFB, VGA_QXL,
VGA_TCX, VGA_CG3, VGA_DEVICE VGA_TCX, VGA_CG3, VGA_DEVICE, VGA_VIRTIO,
} VGAInterfaceType; } VGAInterfaceType;
extern int vga_interface_type; extern int vga_interface_type;

View File

@ -1104,7 +1104,7 @@ Rotate graphical output some deg left (only PXA LCD).
ETEXI ETEXI
DEF("vga", HAS_ARG, QEMU_OPTION_vga, DEF("vga", HAS_ARG, QEMU_OPTION_vga,
"-vga [std|cirrus|vmware|qxl|xenfb|tcx|cg3|none]\n" "-vga [std|cirrus|vmware|qxl|xenfb|tcx|cg3|virtio|none]\n"
" select video card type\n", QEMU_ARCH_ALL) " select video card type\n", QEMU_ARCH_ALL)
STEXI STEXI
@item -vga @var{type} @item -vga @var{type}
@ -1137,6 +1137,8 @@ fixed resolution of 1024x768.
(sun4m only) Sun cgthree framebuffer. This is a simple 8-bit framebuffer (sun4m only) Sun cgthree framebuffer. This is a simple 8-bit framebuffer
for sun4m machines available in both 1024x768 (OpenBIOS) and 1152x900 (OBP) for sun4m machines available in both 1024x768 (OpenBIOS) and 1152x900 (OBP)
resolutions aimed at people wishing to run older Solaris versions. resolutions aimed at people wishing to run older Solaris versions.
@item virtio
Virtio VGA card.
@item none @item none
Disable VGA card. Disable VGA card.
@end table @end table

View File

@ -1,5 +1,5 @@
vgabios_variants := stdvga cirrus vmware qxl isavga vgabios_variants := stdvga cirrus vmware qxl isavga virtio
vgabios_targets := $(subst -isavga,,$(patsubst %,vgabios-%.bin,$(vgabios_variants))) vgabios_targets := $(subst -isavga,,$(patsubst %,vgabios-%.bin,$(vgabios_variants)))
pxerom_variants := e1000 eepro100 ne2k_pci pcnet rtl8139 virtio pxerom_variants := e1000 eepro100 ne2k_pci pcnet rtl8139 virtio
pxerom_targets := 8086100e 80861209 10500940 10222000 10ec8139 1af41000 pxerom_targets := 8086100e 80861209 10500940 10222000 10ec8139 1af41000

6
roms/config.vga-virtio Normal file
View File

@ -0,0 +1,6 @@
CONFIG_BUILD_VGABIOS=y
CONFIG_VGA_BOCHS=y
CONFIG_VGA_PCI=y
CONFIG_OVERRIDE_PCI_ID=y
CONFIG_VGA_VID=0x1af4
CONFIG_VGA_DID=0x1050

13
vl.c
View File

@ -231,6 +231,7 @@ static struct {
{ .driver = "isa-cirrus-vga", .flag = &default_vga }, { .driver = "isa-cirrus-vga", .flag = &default_vga },
{ .driver = "vmware-svga", .flag = &default_vga }, { .driver = "vmware-svga", .flag = &default_vga },
{ .driver = "qxl-vga", .flag = &default_vga }, { .driver = "qxl-vga", .flag = &default_vga },
{ .driver = "virtio-vga", .flag = &default_vga },
}; };
static QemuOptsList qemu_rtc_opts = { static QemuOptsList qemu_rtc_opts = {
@ -1884,6 +1885,11 @@ static bool cg3_vga_available(void)
return object_class_by_name("cgthree"); return object_class_by_name("cgthree");
} }
static bool virtio_vga_available(void)
{
return object_class_by_name("virtio-vga");
}
static void select_vgahw (const char *p) static void select_vgahw (const char *p)
{ {
const char *opts; const char *opts;
@ -1910,6 +1916,13 @@ static void select_vgahw (const char *p)
fprintf(stderr, "Error: VMWare SVGA not available\n"); fprintf(stderr, "Error: VMWare SVGA not available\n");
exit(0); exit(0);
} }
} else if (strstart(p, "virtio", &opts)) {
if (virtio_vga_available()) {
vga_interface_type = VGA_VIRTIO;
} else {
fprintf(stderr, "Error: Virtio VGA not available\n");
exit(0);
}
} else if (strstart(p, "xenfb", &opts)) { } else if (strstart(p, "xenfb", &opts)) {
vga_interface_type = VGA_XENFB; vga_interface_type = VGA_XENFB;
} else if (strstart(p, "qxl", &opts)) { } else if (strstart(p, "qxl", &opts)) {