mirror of https://github.com/xemu-project/xemu.git
MAINTAINERS: audio updates
microvm: device tree support console: chardev fixes misc: deprecate sga usb: fix struct usb_msd_csw -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEoDKM/7k6F6eZAf59TLbY7tPocTgFAmGBZp8ACgkQTLbY7tPo cTg/fxAAj4z7EqdQXykN4ra+JWbmxp9KE4Y7uDb7XIuzG1KRU/7zZeVaZ2+0X1R9 9LicHo4wd0DN3JfHrkrQrpEN22zB0x7zUh9/5F7jtdOUzKf8GuhxBq9EmFpS5Uk1 w4a/5bEmbfOf9G9kGm6DWFvUGj9AzmeCoJFCGxzWTjcqNQlyk/P1Plsq7m21RIXy le2tCevivE6LzxGZLXBH3YO0wjI6oSHBGaN9/0lOj4bUMGls5NpRB9gFR8IFcFeo XTGeJeB+INVt3/kTft65HkPqLif9FU/8Q/cqiglauLUyLFRVwe1sGtL7gnwmYBat xELqemBp0eVId+X1EOjkx2jdd70pwTxLT0alG/e34PsWF020AJIYvgLkXYS0FUqV PZDILgz6bGJ7o+vy0uYDzS20wMjBYhZ5UCuew4rN9xRxWA1qdJ8pk+4Bmal77oxQ cn/7pSkhD/Yz6ya/7yFNzzhy44Id8WRlYTbtjrgSvISSW+UHFotT/+io3dzdRuzC DnXl+DusxiCbNm0uE6xufS1gQLMlWqy8eAYrforIziVJG+RpxRjU0bTtzqyTqjm4 MPiBWTM5InbM7IhoRo+x00vREPO5nGmtKCruaYW39uxT7MXQvociFObnspuwdfsc ZWwsMH79DSjpx8lXYyyls5uyEIgjY6mPYL9r8m1b2T05EF6Vy9E= =cLSX -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/misc-20211102-pull-request' into staging MAINTAINERS: audio updates microvm: device tree support console: chardev fixes misc: deprecate sga usb: fix struct usb_msd_csw # gpg: Signature made Tue 02 Nov 2021 12:26:07 PM EDT # gpg: using RSA key A0328CFFB93A17A79901FE7D4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full] * remotes/kraxel/tags/misc-20211102-pull-request: usb-storage: tag usb_msd_csw as packed struct hw/misc: deprecate the 'sga' device ui/console: remove chardev frontend connected test ui/console: replace kbd_timer with chr_accept_input callback ui/console: replace QEMUFIFO with Fifo8 ui/gtk: skip any extra draw of same guest scanout blob res ui/gtk: Update the refresh rate for gl-area too microvm: add device tree support. MAINTAINERS: add myself as partial audio reviewer MAINTAINERS: Add myself as a reviewer for SDL audio Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
58b6476164
|
@ -575,7 +575,6 @@ build-without-default-features:
|
|||
CONFIGURE_ARGS:
|
||||
--without-default-features
|
||||
--disable-capstone
|
||||
--disable-fdt
|
||||
--disable-pie
|
||||
--disable-qom-cast-debug
|
||||
--disable-slirp
|
||||
|
|
|
@ -2302,11 +2302,13 @@ F: qapi/audio.json
|
|||
|
||||
ALSA Audio backend
|
||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||
R: Christian Schoenebeck <qemu_oss@crudebyte.com>
|
||||
S: Odd Fixes
|
||||
F: audio/alsaaudio.c
|
||||
|
||||
Core Audio framework backend
|
||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||
R: Christian Schoenebeck <qemu_oss@crudebyte.com>
|
||||
S: Odd Fixes
|
||||
F: audio/coreaudio.c
|
||||
|
||||
|
@ -2317,6 +2319,7 @@ F: audio/dsound*
|
|||
|
||||
JACK Audio Connection Kit backend
|
||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||
R: Christian Schoenebeck <qemu_oss@crudebyte.com>
|
||||
S: Odd Fixes
|
||||
F: audio/jackaudio.c
|
||||
|
||||
|
@ -2332,6 +2335,7 @@ F: audio/paaudio.c
|
|||
|
||||
SDL Audio backend
|
||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||
R: Thomas Huth <huth@tuxfamily.org>
|
||||
S: Odd Fixes
|
||||
F: audio/sdlaudio.c
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
TARGET_ARCH=i386
|
||||
TARGET_SUPPORTS_MTTCG=y
|
||||
TARGET_NEED_FDT=y
|
||||
TARGET_XML_FILES= gdb-xml/i386-32bit.xml
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
TARGET_ARCH=x86_64
|
||||
TARGET_BASE_ARCH=i386
|
||||
TARGET_SUPPORTS_MTTCG=y
|
||||
TARGET_NEED_FDT=y
|
||||
TARGET_XML_FILES= gdb-xml/i386-64bit.xml
|
||||
|
|
|
@ -313,6 +313,16 @@ full SCSI support. Use virtio-scsi instead when SCSI passthrough is required.
|
|||
Note this also applies to ``-device virtio-blk-pci,scsi=on|off``, which is an
|
||||
alias.
|
||||
|
||||
``-device sga`` (since 6.2)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``sga`` device loads an option ROM for x86 targets which enables
|
||||
SeaBIOS to send messages to the serial console. SeaBIOS 1.11.0 onwards
|
||||
contains native support for this feature and thus use of the option
|
||||
ROM approach is obsolete. The native SeaBIOS support can be activated
|
||||
by using ``-machine graphics=off``.
|
||||
|
||||
|
||||
Block device options
|
||||
''''''''''''''''''''
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ static VGPUDMABuf
|
|||
dmabuf->buf.fourcc = qemu_pixman_to_drm_format(fb->format);
|
||||
dmabuf->buf.fd = res->dmabuf_fd;
|
||||
dmabuf->buf.allow_fences = true;
|
||||
|
||||
dmabuf->buf.draw_submitted = false;
|
||||
dmabuf->scanout_id = scanout_id;
|
||||
QTAILQ_INSERT_HEAD(&g->dmabuf.bufs, dmabuf, next);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ i386_ss.add(when: 'CONFIG_X86_IOMMU', if_true: files('x86-iommu.c'),
|
|||
if_false: files('x86-iommu-stub.c'))
|
||||
i386_ss.add(when: 'CONFIG_AMD_IOMMU', if_true: files('amd_iommu.c'))
|
||||
i386_ss.add(when: 'CONFIG_I440FX', if_true: files('pc_piix.c'))
|
||||
i386_ss.add(when: 'CONFIG_MICROVM', if_true: files('microvm.c', 'acpi-microvm.c'))
|
||||
i386_ss.add(when: 'CONFIG_MICROVM', if_true: files('microvm.c', 'acpi-microvm.c', 'microvm-dt.c'))
|
||||
i386_ss.add(when: 'CONFIG_Q35', if_true: files('pc_q35.c'))
|
||||
i386_ss.add(when: 'CONFIG_VMMOUSE', if_true: files('vmmouse.c'))
|
||||
i386_ss.add(when: 'CONFIG_VMPORT', if_true: files('vmport.c'))
|
||||
|
|
|
@ -0,0 +1,341 @@
|
|||
/*
|
||||
* microvm device tree support
|
||||
*
|
||||
* This generates an device tree for microvm and exports it via fw_cfg
|
||||
* as "etc/fdt" to the firmware (edk2 specifically).
|
||||
*
|
||||
* The use case is to allow edk2 find the pcie ecam and the virtio
|
||||
* devices, without adding an ACPI parser, reusing the fdt parser
|
||||
* which is needed anyway for the arm platform.
|
||||
*
|
||||
* Note 1: The device tree is incomplete. CPUs and memory is missing
|
||||
* for example, those can be detected using other fw_cfg files.
|
||||
* Also pci ecam irq routing is not there, edk2 doesn't use
|
||||
* interrupts.
|
||||
*
|
||||
* Note 2: This is for firmware only. OSes should use the more
|
||||
* complete ACPI tables for hardware discovery.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2 or later, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "sysemu/device_tree.h"
|
||||
#include "hw/char/serial.h"
|
||||
#include "hw/i386/fw_cfg.h"
|
||||
#include "hw/rtc/mc146818rtc.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/virtio/virtio-mmio.h"
|
||||
#include "hw/usb/xhci.h"
|
||||
|
||||
#include "microvm-dt.h"
|
||||
|
||||
static bool debug;
|
||||
|
||||
static void dt_add_microvm_irq(MicrovmMachineState *mms,
|
||||
const char *nodename, uint32_t irq)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
if (irq >= IO_APIC_SECONDARY_IRQBASE) {
|
||||
irq -= IO_APIC_SECONDARY_IRQBASE;
|
||||
index++;
|
||||
}
|
||||
|
||||
qemu_fdt_setprop_cell(mms->fdt, nodename, "interrupt-parent",
|
||||
mms->ioapic_phandle[index]);
|
||||
qemu_fdt_setprop_cells(mms->fdt, nodename, "interrupts", irq, 0);
|
||||
}
|
||||
|
||||
static void dt_add_virtio(MicrovmMachineState *mms, VirtIOMMIOProxy *mmio)
|
||||
{
|
||||
SysBusDevice *dev = SYS_BUS_DEVICE(mmio);
|
||||
VirtioBusState *mmio_virtio_bus = &mmio->bus;
|
||||
BusState *mmio_bus = &mmio_virtio_bus->parent_obj;
|
||||
char *nodename;
|
||||
|
||||
if (QTAILQ_EMPTY(&mmio_bus->children)) {
|
||||
return;
|
||||
}
|
||||
|
||||
hwaddr base = dev->mmio[0].addr;
|
||||
hwaddr size = 512;
|
||||
unsigned index = (base - VIRTIO_MMIO_BASE) / size;
|
||||
uint32_t irq = mms->virtio_irq_base + index;
|
||||
|
||||
nodename = g_strdup_printf("/virtio_mmio@%" PRIx64, base);
|
||||
qemu_fdt_add_subnode(mms->fdt, nodename);
|
||||
qemu_fdt_setprop_string(mms->fdt, nodename, "compatible", "virtio,mmio");
|
||||
qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "reg", 2, base, 2, size);
|
||||
qemu_fdt_setprop(mms->fdt, nodename, "dma-coherent", NULL, 0);
|
||||
dt_add_microvm_irq(mms, nodename, irq);
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
static void dt_add_xhci(MicrovmMachineState *mms)
|
||||
{
|
||||
const char compat[] = "generic-xhci";
|
||||
uint32_t irq = MICROVM_XHCI_IRQ;
|
||||
hwaddr base = MICROVM_XHCI_BASE;
|
||||
hwaddr size = XHCI_LEN_REGS;
|
||||
char *nodename;
|
||||
|
||||
nodename = g_strdup_printf("/usb@%" PRIx64, base);
|
||||
qemu_fdt_add_subnode(mms->fdt, nodename);
|
||||
qemu_fdt_setprop(mms->fdt, nodename, "compatible", compat, sizeof(compat));
|
||||
qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "reg", 2, base, 2, size);
|
||||
qemu_fdt_setprop(mms->fdt, nodename, "dma-coherent", NULL, 0);
|
||||
dt_add_microvm_irq(mms, nodename, irq);
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
static void dt_add_pcie(MicrovmMachineState *mms)
|
||||
{
|
||||
hwaddr base = PCIE_MMIO_BASE;
|
||||
int nr_pcie_buses;
|
||||
char *nodename;
|
||||
|
||||
nodename = g_strdup_printf("/pcie@%" PRIx64, base);
|
||||
qemu_fdt_add_subnode(mms->fdt, nodename);
|
||||
qemu_fdt_setprop_string(mms->fdt, nodename,
|
||||
"compatible", "pci-host-ecam-generic");
|
||||
qemu_fdt_setprop_string(mms->fdt, nodename, "device_type", "pci");
|
||||
qemu_fdt_setprop_cell(mms->fdt, nodename, "#address-cells", 3);
|
||||
qemu_fdt_setprop_cell(mms->fdt, nodename, "#size-cells", 2);
|
||||
qemu_fdt_setprop_cell(mms->fdt, nodename, "linux,pci-domain", 0);
|
||||
qemu_fdt_setprop(mms->fdt, nodename, "dma-coherent", NULL, 0);
|
||||
|
||||
qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "reg",
|
||||
2, PCIE_ECAM_BASE, 2, PCIE_ECAM_SIZE);
|
||||
if (mms->gpex.mmio64.size) {
|
||||
qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "ranges",
|
||||
|
||||
1, FDT_PCI_RANGE_MMIO,
|
||||
2, mms->gpex.mmio32.base,
|
||||
2, mms->gpex.mmio32.base,
|
||||
2, mms->gpex.mmio32.size,
|
||||
|
||||
1, FDT_PCI_RANGE_MMIO_64BIT,
|
||||
2, mms->gpex.mmio64.base,
|
||||
2, mms->gpex.mmio64.base,
|
||||
2, mms->gpex.mmio64.size);
|
||||
} else {
|
||||
qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "ranges",
|
||||
|
||||
1, FDT_PCI_RANGE_MMIO,
|
||||
2, mms->gpex.mmio32.base,
|
||||
2, mms->gpex.mmio32.base,
|
||||
2, mms->gpex.mmio32.size);
|
||||
}
|
||||
|
||||
nr_pcie_buses = PCIE_ECAM_SIZE / PCIE_MMCFG_SIZE_MIN;
|
||||
qemu_fdt_setprop_cells(mms->fdt, nodename, "bus-range", 0,
|
||||
nr_pcie_buses - 1);
|
||||
}
|
||||
|
||||
static void dt_add_ioapic(MicrovmMachineState *mms, SysBusDevice *dev)
|
||||
{
|
||||
hwaddr base = dev->mmio[0].addr;
|
||||
char *nodename;
|
||||
uint32_t ph;
|
||||
int index;
|
||||
|
||||
switch (base) {
|
||||
case IO_APIC_DEFAULT_ADDRESS:
|
||||
index = 0;
|
||||
break;
|
||||
case IO_APIC_SECONDARY_ADDRESS:
|
||||
index = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unknown ioapic @ %" PRIx64 "\n", base);
|
||||
return;
|
||||
}
|
||||
|
||||
nodename = g_strdup_printf("/ioapic%d@%" PRIx64, index + 1, base);
|
||||
qemu_fdt_add_subnode(mms->fdt, nodename);
|
||||
qemu_fdt_setprop_string(mms->fdt, nodename,
|
||||
"compatible", "intel,ce4100-ioapic");
|
||||
qemu_fdt_setprop(mms->fdt, nodename, "interrupt-controller", NULL, 0);
|
||||
qemu_fdt_setprop_cell(mms->fdt, nodename, "#interrupt-cells", 0x2);
|
||||
qemu_fdt_setprop_cell(mms->fdt, nodename, "#address-cells", 0x2);
|
||||
qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "reg",
|
||||
2, base, 2, 0x1000);
|
||||
|
||||
ph = qemu_fdt_alloc_phandle(mms->fdt);
|
||||
qemu_fdt_setprop_cell(mms->fdt, nodename, "phandle", ph);
|
||||
qemu_fdt_setprop_cell(mms->fdt, nodename, "linux,phandle", ph);
|
||||
mms->ioapic_phandle[index] = ph;
|
||||
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
static void dt_add_isa_serial(MicrovmMachineState *mms, ISADevice *dev)
|
||||
{
|
||||
const char compat[] = "ns16550";
|
||||
uint32_t irq = object_property_get_int(OBJECT(dev), "irq", NULL);
|
||||
hwaddr base = object_property_get_int(OBJECT(dev), "iobase", NULL);
|
||||
hwaddr size = 8;
|
||||
char *nodename;
|
||||
|
||||
nodename = g_strdup_printf("/serial@%" PRIx64, base);
|
||||
qemu_fdt_add_subnode(mms->fdt, nodename);
|
||||
qemu_fdt_setprop(mms->fdt, nodename, "compatible", compat, sizeof(compat));
|
||||
qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "reg", 2, base, 2, size);
|
||||
dt_add_microvm_irq(mms, nodename, irq);
|
||||
|
||||
if (base == 0x3f8 /* com1 */) {
|
||||
qemu_fdt_setprop_string(mms->fdt, "/chosen", "stdout-path", nodename);
|
||||
}
|
||||
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
static void dt_add_isa_rtc(MicrovmMachineState *mms, ISADevice *dev)
|
||||
{
|
||||
const char compat[] = "motorola,mc146818";
|
||||
uint32_t irq = RTC_ISA_IRQ;
|
||||
hwaddr base = RTC_ISA_BASE;
|
||||
hwaddr size = 8;
|
||||
char *nodename;
|
||||
|
||||
nodename = g_strdup_printf("/rtc@%" PRIx64, base);
|
||||
qemu_fdt_add_subnode(mms->fdt, nodename);
|
||||
qemu_fdt_setprop(mms->fdt, nodename, "compatible", compat, sizeof(compat));
|
||||
qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "reg", 2, base, 2, size);
|
||||
dt_add_microvm_irq(mms, nodename, irq);
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
static void dt_setup_isa_bus(MicrovmMachineState *mms, DeviceState *bridge)
|
||||
{
|
||||
BusState *bus = qdev_get_child_bus(bridge, "isa.0");
|
||||
BusChild *kid;
|
||||
Object *obj;
|
||||
|
||||
QTAILQ_FOREACH(kid, &bus->children, sibling) {
|
||||
DeviceState *dev = kid->child;
|
||||
|
||||
/* serial */
|
||||
obj = object_dynamic_cast(OBJECT(dev), TYPE_ISA_SERIAL);
|
||||
if (obj) {
|
||||
dt_add_isa_serial(mms, ISA_DEVICE(obj));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* rtc */
|
||||
obj = object_dynamic_cast(OBJECT(dev), TYPE_MC146818_RTC);
|
||||
if (obj) {
|
||||
dt_add_isa_rtc(mms, ISA_DEVICE(obj));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
fprintf(stderr, "%s: unhandled: %s\n", __func__,
|
||||
object_get_typename(OBJECT(dev)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dt_setup_sys_bus(MicrovmMachineState *mms)
|
||||
{
|
||||
BusState *bus;
|
||||
BusChild *kid;
|
||||
Object *obj;
|
||||
|
||||
/* sysbus devices */
|
||||
bus = sysbus_get_default();
|
||||
QTAILQ_FOREACH(kid, &bus->children, sibling) {
|
||||
DeviceState *dev = kid->child;
|
||||
|
||||
/* ioapic */
|
||||
obj = object_dynamic_cast(OBJECT(dev), TYPE_IOAPIC);
|
||||
if (obj) {
|
||||
dt_add_ioapic(mms, SYS_BUS_DEVICE(obj));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH(kid, &bus->children, sibling) {
|
||||
DeviceState *dev = kid->child;
|
||||
|
||||
/* virtio */
|
||||
obj = object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MMIO);
|
||||
if (obj) {
|
||||
dt_add_virtio(mms, VIRTIO_MMIO(obj));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* xhci */
|
||||
obj = object_dynamic_cast(OBJECT(dev), TYPE_XHCI_SYSBUS);
|
||||
if (obj) {
|
||||
dt_add_xhci(mms);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* pcie */
|
||||
obj = object_dynamic_cast(OBJECT(dev), TYPE_GPEX_HOST);
|
||||
if (obj) {
|
||||
dt_add_pcie(mms);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* isa */
|
||||
obj = object_dynamic_cast(OBJECT(dev), "isabus-bridge");
|
||||
if (obj) {
|
||||
dt_setup_isa_bus(mms, DEVICE(obj));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
obj = object_dynamic_cast(OBJECT(dev), TYPE_IOAPIC);
|
||||
if (obj) {
|
||||
/* ioapic already added in first pass */
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "%s: unhandled: %s\n", __func__,
|
||||
object_get_typename(OBJECT(dev)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dt_setup_microvm(MicrovmMachineState *mms)
|
||||
{
|
||||
X86MachineState *x86ms = X86_MACHINE(mms);
|
||||
int size = 0;
|
||||
|
||||
mms->fdt = create_device_tree(&size);
|
||||
|
||||
/* root node */
|
||||
qemu_fdt_setprop_string(mms->fdt, "/", "compatible", "linux,microvm");
|
||||
qemu_fdt_setprop_cell(mms->fdt, "/", "#address-cells", 0x2);
|
||||
qemu_fdt_setprop_cell(mms->fdt, "/", "#size-cells", 0x2);
|
||||
|
||||
qemu_fdt_add_subnode(mms->fdt, "/chosen");
|
||||
dt_setup_sys_bus(mms);
|
||||
|
||||
/* add to fw_cfg */
|
||||
fprintf(stderr, "%s: add etc/fdt to fw_cfg\n", __func__);
|
||||
fw_cfg_add_file(x86ms->fw_cfg, "etc/fdt", mms->fdt, size);
|
||||
|
||||
if (debug) {
|
||||
fprintf(stderr, "%s: writing microvm.fdt\n", __func__);
|
||||
g_file_set_contents("microvm.fdt", mms->fdt, size, NULL);
|
||||
int ret = system("dtc -I dtb -O dts microvm.fdt");
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "%s: oops, dtc not installed?\n", __func__);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef HW_I386_MICROVM_DT_H
|
||||
#define HW_I386_MICROVM_DT_H
|
||||
|
||||
#include "hw/i386/microvm.h"
|
||||
|
||||
void dt_setup_microvm(MicrovmMachineState *mms);
|
||||
|
||||
#endif
|
|
@ -28,6 +28,7 @@
|
|||
#include "sysemu/reset.h"
|
||||
#include "sysemu/runstate.h"
|
||||
#include "acpi-microvm.h"
|
||||
#include "microvm-dt.h"
|
||||
|
||||
#include "hw/loader.h"
|
||||
#include "hw/irq.h"
|
||||
|
@ -626,6 +627,7 @@ static void microvm_machine_done(Notifier *notifier, void *data)
|
|||
machine_done);
|
||||
|
||||
acpi_setup_microvm(mms);
|
||||
dt_setup_microvm(mms);
|
||||
}
|
||||
|
||||
static void microvm_powerdown_req(Notifier *notifier, void *data)
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "hw/loader.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qom/object.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
||||
#define SGABIOS_FILENAME "sgabios.bin"
|
||||
|
||||
|
@ -42,6 +43,7 @@ struct ISASGAState {
|
|||
|
||||
static void sga_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
warn_report("-device sga is deprecated, use -machine graphics=off");
|
||||
rom_add_vga(SGABIOS_FILENAME);
|
||||
}
|
||||
|
||||
|
|
|
@ -104,6 +104,10 @@ struct MicrovmMachineState {
|
|||
Notifier machine_done;
|
||||
Notifier powerdown_req;
|
||||
struct GPEXConfig gpex;
|
||||
|
||||
/* device tree */
|
||||
void *fdt;
|
||||
uint32_t ioapic_phandle[2];
|
||||
};
|
||||
|
||||
#define TYPE_MICROVM_MACHINE MACHINE_TYPE_NAME("microvm")
|
||||
|
|
|
@ -17,7 +17,7 @@ enum USBMSDMode {
|
|||
USB_MSDM_CSW /* Command Status. */
|
||||
};
|
||||
|
||||
struct usb_msd_csw {
|
||||
struct QEMU_PACKED usb_msd_csw {
|
||||
uint32_t sig;
|
||||
uint32_t tag;
|
||||
uint32_t residue;
|
||||
|
|
|
@ -171,6 +171,7 @@ typedef struct QemuDmaBuf {
|
|||
void *sync;
|
||||
int fence_fd;
|
||||
bool allow_fences;
|
||||
bool draw_submitted;
|
||||
} QemuDmaBuf;
|
||||
|
||||
typedef struct DisplayState DisplayState;
|
||||
|
|
109
ui/console.c
109
ui/console.c
|
@ -27,10 +27,12 @@
|
|||
#include "hw/qdev-core.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qapi-commands-ui.h"
|
||||
#include "qemu/fifo8.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/option.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "chardev/char-fe.h"
|
||||
#include "chardev/char.h"
|
||||
#include "trace.h"
|
||||
#include "exec/memory.h"
|
||||
#include "io/channel-file.h"
|
||||
|
@ -62,57 +64,6 @@ enum TTYState {
|
|||
TTY_STATE_CSI,
|
||||
};
|
||||
|
||||
typedef struct QEMUFIFO {
|
||||
uint8_t *buf;
|
||||
int buf_size;
|
||||
int count, wptr, rptr;
|
||||
} QEMUFIFO;
|
||||
|
||||
static int qemu_fifo_write(QEMUFIFO *f, const uint8_t *buf, int len1)
|
||||
{
|
||||
int l, len;
|
||||
|
||||
l = f->buf_size - f->count;
|
||||
if (len1 > l)
|
||||
len1 = l;
|
||||
len = len1;
|
||||
while (len > 0) {
|
||||
l = f->buf_size - f->wptr;
|
||||
if (l > len)
|
||||
l = len;
|
||||
memcpy(f->buf + f->wptr, buf, l);
|
||||
f->wptr += l;
|
||||
if (f->wptr >= f->buf_size)
|
||||
f->wptr = 0;
|
||||
buf += l;
|
||||
len -= l;
|
||||
}
|
||||
f->count += len1;
|
||||
return len1;
|
||||
}
|
||||
|
||||
static int qemu_fifo_read(QEMUFIFO *f, uint8_t *buf, int len1)
|
||||
{
|
||||
int l, len;
|
||||
|
||||
if (len1 > f->count)
|
||||
len1 = f->count;
|
||||
len = len1;
|
||||
while (len > 0) {
|
||||
l = f->buf_size - f->rptr;
|
||||
if (l > len)
|
||||
l = len;
|
||||
memcpy(buf, f->buf + f->rptr, l);
|
||||
f->rptr += l;
|
||||
if (f->rptr >= f->buf_size)
|
||||
f->rptr = 0;
|
||||
buf += l;
|
||||
len -= l;
|
||||
}
|
||||
f->count -= len1;
|
||||
return len1;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
GRAPHIC_CONSOLE,
|
||||
TEXT_CONSOLE,
|
||||
|
@ -165,9 +116,7 @@ struct QemuConsole {
|
|||
|
||||
Chardev *chr;
|
||||
/* fifo for key pressed */
|
||||
QEMUFIFO out_fifo;
|
||||
uint8_t out_fifo_buf[16];
|
||||
QEMUTimer *kbd_timer;
|
||||
Fifo8 out_fifo;
|
||||
CoQueue dump_queue;
|
||||
|
||||
QTAILQ_ENTRY(QemuConsole) next;
|
||||
|
@ -1157,25 +1106,20 @@ static int vc_chr_write(Chardev *chr, const uint8_t *buf, int len)
|
|||
return len;
|
||||
}
|
||||
|
||||
static void kbd_send_chars(void *opaque)
|
||||
static void kbd_send_chars(QemuConsole *s)
|
||||
{
|
||||
QemuConsole *s = opaque;
|
||||
int len;
|
||||
uint8_t buf[16];
|
||||
uint32_t len, avail;
|
||||
|
||||
len = qemu_chr_be_can_write(s->chr);
|
||||
if (len > s->out_fifo.count)
|
||||
len = s->out_fifo.count;
|
||||
if (len > 0) {
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
||||
qemu_fifo_read(&s->out_fifo, buf, len);
|
||||
qemu_chr_be_write(s->chr, buf, len);
|
||||
}
|
||||
/* characters are pending: we send them a bit later (XXX:
|
||||
horrible, should change char device API) */
|
||||
if (s->out_fifo.count > 0) {
|
||||
timer_mod(s->kbd_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1);
|
||||
avail = fifo8_num_used(&s->out_fifo);
|
||||
while (len > 0 && avail > 0) {
|
||||
const uint8_t *buf;
|
||||
uint32_t size;
|
||||
|
||||
buf = fifo8_pop_buf(&s->out_fifo, MIN(len, avail), &size);
|
||||
qemu_chr_be_write(s->chr, (uint8_t *)buf, size);
|
||||
len = qemu_chr_be_can_write(s->chr);
|
||||
avail -= size;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1183,8 +1127,8 @@ static void kbd_send_chars(void *opaque)
|
|||
void kbd_put_keysym_console(QemuConsole *s, int keysym)
|
||||
{
|
||||
uint8_t buf[16], *q;
|
||||
CharBackend *be;
|
||||
int c;
|
||||
uint32_t num_free;
|
||||
|
||||
if (!s || (s->console_type == GRAPHIC_CONSOLE))
|
||||
return;
|
||||
|
@ -1226,11 +1170,9 @@ void kbd_put_keysym_console(QemuConsole *s, int keysym)
|
|||
if (s->echo) {
|
||||
vc_chr_write(s->chr, buf, q - buf);
|
||||
}
|
||||
be = s->chr->be;
|
||||
if (be && be->chr_read) {
|
||||
qemu_fifo_write(&s->out_fifo, buf, q - buf);
|
||||
kbd_send_chars(s);
|
||||
}
|
||||
num_free = fifo8_num_free(&s->out_fifo);
|
||||
fifo8_push_all(&s->out_fifo, buf, MIN(num_free, q - buf));
|
||||
kbd_send_chars(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2186,6 +2128,14 @@ int qemu_console_get_height(QemuConsole *con, int fallback)
|
|||
return con ? surface_height(con->surface) : fallback;
|
||||
}
|
||||
|
||||
static void vc_chr_accept_input(Chardev *chr)
|
||||
{
|
||||
VCChardev *drv = VC_CHARDEV(chr);
|
||||
QemuConsole *s = drv->console;
|
||||
|
||||
kbd_send_chars(s);
|
||||
}
|
||||
|
||||
static void vc_chr_set_echo(Chardev *chr, bool echo)
|
||||
{
|
||||
VCChardev *drv = VC_CHARDEV(chr);
|
||||
|
@ -2233,9 +2183,7 @@ static void text_console_do_init(Chardev *chr, DisplayState *ds)
|
|||
int g_width = 80 * FONT_WIDTH;
|
||||
int g_height = 24 * FONT_HEIGHT;
|
||||
|
||||
s->out_fifo.buf = s->out_fifo_buf;
|
||||
s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
|
||||
s->kbd_timer = timer_new_ms(QEMU_CLOCK_REALTIME, kbd_send_chars, s);
|
||||
fifo8_create(&s->out_fifo, 16);
|
||||
s->ds = ds;
|
||||
|
||||
s->y_displayed = 0;
|
||||
|
@ -2485,6 +2433,7 @@ static void char_vc_class_init(ObjectClass *oc, void *data)
|
|||
cc->parse = qemu_chr_parse_vc;
|
||||
cc->open = vc_chr_open;
|
||||
cc->chr_write = vc_chr_write;
|
||||
cc->chr_accept_input = vc_chr_accept_input;
|
||||
cc->chr_set_echo = vc_chr_set_echo;
|
||||
}
|
||||
|
||||
|
|
40
ui/gtk-egl.c
40
ui/gtk-egl.c
|
@ -63,6 +63,9 @@ void gd_egl_init(VirtualConsole *vc)
|
|||
void gd_egl_draw(VirtualConsole *vc)
|
||||
{
|
||||
GdkWindow *window;
|
||||
#ifdef CONFIG_GBM
|
||||
QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
|
||||
#endif
|
||||
int ww, wh;
|
||||
|
||||
if (!vc->gfx.gls) {
|
||||
|
@ -74,10 +77,31 @@ void gd_egl_draw(VirtualConsole *vc)
|
|||
wh = gdk_window_get_height(window);
|
||||
|
||||
if (vc->gfx.scanout_mode) {
|
||||
#ifdef CONFIG_GBM
|
||||
if (dmabuf) {
|
||||
if (!dmabuf->draw_submitted) {
|
||||
return;
|
||||
} else {
|
||||
dmabuf->draw_submitted = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
gd_egl_scanout_flush(&vc->gfx.dcl, 0, 0, vc->gfx.w, vc->gfx.h);
|
||||
|
||||
vc->gfx.scale_x = (double)ww / vc->gfx.w;
|
||||
vc->gfx.scale_y = (double)wh / vc->gfx.h;
|
||||
|
||||
glFlush();
|
||||
#ifdef CONFIG_GBM
|
||||
if (dmabuf) {
|
||||
egl_dmabuf_create_fence(dmabuf);
|
||||
if (dmabuf->fence_fd > 0) {
|
||||
qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
|
||||
return;
|
||||
}
|
||||
graphic_hw_gl_block(vc->gfx.dcl.con, false);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if (!vc->gfx.ds) {
|
||||
return;
|
||||
|
@ -92,21 +116,10 @@ void gd_egl_draw(VirtualConsole *vc)
|
|||
|
||||
vc->gfx.scale_x = (double)ww / surface_width(vc->gfx.ds);
|
||||
vc->gfx.scale_y = (double)wh / surface_height(vc->gfx.ds);
|
||||
|
||||
glFlush();
|
||||
}
|
||||
|
||||
glFlush();
|
||||
#ifdef CONFIG_GBM
|
||||
if (vc->gfx.guest_fb.dmabuf) {
|
||||
QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
|
||||
|
||||
egl_dmabuf_create_fence(dmabuf);
|
||||
if (dmabuf->fence_fd > 0) {
|
||||
qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
|
||||
return;
|
||||
}
|
||||
graphic_hw_gl_block(vc->gfx.dcl.con, false);
|
||||
}
|
||||
#endif
|
||||
graphic_hw_gl_flushed(vc->gfx.dcl.con);
|
||||
}
|
||||
|
||||
|
@ -317,6 +330,7 @@ void gd_egl_flush(DisplayChangeListener *dcl,
|
|||
|
||||
if (vc->gfx.guest_fb.dmabuf) {
|
||||
graphic_hw_gl_block(vc->gfx.dcl.con, true);
|
||||
vc->gfx.guest_fb.dmabuf->draw_submitted = true;
|
||||
gtk_widget_queue_draw_area(area, x, y, w, h);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,9 @@ static void gtk_gl_area_set_scanout_mode(VirtualConsole *vc, bool scanout)
|
|||
|
||||
void gd_gl_area_draw(VirtualConsole *vc)
|
||||
{
|
||||
#ifdef CONFIG_GBM
|
||||
QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
|
||||
#endif
|
||||
int ww, wh, y1, y2;
|
||||
|
||||
if (!vc->gfx.gls) {
|
||||
|
@ -53,6 +56,16 @@ void gd_gl_area_draw(VirtualConsole *vc)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GBM
|
||||
if (dmabuf) {
|
||||
if (!dmabuf->draw_submitted) {
|
||||
return;
|
||||
} else {
|
||||
dmabuf->draw_submitted = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.guest_fb.framebuffer);
|
||||
/* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */
|
||||
|
||||
|
@ -62,6 +75,22 @@ void gd_gl_area_draw(VirtualConsole *vc)
|
|||
glBlitFramebuffer(0, y1, vc->gfx.w, y2,
|
||||
0, 0, ww, wh,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
#ifdef CONFIG_GBM
|
||||
if (dmabuf) {
|
||||
egl_dmabuf_create_sync(dmabuf);
|
||||
}
|
||||
#endif
|
||||
glFlush();
|
||||
#ifdef CONFIG_GBM
|
||||
if (dmabuf) {
|
||||
egl_dmabuf_create_fence(dmabuf);
|
||||
if (dmabuf->fence_fd > 0) {
|
||||
qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
|
||||
return;
|
||||
}
|
||||
graphic_hw_gl_block(vc->gfx.dcl.con, false);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if (!vc->gfx.ds) {
|
||||
return;
|
||||
|
@ -72,25 +101,6 @@ void gd_gl_area_draw(VirtualConsole *vc)
|
|||
surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GBM
|
||||
if (vc->gfx.guest_fb.dmabuf) {
|
||||
egl_dmabuf_create_sync(vc->gfx.guest_fb.dmabuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
glFlush();
|
||||
#ifdef CONFIG_GBM
|
||||
if (vc->gfx.guest_fb.dmabuf) {
|
||||
QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
|
||||
|
||||
egl_dmabuf_create_fence(dmabuf);
|
||||
if (dmabuf->fence_fd > 0) {
|
||||
qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
|
||||
return;
|
||||
}
|
||||
graphic_hw_gl_block(vc->gfx.dcl.con, false);
|
||||
}
|
||||
#endif
|
||||
graphic_hw_gl_flushed(vc->gfx.dcl.con);
|
||||
}
|
||||
|
||||
|
@ -112,6 +122,9 @@ void gd_gl_area_refresh(DisplayChangeListener *dcl)
|
|||
{
|
||||
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
||||
|
||||
vc->gfx.dcl.update_interval = gd_monitor_update_interval(
|
||||
vc->window ? vc->window : vc->gfx.drawing_area);
|
||||
|
||||
if (!vc->gfx.gls) {
|
||||
if (!gtk_widget_get_realized(vc->gfx.drawing_area)) {
|
||||
return;
|
||||
|
@ -234,6 +247,7 @@ void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
|
|||
|
||||
if (vc->gfx.guest_fb.dmabuf) {
|
||||
graphic_hw_gl_block(vc->gfx.dcl.con, true);
|
||||
vc->gfx.guest_fb.dmabuf->draw_submitted = true;
|
||||
}
|
||||
gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue