From f09a8d8dc9687c9ad1a5bae26c8e15516f6798a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 6 Oct 2023 08:24:21 +0200 Subject: [PATCH 01/55] pc-bios/meson.build: Silent unuseful DTC warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QEMU consumes some device tree blobs, so these have been committed to the tree in as firmware, along with the device tree source used to generate them. We know the blobs are "good enough" to have QEMU boot a system, so we don't really maintain and rebuild the sources. These blobs were generated with older 'dtc' binaries. We use the v1.6.1 version since 2021 (commit 962fde57b7 "dtc: Update to version 1.6.1"). Since commit 6e0dc9d2a8 ("meson: compile bundled device trees"), if dtc binary is available, it is directly used to compile the device tree sources. New versions of 'dtc' add checks which display warnings or errors. Our sources are a bit old, so dtc v1.6.1 now emit the following warnings on a fresh build: [163/3414] Generating pc-bios/canyonlands.dts with a custom command pc-bios/canyonlands.dts:47.9-50.4: Warning (unit_address_vs_reg): /memory: node has a reg or ranges property, but no unit name pc-bios/canyonlands.dts:210.13-429.5: Warning (unit_address_vs_reg): /plb/opb: node has a reg or ranges property, but no unit name pc-bios/canyonlands.dts:464.26-504.5: Warning (pci_bridge): /plb/pciex@d00000000: node name is not "pci" or "pcie" pc-bios/canyonlands.dts:506.26-546.5: Warning (pci_bridge): /plb/pciex@d20000000: node name is not "pci" or "pcie" pc-bios/canyonlands.dtb: Warning (unit_address_format): Failed prerequisite 'pci_bridge' pc-bios/canyonlands.dtb: Warning (pci_device_reg): Failed prerequisite 'pci_bridge' pc-bios/canyonlands.dtb: Warning (pci_device_bus_num): Failed prerequisite 'pci_bridge' pc-bios/canyonlands.dts:268.14-289.7: Warning (avoid_unnecessary_addr_size): /plb/opb/ebc/ndfc@3,0: unnecessary #address-cells/#size-cells without "ranges" or child "reg" property [164/3414] Generating pc-bios/petalogix-s3adsp1800.dts with a custom command pc-bios/petalogix-s3adsp1800.dts:258.33-266.5: Warning (interrupt_provider): /plb/interrupt-controller@81800000: Missing #address-cells in interrupt provider [165/3414] Generating pc-bios/petalogix-ml605.dts with a custom command pc-bios/petalogix-ml605.dts:234.39-241.5: Warning (interrupt_provider): /axi/interrupt-controller@81800000: Missing #address-cells in interrupt provider [177/3414] Generating pc-bios/bamboo.dts with a custom command pc-bios/bamboo.dts:45.9-48.4: Warning (unit_address_vs_reg): /memory: node has a reg or ranges property, but no unit name pc-bios/bamboo.dts:87.13-154.5: Warning (unit_address_vs_reg): /plb/opb: node has a reg or ranges property, but no unit name pc-bios/bamboo.dts:198.3-50: Warning (chosen_node_stdout_path): /chosen:linux,stdout-path: Use 'stdout-path' instead pc-bios/bamboo.dts:87.13-154.5: Warning (interrupts_property): /plb/opb: Missing interrupt-parent pc-bios/bamboo.dts:100.14-108.6: Warning (interrupts_property): /plb/opb/ebc: Missing interrupt-parent From QEMU perspective, these warnings are not really useful. It is the responsibility of developers adding DT source/blob to QEMU repository to check the source doesn't produce warnings, but as long as the blob is useful enough, QEMU can consume it. So these warnings don't add any value, instead they are noisy and might distract us to focus on important warnings. Better disable them. 'dtc' provides the '--quiet' option for that [*]: $ dtc --help Usage: dtc [options] Options: -[qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@AThv] -q, --quiet Quiet: -q suppress warnings, -qq errors, -qqq all Update meson to disable these unuseful DTC warnings. [*] https://lore.kernel.org/qemu-devel/CAFEAcA-WJ9J1YQunJ+bSG=wnpxh1By+Bf18j2CyV7G0vZ=8b7g@mail.gmail.com/ Suggested-by: Peter Maydell Signed-off-by: Philippe Mathieu-Daudé Acked-by: BALATON Zoltan Message-Id: <20231006064750.33852-1-philmd@linaro.org> --- pc-bios/meson.build | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pc-bios/meson.build b/pc-bios/meson.build index 4823dff189..b68b29cc7d 100644 --- a/pc-bios/meson.build +++ b/pc-bios/meson.build @@ -99,7 +99,8 @@ foreach f : [ output: out, install: get_option('install_blobs'), install_dir: qemu_datadir, - command: [ dtc, '-I', 'dts', '-O', 'dtb', '-o', '@OUTPUT@', '@INPUT0@' ]) + command: [ dtc, '-q', '-I', 'dts', '-O', 'dtb', + '-o', '@OUTPUT@', '@INPUT0@' ]) else blobs += out endif From b708e31185e060dac0fbc1420656f1dc812451eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 16 Dec 2023 03:07:33 +0100 Subject: [PATCH 02/55] target: Replace DEVICE(object_new) -> qdev_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prefer QDev API for QDev objects, avoid the underlying QOM layer. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Zhao Liu Message-Id: <20240216110313.17039-8-philmd@linaro.org> --- target/mips/cpu.c | 2 +- target/xtensa/cpu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/target/mips/cpu.c b/target/mips/cpu.c index e3af02a4e6..47cd7cfdce 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -644,7 +644,7 @@ MIPSCPU *mips_cpu_create_with_clock(const char *cpu_type, Clock *cpu_refclk, { DeviceState *cpu; - cpu = DEVICE(object_new(cpu_type)); + cpu = qdev_new(cpu_type); qdev_connect_clock_in(cpu, "clk-in", cpu_refclk); object_property_set_bool(OBJECT(cpu), "big-endian", is_big_endian, &error_abort); diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c index 0910a3d290..4eb699d1f4 100644 --- a/target/xtensa/cpu.c +++ b/target/xtensa/cpu.c @@ -208,7 +208,7 @@ XtensaCPU *xtensa_cpu_create_with_clock(const char *cpu_type, Clock *cpu_refclk) { DeviceState *cpu; - cpu = DEVICE(object_new(cpu_type)); + cpu = qdev_new(cpu_type); qdev_connect_clock_in(cpu, "clk-in", cpu_refclk); qdev_realize(cpu, NULL, &error_abort); From 901b78a0eeda7d8d955e9ffe6608801df14b5638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 16 Dec 2023 03:07:33 +0100 Subject: [PATCH 03/55] hw: Replace DEVICE(object_new) -> qdev_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prefer QDev API for QDev objects, avoid the underlying QOM layer. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Zhao Liu Message-Id: <20240216110313.17039-7-philmd@linaro.org> --- hw/arm/musicpal.c | 2 +- hw/sparc/sun4m.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c index a712ff954b..48a32c2407 100644 --- a/hw/arm/musicpal.c +++ b/hw/arm/musicpal.c @@ -1238,7 +1238,7 @@ static void musicpal_init(MachineState *machine) qdev_get_gpio_in(pic, MP_TIMER4_IRQ), NULL); /* Logically OR both UART IRQs together */ - uart_orgate = DEVICE(object_new(TYPE_OR_IRQ)); + uart_orgate = qdev_new(TYPE_OR_IRQ); object_property_set_int(OBJECT(uart_orgate), "num-lines", 2, &error_fatal); qdev_realize_and_unref(uart_orgate, NULL, &error_fatal); qdev_connect_gpio_out(uart_orgate, 0, diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index 217a69e4d5..e070360a2c 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -974,7 +974,7 @@ static void sun4m_hw_init(MachineState *machine) sysbus_mmio_map(s, 0, hwdef->ms_kb_base); /* Logically OR both its IRQs together */ - ms_kb_orgate = DEVICE(object_new(TYPE_OR_IRQ)); + ms_kb_orgate = qdev_new(TYPE_OR_IRQ); object_property_set_int(OBJECT(ms_kb_orgate), "num-lines", 2, &error_fatal); qdev_realize_and_unref(ms_kb_orgate, NULL, &error_fatal); sysbus_connect_irq(s, 0, qdev_get_gpio_in(ms_kb_orgate, 0)); @@ -995,7 +995,7 @@ static void sun4m_hw_init(MachineState *machine) sysbus_mmio_map(s, 0, hwdef->serial_base); /* Logically OR both its IRQs together */ - serial_orgate = DEVICE(object_new(TYPE_OR_IRQ)); + serial_orgate = qdev_new(TYPE_OR_IRQ); object_property_set_int(OBJECT(serial_orgate), "num-lines", 2, &error_fatal); qdev_realize_and_unref(serial_orgate, NULL, &error_fatal); From 8bf6275f7e08ed8fea309ecda29c5da8837ed952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 16 Dec 2023 18:23:26 +0100 Subject: [PATCH 04/55] hw/usb: Inline usb_try_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inline the single use of usb_try_new(). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Zhao Liu Message-Id: <20240216110313.17039-10-philmd@linaro.org> --- hw/usb/bus.c | 2 +- include/hw/usb.h | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/hw/usb/bus.c b/hw/usb/bus.c index b19b0b13eb..7e7deaadca 100644 --- a/hw/usb/bus.c +++ b/hw/usb/bus.c @@ -411,7 +411,7 @@ void usb_claim_port(USBDevice *dev, Error **errp) } else { if (bus->nfree == 1 && strcmp(object_get_typename(OBJECT(dev)), "usb-hub") != 0) { /* Create a new hub and chain it on */ - hub = usb_try_new("usb-hub"); + hub = USB_DEVICE(qdev_try_new("usb-hub")); if (hub) { usb_realize_and_unref(hub, bus, NULL); } diff --git a/include/hw/usb.h b/include/hw/usb.h index d46d96779a..bb778cb844 100644 --- a/include/hw/usb.h +++ b/include/hw/usb.h @@ -584,11 +584,6 @@ static inline USBDevice *usb_new(const char *name) return USB_DEVICE(qdev_new(name)); } -static inline USBDevice *usb_try_new(const char *name) -{ - return USB_DEVICE(qdev_try_new(name)); -} - static inline bool usb_realize_and_unref(USBDevice *dev, USBBus *bus, Error **errp) { return qdev_realize_and_unref(&dev->qdev, &bus->qbus, errp); From 8d2701072e44cda756148a29ef013a4b91316644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 16 Dec 2023 18:24:11 +0100 Subject: [PATCH 05/55] hw/usb: Inline usb_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inline the 3 uses of usb_new(). Reviewed-by: Zhao Liu Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20240216110313.17039-11-philmd@linaro.org> --- hw/usb/bus.c | 3 ++- hw/usb/dev-serial.c | 2 +- include/hw/usb.h | 7 +------ 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/hw/usb/bus.c b/hw/usb/bus.c index 7e7deaadca..f45b82c776 100644 --- a/hw/usb/bus.c +++ b/hw/usb/bus.c @@ -662,7 +662,8 @@ USBDevice *usbdevice_create(const char *driver) return NULL; } - dev = f->usbdevice_init ? f->usbdevice_init() : usb_new(f->name); + dev = f->usbdevice_init ? f->usbdevice_init() + : USB_DEVICE(qdev_new(f->name)); if (!dev) { error_report("Failed to create USB device '%s'", f->name); return NULL; diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c index a0821db902..aa50a92e26 100644 --- a/hw/usb/dev-serial.c +++ b/hw/usb/dev-serial.c @@ -624,7 +624,7 @@ static USBDevice *usb_braille_init(void) return NULL; } - dev = usb_new("usb-braille"); + dev = USB_DEVICE(qdev_new("usb-braille")); qdev_prop_set_chr(&dev->qdev, "chardev", cdrv); return dev; } diff --git a/include/hw/usb.h b/include/hw/usb.h index bb778cb844..e410693d0c 100644 --- a/include/hw/usb.h +++ b/include/hw/usb.h @@ -579,11 +579,6 @@ void usb_pcap_init(FILE *fp); void usb_pcap_ctrl(USBPacket *p, bool setup); void usb_pcap_data(USBPacket *p, bool setup); -static inline USBDevice *usb_new(const char *name) -{ - return USB_DEVICE(qdev_new(name)); -} - static inline bool usb_realize_and_unref(USBDevice *dev, USBBus *bus, Error **errp) { return qdev_realize_and_unref(&dev->qdev, &bus->qbus, errp); @@ -591,7 +586,7 @@ static inline bool usb_realize_and_unref(USBDevice *dev, USBBus *bus, Error **er static inline USBDevice *usb_create_simple(USBBus *bus, const char *name) { - USBDevice *dev = usb_new(name); + USBDevice *dev = USB_DEVICE(qdev_new(name)); usb_realize_and_unref(dev, bus, &error_abort); return dev; From 8915c118599d47c8d73f0b5982d28289c3ad797f Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sun, 18 Feb 2024 15:57:11 +0900 Subject: [PATCH 06/55] hw/qdev: Pass bus argument to qdev_hotplug_allowed() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation of checking the parent bus is hot(un)pluggable in a few commits, pass a 'bus' argument to qdev_hotplug_allowed(). Signed-off-by: Akihiko Odaki [PMD: Split from bigger patch, part 1/6] Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Igor Mammedov Message-Id: <20250110091908.64454-2-philmd@linaro.org> --- hw/core/qdev-hotplug.c | 2 +- include/hw/qdev-core.h | 2 +- system/qdev-monitor.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/core/qdev-hotplug.c b/hw/core/qdev-hotplug.c index d495d0e9c7..19fbb11a31 100644 --- a/hw/core/qdev-hotplug.c +++ b/hw/core/qdev-hotplug.c @@ -30,7 +30,7 @@ HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev) return NULL; } -bool qdev_hotplug_allowed(DeviceState *dev, Error **errp) +bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp) { MachineState *machine; MachineClass *mc; diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 89575e74e2..930b00fb09 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -540,7 +540,7 @@ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id, int required_for_version); HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev); HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev); -bool qdev_hotplug_allowed(DeviceState *dev, Error **errp); +bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp); /** * qdev_get_hotplug_handler() - Get handler responsible for device wiring diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c index 23043b1e0d..83388dc0c4 100644 --- a/system/qdev-monitor.c +++ b/system/qdev-monitor.c @@ -691,7 +691,7 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts, /* Check whether the hotplug is allowed by the machine */ if (phase_check(PHASE_MACHINE_READY)) { - if (!qdev_hotplug_allowed(dev, errp)) { + if (!qdev_hotplug_allowed(dev, bus, errp)) { goto err_del_dev; } From 206d602e9b73d9079449b44899d572624d57390a Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sun, 18 Feb 2024 15:57:11 +0900 Subject: [PATCH 07/55] hw/qdev: Factor qdev_hotunplug_allowed() out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Factor qdev_hotunplug_allowed() out of qdev_unplug(). Start checking the device is not blocked. Signed-off-by: Akihiko Odaki [PMD: Split from bigger patch, part 2/6] Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Igor Mammedov Message-Id: <20250110091908.64454-3-philmd@linaro.org> --- hw/core/qdev-hotplug.c | 5 +++++ include/hw/qdev-core.h | 1 + system/qdev-monitor.c | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/core/qdev-hotplug.c b/hw/core/qdev-hotplug.c index 19fbb11a31..dc35110e73 100644 --- a/hw/core/qdev-hotplug.c +++ b/hw/core/qdev-hotplug.c @@ -47,6 +47,11 @@ bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp) return true; } +bool qdev_hotunplug_allowed(DeviceState *dev, Error **errp) +{ + return !qdev_unplug_blocked(dev, errp); +} + HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev) { if (dev->parent_bus) { diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 930b00fb09..530f3da702 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -541,6 +541,7 @@ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id, HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev); HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev); bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp); +bool qdev_hotunplug_allowed(DeviceState *dev, Error **errp); /** * qdev_get_hotplug_handler() - Get handler responsible for device wiring diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c index 83388dc0c4..511d1aa83c 100644 --- a/system/qdev-monitor.c +++ b/system/qdev-monitor.c @@ -909,7 +909,7 @@ void qdev_unplug(DeviceState *dev, Error **errp) HotplugHandlerClass *hdc; Error *local_err = NULL; - if (qdev_unplug_blocked(dev, errp)) { + if (!qdev_hotunplug_allowed(dev, errp)) { return; } From f2694f1b1a1a38c586ee6f00e88b729828012d3a Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sun, 18 Feb 2024 15:57:11 +0900 Subject: [PATCH 08/55] hw/qdev: Introduce qdev_hotplug_unplug_allowed_common() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce qdev_hotplug_unplug_allowed_common() to hold common code between checking hot-plug/unplug is allowed. Signed-off-by: Akihiko Odaki [PMD: Split from bigger patch, part 3/6] Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Igor Mammedov Message-Id: <20250110091908.64454-4-philmd@linaro.org> --- hw/core/qdev-hotplug.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/hw/core/qdev-hotplug.c b/hw/core/qdev-hotplug.c index dc35110e73..168d796474 100644 --- a/hw/core/qdev-hotplug.c +++ b/hw/core/qdev-hotplug.c @@ -30,12 +30,22 @@ HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev) return NULL; } +static bool qdev_hotplug_unplug_allowed_common(DeviceState *dev, BusState *bus, + Error **errp) +{ + return true; +} + bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp) { MachineState *machine; MachineClass *mc; Object *m_obj = qdev_get_machine(); + if (!qdev_hotplug_unplug_allowed_common(dev, bus, errp)) { + return false; + } + if (object_dynamic_cast(m_obj, TYPE_MACHINE)) { machine = MACHINE(m_obj); mc = MACHINE_GET_CLASS(machine); @@ -49,7 +59,8 @@ bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp) bool qdev_hotunplug_allowed(DeviceState *dev, Error **errp) { - return !qdev_unplug_blocked(dev, errp); + return !qdev_unplug_blocked(dev, errp) && + qdev_hotplug_unplug_allowed_common(dev, dev->parent_bus, errp); } HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev) From 1bff035be76cc30ff0fc4e8f0b0fbda84db7d1dc Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sun, 18 Feb 2024 15:57:11 +0900 Subject: [PATCH 09/55] hw/qdev: Check DevClass::hotpluggable in hotplug_unplug_allowed_common MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check the same code once in the common helper. Signed-off-by: Akihiko Odaki [PMD: Split from bigger patch, part 4/6] Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Igor Mammedov Message-Id: <20250110091908.64454-5-philmd@linaro.org> --- hw/core/qdev-hotplug.c | 9 +++++++++ system/qdev-monitor.c | 10 +--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/hw/core/qdev-hotplug.c b/hw/core/qdev-hotplug.c index 168d796474..1d77fffb5e 100644 --- a/hw/core/qdev-hotplug.c +++ b/hw/core/qdev-hotplug.c @@ -12,6 +12,7 @@ #include "qemu/osdep.h" #include "hw/qdev-core.h" #include "hw/boards.h" +#include "qapi/error.h" HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev) { @@ -33,6 +34,14 @@ HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev) static bool qdev_hotplug_unplug_allowed_common(DeviceState *dev, BusState *bus, Error **errp) { + DeviceClass *dc = DEVICE_GET_CLASS(dev); + + if (!dc->hotpluggable) { + error_setg(errp, "Device '%s' does not support hotplugging", + object_get_typename(OBJECT(dev))); + return false; + } + return true; } diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c index 511d1aa83c..81f747b38f 100644 --- a/system/qdev-monitor.c +++ b/system/qdev-monitor.c @@ -263,8 +263,7 @@ static DeviceClass *qdev_get_device_class(const char **driver, Error **errp) } dc = DEVICE_CLASS(oc); - if (!dc->user_creatable || - (phase_check(PHASE_MACHINE_READY) && !dc->hotpluggable)) { + if (!dc->user_creatable) { error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver", "a pluggable device type"); return NULL; @@ -904,7 +903,6 @@ static DeviceState *find_device_state(const char *id, bool use_generic_error, void qdev_unplug(DeviceState *dev, Error **errp) { - DeviceClass *dc = DEVICE_GET_CLASS(dev); HotplugHandler *hotplug_ctrl; HotplugHandlerClass *hdc; Error *local_err = NULL; @@ -919,12 +917,6 @@ void qdev_unplug(DeviceState *dev, Error **errp) return; } - if (!dc->hotpluggable) { - error_setg(errp, "Device '%s' does not support hotplugging", - object_get_typename(OBJECT(dev))); - return; - } - if (migration_is_running() && !dev->allow_unplug_during_migration) { error_setg(errp, "device_del not allowed while migrating"); return; From ccaca8929d53b23e2f7acc45cc88d05fc0479a1b Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sun, 18 Feb 2024 15:57:11 +0900 Subject: [PATCH 10/55] hw/qdev: Check qbus_is_hotpluggable in hotplug_unplug_allowed_common MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check the same code once in the common helper. Signed-off-by: Akihiko Odaki [PMD: Split from bigger patch, part 5/6] Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Igor Mammedov Message-Id: <20250110091908.64454-6-philmd@linaro.org> --- hw/core/qdev-hotplug.c | 8 ++++++++ system/qdev-monitor.c | 11 ----------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/hw/core/qdev-hotplug.c b/hw/core/qdev-hotplug.c index 1d77fffb5e..f6422cd0e4 100644 --- a/hw/core/qdev-hotplug.c +++ b/hw/core/qdev-hotplug.c @@ -42,6 +42,14 @@ static bool qdev_hotplug_unplug_allowed_common(DeviceState *dev, BusState *bus, return false; } + if (bus) { + if (!qbus_is_hotpluggable(bus)) { + error_setg(errp, "Bus '%s' does not support hotplugging", + bus->name); + return false; + } + } + return true; } diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c index 81f747b38f..e27d25c585 100644 --- a/system/qdev-monitor.c +++ b/system/qdev-monitor.c @@ -675,11 +675,6 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts, return NULL; } - if (phase_check(PHASE_MACHINE_READY) && bus && !qbus_is_hotpluggable(bus)) { - error_setg(errp, "Bus '%s' does not support hotplugging", bus->name); - return NULL; - } - if (migration_is_running()) { error_setg(errp, "device_add not allowed while migrating"); return NULL; @@ -911,12 +906,6 @@ void qdev_unplug(DeviceState *dev, Error **errp) return; } - if (dev->parent_bus && !qbus_is_hotpluggable(dev->parent_bus)) { - error_setg(errp, "Bus '%s' does not support hotplugging", - dev->parent_bus->name); - return; - } - if (migration_is_running() && !dev->allow_unplug_during_migration) { error_setg(errp, "device_del not allowed while migrating"); return; From 937874a83d149a1b871a569d6abded3fdd302267 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sun, 18 Feb 2024 15:57:11 +0900 Subject: [PATCH 11/55] hw/qdev: Check machine_hotplug_handler in hotplug_unplug_allowed_common MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 03fcbd9dc508 ("qdev: Check for the availability of a hotplug controller before adding a device") says: > The qdev_unplug() function contains a g_assert(hotplug_ctrl) > statement, so QEMU crashes when the user tries to device_add + > device_del a device that does not have a corresponding hotplug > controller. > The code in qdev_device_add() already checks whether the bus has a > proper hotplug controller, but for devices that do not have a > corresponding bus, here is no appropriate check available yet. In that > case we should check whether the machine itself provides a suitable > hotplug controller and refuse to plug the device if none is available. However, it forgot to add the corresponding check to qdev_unplug(). Check the machine hotplug handler once in the common qdev_hotplug_unplug_allowed_common() helper so both hotplug and hot-unplug path are covered. Fixes: 7716b8ca74 ("qdev: HotplugHandler: Add support for unplugging BUS-less devices") Signed-off-by: Akihiko Odaki [PMD: Split from bigger patch, part 6/6] Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Igor Mammedov Message-Id: <20250110091908.64454-7-philmd@linaro.org> --- hw/core/qdev-hotplug.c | 10 ++++++++++ system/qdev-monitor.c | 14 +++----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/hw/core/qdev-hotplug.c b/hw/core/qdev-hotplug.c index f6422cd0e4..ff176dc1bb 100644 --- a/hw/core/qdev-hotplug.c +++ b/hw/core/qdev-hotplug.c @@ -48,6 +48,16 @@ static bool qdev_hotplug_unplug_allowed_common(DeviceState *dev, BusState *bus, bus->name); return false; } + } else { + if (!qdev_get_machine_hotplug_handler(dev)) { + /* + * No bus, no machine hotplug handler --> device is not hotpluggable + */ + error_setg(errp, + "Device '%s' can not be hotplugged on this machine", + object_get_typename(OBJECT(dev))); + return false; + } } return true; diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c index e27d25c585..861c25c855 100644 --- a/system/qdev-monitor.c +++ b/system/qdev-monitor.c @@ -684,17 +684,9 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts, dev = qdev_new(driver); /* Check whether the hotplug is allowed by the machine */ - if (phase_check(PHASE_MACHINE_READY)) { - if (!qdev_hotplug_allowed(dev, bus, errp)) { - goto err_del_dev; - } - - if (!bus && !qdev_get_machine_hotplug_handler(dev)) { - /* No bus, no machine hotplug handler --> device is not hotpluggable */ - error_setg(errp, "Device '%s' can not be hotplugged on this machine", - driver); - goto err_del_dev; - } + if (phase_check(PHASE_MACHINE_READY) && + !qdev_hotplug_allowed(dev, bus, errp)) { + goto err_del_dev; } /* From 6909b616efbc9b627a0c9ea87d25a10d508cc879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 25 Sep 2024 23:14:08 +0200 Subject: [PATCH 12/55] hw/microblaze: Restrict MemoryRegionOps are implemented as 32-bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All these MemoryRegionOps read() and write() handlers are implemented expecting 32-bit accesses. Clarify that setting .impl.min/max_access_size fields. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Anton Johansson Message-Id: <20241105130431.22564-8-philmd@linaro.org> --- hw/intc/xilinx_intc.c | 4 ++++ hw/net/xilinx_ethlite.c | 4 ++++ hw/timer/xilinx_timer.c | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/hw/intc/xilinx_intc.c b/hw/intc/xilinx_intc.c index d99cf567ae..6930f83907 100644 --- a/hw/intc/xilinx_intc.c +++ b/hw/intc/xilinx_intc.c @@ -144,6 +144,10 @@ static const MemoryRegionOps pic_ops = { .read = pic_read, .write = pic_write, .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, .valid = { .min_access_size = 4, .max_access_size = 4 diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 4c0c7fcae3..88ab331acc 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -166,6 +166,10 @@ static const MemoryRegionOps eth_ops = { .read = eth_read, .write = eth_write, .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, .valid = { .min_access_size = 4, .max_access_size = 4 diff --git a/hw/timer/xilinx_timer.c b/hw/timer/xilinx_timer.c index 4955fe1b01..6595cf5f51 100644 --- a/hw/timer/xilinx_timer.c +++ b/hw/timer/xilinx_timer.c @@ -193,6 +193,10 @@ static const MemoryRegionOps timer_ops = { .read = timer_read, .write = timer_write, .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, .valid = { .min_access_size = 4, .max_access_size = 4 From fa3ca9aa1ceb9b762f4c7a51245226f247e35560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 9 Nov 2024 19:35:36 +0100 Subject: [PATCH 13/55] hw/net/xilinx_ethlite: Map MDIO registers (as unimplemented) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than handling the MDIO registers as RAM, map them as unimplemented I/O within the device MR. The memory flat view becomes: (qemu) info mtree -f FlatView #0 Root memory region: system 0000000081000000-00000000810007e3 (prio 0, i/o): xlnx.xps-ethernetlite 00000000810007e4-00000000810007f3 (prio 0, i/o): ethlite.mdio 00000000810007f4-0000000081001fff (prio 0, i/o): xlnx.xps-ethernetlite @00000000000007f4 Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Edgar E. Iglesias Message-Id: <20241112181044.92193-7-philmd@linaro.org> --- hw/net/xilinx_ethlite.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 88ab331acc..442467abeb 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -28,15 +28,18 @@ #include "qemu/osdep.h" #include "qemu/module.h" #include "qom/object.h" +#include "qapi/error.h" #include "exec/tswap.h" #include "hw/sysbus.h" #include "hw/irq.h" #include "hw/qdev-properties.h" +#include "hw/misc/unimp.h" #include "net/net.h" #include "trace.h" #define R_TX_BUF0 0 #define BUFSZ_MAX 0x07e4 +#define A_MDIO_BASE 0x07e4 #define R_TX_LEN0 (0x07f4 / 4) #define R_TX_GIE0 (0x07f8 / 4) #define R_TX_CTRL0 (0x07fc / 4) @@ -72,6 +75,7 @@ struct XlnxXpsEthLite uint32_t c_rx_pingpong; unsigned int port_index; /* dual port RAM index */ + UnimplementedDeviceState mdio; uint32_t regs[R_MAX]; }; @@ -232,6 +236,14 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) { XlnxXpsEthLite *s = XILINX_ETHLITE(dev); + object_initialize_child(OBJECT(dev), "ethlite.mdio", &s->mdio, + TYPE_UNIMPLEMENTED_DEVICE); + qdev_prop_set_string(DEVICE(&s->mdio), "name", "ethlite.mdio"); + qdev_prop_set_uint64(DEVICE(&s->mdio), "size", 4 * 4); + sysbus_realize(SYS_BUS_DEVICE(&s->mdio), &error_fatal); + memory_region_add_subregion(&s->mmio, A_MDIO_BASE, + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mdio), 0)); + qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, From 8d956610f5e79bcc53a9f296ebecd53ee7c449ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 11 Nov 2024 18:49:56 +0100 Subject: [PATCH 14/55] hw/net/xilinx_ethlite: Introduce txbuf_ptr() helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For a particular physical address within the EthLite MMIO range, addr_to_port_index() returns which port is accessed. txbuf_ptr() points to the beginning of a (RAM) TX buffer within the device state. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Edgar E. Iglesias Message-Id: <20241112181044.92193-10-philmd@linaro.org> --- hw/net/xilinx_ethlite.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 442467abeb..8df621904a 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -27,6 +27,7 @@ #include "qemu/osdep.h" #include "qemu/module.h" +#include "qemu/bitops.h" #include "qom/object.h" #include "qapi/error.h" #include "exec/tswap.h" @@ -87,6 +88,18 @@ static inline void eth_pulse_irq(XlnxXpsEthLite *s) } } +static unsigned addr_to_port_index(hwaddr addr) +{ + return extract64(addr, 11, 1); +} + +static void *txbuf_ptr(XlnxXpsEthLite *s, unsigned port_index) +{ + unsigned int rxbase = port_index * (0x800 / 4); + + return &s->regs[rxbase + R_TX_BUF0]; +} + static uint64_t eth_read(void *opaque, hwaddr addr, unsigned int size) { @@ -119,6 +132,7 @@ eth_write(void *opaque, hwaddr addr, uint64_t val64, unsigned int size) { XlnxXpsEthLite *s = opaque; + unsigned int port_index = addr_to_port_index(addr); unsigned int base = 0; uint32_t value = val64; @@ -132,12 +146,12 @@ eth_write(void *opaque, hwaddr addr, if ((value & (CTRL_P | CTRL_S)) == CTRL_S) { qemu_send_packet(qemu_get_queue(s->nic), - (void *) &s->regs[base], + txbuf_ptr(s, port_index), s->regs[base + R_TX_LEN0]); if (s->regs[base + R_TX_CTRL0] & CTRL_I) eth_pulse_irq(s); } else if ((value & (CTRL_P | CTRL_S)) == (CTRL_P | CTRL_S)) { - memcpy(&s->conf.macaddr.a[0], &s->regs[base], 6); + memcpy(&s->conf.macaddr.a[0], txbuf_ptr(s, port_index), 6); if (s->regs[base + R_TX_CTRL0] & CTRL_I) eth_pulse_irq(s); } From 785fd1a9afd5cb894f3e53753d732c7fbbb3d74a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 11 Nov 2024 18:51:57 +0100 Subject: [PATCH 15/55] hw/net/xilinx_ethlite: Introduce rxbuf_ptr() helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rxbuf_ptr() points to the beginning of a (RAM) RX buffer within the device state. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Edgar E. Iglesias Message-Id: <20241112181044.92193-11-philmd@linaro.org> --- hw/net/xilinx_ethlite.c | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 8df621904a..67adecc088 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -60,6 +60,12 @@ #define CTRL_P 0x2 #define CTRL_S 0x1 +typedef struct XlnxXpsEthLitePort { + struct { + uint32_t rx_ctrl; + } reg; +} XlnxXpsEthLitePort; + #define TYPE_XILINX_ETHLITE "xlnx.xps-ethernetlite" OBJECT_DECLARE_SIMPLE_TYPE(XlnxXpsEthLite, XILINX_ETHLITE) @@ -77,6 +83,7 @@ struct XlnxXpsEthLite unsigned int port_index; /* dual port RAM index */ UnimplementedDeviceState mdio; + XlnxXpsEthLitePort port[2]; uint32_t regs[R_MAX]; }; @@ -100,10 +107,18 @@ static void *txbuf_ptr(XlnxXpsEthLite *s, unsigned port_index) return &s->regs[rxbase + R_TX_BUF0]; } +static void *rxbuf_ptr(XlnxXpsEthLite *s, unsigned port_index) +{ + unsigned int rxbase = port_index * (0x800 / 4); + + return &s->regs[rxbase + R_RX_BUF0]; +} + static uint64_t eth_read(void *opaque, hwaddr addr, unsigned int size) { XlnxXpsEthLite *s = opaque; + unsigned port_index = addr_to_port_index(addr); uint32_t r = 0; addr >>= 2; @@ -115,9 +130,12 @@ eth_read(void *opaque, hwaddr addr, unsigned int size) case R_TX_LEN1: case R_TX_CTRL1: case R_TX_CTRL0: + r = s->regs[addr]; + break; + case R_RX_CTRL1: case R_RX_CTRL0: - r = s->regs[addr]; + r = s->port[port_index].reg.rx_ctrl; break; default: @@ -167,7 +185,9 @@ eth_write(void *opaque, hwaddr addr, if (!(value & CTRL_S)) { qemu_flush_queued_packets(qemu_get_queue(s->nic)); } - /* fall through */ + s->port[port_index].reg.rx_ctrl = value; + break; + case R_TX_LEN0: case R_TX_LEN1: case R_TX_GIE0: @@ -197,22 +217,21 @@ static const MemoryRegionOps eth_ops = { static bool eth_can_rx(NetClientState *nc) { XlnxXpsEthLite *s = qemu_get_nic_opaque(nc); - unsigned int rxbase = s->port_index * (0x800 / 4); - return !(s->regs[rxbase + R_RX_CTRL0] & CTRL_S); + return !(s->port[s->port_index].reg.rx_ctrl & CTRL_S); } static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size) { XlnxXpsEthLite *s = qemu_get_nic_opaque(nc); - unsigned int rxbase = s->port_index * (0x800 / 4); + unsigned int port_index = s->port_index; /* DA filter. */ if (!(buf[0] & 0x80) && memcmp(&s->conf.macaddr.a[0], buf, 6)) return size; - if (s->regs[rxbase + R_RX_CTRL0] & CTRL_S) { - trace_ethlite_pkt_lost(s->regs[R_RX_CTRL0]); + if (s->port[port_index].reg.rx_ctrl & CTRL_S) { + trace_ethlite_pkt_lost(s->port[port_index].reg.rx_ctrl); return -1; } @@ -220,10 +239,10 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size) trace_ethlite_pkt_size_too_big(size); return -1; } - memcpy(&s->regs[rxbase + R_RX_BUF0], buf, size); + memcpy(rxbuf_ptr(s, port_index), buf, size); - s->regs[rxbase + R_RX_CTRL0] |= CTRL_S; - if (s->regs[R_RX_CTRL0] & CTRL_I) { + s->port[port_index].reg.rx_ctrl |= CTRL_S; + if (s->port[port_index].reg.rx_ctrl & CTRL_I) { eth_pulse_irq(s); } From 64fdbae7e1bc6408204a3cf3b8e6a2e7d8e36fe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 9 Nov 2024 19:45:58 +0100 Subject: [PATCH 16/55] hw/net/xilinx_ethlite: Access TX_GIE register for each port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than accessing the registers within the mixed RAM/MMIO region as indexed register, declare a per-port TX_GIE. This will help to map the RAM as RAM (keeping MMIO as MMIO) in few commits. Previous s->regs[R_TX_GIE0] and s->regs[R_TX_GIE1] are now unused. Not a concern, this array will soon disappear. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Edgar E. Iglesias Message-Id: <20241112181044.92193-13-philmd@linaro.org> --- hw/net/xilinx_ethlite.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 67adecc088..3252c9d508 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -62,6 +62,8 @@ typedef struct XlnxXpsEthLitePort { struct { + uint32_t tx_gie; + uint32_t rx_ctrl; } reg; } XlnxXpsEthLitePort; @@ -90,7 +92,7 @@ struct XlnxXpsEthLite static inline void eth_pulse_irq(XlnxXpsEthLite *s) { /* Only the first gie reg is active. */ - if (s->regs[R_TX_GIE0] & GIE_GIE) { + if (s->port[0].reg.tx_gie & GIE_GIE) { qemu_irq_pulse(s->irq); } } @@ -126,6 +128,9 @@ eth_read(void *opaque, hwaddr addr, unsigned int size) switch (addr) { case R_TX_GIE0: + r = s->port[port_index].reg.tx_gie; + break; + case R_TX_LEN0: case R_TX_LEN1: case R_TX_CTRL1: @@ -190,10 +195,13 @@ eth_write(void *opaque, hwaddr addr, case R_TX_LEN0: case R_TX_LEN1: - case R_TX_GIE0: s->regs[addr] = value; break; + case R_TX_GIE0: + s->port[port_index].reg.tx_gie = value; + break; + default: s->regs[addr] = tswap32(value); break; From c629791859d5d1777d8471f260f418e76078e97e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 9 Nov 2024 19:48:36 +0100 Subject: [PATCH 17/55] hw/net/xilinx_ethlite: Access TX_LEN register for each port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than accessing the registers within the mixed RAM/MMIO region as indexed register, declare a per-port TX_LEN. This will help to map the RAM as RAM (keeping MMIO as MMIO) in few commits. Previous s->regs[R_TX_LEN0] and s->regs[R_TX_LEN1] are now unused. Not a concern, this array will soon disappear. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Edgar E. Iglesias Message-Id: <20241112181044.92193-14-philmd@linaro.org> --- hw/net/xilinx_ethlite.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 3252c9d508..ce9555bd1e 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -62,6 +62,7 @@ typedef struct XlnxXpsEthLitePort { struct { + uint32_t tx_len; uint32_t tx_gie; uint32_t rx_ctrl; @@ -133,6 +134,9 @@ eth_read(void *opaque, hwaddr addr, unsigned int size) case R_TX_LEN0: case R_TX_LEN1: + r = s->port[port_index].reg.tx_len; + break; + case R_TX_CTRL1: case R_TX_CTRL0: r = s->regs[addr]; @@ -170,7 +174,7 @@ eth_write(void *opaque, hwaddr addr, if ((value & (CTRL_P | CTRL_S)) == CTRL_S) { qemu_send_packet(qemu_get_queue(s->nic), txbuf_ptr(s, port_index), - s->regs[base + R_TX_LEN0]); + s->port[port_index].reg.tx_len); if (s->regs[base + R_TX_CTRL0] & CTRL_I) eth_pulse_irq(s); } else if ((value & (CTRL_P | CTRL_S)) == (CTRL_P | CTRL_S)) { @@ -195,7 +199,7 @@ eth_write(void *opaque, hwaddr addr, case R_TX_LEN0: case R_TX_LEN1: - s->regs[addr] = value; + s->port[port_index].reg.tx_len = value; break; case R_TX_GIE0: From a37506699109d2dbf86ec5c02734eee35d065d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 9 Nov 2024 19:51:55 +0100 Subject: [PATCH 18/55] hw/net/xilinx_ethlite: Access TX_CTRL register for each port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than accessing the registers within the mixed RAM/MMIO region as indexed register, declare a per-port TX_CTRL. This will help to map the RAM as RAM (keeping MMIO as MMIO) in few commits. Previous s->regs[R_TX_CTRL0] and s->regs[R_TX_CTRL1] are now unused. Not a concern, this array will soon disappear. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Edgar E. Iglesias Message-Id: <20241112181044.92193-15-philmd@linaro.org> --- hw/net/xilinx_ethlite.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index ce9555bd1e..f8b01fe9a6 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -64,6 +64,7 @@ typedef struct XlnxXpsEthLitePort { struct { uint32_t tx_len; uint32_t tx_gie; + uint32_t tx_ctrl; uint32_t rx_ctrl; } reg; @@ -139,7 +140,7 @@ eth_read(void *opaque, hwaddr addr, unsigned int size) case R_TX_CTRL1: case R_TX_CTRL0: - r = s->regs[addr]; + r = s->port[port_index].reg.tx_ctrl; break; case R_RX_CTRL1: @@ -160,7 +161,6 @@ eth_write(void *opaque, hwaddr addr, { XlnxXpsEthLite *s = opaque; unsigned int port_index = addr_to_port_index(addr); - unsigned int base = 0; uint32_t value = val64; addr >>= 2; @@ -168,24 +168,23 @@ eth_write(void *opaque, hwaddr addr, { case R_TX_CTRL0: case R_TX_CTRL1: - if (addr == R_TX_CTRL1) - base = 0x800 / 4; - if ((value & (CTRL_P | CTRL_S)) == CTRL_S) { qemu_send_packet(qemu_get_queue(s->nic), txbuf_ptr(s, port_index), s->port[port_index].reg.tx_len); - if (s->regs[base + R_TX_CTRL0] & CTRL_I) + if (s->port[port_index].reg.tx_ctrl & CTRL_I) { eth_pulse_irq(s); + } } else if ((value & (CTRL_P | CTRL_S)) == (CTRL_P | CTRL_S)) { memcpy(&s->conf.macaddr.a[0], txbuf_ptr(s, port_index), 6); - if (s->regs[base + R_TX_CTRL0] & CTRL_I) + if (s->port[port_index].reg.tx_ctrl & CTRL_I) { eth_pulse_irq(s); + } } /* We are fast and get ready pretty much immediately so we actually never flip the S nor P bits to one. */ - s->regs[addr] = value & ~(CTRL_P | CTRL_S); + s->port[port_index].reg.tx_ctrl = value & ~(CTRL_P | CTRL_S); break; /* Keep these native. */ From 72294962065e5d237dda3cd298016b47fef0c3c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 9 Nov 2024 20:03:00 +0100 Subject: [PATCH 19/55] hw/net/xilinx_ethlite: Map RX_CTRL as MMIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declare RX registers as MMIO region, split it out of the current mixed RAM/MMIO region. The memory flat view becomes: (qemu) info mtree -f FlatView #0 Root memory region: system 0000000081000000-00000000810007e3 (prio 0, i/o): xlnx.xps-ethernetlite 00000000810007e4-00000000810007f3 (prio 0, i/o): ethlite.mdio 00000000810007f4-00000000810017fb (prio 0, i/o): xlnx.xps-ethernetlite @00000000000007f4 00000000810017fc-00000000810017ff (prio 0, i/o): ethlite.rx[0]io 0000000081001800-0000000081001ffb (prio 0, i/o): xlnx.xps-ethernetlite @0000000000001800 0000000081001ffc-0000000081001fff (prio 0, i/o): ethlite.rx[1]io Reviewed-by: Edgar E. Iglesias Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20241112181044.92193-16-philmd@linaro.org> --- hw/net/xilinx_ethlite.c | 82 +++++++++++++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 15 deletions(-) diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index f8b01fe9a6..9ac81ca1e0 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -49,11 +49,16 @@ #define R_TX_CTRL1 (0x0ffc / 4) #define R_RX_BUF0 (0x1000 / 4) -#define R_RX_CTRL0 (0x17fc / 4) +#define A_RX_BASE0 0x17fc #define R_RX_BUF1 (0x1800 / 4) -#define R_RX_CTRL1 (0x1ffc / 4) +#define A_RX_BASE1 0x1ffc #define R_MAX (0x2000 / 4) +enum { + RX_CTRL = 0, + RX_MAX +}; + #define GIE_GIE 0x80000000 #define CTRL_I 0x8 @@ -61,6 +66,8 @@ #define CTRL_S 0x1 typedef struct XlnxXpsEthLitePort { + MemoryRegion rxio; + struct { uint32_t tx_len; uint32_t tx_gie; @@ -118,6 +125,55 @@ static void *rxbuf_ptr(XlnxXpsEthLite *s, unsigned port_index) return &s->regs[rxbase + R_RX_BUF0]; } +static uint64_t port_rx_read(void *opaque, hwaddr addr, unsigned int size) +{ + XlnxXpsEthLite *s = opaque; + unsigned port_index = addr_to_port_index(addr); + uint32_t r = 0; + + switch (addr >> 2) { + case RX_CTRL: + r = s->port[port_index].reg.rx_ctrl; + break; + default: + g_assert_not_reached(); + } + + return r; +} + +static void port_rx_write(void *opaque, hwaddr addr, uint64_t value, + unsigned int size) +{ + XlnxXpsEthLite *s = opaque; + unsigned port_index = addr_to_port_index(addr); + + switch (addr >> 2) { + case RX_CTRL: + if (!(value & CTRL_S)) { + qemu_flush_queued_packets(qemu_get_queue(s->nic)); + } + s->port[port_index].reg.rx_ctrl = value; + break; + default: + g_assert_not_reached(); + } +} + +static const MemoryRegionOps eth_portrx_ops = { + .read = port_rx_read, + .write = port_rx_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + static uint64_t eth_read(void *opaque, hwaddr addr, unsigned int size) { @@ -143,11 +199,6 @@ eth_read(void *opaque, hwaddr addr, unsigned int size) r = s->port[port_index].reg.tx_ctrl; break; - case R_RX_CTRL1: - case R_RX_CTRL0: - r = s->port[port_index].reg.rx_ctrl; - break; - default: r = tswap32(s->regs[addr]); break; @@ -188,14 +239,6 @@ eth_write(void *opaque, hwaddr addr, break; /* Keep these native. */ - case R_RX_CTRL0: - case R_RX_CTRL1: - if (!(value & CTRL_S)) { - qemu_flush_queued_packets(qemu_get_queue(s->nic)); - } - s->port[port_index].reg.rx_ctrl = value; - break; - case R_TX_LEN0: case R_TX_LEN1: s->port[port_index].reg.tx_len = value; @@ -288,6 +331,15 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&s->mmio, A_MDIO_BASE, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mdio), 0)); + for (unsigned i = 0; i < 2; i++) { + memory_region_init_io(&s->port[i].rxio, OBJECT(dev), + ð_portrx_ops, s, + i ? "ethlite.rx[1]io" : "ethlite.rx[0]io", + 4 * RX_MAX); + memory_region_add_subregion(&s->mmio, i ? A_RX_BASE1 : A_RX_BASE0, + &s->port[i].rxio); + } + qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, From 46dd6af2592d7a7d876ed8617b1e70d43c676ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 10 Nov 2024 16:51:24 +0100 Subject: [PATCH 20/55] hw/net/xilinx_ethlite: Map TX_LEN as MMIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declare TX registers as MMIO region, split it out of the current mixed RAM/MMIO region. The memory flat view becomes: (qemu) info mtree -f FlatView #0 Root memory region: system 0000000081000000-00000000810007e3 (prio 0, i/o): xlnx.xps-ethernetlite 00000000810007e4-00000000810007f3 (prio 0, i/o): ethlite.mdio 00000000810007f4-00000000810007f7 (prio 0, i/o): ethlite.tx[0]io 00000000810007f8-0000000081000ff3 (prio 0, i/o): xlnx.xps-ethernetlite @00000000000007f8 0000000081000ff4-0000000081000ff7 (prio 0, i/o): ethlite.tx[1]io 0000000081000ff8-00000000810017fb (prio 0, i/o): xlnx.xps-ethernetlite @0000000000000ff8 00000000810017fc-00000000810017ff (prio 0, i/o): ethlite.rx[0]io 0000000081001800-0000000081001ffb (prio 0, i/o): xlnx.xps-ethernetlite @0000000000001800 0000000081001ffc-0000000081001fff (prio 0, i/o): ethlite.rx[1]io Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Edgar E. Iglesias Message-Id: <20241112181044.92193-17-philmd@linaro.org> --- hw/net/xilinx_ethlite.c | 73 ++++++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 9ac81ca1e0..5dac44fa68 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -41,11 +41,11 @@ #define R_TX_BUF0 0 #define BUFSZ_MAX 0x07e4 #define A_MDIO_BASE 0x07e4 -#define R_TX_LEN0 (0x07f4 / 4) +#define A_TX_BASE0 0x07f4 #define R_TX_GIE0 (0x07f8 / 4) #define R_TX_CTRL0 (0x07fc / 4) #define R_TX_BUF1 (0x0800 / 4) -#define R_TX_LEN1 (0x0ff4 / 4) +#define A_TX_BASE1 0x0ff4 #define R_TX_CTRL1 (0x0ffc / 4) #define R_RX_BUF0 (0x1000 / 4) @@ -54,6 +54,11 @@ #define A_RX_BASE1 0x1ffc #define R_MAX (0x2000 / 4) +enum { + TX_LEN = 0, + TX_MAX +}; + enum { RX_CTRL = 0, RX_MAX @@ -66,6 +71,7 @@ enum { #define CTRL_S 0x1 typedef struct XlnxXpsEthLitePort { + MemoryRegion txio; MemoryRegion rxio; struct { @@ -125,6 +131,52 @@ static void *rxbuf_ptr(XlnxXpsEthLite *s, unsigned port_index) return &s->regs[rxbase + R_RX_BUF0]; } +static uint64_t port_tx_read(void *opaque, hwaddr addr, unsigned int size) +{ + XlnxXpsEthLite *s = opaque; + unsigned port_index = addr_to_port_index(addr); + uint32_t r = 0; + + switch (addr >> 2) { + case TX_LEN: + r = s->port[port_index].reg.tx_len; + break; + default: + g_assert_not_reached(); + } + + return r; +} + +static void port_tx_write(void *opaque, hwaddr addr, uint64_t value, + unsigned int size) +{ + XlnxXpsEthLite *s = opaque; + unsigned port_index = addr_to_port_index(addr); + + switch (addr >> 2) { + case TX_LEN: + s->port[port_index].reg.tx_len = value; + break; + default: + g_assert_not_reached(); + } +} + +static const MemoryRegionOps eth_porttx_ops = { + .read = port_tx_read, + .write = port_tx_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + static uint64_t port_rx_read(void *opaque, hwaddr addr, unsigned int size) { XlnxXpsEthLite *s = opaque; @@ -189,11 +241,6 @@ eth_read(void *opaque, hwaddr addr, unsigned int size) r = s->port[port_index].reg.tx_gie; break; - case R_TX_LEN0: - case R_TX_LEN1: - r = s->port[port_index].reg.tx_len; - break; - case R_TX_CTRL1: case R_TX_CTRL0: r = s->port[port_index].reg.tx_ctrl; @@ -239,11 +286,6 @@ eth_write(void *opaque, hwaddr addr, break; /* Keep these native. */ - case R_TX_LEN0: - case R_TX_LEN1: - s->port[port_index].reg.tx_len = value; - break; - case R_TX_GIE0: s->port[port_index].reg.tx_gie = value; break; @@ -332,6 +374,13 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mdio), 0)); for (unsigned i = 0; i < 2; i++) { + memory_region_init_io(&s->port[i].txio, OBJECT(dev), + ð_porttx_ops, s, + i ? "ethlite.tx[1]io" : "ethlite.tx[0]io", + 4 * TX_MAX); + memory_region_add_subregion(&s->mmio, i ? A_TX_BASE1 : A_TX_BASE0, + &s->port[i].txio); + memory_region_init_io(&s->port[i].rxio, OBJECT(dev), ð_portrx_ops, s, i ? "ethlite.rx[1]io" : "ethlite.rx[0]io", From 01198add29ddecc1283f1ab5cb4b34885e7daaa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 11 Nov 2024 17:15:56 +0100 Subject: [PATCH 21/55] hw/net/xilinx_ethlite: Map TX_GIE as MMIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add TX_GIE to the TX registers MMIO region. Before TX_GIE1 was accessed as RAM, with no effect. Now it is accessed as MMIO, also without any effect. The memory flat view becomes: (qemu) info mtree -f FlatView #0 Root memory region: system 0000000081000000-00000000810007e3 (prio 0, i/o): xlnx.xps-ethernetlite 00000000810007e4-00000000810007f3 (prio 0, i/o): ethlite.mdio 00000000810007f4-00000000810007fb (prio 0, i/o): ethlite.tx[0]io 00000000810007fc-0000000081000ff3 (prio 0, i/o): xlnx.xps-ethernetlite @00000000000007fc 0000000081000ff4-0000000081000ffb (prio 0, i/o): ethlite.tx[1]io 0000000081000ffc-00000000810017fb (prio 0, i/o): xlnx.xps-ethernetlite @0000000000000ffc 00000000810017fc-00000000810017ff (prio 0, i/o): ethlite.rx[0]io 0000000081001800-0000000081001ffb (prio 0, i/o): xlnx.xps-ethernetlite @0000000000001800 0000000081001ffc-0000000081001fff (prio 0, i/o): ethlite.rx[1]io Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Edgar E. Iglesias Message-Id: <20241112181044.92193-18-philmd@linaro.org> --- hw/net/xilinx_ethlite.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 5dac44fa68..898c09b398 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -42,7 +42,6 @@ #define BUFSZ_MAX 0x07e4 #define A_MDIO_BASE 0x07e4 #define A_TX_BASE0 0x07f4 -#define R_TX_GIE0 (0x07f8 / 4) #define R_TX_CTRL0 (0x07fc / 4) #define R_TX_BUF1 (0x0800 / 4) #define A_TX_BASE1 0x0ff4 @@ -56,6 +55,7 @@ enum { TX_LEN = 0, + TX_GIE = 1, TX_MAX }; @@ -141,6 +141,9 @@ static uint64_t port_tx_read(void *opaque, hwaddr addr, unsigned int size) case TX_LEN: r = s->port[port_index].reg.tx_len; break; + case TX_GIE: + r = s->port[port_index].reg.tx_gie; + break; default: g_assert_not_reached(); } @@ -158,6 +161,9 @@ static void port_tx_write(void *opaque, hwaddr addr, uint64_t value, case TX_LEN: s->port[port_index].reg.tx_len = value; break; + case TX_GIE: + s->port[port_index].reg.tx_gie = value; + break; default: g_assert_not_reached(); } @@ -237,10 +243,6 @@ eth_read(void *opaque, hwaddr addr, unsigned int size) switch (addr) { - case R_TX_GIE0: - r = s->port[port_index].reg.tx_gie; - break; - case R_TX_CTRL1: case R_TX_CTRL0: r = s->port[port_index].reg.tx_ctrl; @@ -285,11 +287,6 @@ eth_write(void *opaque, hwaddr addr, s->port[port_index].reg.tx_ctrl = value & ~(CTRL_P | CTRL_S); break; - /* Keep these native. */ - case R_TX_GIE0: - s->port[port_index].reg.tx_gie = value; - break; - default: s->regs[addr] = tswap32(value); break; From a34606dbb3c7094b6e9fde5e1463a306b6921255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 11 Nov 2024 17:19:39 +0100 Subject: [PATCH 22/55] hw/net/xilinx_ethlite: Map TX_CTRL as MMIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add TX_CTRL to the TX registers MMIO region. The memory flat view becomes: (qemu) info mtree -f FlatView #0 Root memory region: system 0000000081000000-00000000810007e3 (prio 0, i/o): xlnx.xps-ethernetlite 00000000810007e4-00000000810007f3 (prio 0, i/o): ethlite.mdio 00000000810007f4-00000000810007ff (prio 0, i/o): ethlite.tx[0]io 0000000081000800-0000000081000ff3 (prio 0, i/o): xlnx.xps-ethernetlite @0000000000000800 0000000081000ff4-0000000081000fff (prio 0, i/o): ethlite.tx[1]io 0000000081001000-00000000810017fb (prio 0, i/o): xlnx.xps-ethernetlite @0000000000001000 00000000810017fc-00000000810017ff (prio 0, i/o): ethlite.rx[0]io 0000000081001800-0000000081001ffb (prio 0, i/o): xlnx.xps-ethernetlite @0000000000001800 0000000081001ffc-0000000081001fff (prio 0, i/o): ethlite.rx[1]io Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Edgar E. Iglesias Message-Id: <20241112181044.92193-19-philmd@linaro.org> --- hw/net/xilinx_ethlite.c | 54 ++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 898c09b398..5ab8ae43b2 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -42,10 +42,8 @@ #define BUFSZ_MAX 0x07e4 #define A_MDIO_BASE 0x07e4 #define A_TX_BASE0 0x07f4 -#define R_TX_CTRL0 (0x07fc / 4) #define R_TX_BUF1 (0x0800 / 4) #define A_TX_BASE1 0x0ff4 -#define R_TX_CTRL1 (0x0ffc / 4) #define R_RX_BUF0 (0x1000 / 4) #define A_RX_BASE0 0x17fc @@ -56,6 +54,7 @@ enum { TX_LEN = 0, TX_GIE = 1, + TX_CTRL = 2, TX_MAX }; @@ -144,6 +143,9 @@ static uint64_t port_tx_read(void *opaque, hwaddr addr, unsigned int size) case TX_GIE: r = s->port[port_index].reg.tx_gie; break; + case TX_CTRL: + r = s->port[port_index].reg.tx_ctrl; + break; default: g_assert_not_reached(); } @@ -164,6 +166,26 @@ static void port_tx_write(void *opaque, hwaddr addr, uint64_t value, case TX_GIE: s->port[port_index].reg.tx_gie = value; break; + case TX_CTRL: + if ((value & (CTRL_P | CTRL_S)) == CTRL_S) { + qemu_send_packet(qemu_get_queue(s->nic), + txbuf_ptr(s, port_index), + s->port[port_index].reg.tx_len); + if (s->port[port_index].reg.tx_ctrl & CTRL_I) { + eth_pulse_irq(s); + } + } else if ((value & (CTRL_P | CTRL_S)) == (CTRL_P | CTRL_S)) { + memcpy(&s->conf.macaddr.a[0], txbuf_ptr(s, port_index), 6); + if (s->port[port_index].reg.tx_ctrl & CTRL_I) { + eth_pulse_irq(s); + } + } + /* + * We are fast and get ready pretty much immediately + * so we actually never flip the S nor P bits to one. + */ + s->port[port_index].reg.tx_ctrl = value & ~(CTRL_P | CTRL_S); + break; default: g_assert_not_reached(); } @@ -236,18 +258,12 @@ static uint64_t eth_read(void *opaque, hwaddr addr, unsigned int size) { XlnxXpsEthLite *s = opaque; - unsigned port_index = addr_to_port_index(addr); uint32_t r = 0; addr >>= 2; switch (addr) { - case R_TX_CTRL1: - case R_TX_CTRL0: - r = s->port[port_index].reg.tx_ctrl; - break; - default: r = tswap32(s->regs[addr]); break; @@ -260,33 +276,11 @@ eth_write(void *opaque, hwaddr addr, uint64_t val64, unsigned int size) { XlnxXpsEthLite *s = opaque; - unsigned int port_index = addr_to_port_index(addr); uint32_t value = val64; addr >>= 2; switch (addr) { - case R_TX_CTRL0: - case R_TX_CTRL1: - if ((value & (CTRL_P | CTRL_S)) == CTRL_S) { - qemu_send_packet(qemu_get_queue(s->nic), - txbuf_ptr(s, port_index), - s->port[port_index].reg.tx_len); - if (s->port[port_index].reg.tx_ctrl & CTRL_I) { - eth_pulse_irq(s); - } - } else if ((value & (CTRL_P | CTRL_S)) == (CTRL_P | CTRL_S)) { - memcpy(&s->conf.macaddr.a[0], txbuf_ptr(s, port_index), 6); - if (s->port[port_index].reg.tx_ctrl & CTRL_I) { - eth_pulse_irq(s); - } - } - - /* We are fast and get ready pretty much immediately so - we actually never flip the S nor P bits to one. */ - s->port[port_index].reg.tx_ctrl = value & ~(CTRL_P | CTRL_S); - break; - default: s->regs[addr] = tswap32(value); break; From 0bd0ba87a0fa22b5d3dda206f1920547df6eb918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 11 Nov 2024 17:44:53 +0100 Subject: [PATCH 23/55] hw/net/xilinx_ethlite: Map the RAM buffer as RAM memory region MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than using I/O registers for RAM buffer, having to swap endianness back and forth (because the core memory layer automatically swaps endiannes for us), declare the buffers as RAM regions. The "xlnx.xps-ethernetlite" MR doesn't have any more I/O regions. Remove the now unused s->regs[] array. The memory flat view becomes: FlatView #0 Root memory region: system 0000000081000000-00000000810007e3 (prio 0, ram): ethlite.tx[0]buf 00000000810007e4-00000000810007f3 (prio 0, i/o): ethlite.mdio 00000000810007f4-00000000810007ff (prio 0, i/o): ethlite.tx[0]io 0000000081000800-0000000081000fe3 (prio 0, ram): ethlite.tx[1]buf 0000000081000ff4-0000000081000fff (prio 0, i/o): ethlite.tx[1]io 0000000081001000-00000000810017e3 (prio 0, ram): ethlite.rx[0]buf 00000000810017fc-00000000810017ff (prio 0, i/o): ethlite.rx[0]io 0000000081001800-0000000081001fe3 (prio 0, ram): ethlite.rx[1]buf 0000000081001ffc-0000000081001fff (prio 0, i/o): ethlite.rx[1]io Reported-by: Paolo Bonzini Reviewed-by: Edgar E. Iglesias Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20241114210010.34502-18-philmd@linaro.org> --- hw/net/xilinx_ethlite.c | 81 +++++++++-------------------------------- 1 file changed, 17 insertions(+), 64 deletions(-) diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 5ab8ae43b2..758226a65d 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -2,6 +2,7 @@ * QEMU model of the Xilinx Ethernet Lite MAC. * * Copyright (c) 2009 Edgar E. Iglesias. + * Copyright (c) 2024 Linaro, Ltd * * DS580: https://docs.amd.com/v/u/en-US/xps_ethernetlite * LogiCORE IP XPS Ethernet Lite Media Access Controller @@ -30,7 +31,6 @@ #include "qemu/bitops.h" #include "qom/object.h" #include "qapi/error.h" -#include "exec/tswap.h" #include "hw/sysbus.h" #include "hw/irq.h" #include "hw/qdev-properties.h" @@ -38,18 +38,12 @@ #include "net/net.h" #include "trace.h" -#define R_TX_BUF0 0 #define BUFSZ_MAX 0x07e4 #define A_MDIO_BASE 0x07e4 #define A_TX_BASE0 0x07f4 -#define R_TX_BUF1 (0x0800 / 4) #define A_TX_BASE1 0x0ff4 - -#define R_RX_BUF0 (0x1000 / 4) #define A_RX_BASE0 0x17fc -#define R_RX_BUF1 (0x1800 / 4) #define A_RX_BASE1 0x1ffc -#define R_MAX (0x2000 / 4) enum { TX_LEN = 0, @@ -72,6 +66,8 @@ enum { typedef struct XlnxXpsEthLitePort { MemoryRegion txio; MemoryRegion rxio; + MemoryRegion txbuf; + MemoryRegion rxbuf; struct { uint32_t tx_len; @@ -100,7 +96,6 @@ struct XlnxXpsEthLite UnimplementedDeviceState mdio; XlnxXpsEthLitePort port[2]; - uint32_t regs[R_MAX]; }; static inline void eth_pulse_irq(XlnxXpsEthLite *s) @@ -118,16 +113,12 @@ static unsigned addr_to_port_index(hwaddr addr) static void *txbuf_ptr(XlnxXpsEthLite *s, unsigned port_index) { - unsigned int rxbase = port_index * (0x800 / 4); - - return &s->regs[rxbase + R_TX_BUF0]; + return memory_region_get_ram_ptr(&s->port[port_index].txbuf); } static void *rxbuf_ptr(XlnxXpsEthLite *s, unsigned port_index) { - unsigned int rxbase = port_index * (0x800 / 4); - - return &s->regs[rxbase + R_RX_BUF0]; + return memory_region_get_ram_ptr(&s->port[port_index].rxbuf); } static uint64_t port_tx_read(void *opaque, hwaddr addr, unsigned int size) @@ -254,53 +245,6 @@ static const MemoryRegionOps eth_portrx_ops = { }, }; -static uint64_t -eth_read(void *opaque, hwaddr addr, unsigned int size) -{ - XlnxXpsEthLite *s = opaque; - uint32_t r = 0; - - addr >>= 2; - - switch (addr) - { - default: - r = tswap32(s->regs[addr]); - break; - } - return r; -} - -static void -eth_write(void *opaque, hwaddr addr, - uint64_t val64, unsigned int size) -{ - XlnxXpsEthLite *s = opaque; - uint32_t value = val64; - - addr >>= 2; - switch (addr) - { - default: - s->regs[addr] = tswap32(value); - break; - } -} - -static const MemoryRegionOps eth_ops = { - .read = eth_read, - .write = eth_write, - .endianness = DEVICE_NATIVE_ENDIAN, - .impl = { - .min_access_size = 4, - .max_access_size = 4, - }, - .valid = { - .min_access_size = 4, - .max_access_size = 4 - } -}; - static bool eth_can_rx(NetClientState *nc) { XlnxXpsEthLite *s = qemu_get_nic_opaque(nc); @@ -356,6 +300,9 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) { XlnxXpsEthLite *s = XILINX_ETHLITE(dev); + memory_region_init(&s->mmio, OBJECT(dev), + "xlnx.xps-ethernetlite", 0x2000); + object_initialize_child(OBJECT(dev), "ethlite.mdio", &s->mdio, TYPE_UNIMPLEMENTED_DEVICE); qdev_prop_set_string(DEVICE(&s->mdio), "name", "ethlite.mdio"); @@ -365,6 +312,10 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mdio), 0)); for (unsigned i = 0; i < 2; i++) { + memory_region_init_ram(&s->port[i].txbuf, OBJECT(dev), + i ? "ethlite.tx[1]buf" : "ethlite.tx[0]buf", + BUFSZ_MAX, &error_abort); + memory_region_add_subregion(&s->mmio, 0x0800 * i, &s->port[i].txbuf); memory_region_init_io(&s->port[i].txio, OBJECT(dev), ð_porttx_ops, s, i ? "ethlite.tx[1]io" : "ethlite.tx[0]io", @@ -372,6 +323,11 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&s->mmio, i ? A_TX_BASE1 : A_TX_BASE0, &s->port[i].txio); + memory_region_init_ram(&s->port[i].rxbuf, OBJECT(dev), + i ? "ethlite.rx[1]buf" : "ethlite.rx[0]buf", + BUFSZ_MAX, &error_abort); + memory_region_add_subregion(&s->mmio, 0x1000 + 0x0800 * i, + &s->port[i].rxbuf); memory_region_init_io(&s->port[i].rxio, OBJECT(dev), ð_portrx_ops, s, i ? "ethlite.rx[1]io" : "ethlite.rx[0]io", @@ -392,9 +348,6 @@ static void xilinx_ethlite_init(Object *obj) XlnxXpsEthLite *s = XILINX_ETHLITE(obj); sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); - - memory_region_init_io(&s->mmio, obj, ð_ops, s, - "xlnx.xps-ethernetlite", R_MAX * 4); sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); } From ce336679b72cfb5cbbf1539d209764242fc5458a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 11 Nov 2024 17:44:53 +0100 Subject: [PATCH 24/55] hw/net/xilinx_ethlite: Rename 'mmio' MR as 'container' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Having all its address range mapped by subregions, s->mmio MemoryRegion effectively became a container. Rename it as 'container' for clarity. Reviewed-by: Edgar E. Iglesias Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20241112181044.92193-21-philmd@linaro.org> --- hw/net/xilinx_ethlite.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 758226a65d..a7f6d1b368 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -85,7 +85,7 @@ struct XlnxXpsEthLite { SysBusDevice parent_obj; - MemoryRegion mmio; + MemoryRegion container; qemu_irq irq; NICState *nic; NICConf conf; @@ -300,7 +300,7 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) { XlnxXpsEthLite *s = XILINX_ETHLITE(dev); - memory_region_init(&s->mmio, OBJECT(dev), + memory_region_init(&s->container, OBJECT(dev), "xlnx.xps-ethernetlite", 0x2000); object_initialize_child(OBJECT(dev), "ethlite.mdio", &s->mdio, @@ -308,31 +308,31 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) qdev_prop_set_string(DEVICE(&s->mdio), "name", "ethlite.mdio"); qdev_prop_set_uint64(DEVICE(&s->mdio), "size", 4 * 4); sysbus_realize(SYS_BUS_DEVICE(&s->mdio), &error_fatal); - memory_region_add_subregion(&s->mmio, A_MDIO_BASE, + memory_region_add_subregion(&s->container, A_MDIO_BASE, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mdio), 0)); for (unsigned i = 0; i < 2; i++) { memory_region_init_ram(&s->port[i].txbuf, OBJECT(dev), i ? "ethlite.tx[1]buf" : "ethlite.tx[0]buf", BUFSZ_MAX, &error_abort); - memory_region_add_subregion(&s->mmio, 0x0800 * i, &s->port[i].txbuf); + memory_region_add_subregion(&s->container, 0x0800 * i, &s->port[i].txbuf); memory_region_init_io(&s->port[i].txio, OBJECT(dev), ð_porttx_ops, s, i ? "ethlite.tx[1]io" : "ethlite.tx[0]io", 4 * TX_MAX); - memory_region_add_subregion(&s->mmio, i ? A_TX_BASE1 : A_TX_BASE0, + memory_region_add_subregion(&s->container, i ? A_TX_BASE1 : A_TX_BASE0, &s->port[i].txio); memory_region_init_ram(&s->port[i].rxbuf, OBJECT(dev), i ? "ethlite.rx[1]buf" : "ethlite.rx[0]buf", BUFSZ_MAX, &error_abort); - memory_region_add_subregion(&s->mmio, 0x1000 + 0x0800 * i, + memory_region_add_subregion(&s->container, 0x1000 + 0x0800 * i, &s->port[i].rxbuf); memory_region_init_io(&s->port[i].rxio, OBJECT(dev), ð_portrx_ops, s, i ? "ethlite.rx[1]io" : "ethlite.rx[0]io", 4 * RX_MAX); - memory_region_add_subregion(&s->mmio, i ? A_RX_BASE1 : A_RX_BASE0, + memory_region_add_subregion(&s->container, i ? A_RX_BASE1 : A_RX_BASE0, &s->port[i].rxio); } @@ -348,7 +348,7 @@ static void xilinx_ethlite_init(Object *obj) XlnxXpsEthLite *s = XILINX_ETHLITE(obj); sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); - sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->container); } static const Property xilinx_ethlite_properties[] = { From 74f1caa8c33f608168c4224bb23d9a6453224a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 14 Nov 2024 18:46:36 +0100 Subject: [PATCH 25/55] hw/net/xilinx_ethlite: Map RESERVED I/O as unimplemented MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to track access to reserved I/O space, use yet another UnimplementedDevice covering the whole device memory range. Mapped with lower priority (-1). The memory flat view becomes: (qemu) info mtree -f FlatView #0 Root memory region: system 0000000081000000-00000000810007e3 (prio 0, ram): ethlite.tx[0]buf 00000000810007e4-00000000810007f3 (prio 0, i/o): ethlite.mdio 00000000810007f4-00000000810007ff (prio 0, i/o): ethlite.tx[0]io 0000000081000800-0000000081000fe3 (prio 0, ram): ethlite.tx[1]buf 0000000081000fe4-0000000081000ff3 (prio -1, i/o): ethlite.reserved @0000000000000fe4 0000000081000ff4-0000000081000fff (prio 0, i/o): ethlite.tx[1]io 0000000081001000-00000000810017e3 (prio 0, ram): ethlite.rx[0]buf 00000000810017e4-00000000810017fb (prio -1, i/o): ethlite.reserved @00000000000017e4 00000000810017fc-00000000810017ff (prio 0, i/o): ethlite.rx[0]io 0000000081001800-0000000081001fe3 (prio 0, ram): ethlite.rx[1]buf 0000000081001fe4-0000000081001ffb (prio -1, i/o): ethlite.reserved @0000000000001fe4 0000000081001ffc-0000000081001fff (prio 0, i/o): ethlite.rx[1]io Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alex Bennée Message-Id: <20241114210010.34502-20-philmd@linaro.org> --- hw/net/xilinx_ethlite.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index a7f6d1b368..14bf2b2e17 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -94,6 +94,7 @@ struct XlnxXpsEthLite uint32_t c_rx_pingpong; unsigned int port_index; /* dual port RAM index */ + UnimplementedDeviceState rsvd; UnimplementedDeviceState mdio; XlnxXpsEthLitePort port[2]; }; @@ -303,6 +304,16 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) memory_region_init(&s->container, OBJECT(dev), "xlnx.xps-ethernetlite", 0x2000); + object_initialize_child(OBJECT(dev), "ethlite.reserved", &s->rsvd, + TYPE_UNIMPLEMENTED_DEVICE); + qdev_prop_set_string(DEVICE(&s->rsvd), "name", "ethlite.reserved"); + qdev_prop_set_uint64(DEVICE(&s->rsvd), "size", + memory_region_size(&s->container)); + sysbus_realize(SYS_BUS_DEVICE(&s->rsvd), &error_fatal); + memory_region_add_subregion_overlap(&s->container, 0, + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->rsvd), 0), + -1); + object_initialize_child(OBJECT(dev), "ethlite.mdio", &s->mdio, TYPE_UNIMPLEMENTED_DEVICE); qdev_prop_set_string(DEVICE(&s->mdio), "name", "ethlite.mdio"); From d024d0adf48e28d4f93161878053936d55dab9c9 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 11 Dec 2024 22:25:12 +0000 Subject: [PATCH 26/55] docs/nitro-enclave: Clarify Enclave and Firecracker relationship MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The documentation says that Nitro Enclaves are based on Firecracker. AWS has never made that statement. This patch nudges the wording to instead say it "looks like a Firecracker microvm". Signed-off-by: Alexander Graf Reviewed-by: Dorjoy Chowdhury Message-ID: <20241211222512.95660-1-graf@amazon.com> Signed-off-by: Philippe Mathieu-Daudé --- docs/system/i386/nitro-enclave.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/system/i386/nitro-enclave.rst b/docs/system/i386/nitro-enclave.rst index 48eda5bd9e..7317f547dc 100644 --- a/docs/system/i386/nitro-enclave.rst +++ b/docs/system/i386/nitro-enclave.rst @@ -13,7 +13,7 @@ the enclave VM gets a dynamic CID. Enclaves use an EIF (`Enclave Image Format`_) file which contains the necessary kernel, cmdline and ramdisk(s) to boot. In QEMU, ``nitro-enclave`` is a machine type based on ``microvm`` similar to how -AWS nitro enclaves are based on `Firecracker`_ microvm. This is useful for +AWS nitro enclaves look like a `Firecracker`_ microvm. This is useful for local testing of EIF files using QEMU instead of running real AWS Nitro Enclaves which can be difficult for debugging due to its roots in security. The vsock device emulation is done using vhost-user-vsock which means another process that From b2d4e9f3b8437359e063431d991d4d4eb1ef7d6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 19 Dec 2024 15:01:52 +0100 Subject: [PATCH 27/55] hw/misc/vmcoreinfo: Rename VMCOREINFO_DEVICE -> TYPE_VMCOREINFO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow the assumed QOM type definition style, prefixing with 'TYPE_', and dropping the '_DEVICE' suffix which doesn't add any value. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Marc-André Lureau Message-Id: <20250102132624.53443-1-philmd@linaro.org> --- hw/misc/vmcoreinfo.c | 6 +++--- include/hw/misc/vmcoreinfo.h | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/hw/misc/vmcoreinfo.c b/hw/misc/vmcoreinfo.c index b1fcc22e92..145f13a65c 100644 --- a/hw/misc/vmcoreinfo.c +++ b/hw/misc/vmcoreinfo.c @@ -47,13 +47,13 @@ static void vmcoreinfo_realize(DeviceState *dev, Error **errp) */ if (!vmcoreinfo_find()) { error_setg(errp, "at most one %s device is permitted", - VMCOREINFO_DEVICE); + TYPE_VMCOREINFO); return; } if (!fw_cfg || !fw_cfg->dma_enabled) { error_setg(errp, "%s device requires fw_cfg with DMA", - VMCOREINFO_DEVICE); + TYPE_VMCOREINFO); return; } @@ -95,7 +95,7 @@ static void vmcoreinfo_device_class_init(ObjectClass *klass, void *data) static const TypeInfo vmcoreinfo_types[] = { { - .name = VMCOREINFO_DEVICE, + .name = TYPE_VMCOREINFO, .parent = TYPE_DEVICE, .instance_size = sizeof(VMCoreInfoState), .class_init = vmcoreinfo_device_class_init, diff --git a/include/hw/misc/vmcoreinfo.h b/include/hw/misc/vmcoreinfo.h index 0b7b55d400..1aa4477163 100644 --- a/include/hw/misc/vmcoreinfo.h +++ b/include/hw/misc/vmcoreinfo.h @@ -16,10 +16,9 @@ #include "standard-headers/linux/qemu_fw_cfg.h" #include "qom/object.h" -#define VMCOREINFO_DEVICE "vmcoreinfo" +#define TYPE_VMCOREINFO "vmcoreinfo" typedef struct VMCoreInfoState VMCoreInfoState; -DECLARE_INSTANCE_CHECKER(VMCoreInfoState, VMCOREINFO, - VMCOREINFO_DEVICE) +DECLARE_INSTANCE_CHECKER(VMCoreInfoState, VMCOREINFO, TYPE_VMCOREINFO) typedef struct fw_cfg_vmcoreinfo FWCfgVMCoreInfo; @@ -33,7 +32,7 @@ struct VMCoreInfoState { /* returns NULL unless there is exactly one device */ static inline VMCoreInfoState *vmcoreinfo_find(void) { - Object *o = object_resolve_path_type("", VMCOREINFO_DEVICE, NULL); + Object *o = object_resolve_path_type("", TYPE_VMCOREINFO, NULL); return o ? VMCOREINFO(o) : NULL; } From b7700c9fb1c052e3f2c503c535bccdb6dd70dd97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 19 Dec 2024 16:19:35 +0100 Subject: [PATCH 28/55] hw/misc/vmcoreinfo: Convert to three-phase reset interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Daniel P. Berrangé Message-Id: <20241219153857.57450-6-philmd@linaro.org> --- hw/misc/vmcoreinfo.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/hw/misc/vmcoreinfo.c b/hw/misc/vmcoreinfo.c index 145f13a65c..b0145fa504 100644 --- a/hw/misc/vmcoreinfo.c +++ b/hw/misc/vmcoreinfo.c @@ -26,9 +26,9 @@ static void fw_cfg_vmci_write(void *opaque, off_t offset, size_t len) && s->vmcoreinfo.guest_format != FW_CFG_VMCOREINFO_FORMAT_NONE; } -static void vmcoreinfo_reset(void *opaque) +static void vmcoreinfo_reset_hold(Object *obj, ResetType type) { - VMCoreInfoState *s = opaque; + VMCoreInfoState *s = VMCOREINFO(obj); s->has_vmcoreinfo = false; memset(&s->vmcoreinfo, 0, sizeof(s->vmcoreinfo)); @@ -65,7 +65,7 @@ static void vmcoreinfo_realize(DeviceState *dev, Error **errp) * This device requires to register a global reset because it is * not plugged to a bus (which, as its QOM parent, would reset it). */ - qemu_register_reset(vmcoreinfo_reset, s); + qemu_register_resettable(OBJECT(s)); vmcoreinfo_state = s; } @@ -86,11 +86,13 @@ static const VMStateDescription vmstate_vmcoreinfo = { static void vmcoreinfo_device_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); dc->vmsd = &vmstate_vmcoreinfo; dc->realize = vmcoreinfo_realize; dc->hotpluggable = false; set_bit(DEVICE_CATEGORY_MISC, dc->categories); + rc->phases.hold = vmcoreinfo_reset_hold; } static const TypeInfo vmcoreinfo_types[] = { From c407eef162f765dd83d45e048585731be41a66fc Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Thu, 9 Jan 2025 15:29:46 +0900 Subject: [PATCH 29/55] hw/pci: Rename has_power to enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The renamed state will not only represent powering state of PFs, but also represent SR-IOV VF enablement in the future. Signed-off-by: Akihiko Odaki Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20250109-reuse-v19-1-f541e82ca5f7@daynix.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/pci/pci.c | 17 +++++++++++------ hw/pci/pci_host.c | 4 ++-- include/hw/pci/pci.h | 1 + include/hw/pci/pci_device.h | 2 +- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 78907527f2..2afa423925 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1598,7 +1598,7 @@ static void pci_update_mappings(PCIDevice *d) continue; new_addr = pci_bar_address(d, i, r->type, r->size); - if (!d->has_power) { + if (!d->enabled) { new_addr = PCI_BAR_UNMAPPED; } @@ -1686,7 +1686,7 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val_in, int pci_update_irq_disabled(d, was_irq_disabled); memory_region_set_enabled(&d->bus_master_enable_region, (pci_get_word(d->config + PCI_COMMAND) - & PCI_COMMAND_MASTER) && d->has_power); + & PCI_COMMAND_MASTER) && d->enabled); } msi_write_config(d, addr, val_in, l); @@ -2963,16 +2963,21 @@ MSIMessage pci_get_msi_message(PCIDevice *dev, int vector) void pci_set_power(PCIDevice *d, bool state) { - if (d->has_power == state) { + pci_set_enabled(d, state); +} + +void pci_set_enabled(PCIDevice *d, bool state) +{ + if (d->enabled == state) { return; } - d->has_power = state; + d->enabled = state; pci_update_mappings(d); memory_region_set_enabled(&d->bus_master_enable_region, (pci_get_word(d->config + PCI_COMMAND) - & PCI_COMMAND_MASTER) && d->has_power); - if (!d->has_power) { + & PCI_COMMAND_MASTER) && d->enabled); + if (!d->enabled) { pci_device_reset(d); } } diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c index 4510890dfc..80f91f409f 100644 --- a/hw/pci/pci_host.c +++ b/hw/pci/pci_host.c @@ -86,7 +86,7 @@ void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr, * allowing direct removal of unexposed functions. */ if ((pci_dev->qdev.hotplugged && !pci_get_function_0(pci_dev)) || - !pci_dev->has_power || is_pci_dev_ejected(pci_dev)) { + !pci_dev->enabled || is_pci_dev_ejected(pci_dev)) { return; } @@ -111,7 +111,7 @@ uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr, * allowing direct removal of unexposed functions. */ if ((pci_dev->qdev.hotplugged && !pci_get_function_0(pci_dev)) || - !pci_dev->has_power || is_pci_dev_ejected(pci_dev)) { + !pci_dev->enabled || is_pci_dev_ejected(pci_dev)) { return ~0x0; } diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index cefeb388bd..4002bbeebd 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -674,6 +674,7 @@ static inline void pci_irq_deassert(PCIDevice *pci_dev) } MSIMessage pci_get_msi_message(PCIDevice *dev, int vector); +void pci_set_enabled(PCIDevice *pci_dev, bool state); void pci_set_power(PCIDevice *pci_dev, bool state); #endif diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h index 16ea7f4c19..add208edfa 100644 --- a/include/hw/pci/pci_device.h +++ b/include/hw/pci/pci_device.h @@ -57,7 +57,7 @@ typedef struct PCIReqIDCache PCIReqIDCache; struct PCIDevice { DeviceState qdev; bool partially_hotplugged; - bool has_power; + bool enabled; /* PCI config space */ uint8_t *config; From 4572dacc33e232a7c951ba7ba7a20887fad29e71 Mon Sep 17 00:00:00 2001 From: Keoseong Park Date: Tue, 7 Jan 2025 17:43:56 +0900 Subject: [PATCH 30/55] hw/ufs: Adjust value to match CPU's endian format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In ufs_write_attr_value(), the value parameter is handled in the CPU's endian format but provided in big-endian format by the caller. Thus, it is converted to the CPU's endian format. The related test code is also fixed to reflect this change. Fixes: 7c85332a2b3e ("hw/ufs: minor bug fixes related to ufs-test") Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Keoseong Park Reviewed-by: Jeuk Kim Message-ID: <20250107084356epcms2p2af4d86432174d76ea57336933e46b4c3@epcms2p2> Signed-off-by: Philippe Mathieu-Daudé --- hw/ufs/ufs.c | 2 +- tests/qtest/ufs-test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c index 8d26d13791..428fe927ad 100644 --- a/hw/ufs/ufs.c +++ b/hw/ufs/ufs.c @@ -1164,7 +1164,7 @@ static QueryRespCode ufs_exec_query_attr(UfsRequest *req, int op) value = ufs_read_attr_value(u, idn); ret = UFS_QUERY_RESULT_SUCCESS; } else { - value = req->req_upiu.qr.value; + value = be32_to_cpu(req->req_upiu.qr.value); ret = ufs_write_attr_value(u, idn, value); } req->rsp_upiu.qr.value = cpu_to_be32(value); diff --git a/tests/qtest/ufs-test.c b/tests/qtest/ufs-test.c index 60199abbee..1f860b41c0 100644 --- a/tests/qtest/ufs-test.c +++ b/tests/qtest/ufs-test.c @@ -145,7 +145,7 @@ static void ufs_send_query(QUfs *ufs, uint8_t slot, uint8_t query_function, req_upiu.qr.idn = idn; req_upiu.qr.index = index; req_upiu.qr.selector = selector; - req_upiu.qr.value = attr_value; + req_upiu.qr.value = cpu_to_be32(attr_value); req_upiu.qr.length = UFS_QUERY_DESC_MAX_SIZE; qtest_memwrite(ufs->dev.bus->qts, req_upiu_addr, &req_upiu, sizeof(req_upiu)); From 5df50b8e97377d2468bd8759ec3275e747a147bb Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Wed, 8 Jan 2025 10:25:25 +0100 Subject: [PATCH 31/55] hw/sd/sdhci: Set SDHC_NIS_DMA bit when appropriate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In U-Boot, the fsl_esdhc[_imx] driver waits for both "transmit completed" and "DMA" bits in esdhc_send_cmd_common() by means of DATA_COMPLETE constant. QEMU currently misses to set the DMA bit which causes the driver to loop forever. Fix that by setting the DMA bit if enabled when doing DMA block transfers. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20250108092538.11474-2-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/sd/sdhci.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index 299cd4bc1b..a958c11497 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -665,12 +665,13 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s) } } + if (s->norintstsen & SDHC_NISEN_DMA) { + s->norintsts |= SDHC_NIS_DMA; + } + if (s->blkcnt == 0) { sdhci_end_transfer(s); } else { - if (s->norintstsen & SDHC_NISEN_DMA) { - s->norintsts |= SDHC_NIS_DMA; - } sdhci_update_irq(s); } } @@ -691,6 +692,10 @@ static void sdhci_sdma_transfer_single_block(SDHCIState *s) } s->blkcnt--; + if (s->norintstsen & SDHC_NISEN_DMA) { + s->norintsts |= SDHC_NIS_DMA; + } + sdhci_end_transfer(s); } From 14b1086f92ae8d45fc1e66c837ddc7da79d93f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 9 Jan 2025 13:12:37 +0100 Subject: [PATCH 32/55] hw/sd/sdhci: Factor sdhci_sdma_transfer() out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Factor sdhci_sdma_transfer() out of sdhci_data_transfer(). Re-use it in sdhci_write(), so we don't try to run multi block transfer for a single block. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Bernhard Beschow Message-Id: <20250109122029.22780-1-philmd@linaro.org> --- hw/sd/sdhci.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index a958c11497..318587ff57 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -699,6 +699,15 @@ static void sdhci_sdma_transfer_single_block(SDHCIState *s) sdhci_end_transfer(s); } +static void sdhci_sdma_transfer(SDHCIState *s) +{ + if ((s->blkcnt == 1) || !(s->trnmod & SDHC_TRNS_MULTI)) { + sdhci_sdma_transfer_single_block(s); + } else { + sdhci_sdma_transfer_multi_blocks(s); + } +} + typedef struct ADMADescr { hwaddr addr; uint16_t length; @@ -930,12 +939,7 @@ static void sdhci_data_transfer(void *opaque) if (s->trnmod & SDHC_TRNS_DMA) { switch (SDHC_DMA_TYPE(s->hostctl1)) { case SDHC_CTRL_SDMA: - if ((s->blkcnt == 1) || !(s->trnmod & SDHC_TRNS_MULTI)) { - sdhci_sdma_transfer_single_block(s); - } else { - sdhci_sdma_transfer_multi_blocks(s); - } - + sdhci_sdma_transfer(s); break; case SDHC_CTRL_ADMA1_32: if (!(s->capareg & R_SDHC_CAPAB_ADMA1_MASK)) { @@ -1179,11 +1183,7 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) if (!(mask & 0xFF000000) && s->blkcnt && (s->blksize & BLOCK_SIZE_MASK) && SDHC_DMA_TYPE(s->hostctl1) == SDHC_CTRL_SDMA) { - if (s->trnmod & SDHC_TRNS_MULTI) { - sdhci_sdma_transfer_multi_blocks(s); - } else { - sdhci_sdma_transfer_single_block(s); - } + sdhci_sdma_transfer(s); } } break; From d25202fe836805d7e28dea5d11e39e19a7801780 Mon Sep 17 00:00:00 2001 From: Nikita Shubin Date: Fri, 20 Dec 2024 14:17:56 +0300 Subject: [PATCH 33/55] hw/char/stm32f2xx_usart: replace print with trace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop debug printing macros and replace them with according trace functions. Signed-off-by: Nikita Shubin Reviewed-by: Alistair Francis Message-ID: <20241220111756.16511-1-nikita.shubin@maquefel.me> Signed-off-by: Philippe Mathieu-Daudé --- hw/char/stm32f2xx_usart.c | 49 ++++++++++++++++++--------------------- hw/char/trace-events | 6 +++++ 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c index ebcc510f4e..87882daa71 100644 --- a/hw/char/stm32f2xx_usart.c +++ b/hw/char/stm32f2xx_usart.c @@ -30,17 +30,7 @@ #include "qemu/log.h" #include "qemu/module.h" -#ifndef STM_USART_ERR_DEBUG -#define STM_USART_ERR_DEBUG 0 -#endif - -#define DB_PRINT_L(lvl, fmt, args...) do { \ - if (STM_USART_ERR_DEBUG >= lvl) { \ - qemu_log("%s: " fmt, __func__, ## args); \ - } \ -} while (0) - -#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args) +#include "trace.h" static int stm32f2xx_usart_can_receive(void *opaque) { @@ -67,10 +57,11 @@ static void stm32f2xx_update_irq(STM32F2XXUsartState *s) static void stm32f2xx_usart_receive(void *opaque, const uint8_t *buf, int size) { STM32F2XXUsartState *s = opaque; + DeviceState *d = DEVICE(s); if (!(s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_RE)) { /* USART not enabled - drop the chars */ - DB_PRINT("Dropping the chars\n"); + trace_stm32f2xx_usart_drop(d->id); return; } @@ -79,7 +70,7 @@ static void stm32f2xx_usart_receive(void *opaque, const uint8_t *buf, int size) stm32f2xx_update_irq(s); - DB_PRINT("Receiving: %c\n", s->usart_dr); + trace_stm32f2xx_usart_receive(d->id, *buf); } static void stm32f2xx_usart_reset(DeviceState *dev) @@ -101,49 +92,55 @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr, unsigned int size) { STM32F2XXUsartState *s = opaque; - uint64_t retvalue; - - DB_PRINT("Read 0x%"HWADDR_PRIx"\n", addr); + DeviceState *d = DEVICE(s); + uint64_t retvalue = 0; switch (addr) { case USART_SR: retvalue = s->usart_sr; qemu_chr_fe_accept_input(&s->chr); - return retvalue; + break; case USART_DR: - DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) s->usart_dr); retvalue = s->usart_dr & 0x3FF; s->usart_sr &= ~USART_SR_RXNE; qemu_chr_fe_accept_input(&s->chr); stm32f2xx_update_irq(s); - return retvalue; + break; case USART_BRR: - return s->usart_brr; + retvalue = s->usart_brr; + break; case USART_CR1: - return s->usart_cr1; + retvalue = s->usart_cr1; + break; case USART_CR2: - return s->usart_cr2; + retvalue = s->usart_cr2; + break; case USART_CR3: - return s->usart_cr3; + retvalue = s->usart_cr3; + break; case USART_GTPR: - return s->usart_gtpr; + retvalue = s->usart_gtpr; + break; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr); return 0; } - return 0; + trace_stm32f2xx_usart_read(d->id, size, addr, retvalue); + + return retvalue; } static void stm32f2xx_usart_write(void *opaque, hwaddr addr, uint64_t val64, unsigned int size) { STM32F2XXUsartState *s = opaque; + DeviceState *d = DEVICE(s); uint32_t value = val64; unsigned char ch; - DB_PRINT("Write 0x%" PRIx32 ", 0x%"HWADDR_PRIx"\n", value, addr); + trace_stm32f2xx_usart_write(d->id, size, addr, val64); switch (addr) { case USART_SR: diff --git a/hw/char/trace-events b/hw/char/trace-events index 59e1f734a7..140b994fd4 100644 --- a/hw/char/trace-events +++ b/hw/char/trace-events @@ -125,3 +125,9 @@ xen_console_unrealize(unsigned int idx) "idx %u" xen_console_realize(unsigned int idx, const char *chrdev) "idx %u chrdev %s" xen_console_device_create(unsigned int idx) "idx %u" xen_console_device_destroy(unsigned int idx) "idx %u" + +# stm32f2xx_usart.c +stm32f2xx_usart_read(char *id, unsigned size, uint64_t ofs, uint64_t val) " %s size %d ofs 0x%02" PRIx64 " -> 0x%02" PRIx64 +stm32f2xx_usart_write(char *id, unsigned size, uint64_t ofs, uint64_t val) "%s size %d ofs 0x%02" PRIx64 " <- 0x%02" PRIx64 +stm32f2xx_usart_drop(char *id) " %s dropping the chars" +stm32f2xx_usart_receive(char *id, uint8_t chr) " %s receiving '%c'" From 2ee8c2ccb5a5bb2295b8a17e307efbe35539d289 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Wed, 8 Jan 2025 10:25:34 +0100 Subject: [PATCH 34/55] hw/timer/imx_gpt: Remove unused define MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20250108092538.11474-11-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/timer/imx_gpt.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c index 2663a9d9ef..11eca9fa4d 100644 --- a/hw/timer/imx_gpt.c +++ b/hw/timer/imx_gpt.c @@ -20,10 +20,6 @@ #include "qemu/log.h" #include "trace.h" -#ifndef DEBUG_IMX_GPT -#define DEBUG_IMX_GPT 0 -#endif - static const char *imx_gpt_reg_name(uint32_t reg) { switch (reg) { From bbaf7a0d4c9f653edd085c06bc2a343e356d9b6a Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Wed, 8 Jan 2025 10:25:35 +0100 Subject: [PATCH 35/55] tests/qtest/libqos: Reuse TYPE_IMX_I2C define MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Reviewed-by: Fabiano Rosas Message-ID: <20250108092538.11474-12-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- tests/qtest/libqos/arm-imx25-pdk-machine.c | 5 +++-- tests/qtest/libqos/i2c-imx.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/qtest/libqos/arm-imx25-pdk-machine.c b/tests/qtest/libqos/arm-imx25-pdk-machine.c index 8fe128fae8..2d8b754343 100644 --- a/tests/qtest/libqos/arm-imx25-pdk-machine.c +++ b/tests/qtest/libqos/arm-imx25-pdk-machine.c @@ -23,6 +23,7 @@ #include "libqos-malloc.h" #include "qgraph.h" #include "i2c.h" +#include "hw/i2c/imx_i2c.h" #define ARM_PAGE_SIZE 4096 #define IMX25_PDK_RAM_START 0x80000000 @@ -50,7 +51,7 @@ static void *imx25_pdk_get_driver(void *object, const char *interface) static QOSGraphObject *imx25_pdk_get_device(void *obj, const char *device) { QIMX25PDKMachine *machine = obj; - if (!g_strcmp0(device, "imx.i2c")) { + if (!g_strcmp0(device, TYPE_IMX_I2C)) { return &machine->i2c_1.obj; } @@ -86,7 +87,7 @@ static void imx25_pdk_register_nodes(void) .extra_device_opts = "bus=i2c-bus.0" }; qos_node_create_machine("arm/imx25-pdk", qos_create_machine_arm_imx25_pdk); - qos_node_contains("arm/imx25-pdk", "imx.i2c", &edge, NULL); + qos_node_contains("arm/imx25-pdk", TYPE_IMX_I2C, &edge, NULL); } libqos_init(imx25_pdk_register_nodes); diff --git a/tests/qtest/libqos/i2c-imx.c b/tests/qtest/libqos/i2c-imx.c index 710cb926d6..6d868e4cc4 100644 --- a/tests/qtest/libqos/i2c-imx.c +++ b/tests/qtest/libqos/i2c-imx.c @@ -209,8 +209,8 @@ void imx_i2c_init(IMXI2C *s, QTestState *qts, uint64_t addr) static void imx_i2c_register_nodes(void) { - qos_node_create_driver("imx.i2c", NULL); - qos_node_produces("imx.i2c", "i2c-bus"); + qos_node_create_driver(TYPE_IMX_I2C, NULL); + qos_node_produces(TYPE_IMX_I2C, "i2c-bus"); } libqos_init(imx_i2c_register_nodes); From 2eabc49809b16317094b005320efba8e82b885db Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Wed, 8 Jan 2025 10:25:37 +0100 Subject: [PATCH 36/55] hw/misc/imx6_src: Convert DPRINTF() to trace events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Message-ID: <20250108092538.11474-14-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/misc/imx6_src.c | 23 +++++------------------ hw/misc/trace-events | 6 ++++++ 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/hw/misc/imx6_src.c b/hw/misc/imx6_src.c index dc6a2b92ba..06cc46292e 100644 --- a/hw/misc/imx6_src.c +++ b/hw/misc/imx6_src.c @@ -17,18 +17,7 @@ #include "qemu/module.h" #include "target/arm/arm-powerctl.h" #include "hw/core/cpu.h" - -#ifndef DEBUG_IMX6_SRC -#define DEBUG_IMX6_SRC 0 -#endif - -#define DPRINTF(fmt, args...) \ - do { \ - if (DEBUG_IMX6_SRC) { \ - fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX6_SRC, \ - __func__, ##args); \ - } \ - } while (0) +#include "trace.h" static const char *imx6_src_reg_name(uint32_t reg) { @@ -87,7 +76,7 @@ static void imx6_src_reset(DeviceState *dev) { IMX6SRCState *s = IMX6_SRC(dev); - DPRINTF("\n"); + trace_imx6_src_reset(); memset(s->regs, 0, sizeof(s->regs)); @@ -111,7 +100,7 @@ static uint64_t imx6_src_read(void *opaque, hwaddr offset, unsigned size) } - DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx6_src_reg_name(index), value); + trace_imx6_src_read(imx6_src_reg_name(index), value); return value; } @@ -134,8 +123,7 @@ static void imx6_clear_reset_bit(CPUState *cpu, run_on_cpu_data data) assert(bql_locked()); s->regs[SRC_SCR] = deposit32(s->regs[SRC_SCR], ri->reset_bit, 1, 0); - DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", - imx6_src_reg_name(SRC_SCR), s->regs[SRC_SCR]); + trace_imx6_clear_reset_bit(imx6_src_reg_name(SRC_SCR), s->regs[SRC_SCR]); g_free(ri); } @@ -173,8 +161,7 @@ static void imx6_src_write(void *opaque, hwaddr offset, uint64_t value, return; } - DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx6_src_reg_name(index), - (uint32_t)current_value); + trace_imx6_src_write(imx6_src_reg_name(index), value); change_mask = s->regs[index] ^ (uint32_t)current_value; diff --git a/hw/misc/trace-events b/hw/misc/trace-events index 0f5d2b5666..cf1abe6928 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -253,6 +253,12 @@ ccm_clock_freq(uint32_t clock, uint32_t freq) "(Clock = %d) = %d" ccm_read_reg(const char *reg_name, uint32_t value) "reg[%s] <= 0x%" PRIx32 ccm_write_reg(const char *reg_name, uint32_t value) "reg[%s] => 0x%" PRIx32 +# imx6_src.c +imx6_src_read(const char *reg_name, uint32_t value) "reg[%s] => 0x%" PRIx32 +imx6_src_write(const char *reg_name, uint64_t value) "reg[%s] <= 0x%" PRIx64 +imx6_clear_reset_bit(const char *reg_name, uint32_t value) "reg[%s] <= 0x%" PRIx32 +imx6_src_reset(void) "" + # imx7_src.c imx7_src_read(const char *reg_name, uint32_t value) "reg[%s] => 0x%" PRIx32 imx7_src_write(const char *reg_name, uint32_t value) "reg[%s] <= 0x%" PRIx32 From 1bada3c94c7d6a3ebb731eb23a6e4454a921c4e0 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Sat, 11 Jan 2025 19:37:06 +0100 Subject: [PATCH 37/55] hw/char/imx_serial: Turn some DPRINTF() statements into trace events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Signed-off-by: Bernhard Beschow Message-ID: <20250111183711.2338-9-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/char/imx_serial.c | 58 +++++++++++++++++++++++++++++--------------- hw/char/trace-events | 5 ++++ 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c index 12705a1337..7c353fde50 100644 --- a/hw/char/imx_serial.c +++ b/hw/char/imx_serial.c @@ -27,6 +27,7 @@ #include "qemu/log.h" #include "qemu/module.h" #include "qemu/fifo32.h" +#include "trace.h" #ifndef DEBUG_IMX_UART #define DEBUG_IMX_UART 0 @@ -184,10 +185,10 @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset, unsigned size) { IMXSerialState *s = (IMXSerialState *)opaque; + Chardev *chr = qemu_chr_fe_get_driver(&s->chr); uint32_t c, rx_used; uint8_t rxtl = s->ufcr & TL_MASK; - - DPRINTF("read(offset=0x%" HWADDR_PRIx ")\n", offset); + uint64_t value; switch (offset >> 2) { case 0x0: /* URXD */ @@ -208,49 +209,67 @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset, imx_serial_rx_fifo_ageing_timer_restart(s); qemu_chr_fe_accept_input(&s->chr); } - return c; + value = c; + break; case 0x20: /* UCR1 */ - return s->ucr1; + value = s->ucr1; + break; case 0x21: /* UCR2 */ - return s->ucr2; + value = s->ucr2; + break; case 0x25: /* USR1 */ - return s->usr1; + value = s->usr1; + break; case 0x26: /* USR2 */ - return s->usr2; + value = s->usr2; + break; case 0x2A: /* BRM Modulator */ - return s->ubmr; + value = s->ubmr; + break; case 0x2B: /* Baud Rate Count */ - return s->ubrc; + value = s->ubrc; + break; case 0x2d: /* Test register */ - return s->uts1; + value = s->uts1; + break; case 0x24: /* UFCR */ - return s->ufcr; + value = s->ufcr; + break; case 0x2c: - return s->onems; + value = s->onems; + break; case 0x22: /* UCR3 */ - return s->ucr3; + value = s->ucr3; + break; case 0x23: /* UCR4 */ - return s->ucr4; + value = s->ucr4; + break; case 0x29: /* BRM Incremental */ - return 0x0; /* TODO */ + value = 0x0; /* TODO */ + break; default: qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%" HWADDR_PRIx "\n", TYPE_IMX_SERIAL, __func__, offset); - return 0; + value = 0; + break; } + + trace_imx_serial_read(chr ? chr->label : "NODEV", offset, value); + + return value; } static void imx_serial_write(void *opaque, hwaddr offset, @@ -260,8 +279,7 @@ static void imx_serial_write(void *opaque, hwaddr offset, Chardev *chr = qemu_chr_fe_get_driver(&s->chr); unsigned char ch; - DPRINTF("write(offset=0x%" HWADDR_PRIx ", value = 0x%x) to %s\n", - offset, (unsigned int)value, chr ? chr->label : "NODEV"); + trace_imx_serial_write(chr ? chr->label : "NODEV", offset, value); switch (offset >> 2) { case 0x10: /* UTXD */ @@ -373,9 +391,11 @@ static int imx_can_receive(void *opaque) static void imx_put_data(void *opaque, uint32_t value) { IMXSerialState *s = (IMXSerialState *)opaque; + Chardev *chr = qemu_chr_fe_get_driver(&s->chr); uint8_t rxtl = s->ufcr & TL_MASK; - DPRINTF("received char\n"); + trace_imx_serial_put_data(chr ? chr->label : "NODEV", value); + imx_serial_rx_fifo_push(s, value); if (fifo32_num_used(&s->rx_fifo) >= rxtl) { s->usr1 |= USR1_RRDY; diff --git a/hw/char/trace-events b/hw/char/trace-events index 140b994fd4..3ee7cfcdff 100644 --- a/hw/char/trace-events +++ b/hw/char/trace-events @@ -52,6 +52,11 @@ escc_sunkbd_event_out(int ch) "Translated keycode 0x%2.2x" escc_kbd_command(int val) "Command %d" escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=0x%01x" +# imx_serial.c +imx_serial_read(const char *chrname, uint64_t addr, uint64_t value) "%s:[0x%03" PRIu64 "] -> 0x%08" PRIx64 +imx_serial_write(const char *chrname, uint64_t addr, uint64_t value) "%s:[0x%03" PRIu64 "] <- 0x%08" PRIx64 +imx_serial_put_data(const char *chrname, uint32_t value) "%s: 0x%" PRIx32 + # pl011.c pl011_irq_state(int level) "irq state %d" pl011_read(uint32_t addr, uint32_t value, const char *regname) "addr 0x%03x value 0x%08x reg %s" From e589c0ea9c991094a85dbd7bee24e02e7d272310 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Sat, 11 Jan 2025 19:37:09 +0100 Subject: [PATCH 38/55] hw/i2c/imx_i2c: Convert DPRINTF() to trace events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also print the QOM canonical path when tracing which allows for distinguishing the many instances a typical i.MX SoC has. Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Signed-off-by: Bernhard Beschow Message-ID: <20250111183711.2338-12-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/i2c/imx_i2c.c | 21 +++++---------------- hw/i2c/trace-events | 5 +++++ 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c index c565fd5b8a..d62213b9e0 100644 --- a/hw/i2c/imx_i2c.c +++ b/hw/i2c/imx_i2c.c @@ -25,18 +25,7 @@ #include "hw/i2c/i2c.h" #include "qemu/log.h" #include "qemu/module.h" - -#ifndef DEBUG_IMX_I2C -#define DEBUG_IMX_I2C 0 -#endif - -#define DPRINTF(fmt, args...) \ - do { \ - if (DEBUG_IMX_I2C) { \ - fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_I2C, \ - __func__, ##args); \ - } \ - } while (0) +#include "trace.h" static const char *imx_i2c_get_regname(unsigned offset) { @@ -152,8 +141,8 @@ static uint64_t imx_i2c_read(void *opaque, hwaddr offset, break; } - DPRINTF("read %s [0x%" HWADDR_PRIx "] -> 0x%02x\n", - imx_i2c_get_regname(offset), offset, value); + trace_imx_i2c_read(DEVICE(s)->canonical_path, imx_i2c_get_regname(offset), + offset, value); return (uint64_t)value; } @@ -163,8 +152,8 @@ static void imx_i2c_write(void *opaque, hwaddr offset, { IMXI2CState *s = IMX_I2C(opaque); - DPRINTF("write %s [0x%" HWADDR_PRIx "] <- 0x%02x\n", - imx_i2c_get_regname(offset), offset, (int)value); + trace_imx_i2c_read(DEVICE(s)->canonical_path, imx_i2c_get_regname(offset), + offset, value); value &= 0xff; diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events index f708a7ace1..1ad0e95c0e 100644 --- a/hw/i2c/trace-events +++ b/hw/i2c/trace-events @@ -56,3 +56,8 @@ npcm7xx_smbus_recv_fifo(const char *id, uint8_t received, uint8_t expected) "%s pca954x_write_bytes(uint8_t value) "PCA954X write data: 0x%02x" pca954x_read_data(uint8_t value) "PCA954X read data: 0x%02x" + +# imx_i2c.c + +imx_i2c_read(const char *id, const char *reg, uint64_t ofs, uint64_t value) "%s:[%s (0x%" PRIx64 ")] -> 0x%02" PRIx64 +imx_i2c_write(const char *id, const char *reg, uint64_t ofs, uint64_t value) "%s:[%s (0x%" PRIx64 ")] <- 0x%02" PRIx64 From e3778c8499add463fa2c62b0251a4c9879f37e04 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Sat, 11 Jan 2025 19:37:11 +0100 Subject: [PATCH 39/55] hw/gpio/imx_gpio: Turn DPRINTF() into trace events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While at it add a trace event for input GPIO events. Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Signed-off-by: Bernhard Beschow Message-ID: <20250111183711.2338-14-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/gpio/imx_gpio.c | 18 +++++++----------- hw/gpio/trace-events | 5 +++++ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/hw/gpio/imx_gpio.c b/hw/gpio/imx_gpio.c index 898f80f8c8..549a281ed7 100644 --- a/hw/gpio/imx_gpio.c +++ b/hw/gpio/imx_gpio.c @@ -24,6 +24,7 @@ #include "migration/vmstate.h" #include "qemu/log.h" #include "qemu/module.h" +#include "trace.h" #ifndef DEBUG_IMX_GPIO #define DEBUG_IMX_GPIO 0 @@ -34,14 +35,6 @@ typedef enum IMXGPIOLevel { IMX_GPIO_LEVEL_HIGH = 1, } IMXGPIOLevel; -#define DPRINTF(fmt, args...) \ - do { \ - if (DEBUG_IMX_GPIO) { \ - fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_GPIO, \ - __func__, ##args); \ - } \ - } while (0) - static const char *imx_gpio_reg_name(uint32_t reg) { switch (reg) { @@ -111,6 +104,8 @@ static void imx_gpio_set(void *opaque, int line, int level) IMXGPIOState *s = IMX_GPIO(opaque); IMXGPIOLevel imx_level = level ? IMX_GPIO_LEVEL_HIGH : IMX_GPIO_LEVEL_LOW; + trace_imx_gpio_set(DEVICE(s)->canonical_path, line, imx_level); + imx_gpio_set_int_line(s, line, imx_level); /* this is an input signal, so set PSR */ @@ -200,7 +195,8 @@ static uint64_t imx_gpio_read(void *opaque, hwaddr offset, unsigned size) break; } - DPRINTF("(%s) = 0x%" PRIx32 "\n", imx_gpio_reg_name(offset), reg_value); + trace_imx_gpio_read(DEVICE(s)->canonical_path, imx_gpio_reg_name(offset), + reg_value); return reg_value; } @@ -210,8 +206,8 @@ static void imx_gpio_write(void *opaque, hwaddr offset, uint64_t value, { IMXGPIOState *s = IMX_GPIO(opaque); - DPRINTF("(%s, value = 0x%" PRIx32 ")\n", imx_gpio_reg_name(offset), - (uint32_t)value); + trace_imx_gpio_write(DEVICE(s)->canonical_path, imx_gpio_reg_name(offset), + value); switch (offset) { case DR_ADDR: diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events index b91cc7e9a4..cea896b28f 100644 --- a/hw/gpio/trace-events +++ b/hw/gpio/trace-events @@ -1,5 +1,10 @@ # See docs/devel/tracing.rst for syntax documentation. +# imx_gpio.c +imx_gpio_read(const char *id, const char *reg, uint32_t value) "%s:[%s] -> 0x%" PRIx32 +imx_gpio_write(const char *id, const char *reg, uint32_t value) "%s:[%s] <- 0x%" PRIx32 +imx_gpio_set(const char *id, int line, int level) "%s:[%d] <- %d" + # npcm7xx_gpio.c npcm7xx_gpio_read(const char *id, uint64_t offset, uint64_t value) " %s offset: 0x%04" PRIx64 " value 0x%08" PRIx64 npcm7xx_gpio_write(const char *id, uint64_t offset, uint64_t value) "%s offset: 0x%04" PRIx64 " value 0x%08" PRIx64 From a87077316ed2f1c1c8ba8faf05feed9dbf0f2fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 2 Jan 2025 10:59:31 +0100 Subject: [PATCH 40/55] tests/qtest/boot-serial-test: Correct HPPA machine name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 7df6f751176 ("hw/hppa: Split out machine creation") renamed the 'hppa' machine as 'B160L', but forgot to update the boot serial test, which ended being skipped. Cc: qemu-stable@nongnu.org Fixes: 7df6f751176 ("hw/hppa: Split out machine creation") Reported-by: Thomas Huth Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Thomas Huth Message-Id: <20250102100340.43014-2-philmd@linaro.org> --- tests/qtest/boot-serial-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c index ffa9e780ad..c924cf94fc 100644 --- a/tests/qtest/boot-serial-test.c +++ b/tests/qtest/boot-serial-test.c @@ -190,7 +190,7 @@ static const testdef_t tests[] = { sizeof(kernel_plml605), kernel_plml605 }, { "arm", "raspi2b", "", "TT", sizeof(bios_raspi2), 0, bios_raspi2 }, /* For hppa, force bios to output to serial by disabling graphics. */ - { "hppa", "hppa", "-vga none", "SeaBIOS wants SYSTEM HALT" }, + { "hppa", "B160L", "-vga none", "SeaBIOS wants SYSTEM HALT" }, { "aarch64", "virt", "-cpu max", "TT", sizeof(kernel_aarch64), kernel_aarch64 }, { "arm", "microbit", "", "T", sizeof(kernel_nrf51), kernel_nrf51 }, From e4a407d2b41de8a35e2a1ecc0b9f22178ce71577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 31 Dec 2024 19:58:37 +0100 Subject: [PATCH 41/55] tests: Add functional tests for HPPA machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add quick firmware boot tests (less than 1sec) for the B160L (32-bit) and C3700 (64-bit) HPPA machines: $ make check-functional-hppa ... 4/4 qemu:func-quick+func-hppa / func-hppa-hppa_seabios OK 0.22s 2 subtests passed Remove the duplicated B160L test in qtest/boot-serial-test.c. Suggested-by: Helge Deller Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Helge Deller Tested-by: Helge Deller Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Message-Id: <20250102100340.43014-3-philmd@linaro.org> --- MAINTAINERS | 1 + tests/functional/meson.build | 4 +++ tests/functional/test_hppa_seabios.py | 35 +++++++++++++++++++++++++++ tests/qtest/boot-serial-test.c | 2 -- tests/qtest/meson.build | 2 +- 5 files changed, 41 insertions(+), 3 deletions(-) create mode 100755 tests/functional/test_hppa_seabios.py diff --git a/MAINTAINERS b/MAINTAINERS index c1d954c9de..d26d497a38 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1203,6 +1203,7 @@ F: include/hw/pci-host/astro.h F: include/hw/pci-host/dino.h F: pc-bios/hppa-firmware.img F: roms/seabios-hppa/ +F: tests/functional/test_hppa_seabios.py LoongArch Machines ------------------ diff --git a/tests/functional/meson.build b/tests/functional/meson.build index bd3d903cfc..cf80924ddc 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -108,6 +108,10 @@ tests_avr_system_thorough = [ 'avr_mega2560', ] +tests_hppa_system_quick = [ + 'hppa_seabios', +] + tests_i386_system_thorough = [ 'i386_tuxrun', ] diff --git a/tests/functional/test_hppa_seabios.py b/tests/functional/test_hppa_seabios.py new file mode 100755 index 0000000000..a44d1a3eeb --- /dev/null +++ b/tests/functional/test_hppa_seabios.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +# +# SeaBIOS boot test for HPPA machines +# +# Copyright (c) 2024 Linaro, Ltd +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from qemu_test import QemuSystemTest +from qemu_test import wait_for_console_pattern + +class HppaSeabios(QemuSystemTest): + + timeout = 5 + MACH_BITS = {'B160L': 32, 'C3700': 64} + + def boot_seabios(self): + mach = self.machine + bits = self.MACH_BITS[mach] + self.vm.set_console() + self.vm.launch() + self.machine + wait_for_console_pattern(self, f'SeaBIOS PA-RISC {bits}-bit Firmware') + wait_for_console_pattern(self, f'Emulated machine: HP {mach} ({bits}-bit') + + def test_hppa_32(self): + self.set_machine('B160L') + self.boot_seabios() + + def test_hppa_64(self): + self.set_machine('C3700') + self.boot_seabios() + +if __name__ == '__main__': + QemuSystemTest.main() diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c index c924cf94fc..a05d26ee99 100644 --- a/tests/qtest/boot-serial-test.c +++ b/tests/qtest/boot-serial-test.c @@ -189,8 +189,6 @@ static const testdef_t tests[] = { { "microblazeel", "petalogix-ml605", "", "TT", sizeof(kernel_plml605), kernel_plml605 }, { "arm", "raspi2b", "", "TT", sizeof(bios_raspi2), 0, bios_raspi2 }, - /* For hppa, force bios to output to serial by disabling graphics. */ - { "hppa", "B160L", "-vga none", "SeaBIOS wants SYSTEM HALT" }, { "aarch64", "virt", "-cpu max", "TT", sizeof(kernel_aarch64), kernel_aarch64 }, { "arm", "microbit", "", "T", sizeof(kernel_nrf51), kernel_nrf51 }, diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index f75c1057a4..bf4d5c268b 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -140,7 +140,7 @@ qtests_alpha = ['boot-serial-test'] + \ qtests_avr = [ 'boot-serial-test' ] -qtests_hppa = ['boot-serial-test'] + \ +qtests_hppa = \ qtests_filter + \ (config_all_devices.has_key('CONFIG_VGA') ? ['display-vga-test'] : []) From f4f4173188249d33a3ec4a0c910c168c9181ac9d Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 30 Dec 2024 12:46:47 +0100 Subject: [PATCH 42/55] target/hppa: Convert hppa_cpu_init() to ResetHold handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hppa_cpu_initfn() is called once when a HPPA CPU instance is initialized, but it sets fields which should be set each time a CPU resets. Rename it as a reset handler, having it matching the ResettablePhases::hold() signature, and register it as ResettableClass handler. Since on reset the CPU registers and TLB entries are expected to be zero, add a memset() call clearing CPUHPPAState up to the &end_reset_fields marker. Signed-off-by: Helge Deller Co-developed-by: Philippe Mathieu-Daudé Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20241231190620.24442-3-philmd@linaro.org> --- target/hppa/cpu.c | 14 ++++++++++++-- target/hppa/cpu.h | 5 +++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index 47d0160955..d784bcdd60 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -193,13 +193,20 @@ static void hppa_cpu_realizefn(DeviceState *dev, Error **errp) tcg_cflags_set(cs, CF_PCREL); } -static void hppa_cpu_initfn(Object *obj) +static void hppa_cpu_reset_hold(Object *obj, ResetType type) { + HPPACPUClass *scc = HPPA_CPU_GET_CLASS(obj); CPUState *cs = CPU(obj); HPPACPU *cpu = HPPA_CPU(obj); CPUHPPAState *env = &cpu->env; + if (scc->parent_phases.hold) { + scc->parent_phases.hold(obj, type); + } cs->exception_index = -1; + + memset(env, 0, offsetof(CPUHPPAState, end_reset_fields)); + cpu_hppa_loaded_fr0(env); cpu_hppa_put_psw(env, PSW_W); } @@ -242,10 +249,14 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data) DeviceClass *dc = DEVICE_CLASS(oc); CPUClass *cc = CPU_CLASS(oc); HPPACPUClass *acc = HPPA_CPU_CLASS(oc); + ResettableClass *rc = RESETTABLE_CLASS(oc); device_class_set_parent_realize(dc, hppa_cpu_realizefn, &acc->parent_realize); + resettable_class_set_parent_phases(rc, NULL, hppa_cpu_reset_hold, NULL, + &acc->parent_phases); + cc->class_by_name = hppa_cpu_class_by_name; cc->has_work = hppa_cpu_has_work; cc->mmu_index = hppa_cpu_mmu_index; @@ -269,7 +280,6 @@ static const TypeInfo hppa_cpu_type_infos[] = { .parent = TYPE_CPU, .instance_size = sizeof(HPPACPU), .instance_align = __alignof(HPPACPU), - .instance_init = hppa_cpu_initfn, .abstract = false, .class_size = sizeof(HPPACPUClass), .class_init = hppa_cpu_class_init, diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index 22a6510e08..c1d69c1a83 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -263,6 +263,9 @@ typedef struct CPUArchState { IntervalTreeRoot tlb_root; HPPATLBEntry tlb[HPPA_TLB_ENTRIES]; + + /* Fields up to this point are cleared by a CPU reset */ + struct {} end_reset_fields; } CPUHPPAState; /** @@ -281,6 +284,7 @@ struct ArchCPU { /** * HPPACPUClass: * @parent_realize: The parent class' realize handler. + * @parent_phases: The parent class' reset phase handlers. * * An HPPA CPU model. */ @@ -288,6 +292,7 @@ struct HPPACPUClass { CPUClass parent_class; DeviceRealize parent_realize; + ResettablePhases parent_phases; }; #include "exec/cpu-all.h" From 20f7b890173be6cd38dabad8122b8b2fe51d0255 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 30 Dec 2024 10:53:25 +0100 Subject: [PATCH 43/55] hw/hppa: Reset vCPUs calling resettable_reset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than manually (and incompletely) resetting vCPUs, call resettable_reset() which will fully reset the vCPUs. Remove redundant assignations. Signed-off-by: Helge Deller Co-developed-by: Philippe Mathieu-Daudé Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20241231190620.24442-4-philmd@linaro.org> --- hw/hppa/machine.c | 6 +++--- target/hppa/cpu.c | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index 65259308e2..8230f43e41 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -655,12 +655,12 @@ static void hppa_machine_reset(MachineState *ms, ResetType type) for (i = 0; i < smp_cpus; i++) { CPUState *cs = CPU(cpu[i]); + /* reset CPU */ + resettable_reset(OBJECT(cs), RESET_TYPE_COLD); + cpu_set_pc(cs, firmware_entry); cpu[i]->env.psw = PSW_Q; cpu[i]->env.gr[5] = CPU_HPA + i * 0x1000; - - cs->exception_index = -1; - cs->halted = 0; } /* already initialized by machine_hppa_init()? */ diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index d784bcdd60..41538d39d6 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -204,6 +204,7 @@ static void hppa_cpu_reset_hold(Object *obj, ResetType type) scc->parent_phases.hold(obj, type); } cs->exception_index = -1; + cs->halted = 0; memset(env, 0, offsetof(CPUHPPAState, end_reset_fields)); From 3d66ec208ca75329b61a4e9c4a58462ed5948504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 30 Dec 2024 16:11:09 +0100 Subject: [PATCH 44/55] target/hppa: Only set PSW 'M' bit on reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On reset: "All PSW bits except the M bit is reset. The M bit is set." Commit 1a19da0da44 ("target/hppa: Fill in hppa_cpu_do_interrupt / hppa_cpu_exec_interrupt") inadvertently set the W bit at RESET, remove it and set the M bit. Signed-off-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20241231190620.24442-5-philmd@linaro.org> --- target/hppa/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index 41538d39d6..dbd4684284 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -209,7 +209,7 @@ static void hppa_cpu_reset_hold(Object *obj, ResetType type) memset(env, 0, offsetof(CPUHPPAState, end_reset_fields)); cpu_hppa_loaded_fr0(env); - cpu_hppa_put_psw(env, PSW_W); + cpu_hppa_put_psw(env, PSW_M); } static ObjectClass *hppa_cpu_class_by_name(const char *cpu_model) From 46f7be06c8e568ec5d5c4aa07c81b42fc0fc863a Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 30 Dec 2024 12:47:52 +0100 Subject: [PATCH 45/55] target/hppa: Set PC on vCPU reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On reset: "The CPU begins fetching instructions from address 0xf0000004. This address is in PDC space." Switch vCPUs to 32-bit mode (PSW_W bit is not set) and start execution at address 0xf0000004. Signed-off-by: Helge Deller Co-developed-by: Philippe Mathieu-Daudé Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20241231190620.24442-6-philmd@linaro.org> --- target/hppa/cpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index dbd4684284..7278b7ca6b 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -205,6 +205,7 @@ static void hppa_cpu_reset_hold(Object *obj, ResetType type) } cs->exception_index = -1; cs->halted = 0; + cpu_set_pc(cs, 0xf0000004); memset(env, 0, offsetof(CPUHPPAState, end_reset_fields)); From 5c27cbd7b2ab825528086c0bd10029556ab88fd8 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 30 Dec 2024 00:41:54 +0100 Subject: [PATCH 46/55] target/hppa: Speed up hppa_is_pa20() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although the hppa_is_pa20() helper is costly due to string comparisons in object_dynamic_cast(), it is called quite often during memory lookups and at each start of a block of instruction translations. Speed hppa_is_pa20() up by calling object_dynamic_cast() only once at CPU creation and store the result in the is_pa20 of struct CPUArchState. Signed-off-by: Helge Deller Co-developed-by: Philippe Mathieu-Daudé Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20241231190620.24442-7-philmd@linaro.org> --- target/hppa/cpu.c | 8 ++++++++ target/hppa/cpu.h | 6 ++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index 7278b7ca6b..b0bc9d35e4 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -193,6 +193,13 @@ static void hppa_cpu_realizefn(DeviceState *dev, Error **errp) tcg_cflags_set(cs, CF_PCREL); } +static void hppa_cpu_initfn(Object *obj) +{ + CPUHPPAState *env = cpu_env(CPU(obj)); + + env->is_pa20 = !!object_dynamic_cast(obj, TYPE_HPPA64_CPU); +} + static void hppa_cpu_reset_hold(Object *obj, ResetType type) { HPPACPUClass *scc = HPPA_CPU_GET_CLASS(obj); @@ -282,6 +289,7 @@ static const TypeInfo hppa_cpu_type_infos[] = { .parent = TYPE_CPU, .instance_size = sizeof(HPPACPU), .instance_align = __alignof(HPPACPU), + .instance_init = hppa_cpu_initfn, .abstract = false, .class_size = sizeof(HPPACPUClass), .class_init = hppa_cpu_class_init, diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index c1d69c1a83..083d4f5a56 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -266,6 +266,8 @@ typedef struct CPUArchState { /* Fields up to this point are cleared by a CPU reset */ struct {} end_reset_fields; + + bool is_pa20; } CPUHPPAState; /** @@ -297,9 +299,9 @@ struct HPPACPUClass { #include "exec/cpu-all.h" -static inline bool hppa_is_pa20(CPUHPPAState *env) +static inline bool hppa_is_pa20(const CPUHPPAState *env) { - return object_dynamic_cast(OBJECT(env_cpu(env)), TYPE_HPPA64_CPU) != NULL; + return env->is_pa20; } static inline int HPPA_BTLB_ENTRIES(CPUHPPAState *env) From c48cc87ba15b3f7e327f6c6fab9eec7fe7421136 Mon Sep 17 00:00:00 2001 From: Bibo Mao Date: Fri, 3 Jan 2025 14:45:14 +0800 Subject: [PATCH 47/55] hw/loongarch/virt: Checkpatch cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Code cleanup with directory hw/loongarch/, removing errors from command "scripts/checkpatch.pl hw/loongarch/*" Signed-off-by: Bibo Mao Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20250103064514.2660438-1-maobibo@loongson.cn> Signed-off-by: Philippe Mathieu-Daudé --- hw/loongarch/acpi-build.c | 3 ++- hw/loongarch/boot.c | 4 ++-- hw/loongarch/virt.c | 8 +++++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c index 9eb5fb68bf..fdd62acf7e 100644 --- a/hw/loongarch/acpi-build.c +++ b/hw/loongarch/acpi-build.c @@ -456,8 +456,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) acpi_table_begin(&table, table_data); dsdt = init_aml_allocator(); - for (i = 0; i < VIRT_UART_COUNT; i++) + for (i = 0; i < VIRT_UART_COUNT; i++) { build_uart_device_aml(dsdt, i); + } build_pci_device_aml(dsdt, lvms); build_la_ged_aml(dsdt, machine); build_flash_aml(dsdt, lvms); diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 241c0eef1f..bd8763c61c 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -292,7 +292,7 @@ static void reset_load_elf(void *opaque) cpu_reset(CPU(cpu)); if (env->load_elf) { - if (cpu == LOONGARCH_CPU(first_cpu)) { + if (cpu == LOONGARCH_CPU(first_cpu)) { env->gpr[4] = env->boot_info->a0; env->gpr[5] = env->boot_info->a1; env->gpr[6] = env->boot_info->a2; @@ -354,7 +354,7 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) if (info->kernel_filename) { kernel_addr = load_kernel_info(info); } else { - if(!qtest_enabled()) { + if (!qtest_enabled()) { warn_report("No kernel provided, booting from flash drive."); } } diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index df56d75a6e..db37ed6a71 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -331,8 +331,9 @@ static void fdt_add_uart_node(LoongArchVirtMachineState *lvms, qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "ns16550a"); qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0, base, 0x0, size); qemu_fdt_setprop_cell(ms->fdt, nodename, "clock-frequency", 100000000); - if (chosen) + if (chosen) { qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename); + } qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0x4); qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", *pch_pic_phandle); @@ -815,7 +816,7 @@ static void virt_devices_init(DeviceState *pch_pic, * Create uart fdt node in reverse order so that they appear * in the finished device tree lowest address first */ - for (i = VIRT_UART_COUNT; i --> 0;) { + for (i = VIRT_UART_COUNT; i-- > 0;) { hwaddr base = VIRT_UART_BASE + i * VIRT_UART_SIZE; int irq = VIRT_UART_IRQ + i - VIRT_GSI_BASE; serial_mm_init(get_system_memory(), base, 0, @@ -1175,8 +1176,9 @@ static void fw_cfg_add_memory(MachineState *ms) size = ram_size - numa_info[0].node_mem; } - if (size) + if (size) { memmap_add_entry(base, size, 1); + } } static void virt_init(MachineState *machine) From 78b0c15a563ac4be5afb0375602ca0a3adc6c442 Mon Sep 17 00:00:00 2001 From: Gabriel Barrantes Date: Sat, 28 Dec 2024 01:16:57 +0000 Subject: [PATCH 48/55] backends/cryptodev-vhost-user: Fix local_error leaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not propagate error to the upper, directly output the error to avoid leaks. Fixes: 2fda101de07 ("virtio-crypto: Support asynchronous mode") Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2714 Signed-off-by: Gabriel Barrantes Reviewed-by: zhenwei pi Message-Id: Signed-off-by: Philippe Mathieu-Daudé --- backends/cryptodev-vhost-user.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c index 43efdf9747..3295c6198a 100644 --- a/backends/cryptodev-vhost-user.c +++ b/backends/cryptodev-vhost-user.c @@ -281,8 +281,7 @@ static int cryptodev_vhost_user_create_session( break; default: - error_setg(&local_error, "Unsupported opcode :%" PRIu32 "", - sess_info->op_code); + error_report("Unsupported opcode :%" PRIu32 "", sess_info->op_code); return -VIRTIO_CRYPTO_NOTSUPP; } From bb5b7fced6b5d3334ab20702fc846e47bb1fb731 Mon Sep 17 00:00:00 2001 From: Phil Dennis-Jordan Date: Fri, 13 Dec 2024 17:06:14 +0100 Subject: [PATCH 49/55] hw/usb/hcd-xhci-pci: Use modulo to select MSI vector as per spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QEMU would crash with a failed assertion if the XHCI controller attempted to raise the interrupt on an interrupter corresponding to a MSI vector with a higher index than the highest configured for the device by the guest driver. This behaviour is correct on the MSI/PCI side: per PCI 3.0 spec, devices must ensure they do not send MSI notifications for vectors beyond the range of those allocated by the system/driver software. Unlike MSI-X, there is no generic way for handling aliasing in the case of fewer allocated vectors than requested, so the specifics are up to device implementors. (Section 6.8.3.4. "Sending Messages") It turns out the XHCI spec (Implementation Note in section 4.17, "Interrupters") requires that the host controller signal the MSI vector with the number computed by taking the interrupter number modulo the number of enabled MSI vectors. This change introduces that modulo calculation, fixing the failed assertion. This makes the device work correctly in MSI mode with macOS's XHCI driver, which only allocates a single vector. Signed-off-by: Phil Dennis-Jordan Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20250112210056.16658-2-phil@philjordan.eu> Signed-off-by: Philippe Mathieu-Daudé --- hw/usb/hcd-xhci-pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c index a069b42338..49642aab58 100644 --- a/hw/usb/hcd-xhci-pci.c +++ b/hw/usb/hcd-xhci-pci.c @@ -74,6 +74,7 @@ static bool xhci_pci_intr_raise(XHCIState *xhci, int n, bool level) } if (msi_enabled(pci_dev) && level) { + n %= msi_nr_vectors_allocated(pci_dev); msi_notify(pci_dev, n); return true; } From ef82ab692424c7fb42c3aeb6b65db68eade6213a Mon Sep 17 00:00:00 2001 From: Phil Dennis-Jordan Date: Fri, 27 Dec 2024 13:13:33 +0100 Subject: [PATCH 50/55] hw/usb/hcd-xhci-pci: Use event ring 0 if mapping unsupported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The XHCI specification, section 4.17.1 specifies that "If the Number of Interrupters (MaxIntrs) field is greater than 1, then Interrupter Mapping shall be supported." and "If Interrupter Mapping is not supported, the Interrupter Target field shall be ignored by the xHC and all Events targeted at Interrupter 0." QEMU's XHCI device has so far not specially addressed this case, so we add a check to xhci_event() to redirect to event ring and interrupt 0 if mapping is disabled. Signed-off-by: Phil Dennis-Jordan Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20241227121336.25838-4-phil@philjordan.eu> Signed-off-by: Philippe Mathieu-Daudé --- hw/usb/hcd-xhci.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 7dc0994c89..00d5bc3779 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -644,6 +644,10 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v) dma_addr_t erdp; unsigned int dp_idx; + if (xhci->numintrs == 1) { + v = 0; + } + if (v >= xhci->numintrs) { DPRINTF("intr nr out of range (%d >= %d)\n", v, xhci->numintrs); return; From e555abceec0c7f958d553a39ce4ac79239a34537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 10 Jan 2025 19:07:05 +0100 Subject: [PATCH 51/55] hw/tricore/triboard: Remove unnecessary use of &first_cpu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit triboard_machine_init() has access to the single CPU via: TriBoardMachineState { TC27XSoCState { TriCoreCPU cpu; ... } tc27x_soc; } ms; Pass it as argument to tricore_load_kernel() so we can remove the &first_cpu global use. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Pierrick Bouvier Reviewed-by: Bastian Koppelmann Message-Id: <20250110180909.83165-1-philmd@linaro.org> --- hw/tricore/triboard.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/hw/tricore/triboard.c b/hw/tricore/triboard.c index 4dba0259cd..9cc8d282ff 100644 --- a/hw/tricore/triboard.c +++ b/hw/tricore/triboard.c @@ -31,11 +31,10 @@ #include "hw/tricore/triboard.h" #include "hw/tricore/tc27x_soc.h" -static void tricore_load_kernel(const char *kernel_filename) +static void tricore_load_kernel(TriCoreCPU *cpu, const char *kernel_filename) { uint64_t entry; long kernel_size; - TriCoreCPU *cpu; CPUTriCoreState *env; kernel_size = load_elf(kernel_filename, NULL, @@ -46,7 +45,6 @@ static void tricore_load_kernel(const char *kernel_filename) error_report("no kernel file '%s'", kernel_filename); exit(1); } - cpu = TRICORE_CPU(first_cpu); env = &cpu->env; env->PC = entry; } @@ -62,7 +60,7 @@ static void triboard_machine_init(MachineState *machine) sysbus_realize(SYS_BUS_DEVICE(&ms->tc27x_soc), &error_fatal); if (machine->kernel_filename) { - tricore_load_kernel(machine->kernel_filename); + tricore_load_kernel(&ms->tc27x_soc.cpu, machine->kernel_filename); } } From a18ed70625e7360cafbd810bf35c6bc0abf005fb Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Wed, 18 Dec 2024 13:30:55 +0100 Subject: [PATCH 52/55] MAINTAINERS: remove myself from sbsa-ref MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I am ending my time with Linaro and do not have plans to continue working on SBSA Reference Platform anymore. Signed-off-by: Marcin Juszkiewicz Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Leif Lindholm Message-ID: <20241218123055.11220-1-marcin.juszkiewicz@linaro.org> Signed-off-by: Philippe Mathieu-Daudé --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index d26d497a38..026890ddc0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -923,7 +923,6 @@ SBSA-REF M: Radoslaw Biernacki M: Peter Maydell R: Leif Lindholm -R: Marcin Juszkiewicz L: qemu-arm@nongnu.org S: Maintained F: hw/arm/sbsa-ref.c From b44314abca6fe22d21795eaeaf280d504183cb11 Mon Sep 17 00:00:00 2001 From: Gustavo Romero Date: Tue, 7 Jan 2025 01:56:39 +0000 Subject: [PATCH 53/55] MAINTAINERS: Add me as the maintainer for ivshmem-flat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add me as the maintainer for the ivshmem-flat device. Signed-off-by: Gustavo Romero Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20250107015639.27648-1-gustavo.romero@linaro.org> Signed-off-by: Philippe Mathieu-Daudé --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 026890ddc0..ce42b95e71 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2786,6 +2786,13 @@ F: hw/hyperv/hv-balloon*.h F: include/hw/hyperv/dynmem-proto.h F: include/hw/hyperv/hv-balloon.h +ivshmem-flat +M: Gustavo Romero +S: Maintained +F: hw/misc/ivshmem-flat.c +F: include/hw/misc/ivshmem-flat.h +F: docs/system/devices/ivshmem-flat.rst + Subsystems ---------- Overall Audio backends From 07340820e63460e8b859c1ce0568c31226d31311 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sat, 11 Jan 2025 15:42:36 +0900 Subject: [PATCH 54/55] MAINTAINERS: Update path to coreaudio.m MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 8b46d7e2dc8e ("audio: Rename coreaudio extension to use Objective-C compiler") renamed coreaudio.c to coreaudio.m. Signed-off-by: Akihiko Odaki Reviewed-by: Christian Schoenebeck Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20250111-maintainers-v1-1-faebe6ef0fec@daynix.com> Signed-off-by: Philippe Mathieu-Daudé --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index ce42b95e71..8b9d9a7cac 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2801,7 +2801,7 @@ M: Marc-André Lureau S: Odd Fixes F: audio/ X: audio/alsaaudio.c -X: audio/coreaudio.c +X: audio/coreaudio.m X: audio/dsound* X: audio/jackaudio.c X: audio/ossaudio.c @@ -2823,7 +2823,7 @@ M: Philippe Mathieu-Daudé R: Christian Schoenebeck R: Akihiko Odaki S: Odd Fixes -F: audio/coreaudio.c +F: audio/coreaudio.m DSound Audio backend M: Gerd Hoffmann From 838cf72b5d2cd875897d8bdfea4b23f6d9fdc602 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Sun, 22 Dec 2024 16:53:41 +0000 Subject: [PATCH 55/55] Add a b4 configuration file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit b4 [1] is a convenient tool to manage patch series with mailing list working flow. Add a project default config file to match QEMU's mailing list conventions as well as adopting differences on scripting. Examples of b4: ``` $ b4 prep --check Checking patches using: scripts/checkpatch.pl -q --terse --no-summary --mailback - --- Signed-off-by: Jiaxun Yang --- Changes in v2: - Add lore masks (philmd) from: https://lore.kernel.org/qemu-devel/20241224135054.10243-1-philmd@linaro.org/ - Link to v1: https://lore.kernel.org/r/20241222-b4-config-v1-1-b3667beb30a4@flygoat.com --- ● cc5a4c890fed: Add a b4 configuration file ● checkpatch.pl: 27: WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? --- Success: 0, Warning: 1, Error: 0 ``` ``` $ b4 prep -c Will collect To: addresses using echo Will collect Cc: addresses using get_maintainer.pl Collecting To/Cc addresses + To: qemu-devel@nongnu.org --- You can trim/expand this list with: b4 prep --edit-cover Invoking git-filter-repo to update the cover letter. New history written in 0.02 seconds... Completely finished after 0.06 seconds ``` [1]: https://b4.docs.kernel.org/ Co-developed-by: Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: Jiaxun Yang Message-ID: <20250102-b4-config-v2-1-cc7299e399bb@flygoat.com> Signed-off-by: Philippe Mathieu-Daudé --- .b4-config | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .b4-config diff --git a/.b4-config b/.b4-config new file mode 100644 index 0000000000..4b9b2fe290 --- /dev/null +++ b/.b4-config @@ -0,0 +1,14 @@ +# +# Common b4 settings that can be used to send patches to QEMU upstream. +# https://b4.docs.kernel.org/ +# + +[b4] + send-series-to = qemu-devel@nongnu.org + send-auto-to-cmd = echo + send-auto-cc-cmd = scripts/get_maintainer.pl --noroles --norolestats --nogit --nogit-fallback + am-perpatch-check-cmd = scripts/checkpatch.pl -q --terse --no-summary --mailback - + prep-perpatch-check-cmd = scripts/checkpatch.pl -q --terse --no-summary --mailback - + searchmask = https://lore.kernel.org/qemu-devel/?x=m&t=1&q=%s + linkmask = https://lore.kernel.org/qemu-devel/%s + linktrailermask = Message-ID: <%s>