summaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/npcm7xx.c12
-rw-r--r--hw/arm/npcm7xx_boards.c20
-rw-r--r--hw/arm/virt.c4
-rw-r--r--hw/core/loader.c39
-rw-r--r--hw/core/machine-hmp-cmds.c38
-rw-r--r--hw/core/machine-qmp-cmds.c40
-rw-r--r--hw/core/machine.c3
-rw-r--r--hw/display/virtio-gpu-udmabuf.c2
-rw-r--r--hw/i386/intel_iommu.c2
-rw-r--r--hw/i386/meson.build2
-rw-r--r--hw/i386/microvm-dt.c341
-rw-r--r--hw/i386/microvm-dt.h8
-rw-r--r--hw/i386/microvm.c7
-rw-r--r--hw/i386/multiboot.c10
-rw-r--r--hw/i386/multiboot.h4
-rw-r--r--hw/i386/pc.c10
-rw-r--r--hw/i386/pc_piix.c3
-rw-r--r--hw/i386/pc_q35.c3
-rw-r--r--hw/i386/x86.c7
-rw-r--r--hw/input/lasips2.c8
-rw-r--r--hw/misc/sga.c2
-rw-r--r--hw/rdma/rdma_rm.c104
-rw-r--r--hw/rdma/rdma_rm.h2
-rw-r--r--hw/rdma/vmw/pvrdma_main.c31
-rw-r--r--hw/scsi/esp.c10
-rw-r--r--hw/sd/meson.build1
-rw-r--r--hw/sd/npcm7xx_sdhci.c182
-rw-r--r--hw/usb/bus.c24
-rw-r--r--hw/watchdog/sbsa_gwdt.c3
-rw-r--r--hw/watchdog/watchdog.c14
-rw-r--r--hw/watchdog/wdt_aspeed.c3
-rw-r--r--hw/watchdog/wdt_diag288.c3
-rw-r--r--hw/watchdog/wdt_i6300esb.c3
-rw-r--r--hw/watchdog/wdt_ib700.c3
-rw-r--r--hw/watchdog/wdt_imx2.c4
35 files changed, 771 insertions, 181 deletions
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 2ab0080e0b..878c2208e0 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -63,6 +63,8 @@
#define NPCM7XX_ROM_BA (0xffff0000)
#define NPCM7XX_ROM_SZ (64 * KiB)
+/* SDHCI Modules */
+#define NPCM7XX_MMC_BA (0xf0842000)
/* Clock configuration values to be fixed up when bypassing bootloader */
@@ -83,6 +85,7 @@ enum NPCM7xxInterrupt {
NPCM7XX_UART3_IRQ,
NPCM7XX_EMC1RX_IRQ = 15,
NPCM7XX_EMC1TX_IRQ,
+ NPCM7XX_MMC_IRQ = 26,
NPCM7XX_TIMER0_IRQ = 32, /* Timer Module 0 */
NPCM7XX_TIMER1_IRQ,
NPCM7XX_TIMER2_IRQ,
@@ -443,6 +446,8 @@ static void npcm7xx_init(Object *obj)
for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
object_initialize_child(obj, "emc[*]", &s->emc[i], TYPE_NPCM7XX_EMC);
}
+
+ object_initialize_child(obj, "mmc", &s->mmc, TYPE_NPCM7XX_SDHCI);
}
static void npcm7xx_realize(DeviceState *dev, Error **errp)
@@ -707,6 +712,12 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
&error_abort);
memory_region_add_subregion(get_system_memory(), NPCM7XX_ROM_BA, &s->irom);
+ /* SDHCI */
+ sysbus_realize(SYS_BUS_DEVICE(&s->mmc), &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->mmc), 0, NPCM7XX_MMC_BA);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc), 0,
+ npcm7xx_irq(s, NPCM7XX_MMC_IRQ));
+
create_unimplemented_device("npcm7xx.shm", 0xc0001000, 4 * KiB);
create_unimplemented_device("npcm7xx.vdmx", 0xe0800000, 4 * KiB);
create_unimplemented_device("npcm7xx.pcierc", 0xe1000000, 64 * KiB);
@@ -736,7 +747,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
create_unimplemented_device("npcm7xx.usbd[8]", 0xf0838000, 4 * KiB);
create_unimplemented_device("npcm7xx.usbd[9]", 0xf0839000, 4 * KiB);
create_unimplemented_device("npcm7xx.sd", 0xf0840000, 8 * KiB);
- create_unimplemented_device("npcm7xx.mmc", 0xf0842000, 8 * KiB);
create_unimplemented_device("npcm7xx.pcimbx", 0xf0848000, 512 * KiB);
create_unimplemented_device("npcm7xx.aes", 0xf0858000, 4 * KiB);
create_unimplemented_device("npcm7xx.des", 0xf0859000, 4 * KiB);
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index a656169f61..dec7d16ae5 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -27,6 +27,9 @@
#include "qemu-common.h"
#include "qemu/datadir.h"
#include "qemu/units.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/block-backend.h"
#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
@@ -81,6 +84,22 @@ static void npcm7xx_connect_dram(NPCM7xxState *soc, MemoryRegion *dram)
&error_abort);
}
+static void sdhci_attach_drive(SDHCIState *sdhci)
+{
+ DriveInfo *di = drive_get_next(IF_SD);
+ BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
+
+ BusState *bus = qdev_get_child_bus(DEVICE(sdhci), "sd-bus");
+ if (bus == NULL) {
+ error_report("No SD bus found in SOC object");
+ exit(1);
+ }
+
+ DeviceState *carddev = qdev_new(TYPE_SD_CARD);
+ qdev_prop_set_drive_err(carddev, "drive", blk, &error_fatal);
+ qdev_realize_and_unref(carddev, bus, &error_fatal);
+}
+
static NPCM7xxState *npcm7xx_create_soc(MachineState *machine,
uint32_t hw_straps)
{
@@ -355,6 +374,7 @@ static void quanta_gbs_init(MachineState *machine)
drive_get(IF_MTD, 0, 0));
quanta_gbs_i2c_init(soc);
+ sdhci_attach_drive(&soc->mmc.sdhci);
npcm7xx_load_kernel(machine, soc);
}
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index ca433adb5b..369552ad45 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2737,10 +2737,10 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
"Set the IOMMU type. "
"Valid values are none and smmuv3");
- object_class_property_add_bool(oc, "default_bus_bypass_iommu",
+ object_class_property_add_bool(oc, "default-bus-bypass-iommu",
virt_get_default_bus_bypass_iommu,
virt_set_default_bus_bypass_iommu);
- object_class_property_set_description(oc, "default_bus_bypass_iommu",
+ object_class_property_set_description(oc, "default-bus-bypass-iommu",
"Set on/off to enable/disable "
"bypass_iommu for default root bus");
diff --git a/hw/core/loader.c b/hw/core/loader.c
index c7f97fdce8..052a0fd719 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -46,6 +46,8 @@
#include "qemu-common.h"
#include "qemu/datadir.h"
#include "qapi/error.h"
+#include "qapi/qapi-commands-machine.h"
+#include "qapi/type-helpers.h"
#include "trace.h"
#include "hw/hw.h"
#include "disas/disas.h"
@@ -1474,32 +1476,35 @@ void *rom_ptr_for_as(AddressSpace *as, hwaddr addr, size_t size)
return cbdata.rom;
}
-void hmp_info_roms(Monitor *mon, const QDict *qdict)
+HumanReadableText *qmp_x_query_roms(Error **errp)
{
Rom *rom;
+ g_autoptr(GString) buf = g_string_new("");
QTAILQ_FOREACH(rom, &roms, next) {
if (rom->mr) {
- monitor_printf(mon, "%s"
- " size=0x%06zx name=\"%s\"\n",
- memory_region_name(rom->mr),
- rom->romsize,
- rom->name);
+ g_string_append_printf(buf, "%s"
+ " size=0x%06zx name=\"%s\"\n",
+ memory_region_name(rom->mr),
+ rom->romsize,
+ rom->name);
} else if (!rom->fw_file) {
- monitor_printf(mon, "addr=" TARGET_FMT_plx
- " size=0x%06zx mem=%s name=\"%s\"\n",
- rom->addr, rom->romsize,
- rom->isrom ? "rom" : "ram",
- rom->name);
+ g_string_append_printf(buf, "addr=" TARGET_FMT_plx
+ " size=0x%06zx mem=%s name=\"%s\"\n",
+ rom->addr, rom->romsize,
+ rom->isrom ? "rom" : "ram",
+ rom->name);
} else {
- monitor_printf(mon, "fw=%s/%s"
- " size=0x%06zx name=\"%s\"\n",
- rom->fw_dir,
- rom->fw_file,
- rom->romsize,
- rom->name);
+ g_string_append_printf(buf, "fw=%s/%s"
+ " size=0x%06zx name=\"%s\"\n",
+ rom->fw_dir,
+ rom->fw_file,
+ rom->romsize,
+ rom->name);
}
}
+
+ return human_readable_text_from_str(buf);
}
typedef enum HexRecord HexRecord;
diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
index 76b22b00d6..4e2f319aeb 100644
--- a/hw/core/machine-hmp-cmds.c
+++ b/hw/core/machine-hmp-cmds.c
@@ -53,8 +53,7 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict)
HotpluggableCPUList *saved = l;
CpuInstanceProperties *c;
- if (err != NULL) {
- hmp_handle_error(mon, err);
+ if (hmp_handle_error(mon, err)) {
return;
}
@@ -131,38 +130,3 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict)
qapi_free_MemdevList(memdev_list);
hmp_handle_error(mon, err);
}
-
-void hmp_info_numa(Monitor *mon, const QDict *qdict)
-{
- int i, nb_numa_nodes;
- NumaNodeMem *node_mem;
- CpuInfoFastList *cpu_list, *cpu;
- MachineState *ms = MACHINE(qdev_get_machine());
-
- nb_numa_nodes = ms->numa_state ? ms->numa_state->num_nodes : 0;
- monitor_printf(mon, "%d nodes\n", nb_numa_nodes);
- if (!nb_numa_nodes) {
- return;
- }
-
- cpu_list = qmp_query_cpus_fast(&error_abort);
- node_mem = g_new0(NumaNodeMem, nb_numa_nodes);
-
- query_numa_node_mem(node_mem, ms);
- for (i = 0; i < nb_numa_nodes; i++) {
- monitor_printf(mon, "node %d cpus:", i);
- for (cpu = cpu_list; cpu; cpu = cpu->next) {
- if (cpu->value->has_props && cpu->value->props->has_node_id &&
- cpu->value->props->node_id == i) {
- monitor_printf(mon, " %" PRIi64, cpu->value->cpu_index);
- }
- }
- monitor_printf(mon, "\n");
- monitor_printf(mon, "node %d size: %" PRId64 " MB\n", i,
- node_mem[i].node_mem >> 20);
- monitor_printf(mon, "node %d plugged: %" PRId64 " MB\n", i,
- node_mem[i].node_plugged_mem >> 20);
- }
- qapi_free_CpuInfoFastList(cpu_list);
- g_free(node_mem);
-}
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index 216fdfaf3a..4f4ab30f8c 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -15,6 +15,7 @@
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qobject.h"
#include "qapi/qobject-input-visitor.h"
+#include "qapi/type-helpers.h"
#include "qemu/main-loop.h"
#include "qom/qom-qobject.h"
#include "sysemu/hostmem.h"
@@ -204,3 +205,42 @@ MemdevList *qmp_query_memdev(Error **errp)
object_child_foreach(obj, query_memdev, &list);
return list;
}
+
+HumanReadableText *qmp_x_query_numa(Error **errp)
+{
+ g_autoptr(GString) buf = g_string_new("");
+ int i, nb_numa_nodes;
+ NumaNodeMem *node_mem;
+ CpuInfoFastList *cpu_list, *cpu;
+ MachineState *ms = MACHINE(qdev_get_machine());
+
+ nb_numa_nodes = ms->numa_state ? ms->numa_state->num_nodes : 0;
+ g_string_append_printf(buf, "%d nodes\n", nb_numa_nodes);
+ if (!nb_numa_nodes) {
+ goto done;
+ }
+
+ cpu_list = qmp_query_cpus_fast(&error_abort);
+ node_mem = g_new0(NumaNodeMem, nb_numa_nodes);
+
+ query_numa_node_mem(node_mem, ms);
+ for (i = 0; i < nb_numa_nodes; i++) {
+ g_string_append_printf(buf, "node %d cpus:", i);
+ for (cpu = cpu_list; cpu; cpu = cpu->next) {
+ if (cpu->value->has_props && cpu->value->props->has_node_id &&
+ cpu->value->props->node_id == i) {
+ g_string_append_printf(buf, " %" PRIi64, cpu->value->cpu_index);
+ }
+ }
+ g_string_append_printf(buf, "\n");
+ g_string_append_printf(buf, "node %d size: %" PRId64 " MB\n", i,
+ node_mem[i].node_mem >> 20);
+ g_string_append_printf(buf, "node %d plugged: %" PRId64 " MB\n", i,
+ node_mem[i].node_plugged_mem >> 20);
+ }
+ qapi_free_CpuInfoFastList(cpu_list);
+ g_free(node_mem);
+
+ done:
+ return human_readable_text_from_str(buf);
+}
diff --git a/hw/core/machine.c b/hw/core/machine.c
index e24e3e27db..948b3d9524 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -978,6 +978,9 @@ static char *cpu_slot_to_string(const CPUArchId *cpu)
g_string_append_printf(s, "socket-id: %"PRId64, cpu->props.socket_id);
}
if (cpu->props.has_die_id) {
+ if (s->len) {
+ g_string_append_printf(s, ", ");
+ }
g_string_append_printf(s, "die-id: %"PRId64, cpu->props.die_id);
}
if (cpu->props.has_core_id) {
diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c
index c6f7f58784..60ea7f8f49 100644
--- a/hw/display/virtio-gpu-udmabuf.c
+++ b/hw/display/virtio-gpu-udmabuf.c
@@ -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);
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index c27b20090e..294499ee20 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1105,7 +1105,7 @@ static int vtd_page_walk_one(IOMMUTLBEvent *event, vtd_page_walk_info *info)
.translated_addr = entry->translated_addr,
.perm = entry->perm,
};
- DMAMap *mapped = iova_tree_find(as->iova_tree, &target);
+ const DMAMap *mapped = iova_tree_find(as->iova_tree, &target);
if (event->type == IOMMU_NOTIFIER_UNMAP && !info->notify_unmap) {
trace_vtd_page_walk_one_skip_unmap(entry->iova, entry->addr_mask);
diff --git a/hw/i386/meson.build b/hw/i386/meson.build
index c502965219..213e2e82b3 100644
--- a/hw/i386/meson.build
+++ b/hw/i386/meson.build
@@ -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'))
diff --git a/hw/i386/microvm-dt.c b/hw/i386/microvm-dt.c
new file mode 100644
index 0000000000..875ba91963
--- /dev/null
+++ b/hw/i386/microvm-dt.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__);
+ }
+ }
+}
diff --git a/hw/i386/microvm-dt.h b/hw/i386/microvm-dt.h
new file mode 100644
index 0000000000..77c79cbdd9
--- /dev/null
+++ b/hw/i386/microvm-dt.h
@@ -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
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index f257ec5a0b..4b3b1dd262 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -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"
@@ -331,7 +332,7 @@ static void microvm_memory_init(MicrovmMachineState *mms)
rom_set_fw(fw_cfg);
if (machine->kernel_filename != NULL) {
- x86_load_linux(x86ms, fw_cfg, 0, true, true);
+ x86_load_linux(x86ms, fw_cfg, 0, true);
}
if (mms->option_roms) {
@@ -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)
@@ -667,6 +669,7 @@ static void microvm_machine_initfn(Object *obj)
static void microvm_class_init(ObjectClass *oc, void *data)
{
+ X86MachineClass *x86mc = X86_MACHINE_CLASS(oc);
MachineClass *mc = MACHINE_CLASS(oc);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
@@ -697,6 +700,8 @@ static void microvm_class_init(ObjectClass *oc, void *data)
hc->unplug_request = microvm_device_unplug_request_cb;
hc->unplug = microvm_device_unplug_cb;
+ x86mc->fwcfg_dma_enabled = true;
+
object_class_property_add(oc, MICROVM_MACHINE_PIC, "OnOffAuto",
microvm_machine_get_pic,
microvm_machine_set_pic,
diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
index 9e7d69d470..0a10089f14 100644
--- a/hw/i386/multiboot.c
+++ b/hw/i386/multiboot.c
@@ -143,7 +143,8 @@ static void mb_add_mod(MultibootState *s,
s->mb_mods_count++;
}
-int load_multiboot(FWCfgState *fw_cfg,
+int load_multiboot(X86MachineState *x86ms,
+ FWCfgState *fw_cfg,
FILE *f,
const char *kernel_filename,
const char *initrd_filename,
@@ -151,6 +152,7 @@ int load_multiboot(FWCfgState *fw_cfg,
int kernel_file_size,
uint8_t *header)
{
+ bool multiboot_dma_enabled = X86_MACHINE_GET_CLASS(x86ms)->fwcfg_dma_enabled;
int i, is_multiboot = 0;
uint32_t flags = 0;
uint32_t mh_entry_addr;
@@ -401,7 +403,11 @@ int load_multiboot(FWCfgState *fw_cfg,
fw_cfg_add_bytes(fw_cfg, FW_CFG_INITRD_DATA, mb_bootinfo_data,
sizeof(bootinfo));
- option_rom[nb_option_roms].name = "multiboot.bin";
+ if (multiboot_dma_enabled) {
+ option_rom[nb_option_roms].name = "multiboot_dma.bin";
+ } else {
+ option_rom[nb_option_roms].name = "multiboot.bin";
+ }
option_rom[nb_option_roms].bootindex = 0;
nb_option_roms++;
diff --git a/hw/i386/multiboot.h b/hw/i386/multiboot.h
index 60de309cd1..2b9182a8ea 100644
--- a/hw/i386/multiboot.h
+++ b/hw/i386/multiboot.h
@@ -2,8 +2,10 @@
#define QEMU_MULTIBOOT_H
#include "hw/nvram/fw_cfg.h"
+#include "hw/i386/x86.h"
-int load_multiboot(FWCfgState *fw_cfg,
+int load_multiboot(X86MachineState *x86ms,
+ FWCfgState *fw_cfg,
FILE *f,
const char *kernel_filename,
const char *initrd_filename,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e99017e662..2592a82148 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -776,12 +776,13 @@ void xen_load_linux(PCMachineState *pcms)
rom_set_fw(fw_cfg);
x86_load_linux(x86ms, fw_cfg, pcmc->acpi_data_size,
- pcmc->pvh_enabled, pcmc->linuxboot_dma_enabled);
+ pcmc->pvh_enabled);
for (i = 0; i < nb_option_roms; i++) {
assert(!strcmp(option_rom[i].name, "linuxboot.bin") ||
!strcmp(option_rom[i].name, "linuxboot_dma.bin") ||
!strcmp(option_rom[i].name, "pvh.bin") ||
- !strcmp(option_rom[i].name, "multiboot.bin"));
+ !strcmp(option_rom[i].name, "multiboot.bin") ||
+ !strcmp(option_rom[i].name, "multiboot_dma.bin"));
rom_add_option(option_rom[i].name, option_rom[i].bootindex);
}
x86ms->fw_cfg = fw_cfg;
@@ -928,7 +929,7 @@ void pc_memory_init(PCMachineState *pcms,
if (linux_boot) {
x86_load_linux(x86ms, fw_cfg, pcmc->acpi_data_size,
- pcmc->pvh_enabled, pcmc->linuxboot_dma_enabled);
+ pcmc->pvh_enabled);
}
for (i = 0; i < nb_option_roms; i++) {
@@ -1688,7 +1689,6 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
/* BIOS ACPI tables: 128K. Other BIOS datastructures: less than 4K reported
* to be used at the moment, 32K should be enough for a while. */
pcmc->acpi_data_size = 0x20000 + 0x8000;
- pcmc->linuxboot_dma_enabled = true;
pcmc->pvh_enabled = true;
pcmc->kvmclock_create_always = true;
assert(!mc->get_hotplug_handler);
@@ -1742,7 +1742,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
object_class_property_add_bool(oc, "hpet",
pc_machine_get_hpet, pc_machine_set_hpet);
- object_class_property_add_bool(oc, "default_bus_bypass_iommu",
+ object_class_property_add_bool(oc, "default-bus-bypass-iommu",
pc_machine_get_default_bus_bypass_iommu,
pc_machine_set_default_bus_bypass_iommu);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 6ad0d763c5..223dd3e05d 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -620,11 +620,12 @@ DEFINE_I440FX_MACHINE(v2_7, "pc-i440fx-2.7", NULL,
static void pc_i440fx_2_6_machine_options(MachineClass *m)
{
+ X86MachineClass *x86mc = X86_MACHINE_CLASS(m);
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
pc_i440fx_2_7_machine_options(m);
pcmc->legacy_cpu_hotplug = true;
- pcmc->linuxboot_dma_enabled = false;
+ x86mc->fwcfg_dma_enabled = false;
compat_props_add(m->compat_props, hw_compat_2_6, hw_compat_2_6_len);
compat_props_add(m->compat_props, pc_compat_2_6, pc_compat_2_6_len);
}
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index fcc6e4eb2b..797e09500b 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -573,11 +573,12 @@ DEFINE_Q35_MACHINE(v2_7, "pc-q35-2.7", NULL,
static void pc_q35_2_6_machine_options(MachineClass *m)
{
+ X86MachineClass *x86mc = X86_MACHINE_CLASS(m);
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
pc_q35_2_7_machine_options(m);
pcmc->legacy_cpu_hotplug = true;
- pcmc->linuxboot_dma_enabled = false;
+ x86mc->fwcfg_dma_enabled = false;
compat_props_add(m->compat_props, hw_compat_2_6, hw_compat_2_6_len);
compat_props_add(m->compat_props, pc_compat_2_6, pc_compat_2_6_len);
}
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 76de7e2265..b84840a1bb 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -764,9 +764,9 @@ static bool load_elfboot(const char *kernel_filename,
void x86_load_linux(X86MachineState *x86ms,
FWCfgState *fw_cfg,
int acpi_data_size,
- bool pvh_enabled,
- bool linuxboot_dma_enabled)
+ bool pvh_enabled)
{
+ bool linuxboot_dma_enabled = X86_MACHINE_GET_CLASS(x86ms)->fwcfg_dma_enabled;
uint16_t protocol;
int setup_size, kernel_size, cmdline_size;
int dtb_size, setup_data_offset;
@@ -814,7 +814,7 @@ void x86_load_linux(X86MachineState *x86ms,
* PVH), so we try multiboot first since we check the multiboot magic
* header before to load it.
*/
- if (load_multiboot(fw_cfg, f, kernel_filename, initrd_filename,
+ if (load_multiboot(x86ms, fw_cfg, f, kernel_filename, initrd_filename,
kernel_cmdline, kernel_size, header)) {
return;
}
@@ -1332,6 +1332,7 @@ static void x86_machine_class_init(ObjectClass *oc, void *data)
mc->possible_cpu_arch_ids = x86_possible_cpu_arch_ids;
x86mc->compat_apic_id_mode = false;
x86mc->save_tsc_khz = true;
+ x86mc->fwcfg_dma_enabled = true;
nc->nmi_monitor_handler = x86_nmi;
object_class_property_add(oc, X86_MACHINE_SMM, "OnOffAuto",
diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index e7faf24058..68d741d342 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -96,7 +96,7 @@ typedef enum {
LASIPS2_STATUS_CLKSHD = 0x80,
} lasips2_status_reg_t;
-static const char *artist_read_reg_name(uint64_t addr)
+static const char *lasips2_read_reg_name(uint64_t addr)
{
switch (addr & 0xc) {
case REG_PS2_ID:
@@ -116,7 +116,7 @@ static const char *artist_read_reg_name(uint64_t addr)
}
}
-static const char *artist_write_reg_name(uint64_t addr)
+static const char *lasips2_write_reg_name(uint64_t addr)
{
switch (addr & 0x0c) {
case REG_PS2_RESET:
@@ -145,7 +145,7 @@ static void lasips2_reg_write(void *opaque, hwaddr addr, uint64_t val,
LASIPS2Port *port = opaque;
trace_lasips2_reg_write(size, port->id, addr,
- artist_write_reg_name(addr), val);
+ lasips2_write_reg_name(addr), val);
switch (addr & 0xc) {
case REG_PS2_CONTROL:
@@ -239,7 +239,7 @@ static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, unsigned size)
break;
}
trace_lasips2_reg_read(size, port->id, addr,
- artist_read_reg_name(addr), ret);
+ lasips2_read_reg_name(addr), ret);
return ret;
}
diff --git a/hw/misc/sga.c b/hw/misc/sga.c
index 4dbe6d78f9..1d04672b01 100644
--- a/hw/misc/sga.c
+++ b/hw/misc/sga.c
@@ -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);
}
diff --git a/hw/rdma/rdma_rm.c b/hw/rdma/rdma_rm.c
index 49141d4074..cfd85de3e6 100644
--- a/hw/rdma/rdma_rm.c
+++ b/hw/rdma/rdma_rm.c
@@ -27,58 +27,58 @@
#define PG_DIR_SZ { TARGET_PAGE_SIZE / sizeof(__u64) }
#define PG_TBL_SZ { TARGET_PAGE_SIZE / sizeof(__u64) }
-void rdma_dump_device_counters(Monitor *mon, RdmaDeviceResources *dev_res)
-{
- monitor_printf(mon, "\ttx : %" PRId64 "\n",
- dev_res->stats.tx);
- monitor_printf(mon, "\ttx_len : %" PRId64 "\n",
- dev_res->stats.tx_len);
- monitor_printf(mon, "\ttx_err : %" PRId64 "\n",
- dev_res->stats.tx_err);
- monitor_printf(mon, "\trx_bufs : %" PRId64 "\n",
- dev_res->stats.rx_bufs);
- monitor_printf(mon, "\trx_srq : %" PRId64 "\n",
- dev_res->stats.rx_srq);
- monitor_printf(mon, "\trx_bufs_len : %" PRId64 "\n",
- dev_res->stats.rx_bufs_len);
- monitor_printf(mon, "\trx_bufs_err : %" PRId64 "\n",
- dev_res->stats.rx_bufs_err);
- monitor_printf(mon, "\tcomps : %" PRId64 "\n",
- dev_res->stats.completions);
- monitor_printf(mon, "\tmissing_comps : %" PRId32 "\n",
- dev_res->stats.missing_cqe);
- monitor_printf(mon, "\tpoll_cq (bk) : %" PRId64 "\n",
- dev_res->stats.poll_cq_from_bk);
- monitor_printf(mon, "\tpoll_cq_ppoll_to : %" PRId64 "\n",
- dev_res->stats.poll_cq_ppoll_to);
- monitor_printf(mon, "\tpoll_cq (fe) : %" PRId64 "\n",
- dev_res->stats.poll_cq_from_guest);
- monitor_printf(mon, "\tpoll_cq_empty : %" PRId64 "\n",
- dev_res->stats.poll_cq_from_guest_empty);
- monitor_printf(mon, "\tmad_tx : %" PRId64 "\n",
- dev_res->stats.mad_tx);
- monitor_printf(mon, "\tmad_tx_err : %" PRId64 "\n",
- dev_res->stats.mad_tx_err);
- monitor_printf(mon, "\tmad_rx : %" PRId64 "\n",
- dev_res->stats.mad_rx);
- monitor_printf(mon, "\tmad_rx_err : %" PRId64 "\n",
- dev_res->stats.mad_rx_err);
- monitor_printf(mon, "\tmad_rx_bufs : %" PRId64 "\n",
- dev_res->stats.mad_rx_bufs);
- monitor_printf(mon, "\tmad_rx_bufs_err : %" PRId64 "\n",
- dev_res->stats.mad_rx_bufs_err);
- monitor_printf(mon, "\tPDs : %" PRId32 "\n",
- dev_res->pd_tbl.used);
- monitor_printf(mon, "\tMRs : %" PRId32 "\n",
- dev_res->mr_tbl.used);
- monitor_printf(mon, "\tUCs : %" PRId32 "\n",
- dev_res->uc_tbl.used);
- monitor_printf(mon, "\tQPs : %" PRId32 "\n",
- dev_res->qp_tbl.used);
- monitor_printf(mon, "\tCQs : %" PRId32 "\n",
- dev_res->cq_tbl.used);
- monitor_printf(mon, "\tCEQ_CTXs : %" PRId32 "\n",
- dev_res->cqe_ctx_tbl.used);
+void rdma_format_device_counters(RdmaDeviceResources *dev_res, GString *buf)
+{
+ g_string_append_printf(buf, "\ttx : %" PRId64 "\n",
+ dev_res->stats.tx);
+ g_string_append_printf(buf, "\ttx_len : %" PRId64 "\n",
+ dev_res->stats.tx_len);
+ g_string_append_printf(buf, "\ttx_err : %" PRId64 "\n",
+ dev_res->stats.tx_err);
+ g_string_append_printf(buf, "\trx_bufs : %" PRId64 "\n",
+ dev_res->stats.rx_bufs);
+ g_string_append_printf(buf, "\trx_srq : %" PRId64 "\n",
+ dev_res->stats.rx_srq);
+ g_string_append_printf(buf, "\trx_bufs_len : %" PRId64 "\n",
+ dev_res->stats.rx_bufs_len);
+ g_string_append_printf(buf, "\trx_bufs_err : %" PRId64 "\n",
+ dev_res->stats.rx_bufs_err);
+ g_string_append_printf(buf, "\tcomps : %" PRId64 "\n",
+ dev_res->stats.completions);
+ g_string_append_printf(buf, "\tmissing_comps : %" PRId32 "\n",
+ dev_res->stats.missing_cqe);
+ g_string_append_printf(buf, "\tpoll_cq (bk) : %" PRId64 "\n",
+ dev_res->stats.poll_cq_from_bk);
+ g_string_append_printf(buf, "\tpoll_cq_ppoll_to : %" PRId64 "\n",
+ dev_res->stats.poll_cq_ppoll_to);
+ g_string_append_printf(buf, "\tpoll_cq (fe) : %" PRId64 "\n",
+ dev_res->stats.poll_cq_from_guest);
+ g_string_append_printf(buf, "\tpoll_cq_empty : %" PRId64 "\n",
+ dev_res->stats.poll_cq_from_guest_empty);
+ g_string_append_printf(buf, "\tmad_tx : %" PRId64 "\n",
+ dev_res->stats.mad_tx);
+ g_string_append_printf(buf, "\tmad_tx_err : %" PRId64 "\n",
+ dev_res->stats.mad_tx_err);
+ g_string_append_printf(buf, "\tmad_rx : %" PRId64 "\n",
+ dev_res->stats.mad_rx);
+ g_string_append_printf(buf, "\tmad_rx_err : %" PRId64 "\n",
+ dev_res->stats.mad_rx_err);
+ g_string_append_printf(buf, "\tmad_rx_bufs : %" PRId64 "\n",
+ dev_res->stats.mad_rx_bufs);
+ g_string_append_printf(buf, "\tmad_rx_bufs_err : %" PRId64 "\n",
+ dev_res->stats.mad_rx_bufs_err);
+ g_string_append_printf(buf, "\tPDs : %" PRId32 "\n",
+ dev_res->pd_tbl.used);
+ g_string_append_printf(buf, "\tMRs : %" PRId32 "\n",
+ dev_res->mr_tbl.used);
+ g_string_append_printf(buf, "\tUCs : %" PRId32 "\n",
+ dev_res->uc_tbl.used);
+ g_string_append_printf(buf, "\tQPs : %" PRId32 "\n",
+ dev_res->qp_tbl.used);
+ g_string_append_printf(buf, "\tCQs : %" PRId32 "\n",
+ dev_res->cq_tbl.used);
+ g_string_append_printf(buf, "\tCEQ_CTXs : %" PRId32 "\n",
+ dev_res->cqe_ctx_tbl.used);
}
static inline void res_tbl_init(const char *name, RdmaRmResTbl *tbl,
diff --git a/hw/rdma/rdma_rm.h b/hw/rdma/rdma_rm.h
index e8639909cd..d69a917795 100644
--- a/hw/rdma/rdma_rm.h
+++ b/hw/rdma/rdma_rm.h
@@ -92,6 +92,6 @@ static inline union ibv_gid *rdma_rm_get_gid(RdmaDeviceResources *dev_res,
{
return &dev_res->port.gid_tbl[sgid_idx].gid;
}
-void rdma_dump_device_counters(Monitor *mon, RdmaDeviceResources *dev_res);
+void rdma_format_device_counters(RdmaDeviceResources *dev_res, GString *buf);
#endif
diff --git a/hw/rdma/vmw/pvrdma_main.c b/hw/rdma/vmw/pvrdma_main.c
index 7c0c3551a8..91206dbb8e 100644
--- a/hw/rdma/vmw/pvrdma_main.c
+++ b/hw/rdma/vmw/pvrdma_main.c
@@ -58,24 +58,25 @@ static Property pvrdma_dev_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
-static void pvrdma_print_statistics(Monitor *mon, RdmaProvider *obj)
+static void pvrdma_format_statistics(RdmaProvider *obj, GString *buf)
{
PVRDMADev *dev = PVRDMA_DEV(obj);
PCIDevice *pdev = PCI_DEVICE(dev);
- monitor_printf(mon, "%s, %x.%x\n", pdev->name, PCI_SLOT(pdev->devfn),
- PCI_FUNC(pdev->devfn));
- monitor_printf(mon, "\tcommands : %" PRId64 "\n",
- dev->stats.commands);
- monitor_printf(mon, "\tregs_reads : %" PRId64 "\n",
- dev->stats.regs_reads);
- monitor_printf(mon, "\tregs_writes : %" PRId64 "\n",
- dev->stats.regs_writes);
- monitor_printf(mon, "\tuar_writes : %" PRId64 "\n",
- dev->stats.uar_writes);
- monitor_printf(mon, "\tinterrupts : %" PRId64 "\n",
- dev->stats.interrupts);
- rdma_dump_device_counters(mon, &dev->rdma_dev_res);
+ g_string_append_printf(buf, "%s, %x.%x\n",
+ pdev->name, PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn));
+ g_string_append_printf(buf, "\tcommands : %" PRId64 "\n",
+ dev->stats.commands);
+ g_string_append_printf(buf, "\tregs_reads : %" PRId64 "\n",
+ dev->stats.regs_reads);
+ g_string_append_printf(buf, "\tregs_writes : %" PRId64 "\n",
+ dev->stats.regs_writes);
+ g_string_append_printf(buf, "\tuar_writes : %" PRId64 "\n",
+ dev->stats.uar_writes);
+ g_string_append_printf(buf, "\tinterrupts : %" PRId64 "\n",
+ dev->stats.interrupts);
+ rdma_format_device_counters(&dev->rdma_dev_res, buf);
}
static void free_dev_ring(PCIDevice *pci_dev, PvrdmaRing *ring,
@@ -699,7 +700,7 @@ static void pvrdma_class_init(ObjectClass *klass, void *data)
device_class_set_props(dc, pvrdma_dev_properties);
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
- ir->print_statistics = pvrdma_print_statistics;
+ ir->format_statistics = pvrdma_format_statistics;
}
static const TypeInfo pvrdma_info = {
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 8454ed1773..84f935b549 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -204,11 +204,6 @@ static int esp_select(ESPState *s)
s->ti_size = 0;
fifo8_reset(&s->fifo);
- if (s->current_req) {
- /* Started a new command before the old one finished. Cancel it. */
- scsi_req_cancel(s->current_req);
- }
-
s->current_dev = scsi_device_find(&s->bus, 0, target, 0);
if (!s->current_dev) {
/* No such drive */
@@ -235,6 +230,11 @@ static uint32_t get_cmd(ESPState *s, uint32_t maxlen)
uint32_t dmalen, n;
int target;
+ if (s->current_req) {
+ /* Started a new command before the old one finished. Cancel it. */
+ scsi_req_cancel(s->current_req);
+ }
+
target = s->wregs[ESP_WBUSID] & BUSID_DID;
if (s->dma) {
dmalen = MIN(esp_get_tc(s), maxlen);
diff --git a/hw/sd/meson.build b/hw/sd/meson.build
index f1ce357a3b..807ca07b7c 100644
--- a/hw/sd/meson.build
+++ b/hw/sd/meson.build
@@ -9,4 +9,5 @@ softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_mmci.c'))
softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_sdhost.c'))
softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_sdhci.c'))
softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-sdhost.c'))
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_sdhci.c'))
softmmu_ss.add(when: 'CONFIG_CADENCE_SDHCI', if_true: files('cadence_sdhci.c'))
diff --git a/hw/sd/npcm7xx_sdhci.c b/hw/sd/npcm7xx_sdhci.c
new file mode 100644
index 0000000000..ef503365df
--- /dev/null
+++ b/hw/sd/npcm7xx_sdhci.c
@@ -0,0 +1,182 @@
+/*
+ * NPCM7xx SD-3.0 / eMMC-4.51 Host Controller
+ *
+ * Copyright (c) 2021 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/sd/npcm7xx_sdhci.h"
+#include "migration/vmstate.h"
+#include "sdhci-internal.h"
+#include "qemu/log.h"
+
+static uint64_t npcm7xx_sdhci_read(void *opaque, hwaddr addr, unsigned int size)
+{
+ NPCM7xxSDHCIState *s = opaque;
+ uint64_t val = 0;
+
+ switch (addr) {
+ case NPCM7XX_PRSTVALS_0:
+ case NPCM7XX_PRSTVALS_1:
+ case NPCM7XX_PRSTVALS_2:
+ case NPCM7XX_PRSTVALS_3:
+ case NPCM7XX_PRSTVALS_4:
+ case NPCM7XX_PRSTVALS_5:
+ val = s->regs.prstvals[(addr - NPCM7XX_PRSTVALS_0) / 2];
+ break;
+ case NPCM7XX_BOOTTOCTRL:
+ val = s->regs.boottoctrl;
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "SDHCI read of nonexistent reg: 0x%02"
+ HWADDR_PRIx, addr);
+ break;
+ }
+
+ return val;
+}
+
+static void npcm7xx_sdhci_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned int size)
+{
+ NPCM7xxSDHCIState *s = opaque;
+
+ switch (addr) {
+ case NPCM7XX_BOOTTOCTRL:
+ s->regs.boottoctrl = val;
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "SDHCI write of nonexistent reg: 0x%02"
+ HWADDR_PRIx, addr);
+ break;
+ }
+}
+
+static bool npcm7xx_sdhci_check_mem_op(void *opaque, hwaddr addr,
+ unsigned size, bool is_write,
+ MemTxAttrs attrs)
+{
+ switch (addr) {
+ case NPCM7XX_PRSTVALS_0:
+ case NPCM7XX_PRSTVALS_1:
+ case NPCM7XX_PRSTVALS_2:
+ case NPCM7XX_PRSTVALS_3:
+ case NPCM7XX_PRSTVALS_4:
+ case NPCM7XX_PRSTVALS_5:
+ /* RO Word */
+ return !is_write && size == 2;
+ case NPCM7XX_BOOTTOCTRL:
+ /* R/W Dword */
+ return size == 4;
+ default:
+ return false;
+ }
+}
+
+static const MemoryRegionOps npcm7xx_sdhci_ops = {
+ .read = npcm7xx_sdhci_read,
+ .write = npcm7xx_sdhci_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 4,
+ .unaligned = false,
+ .accepts = npcm7xx_sdhci_check_mem_op,
+ },
+};
+
+static void npcm7xx_sdhci_realize(DeviceState *dev, Error **errp)
+{
+ NPCM7xxSDHCIState *s = NPCM7XX_SDHCI(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+ SysBusDevice *sbd_sdhci = SYS_BUS_DEVICE(&s->sdhci);
+
+ memory_region_init(&s->container, OBJECT(s),
+ "npcm7xx.sdhci-container", 0x1000);
+ sysbus_init_mmio(sbd, &s->container);
+
+ memory_region_init_io(&s->iomem, OBJECT(s), &npcm7xx_sdhci_ops, s,
+ TYPE_NPCM7XX_SDHCI, NPCM7XX_SDHCI_REGSIZE);
+ memory_region_add_subregion_overlap(&s->container, NPCM7XX_PRSTVALS,
+ &s->iomem, 1);
+
+ sysbus_realize(sbd_sdhci, errp);
+ memory_region_add_subregion(&s->container, 0,
+ sysbus_mmio_get_region(sbd_sdhci, 0));
+
+ /* propagate irq and "sd-bus" from generic-sdhci */
+ sysbus_pass_irq(sbd, sbd_sdhci);
+ s->bus = qdev_get_child_bus(DEVICE(sbd_sdhci), "sd-bus");
+
+ /* Set the read only preset values. */
+ memset(s->regs.prstvals, 0, sizeof(s->regs.prstvals));
+ s->regs.prstvals[0] = NPCM7XX_PRSTVALS_0_RESET;
+ s->regs.prstvals[1] = NPCM7XX_PRSTVALS_1_RESET;
+ s->regs.prstvals[3] = NPCM7XX_PRSTVALS_3_RESET;
+}
+
+static void npcm7xx_sdhci_reset(DeviceState *dev)
+{
+ NPCM7xxSDHCIState *s = NPCM7XX_SDHCI(dev);
+ device_cold_reset(DEVICE(&s->sdhci));
+ s->regs.boottoctrl = 0;
+
+ s->sdhci.prnsts = NPCM7XX_PRSNTS_RESET;
+ s->sdhci.blkgap = NPCM7XX_BLKGAP_RESET;
+ s->sdhci.capareg = NPCM7XX_CAPAB_RESET;
+ s->sdhci.maxcurr = NPCM7XX_MAXCURR_RESET;
+ s->sdhci.version = NPCM7XX_HCVER_RESET;
+}
+
+static const VMStateDescription vmstate_npcm7xx_sdhci = {
+ .name = TYPE_NPCM7XX_SDHCI,
+ .version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(regs.boottoctrl, NPCM7xxSDHCIState),
+ VMSTATE_END_OF_LIST(),
+ },
+};
+
+static void npcm7xx_sdhci_class_init(ObjectClass *classp, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(classp);
+
+ dc->desc = "NPCM7xx SD/eMMC Host Controller";
+ dc->realize = npcm7xx_sdhci_realize;
+ dc->reset = npcm7xx_sdhci_reset;
+ dc->vmsd = &vmstate_npcm7xx_sdhci;
+}
+
+static void npcm7xx_sdhci_instance_init(Object *obj)
+{
+ NPCM7xxSDHCIState *s = NPCM7XX_SDHCI(obj);
+
+ object_initialize_child(OBJECT(s), "generic-sdhci", &s->sdhci,
+ TYPE_SYSBUS_SDHCI);
+}
+
+static TypeInfo npcm7xx_sdhci_info = {
+ .name = TYPE_NPCM7XX_SDHCI,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(NPCM7xxSDHCIState),
+ .instance_init = npcm7xx_sdhci_instance_init,
+ .class_init = npcm7xx_sdhci_class_init,
+};
+
+static void npcm7xx_sdhci_register_types(void)
+{
+ type_register_static(&npcm7xx_sdhci_info);
+}
+
+type_init(npcm7xx_sdhci_register_types)
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 5d441a7065..92d6ed5626 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -2,6 +2,8 @@
#include "hw/qdev-properties.h"
#include "hw/usb.h"
#include "qapi/error.h"
+#include "qapi/qapi-commands-machine.h"
+#include "qapi/type-helpers.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "sysemu/sysemu.h"
@@ -631,15 +633,16 @@ static char *usb_get_fw_dev_path(DeviceState *qdev)
return fw_path;
}
-void hmp_info_usb(Monitor *mon, const QDict *qdict)
+HumanReadableText *qmp_x_query_usb(Error **errp)
{
+ g_autoptr(GString) buf = g_string_new("");
USBBus *bus;
USBDevice *dev;
USBPort *port;
if (QTAILQ_EMPTY(&busses)) {
- monitor_printf(mon, "USB support not enabled\n");
- return;
+ error_setg(errp, "USB support not enabled");
+ return NULL;
}
QTAILQ_FOREACH(bus, &busses, next) {
@@ -647,14 +650,17 @@ void hmp_info_usb(Monitor *mon, const QDict *qdict)
dev = port->dev;
if (!dev)
continue;
- monitor_printf(mon, " Device %d.%d, Port %s, Speed %s Mb/s, "
- "Product %s%s%s\n",
- bus->busnr, dev->addr, port->path,
- usb_speed(dev->speed), dev->product_desc,
- dev->qdev.id ? ", ID: " : "",
- dev->qdev.id ?: "");
+ g_string_append_printf(buf,
+ " Device %d.%d, Port %s, Speed %s Mb/s, "
+ "Product %s%s%s\n",
+ bus->busnr, dev->addr, port->path,
+ usb_speed(dev->speed), dev->product_desc,
+ dev->qdev.id ? ", ID: " : "",
+ dev->qdev.id ?: "");
}
}
+
+ return human_readable_text_from_str(buf);
}
/* handle legacy -usbdevice cmd line option */
diff --git a/hw/watchdog/sbsa_gwdt.c b/hw/watchdog/sbsa_gwdt.c
index d0998f8489..e49cacd0e2 100644
--- a/hw/watchdog/sbsa_gwdt.c
+++ b/hw/watchdog/sbsa_gwdt.c
@@ -273,8 +273,9 @@ static void wdt_sbsa_gwdt_class_init(ObjectClass *klass, void *data)
dc->realize = wdt_sbsa_gwdt_realize;
dc->reset = wdt_sbsa_gwdt_reset;
dc->hotpluggable = false;
- set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ set_bit(DEVICE_CATEGORY_WATCHDOG, dc->categories);
dc->vmsd = &vmstate_sbsa_gwdt;
+ dc->desc = "SBSA-compliant generic watchdog device";
}
static const TypeInfo wdt_sbsa_gwdt_info = {
diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c
index 0e98ffb73f..1437e6c5b6 100644
--- a/hw/watchdog/watchdog.c
+++ b/hw/watchdog/watchdog.c
@@ -76,20 +76,6 @@ int select_watchdog(const char *p)
return 1;
}
-int select_watchdog_action(const char *p)
-{
- int action;
- char *qapi_value;
-
- qapi_value = g_ascii_strdown(p, -1);
- action = qapi_enum_parse(&WatchdogAction_lookup, qapi_value, -1, NULL);
- g_free(qapi_value);
- if (action < 0)
- return -1;
- qmp_watchdog_set_action(action, &error_abort);
- return 0;
-}
-
WatchdogAction get_watchdog_action(void)
{
return watchdog_action;
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
index 146ffcd713..6aa6f90b66 100644
--- a/hw/watchdog/wdt_aspeed.c
+++ b/hw/watchdog/wdt_aspeed.c
@@ -293,9 +293,10 @@ static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
dc->desc = "ASPEED Watchdog Controller";
dc->realize = aspeed_wdt_realize;
dc->reset = aspeed_wdt_reset;
- set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ set_bit(DEVICE_CATEGORY_WATCHDOG, dc->categories);
dc->vmsd = &vmstate_aspeed_wdt;
device_class_set_props(dc, aspeed_wdt_properties);
+ dc->desc = "Aspeed watchdog device";
}
static const TypeInfo aspeed_wdt_info = {
diff --git a/hw/watchdog/wdt_diag288.c b/hw/watchdog/wdt_diag288.c
index e135a4de8b..9e8882a11c 100644
--- a/hw/watchdog/wdt_diag288.c
+++ b/hw/watchdog/wdt_diag288.c
@@ -122,9 +122,10 @@ static void wdt_diag288_class_init(ObjectClass *klass, void *data)
dc->unrealize = wdt_diag288_unrealize;
dc->reset = wdt_diag288_reset;
dc->hotpluggable = false;
- set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ set_bit(DEVICE_CATEGORY_WATCHDOG, dc->categories);
dc->vmsd = &vmstate_diag288;
diag288->handle_timer = wdt_diag288_handle_timer;
+ dc->desc = "diag288 device for s390x platform";
}
static const TypeInfo wdt_diag288_info = {
diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c
index 4c52e3bb9e..f99a1c9d29 100644
--- a/hw/watchdog/wdt_i6300esb.c
+++ b/hw/watchdog/wdt_i6300esb.c
@@ -476,7 +476,8 @@ static void i6300esb_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_SYSTEM_OTHER;
dc->reset = i6300esb_reset;
dc->vmsd = &vmstate_i6300esb;
- set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ set_bit(DEVICE_CATEGORY_WATCHDOG, dc->categories);
+ dc->desc = "Intel 6300ESB";
}
static const TypeInfo i6300esb_info = {
diff --git a/hw/watchdog/wdt_ib700.c b/hw/watchdog/wdt_ib700.c
index 177aaa503f..91d1bdc0da 100644
--- a/hw/watchdog/wdt_ib700.c
+++ b/hw/watchdog/wdt_ib700.c
@@ -140,7 +140,8 @@ static void wdt_ib700_class_init(ObjectClass *klass, void *data)
dc->realize = wdt_ib700_realize;
dc->reset = wdt_ib700_reset;
dc->vmsd = &vmstate_ib700;
- set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ set_bit(DEVICE_CATEGORY_WATCHDOG, dc->categories);
+ dc->desc = "iBASE 700";
}
static const TypeInfo wdt_ib700_info = {
diff --git a/hw/watchdog/wdt_imx2.c b/hw/watchdog/wdt_imx2.c
index a5fb76308f..c3128370b5 100644
--- a/hw/watchdog/wdt_imx2.c
+++ b/hw/watchdog/wdt_imx2.c
@@ -280,8 +280,8 @@ static void imx2_wdt_class_init(ObjectClass *klass, void *data)
dc->realize = imx2_wdt_realize;
dc->reset = imx2_wdt_reset;
dc->vmsd = &vmstate_imx2_wdt;
- dc->desc = "i.MX watchdog timer";
- set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ dc->desc = "i.MX2 watchdog timer";
+ set_bit(DEVICE_CATEGORY_WATCHDOG, dc->categories);
}
static const TypeInfo imx2_wdt_info = {