qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Michael S. Tsirkin" <mst@redhat.com>,
	"Alex Williamson" <alex.williamson@redhat.com>,
	"László Érsek" <lersek@redhat.com>,
	"Gerd Hoffmann" <kraxel@redhat.com>
Subject: [Qemu-devel] [PATCH v2 3/7] hw/display: add ramfb, a simple boot framebuffer living in guest ram
Date: Fri, 23 Mar 2018 13:25:16 +0100	[thread overview]
Message-ID: <20180323122520.11270-4-kraxel@redhat.com> (raw)
In-Reply-To: <20180323122520.11270-1-kraxel@redhat.com>

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.  So it is *really* intended to be only active for a short time
at boot, before the guest loaded the drivers for the real display
hardware.

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 |  8 ++++
 hw/display/ramfb.c         | 95 ++++++++++++++++++++++++++++++++++++++++++++++
 hw/display/Makefile.objs   |  2 +
 3 files changed, 105 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..f3a772e99e
--- /dev/null
+++ b/include/hw/display/ramfb.h
@@ -0,0 +1,8 @@
+#ifndef RAMFB_H
+#define RAMFB_H
+
+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..5425e1feb1
--- /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);
+    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(con, 0, 0, s->width, s->height);
+}
+
+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);
+
+    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);
+    return s;
+}
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index 3c7c75b94d..fae17fd5ea 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

  parent reply	other threads:[~2018-03-23 12:25 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-23 12:25 [Qemu-devel] [PATCH v2 0/7] ramfb: simple boot framebuffer, no legacy vga Gerd Hoffmann
2018-03-23 12:25 ` [Qemu-devel] [PATCH v2 1/7] [testing] update bios, add vgabios-ramfb Gerd Hoffmann
2018-03-23 12:25 ` [Qemu-devel] [PATCH v2 2/7] [testing] add ovmf build with ramfb support Gerd Hoffmann
2018-03-23 12:25 ` Gerd Hoffmann [this message]
2018-03-23 12:25 ` [Qemu-devel] [PATCH v2 4/7] hw/display: add ramfb-testdev Gerd Hoffmann
2018-03-23 12:25 ` [Qemu-devel] [PATCH v2 5/7] hw/display: add virtio-ramfb Gerd Hoffmann
2018-03-23 12:25 ` [Qemu-devel] [PATCH v2 6/7] hw/vfio/display: add ramfb support Gerd Hoffmann
2018-03-23 12:25 ` [Qemu-devel] [PATCH v2 7/7] [wip] hw/display: add qxl-ramfb Gerd Hoffmann
2018-03-23 13:27 ` [Qemu-devel] [PATCH v2 0/7] ramfb: simple boot framebuffer, no legacy vga Laszlo Ersek
2018-03-23 14:51   ` Gerd Hoffmann
2018-03-23 15:12     ` Laszlo Ersek
2018-03-23 17:07       ` Gerd Hoffmann
2018-03-23 18:29         ` Laszlo Ersek
2018-03-24  3:51   ` Ard Biesheuvel
2018-04-25 14:07   ` Gerd Hoffmann
2018-04-25 20:43     ` Laszlo Ersek
2018-05-31  8:43       ` Gerd Hoffmann
2018-05-31  9:11         ` Laszlo Ersek
2018-06-05 11:06           ` Gerd Hoffmann
2018-06-05 12:07             ` Laszlo Ersek
2018-06-05 13:16               ` Gerd Hoffmann
2018-06-05 13:23                 ` Laszlo Ersek
2018-06-06  8:49                   ` Gerd Hoffmann
2018-06-06 12:43                     ` Laszlo Ersek
2018-06-06 13:21                       ` Gerd Hoffmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180323122520.11270-4-kraxel@redhat.com \
    --to=kraxel@redhat.com \
    --cc=alex.williamson@redhat.com \
    --cc=lersek@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).