* [Qemu-devel] [PATCH v3 0/6] ramfb: simple boot framebuffer, no legacy vga
@ 2018-06-08 11:19 Gerd Hoffmann
2018-06-08 11:19 ` [Qemu-devel] [PATCH v3 1/6] hw/display: add ramfb, a simple boot framebuffer living in guest ram Gerd Hoffmann
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2018-06-08 11:19 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Eduardo Habkost, Marcel Apfelbaum,
Richard Henderson, qemu-arm, Michael S. Tsirkin, Alex Williamson,
Peter Maydell, László Érsek, Gerd Hoffmann
Hi,
Ok folks, here is a experimental patch series for a legacy free boot
framebuffer. If you want play with it I recommend getting the bits from
https://www.kraxel.org/cgit/qemu/log/?h=sirius/ramfb
because they come with an updated seabios and a new vgabios rom and an
experimental OVMF build.
Functional overview
-------------------
The boot framebuffer is expected to be configured by the firmware, so it
uses fw_cfg as interface. Initialization goes as follows:
(1) Check whenever etc/ramfb is present.
(2) Allocate framebuffer from RAM.
(3) Fill struct RAMFBCfg, write it to etc/ramfb.
Done. You can write stuff to the framebuffer now, and it should appear
automagically on the screen.
Note that this isn't very efficient because it does a full display
update on each refresh. No dirty tracking. Dirty tracking would have
to be active for the whole ram slot, so that wouldn't be very efficient
either.
Firmware support -- seabios
---------------------------
seavgabios is able to emulate vga text mode on top of a framebuffer, for
coreboot native graphics initialialization. Which works fine for
everything which writes text using the vgabios interface (basically
everyhing which works with sgabios).
So I hacked that up to work with ramfb (and, while being at it,
bochs-display too). Right now it's proof-of-concept code with fwcfg
support being cut+paste, so it'll need cleanups before merging.
Look here:
https://www.kraxe.org/cgit/seabios/log/?h=bochs
Firmware support -- edk2
------------------------
There is a EFI driver too. Code is here:
https://github.com/kraxel/edk2/commits/ramfb
Firmware blob is in pc-bios/OVMF-ramfb.fd, to be used with -bios.
So, how to play?
----------------
There is ramfb. Standalone device.
There is virtio-ramfb. Simliar to virtio-vga, but using ramfb instead of
adding vga compatibility. Shows how you can wire up ramfb support to
some display device. Unlike virtio-vga it should work fine on arm. Use
"qemu -vga none -device virtio-ramfb" for this one. Not clear whenever
this will be actually be merged, given that edk2 has a native virtio-gpu
driver.
There is virtio-pci-ramfb, which provides boot display support to vgpu
devices.
What works?
-----------
Both windows (x86 tested) and linux (x86 + arm tested) UEFI guests
handle the ramfb GOP just fine.
BIOS boot loaders for linux all use vgabios calls for text mode, so they
show up just fine. Also ipxe, seabios itself of course. So you can
boot up your linux guest. vesafb works too.
Windows in BIOS mode doesn't use text mode and works fine too.
What doesn't work?
------------------
vgacon (direct vga hardware access). Linux boots just fine
nevertheless, the only effect is that you don't see any boot messages
until the drm driver loads.
Known issues
------------
Handover from ramfb-backed efifb to the native linux driver is tricky.
Usually efifb gets kicked out when the native driver loads because of
overlapping ressources. With efifb being in RAM instead of using a GPU
PCI bar this doesn't happen though, so you'll end up with two
framebuffer devices.
In case vgaarb classifies the GPU as primary display device fbcon will
switch all VTs over to the framebuffer device of the real GPU, so there
isn't a noticable difference. Otherwise you'll end up with a
non-visible fbcon, because it continues to run on ramfb whereas qemu
switched over to the GPU because the native linux driver initialized the
display.
xorg/wayland will show up on the GPU in any case because they prefer drm
over fbdev, so they wouldn't run on efifb.
enjoy,
Gerd
Gerd Hoffmann (6):
hw/display: add ramfb, a simple boot framebuffer living in guest ram
hw/display: add standalone ramfb device
hw/display: add virtio-ramfb device
hw/vfio/display: add ramfb support
ramfb: enable vgabios
bochs-display: enable vgabios
include/hw/display/ramfb.h | 12 ++++
include/hw/vfio/vfio-common.h | 2 +
hw/arm/sysbus-fdt.c | 7 ++
hw/arm/virt.c | 2 +
hw/display/bochs-display.c | 1 +
hw/display/ramfb-standalone.c | 62 ++++++++++++++++++
hw/display/ramfb.c | 96 +++++++++++++++++++++++++++
hw/display/virtio-ramfb.c | 149 ++++++++++++++++++++++++++++++++++++++++++
hw/i386/pc_piix.c | 2 +
hw/i386/pc_q35.c | 2 +
hw/vfio/display.c | 10 +++
hw/vfio/pci.c | 15 +++++
hw/display/Makefile.objs | 5 +-
13 files changed, 364 insertions(+), 1 deletion(-)
create mode 100644 include/hw/display/ramfb.h
create mode 100644 hw/display/ramfb-standalone.c
create mode 100644 hw/display/ramfb.c
create mode 100644 hw/display/virtio-ramfb.c
--
2.9.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH v3 1/6] hw/display: add ramfb, a simple boot framebuffer living in guest ram
2018-06-08 11:19 [Qemu-devel] [PATCH v3 0/6] ramfb: simple boot framebuffer, no legacy vga Gerd Hoffmann
@ 2018-06-08 11:19 ` Gerd Hoffmann
2018-06-08 11:19 ` [Qemu-devel] [PATCH v3 2/6] hw/display: add standalone ramfb device Gerd Hoffmann
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2018-06-08 11:19 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Eduardo Habkost, Marcel Apfelbaum,
Richard Henderson, qemu-arm, Michael S. Tsirkin, Alex Williamson,
Peter Maydell, László Érsek, Gerd Hoffmann
The boot framebuffer is expected to be configured by the firmware, so it
uses fw_cfg as interface. Initialization goes as follows:
(1) Check whenever etc/ramfb is present.
(2) Allocate framebuffer from RAM.
(3) Fill struct RAMFBCfg, write it to etc/ramfb.
Done. You can write stuff to the framebuffer now, and it should appear
automagically on the screen.
Note that this isn't very efficient because it does a full display
update on each refresh. No dirty tracking. Dirty tracking would have
to be active for the whole ram slot, so that wouldn't be very efficient
either. For a boot display which is active for a short time only this
isn't a big deal. As permanent guest display something better should be
used (if possible).
This is the ramfb core code. Some windup is needed for display devices
which want have a ramfb boot display.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/hw/display/ramfb.h | 9 +++++
hw/display/ramfb.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++
hw/display/Makefile.objs | 2 +
3 files changed, 106 insertions(+)
create mode 100644 include/hw/display/ramfb.h
create mode 100644 hw/display/ramfb.c
diff --git a/include/hw/display/ramfb.h b/include/hw/display/ramfb.h
new file mode 100644
index 0000000000..a3d4c79942
--- /dev/null
+++ b/include/hw/display/ramfb.h
@@ -0,0 +1,9 @@
+#ifndef RAMFB_H
+#define RAMFB_H
+
+/* ramfb.c */
+typedef struct RAMFBState RAMFBState;
+void ramfb_display_update(QemuConsole *con, RAMFBState *s);
+RAMFBState *ramfb_setup(Error **errp);
+
+#endif /* RAMFB_H */
diff --git a/hw/display/ramfb.c b/hw/display/ramfb.c
new file mode 100644
index 0000000000..258783fe3b
--- /dev/null
+++ b/hw/display/ramfb.c
@@ -0,0 +1,95 @@
+/*
+ * early boot framebuffer in guest ram
+ * configured using fw_cfg
+ *
+ * Copyright Red Hat, Inc. 2017
+ *
+ * Author:
+ * Gerd Hoffmann <kraxel@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/loader.h"
+#include "hw/display/ramfb.h"
+#include "ui/console.h"
+#include "sysemu/sysemu.h"
+
+struct RAMFBCfg {
+ uint64_t addr;
+ uint32_t fourcc;
+ uint32_t flags;
+ uint32_t width;
+ uint32_t height;
+ uint32_t stride;
+};
+
+struct RAMFBState {
+ DisplaySurface *ds;
+ uint32_t width, height;
+ struct RAMFBCfg cfg;
+};
+
+static void ramfb_fw_cfg_write(void *dev, off_t offset, size_t len)
+{
+ RAMFBState *s = dev;
+ void *framebuffer;
+ uint32_t stride, fourcc, format;
+ hwaddr addr, length;
+
+ s->width = be32_to_cpu(s->cfg.width);
+ s->height = be32_to_cpu(s->cfg.height);
+ stride = be32_to_cpu(s->cfg.stride);
+ fourcc = be32_to_cpu(s->cfg.fourcc);
+ addr = be64_to_cpu(s->cfg.addr);
+ length = stride * s->height;
+ format = qemu_drm_format_to_pixman(fourcc);
+
+ fprintf(stderr, "%s: %dx%d @ 0x%" PRIx64 "\n", __func__,
+ s->width, s->height, addr);
+ framebuffer = address_space_map(&address_space_memory,
+ addr, &length, false,
+ MEMTXATTRS_UNSPECIFIED);
+ if (!framebuffer || length < stride * s->height) {
+ s->width = 0;
+ s->height = 0;
+ return;
+ }
+ s->ds = qemu_create_displaysurface_from(s->width, s->height,
+ format, stride, framebuffer);
+}
+
+void ramfb_display_update(QemuConsole *con, RAMFBState *s)
+{
+ if (!s->width || !s->height) {
+ return;
+ }
+
+ if (s->ds) {
+ dpy_gfx_replace_surface(con, s->ds);
+ s->ds = NULL;
+ }
+
+ /* simple full screen update */
+ dpy_gfx_update_full(con);
+}
+
+RAMFBState *ramfb_setup(Error **errp)
+{
+ FWCfgState *fw_cfg = fw_cfg_find();
+ RAMFBState *s;
+
+ if (!fw_cfg || !fw_cfg->dma_enabled) {
+ error_setg(errp, "ramfb device requires fw_cfg with DMA");
+ return NULL;
+ }
+
+ s = g_new0(RAMFBState, 1);
+
+ fw_cfg_add_file_callback(fw_cfg, "etc/ramfb",
+ NULL, ramfb_fw_cfg_write, s,
+ &s->cfg, sizeof(s->cfg), false);
+ return s;
+}
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index b5d97ab26d..0af04985d2 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -1,3 +1,5 @@
+common-obj-y += ramfb.o
+
common-obj-$(CONFIG_ADS7846) += ads7846.o
common-obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o
common-obj-$(CONFIG_G364FB) += g364fb.o
--
2.9.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH v3 2/6] hw/display: add standalone ramfb device
2018-06-08 11:19 [Qemu-devel] [PATCH v3 0/6] ramfb: simple boot framebuffer, no legacy vga Gerd Hoffmann
2018-06-08 11:19 ` [Qemu-devel] [PATCH v3 1/6] hw/display: add ramfb, a simple boot framebuffer living in guest ram Gerd Hoffmann
@ 2018-06-08 11:19 ` Gerd Hoffmann
2018-06-08 11:19 ` [Qemu-devel] [PATCH v3 3/6] hw/display: add virtio-ramfb device Gerd Hoffmann
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2018-06-08 11:19 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Eduardo Habkost, Marcel Apfelbaum,
Richard Henderson, qemu-arm, Michael S. Tsirkin, Alex Williamson,
Peter Maydell, László Érsek, Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/hw/display/ramfb.h | 3 +++
hw/arm/sysbus-fdt.c | 7 +++++
hw/arm/virt.c | 2 ++
hw/display/ramfb-standalone.c | 62 +++++++++++++++++++++++++++++++++++++++++++
hw/i386/pc_piix.c | 2 ++
hw/i386/pc_q35.c | 2 ++
hw/display/Makefile.objs | 1 +
7 files changed, 79 insertions(+)
create mode 100644 hw/display/ramfb-standalone.c
diff --git a/include/hw/display/ramfb.h b/include/hw/display/ramfb.h
index a3d4c79942..b33a2c467b 100644
--- a/include/hw/display/ramfb.h
+++ b/include/hw/display/ramfb.h
@@ -6,4 +6,7 @@ typedef struct RAMFBState RAMFBState;
void ramfb_display_update(QemuConsole *con, RAMFBState *s);
RAMFBState *ramfb_setup(Error **errp);
+/* ramfb-standalone.c */
+#define TYPE_RAMFB_DEVICE "ramfb"
+
#endif /* RAMFB_H */
diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index e4c492ea44..277ed872e7 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -36,6 +36,7 @@
#include "hw/vfio/vfio-platform.h"
#include "hw/vfio/vfio-calxeda-xgmac.h"
#include "hw/vfio/vfio-amd-xgbe.h"
+#include "hw/display/ramfb.h"
#include "hw/arm/fdt.h"
/*
@@ -406,12 +407,18 @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)
#endif /* CONFIG_LINUX */
+static int no_fdt_node(SysBusDevice *sbdev, void *opaque)
+{
+ return 0;
+}
+
/* list of supported dynamic sysbus devices */
static const NodeCreationPair add_fdt_node_functions[] = {
#ifdef CONFIG_LINUX
{TYPE_VFIO_CALXEDA_XGMAC, add_calxeda_midway_xgmac_fdt_node},
{TYPE_VFIO_AMD_XGBE, add_amd_xgbe_fdt_node},
#endif
+ {TYPE_RAMFB_DEVICE, no_fdt_node},
{"", NULL}, /* last element */
};
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f0a4fa004c..98b99cf236 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -36,6 +36,7 @@
#include "hw/arm/virt.h"
#include "hw/vfio/vfio-calxeda-xgmac.h"
#include "hw/vfio/vfio-amd-xgbe.h"
+#include "hw/display/ramfb.h"
#include "hw/devices.h"
#include "net/net.h"
#include "sysemu/device_tree.h"
@@ -1659,6 +1660,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->max_cpus = 255;
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_CALXEDA_XGMAC);
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE);
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
mc->block_default_type = IF_VIRTIO;
mc->no_cdrom = 1;
mc->pci_allow_0_address = true;
diff --git a/hw/display/ramfb-standalone.c b/hw/display/ramfb-standalone.c
new file mode 100644
index 0000000000..05d2b9839e
--- /dev/null
+++ b/hw/display/ramfb-standalone.c
@@ -0,0 +1,62 @@
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/loader.h"
+#include "hw/isa/isa.h"
+#include "hw/display/ramfb.h"
+#include "ui/console.h"
+#include "sysemu/sysemu.h"
+
+#define RAMFB(obj) OBJECT_CHECK(RAMFBState, (obj), TYPE_RAMFB_DEVICE)
+
+typedef struct RAMFBState {
+ SysBusDevice parent_obj;
+ QemuConsole *con;
+ RAMFBState *state;
+} RAMFBState;
+
+static void display_update_wrapper(void *dev)
+{
+ RAMFBState *ramfb = RAMFB(dev);
+
+ if (0 /* native driver active */) {
+ /* non-standalone device would run native display update here */;
+ } else {
+ ramfb_display_update(ramfb->con, ramfb->state);
+ }
+}
+
+static const GraphicHwOps wrapper_ops = {
+ .gfx_update = display_update_wrapper,
+};
+
+static void ramfb_realizefn(DeviceState *dev, Error **errp)
+{
+ RAMFBState *ramfb = RAMFB(dev);
+
+ ramfb->con = graphic_console_init(dev, 0, &wrapper_ops, dev);
+ ramfb->state = ramfb_setup(errp);
+}
+
+static void ramfb_class_initfn(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
+ dc->realize = ramfb_realizefn;
+ dc->desc = "ram framebuffer standalone device";
+ dc->user_creatable = true;
+}
+
+static const TypeInfo ramfb_info = {
+ .name = TYPE_RAMFB_DEVICE,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(RAMFBState),
+ .class_init = ramfb_class_initfn,
+};
+
+static void ramfb_register_types(void)
+{
+ type_register_static(&ramfb_info);
+}
+
+type_init(ramfb_register_types)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 3d81136065..5dc4220d02 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -28,6 +28,7 @@
#include "hw/loader.h"
#include "hw/i386/pc.h"
#include "hw/i386/apic.h"
+#include "hw/display/ramfb.h"
#include "hw/smbios/smbios.h"
#include "hw/pci/pci.h"
#include "hw/pci/pci_ids.h"
@@ -423,6 +424,7 @@ static void pc_i440fx_machine_options(MachineClass *m)
m->desc = "Standard PC (i440FX + PIIX, 1996)";
m->default_machine_opts = "firmware=bios-256k.bin";
m->default_display = "std";
+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
}
static void pc_i440fx_3_0_machine_options(MachineClass *m)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index b60cbb9266..19294949ce 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -45,6 +45,7 @@
#include "hw/i386/ich9.h"
#include "hw/i386/amd_iommu.h"
#include "hw/i386/intel_iommu.h"
+#include "hw/display/ramfb.h"
#include "hw/smbios/smbios.h"
#include "hw/ide/pci.h"
#include "hw/ide/ahci.h"
@@ -305,6 +306,7 @@ static void pc_q35_machine_options(MachineClass *m)
m->no_floppy = 1;
machine_class_allow_dynamic_sysbus_dev(m, TYPE_AMD_IOMMU_DEVICE);
machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE);
+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
m->max_cpus = 288;
}
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index 0af04985d2..fb8408c6d0 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -1,4 +1,5 @@
common-obj-y += ramfb.o
+common-obj-y += ramfb-standalone.o
common-obj-$(CONFIG_ADS7846) += ads7846.o
common-obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o
--
2.9.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH v3 3/6] hw/display: add virtio-ramfb device
2018-06-08 11:19 [Qemu-devel] [PATCH v3 0/6] ramfb: simple boot framebuffer, no legacy vga Gerd Hoffmann
2018-06-08 11:19 ` [Qemu-devel] [PATCH v3 1/6] hw/display: add ramfb, a simple boot framebuffer living in guest ram Gerd Hoffmann
2018-06-08 11:19 ` [Qemu-devel] [PATCH v3 2/6] hw/display: add standalone ramfb device Gerd Hoffmann
@ 2018-06-08 11:19 ` Gerd Hoffmann
2018-06-08 11:19 ` [Qemu-devel] [PATCH v3 4/6] hw/vfio/display: add ramfb support Gerd Hoffmann
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2018-06-08 11:19 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Eduardo Habkost, Marcel Apfelbaum,
Richard Henderson, qemu-arm, Michael S. Tsirkin, Alex Williamson,
Peter Maydell, László Érsek, Gerd Hoffmann
Like virtio-vga, but using ramfb instead of legacy vga.
Note: Not clear yet whenever this will be ever merged upstream.
No clear benefit, given that edk2 has a virtio-gpu driver
which doesn't depend on the vga compatibility mode.
Will keeping it in the devel branch for now, for testing
purposes and as playground.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/display/virtio-ramfb.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++
hw/display/Makefile.objs | 2 +-
2 files changed, 150 insertions(+), 1 deletion(-)
create mode 100644 hw/display/virtio-ramfb.c
diff --git a/hw/display/virtio-ramfb.c b/hw/display/virtio-ramfb.c
new file mode 100644
index 0000000000..e8ffe66047
--- /dev/null
+++ b/hw/display/virtio-ramfb.c
@@ -0,0 +1,149 @@
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/pci/pci.h"
+#include "ui/console.h"
+#include "hw/virtio/virtio-pci.h"
+#include "hw/display/ramfb.h"
+#include "qapi/error.h"
+
+/*
+ * virtio-ramfb: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_RAMFB "virtio-ramfb"
+#define VIRTIO_RAMFB(obj) \
+ OBJECT_CHECK(VirtIORAMFB, (obj), TYPE_VIRTIO_RAMFB)
+
+typedef struct VirtIORAMFB {
+ VirtIOPCIProxy parent_obj;
+ VirtIOGPU vdev;
+ RAMFBState *ramfb;
+} VirtIORAMFB;
+
+static void virtio_ramfb_invalidate_display(void *opaque)
+{
+ VirtIORAMFB *vramfb = opaque;
+
+ if (vramfb->vdev.enable) {
+ virtio_gpu_ops.invalidate(&vramfb->vdev);
+ }
+}
+
+static void virtio_ramfb_update_display(void *opaque)
+{
+ VirtIORAMFB *vramfb = opaque;
+ VirtIOGPU *g = &vramfb->vdev;
+
+ if (vramfb->vdev.enable) {
+ virtio_gpu_ops.gfx_update(&vramfb->vdev);
+ } else {
+ ramfb_display_update(g->scanout[0].con, vramfb->ramfb);
+ }
+}
+
+static int virtio_ramfb_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)
+{
+ VirtIORAMFB *vramfb = opaque;
+
+ if (virtio_gpu_ops.ui_info) {
+ return virtio_gpu_ops.ui_info(&vramfb->vdev, idx, info);
+ }
+ return -1;
+}
+
+static void virtio_ramfb_gl_block(void *opaque, bool block)
+{
+ VirtIORAMFB *vramfb = opaque;
+
+ if (virtio_gpu_ops.gl_block) {
+ virtio_gpu_ops.gl_block(&vramfb->vdev, block);
+ }
+}
+
+static const GraphicHwOps virtio_ramfb_ops = {
+ .invalidate = virtio_ramfb_invalidate_display,
+ .gfx_update = virtio_ramfb_update_display,
+ .ui_info = virtio_ramfb_ui_info,
+ .gl_block = virtio_ramfb_gl_block,
+};
+
+static const VMStateDescription vmstate_virtio_ramfb = {
+ .name = "virtio-ramfb",
+ .version_id = 2,
+ .minimum_version_id = 2,
+ .fields = (VMStateField[]) {
+ /* no pci stuff here, saving the virtio device will handle that */
+ /* FIXME */
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+/* RAMFB device wrapper around PCI device around virtio GPU */
+static void virtio_ramfb_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+ VirtIORAMFB *vramfb = VIRTIO_RAMFB(vpci_dev);
+ VirtIOGPU *g = &vramfb->vdev;
+ Error *err = NULL;
+ int i;
+
+ /* init virtio bits */
+ qdev_set_parent_bus(DEVICE(g), BUS(&vpci_dev->bus));
+ virtio_pci_force_virtio_1(vpci_dev);
+ object_property_set_bool(OBJECT(g), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ /* init ramfb */
+ vramfb->ramfb = ramfb_setup(errp);
+ graphic_console_set_hwops(g->scanout[0].con, &virtio_ramfb_ops, vramfb);
+
+ for (i = 0; i < g->conf.max_outputs; i++) {
+ object_property_set_link(OBJECT(g->scanout[i].con),
+ OBJECT(vpci_dev),
+ "device", errp);
+ }
+}
+
+static Property virtio_ramfb_properties[] = {
+ DEFINE_VIRTIO_GPU_PCI_PROPERTIES(VirtIOPCIProxy),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_ramfb_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_ramfb_properties;
+ dc->vmsd = &vmstate_virtio_ramfb;
+ dc->hotpluggable = false;
+
+ k->realize = virtio_ramfb_realize;
+ pcidev_k->class_id = PCI_CLASS_DISPLAY_OTHER;
+}
+
+static void virtio_ramfb_inst_initfn(Object *obj)
+{
+ VirtIORAMFB *dev = VIRTIO_RAMFB(obj);
+
+ virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+ TYPE_VIRTIO_GPU);
+}
+
+static TypeInfo virtio_ramfb_info = {
+ .name = TYPE_VIRTIO_RAMFB,
+ .parent = TYPE_VIRTIO_PCI,
+ .instance_size = sizeof(struct VirtIORAMFB),
+ .instance_init = virtio_ramfb_inst_initfn,
+ .class_init = virtio_ramfb_class_init,
+};
+
+static void virtio_ramfb_register_types(void)
+{
+ type_register_static(&virtio_ramfb_info);
+}
+
+type_init(virtio_ramfb_register_types)
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index fb8408c6d0..e70e71ac5c 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -40,7 +40,7 @@ obj-$(CONFIG_VGA) += vga.o
common-obj-$(CONFIG_QXL) += qxl.o qxl-logger.o qxl-render.o
obj-$(CONFIG_VIRTIO_GPU) += virtio-gpu.o virtio-gpu-3d.o
-obj-$(call land,$(CONFIG_VIRTIO_GPU),$(CONFIG_VIRTIO_PCI)) += virtio-gpu-pci.o
+obj-$(call land,$(CONFIG_VIRTIO_GPU),$(CONFIG_VIRTIO_PCI)) += virtio-gpu-pci.o virtio-ramfb.o
obj-$(CONFIG_VIRTIO_VGA) += virtio-vga.o
virtio-gpu.o-cflags := $(VIRGL_CFLAGS)
virtio-gpu.o-libs += $(VIRGL_LIBS)
--
2.9.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH v3 4/6] hw/vfio/display: add ramfb support
2018-06-08 11:19 [Qemu-devel] [PATCH v3 0/6] ramfb: simple boot framebuffer, no legacy vga Gerd Hoffmann
` (2 preceding siblings ...)
2018-06-08 11:19 ` [Qemu-devel] [PATCH v3 3/6] hw/display: add virtio-ramfb device Gerd Hoffmann
@ 2018-06-08 11:19 ` Gerd Hoffmann
2018-06-08 11:20 ` [Qemu-devel] [PATCH v3 5/6] ramfb: enable vgabios Gerd Hoffmann
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2018-06-08 11:19 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Eduardo Habkost, Marcel Apfelbaum,
Richard Henderson, qemu-arm, Michael S. Tsirkin, Alex Williamson,
Peter Maydell, László Érsek, Gerd Hoffmann
So we have a boot display when using a vgpu as primary display.
Use vfio-pci-ramfb instead of vfio-pci to enable it.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/hw/vfio/vfio-common.h | 2 ++
hw/vfio/display.c | 10 ++++++++++
hw/vfio/pci.c | 15 +++++++++++++++
3 files changed, 27 insertions(+)
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index a9036929b2..a58d7e7e77 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -26,6 +26,7 @@
#include "qemu/queue.h"
#include "qemu/notify.h"
#include "ui/console.h"
+#include "hw/display/ramfb.h"
#ifdef CONFIG_LINUX
#include <linux/vfio.h>
#endif
@@ -143,6 +144,7 @@ typedef struct VFIODMABuf {
typedef struct VFIODisplay {
QemuConsole *con;
+ RAMFBState *ramfb;
struct {
VFIORegion buffer;
DisplaySurface *surface;
diff --git a/hw/vfio/display.c b/hw/vfio/display.c
index 59c0e5d1d7..409d5a2e3a 100644
--- a/hw/vfio/display.c
+++ b/hw/vfio/display.c
@@ -124,6 +124,9 @@ static void vfio_display_dmabuf_update(void *opaque)
primary = vfio_display_get_dmabuf(vdev, DRM_PLANE_TYPE_PRIMARY);
if (primary == NULL) {
+ if (dpy->ramfb) {
+ ramfb_display_update(dpy->con, dpy->ramfb);
+ }
return;
}
@@ -181,6 +184,8 @@ static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev, Error **errp)
vdev->dpy->con = graphic_console_init(DEVICE(vdev), 0,
&vfio_display_dmabuf_ops,
vdev);
+ if (strcmp(object_get_typename(OBJECT(vdev)), "vfio-pci-ramfb") == 0)
+ vdev->dpy->ramfb = ramfb_setup(errp);
return 0;
}
@@ -228,6 +233,9 @@ static void vfio_display_region_update(void *opaque)
return;
}
if (!plane.drm_format || !plane.size) {
+ if (dpy->ramfb) {
+ ramfb_display_update(dpy->con, dpy->ramfb);
+ }
return;
}
format = qemu_drm_format_to_pixman(plane.drm_format);
@@ -300,6 +308,8 @@ static int vfio_display_region_init(VFIOPCIDevice *vdev, Error **errp)
vdev->dpy->con = graphic_console_init(DEVICE(vdev), 0,
&vfio_display_region_ops,
vdev);
+ if (strcmp(object_get_typename(OBJECT(vdev)), "vfio-pci-ramfb") == 0)
+ vdev->dpy->ramfb = ramfb_setup(errp);
return 0;
}
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 18c493b49e..6a2b42a595 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3234,9 +3234,24 @@ static const TypeInfo vfio_pci_dev_info = {
},
};
+static void vfio_pci_ramfb_dev_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->hotpluggable = false;
+}
+
+static const TypeInfo vfio_pci_ramfb_dev_info = {
+ .name = "vfio-pci-ramfb",
+ .parent = "vfio-pci",
+ .instance_size = sizeof(VFIOPCIDevice),
+ .class_init = vfio_pci_ramfb_dev_class_init,
+};
+
static void register_vfio_pci_dev_type(void)
{
type_register_static(&vfio_pci_dev_info);
+ type_register_static(&vfio_pci_ramfb_dev_info);
}
type_init(register_vfio_pci_dev_type)
--
2.9.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH v3 5/6] ramfb: enable vgabios
2018-06-08 11:19 [Qemu-devel] [PATCH v3 0/6] ramfb: simple boot framebuffer, no legacy vga Gerd Hoffmann
` (3 preceding siblings ...)
2018-06-08 11:19 ` [Qemu-devel] [PATCH v3 4/6] hw/vfio/display: add ramfb support Gerd Hoffmann
@ 2018-06-08 11:20 ` Gerd Hoffmann
2018-06-08 11:20 ` [Qemu-devel] [PATCH v3 6/6] bochs-display: " Gerd Hoffmann
2018-06-08 11:30 ` [Qemu-devel] [PATCH v3 0/6] ramfb: simple boot framebuffer, no legacy vga no-reply
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2018-06-08 11:20 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Eduardo Habkost, Marcel Apfelbaum,
Richard Henderson, qemu-arm, Michael S. Tsirkin, Alex Williamson,
Peter Maydell, László Érsek, Gerd Hoffmann
---
hw/display/ramfb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/display/ramfb.c b/hw/display/ramfb.c
index 258783fe3b..477316a14d 100644
--- a/hw/display/ramfb.c
+++ b/hw/display/ramfb.c
@@ -88,6 +88,7 @@ RAMFBState *ramfb_setup(Error **errp)
s = g_new0(RAMFBState, 1);
+ rom_add_vga("vgabios-ramfb.bin");
fw_cfg_add_file_callback(fw_cfg, "etc/ramfb",
NULL, ramfb_fw_cfg_write, s,
&s->cfg, sizeof(s->cfg), false);
--
2.9.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH v3 6/6] bochs-display: enable vgabios
2018-06-08 11:19 [Qemu-devel] [PATCH v3 0/6] ramfb: simple boot framebuffer, no legacy vga Gerd Hoffmann
` (4 preceding siblings ...)
2018-06-08 11:20 ` [Qemu-devel] [PATCH v3 5/6] ramfb: enable vgabios Gerd Hoffmann
@ 2018-06-08 11:20 ` Gerd Hoffmann
2018-06-08 11:30 ` [Qemu-devel] [PATCH v3 0/6] ramfb: simple boot framebuffer, no legacy vga no-reply
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2018-06-08 11:20 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Eduardo Habkost, Marcel Apfelbaum,
Richard Henderson, qemu-arm, Michael S. Tsirkin, Alex Williamson,
Peter Maydell, László Érsek, Gerd Hoffmann
---
hw/display/bochs-display.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/display/bochs-display.c b/hw/display/bochs-display.c
index 1187d77576..12d8a66c6c 100644
--- a/hw/display/bochs-display.c
+++ b/hw/display/bochs-display.c
@@ -337,6 +337,7 @@ static void bochs_display_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_QEMU_VGA;
k->realize = bochs_display_realize;
+ k->romfile = "vgabios-bochs-display.bin";
k->exit = bochs_display_exit;
dc->vmsd = &vmstate_bochs_display;
dc->props = bochs_display_properties;
--
2.9.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH v3 0/6] ramfb: simple boot framebuffer, no legacy vga
2018-06-08 11:19 [Qemu-devel] [PATCH v3 0/6] ramfb: simple boot framebuffer, no legacy vga Gerd Hoffmann
` (5 preceding siblings ...)
2018-06-08 11:20 ` [Qemu-devel] [PATCH v3 6/6] bochs-display: " Gerd Hoffmann
@ 2018-06-08 11:30 ` no-reply
6 siblings, 0 replies; 8+ messages in thread
From: no-reply @ 2018-06-08 11:30 UTC (permalink / raw)
To: kraxel
Cc: famz, qemu-devel, peter.maydell, ehabkost, mst, alex.williamson,
qemu-arm, pbonzini, lersek, rth
Hi,
This series seems to have some coding style problems. See output below for
more information:
Type: series
Message-id: 20180608112001.14729-1-kraxel@redhat.com
Subject: [Qemu-devel] [PATCH v3 0/6] ramfb: simple boot framebuffer, no legacy vga
=== TEST SCRIPT BEGIN ===
#!/bin/bash
BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done
exit $failed
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
a674da0ab7..bac5ba3dc5 master -> master
* [new tag] patchew/20180608112001.14729-1-kraxel@redhat.com -> patchew/20180608112001.14729-1-kraxel@redhat.com
Switched to a new branch 'test'
b3b768bdcf bochs-display: enable vgabios
be08ed14be ramfb: enable vgabios
f2f2069625 hw/vfio/display: add ramfb support
717edb2f4d hw/display: add virtio-ramfb device
cfb87c9b3b hw/display: add standalone ramfb device
add39ce518 hw/display: add ramfb, a simple boot framebuffer living in guest ram
=== OUTPUT BEGIN ===
Checking PATCH 1/6: hw/display: add ramfb, a simple boot framebuffer living in guest ram...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#41:
new file mode 100644
total: 0 errors, 1 warnings, 109 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 2/6: hw/display: add standalone ramfb device...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#71:
new file mode 100644
total: 0 errors, 1 warnings, 141 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 3/6: hw/display: add virtio-ramfb device...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#32:
new file mode 100644
total: 0 errors, 1 warnings, 157 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 4/6: hw/vfio/display: add ramfb support...
ERROR: braces {} are necessary for all arms of this statement
#31: FILE: hw/vfio/display.c:187:
+ if (strcmp(object_get_typename(OBJECT(vdev)), "vfio-pci-ramfb") == 0)
[...]
ERROR: braces {} are necessary for all arms of this statement
#50: FILE: hw/vfio/display.c:311:
+ if (strcmp(object_get_typename(OBJECT(vdev)), "vfio-pci-ramfb") == 0)
[...]
total: 2 errors, 0 warnings, 72 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 5/6: ramfb: enable vgabios...
Checking PATCH 6/6: bochs-display: enable vgabios...
=== OUTPUT END ===
Test command exited with code: 1
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2018-06-08 11:46 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-06-08 11:19 [Qemu-devel] [PATCH v3 0/6] ramfb: simple boot framebuffer, no legacy vga Gerd Hoffmann
2018-06-08 11:19 ` [Qemu-devel] [PATCH v3 1/6] hw/display: add ramfb, a simple boot framebuffer living in guest ram Gerd Hoffmann
2018-06-08 11:19 ` [Qemu-devel] [PATCH v3 2/6] hw/display: add standalone ramfb device Gerd Hoffmann
2018-06-08 11:19 ` [Qemu-devel] [PATCH v3 3/6] hw/display: add virtio-ramfb device Gerd Hoffmann
2018-06-08 11:19 ` [Qemu-devel] [PATCH v3 4/6] hw/vfio/display: add ramfb support Gerd Hoffmann
2018-06-08 11:20 ` [Qemu-devel] [PATCH v3 5/6] ramfb: enable vgabios Gerd Hoffmann
2018-06-08 11:20 ` [Qemu-devel] [PATCH v3 6/6] bochs-display: " Gerd Hoffmann
2018-06-08 11:30 ` [Qemu-devel] [PATCH v3 0/6] ramfb: simple boot framebuffer, no legacy vga no-reply
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).