* [PULL 00/63] target-arm queue
@ 2026-04-27 12:46 Peter Maydell
2026-04-27 12:46 ` [PULL 01/63] docs/system: add FEAT_AA32 and FEAT_AA64 to emulation list Peter Maydell
` (63 more replies)
0 siblings, 64 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
Hi; here's another arm pullreq; main parts here are the
new i.MX 8MM EVK board, and a lot of refactoring.
thanks
-- PMM
The following changes since commit aa15257174da180c6a8a9d58f87319cfe61c5520:
Merge tag 'pbouvier/pr/plugins-20260424' of https://gitlab.com/p-b-o/qemu into staging (2026-04-25 10:22:04 -0400)
are available in the Git repository at:
https://gitlab.com/pm215/qemu.git tags/pull-target-arm-20260427
for you to fetch changes up to 4575da5ecb7a27544aa6da1f78e700e8100ceaea:
target/arm: report register in WFIT syndromes (2026-04-27 11:46:34 +0100)
----------------------------------------------------------------
target-arm queue:
docs/system: add FEAT_AA32 and FEAT_AA64 to emulation list
hw/arm: Add the i.MX 8MM EVK(Evaluation Kit) board
target/arm: Build M-profile helper code once only
hw/arm: Remove hw_error() for the unimplemented CM_LMBUSCNT register
hw: Move ARM_SYSCTL_GPIO definitions to arm sysctl specific header
target/arm: Allow 'aarch64=off' to be set for TCG CPUs
target/arm: Allow some sysregs to not have to be an exact match for migration
hw/arm/raspi4b: NOP all DTB nodes when removing unimplemented devices
hw/arm/fsl-imx6ul: Implement LCDIF display device
target/arm: Refactor syndrome value code to use registerfields
target/arm: Report the register in WFxT syndromes
----------------------------------------------------------------
Alex Bennée (24):
docs/system: add FEAT_AA32 and FEAT_AA64 to emulation list
target/arm: migrate basic syndrome helpers to registerfields
target/arm: migrate system/cp trap syndromes to registerfields
target/arm: migrate FP/SIMD trap syndromes to registerfields
target/arm: migrate eret trap syndromes to registerfields
target/arm: migrate SME trap syndromes to registerfields
target/arm: migrate PAC trap syndromes to registerfields
target/arm: migrate BTI trap syndromes to registerfields
target/arm: migrate BXJ trap syndromes to registerfields
target/arm: migrate Granule Protection traps to registerfields
target/arm: migrate fault syndromes to registerfields
target/arm: migrate debug syndromes to registerfields
target/arm: migrate wfx syndromes to registerfields
target/arm: migrate gcs syndromes to registerfields
target/arm: migrate memory op syndromes to registerfields
target/arm: migrate check_hcr_el2_trap to use syndrome helper
target/arm: use syndrome helpers in arm_cpu_do_interrupt_aarch32_hyp
target/arm: use syndrome helpers to set SAME_EL EC bit
target/arm: make whpx use syndrome helpers for decode
target/arm: make hvf use syndrome helpers for decode
target/arm: use syndrome helpers in merge_syn_data_abort
target/arm: use syndrome helpers to query VNCR bit
target/arm: remove old syndrome defines
target/arm: report register in WFIT syndromes
Eric Auger (7):
target/arm/cpu: Introduce the infrastructure for cpreg migration tolerances
target/arm/machine: Handle ToleranceNotOnBothEnds migration tolerances
target/arm/machine: Handle ToleranceOnlySrcTestValue migration tolerance
target/arm/cpu64: Mitigate migration failures due to spurious TCR_EL1, PIRE0_EL1 and PIR_EL1
target/arm/cpu64: Define cpreg migration tolerance for KVM_REG_ARM_VENDOR_HYP_BMAP_2
target/arm/helper: Define cpreg migration tolerance for DGBDTR_EL0
Revert "target/arm: Reinstate bogus AArch32 DBGDTRTX register for migration compat"
Gaurav Sharma (15):
hw/arm: Add the i.MX 8MM EVK(Evaluation Kit) board
hw/misc/imx8mp_analog: Add property to analog device
hw/arm/fsl-imx8mm: Add Analog device IP to iMX8MM SOC
hw/arm/fsl-imx8mm: Add Clock Control Module IP to iMX8MM
hw/arm/fsl-imx8mm: Implemented support for SNVS
hw/arm/fsl-imx8mm: Adding support for USDHC storage controllers
hw/arm/fsl-imx8mm: Add PCIe support
hw/arm/fsl-imx8mm: Add GPIO controllers
hw/arm/fsl-imx8mm: Adding support for I2C emulation
hw/arm/fsl-imx8mm: Adding support for SPI controller
hw/arm/fsl-imx8mm: Adding support for Watchdog Timers
hw/arm/fsl-imx8mm: Adding support for General Purpose Timers
hw/arm/fsl-imx8mm: Adding support for ENET ethernet controller
hw/arm/fsl-imx8mm: Adding support for USB controller
hw/arm/fsl-imx8mm: Adding functional testing of iMX8MM emulation
Osama Abdelkader (1):
hw/arm/raspi4b: NOP all DTB nodes when removing unimplemented devices
Peter Maydell (4):
hw: Move ARM_SYSCTL_GPIO definitions to arm sysctl specific header
target/arm: Clear AArch64 ID regs from ARMISARegisters if AArch64 disabled
target/arm: Allow 'aarch64=off' to be set for TCG CPUs
tests/functional/aarch64: Add basic test of TCG aarch64=off
Philippe Mathieu-Daudé (9):
target/arm: Ignore endianness when setting MTE tags
target/arm: Explode MO_TExx -> MO_TE | MO_xx
target/arm: Hoist MO_TE into mve_advance_vpt()
target/arm: Hoist MO_TE into MVE DO_VSTR() macro
target/arm: Introduce mo_endian() helper
target/arm: Replace MO_TE -> mo_endian() for MVE helpers
target/arm: Compile mve_helper.c once
target/arm: Replace MO_TE -> mo_endian() for Cortex-M helpers
target/arm: Compile m_helper.c once
Thomas Huth (1):
hw/arm: Remove hw_error() for the unimplemented CM_LMBUSCNT register
Yucai Liu (2):
hw/display: Add i.MX6UL LCDIF device model
hw/arm/fsl-imx6ul: Wire in the LCDIF device model
MAINTAINERS | 16 +-
docs/system/arm/cpu-features.rst | 10 +-
docs/system/arm/emulation.rst | 2 +
docs/system/arm/{imx8mp-evk.rst => imx8m.rst} | 49 +-
docs/system/target-arm.rst | 2 +-
hw/arm/Kconfig | 25 +
hw/arm/fsl-imx6ul.c | 12 +-
hw/arm/fsl-imx8mm.c | 704 ++++++++++++++++++++++
hw/arm/imx8mm-evk.c | 130 ++++
hw/arm/integratorcp.c | 3 -
hw/arm/meson.build | 2 +
hw/arm/raspi4b.c | 10 +-
hw/arm/realview.c | 2 +-
hw/arm/vexpress.c | 2 +-
hw/arm/virt.c | 1 -
hw/display/Kconfig | 4 +
hw/display/imx6ul_lcdif.c | 453 ++++++++++++++
hw/display/meson.build | 1 +
hw/misc/arm_sysctl.c | 2 +-
hw/misc/imx8mp_analog.c | 12 +-
hw/timer/imx_gpt.c | 26 +
hw/vmapple/vmapple.c | 1 -
include/hw/arm/fsl-imx6ul.h | 4 +-
include/hw/arm/fsl-imx8mm.h | 242 ++++++++
include/hw/arm/primecell.h | 12 -
include/hw/display/imx6ul_lcdif.h | 37 ++
include/hw/misc/arm_sysctl.h | 16 +
include/hw/misc/imx8mp_analog.h | 3 +
include/hw/timer/imx_gpt.h | 2 +
target/arm/cpu-features.h | 5 +
target/arm/cpu.c | 153 ++++-
target/arm/cpu.h | 4 +-
target/arm/cpu64.c | 39 ++
target/arm/debug_helper.c | 29 -
target/arm/helper.c | 27 +-
target/arm/hvf/hvf.c | 14 +-
target/arm/internals.h | 60 ++
target/arm/machine.c | 33 +-
target/arm/syndrome.h | 595 ++++++++++++++----
target/arm/tcg/debug.c | 2 +-
target/arm/tcg/helper-a64.c | 2 +-
target/arm/tcg/helper-defs.h | 2 +-
target/arm/tcg/m_helper.c | 8 +-
target/arm/tcg/meson.build | 6 +-
target/arm/tcg/mve_helper.c | 102 ++--
target/arm/tcg/op_helper.c | 7 +-
target/arm/tcg/tlb_helper.c | 6 +-
target/arm/tcg/translate-a64.c | 2 +-
target/arm/tcg/vfp_helper.c | 5 +-
target/arm/trace-events | 2 +
target/arm/whpx/whpx-all.c | 13 +-
tests/functional/aarch64/meson.build | 3 +
tests/functional/aarch64/test_imx8mm_evk.py | 69 +++
tests/functional/aarch64/test_virt_aarch64_off.py | 37 ++
tests/qtest/arm-cpu-features.c | 8 +-
55 files changed, 2743 insertions(+), 275 deletions(-)
rename docs/system/arm/{imx8mp-evk.rst => imx8m.rst} (58%)
create mode 100644 hw/arm/fsl-imx8mm.c
create mode 100644 hw/arm/imx8mm-evk.c
create mode 100644 hw/display/imx6ul_lcdif.c
create mode 100644 include/hw/arm/fsl-imx8mm.h
delete mode 100644 include/hw/arm/primecell.h
create mode 100644 include/hw/display/imx6ul_lcdif.h
create mode 100644 include/hw/misc/arm_sysctl.h
create mode 100755 tests/functional/aarch64/test_imx8mm_evk.py
create mode 100755 tests/functional/aarch64/test_virt_aarch64_off.py
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PULL 01/63] docs/system: add FEAT_AA32 and FEAT_AA64 to emulation list
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 02/63] hw/arm: Add the i.MX 8MM EVK(Evaluation Kit) board Peter Maydell
` (62 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
This is just a documentation tweak as we already support both.
FEAT_AA32 implies FEAT_AA32EL0. FEAT_AA64 implies FEAT_AA64EL[0123].
This is however useful if you are using emulation.rst as a source of
truth of what QEMU emulates and when cross checking with
Features.json from Arm.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20260421093506.616307-1-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
docs/system/arm/emulation.rst | 2 ++
1 file changed, 2 insertions(+)
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
index 7787691853..8cd7fe7b00 100644
--- a/docs/system/arm/emulation.rst
+++ b/docs/system/arm/emulation.rst
@@ -7,6 +7,7 @@ QEMU's TCG emulation includes support for the Armv5, Armv6, Armv7,
Armv8 and Armv9 versions of the A-profile architecture. It also has support for
the following architecture extensions:
+- FEAT_AA32 (PE Support for AArch32)
- FEAT_AA32BF16 (AArch32 BFloat16 instructions)
- FEAT_AA32EL0 (Support for AArch32 at EL0)
- FEAT_AA32EL1 (Support for AArch32 at EL1)
@@ -14,6 +15,7 @@ the following architecture extensions:
- FEAT_AA32EL3 (Support for AArch32 at EL3)
- FEAT_AA32HPD (AArch32 hierarchical permission disables)
- FEAT_AA32I8MM (AArch32 Int8 matrix multiplication instructions)
+- FEAT_AA64 (PE uses AArch64 after last reboot)
- FEAT_AA64EL0 (Support for AArch64 at EL0)
- FEAT_AA64EL1 (Support for AArch64 at EL1)
- FEAT_AA64EL2 (Support for AArch64 at EL2)
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 02/63] hw/arm: Add the i.MX 8MM EVK(Evaluation Kit) board
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
2026-04-27 12:46 ` [PULL 01/63] docs/system: add FEAT_AA32 and FEAT_AA64 to emulation list Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 03/63] hw/misc/imx8mp_analog: Add property to analog device Peter Maydell
` (61 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Implemented CPUs, RAM, UARTs and Interrupt Controller
Other peripherals are represented as TYPE_UNIMPLEMENTED_DEVICE
Complete memory map of the SoC is provided.
Set default RAM size to 2GB and default CPU count to 4 to match
the real i.MX8MM EVK hardware configuration.
Documentation is shared with imx8mp-evk to avoid duplication.
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
[PMM: fixed over-long lines in doc]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
MAINTAINERS | 11 +-
docs/system/arm/{imx8mp-evk.rst => imx8m.rst} | 49 ++-
docs/system/target-arm.rst | 2 +-
hw/arm/Kconfig | 12 +
hw/arm/fsl-imx8mm.c | 377 ++++++++++++++++++
hw/arm/imx8mm-evk.c | 112 ++++++
hw/arm/meson.build | 2 +
include/hw/arm/fsl-imx8mm.h | 158 ++++++++
8 files changed, 709 insertions(+), 14 deletions(-)
rename docs/system/arm/{imx8mp-evk.rst => imx8m.rst} (58%)
create mode 100644 hw/arm/fsl-imx8mm.c
create mode 100644 hw/arm/imx8mm-evk.c
create mode 100644 include/hw/arm/fsl-imx8mm.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 35529266a2..8167d42876 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -913,6 +913,15 @@ F: hw/pci-host/designware.c
F: include/hw/pci-host/designware.h
F: docs/system/arm/mcimx7d-sabre.rst
+MCIMX8MM-EVK / iMX8MM
+M: Gaurav Sharma <gaurav.sharma_7@nxp.com>
+L: qemu-arm@nongnu.org
+S: Maintained
+F: hw/arm/fsl-imx8mm.c
+F: hw/arm/imx8mm-evk.c
+F: include/hw/arm/fsl-imx8mm.h
+F: docs/system/arm/imx8m.rst
+
MCIMX8MP-EVK / i.MX8MP
M: Bernhard Beschow <shentey@gmail.com>
L: qemu-arm@nongnu.org
@@ -925,7 +934,7 @@ F: hw/rtc/rs5c372.c
F: include/hw/arm/fsl-imx8mp.h
F: include/hw/misc/imx8mp_*.h
F: include/hw/pci-host/fsl_imx8m_phy.h
-F: docs/system/arm/imx8mp-evk.rst
+F: docs/system/arm/imx8m.rst
F: tests/functional/aarch64/test_imx8mp_evk.py
F: tests/qtest/rs5c372-test.c
diff --git a/docs/system/arm/imx8mp-evk.rst b/docs/system/arm/imx8m.rst
similarity index 58%
rename from docs/system/arm/imx8mp-evk.rst
rename to docs/system/arm/imx8m.rst
index e60a422824..afbc33b2f4 100644
--- a/docs/system/arm/imx8mp-evk.rst
+++ b/docs/system/arm/imx8m.rst
@@ -1,13 +1,15 @@
-NXP i.MX 8M Plus Evaluation Kit (``imx8mp-evk``)
-================================================
+NXP i.MX 8M Plus and i.MX 8M Mini Evaluation Kits (``imx8mp-evk``, ``imx8mm-evk``)
+==================================================================================
-The ``imx8mp-evk`` machine models the i.MX 8M Plus Evaluation Kit, based on an
-i.MX 8M Plus SoC.
+The ``imx8mp-evk`` and ``imx8mm-evk`` machine models the i.MX 8M Plus
+and i.MX 8M Mini Evaluation Kits, based on i.MX 8M Plus and i.MX8M
+Mini SoCs.
Supported devices
-----------------
-The ``imx8mp-evk`` machine implements the following devices:
+The ``imx8mp-evk`` and ``imx8mm-evk`` machines implement the
+following devices:
* Up to 4 Cortex-A53 cores
* Generic Interrupt Controller (GICv3)
@@ -27,8 +29,8 @@ The ``imx8mp-evk`` machine implements the following devices:
Boot options
------------
-The ``imx8mp-evk`` machine can start a Linux kernel directly using the standard
-``-kernel`` functionality.
+The ``imx8mp-evk`` and ``imx8mm-evk`` machines can start a Linux
+kernel directly using the standard ``-kernel`` functionality.
Direct Linux Kernel Boot
''''''''''''''''''''''''
@@ -38,11 +40,20 @@ is to generate an image with Buildroot. Version 2024.11.1 is tested at the time
of writing and involves two steps. First run the following commands in the
toplevel directory of the Buildroot source tree:
+For i.MX 8M Plus EVK:
+
.. code-block:: bash
$ make freescale_imx8mpevk_defconfig
$ make
+For i.MX 8M Mini EVK:
+
+.. code-block:: bash
+
+ $ make freescale_imx8mmevk_defconfig
+ $ make
+
Once finished successfully there is an ``output/image`` subfolder. Navigate into
it and resize the SD card image to a power of two:
@@ -52,6 +63,8 @@ it and resize the SD card image to a power of two:
Now that everything is prepared the machine can be started as follows:
+For i.MX 8M Plus EVK:
+
.. code-block:: bash
$ qemu-system-aarch64 -M imx8mp-evk \
@@ -61,6 +74,16 @@ Now that everything is prepared the machine can be started as follows:
-append "root=/dev/mmcblk2p2" \
-drive file=sdcard.img,if=sd,bus=2,format=raw,id=mmcblk2
+For i.MX 8M Mini EVK:
+
+.. code-block:: bash
+
+ $ qemu-system-aarch64 -M imx8mm-evk -smp 4 -m 2G \
+ -display none -serial null -serial stdio \
+ -kernel Image \
+ -dtb imx8mm-evk.dtb \
+ -append "root=/dev/mmcblk2p2" \
+ -drive file=sdcard.img,if=sd,bus=2,format=raw,id=mmcblk2
KVM Acceleration
----------------
@@ -69,11 +92,13 @@ To enable hardware-assisted acceleration via KVM, append
``-accel kvm`` to the command line. While this speeds up performance
significantly, be aware of the following limitations:
-* The ``imx8mp-evk`` machine is not included under the "virtualization use case"
- of :doc:`QEMU's security policy </system/security>`. This means that you
- should not trust that it can contain malicious guests, whether it is run
- using TCG or KVM. If you don't trust your guests and you're relying on QEMU to
- be the security boundary, you want to choose another machine such as ``virt``.
+* The ``imx8mp-evk`` and ``imx8mm-evk`` machines are not included
+ under the "virtualization use case" of :doc:`QEMU's security
+ policy </system/security>`. This means that you should not trust that
+ it can contain malicious guests, whether it is run using TCG or KVM.
+ If you don't trust your guests and you're relying on QEMU to be the
+ security boundary, you want to choose another machine such as
+ ``virt``.
* Rather than Cortex-A53 CPUs, the same CPU type as the host's will be used.
This is a limitation of KVM and may not work with guests with a tight
dependency on Cortex-A53.
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
index 89f7b77313..c57102a414 100644
--- a/docs/system/target-arm.rst
+++ b/docs/system/target-arm.rst
@@ -95,7 +95,7 @@ Board-specific documentation
arm/imx25-pdk
arm/mcimx6ul-evk
arm/mcimx7d-sabre
- arm/imx8mp-evk
+ arm/imx8m
arm/orangepi
arm/raspi
arm/collie
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 41d5e968c8..86f4d9bc4d 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -617,6 +617,18 @@ config FSL_IMX8MP_EVK
depends on TCG
select FSL_IMX8MP
+config FSL_IMX8MM
+ bool
+ select ARM_GIC
+ select IMX
+
+config FSL_IMX8MM_EVK
+ bool
+ default y
+ depends on AARCH64
+ depends on TCG
+ select FSL_IMX8MM
+
config ARM_SMMUV3_ACCEL
bool
depends on ARM_SMMUV3
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
new file mode 100644
index 0000000000..23a82613d7
--- /dev/null
+++ b/hw/arm/fsl-imx8mm.c
@@ -0,0 +1,377 @@
+/*
+ * i.MX 8MM SoC Implementation
+ *
+ * Based on hw/arm/fsl-imx6.c
+ *
+ * Copyright (c) 2025, NXP Semiconductors
+ * Author: Gaurav Sharma <gaurav.sharma_7@nxp.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * iMX8MM Reference Manual - https://www.nxp.com/products/i.MX8MMINI -> Documentation
+ */
+
+#include "qemu/osdep.h"
+#include "system/address-spaces.h"
+#include "hw/arm/bsa.h"
+#include "hw/arm/fsl-imx8mm.h"
+#include "hw/misc/unimp.h"
+#include "hw/core/boards.h"
+#include "system/kvm.h"
+#include "system/system.h"
+#include "target/arm/cpu.h"
+#include "target/arm/cpu-qom.h"
+#include "target/arm/kvm_arm.h"
+#include "qapi/error.h"
+#include "qobject/qlist.h"
+
+static const struct {
+ hwaddr addr;
+ size_t size;
+ const char *name;
+} fsl_imx8mm_memmap[] = {
+ [FSL_IMX8MM_RAM] = { FSL_IMX8MM_RAM_START, FSL_IMX8MM_RAM_SIZE_MAX, "ram" },
+ [FSL_IMX8MM_DDR_PHY_BROADCAST] = { 0x3dc00000, 4 * MiB, "ddr_phy_broadcast" },
+ [FSL_IMX8MM_DDR_PERF_MON] = { 0x3d800000, 4 * MiB, "ddr_perf_mon" },
+ [FSL_IMX8MM_DDR_CTL] = { 0x3d400000, 4 * MiB, "ddr_ctl" },
+ [FSL_IMX8MM_DDR_PHY] = { 0x3c000000, 16 * MiB, "ddr_phy" },
+ [FSL_IMX8MM_GIC_DIST] = { 0x38800000, 512 * KiB, "gic_dist" },
+ [FSL_IMX8MM_GIC_REDIST] = { 0x38880000, 512 * KiB, "gic_redist" },
+ [FSL_IMX8MM_VPU] = { 0x38340000, 2 * MiB, "vpu" },
+ [FSL_IMX8MM_VPU_BLK_CTRL] = { 0x38330000, 2 * MiB, "vpu_blk_ctrl" },
+ [FSL_IMX8MM_VPU_G2_DECODER] = { 0x38310000, 1 * MiB, "vpu_g2_decoder" },
+ [FSL_IMX8MM_VPU_G1_DECODER] = { 0x38300000, 1 * MiB, "vpu_g1_decoder" },
+ [FSL_IMX8MM_USB2_OTG] = { 0x32e50200, 0x200, "usb2_otg" },
+ [FSL_IMX8MM_USB2] = { 0x32e50000, 0x200, "usb2" },
+ [FSL_IMX8MM_USB1_OTG] = { 0x32e40200, 0x200, "usb1_otg" },
+ [FSL_IMX8MM_USB1] = { 0x32e40000, 0x200, "usb1" },
+ [FSL_IMX8MM_GPU2D] = { 0x38000000, 64 * KiB, "gpu2d" },
+ [FSL_IMX8MM_QSPI1_RX_BUFFER] = { 0x34000000, 32 * MiB, "qspi1_rx_buffer" },
+ [FSL_IMX8MM_PCIE1] = { 0x33800000, 4 * MiB, "pcie1" },
+ [FSL_IMX8MM_QSPI1_TX_BUFFER] = { 0x33008000, 32 * KiB, "qspi1_tx_buffer" },
+ [FSL_IMX8MM_APBH_DMA] = { 0x33000000, 32 * KiB, "apbh_dma" },
+
+ /* AIPS-4 Begin */
+ [FSL_IMX8MM_TZASC] = { 0x32f80000, 64 * KiB, "tzasc" },
+ [FSL_IMX8MM_PCIE_PHY1] = { 0x32f00000, 64 * KiB, "pcie_phy1" },
+ [FSL_IMX8MM_MEDIA_BLK_CTL] = { 0x32e28000, 256, "media_blk_ctl" },
+ [FSL_IMX8MM_LCDIF] = { 0x32e00000, 64 * KiB, "lcdif" },
+ [FSL_IMX8MM_MIPI_DSI] = { 0x32e10000, 64 * KiB, "mipi_dsi" },
+ [FSL_IMX8MM_MIPI_CSI] = { 0x32e30000, 64 * KiB, "mipi_csi" },
+ [FSL_IMX8MM_AIPS4_CONFIGURATION] = { 0x32df0000, 64 * KiB, "aips4_configuration" },
+ /* AIPS-4 End */
+
+ [FSL_IMX8MM_INTERCONNECT] = { 0x32700000, 1 * MiB, "interconnect" },
+
+ /* AIPS-3 Begin */
+ [FSL_IMX8MM_ENET1] = { 0x30be0000, 64 * KiB, "enet1" },
+ [FSL_IMX8MM_SDMA1] = { 0x30bd0000, 64 * KiB, "sdma1" },
+ [FSL_IMX8MM_QSPI] = { 0x30bb0000, 64 * KiB, "qspi" },
+ [FSL_IMX8MM_USDHC3] = { 0x30b60000, 64 * KiB, "usdhc3" },
+ [FSL_IMX8MM_USDHC2] = { 0x30b50000, 64 * KiB, "usdhc2" },
+ [FSL_IMX8MM_USDHC1] = { 0x30b40000, 64 * KiB, "usdhc1" },
+ [FSL_IMX8MM_SEMAPHORE_HS] = { 0x30ac0000, 64 * KiB, "semaphore_hs" },
+ [FSL_IMX8MM_MU_B] = { 0x30ab0000, 64 * KiB, "mu_b" },
+ [FSL_IMX8MM_MU_A] = { 0x30aa0000, 64 * KiB, "mu_a" },
+ [FSL_IMX8MM_UART4] = { 0x30a60000, 64 * KiB, "uart4" },
+ [FSL_IMX8MM_I2C4] = { 0x30a50000, 64 * KiB, "i2c4" },
+ [FSL_IMX8MM_I2C3] = { 0x30a40000, 64 * KiB, "i2c3" },
+ [FSL_IMX8MM_I2C2] = { 0x30a30000, 64 * KiB, "i2c2" },
+ [FSL_IMX8MM_I2C1] = { 0x30a20000, 64 * KiB, "i2c1" },
+ [FSL_IMX8MM_AIPS3_CONFIGURATION] = { 0x309f0000, 64 * KiB, "aips3_configuration" },
+ [FSL_IMX8MM_CAAM] = { 0x30900000, 256 * KiB, "caam" },
+ [FSL_IMX8MM_SPBA1] = { 0x308f0000, 64 * KiB, "spba1" },
+ [FSL_IMX8MM_UART2] = { 0x30890000, 64 * KiB, "uart2" },
+ [FSL_IMX8MM_UART3] = { 0x30880000, 64 * KiB, "uart3" },
+ [FSL_IMX8MM_UART1] = { 0x30860000, 64 * KiB, "uart1" },
+ [FSL_IMX8MM_ECSPI3] = { 0x30840000, 64 * KiB, "ecspi3" },
+ [FSL_IMX8MM_ECSPI2] = { 0x30830000, 64 * KiB, "ecspi2" },
+ [FSL_IMX8MM_ECSPI1] = { 0x30820000, 64 * KiB, "ecspi1" },
+ /* AIPS-3 End */
+
+ /* AIPS-2 Begin */
+ [FSL_IMX8MM_QOSC] = { 0x307f0000, 64 * KiB, "qosc" },
+ [FSL_IMX8MM_PERFMON2] = { 0x307d0000, 64 * KiB, "perfmon2" },
+ [FSL_IMX8MM_PERFMON1] = { 0x307c0000, 64 * KiB, "perfmon1" },
+ [FSL_IMX8MM_GPT4] = { 0x30700000, 64 * KiB, "gpt4" },
+ [FSL_IMX8MM_GPT5] = { 0x306f0000, 64 * KiB, "gpt5" },
+ [FSL_IMX8MM_GPT6] = { 0x306e0000, 64 * KiB, "gpt6" },
+ [FSL_IMX8MM_SYSCNT_CTRL] = { 0x306c0000, 64 * KiB, "syscnt_ctrl" },
+ [FSL_IMX8MM_SYSCNT_CMP] = { 0x306b0000, 64 * KiB, "syscnt_cmp" },
+ [FSL_IMX8MM_SYSCNT_RD] = { 0x306a0000, 64 * KiB, "syscnt_rd" },
+ [FSL_IMX8MM_PWM4] = { 0x30690000, 64 * KiB, "pwm4" },
+ [FSL_IMX8MM_PWM3] = { 0x30680000, 64 * KiB, "pwm3" },
+ [FSL_IMX8MM_PWM2] = { 0x30670000, 64 * KiB, "pwm2" },
+ [FSL_IMX8MM_PWM1] = { 0x30660000, 64 * KiB, "pwm1" },
+ [FSL_IMX8MM_AIPS2_CONFIGURATION] = { 0x305f0000, 64 * KiB, "aips2_configuration" },
+ /* AIPS-2 End */
+
+ /* AIPS-1 Begin */
+ [FSL_IMX8MM_CSU] = { 0x303e0000, 64 * KiB, "csu" },
+ [FSL_IMX8MM_RDC] = { 0x303d0000, 64 * KiB, "rdc" },
+ [FSL_IMX8MM_SEMAPHORE2] = { 0x303c0000, 64 * KiB, "semaphore2" },
+ [FSL_IMX8MM_SEMAPHORE1] = { 0x303b0000, 64 * KiB, "semaphore1" },
+ [FSL_IMX8MM_GPC] = { 0x303a0000, 64 * KiB, "gpc" },
+ [FSL_IMX8MM_SRC] = { 0x30390000, 64 * KiB, "src" },
+ [FSL_IMX8MM_CCM] = { 0x30380000, 64 * KiB, "ccm" },
+ [FSL_IMX8MM_SNVS_HP] = { 0x30370000, 64 * KiB, "snvs_hp" },
+ [FSL_IMX8MM_ANA_PLL] = { 0x30360000, 64 * KiB, "ana_pll" },
+ [FSL_IMX8MM_OCOTP_CTRL] = { 0x30350000, 64 * KiB, "ocotp_ctrl" },
+ [FSL_IMX8MM_IOMUXC_GPR] = { 0x30340000, 64 * KiB, "iomuxc_gpr" },
+ [FSL_IMX8MM_IOMUXC] = { 0x30330000, 64 * KiB, "iomuxc" },
+ [FSL_IMX8MM_GPT3] = { 0x302f0000, 64 * KiB, "gpt3" },
+ [FSL_IMX8MM_GPT2] = { 0x302e0000, 64 * KiB, "gpt2" },
+ [FSL_IMX8MM_GPT1] = { 0x302d0000, 64 * KiB, "gpt1" },
+ [FSL_IMX8MM_SDMA2] = { 0x302c0000, 64 * KiB, "sdma2" },
+ [FSL_IMX8MM_SDMA3] = { 0x302b0000, 64 * KiB, "sdma3" },
+ [FSL_IMX8MM_WDOG3] = { 0x302a0000, 64 * KiB, "wdog3" },
+ [FSL_IMX8MM_WDOG2] = { 0x30290000, 64 * KiB, "wdog2" },
+ [FSL_IMX8MM_WDOG1] = { 0x30280000, 64 * KiB, "wdog1" },
+ [FSL_IMX8MM_ANA_OSC] = { 0x30270000, 64 * KiB, "ana_osc" },
+ [FSL_IMX8MM_ANA_TSENSOR] = { 0x30260000, 64 * KiB, "ana_tsensor" },
+ [FSL_IMX8MM_GPIO5] = { 0x30240000, 64 * KiB, "gpio5" },
+ [FSL_IMX8MM_GPIO4] = { 0x30230000, 64 * KiB, "gpio4" },
+ [FSL_IMX8MM_GPIO3] = { 0x30220000, 64 * KiB, "gpio3" },
+ [FSL_IMX8MM_GPIO2] = { 0x30210000, 64 * KiB, "gpio2" },
+ [FSL_IMX8MM_GPIO1] = { 0x30200000, 64 * KiB, "gpio1" },
+ [FSL_IMX8MM_AIPS1_CONFIGURATION] = { 0x301f0000, 64 * KiB, "aips1_configuration" },
+ [FSL_IMX8MM_SAI6] = { 0x30060000, 64 * KiB, "sai6" },
+ [FSL_IMX8MM_SAI5] = { 0x30050000, 64 * KiB, "sai5" },
+ [FSL_IMX8MM_SAI3] = { 0x30030000, 64 * KiB, "sai3" },
+ [FSL_IMX8MM_SAI2] = { 0x30020000, 64 * KiB, "sai2" },
+ [FSL_IMX8MM_SAI1] = { 0x30010000, 64 * KiB, "sai1" },
+
+ /* AIPS-1 End */
+
+ [FSL_IMX8MM_A53_DAP] = { 0x28000000, 16 * MiB, "a53_dap" },
+ [FSL_IMX8MM_PCIE1_MEM] = { 0x18000000, 128 * MiB, "pcie1_mem" },
+ [FSL_IMX8MM_QSPI_MEM] = { 0x08000000, 256 * MiB, "qspi_mem" },
+ [FSL_IMX8MM_OCRAM] = { 0x00900000, 256 * KiB, "ocram" },
+ [FSL_IMX8MM_TCM_DTCM] = { 0x00800000, 128 * KiB, "tcm_dtcm" },
+ [FSL_IMX8MM_TCM_ITCM] = { 0x007e0000, 128 * KiB, "tcm_itcm" },
+ [FSL_IMX8MM_OCRAM_S] = { 0x00180000, 32 * KiB, "ocram_s" },
+ [FSL_IMX8MM_CAAM_MEM] = { 0x00100000, 32 * KiB, "caam_mem" },
+ [FSL_IMX8MM_BOOT_ROM_PROTECTED] = { 0x0003f000, 4 * KiB, "boot_rom_protected" },
+ [FSL_IMX8MM_BOOT_ROM] = { 0x00000000, 252 * KiB, "boot_rom" },
+};
+
+static void fsl_imx8mm_init(Object *obj)
+{
+ MachineState *ms = MACHINE(qdev_get_machine());
+ FslImx8mmState *s = FSL_IMX8MM(obj);
+ const char *cpu_type = ms->cpu_type ?: ARM_CPU_TYPE_NAME("cortex-a53");
+ int i;
+
+ for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX8MM_NUM_CPUS); i++) {
+ g_autofree char *name = g_strdup_printf("cpu%d", i);
+ object_initialize_child(obj, name, &s->cpu[i], cpu_type);
+ }
+
+ object_initialize_child(obj, "gic", &s->gic, gicv3_class_name());
+
+ for (i = 0; i < FSL_IMX8MM_NUM_UARTS; i++) {
+ g_autofree char *name = g_strdup_printf("uart%d", i + 1);
+ object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
+ }
+
+}
+
+static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
+{
+ MachineState *ms = MACHINE(qdev_get_machine());
+ FslImx8mmState *s = FSL_IMX8MM(dev);
+ DeviceState *gicdev = DEVICE(&s->gic);
+ int i;
+
+ if (ms->smp.cpus > FSL_IMX8MM_NUM_CPUS) {
+ error_setg(errp, "%s: Only %d CPUs are supported (%d requested)",
+ TYPE_FSL_IMX8MM, FSL_IMX8MM_NUM_CPUS, ms->smp.cpus);
+ return;
+ }
+
+ /* CPUs */
+ for (i = 0; i < ms->smp.cpus; i++) {
+ /* On uniprocessor, the CBAR is set to 0 */
+ if (ms->smp.cpus > 1 &&
+ object_property_find(OBJECT(&s->cpu[i]), "reset-cbar")) {
+ object_property_set_int(OBJECT(&s->cpu[i]), "reset-cbar",
+ fsl_imx8mm_memmap[FSL_IMX8MM_GIC_DIST].addr,
+ &error_abort);
+ }
+
+ /*
+ * CNTFID0 base frequency in Hz of system counter
+ */
+ object_property_set_int(OBJECT(&s->cpu[i]), "cntfrq", 8000000,
+ &error_abort);
+
+ if (object_property_find(OBJECT(&s->cpu[i]), "has_el2")) {
+ object_property_set_bool(OBJECT(&s->cpu[i]), "has_el2",
+ !kvm_enabled(), &error_abort);
+ }
+
+ if (object_property_find(OBJECT(&s->cpu[i]), "has_el3")) {
+ object_property_set_bool(OBJECT(&s->cpu[i]), "has_el3",
+ !kvm_enabled(), &error_abort);
+ }
+
+ if (i) {
+ /*
+ * Secondary CPUs start in powered-down state (and can be
+ * powered up via the SRC system reset controller)
+ */
+ object_property_set_bool(OBJECT(&s->cpu[i]), "start-powered-off",
+ true, &error_abort);
+ }
+
+ if (!qdev_realize(DEVICE(&s->cpu[i]), NULL, errp)) {
+ return;
+ }
+ }
+
+ /* GIC */
+ {
+ SysBusDevice *gicsbd = SYS_BUS_DEVICE(&s->gic);
+ QList *redist_region_count;
+ bool pmu = object_property_get_bool(OBJECT(first_cpu), "pmu", NULL);
+
+ qdev_prop_set_uint32(gicdev, "num-cpu", ms->smp.cpus);
+ qdev_prop_set_uint32(gicdev, "num-irq",
+ FSL_IMX8MM_NUM_IRQS + GIC_INTERNAL);
+ redist_region_count = qlist_new();
+ qlist_append_int(redist_region_count, ms->smp.cpus);
+ qdev_prop_set_array(gicdev, "redist-region-count", redist_region_count);
+ object_property_set_link(OBJECT(&s->gic), "sysmem",
+ OBJECT(get_system_memory()), &error_fatal);
+ if (!sysbus_realize(gicsbd, errp)) {
+ return;
+ }
+ sysbus_mmio_map(gicsbd, 0, fsl_imx8mm_memmap[FSL_IMX8MM_GIC_DIST].addr);
+ sysbus_mmio_map(gicsbd, 1, fsl_imx8mm_memmap[FSL_IMX8MM_GIC_REDIST].addr);
+
+ /*
+ * Wire the outputs from each CPU's generic timer and the GICv3
+ * maintenance interrupt signal to the appropriate GIC PPI inputs, and
+ * the GIC's IRQ/FIQ interrupt outputs to the CPU's inputs.
+ */
+ for (i = 0; i < ms->smp.cpus; i++) {
+ DeviceState *cpudev = DEVICE(&s->cpu[i]);
+ int intidbase = FSL_IMX8MM_NUM_IRQS + i * GIC_INTERNAL;
+ qemu_irq irq;
+
+ /*
+ * Mapping from the output timer irq lines from the CPU to the
+ * GIC PPI inputs.
+ */
+ static const int timer_irqs[] = {
+ [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
+ [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
+ [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
+ [GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
+ };
+
+ for (int j = 0; j < ARRAY_SIZE(timer_irqs); j++) {
+ irq = qdev_get_gpio_in(gicdev, intidbase + timer_irqs[j]);
+ qdev_connect_gpio_out(cpudev, j, irq);
+ }
+
+ irq = qdev_get_gpio_in(gicdev, intidbase + ARCH_GIC_MAINT_IRQ);
+ qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
+ 0, irq);
+
+ irq = qdev_get_gpio_in(gicdev, intidbase + VIRTUAL_PMU_IRQ);
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0, irq);
+
+ sysbus_connect_irq(gicsbd, i,
+ qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
+ sysbus_connect_irq(gicsbd, i + ms->smp.cpus,
+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
+ sysbus_connect_irq(gicsbd, i + 2 * ms->smp.cpus,
+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
+ sysbus_connect_irq(gicsbd, i + 3 * ms->smp.cpus,
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
+
+ if (kvm_enabled()) {
+ if (pmu) {
+ assert(arm_feature(&s->cpu[i].env, ARM_FEATURE_PMU));
+ if (kvm_irqchip_in_kernel()) {
+ kvm_arm_pmu_set_irq(&s->cpu[i], VIRTUAL_PMU_IRQ);
+ }
+ kvm_arm_pmu_init(&s->cpu[i]);
+ }
+ }
+ }
+ }
+
+ /* UARTs */
+ for (i = 0; i < FSL_IMX8MM_NUM_UARTS; i++) {
+ static const struct {
+ hwaddr addr;
+ unsigned int irq;
+ } serial_table[FSL_IMX8MM_NUM_UARTS] = {
+ { fsl_imx8mm_memmap[FSL_IMX8MM_UART1].addr, FSL_IMX8MM_UART1_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_UART2].addr, FSL_IMX8MM_UART2_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_UART3].addr, FSL_IMX8MM_UART3_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_UART4].addr, FSL_IMX8MM_UART4_IRQ },
+ };
+
+ qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hd(i));
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->uart[i]), errp)) {
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
+ qdev_get_gpio_in(gicdev, serial_table[i].irq));
+ }
+
+ /* On-Chip RAM */
+ if (!memory_region_init_ram(&s->ocram, OBJECT(dev), "imx8mm.ocram",
+ fsl_imx8mm_memmap[FSL_IMX8MM_OCRAM].size,
+ errp)) {
+ return;
+ }
+ memory_region_add_subregion(get_system_memory(),
+ fsl_imx8mm_memmap[FSL_IMX8MM_OCRAM].addr,
+ &s->ocram);
+
+ /* Unimplemented devices */
+ for (i = 0; i < ARRAY_SIZE(fsl_imx8mm_memmap); i++) {
+ switch (i) {
+ case FSL_IMX8MM_GIC_DIST:
+ case FSL_IMX8MM_GIC_REDIST:
+ case FSL_IMX8MM_RAM:
+ case FSL_IMX8MM_OCRAM:
+ case FSL_IMX8MM_UART1 ... FSL_IMX8MM_UART4:
+ /* device implemented and treated above */
+ break;
+
+ default:
+ create_unimplemented_device(fsl_imx8mm_memmap[i].name,
+ fsl_imx8mm_memmap[i].addr,
+ fsl_imx8mm_memmap[i].size);
+ break;
+ }
+ }
+}
+
+static void fsl_imx8mm_class_init(ObjectClass *oc, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->realize = fsl_imx8mm_realize;
+
+ dc->desc = "i.MX 8MM SoC";
+}
+
+static const TypeInfo fsl_imx8mm_types[] = {
+ {
+ .name = TYPE_FSL_IMX8MM,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(FslImx8mmState),
+ .instance_init = fsl_imx8mm_init,
+ .class_init = fsl_imx8mm_class_init,
+ },
+};
+
+DEFINE_TYPES(fsl_imx8mm_types)
diff --git a/hw/arm/imx8mm-evk.c b/hw/arm/imx8mm-evk.c
new file mode 100644
index 0000000000..0a8cce8866
--- /dev/null
+++ b/hw/arm/imx8mm-evk.c
@@ -0,0 +1,112 @@
+/*
+ * NXP i.MX 8MM Evaluation Kit System Emulation
+ *
+ * Copyright (c) 2025, NXP Semiconductors
+ * Author: Gaurav Sharma <gaurav.sharma_7@nxp.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "system/address-spaces.h"
+#include "hw/arm/boot.h"
+#include "hw/arm/fsl-imx8mm.h"
+#include "hw/arm/machines-qom.h"
+#include "hw/core/boards.h"
+#include "hw/core/qdev-properties.h"
+#include "system/kvm.h"
+#include "system/qtest.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include <libfdt.h>
+
+static void imx8mm_evk_modify_dtb(const struct arm_boot_info *info, void *fdt)
+{
+ int i, offset;
+
+ /* Temporarily disable following nodes until they are implemented */
+ const char *nodes_to_remove[] = {
+ "nxp,imx8mm-fspi",
+ "fsl,imx8mm-mipi-csi",
+ "fsl,imx8mm-mipi-dsim"
+ };
+
+ for (i = 0; i < ARRAY_SIZE(nodes_to_remove); i++) {
+ const char *dev_str = nodes_to_remove[i];
+
+ offset = fdt_node_offset_by_compatible(fdt, -1, dev_str);
+ while (offset >= 0) {
+ fdt_nop_node(fdt, offset);
+ offset = fdt_node_offset_by_compatible(fdt, offset, dev_str);
+ }
+ }
+
+ /* Remove cpu-idle-states property from CPU nodes */
+ offset = fdt_node_offset_by_compatible(fdt, -1, "arm,cortex-a53");
+ while (offset >= 0) {
+ fdt_nop_property(fdt, offset, "cpu-idle-states");
+ offset = fdt_node_offset_by_compatible(fdt, offset, "arm,cortex-a53");
+ }
+
+ if (kvm_enabled()) {
+ /* Use system counter frequency from host CPU to fix time in guest */
+ offset = fdt_node_offset_by_compatible(fdt, -1, "arm,armv8-timer");
+ while (offset >= 0) {
+ fdt_nop_property(fdt, offset, "clock-frequency");
+ offset = fdt_node_offset_by_compatible(fdt, offset, "arm,armv8-timer");
+ }
+ }
+}
+
+static void imx8mm_evk_init(MachineState *machine)
+{
+ static struct arm_boot_info boot_info;
+ FslImx8mmState *s;
+
+ if (machine->ram_size > FSL_IMX8MM_RAM_SIZE_MAX) {
+ error_report("RAM size " RAM_ADDR_FMT " above max supported (%08" PRIx64 ")",
+ machine->ram_size, FSL_IMX8MM_RAM_SIZE_MAX);
+ exit(1);
+ }
+
+ boot_info = (struct arm_boot_info) {
+ .loader_start = FSL_IMX8MM_RAM_START,
+ .board_id = -1,
+ .ram_size = machine->ram_size,
+ .psci_conduit = QEMU_PSCI_CONDUIT_SMC,
+ .modify_dtb = imx8mm_evk_modify_dtb,
+ };
+
+ s = FSL_IMX8MM(object_new_with_props(TYPE_FSL_IMX8MM, OBJECT(machine),
+ "soc", &error_fatal, NULL));
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(s), &error_fatal);
+
+ memory_region_add_subregion(get_system_memory(), FSL_IMX8MM_RAM_START,
+ machine->ram);
+
+ if (!qtest_enabled()) {
+ arm_load_kernel(&s->cpu[0], machine, &boot_info);
+ }
+}
+
+static const char *imx8mm_evk_get_default_cpu_type(const MachineState *ms)
+{
+ if (kvm_enabled()) {
+ return ARM_CPU_TYPE_NAME("host");
+ }
+
+ return ARM_CPU_TYPE_NAME("cortex-a53");
+}
+
+static void imx8mm_evk_machine_init(MachineClass *mc)
+{
+ mc->desc = "NXP i.MX 8MM EVK Board";
+ mc->init = imx8mm_evk_init;
+ mc->max_cpus = FSL_IMX8MM_NUM_CPUS;
+ mc->default_cpus = FSL_IMX8MM_NUM_CPUS;
+ mc->default_ram_size = 2 * GiB;
+ mc->default_ram_id = "imx8mm-evk.ram";
+ mc->get_default_cpu_type = imx8mm_evk_get_default_cpu_type;
+}
+
+DEFINE_MACHINE_AARCH64("imx8mm-evk", imx8mm_evk_machine_init)
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index 3be1252c4f..84b8ec5fb5 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -84,6 +84,8 @@ arm_common_ss.add(when: 'CONFIG_ARMSSE', if_true: files('armsse.c'))
arm_common_ss.add(when: 'CONFIG_FSL_IMX7', if_true: files('fsl-imx7.c', 'mcimx7d-sabre.c'))
arm_common_ss.add(when: 'CONFIG_FSL_IMX8MP', if_true: files('fsl-imx8mp.c'))
arm_common_ss.add(when: 'CONFIG_FSL_IMX8MP_EVK', if_true: files('imx8mp-evk.c'))
+arm_common_ss.add(when: 'CONFIG_FSL_IMX8MM', if_true: files('fsl-imx8mm.c'))
+arm_common_ss.add(when: 'CONFIG_FSL_IMX8MM_EVK', if_true: files('imx8mm-evk.c'))
arm_common_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmuv3.c'))
arm_common_ss.add(when: 'CONFIG_ARM_SMMUV3_ACCEL', if_true: files('smmuv3-accel.c'))
stub_ss.add(files('smmuv3-accel-stubs.c'))
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
new file mode 100644
index 0000000000..2811e809b9
--- /dev/null
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -0,0 +1,158 @@
+/*
+ * i.MX 8MM SoC Definitions
+ *
+ * Copyright (c) 2025, NXP Semiconductors
+ * Author: Gaurav Sharma <gaurav.sharma_7@nxp.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef FSL_IMX8MM_H
+#define FSL_IMX8MM_H
+
+#include "cpu.h"
+#include "hw/char/imx_serial.h"
+#include "hw/intc/arm_gicv3_common.h"
+#include "qom/object.h"
+#include "qemu/units.h"
+
+#define TYPE_FSL_IMX8MM "fsl-imx8mm"
+OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mmState, FSL_IMX8MM)
+
+#define FSL_IMX8MM_RAM_START 0x40000000
+#define FSL_IMX8MM_RAM_SIZE_MAX (4 * GiB)
+
+enum FslImx8mmConfiguration {
+ FSL_IMX8MM_NUM_CPUS = 4,
+ FSL_IMX8MM_NUM_IRQS = 128,
+ FSL_IMX8MM_NUM_UARTS = 4,
+};
+
+struct FslImx8mmState {
+ SysBusDevice parent_obj;
+
+ ARMCPU cpu[FSL_IMX8MM_NUM_CPUS];
+ GICv3State gic;
+ IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
+ MemoryRegion ocram;
+};
+
+enum FslImx8mmMemoryRegions {
+ FSL_IMX8MM_A53_DAP,
+ FSL_IMX8MM_AIPS1_CONFIGURATION,
+ FSL_IMX8MM_AIPS2_CONFIGURATION,
+ FSL_IMX8MM_AIPS3_CONFIGURATION,
+ FSL_IMX8MM_AIPS4_CONFIGURATION,
+ FSL_IMX8MM_ANA_OSC,
+ FSL_IMX8MM_ANA_PLL,
+ FSL_IMX8MM_ANA_TSENSOR,
+ FSL_IMX8MM_APBH_DMA,
+ FSL_IMX8MM_BOOT_ROM,
+ FSL_IMX8MM_BOOT_ROM_PROTECTED,
+ FSL_IMX8MM_CAAM,
+ FSL_IMX8MM_CAAM_MEM,
+ FSL_IMX8MM_CCM,
+ FSL_IMX8MM_CSU,
+ FSL_IMX8MM_DDR_CTL,
+ FSL_IMX8MM_DDR_PERF_MON,
+ FSL_IMX8MM_DDR_PHY,
+ FSL_IMX8MM_DDR_PHY_BROADCAST,
+ FSL_IMX8MM_ECSPI1,
+ FSL_IMX8MM_ECSPI2,
+ FSL_IMX8MM_ECSPI3,
+ FSL_IMX8MM_ENET1,
+ FSL_IMX8MM_GIC_DIST,
+ FSL_IMX8MM_GIC_REDIST,
+ FSL_IMX8MM_GPC,
+ FSL_IMX8MM_GPIO1,
+ FSL_IMX8MM_GPIO2,
+ FSL_IMX8MM_GPIO3,
+ FSL_IMX8MM_GPIO4,
+ FSL_IMX8MM_GPIO5,
+ FSL_IMX8MM_GPT1,
+ FSL_IMX8MM_GPT2,
+ FSL_IMX8MM_GPT3,
+ FSL_IMX8MM_GPT4,
+ FSL_IMX8MM_GPT5,
+ FSL_IMX8MM_GPT6,
+ FSL_IMX8MM_GPU2D,
+ FSL_IMX8MM_I2C1,
+ FSL_IMX8MM_I2C2,
+ FSL_IMX8MM_I2C3,
+ FSL_IMX8MM_I2C4,
+ FSL_IMX8MM_INTERCONNECT,
+ FSL_IMX8MM_IOMUXC,
+ FSL_IMX8MM_IOMUXC_GPR,
+ FSL_IMX8MM_MEDIA_BLK_CTL,
+ FSL_IMX8MM_LCDIF,
+ FSL_IMX8MM_MIPI_CSI,
+ FSL_IMX8MM_MIPI_DSI,
+ FSL_IMX8MM_MU_A,
+ FSL_IMX8MM_MU_B,
+ FSL_IMX8MM_OCOTP_CTRL,
+ FSL_IMX8MM_OCRAM,
+ FSL_IMX8MM_OCRAM_S,
+ FSL_IMX8MM_PCIE1,
+ FSL_IMX8MM_PCIE1_MEM,
+ FSL_IMX8MM_PCIE_PHY1,
+ FSL_IMX8MM_PERFMON1,
+ FSL_IMX8MM_PERFMON2,
+ FSL_IMX8MM_PWM1,
+ FSL_IMX8MM_PWM2,
+ FSL_IMX8MM_PWM3,
+ FSL_IMX8MM_PWM4,
+ FSL_IMX8MM_QOSC,
+ FSL_IMX8MM_QSPI,
+ FSL_IMX8MM_QSPI1_RX_BUFFER,
+ FSL_IMX8MM_QSPI1_TX_BUFFER,
+ FSL_IMX8MM_QSPI_MEM,
+ FSL_IMX8MM_RAM,
+ FSL_IMX8MM_RDC,
+ FSL_IMX8MM_SAI1,
+ FSL_IMX8MM_SAI2,
+ FSL_IMX8MM_SAI3,
+ FSL_IMX8MM_SAI5,
+ FSL_IMX8MM_SAI6,
+ FSL_IMX8MM_SDMA1,
+ FSL_IMX8MM_SDMA2,
+ FSL_IMX8MM_SDMA3,
+ FSL_IMX8MM_SEMAPHORE1,
+ FSL_IMX8MM_SEMAPHORE2,
+ FSL_IMX8MM_SEMAPHORE_HS,
+ FSL_IMX8MM_SNVS_HP,
+ FSL_IMX8MM_SPBA1,
+ FSL_IMX8MM_SRC,
+ FSL_IMX8MM_SYSCNT_CMP,
+ FSL_IMX8MM_SYSCNT_CTRL,
+ FSL_IMX8MM_SYSCNT_RD,
+ FSL_IMX8MM_TCM_DTCM,
+ FSL_IMX8MM_TCM_ITCM,
+ FSL_IMX8MM_TZASC,
+ FSL_IMX8MM_UART1,
+ FSL_IMX8MM_UART2,
+ FSL_IMX8MM_UART3,
+ FSL_IMX8MM_UART4,
+ FSL_IMX8MM_USB1,
+ FSL_IMX8MM_USB2,
+ FSL_IMX8MM_USB1_OTG,
+ FSL_IMX8MM_USB2_OTG,
+ FSL_IMX8MM_USDHC1,
+ FSL_IMX8MM_USDHC2,
+ FSL_IMX8MM_USDHC3,
+ FSL_IMX8MM_VPU,
+ FSL_IMX8MM_VPU_BLK_CTRL,
+ FSL_IMX8MM_VPU_G1_DECODER,
+ FSL_IMX8MM_VPU_G2_DECODER,
+ FSL_IMX8MM_WDOG1,
+ FSL_IMX8MM_WDOG2,
+ FSL_IMX8MM_WDOG3,
+};
+
+enum FslImx8mmIrqs {
+ FSL_IMX8MM_UART1_IRQ = 26,
+ FSL_IMX8MM_UART2_IRQ = 27,
+ FSL_IMX8MM_UART3_IRQ = 28,
+ FSL_IMX8MM_UART4_IRQ = 29,
+};
+
+#endif /* FSL_IMX8MM_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 03/63] hw/misc/imx8mp_analog: Add property to analog device
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
2026-04-27 12:46 ` [PULL 01/63] docs/system: add FEAT_AA32 and FEAT_AA64 to emulation list Peter Maydell
2026-04-27 12:46 ` [PULL 02/63] hw/arm: Add the i.MX 8MM EVK(Evaluation Kit) board Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 04/63] hw/arm/fsl-imx8mm: Add Analog device IP to iMX8MM SOC Peter Maydell
` (60 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Add configurable properties for register reset values that differ
between i.MX 8M variants (Plus, Mini, etc.). This allows the same
device implementation to be shared across multiple SoCs.
Properties added:
- arm-pll-fdiv-ctl0-reset: ARM PLL divider control reset value
Default value is set to match i.MX 8MP reset value (0x000FA031).
This can be overridden in the variant like iMX8MM with its own
reset value.
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/misc/imx8mp_analog.c | 12 +++++++++++-
include/hw/misc/imx8mp_analog.h | 3 +++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/hw/misc/imx8mp_analog.c b/hw/misc/imx8mp_analog.c
index 23ffae84f8..592512071c 100644
--- a/hw/misc/imx8mp_analog.c
+++ b/hw/misc/imx8mp_analog.c
@@ -12,6 +12,7 @@
#include "qemu/log.h"
#include "hw/misc/imx8mp_analog.h"
+#include "hw/core/qdev-properties.h"
#include "migration/vmstate.h"
#define ANALOG_PLL_LOCK BIT(31)
@@ -51,7 +52,10 @@ static void imx8mp_analog_reset(DeviceState *dev)
s->analog[ANALOG_VPU_PLL_LOCKD_CTRL] = 0x0010003f;
s->analog[ANALOG_VPU_PLL_MNIT_CTRL] = 0x00280081;
s->analog[ANALOG_ARM_PLL_GEN_CTRL] = 0x00000810;
- s->analog[ANALOG_ARM_PLL_FDIV_CTL0] = 0x000fa031;
+
+ /* Use property value instead of hardcoded */
+ s->analog[ANALOG_ARM_PLL_FDIV_CTL0] = s->arm_pll_fdiv_ctl0_reset;
+
s->analog[ANALOG_ARM_PLL_LOCKD_CTRL] = 0x0010003f;
s->analog[ANALOG_ARM_PLL_MNIT_CTRL] = 0x00280081;
s->analog[ANALOG_SYS_PLL1_GEN_CTRL] = 0x0aaaa810;
@@ -138,11 +142,17 @@ static const VMStateDescription imx8mp_analog_vmstate = {
},
};
+static const Property imx8mp_analog_properties[] = {
+ DEFINE_PROP_UINT32("arm-pll-fdiv-ctl0-reset", IMX8MPAnalogState,
+ arm_pll_fdiv_ctl0_reset, 0x000fa031), /* imx8mp default */
+};
+
static void imx8mp_analog_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
device_class_set_legacy_reset(dc, imx8mp_analog_reset);
+ device_class_set_props(dc, imx8mp_analog_properties);
dc->vmsd = &imx8mp_analog_vmstate;
dc->desc = "i.MX 8M Plus Analog Module";
}
diff --git a/include/hw/misc/imx8mp_analog.h b/include/hw/misc/imx8mp_analog.h
index 6996e53771..0765e607b9 100644
--- a/include/hw/misc/imx8mp_analog.h
+++ b/include/hw/misc/imx8mp_analog.h
@@ -76,6 +76,9 @@ struct IMX8MPAnalogState {
} mmio;
uint32_t analog[ANALOG_MAX];
+
+ /* Property for variant-specific reset values */
+ uint32_t arm_pll_fdiv_ctl0_reset;
};
#endif /* IMX8MP_ANALOG_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 04/63] hw/arm/fsl-imx8mm: Add Analog device IP to iMX8MM SOC
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (2 preceding siblings ...)
2026-04-27 12:46 ` [PULL 03/63] hw/misc/imx8mp_analog: Add property to analog device Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 05/63] hw/arm/fsl-imx8mm: Add Clock Control Module IP to iMX8MM Peter Maydell
` (59 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Add the Analog IP to i.MX8MM SoC. iMX8MM and i.MX8MP uses
the same Analog IP so the analog ip source will be shared.
The ARM PLL divider control register (arm-pll-fdiv-ctl0) has
a different reset value on i.MX8MM (0x000fa030) compared to
i.MX8MP (0x000fa031). So iMX8MM will be overriding this property
with its own reset-value.
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/Kconfig | 1 +
hw/arm/fsl-imx8mm.c | 12 ++++++++++++
include/hw/arm/fsl-imx8mm.h | 2 ++
3 files changed, 15 insertions(+)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 86f4d9bc4d..b3db2d6848 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -620,6 +620,7 @@ config FSL_IMX8MP_EVK
config FSL_IMX8MM
bool
select ARM_GIC
+ select FSL_IMX8MP_ANALOG
select IMX
config FSL_IMX8MM_EVK
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 23a82613d7..8218448074 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -169,6 +169,8 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, "gic", &s->gic, gicv3_class_name());
+ object_initialize_child(obj, "analog", &s->analog, TYPE_IMX8MP_ANALOG);
+
for (i = 0; i < FSL_IMX8MM_NUM_UARTS; i++) {
g_autofree char *name = g_strdup_printf("uart%d", i + 1);
object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
@@ -303,6 +305,15 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
}
}
+ /* Analog */
+ object_property_set_uint(OBJECT(&s->analog), "arm-pll-fdiv-ctl0-reset",
+ 0x000fa030, &error_abort);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->analog), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->analog), 0,
+ fsl_imx8mm_memmap[FSL_IMX8MM_ANA_PLL].addr);
+
/* UARTs */
for (i = 0; i < FSL_IMX8MM_NUM_UARTS; i++) {
static const struct {
@@ -338,6 +349,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
/* Unimplemented devices */
for (i = 0; i < ARRAY_SIZE(fsl_imx8mm_memmap); i++) {
switch (i) {
+ case FSL_IMX8MM_ANA_PLL:
case FSL_IMX8MM_GIC_DIST:
case FSL_IMX8MM_GIC_REDIST:
case FSL_IMX8MM_RAM:
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 2811e809b9..0a020c32a1 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -13,6 +13,7 @@
#include "cpu.h"
#include "hw/char/imx_serial.h"
#include "hw/intc/arm_gicv3_common.h"
+#include "hw/misc/imx8mp_analog.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -33,6 +34,7 @@ struct FslImx8mmState {
ARMCPU cpu[FSL_IMX8MM_NUM_CPUS];
GICv3State gic;
+ IMX8MPAnalogState analog;
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
MemoryRegion ocram;
};
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 05/63] hw/arm/fsl-imx8mm: Add Clock Control Module IP to iMX8MM
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (3 preceding siblings ...)
2026-04-27 12:46 ` [PULL 04/63] hw/arm/fsl-imx8mm: Add Analog device IP to iMX8MM SOC Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 06/63] hw/arm/fsl-imx8mm: Implemented support for SNVS Peter Maydell
` (58 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Add the Clock Control Module (CCM) device to i.MX8MM SoC.
The CCM implementation is shared with i.MX8MP as the register
layout is identical between the two variants.Hence iMX8MM will
be using the source of iMX8MP CCM.
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/Kconfig | 1 +
hw/arm/fsl-imx8mm.c | 10 ++++++++++
include/hw/arm/fsl-imx8mm.h | 2 ++
3 files changed, 13 insertions(+)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index b3db2d6848..26dc3e6ed1 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -621,6 +621,7 @@ config FSL_IMX8MM
bool
select ARM_GIC
select FSL_IMX8MP_ANALOG
+ select FSL_IMX8MP_CCM
select IMX
config FSL_IMX8MM_EVK
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 8218448074..053434412c 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -169,6 +169,8 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, "gic", &s->gic, gicv3_class_name());
+ object_initialize_child(obj, "ccm", &s->ccm, TYPE_IMX8MP_CCM);
+
object_initialize_child(obj, "analog", &s->analog, TYPE_IMX8MP_ANALOG);
for (i = 0; i < FSL_IMX8MM_NUM_UARTS; i++) {
@@ -305,6 +307,13 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
}
}
+ /* CCM */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->ccm), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0,
+ fsl_imx8mm_memmap[FSL_IMX8MM_CCM].addr);
+
/* Analog */
object_property_set_uint(OBJECT(&s->analog), "arm-pll-fdiv-ctl0-reset",
0x000fa030, &error_abort);
@@ -350,6 +359,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
for (i = 0; i < ARRAY_SIZE(fsl_imx8mm_memmap); i++) {
switch (i) {
case FSL_IMX8MM_ANA_PLL:
+ case FSL_IMX8MM_CCM:
case FSL_IMX8MM_GIC_DIST:
case FSL_IMX8MM_GIC_REDIST:
case FSL_IMX8MM_RAM:
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 0a020c32a1..df35f0f5ac 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -14,6 +14,7 @@
#include "hw/char/imx_serial.h"
#include "hw/intc/arm_gicv3_common.h"
#include "hw/misc/imx8mp_analog.h"
+#include "hw/misc/imx8mp_ccm.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -34,6 +35,7 @@ struct FslImx8mmState {
ARMCPU cpu[FSL_IMX8MM_NUM_CPUS];
GICv3State gic;
+ IMX8MPCCMState ccm;
IMX8MPAnalogState analog;
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
MemoryRegion ocram;
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 06/63] hw/arm/fsl-imx8mm: Implemented support for SNVS
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (4 preceding siblings ...)
2026-04-27 12:46 ` [PULL 05/63] hw/arm/fsl-imx8mm: Add Clock Control Module IP to iMX8MM Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 07/63] hw/arm/fsl-imx8mm: Adding support for USDHC storage controllers Peter Maydell
` (57 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Gaurav Sharma <gaurav.sharma_7@nxp.com>
SNVS contains an RTC which allows Linux to deal correctly with time
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/fsl-imx8mm.c | 10 ++++++++++
include/hw/arm/fsl-imx8mm.h | 2 ++
2 files changed, 12 insertions(+)
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 053434412c..8999bc701e 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -173,6 +173,8 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, "analog", &s->analog, TYPE_IMX8MP_ANALOG);
+ object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
+
for (i = 0; i < FSL_IMX8MM_NUM_UARTS; i++) {
g_autofree char *name = g_strdup_printf("uart%d", i + 1);
object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
@@ -355,6 +357,13 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
fsl_imx8mm_memmap[FSL_IMX8MM_OCRAM].addr,
&s->ocram);
+ /* SNVS */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->snvs), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0,
+ fsl_imx8mm_memmap[FSL_IMX8MM_SNVS_HP].addr);
+
/* Unimplemented devices */
for (i = 0; i < ARRAY_SIZE(fsl_imx8mm_memmap); i++) {
switch (i) {
@@ -364,6 +373,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_GIC_REDIST:
case FSL_IMX8MM_RAM:
case FSL_IMX8MM_OCRAM:
+ case FSL_IMX8MM_SNVS_HP:
case FSL_IMX8MM_UART1 ... FSL_IMX8MM_UART4:
/* device implemented and treated above */
break;
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index df35f0f5ac..8a172b89e0 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -13,6 +13,7 @@
#include "cpu.h"
#include "hw/char/imx_serial.h"
#include "hw/intc/arm_gicv3_common.h"
+#include "hw/misc/imx7_snvs.h"
#include "hw/misc/imx8mp_analog.h"
#include "hw/misc/imx8mp_ccm.h"
#include "qom/object.h"
@@ -37,6 +38,7 @@ struct FslImx8mmState {
GICv3State gic;
IMX8MPCCMState ccm;
IMX8MPAnalogState analog;
+ IMX7SNVSState snvs;
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
MemoryRegion ocram;
};
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 07/63] hw/arm/fsl-imx8mm: Adding support for USDHC storage controllers
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (5 preceding siblings ...)
2026-04-27 12:46 ` [PULL 06/63] hw/arm/fsl-imx8mm: Implemented support for SNVS Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 08/63] hw/arm/fsl-imx8mm: Add PCIe support Peter Maydell
` (56 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Gaurav Sharma <gaurav.sharma_7@nxp.com>
It enables emulation of SD/MMC cards through a virtual SDHCI interface
The emulated SDHCI controller allows guest OS to use emulated storage as
a standard block device.
This will allow running the images such as those generated
by Buildroot.
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/Kconfig | 1 +
hw/arm/fsl-imx8mm.c | 25 +++++++++++++++++++++++++
hw/arm/imx8mm-evk.c | 17 +++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 7 +++++++
4 files changed, 50 insertions(+)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 26dc3e6ed1..74e8c431a2 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -623,6 +623,7 @@ config FSL_IMX8MM
select FSL_IMX8MP_ANALOG
select FSL_IMX8MP_CCM
select IMX
+ select SDHCI
config FSL_IMX8MM_EVK
bool
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 8999bc701e..2a4d4d5e6d 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -180,6 +180,10 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
}
+ for (i = 0; i < FSL_IMX8MM_NUM_USDHCS; i++) {
+ g_autofree char *name = g_strdup_printf("usdhc%d", i + 1);
+ object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
+ }
}
static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
@@ -357,6 +361,26 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
fsl_imx8mm_memmap[FSL_IMX8MM_OCRAM].addr,
&s->ocram);
+ /* USDHCs */
+ for (i = 0; i < FSL_IMX8MM_NUM_USDHCS; i++) {
+ static const struct {
+ hwaddr addr;
+ unsigned int irq;
+ } usdhc_table[FSL_IMX8MM_NUM_USDHCS] = {
+ { fsl_imx8mm_memmap[FSL_IMX8MM_USDHC1].addr, FSL_IMX8MM_USDHC1_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_USDHC2].addr, FSL_IMX8MM_USDHC2_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_USDHC3].addr, FSL_IMX8MM_USDHC3_IRQ },
+ };
+
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->usdhc[i]), errp)) {
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0, usdhc_table[i].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
+ qdev_get_gpio_in(gicdev, usdhc_table[i].irq));
+ }
+
/* SNVS */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->snvs), errp)) {
return;
@@ -375,6 +399,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_OCRAM:
case FSL_IMX8MM_SNVS_HP:
case FSL_IMX8MM_UART1 ... FSL_IMX8MM_UART4:
+ case FSL_IMX8MM_USDHC1 ... FSL_IMX8MM_USDHC3:
/* device implemented and treated above */
break;
diff --git a/hw/arm/imx8mm-evk.c b/hw/arm/imx8mm-evk.c
index 0a8cce8866..dfdf3cd4f8 100644
--- a/hw/arm/imx8mm-evk.c
+++ b/hw/arm/imx8mm-evk.c
@@ -84,6 +84,23 @@ static void imx8mm_evk_init(MachineState *machine)
memory_region_add_subregion(get_system_memory(), FSL_IMX8MM_RAM_START,
machine->ram);
+ for (int i = 0; i < FSL_IMX8MM_NUM_USDHCS; i++) {
+ BusState *bus;
+ DeviceState *carddev;
+ BlockBackend *blk;
+ DriveInfo *di = drive_get(IF_SD, i, 0);
+
+ if (!di) {
+ continue;
+ }
+
+ blk = blk_by_legacy_dinfo(di);
+ bus = qdev_get_child_bus(DEVICE(&s->usdhc[i]), "sd-bus");
+ carddev = qdev_new(TYPE_SD_CARD);
+ qdev_prop_set_drive_err(carddev, "drive", blk, &error_fatal);
+ qdev_realize_and_unref(carddev, bus, &error_fatal);
+ }
+
if (!qtest_enabled()) {
arm_load_kernel(&s->cpu[0], machine, &boot_info);
}
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 8a172b89e0..93a30a2f55 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -16,6 +16,7 @@
#include "hw/misc/imx7_snvs.h"
#include "hw/misc/imx8mp_analog.h"
#include "hw/misc/imx8mp_ccm.h"
+#include "hw/sd/sdhci.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -29,6 +30,7 @@ enum FslImx8mmConfiguration {
FSL_IMX8MM_NUM_CPUS = 4,
FSL_IMX8MM_NUM_IRQS = 128,
FSL_IMX8MM_NUM_UARTS = 4,
+ FSL_IMX8MM_NUM_USDHCS = 3,
};
struct FslImx8mmState {
@@ -41,6 +43,7 @@ struct FslImx8mmState {
IMX7SNVSState snvs;
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
MemoryRegion ocram;
+ SDHCIState usdhc[FSL_IMX8MM_NUM_USDHCS];
};
enum FslImx8mmMemoryRegions {
@@ -155,6 +158,10 @@ enum FslImx8mmMemoryRegions {
};
enum FslImx8mmIrqs {
+ FSL_IMX8MM_USDHC1_IRQ = 22,
+ FSL_IMX8MM_USDHC2_IRQ = 23,
+ FSL_IMX8MM_USDHC3_IRQ = 24,
+
FSL_IMX8MM_UART1_IRQ = 26,
FSL_IMX8MM_UART2_IRQ = 27,
FSL_IMX8MM_UART3_IRQ = 28,
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 08/63] hw/arm/fsl-imx8mm: Add PCIe support
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (6 preceding siblings ...)
2026-04-27 12:46 ` [PULL 07/63] hw/arm/fsl-imx8mm: Adding support for USDHC storage controllers Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 09/63] hw/arm/fsl-imx8mm: Add GPIO controllers Peter Maydell
` (55 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Gaurav Sharma <gaurav.sharma_7@nxp.com>
This enables support for Designware PCI Express Controller emulation
It provides a controlled environment to debug the linux pci subsystem
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/Kconfig | 3 +++
hw/arm/fsl-imx8mm.c | 30 ++++++++++++++++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 10 ++++++++++
3 files changed, 43 insertions(+)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 74e8c431a2..59d5aba2db 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -619,11 +619,14 @@ config FSL_IMX8MP_EVK
config FSL_IMX8MM
bool
+ imply PCI_DEVICES
select ARM_GIC
select FSL_IMX8MP_ANALOG
select FSL_IMX8MP_CCM
select IMX
select SDHCI
+ select PCI_EXPRESS_DESIGNWARE
+ select PCI_EXPRESS_FSL_IMX8M_PHY
config FSL_IMX8MM_EVK
bool
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 2a4d4d5e6d..633b121630 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -184,6 +184,10 @@ static void fsl_imx8mm_init(Object *obj)
g_autofree char *name = g_strdup_printf("usdhc%d", i + 1);
object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
}
+
+ object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
+ object_initialize_child(obj, "pcie_phy", &s->pcie_phy,
+ TYPE_FSL_IMX8M_PCIE_PHY);
}
static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
@@ -388,6 +392,30 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0,
fsl_imx8mm_memmap[FSL_IMX8MM_SNVS_HP].addr);
+ /* PCIe */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->pcie), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0,
+ fsl_imx8mm_memmap[FSL_IMX8MM_PCIE1].addr);
+
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0,
+ qdev_get_gpio_in(gicdev, FSL_IMX8MM_PCI_INTA_IRQ));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1,
+ qdev_get_gpio_in(gicdev, FSL_IMX8MM_PCI_INTB_IRQ));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2,
+ qdev_get_gpio_in(gicdev, FSL_IMX8MM_PCI_INTC_IRQ));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3,
+ qdev_get_gpio_in(gicdev, FSL_IMX8MM_PCI_INTD_IRQ));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 4,
+ qdev_get_gpio_in(gicdev, FSL_IMX8MM_PCI_MSI_IRQ));
+
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->pcie_phy), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie_phy), 0,
+ fsl_imx8mm_memmap[FSL_IMX8MM_PCIE_PHY1].addr);
+
/* Unimplemented devices */
for (i = 0; i < ARRAY_SIZE(fsl_imx8mm_memmap); i++) {
switch (i) {
@@ -395,6 +423,8 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_CCM:
case FSL_IMX8MM_GIC_DIST:
case FSL_IMX8MM_GIC_REDIST:
+ case FSL_IMX8MM_PCIE1:
+ case FSL_IMX8MM_PCIE_PHY1:
case FSL_IMX8MM_RAM:
case FSL_IMX8MM_OCRAM:
case FSL_IMX8MM_SNVS_HP:
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 93a30a2f55..3181c02574 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -16,6 +16,8 @@
#include "hw/misc/imx7_snvs.h"
#include "hw/misc/imx8mp_analog.h"
#include "hw/misc/imx8mp_ccm.h"
+#include "hw/pci-host/designware.h"
+#include "hw/pci-host/fsl_imx8m_phy.h"
#include "hw/sd/sdhci.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -44,6 +46,8 @@ struct FslImx8mmState {
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
MemoryRegion ocram;
SDHCIState usdhc[FSL_IMX8MM_NUM_USDHCS];
+ DesignwarePCIEHost pcie;
+ FslImx8mPciePhyState pcie_phy;
};
enum FslImx8mmMemoryRegions {
@@ -166,6 +170,12 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_UART2_IRQ = 27,
FSL_IMX8MM_UART3_IRQ = 28,
FSL_IMX8MM_UART4_IRQ = 29,
+
+ FSL_IMX8MM_PCI_INTA_IRQ = 122,
+ FSL_IMX8MM_PCI_INTB_IRQ = 123,
+ FSL_IMX8MM_PCI_INTC_IRQ = 124,
+ FSL_IMX8MM_PCI_INTD_IRQ = 125,
+ FSL_IMX8MM_PCI_MSI_IRQ = 127,
};
#endif /* FSL_IMX8MM_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 09/63] hw/arm/fsl-imx8mm: Add GPIO controllers
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (7 preceding siblings ...)
2026-04-27 12:46 ` [PULL 08/63] hw/arm/fsl-imx8mm: Add PCIe support Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 10/63] hw/arm/fsl-imx8mm: Adding support for I2C emulation Peter Maydell
` (54 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Enabled GPIO controller emulation
Also updated the GPIO IRQ lines of iMX8MM
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/fsl-imx8mm.c | 54 +++++++++++++++++++++++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 14 ++++++++++
2 files changed, 68 insertions(+)
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 633b121630..85bce5a788 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -180,6 +180,11 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
}
+ for (i = 0; i < FSL_IMX8MM_NUM_GPIOS; i++) {
+ g_autofree char *name = g_strdup_printf("gpio%d", i + 1);
+ object_initialize_child(obj, name, &s->gpio[i], TYPE_IMX_GPIO);
+ }
+
for (i = 0; i < FSL_IMX8MM_NUM_USDHCS; i++) {
g_autofree char *name = g_strdup_printf("usdhc%d", i + 1);
object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
@@ -365,6 +370,54 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
fsl_imx8mm_memmap[FSL_IMX8MM_OCRAM].addr,
&s->ocram);
+ /* GPIOs */
+ for (i = 0; i < FSL_IMX8MM_NUM_GPIOS; i++) {
+ static const struct {
+ hwaddr addr;
+ unsigned int irq_low;
+ unsigned int irq_high;
+ } gpio_table[FSL_IMX8MM_NUM_GPIOS] = {
+ {
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPIO1].addr,
+ FSL_IMX8MM_GPIO1_LOW_IRQ,
+ FSL_IMX8MM_GPIO1_HIGH_IRQ
+ },
+ {
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPIO2].addr,
+ FSL_IMX8MM_GPIO2_LOW_IRQ,
+ FSL_IMX8MM_GPIO2_HIGH_IRQ
+ },
+ {
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPIO3].addr,
+ FSL_IMX8MM_GPIO3_LOW_IRQ,
+ FSL_IMX8MM_GPIO3_HIGH_IRQ
+ },
+ {
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPIO4].addr,
+ FSL_IMX8MM_GPIO4_LOW_IRQ,
+ FSL_IMX8MM_GPIO4_HIGH_IRQ
+ },
+ {
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPIO5].addr,
+ FSL_IMX8MM_GPIO5_LOW_IRQ,
+ FSL_IMX8MM_GPIO5_HIGH_IRQ
+ },
+ };
+ object_property_set_bool(OBJECT(&s->gpio[i]), "has-edge-sel", true,
+ &error_abort);
+ object_property_set_bool(OBJECT(&s->gpio[i]), "has-upper-pin-irq",
+ true, &error_abort);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio[i]), errp)) {
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
+ qdev_get_gpio_in(gicdev, gpio_table[i].irq_low));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
+ qdev_get_gpio_in(gicdev, gpio_table[i].irq_high));
+ }
+
/* USDHCs */
for (i = 0; i < FSL_IMX8MM_NUM_USDHCS; i++) {
static const struct {
@@ -423,6 +476,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_CCM:
case FSL_IMX8MM_GIC_DIST:
case FSL_IMX8MM_GIC_REDIST:
+ case FSL_IMX8MM_GPIO1 ... FSL_IMX8MM_GPIO5:
case FSL_IMX8MM_PCIE1:
case FSL_IMX8MM_PCIE_PHY1:
case FSL_IMX8MM_RAM:
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 3181c02574..4fe27b9575 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -12,6 +12,7 @@
#include "cpu.h"
#include "hw/char/imx_serial.h"
+#include "hw/gpio/imx_gpio.h"
#include "hw/intc/arm_gicv3_common.h"
#include "hw/misc/imx7_snvs.h"
#include "hw/misc/imx8mp_analog.h"
@@ -30,6 +31,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mmState, FSL_IMX8MM)
enum FslImx8mmConfiguration {
FSL_IMX8MM_NUM_CPUS = 4,
+ FSL_IMX8MM_NUM_GPIOS = 5,
FSL_IMX8MM_NUM_IRQS = 128,
FSL_IMX8MM_NUM_UARTS = 4,
FSL_IMX8MM_NUM_USDHCS = 3,
@@ -40,6 +42,7 @@ struct FslImx8mmState {
ARMCPU cpu[FSL_IMX8MM_NUM_CPUS];
GICv3State gic;
+ IMXGPIOState gpio[FSL_IMX8MM_NUM_GPIOS];
IMX8MPCCMState ccm;
IMX8MPAnalogState analog;
IMX7SNVSState snvs;
@@ -171,6 +174,17 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_UART3_IRQ = 28,
FSL_IMX8MM_UART4_IRQ = 29,
+ FSL_IMX8MM_GPIO1_LOW_IRQ = 64,
+ FSL_IMX8MM_GPIO1_HIGH_IRQ = 65,
+ FSL_IMX8MM_GPIO2_LOW_IRQ = 66,
+ FSL_IMX8MM_GPIO2_HIGH_IRQ = 67,
+ FSL_IMX8MM_GPIO3_LOW_IRQ = 68,
+ FSL_IMX8MM_GPIO3_HIGH_IRQ = 69,
+ FSL_IMX8MM_GPIO4_LOW_IRQ = 70,
+ FSL_IMX8MM_GPIO4_HIGH_IRQ = 71,
+ FSL_IMX8MM_GPIO5_LOW_IRQ = 72,
+ FSL_IMX8MM_GPIO5_HIGH_IRQ = 73,
+
FSL_IMX8MM_PCI_INTA_IRQ = 122,
FSL_IMX8MM_PCI_INTB_IRQ = 123,
FSL_IMX8MM_PCI_INTC_IRQ = 124,
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 10/63] hw/arm/fsl-imx8mm: Adding support for I2C emulation
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (8 preceding siblings ...)
2026-04-27 12:46 ` [PULL 09/63] hw/arm/fsl-imx8mm: Add GPIO controllers Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 11/63] hw/arm/fsl-imx8mm: Adding support for SPI controller Peter Maydell
` (53 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Gaurav Sharma <gaurav.sharma_7@nxp.com>
This can be used to test and debug I2C device drivers.
Added I2C interrupts
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/Kconfig | 2 ++
hw/arm/fsl-imx8mm.c | 27 +++++++++++++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 8 ++++++++
3 files changed, 37 insertions(+)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 59d5aba2db..e8296f9a28 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -620,10 +620,12 @@ config FSL_IMX8MP_EVK
config FSL_IMX8MM
bool
imply PCI_DEVICES
+ imply I2C_DEVICES
select ARM_GIC
select FSL_IMX8MP_ANALOG
select FSL_IMX8MP_CCM
select IMX
+ select IMX_I2C
select SDHCI
select PCI_EXPRESS_DESIGNWARE
select PCI_EXPRESS_FSL_IMX8M_PHY
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 85bce5a788..3632d85197 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -180,6 +180,11 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
}
+ for (i = 0; i < FSL_IMX8MM_NUM_I2CS; i++) {
+ g_autofree char *name = g_strdup_printf("i2c%d", i + 1);
+ object_initialize_child(obj, name, &s->i2c[i], TYPE_IMX_I2C);
+ }
+
for (i = 0; i < FSL_IMX8MM_NUM_GPIOS; i++) {
g_autofree char *name = g_strdup_printf("gpio%d", i + 1);
object_initialize_child(obj, name, &s->gpio[i], TYPE_IMX_GPIO);
@@ -370,6 +375,27 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
fsl_imx8mm_memmap[FSL_IMX8MM_OCRAM].addr,
&s->ocram);
+ /* I2Cs */
+ for (i = 0; i < FSL_IMX8MM_NUM_I2CS; i++) {
+ static const struct {
+ hwaddr addr;
+ unsigned int irq;
+ } i2c_table[FSL_IMX8MM_NUM_I2CS] = {
+ { fsl_imx8mm_memmap[FSL_IMX8MM_I2C1].addr, FSL_IMX8MM_I2C1_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_I2C2].addr, FSL_IMX8MM_I2C2_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_I2C3].addr, FSL_IMX8MM_I2C3_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_I2C4].addr, FSL_IMX8MM_I2C4_IRQ },
+ };
+
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c[i]), errp)) {
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
+ qdev_get_gpio_in(gicdev, i2c_table[i].irq));
+ }
+
/* GPIOs */
for (i = 0; i < FSL_IMX8MM_NUM_GPIOS; i++) {
static const struct {
@@ -477,6 +503,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_GIC_DIST:
case FSL_IMX8MM_GIC_REDIST:
case FSL_IMX8MM_GPIO1 ... FSL_IMX8MM_GPIO5:
+ case FSL_IMX8MM_I2C1 ... FSL_IMX8MM_I2C4:
case FSL_IMX8MM_PCIE1:
case FSL_IMX8MM_PCIE_PHY1:
case FSL_IMX8MM_RAM:
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 4fe27b9575..d6df16e9d4 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -13,6 +13,7 @@
#include "cpu.h"
#include "hw/char/imx_serial.h"
#include "hw/gpio/imx_gpio.h"
+#include "hw/i2c/imx_i2c.h"
#include "hw/intc/arm_gicv3_common.h"
#include "hw/misc/imx7_snvs.h"
#include "hw/misc/imx8mp_analog.h"
@@ -32,6 +33,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mmState, FSL_IMX8MM)
enum FslImx8mmConfiguration {
FSL_IMX8MM_NUM_CPUS = 4,
FSL_IMX8MM_NUM_GPIOS = 5,
+ FSL_IMX8MM_NUM_I2CS = 4,
FSL_IMX8MM_NUM_IRQS = 128,
FSL_IMX8MM_NUM_UARTS = 4,
FSL_IMX8MM_NUM_USDHCS = 3,
@@ -46,6 +48,7 @@ struct FslImx8mmState {
IMX8MPCCMState ccm;
IMX8MPAnalogState analog;
IMX7SNVSState snvs;
+ IMXI2CState i2c[FSL_IMX8MM_NUM_I2CS];
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
MemoryRegion ocram;
SDHCIState usdhc[FSL_IMX8MM_NUM_USDHCS];
@@ -174,6 +177,11 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_UART3_IRQ = 28,
FSL_IMX8MM_UART4_IRQ = 29,
+ FSL_IMX8MM_I2C1_IRQ = 35,
+ FSL_IMX8MM_I2C2_IRQ = 36,
+ FSL_IMX8MM_I2C3_IRQ = 37,
+ FSL_IMX8MM_I2C4_IRQ = 38,
+
FSL_IMX8MM_GPIO1_LOW_IRQ = 64,
FSL_IMX8MM_GPIO1_HIGH_IRQ = 65,
FSL_IMX8MM_GPIO2_LOW_IRQ = 66,
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 11/63] hw/arm/fsl-imx8mm: Adding support for SPI controller
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (9 preceding siblings ...)
2026-04-27 12:46 ` [PULL 10/63] hw/arm/fsl-imx8mm: Adding support for I2C emulation Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 12/63] hw/arm/fsl-imx8mm: Adding support for Watchdog Timers Peter Maydell
` (52 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Gaurav Sharma <gaurav.sharma_7@nxp.com>
It enables emulation of ECSPI in iMX8MM
Added SPI IRQ lines
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/fsl-imx8mm.c | 26 ++++++++++++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 7 +++++++
2 files changed, 33 insertions(+)
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 3632d85197..f433beeaf2 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -195,6 +195,11 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
}
+ for (i = 0; i < FSL_IMX8MM_NUM_ECSPIS; i++) {
+ g_autofree char *name = g_strdup_printf("spi%d", i + 1);
+ object_initialize_child(obj, name, &s->spi[i], TYPE_IMX_SPI);
+ }
+
object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
object_initialize_child(obj, "pcie_phy", &s->pcie_phy,
TYPE_FSL_IMX8M_PCIE_PHY);
@@ -464,6 +469,26 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in(gicdev, usdhc_table[i].irq));
}
+ /* ECSPIs */
+ for (i = 0; i < FSL_IMX8MM_NUM_ECSPIS; i++) {
+ static const struct {
+ hwaddr addr;
+ unsigned int irq;
+ } spi_table[FSL_IMX8MM_NUM_ECSPIS] = {
+ { fsl_imx8mm_memmap[FSL_IMX8MM_ECSPI1].addr, FSL_IMX8MM_ECSPI1_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_ECSPI2].addr, FSL_IMX8MM_ECSPI2_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_ECSPI3].addr, FSL_IMX8MM_ECSPI3_IRQ },
+ };
+
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) {
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, spi_table[i].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
+ qdev_get_gpio_in(gicdev, spi_table[i].irq));
+ }
+
/* SNVS */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->snvs), errp)) {
return;
@@ -503,6 +528,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_GIC_DIST:
case FSL_IMX8MM_GIC_REDIST:
case FSL_IMX8MM_GPIO1 ... FSL_IMX8MM_GPIO5:
+ case FSL_IMX8MM_ECSPI1 ... FSL_IMX8MM_ECSPI3:
case FSL_IMX8MM_I2C1 ... FSL_IMX8MM_I2C4:
case FSL_IMX8MM_PCIE1:
case FSL_IMX8MM_PCIE_PHY1:
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index d6df16e9d4..13c044412a 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -21,6 +21,7 @@
#include "hw/pci-host/designware.h"
#include "hw/pci-host/fsl_imx8m_phy.h"
#include "hw/sd/sdhci.h"
+#include "hw/ssi/imx_spi.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -32,6 +33,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mmState, FSL_IMX8MM)
enum FslImx8mmConfiguration {
FSL_IMX8MM_NUM_CPUS = 4,
+ FSL_IMX8MM_NUM_ECSPIS = 3,
FSL_IMX8MM_NUM_GPIOS = 5,
FSL_IMX8MM_NUM_I2CS = 4,
FSL_IMX8MM_NUM_IRQS = 128,
@@ -48,6 +50,7 @@ struct FslImx8mmState {
IMX8MPCCMState ccm;
IMX8MPAnalogState analog;
IMX7SNVSState snvs;
+ IMXSPIState spi[FSL_IMX8MM_NUM_ECSPIS];
IMXI2CState i2c[FSL_IMX8MM_NUM_I2CS];
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
MemoryRegion ocram;
@@ -177,6 +180,10 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_UART3_IRQ = 28,
FSL_IMX8MM_UART4_IRQ = 29,
+ FSL_IMX8MM_ECSPI1_IRQ = 31,
+ FSL_IMX8MM_ECSPI2_IRQ = 32,
+ FSL_IMX8MM_ECSPI3_IRQ = 33,
+
FSL_IMX8MM_I2C1_IRQ = 35,
FSL_IMX8MM_I2C2_IRQ = 36,
FSL_IMX8MM_I2C3_IRQ = 37,
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 12/63] hw/arm/fsl-imx8mm: Adding support for Watchdog Timers
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (10 preceding siblings ...)
2026-04-27 12:46 ` [PULL 11/63] hw/arm/fsl-imx8mm: Adding support for SPI controller Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 13/63] hw/arm/fsl-imx8mm: Adding support for General Purpose Timers Peter Maydell
` (51 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Gaurav Sharma <gaurav.sharma_7@nxp.com>
It enables emulation of WDT in iMX8MM
Added WDT IRQ lines
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/Kconfig | 1 +
hw/arm/fsl-imx8mm.c | 28 ++++++++++++++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 7 +++++++
3 files changed, 36 insertions(+)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index e8296f9a28..42901c4383 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -629,6 +629,7 @@ config FSL_IMX8MM
select SDHCI
select PCI_EXPRESS_DESIGNWARE
select PCI_EXPRESS_FSL_IMX8M_PHY
+ select WDT_IMX2
config FSL_IMX8MM_EVK
bool
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index f433beeaf2..34645555d6 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -200,6 +200,11 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->spi[i], TYPE_IMX_SPI);
}
+ for (i = 0; i < FSL_IMX8MM_NUM_WDTS; i++) {
+ g_autofree char *name = g_strdup_printf("wdt%d", i);
+ object_initialize_child(obj, name, &s->wdt[i], TYPE_IMX2_WDT);
+ }
+
object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
object_initialize_child(obj, "pcie_phy", &s->pcie_phy,
TYPE_FSL_IMX8M_PCIE_PHY);
@@ -496,6 +501,28 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0,
fsl_imx8mm_memmap[FSL_IMX8MM_SNVS_HP].addr);
+ /* Watchdogs */
+ for (i = 0; i < FSL_IMX8MM_NUM_WDTS; i++) {
+ static const struct {
+ hwaddr addr;
+ unsigned int irq;
+ } wdog_table[FSL_IMX8MM_NUM_WDTS] = {
+ { fsl_imx8mm_memmap[FSL_IMX8MM_WDOG1].addr, FSL_IMX8MM_WDOG1_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_WDOG2].addr, FSL_IMX8MM_WDOG2_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_WDOG3].addr, FSL_IMX8MM_WDOG3_IRQ },
+ };
+
+ object_property_set_bool(OBJECT(&s->wdt[i]), "pretimeout-support",
+ true, &error_abort);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), errp)) {
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, wdog_table[i].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0,
+ qdev_get_gpio_in(gicdev, wdog_table[i].irq));
+ }
+
/* PCIe */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->pcie), errp)) {
return;
@@ -537,6 +564,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_SNVS_HP:
case FSL_IMX8MM_UART1 ... FSL_IMX8MM_UART4:
case FSL_IMX8MM_USDHC1 ... FSL_IMX8MM_USDHC3:
+ case FSL_IMX8MM_WDOG1 ... FSL_IMX8MM_WDOG3:
/* device implemented and treated above */
break;
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 13c044412a..fd62b19a87 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -22,6 +22,7 @@
#include "hw/pci-host/fsl_imx8m_phy.h"
#include "hw/sd/sdhci.h"
#include "hw/ssi/imx_spi.h"
+#include "hw/watchdog/wdt_imx2.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -39,6 +40,7 @@ enum FslImx8mmConfiguration {
FSL_IMX8MM_NUM_IRQS = 128,
FSL_IMX8MM_NUM_UARTS = 4,
FSL_IMX8MM_NUM_USDHCS = 3,
+ FSL_IMX8MM_NUM_WDTS = 3,
};
struct FslImx8mmState {
@@ -55,6 +57,7 @@ struct FslImx8mmState {
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
MemoryRegion ocram;
SDHCIState usdhc[FSL_IMX8MM_NUM_USDHCS];
+ IMX2WdtState wdt[FSL_IMX8MM_NUM_WDTS];
DesignwarePCIEHost pcie;
FslImx8mPciePhyState pcie_phy;
};
@@ -200,6 +203,10 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_GPIO5_LOW_IRQ = 72,
FSL_IMX8MM_GPIO5_HIGH_IRQ = 73,
+ FSL_IMX8MM_WDOG1_IRQ = 78,
+ FSL_IMX8MM_WDOG2_IRQ = 79,
+ FSL_IMX8MM_WDOG3_IRQ = 10,
+
FSL_IMX8MM_PCI_INTA_IRQ = 122,
FSL_IMX8MM_PCI_INTB_IRQ = 123,
FSL_IMX8MM_PCI_INTC_IRQ = 124,
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 13/63] hw/arm/fsl-imx8mm: Adding support for General Purpose Timers
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (11 preceding siblings ...)
2026-04-27 12:46 ` [PULL 12/63] hw/arm/fsl-imx8mm: Adding support for Watchdog Timers Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 14/63] hw/arm/fsl-imx8mm: Adding support for ENET ethernet controller Peter Maydell
` (50 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Gaurav Sharma <gaurav.sharma_7@nxp.com>
It enables emulation of GPT in iMX8MM
Added GPT IRQ lines
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/Kconfig | 1 +
hw/arm/fsl-imx8mm.c | 54 +++++++++++++++++++++++++++++++++++++
hw/timer/imx_gpt.c | 26 ++++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 11 ++++++++
include/hw/timer/imx_gpt.h | 2 ++
5 files changed, 94 insertions(+)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 42901c4383..44dd401c8a 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -626,6 +626,7 @@ config FSL_IMX8MM
select FSL_IMX8MP_CCM
select IMX
select IMX_I2C
+ select OR_IRQ
select SDHCI
select PCI_EXPRESS_DESIGNWARE
select PCI_EXPRESS_FSL_IMX8M_PHY
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 34645555d6..3736191257 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -180,6 +180,13 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
}
+ for (i = 0; i < FSL_IMX8MM_NUM_GPTS; i++) {
+ g_autofree char *name = g_strdup_printf("gpt%d", i + 1);
+ object_initialize_child(obj, name, &s->gpt[i], TYPE_IMX8MM_GPT);
+ }
+ object_initialize_child(obj, "gpt5-gpt6-irq", &s->gpt5_gpt6_irq,
+ TYPE_OR_IRQ);
+
for (i = 0; i < FSL_IMX8MM_NUM_I2CS; i++) {
g_autofree char *name = g_strdup_printf("i2c%d", i + 1);
object_initialize_child(obj, name, &s->i2c[i], TYPE_IMX_I2C);
@@ -385,6 +392,52 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
fsl_imx8mm_memmap[FSL_IMX8MM_OCRAM].addr,
&s->ocram);
+ /* GPTs */
+ object_property_set_int(OBJECT(&s->gpt5_gpt6_irq), "num-lines", 2,
+ &error_abort);
+ if (!qdev_realize(DEVICE(&s->gpt5_gpt6_irq), NULL, errp)) {
+ return;
+ }
+
+ qdev_connect_gpio_out(DEVICE(&s->gpt5_gpt6_irq), 0,
+ qdev_get_gpio_in(gicdev, FSL_IMX8MM_GPT5_GPT6_IRQ));
+
+ for (i = 0; i < FSL_IMX8MM_NUM_GPTS; i++) {
+ hwaddr gpt_addrs[FSL_IMX8MM_NUM_GPTS] = {
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPT1].addr,
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPT2].addr,
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPT3].addr,
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPT4].addr,
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPT5].addr,
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPT6].addr,
+ };
+
+ s->gpt[i].ccm = IMX_CCM(&s->ccm);
+
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpt[i]), errp)) {
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, gpt_addrs[i]);
+
+ if (i < FSL_IMX8MM_NUM_GPTS - 2) {
+ static const unsigned int gpt_irqs[FSL_IMX8MM_NUM_GPTS - 2] = {
+ FSL_IMX8MM_GPT1_IRQ,
+ FSL_IMX8MM_GPT2_IRQ,
+ FSL_IMX8MM_GPT3_IRQ,
+ FSL_IMX8MM_GPT4_IRQ,
+ };
+
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
+ qdev_get_gpio_in(gicdev, gpt_irqs[i]));
+ } else {
+ int irq = i - FSL_IMX8MM_NUM_GPTS + 2;
+
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
+ qdev_get_gpio_in(DEVICE(&s->gpt5_gpt6_irq), irq));
+ }
+ }
+
/* I2Cs */
for (i = 0; i < FSL_IMX8MM_NUM_I2CS; i++) {
static const struct {
@@ -555,6 +608,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_GIC_DIST:
case FSL_IMX8MM_GIC_REDIST:
case FSL_IMX8MM_GPIO1 ... FSL_IMX8MM_GPIO5:
+ case FSL_IMX8MM_GPT1 ... FSL_IMX8MM_GPT6:
case FSL_IMX8MM_ECSPI1 ... FSL_IMX8MM_ECSPI3:
case FSL_IMX8MM_I2C1 ... FSL_IMX8MM_I2C4:
case FSL_IMX8MM_PCIE1:
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index 168cadcb3f..cdc0257126 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -6,6 +6,7 @@
* Originally written by Hans Jiang
* Updated by Peter Chubb
* Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
+ * Updated by Gaurav Sharma <gaurav.sharma_7@nxp.com>
*
* This code is licensed under GPL version 2 or later. See
* the COPYING file in the top-level directory.
@@ -137,6 +138,17 @@ static const IMXClk imx8mp_gpt_clocks[] = {
CLK_NONE, /* 111 not defined */
};
+static const IMXClk imx8mm_gpt_clocks[] = {
+ CLK_NONE, /* 000 No clock source */
+ CLK_IPG, /* 001 ipg_clk, 532MHz */
+ CLK_IPG_HIGH, /* 010 ipg_clk_highfreq */
+ CLK_EXT, /* 011 External clock */
+ CLK_32k, /* 100 ipg_clk_32k */
+ CLK_HIGH, /* 101 ipg_clk_16M */
+ CLK_NONE, /* 110 not defined */
+ CLK_NONE, /* 111 not defined */
+};
+
/* Must be called from within ptimer_transaction_begin/commit block */
static void imx_gpt_set_freq(IMXGPTState *s)
{
@@ -570,6 +582,13 @@ static void imx8mp_gpt_init(Object *obj)
s->clocks = imx8mp_gpt_clocks;
}
+static void imx8mm_gpt_init(Object *obj)
+{
+ IMXGPTState *s = IMX_GPT(obj);
+
+ s->clocks = imx8mm_gpt_clocks;
+}
+
static const TypeInfo imx25_gpt_info = {
.name = TYPE_IMX25_GPT,
.parent = TYPE_SYS_BUS_DEVICE,
@@ -608,6 +627,12 @@ static const TypeInfo imx8mp_gpt_info = {
.instance_init = imx8mp_gpt_init,
};
+static const TypeInfo imx8mm_gpt_info = {
+ .name = TYPE_IMX8MM_GPT,
+ .parent = TYPE_IMX25_GPT,
+ .instance_init = imx8mm_gpt_init,
+};
+
static void imx_gpt_register_types(void)
{
type_register_static(&imx25_gpt_info);
@@ -616,6 +641,7 @@ static void imx_gpt_register_types(void)
type_register_static(&imx6ul_gpt_info);
type_register_static(&imx7_gpt_info);
type_register_static(&imx8mp_gpt_info);
+ type_register_static(&imx8mm_gpt_info);
}
type_init(imx_gpt_register_types)
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index fd62b19a87..607ac86666 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -18,10 +18,12 @@
#include "hw/misc/imx7_snvs.h"
#include "hw/misc/imx8mp_analog.h"
#include "hw/misc/imx8mp_ccm.h"
+#include "hw/or-irq.h"
#include "hw/pci-host/designware.h"
#include "hw/pci-host/fsl_imx8m_phy.h"
#include "hw/sd/sdhci.h"
#include "hw/ssi/imx_spi.h"
+#include "hw/timer/imx_gpt.h"
#include "hw/watchdog/wdt_imx2.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -36,6 +38,7 @@ enum FslImx8mmConfiguration {
FSL_IMX8MM_NUM_CPUS = 4,
FSL_IMX8MM_NUM_ECSPIS = 3,
FSL_IMX8MM_NUM_GPIOS = 5,
+ FSL_IMX8MM_NUM_GPTS = 6,
FSL_IMX8MM_NUM_I2CS = 4,
FSL_IMX8MM_NUM_IRQS = 128,
FSL_IMX8MM_NUM_UARTS = 4,
@@ -48,6 +51,7 @@ struct FslImx8mmState {
ARMCPU cpu[FSL_IMX8MM_NUM_CPUS];
GICv3State gic;
+ IMXGPTState gpt[FSL_IMX8MM_NUM_GPTS];
IMXGPIOState gpio[FSL_IMX8MM_NUM_GPIOS];
IMX8MPCCMState ccm;
IMX8MPAnalogState analog;
@@ -60,6 +64,7 @@ struct FslImx8mmState {
IMX2WdtState wdt[FSL_IMX8MM_NUM_WDTS];
DesignwarePCIEHost pcie;
FslImx8mPciePhyState pcie_phy;
+ OrIRQState gpt5_gpt6_irq;
};
enum FslImx8mmMemoryRegions {
@@ -192,6 +197,12 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_I2C3_IRQ = 37,
FSL_IMX8MM_I2C4_IRQ = 38,
+ FSL_IMX8MM_GPT1_IRQ = 55,
+ FSL_IMX8MM_GPT2_IRQ = 54,
+ FSL_IMX8MM_GPT3_IRQ = 53,
+ FSL_IMX8MM_GPT4_IRQ = 52,
+ FSL_IMX8MM_GPT5_GPT6_IRQ = 51,
+
FSL_IMX8MM_GPIO1_LOW_IRQ = 64,
FSL_IMX8MM_GPIO1_HIGH_IRQ = 65,
FSL_IMX8MM_GPIO2_LOW_IRQ = 66,
diff --git a/include/hw/timer/imx_gpt.h b/include/hw/timer/imx_gpt.h
index 7f0d55b349..b5d73c5e4b 100644
--- a/include/hw/timer/imx_gpt.h
+++ b/include/hw/timer/imx_gpt.h
@@ -6,6 +6,7 @@
* Originally written by Hans Jiang
* Updated by Peter Chubb
* Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
+ * Updated by Gaurav Sharma <gaurav.sharma_7@nxp.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -81,6 +82,7 @@
#define TYPE_IMX6UL_GPT "imx6ul.gpt"
#define TYPE_IMX7_GPT "imx7.gpt"
#define TYPE_IMX8MP_GPT "imx8mp.gpt"
+#define TYPE_IMX8MM_GPT "imx8mm.gpt"
#define TYPE_IMX_GPT TYPE_IMX25_GPT
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 14/63] hw/arm/fsl-imx8mm: Adding support for ENET ethernet controller
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (12 preceding siblings ...)
2026-04-27 12:46 ` [PULL 13/63] hw/arm/fsl-imx8mm: Adding support for General Purpose Timers Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 15/63] hw/arm/fsl-imx8mm: Adding support for USB controller Peter Maydell
` (49 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Gaurav Sharma <gaurav.sharma_7@nxp.com>
It enables emulation of ENET ethernet controller in iMX8MM
Enables testing and debugging of network dependent drivers
Added ENET MAC IRQ lines
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/Kconfig | 1 +
hw/arm/fsl-imx8mm.c | 24 ++++++++++++++++++++++++
hw/arm/imx8mm-evk.c | 1 +
include/hw/arm/fsl-imx8mm.h | 10 +++++++++-
4 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 44dd401c8a..104954d90d 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -625,6 +625,7 @@ config FSL_IMX8MM
select FSL_IMX8MP_ANALOG
select FSL_IMX8MP_CCM
select IMX
+ select IMX_FEC
select IMX_I2C
select OR_IRQ
select SDHCI
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 3736191257..f1c173dbec 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -212,6 +212,8 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->wdt[i], TYPE_IMX2_WDT);
}
+ object_initialize_child(obj, "eth0", &s->enet, TYPE_IMX_ENET);
+
object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
object_initialize_child(obj, "pcie_phy", &s->pcie_phy,
TYPE_FSL_IMX8M_PCIE_PHY);
@@ -547,6 +549,21 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in(gicdev, spi_table[i].irq));
}
+ /* ENET1 */
+ object_property_set_uint(OBJECT(&s->enet), "phy-num", s->phy_num,
+ &error_abort);
+ object_property_set_uint(OBJECT(&s->enet), "tx-ring-num", 3, &error_abort);
+ qemu_configure_nic_device(DEVICE(&s->enet), true, NULL);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->enet), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->enet), 0,
+ fsl_imx8mm_memmap[FSL_IMX8MM_ENET1].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->enet), 0,
+ qdev_get_gpio_in(gicdev, FSL_IMX8MM_ENET1_MAC_IRQ));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->enet), 1,
+ qdev_get_gpio_in(gicdev, FSL_IMX6_ENET1_MAC_1588_IRQ));
+
/* SNVS */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->snvs), errp)) {
return;
@@ -610,6 +627,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_GPIO1 ... FSL_IMX8MM_GPIO5:
case FSL_IMX8MM_GPT1 ... FSL_IMX8MM_GPT6:
case FSL_IMX8MM_ECSPI1 ... FSL_IMX8MM_ECSPI3:
+ case FSL_IMX8MM_ENET1:
case FSL_IMX8MM_I2C1 ... FSL_IMX8MM_I2C4:
case FSL_IMX8MM_PCIE1:
case FSL_IMX8MM_PCIE_PHY1:
@@ -631,10 +649,16 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
}
}
+static const Property fsl_imx8mm_properties[] = {
+ DEFINE_PROP_UINT32("fec1-phy-num", FslImx8mmState, phy_num, 0),
+ DEFINE_PROP_BOOL("fec1-phy-connected", FslImx8mmState, phy_connected, true),
+};
+
static void fsl_imx8mm_class_init(ObjectClass *oc, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
+ device_class_set_props(dc, fsl_imx8mm_properties);
dc->realize = fsl_imx8mm_realize;
dc->desc = "i.MX 8MM SoC";
diff --git a/hw/arm/imx8mm-evk.c b/hw/arm/imx8mm-evk.c
index dfdf3cd4f8..6b7774d3e2 100644
--- a/hw/arm/imx8mm-evk.c
+++ b/hw/arm/imx8mm-evk.c
@@ -79,6 +79,7 @@ static void imx8mm_evk_init(MachineState *machine)
s = FSL_IMX8MM(object_new_with_props(TYPE_FSL_IMX8MM, OBJECT(machine),
"soc", &error_fatal, NULL));
+ object_property_set_uint(OBJECT(s), "fec1-phy-num", 1, &error_fatal);
sysbus_realize_and_unref(SYS_BUS_DEVICE(s), &error_fatal);
memory_region_add_subregion(get_system_memory(), FSL_IMX8MM_RAM_START,
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 607ac86666..bc5a0922ad 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -18,7 +18,8 @@
#include "hw/misc/imx7_snvs.h"
#include "hw/misc/imx8mp_analog.h"
#include "hw/misc/imx8mp_ccm.h"
-#include "hw/or-irq.h"
+#include "hw/net/imx_fec.h"
+#include "hw/core/or-irq.h"
#include "hw/pci-host/designware.h"
#include "hw/pci-host/fsl_imx8m_phy.h"
#include "hw/sd/sdhci.h"
@@ -60,11 +61,15 @@ struct FslImx8mmState {
IMXI2CState i2c[FSL_IMX8MM_NUM_I2CS];
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
MemoryRegion ocram;
+ IMXFECState enet;
SDHCIState usdhc[FSL_IMX8MM_NUM_USDHCS];
IMX2WdtState wdt[FSL_IMX8MM_NUM_WDTS];
DesignwarePCIEHost pcie;
FslImx8mPciePhyState pcie_phy;
OrIRQState gpt5_gpt6_irq;
+
+ uint32_t phy_num;
+ bool phy_connected;
};
enum FslImx8mmMemoryRegions {
@@ -218,6 +223,9 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_WDOG2_IRQ = 79,
FSL_IMX8MM_WDOG3_IRQ = 10,
+ FSL_IMX8MM_ENET1_MAC_IRQ = 118,
+ FSL_IMX6_ENET1_MAC_1588_IRQ = 121,
+
FSL_IMX8MM_PCI_INTA_IRQ = 122,
FSL_IMX8MM_PCI_INTB_IRQ = 123,
FSL_IMX8MM_PCI_INTC_IRQ = 124,
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 15/63] hw/arm/fsl-imx8mm: Adding support for USB controller
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (13 preceding siblings ...)
2026-04-27 12:46 ` [PULL 14/63] hw/arm/fsl-imx8mm: Adding support for ENET ethernet controller Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 16/63] hw/arm/fsl-imx8mm: Adding functional testing of iMX8MM emulation Peter Maydell
` (48 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Gaurav Sharma <gaurav.sharma_7@nxp.com>
It enables emulation of USB on iMX8MM
Enables testing and debugging of USB drivers
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/Kconfig | 1 +
hw/arm/fsl-imx8mm.c | 27 +++++++++++++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 6 ++++++
3 files changed, 34 insertions(+)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 104954d90d..b940af9345 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -631,6 +631,7 @@ config FSL_IMX8MM
select SDHCI
select PCI_EXPRESS_DESIGNWARE
select PCI_EXPRESS_FSL_IMX8M_PHY
+ select USB_DWC3
select WDT_IMX2
config FSL_IMX8MM_EVK
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index f1c173dbec..97c3f8542c 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -202,6 +202,11 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
}
+ for (i = 0; i < FSL_IMX8MM_NUM_USBS; i++) {
+ g_autofree char *name = g_strdup_printf("usb%d", i);
+ object_initialize_child(obj, name, &s->usb[i], TYPE_USB_DWC3);
+ }
+
for (i = 0; i < FSL_IMX8MM_NUM_ECSPIS; i++) {
g_autofree char *name = g_strdup_printf("spi%d", i + 1);
object_initialize_child(obj, name, &s->spi[i], TYPE_IMX_SPI);
@@ -529,6 +534,27 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in(gicdev, usdhc_table[i].irq));
}
+ /* USBs */
+ for (i = 0; i < FSL_IMX8MM_NUM_USBS; i++) {
+ static const struct {
+ hwaddr addr;
+ unsigned int irq;
+ } usb_table[FSL_IMX8MM_NUM_USBS] = {
+ { fsl_imx8mm_memmap[FSL_IMX8MM_USB1].addr, FSL_IMX8MM_USB1_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_USB2].addr, FSL_IMX8MM_USB2_IRQ },
+ };
+
+ qdev_prop_set_uint32(DEVICE(&s->usb[i].sysbus_xhci), "p2", 1);
+ qdev_prop_set_uint32(DEVICE(&s->usb[i].sysbus_xhci), "p3", 1);
+ qdev_prop_set_uint32(DEVICE(&s->usb[i].sysbus_xhci), "slots", 2);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->usb[i]), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0, usb_table[i].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i].sysbus_xhci), 0,
+ qdev_get_gpio_in(gicdev, usb_table[i].irq));
+ }
+
/* ECSPIs */
for (i = 0; i < FSL_IMX8MM_NUM_ECSPIS; i++) {
static const struct {
@@ -635,6 +661,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_OCRAM:
case FSL_IMX8MM_SNVS_HP:
case FSL_IMX8MM_UART1 ... FSL_IMX8MM_UART4:
+ case FSL_IMX8MM_USB1 ... FSL_IMX8MM_USB2:
case FSL_IMX8MM_USDHC1 ... FSL_IMX8MM_USDHC3:
case FSL_IMX8MM_WDOG1 ... FSL_IMX8MM_WDOG3:
/* device implemented and treated above */
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index bc5a0922ad..60d79a6e3c 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -25,6 +25,7 @@
#include "hw/sd/sdhci.h"
#include "hw/ssi/imx_spi.h"
#include "hw/timer/imx_gpt.h"
+#include "hw/usb/hcd-dwc3.h"
#include "hw/watchdog/wdt_imx2.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -43,6 +44,7 @@ enum FslImx8mmConfiguration {
FSL_IMX8MM_NUM_I2CS = 4,
FSL_IMX8MM_NUM_IRQS = 128,
FSL_IMX8MM_NUM_UARTS = 4,
+ FSL_IMX8MM_NUM_USBS = 2,
FSL_IMX8MM_NUM_USDHCS = 3,
FSL_IMX8MM_NUM_WDTS = 3,
};
@@ -64,6 +66,7 @@ struct FslImx8mmState {
IMXFECState enet;
SDHCIState usdhc[FSL_IMX8MM_NUM_USDHCS];
IMX2WdtState wdt[FSL_IMX8MM_NUM_WDTS];
+ USBDWC3 usb[FSL_IMX8MM_NUM_USBS];
DesignwarePCIEHost pcie;
FslImx8mPciePhyState pcie_phy;
OrIRQState gpt5_gpt6_irq;
@@ -202,6 +205,9 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_I2C3_IRQ = 37,
FSL_IMX8MM_I2C4_IRQ = 38,
+ FSL_IMX8MM_USB1_IRQ = 40,
+ FSL_IMX8MM_USB2_IRQ = 41,
+
FSL_IMX8MM_GPT1_IRQ = 55,
FSL_IMX8MM_GPT2_IRQ = 54,
FSL_IMX8MM_GPT3_IRQ = 53,
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 16/63] hw/arm/fsl-imx8mm: Adding functional testing of iMX8MM emulation
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (14 preceding siblings ...)
2026-04-27 12:46 ` [PULL 15/63] hw/arm/fsl-imx8mm: Adding support for USB controller Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 17/63] target/arm: Ignore endianness when setting MTE tags Peter Maydell
` (47 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Added script that would validate the iMX8MM emulation by checking the
linux console log. If it succeeds, it will return:-
ok 1 test_imx8mm_evk.Imx8mmEvkMachine.test_aarch64_imx8mm_evk_usdhc
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
[PMM: Add missing blank lines that flake8 wants]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
MAINTAINERS | 1 +
tests/functional/aarch64/meson.build | 2 +
tests/functional/aarch64/test_imx8mm_evk.py | 69 +++++++++++++++++++++
3 files changed, 72 insertions(+)
create mode 100755 tests/functional/aarch64/test_imx8mm_evk.py
diff --git a/MAINTAINERS b/MAINTAINERS
index 8167d42876..8d980d6c40 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -921,6 +921,7 @@ F: hw/arm/fsl-imx8mm.c
F: hw/arm/imx8mm-evk.c
F: include/hw/arm/fsl-imx8mm.h
F: docs/system/arm/imx8m.rst
+F: tests/functional/aarch64/test_imx8mm_evk.py
MCIMX8MP-EVK / i.MX8MP
M: Bernhard Beschow <shentey@gmail.com>
diff --git a/tests/functional/aarch64/meson.build b/tests/functional/aarch64/meson.build
index 7ea8c22b04..1067f181f2 100644
--- a/tests/functional/aarch64/meson.build
+++ b/tests/functional/aarch64/meson.build
@@ -5,6 +5,7 @@ test_aarch64_timeouts = {
'aspeed_ast2700a2' : 600,
'aspeed_ast2700fc' : 600,
'device_passthrough' : 720,
+ 'imx8mm_evk' : 240,
'imx8mp_evk' : 240,
'raspi4' : 480,
'reverse_debug' : 180,
@@ -29,6 +30,7 @@ tests_aarch64_system_thorough = [
'aspeed_ast2700fc',
'device_passthrough',
'hotplug_pci',
+ 'imx8mm_evk',
'imx8mp_evk',
'kvm',
'multiprocess',
diff --git a/tests/functional/aarch64/test_imx8mm_evk.py b/tests/functional/aarch64/test_imx8mm_evk.py
new file mode 100755
index 0000000000..86725991f1
--- /dev/null
+++ b/tests/functional/aarch64/test_imx8mm_evk.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots a Linux kernel and checks the console
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import LinuxKernelTest, Asset
+
+
+class Imx8mmEvkMachine(LinuxKernelTest):
+
+ ASSET_IMAGE = Asset(
+ ('https://cloud.debian.org/images/cloud/bookworm/20231210-1590/'
+ 'debian-12-generic-arm64-20231210-1590.tar.xz'),
+ '7ebf1577b32d5af6204df74b54ca2e4675de9b5a9fa14f3ff70b88eeb7b3b359')
+
+ KERNEL_OFFSET = 0x51000000
+ KERNEL_SIZE = 32622528
+ INITRD_OFFSET = 0x76000000
+ INITRD_SIZE = 30987766
+ DTB_OFFSET = 0x64DB5000
+ DTB_SIZE = 36812
+
+ def extract(self, in_path, out_path, offset, size):
+ try:
+ with open(in_path, "rb") as source:
+ source.seek(offset)
+ data = source.read(size)
+ with open(out_path, "wb") as target:
+ target.write(data)
+ except (IOError, ValueError) as e:
+ self.log.error(f"Failed to extract {out_path}: {e}")
+ raise
+
+ def setUp(self):
+ super().setUp()
+
+ self.image_path = self.scratch_file("disk.raw")
+ self.kernel_path = self.scratch_file("linux")
+ self.initrd_path = self.scratch_file("initrd.zstd")
+ self.dtb_path = self.scratch_file("imx8mm-evk.dtb")
+
+ self.archive_extract(self.ASSET_IMAGE)
+ self.extract(self.image_path, self.kernel_path,
+ self.KERNEL_OFFSET, self.KERNEL_SIZE)
+ self.extract(self.image_path, self.initrd_path,
+ self.INITRD_OFFSET, self.INITRD_SIZE)
+ self.extract(self.image_path, self.dtb_path,
+ self.DTB_OFFSET, self.DTB_SIZE)
+
+ def test_aarch64_imx8mm_evk_usdhc(self):
+ self.require_accelerator("tcg")
+ self.set_machine('imx8mm-evk')
+ self.vm.set_console(console_index=1)
+ self.vm.add_args('-m', '2G',
+ '-smp', '4',
+ '-kernel', self.kernel_path,
+ '-initrd', self.initrd_path,
+ '-dtb', self.dtb_path,
+ '-append', 'root=/dev/mmcblk2p1',
+ '-drive', f'file={self.image_path},if=sd,bus=2,'
+ 'format=raw,id=mmcblk2,snapshot=on')
+
+ self.vm.launch()
+ self.wait_for_console_pattern('Welcome to ')
+
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 17/63] target/arm: Ignore endianness when setting MTE tags
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (15 preceding siblings ...)
2026-04-27 12:46 ` [PULL 16/63] hw/arm/fsl-imx8mm: Adding functional testing of iMX8MM emulation Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 18/63] target/arm: Explode MO_TExx -> MO_TE | MO_xx Peter Maydell
` (46 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Philippe Mathieu-Daudé <philmd@linaro.org>
As mentioned by Richard in [*]:
We don't actually need any specific endianness here, because
every byte has the same value. So we could simply drop MO_TE.
That would produce a store in host-endianness, which will be
fractionally more efficient on some hosts.
[*] https://lore.kernel.org/qemu-devel/d64d3576-9188-4e74-afdc-3492c9feb8e0@linaro.org/
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20260414005348.4767-2-philmd@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/tcg/helper-a64.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c
index a7372aa6bb..dd1f9c6dc6 100644
--- a/target/arm/tcg/helper-a64.c
+++ b/target/arm/tcg/helper-a64.c
@@ -1019,7 +1019,7 @@ static uint64_t set_step_tags(CPUARMState *env, uint64_t toaddr,
* the page dirty and will use the fast path.
*/
uint64_t repldata = data * 0x0101010101010101ULL;
- MemOpIdx oi16 = make_memop_idx(MO_TE | MO_128, memidx);
+ MemOpIdx oi16 = make_memop_idx(MO_128, memidx);
cpu_st16_mmu(env, toaddr, int128_make128(repldata, repldata), oi16, ra);
mte_mops_set_tags(env, toaddr, 16, *mtedesc);
return 16;
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 18/63] target/arm: Explode MO_TExx -> MO_TE | MO_xx
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (16 preceding siblings ...)
2026-04-27 12:46 ` [PULL 17/63] target/arm: Ignore endianness when setting MTE tags Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 19/63] target/arm: Hoist MO_TE into mve_advance_vpt() Peter Maydell
` (45 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Extract the implicit MO_TE definition in order to replace
it in the next commit.
Mechanical change using:
$ for n in UW UL UQ UO SW SL SQ; do \
sed -i -e "s/MO_TE$n/MO_TE | MO_$n/" \
$(git grep -l MO_TE$n target/arm); \
done
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20260414005348.4767-3-philmd@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/tcg/m_helper.c | 6 +--
target/arm/tcg/mve_helper.c | 79 ++++++++++++++++++++-----------------
2 files changed, 45 insertions(+), 40 deletions(-)
diff --git a/target/arm/tcg/m_helper.c b/target/arm/tcg/m_helper.c
index a0cb8cb021..f5954ce9bf 100644
--- a/target/arm/tcg/m_helper.c
+++ b/target/arm/tcg/m_helper.c
@@ -634,7 +634,7 @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
/* Note that these stores can throw exceptions on MPU faults */
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN,
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN,
arm_to_core_mmu_idx(mmu_idx));
cpu_stl_mmu(env, sp, nextinst, oi, GETPC());
cpu_stl_mmu(env, sp + 4, saved_psr, oi, GETPC());
@@ -1055,7 +1055,7 @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK;
uintptr_t ra = GETPC();
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN,
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN,
arm_to_core_mmu_idx(mmu_idx));
assert(env->v7m.secure);
@@ -1131,7 +1131,7 @@ void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
ARMCPU *cpu = env_archcpu(env);
uintptr_t ra = GETPC();
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN,
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN,
arm_to_core_mmu_idx(mmu_idx));
/* fptr is the value of Rn, the frame pointer we load the FP regs from */
diff --git a/target/arm/tcg/mve_helper.c b/target/arm/tcg/mve_helper.c
index a67d90d6c7..cc58e0502f 100644
--- a/target/arm/tcg/mve_helper.c
+++ b/target/arm/tcg/mve_helper.c
@@ -194,23 +194,23 @@ static void mve_advance_vpt(CPUARMState *env)
}
DO_VLDR(vldrb, MO_UB, 1, uint8_t, ldb, 1, uint8_t)
-DO_VLDR(vldrh, MO_TEUW, 2, uint16_t, ldw, 2, uint16_t)
-DO_VLDR(vldrw, MO_TEUL, 4, uint32_t, ldl, 4, uint32_t)
+DO_VLDR(vldrh, MO_TE | MO_UW, 2, uint16_t, ldw, 2, uint16_t)
+DO_VLDR(vldrw, MO_TE | MO_UL, 4, uint32_t, ldl, 4, uint32_t)
DO_VSTR(vstrb, MO_UB, 1, stb, 1, uint8_t)
-DO_VSTR(vstrh, MO_TEUW, 2, stw, 2, uint16_t)
-DO_VSTR(vstrw, MO_TEUL, 4, stl, 4, uint32_t)
+DO_VSTR(vstrh, MO_TE | MO_UW, 2, stw, 2, uint16_t)
+DO_VSTR(vstrw, MO_TE | MO_UL, 4, stl, 4, uint32_t)
DO_VLDR(vldrb_sh, MO_SB, 1, int8_t, ldb, 2, int16_t)
DO_VLDR(vldrb_sw, MO_SB, 1, int8_t, ldb, 4, int32_t)
DO_VLDR(vldrb_uh, MO_UB, 1, uint8_t, ldb, 2, uint16_t)
DO_VLDR(vldrb_uw, MO_UB, 1, uint8_t, ldb, 4, uint32_t)
-DO_VLDR(vldrh_sw, MO_TESW, 2, int16_t, ldw, 4, int32_t)
-DO_VLDR(vldrh_uw, MO_TEUW, 2, uint16_t, ldw, 4, uint32_t)
+DO_VLDR(vldrh_sw, MO_TE | MO_SW, 2, int16_t, ldw, 4, int32_t)
+DO_VLDR(vldrh_uw, MO_TE | MO_UW, 2, uint16_t, ldw, 4, uint32_t)
DO_VSTR(vstrb_h, MO_UB, 1, stb, 2, int16_t)
DO_VSTR(vstrb_w, MO_UB, 1, stb, 4, int32_t)
-DO_VSTR(vstrh_w, MO_TEUW, 2, stw, 4, int32_t)
+DO_VSTR(vstrh_w, MO_TE | MO_UW, 2, stw, 4, int32_t)
#undef DO_VLDR
#undef DO_VSTR
@@ -295,7 +295,7 @@ DO_VSTR(vstrh_w, MO_TEUW, 2, stw, 4, int32_t)
unsigned e; \
uint32_t addr; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
for (e = 0; e < 16 / 4; e++, mask >>= 4, eci_mask >>= 4) { \
if (!(eci_mask & 1)) { \
continue; \
@@ -321,7 +321,7 @@ DO_VSTR(vstrh_w, MO_TEUW, 2, stw, 4, int32_t)
unsigned e; \
uint32_t addr; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
for (e = 0; e < 16 / 4; e++, mask >>= 4, eci_mask >>= 4) { \
if (!(eci_mask & 1)) { \
continue; \
@@ -345,42 +345,47 @@ DO_VSTR(vstrh_w, MO_TEUW, 2, stw, 4, int32_t)
DO_VLDR_SG(vldrb_sg_sh, MO_SB, int8_t, ldb, 2, int16_t, uint16_t, ADDR_ADD, false)
DO_VLDR_SG(vldrb_sg_sw, MO_SB, int8_t, ldb, 4, int32_t, uint32_t, ADDR_ADD, false)
-DO_VLDR_SG(vldrh_sg_sw, MO_TESW, int16_t, ldw, 4, int32_t, uint32_t, ADDR_ADD, false)
+DO_VLDR_SG(vldrh_sg_sw, MO_TE | MO_SW, int16_t, ldw, 4,
+ int32_t, uint32_t, ADDR_ADD, false)
DO_VLDR_SG(vldrb_sg_ub, MO_UB, uint8_t, ldb, 1, uint8_t, uint8_t, ADDR_ADD, false)
DO_VLDR_SG(vldrb_sg_uh, MO_UB, uint8_t, ldb, 2, uint16_t, uint16_t, ADDR_ADD, false)
DO_VLDR_SG(vldrb_sg_uw, MO_UB, uint8_t, ldb, 4, uint32_t, uint32_t, ADDR_ADD, false)
-DO_VLDR_SG(vldrh_sg_uh, MO_TEUW, uint16_t, ldw, 2, uint16_t, uint16_t, ADDR_ADD, false)
-DO_VLDR_SG(vldrh_sg_uw, MO_TEUW, uint16_t, ldw, 4, uint32_t, uint32_t, ADDR_ADD, false)
-DO_VLDR_SG(vldrw_sg_uw, MO_TEUL, uint32_t, ldl, 4, uint32_t, uint32_t, ADDR_ADD, false)
+DO_VLDR_SG(vldrh_sg_uh, MO_TE | MO_UW, uint16_t, ldw, 2,
+ uint16_t, uint16_t, ADDR_ADD, false)
+DO_VLDR_SG(vldrh_sg_uw, MO_TE | MO_UW, uint16_t, ldw, 4,
+ uint32_t, uint32_t, ADDR_ADD, false)
+DO_VLDR_SG(vldrw_sg_uw, MO_TE | MO_UL, uint32_t, ldl, 4,
+ uint32_t, uint32_t, ADDR_ADD, false)
DO_VLDR64_SG(vldrd_sg_ud, ADDR_ADD, false)
-DO_VLDR_SG(vldrh_sg_os_sw, MO_TESW, int16_t, ldw, 4,
+DO_VLDR_SG(vldrh_sg_os_sw, MO_TE | MO_SW, int16_t, ldw, 4,
int32_t, uint32_t, ADDR_ADD_OSH, false)
-DO_VLDR_SG(vldrh_sg_os_uh, MO_TEUW, uint16_t, ldw, 2,
+DO_VLDR_SG(vldrh_sg_os_uh, MO_TE | MO_UW, uint16_t, ldw, 2,
uint16_t, uint16_t, ADDR_ADD_OSH, false)
-DO_VLDR_SG(vldrh_sg_os_uw, MO_TEUW, uint16_t, ldw, 4,
+DO_VLDR_SG(vldrh_sg_os_uw, MO_TE | MO_UW, uint16_t, ldw, 4,
uint32_t, uint32_t, ADDR_ADD_OSH, false)
-DO_VLDR_SG(vldrw_sg_os_uw, MO_TEUL, uint32_t, ldl, 4,
+DO_VLDR_SG(vldrw_sg_os_uw, MO_TE | MO_UL, uint32_t, ldl, 4,
uint32_t, uint32_t, ADDR_ADD_OSW, false)
DO_VLDR64_SG(vldrd_sg_os_ud, ADDR_ADD_OSD, false)
DO_VSTR_SG(vstrb_sg_ub, MO_UB, stb, 1, uint8_t, ADDR_ADD, false)
DO_VSTR_SG(vstrb_sg_uh, MO_UB, stb, 2, uint16_t, ADDR_ADD, false)
DO_VSTR_SG(vstrb_sg_uw, MO_UB, stb, 4, uint32_t, ADDR_ADD, false)
-DO_VSTR_SG(vstrh_sg_uh, MO_TEUW, stw, 2, uint16_t, ADDR_ADD, false)
-DO_VSTR_SG(vstrh_sg_uw, MO_TEUW, stw, 4, uint32_t, ADDR_ADD, false)
-DO_VSTR_SG(vstrw_sg_uw, MO_TEUL, stl, 4, uint32_t, ADDR_ADD, false)
+DO_VSTR_SG(vstrh_sg_uh, MO_TE | MO_UW, stw, 2, uint16_t, ADDR_ADD, false)
+DO_VSTR_SG(vstrh_sg_uw, MO_TE | MO_UW, stw, 4, uint32_t, ADDR_ADD, false)
+DO_VSTR_SG(vstrw_sg_uw, MO_TE | MO_UL, stl, 4, uint32_t, ADDR_ADD, false)
DO_VSTR64_SG(vstrd_sg_ud, ADDR_ADD, false)
-DO_VSTR_SG(vstrh_sg_os_uh, MO_TEUW, stw, 2, uint16_t, ADDR_ADD_OSH, false)
-DO_VSTR_SG(vstrh_sg_os_uw, MO_TEUW, stw, 4, uint32_t, ADDR_ADD_OSH, false)
-DO_VSTR_SG(vstrw_sg_os_uw, MO_TEUL, stl, 4, uint32_t, ADDR_ADD_OSW, false)
+DO_VSTR_SG(vstrh_sg_os_uh, MO_TE | MO_UW, stw, 2, uint16_t, ADDR_ADD_OSH, false)
+DO_VSTR_SG(vstrh_sg_os_uw, MO_TE | MO_UW, stw, 4, uint32_t, ADDR_ADD_OSH, false)
+DO_VSTR_SG(vstrw_sg_os_uw, MO_TE | MO_UL, stl, 4, uint32_t, ADDR_ADD_OSW, false)
DO_VSTR64_SG(vstrd_sg_os_ud, ADDR_ADD_OSD, false)
-DO_VLDR_SG(vldrw_sg_wb_uw, MO_TEUL, uint32_t, ldl, 4, uint32_t, uint32_t, ADDR_ADD, true)
+DO_VLDR_SG(vldrw_sg_wb_uw, MO_TE | MO_UL, uint32_t, ldl, 4,
+ uint32_t, uint32_t, ADDR_ADD, true)
DO_VLDR64_SG(vldrd_sg_wb_ud, ADDR_ADD, true)
-DO_VSTR_SG(vstrw_sg_wb_uw, MO_TEUL, stl, 4, uint32_t, ADDR_ADD, true)
+DO_VSTR_SG(vstrw_sg_wb_uw, MO_TE | MO_UL, stl, 4, uint32_t, ADDR_ADD, true)
DO_VSTR64_SG(vstrd_sg_wb_ud, ADDR_ADD, true)
/*
@@ -408,7 +413,7 @@ DO_VSTR64_SG(vstrd_sg_wb_ud, ADDR_ADD, true)
static const uint8_t off[4] = { O1, O2, O3, O4 }; \
uint32_t addr, data; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -434,7 +439,7 @@ DO_VSTR64_SG(vstrd_sg_wb_ud, ADDR_ADD, true)
int y; /* y counts 0 2 0 2 */ \
uint16_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
for (beat = 0, y = 0; beat < 4; beat++, mask >>= 4, y ^= 2) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -461,7 +466,7 @@ DO_VSTR64_SG(vstrd_sg_wb_ud, ADDR_ADD, true)
uint32_t *qd; \
int y; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -500,7 +505,7 @@ DO_VLD4W(vld43w, 6, 7, 8, 9)
uint32_t addr, data; \
uint8_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -526,7 +531,7 @@ DO_VLD4W(vld43w, 6, 7, 8, 9)
int e; \
uint16_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -551,7 +556,7 @@ DO_VLD4W(vld43w, 6, 7, 8, 9)
uint32_t addr, data; \
uint32_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -582,7 +587,7 @@ DO_VLD2W(vld21w, 8, 12, 16, 20)
static const uint8_t off[4] = { O1, O2, O3, O4 }; \
uint32_t addr, data; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -609,7 +614,7 @@ DO_VLD2W(vld21w, 8, 12, 16, 20)
int y; /* y counts 0 2 0 2 */ \
uint16_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
for (beat = 0, y = 0; beat < 4; beat++, mask >>= 4, y ^= 2) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -635,7 +640,7 @@ DO_VLD2W(vld21w, 8, 12, 16, 20)
uint32_t *qd; \
int y; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -674,7 +679,7 @@ DO_VST4W(vst43w, 6, 7, 8, 9)
uint32_t addr, data; \
uint8_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -701,7 +706,7 @@ DO_VST4W(vst43w, 6, 7, 8, 9)
int e; \
uint16_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -727,7 +732,7 @@ DO_VST4W(vst43w, 6, 7, 8, 9)
uint32_t addr, data; \
uint32_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 19/63] target/arm: Hoist MO_TE into mve_advance_vpt()
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (17 preceding siblings ...)
2026-04-27 12:46 ` [PULL 18/63] target/arm: Explode MO_TExx -> MO_TE | MO_xx Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 20/63] target/arm: Hoist MO_TE into MVE DO_VSTR() macro Peter Maydell
` (44 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20260414005348.4767-4-philmd@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/tcg/mve_helper.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/target/arm/tcg/mve_helper.c b/target/arm/tcg/mve_helper.c
index cc58e0502f..fbb64889bf 100644
--- a/target/arm/tcg/mve_helper.c
+++ b/target/arm/tcg/mve_helper.c
@@ -160,7 +160,8 @@ static void mve_advance_vpt(CPUARMState *env)
uint16_t eci_mask = mve_eci_mask(env); \
unsigned b, e; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MFLAG | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MFLAG | MO_ALIGN, \
+ mmu_idx); \
/* \
* R_SXTM allows the dest reg to become UNKNOWN for abandoned \
* beats so we don't care if we update part of the dest and \
@@ -183,7 +184,8 @@ static void mve_advance_vpt(CPUARMState *env)
uint16_t mask = mve_element_mask(env); \
unsigned b, e; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MFLAG | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MFLAG | MO_ALIGN, \
+ mmu_idx); \
for (b = 0, e = 0; b < 16; b += ESIZE, e++) { \
if (mask & (1 << b)) { \
cpu_##STTYPE##_mmu(env, addr, d[H##ESIZE(e)], oi, GETPC()); \
@@ -194,23 +196,23 @@ static void mve_advance_vpt(CPUARMState *env)
}
DO_VLDR(vldrb, MO_UB, 1, uint8_t, ldb, 1, uint8_t)
-DO_VLDR(vldrh, MO_TE | MO_UW, 2, uint16_t, ldw, 2, uint16_t)
-DO_VLDR(vldrw, MO_TE | MO_UL, 4, uint32_t, ldl, 4, uint32_t)
+DO_VLDR(vldrh, MO_UW, 2, uint16_t, ldw, 2, uint16_t)
+DO_VLDR(vldrw, MO_UL, 4, uint32_t, ldl, 4, uint32_t)
DO_VSTR(vstrb, MO_UB, 1, stb, 1, uint8_t)
-DO_VSTR(vstrh, MO_TE | MO_UW, 2, stw, 2, uint16_t)
-DO_VSTR(vstrw, MO_TE | MO_UL, 4, stl, 4, uint32_t)
+DO_VSTR(vstrh, MO_UW, 2, stw, 2, uint16_t)
+DO_VSTR(vstrw, MO_UL, 4, stl, 4, uint32_t)
DO_VLDR(vldrb_sh, MO_SB, 1, int8_t, ldb, 2, int16_t)
DO_VLDR(vldrb_sw, MO_SB, 1, int8_t, ldb, 4, int32_t)
DO_VLDR(vldrb_uh, MO_UB, 1, uint8_t, ldb, 2, uint16_t)
DO_VLDR(vldrb_uw, MO_UB, 1, uint8_t, ldb, 4, uint32_t)
-DO_VLDR(vldrh_sw, MO_TE | MO_SW, 2, int16_t, ldw, 4, int32_t)
-DO_VLDR(vldrh_uw, MO_TE | MO_UW, 2, uint16_t, ldw, 4, uint32_t)
+DO_VLDR(vldrh_sw, MO_SW, 2, int16_t, ldw, 4, int32_t)
+DO_VLDR(vldrh_uw, MO_UW, 2, uint16_t, ldw, 4, uint32_t)
DO_VSTR(vstrb_h, MO_UB, 1, stb, 2, int16_t)
DO_VSTR(vstrb_w, MO_UB, 1, stb, 4, int32_t)
-DO_VSTR(vstrh_w, MO_TE | MO_UW, 2, stw, 4, int32_t)
+DO_VSTR(vstrh_w, MO_UW, 2, stw, 4, int32_t)
#undef DO_VLDR
#undef DO_VSTR
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 20/63] target/arm: Hoist MO_TE into MVE DO_VSTR() macro
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (18 preceding siblings ...)
2026-04-27 12:46 ` [PULL 19/63] target/arm: Hoist MO_TE into mve_advance_vpt() Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 21/63] target/arm: Introduce mo_endian() helper Peter Maydell
` (43 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20260414005348.4767-5-philmd@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/tcg/mve_helper.c | 43 +++++++++++++++++--------------------
1 file changed, 20 insertions(+), 23 deletions(-)
diff --git a/target/arm/tcg/mve_helper.c b/target/arm/tcg/mve_helper.c
index fbb64889bf..4bea0991de 100644
--- a/target/arm/tcg/mve_helper.c
+++ b/target/arm/tcg/mve_helper.c
@@ -235,7 +235,8 @@ DO_VSTR(vstrh_w, MO_UW, 2, stw, 4, int32_t)
unsigned e; \
uint32_t addr; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MFLAG | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MFLAG | MO_ALIGN, \
+ mmu_idx); \
for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE, eci_mask >>= ESIZE) { \
if (!(eci_mask & 1)) { \
continue; \
@@ -262,7 +263,8 @@ DO_VSTR(vstrh_w, MO_UW, 2, stw, 4, int32_t)
unsigned e; \
uint32_t addr; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MFLAG | MO_ALIGN, mmu_idx); \
+ MemOpIdx oi = make_memop_idx(MO_TE | MFLAG | MO_ALIGN, \
+ mmu_idx); \
for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE, eci_mask >>= ESIZE) { \
if (!(eci_mask & 1)) { \
continue; \
@@ -347,47 +349,42 @@ DO_VSTR(vstrh_w, MO_UW, 2, stw, 4, int32_t)
DO_VLDR_SG(vldrb_sg_sh, MO_SB, int8_t, ldb, 2, int16_t, uint16_t, ADDR_ADD, false)
DO_VLDR_SG(vldrb_sg_sw, MO_SB, int8_t, ldb, 4, int32_t, uint32_t, ADDR_ADD, false)
-DO_VLDR_SG(vldrh_sg_sw, MO_TE | MO_SW, int16_t, ldw, 4,
- int32_t, uint32_t, ADDR_ADD, false)
+DO_VLDR_SG(vldrh_sg_sw, MO_SW, int16_t, ldw, 4, int32_t, uint32_t, ADDR_ADD, false)
DO_VLDR_SG(vldrb_sg_ub, MO_UB, uint8_t, ldb, 1, uint8_t, uint8_t, ADDR_ADD, false)
DO_VLDR_SG(vldrb_sg_uh, MO_UB, uint8_t, ldb, 2, uint16_t, uint16_t, ADDR_ADD, false)
DO_VLDR_SG(vldrb_sg_uw, MO_UB, uint8_t, ldb, 4, uint32_t, uint32_t, ADDR_ADD, false)
-DO_VLDR_SG(vldrh_sg_uh, MO_TE | MO_UW, uint16_t, ldw, 2,
- uint16_t, uint16_t, ADDR_ADD, false)
-DO_VLDR_SG(vldrh_sg_uw, MO_TE | MO_UW, uint16_t, ldw, 4,
- uint32_t, uint32_t, ADDR_ADD, false)
-DO_VLDR_SG(vldrw_sg_uw, MO_TE | MO_UL, uint32_t, ldl, 4,
- uint32_t, uint32_t, ADDR_ADD, false)
+DO_VLDR_SG(vldrh_sg_uh, MO_UW, uint16_t, ldw, 2, uint16_t, uint16_t, ADDR_ADD, false)
+DO_VLDR_SG(vldrh_sg_uw, MO_UW, uint16_t, ldw, 4, uint32_t, uint32_t, ADDR_ADD, false)
+DO_VLDR_SG(vldrw_sg_uw, MO_UL, uint32_t, ldl, 4, uint32_t, uint32_t, ADDR_ADD, false)
DO_VLDR64_SG(vldrd_sg_ud, ADDR_ADD, false)
-DO_VLDR_SG(vldrh_sg_os_sw, MO_TE | MO_SW, int16_t, ldw, 4,
+DO_VLDR_SG(vldrh_sg_os_sw, MO_SW, int16_t, ldw, 4,
int32_t, uint32_t, ADDR_ADD_OSH, false)
-DO_VLDR_SG(vldrh_sg_os_uh, MO_TE | MO_UW, uint16_t, ldw, 2,
+DO_VLDR_SG(vldrh_sg_os_uh, MO_UW, uint16_t, ldw, 2,
uint16_t, uint16_t, ADDR_ADD_OSH, false)
-DO_VLDR_SG(vldrh_sg_os_uw, MO_TE | MO_UW, uint16_t, ldw, 4,
+DO_VLDR_SG(vldrh_sg_os_uw, MO_UW, uint16_t, ldw, 4,
uint32_t, uint32_t, ADDR_ADD_OSH, false)
-DO_VLDR_SG(vldrw_sg_os_uw, MO_TE | MO_UL, uint32_t, ldl, 4,
+DO_VLDR_SG(vldrw_sg_os_uw, MO_UL, uint32_t, ldl, 4,
uint32_t, uint32_t, ADDR_ADD_OSW, false)
DO_VLDR64_SG(vldrd_sg_os_ud, ADDR_ADD_OSD, false)
DO_VSTR_SG(vstrb_sg_ub, MO_UB, stb, 1, uint8_t, ADDR_ADD, false)
DO_VSTR_SG(vstrb_sg_uh, MO_UB, stb, 2, uint16_t, ADDR_ADD, false)
DO_VSTR_SG(vstrb_sg_uw, MO_UB, stb, 4, uint32_t, ADDR_ADD, false)
-DO_VSTR_SG(vstrh_sg_uh, MO_TE | MO_UW, stw, 2, uint16_t, ADDR_ADD, false)
-DO_VSTR_SG(vstrh_sg_uw, MO_TE | MO_UW, stw, 4, uint32_t, ADDR_ADD, false)
-DO_VSTR_SG(vstrw_sg_uw, MO_TE | MO_UL, stl, 4, uint32_t, ADDR_ADD, false)
+DO_VSTR_SG(vstrh_sg_uh, MO_UW, stw, 2, uint16_t, ADDR_ADD, false)
+DO_VSTR_SG(vstrh_sg_uw, MO_UW, stw, 4, uint32_t, ADDR_ADD, false)
+DO_VSTR_SG(vstrw_sg_uw, MO_UL, stl, 4, uint32_t, ADDR_ADD, false)
DO_VSTR64_SG(vstrd_sg_ud, ADDR_ADD, false)
-DO_VSTR_SG(vstrh_sg_os_uh, MO_TE | MO_UW, stw, 2, uint16_t, ADDR_ADD_OSH, false)
-DO_VSTR_SG(vstrh_sg_os_uw, MO_TE | MO_UW, stw, 4, uint32_t, ADDR_ADD_OSH, false)
-DO_VSTR_SG(vstrw_sg_os_uw, MO_TE | MO_UL, stl, 4, uint32_t, ADDR_ADD_OSW, false)
+DO_VSTR_SG(vstrh_sg_os_uh, MO_UW, stw, 2, uint16_t, ADDR_ADD_OSH, false)
+DO_VSTR_SG(vstrh_sg_os_uw, MO_UW, stw, 4, uint32_t, ADDR_ADD_OSH, false)
+DO_VSTR_SG(vstrw_sg_os_uw, MO_UL, stl, 4, uint32_t, ADDR_ADD_OSW, false)
DO_VSTR64_SG(vstrd_sg_os_ud, ADDR_ADD_OSD, false)
-DO_VLDR_SG(vldrw_sg_wb_uw, MO_TE | MO_UL, uint32_t, ldl, 4,
- uint32_t, uint32_t, ADDR_ADD, true)
+DO_VLDR_SG(vldrw_sg_wb_uw, MO_UL, uint32_t, ldl, 4, uint32_t, uint32_t, ADDR_ADD, true)
DO_VLDR64_SG(vldrd_sg_wb_ud, ADDR_ADD, true)
-DO_VSTR_SG(vstrw_sg_wb_uw, MO_TE | MO_UL, stl, 4, uint32_t, ADDR_ADD, true)
+DO_VSTR_SG(vstrw_sg_wb_uw, MO_UL, stl, 4, uint32_t, ADDR_ADD, true)
DO_VSTR64_SG(vstrd_sg_wb_ud, ADDR_ADD, true)
/*
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 21/63] target/arm: Introduce mo_endian() helper
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (19 preceding siblings ...)
2026-04-27 12:46 ` [PULL 20/63] target/arm: Hoist MO_TE into MVE DO_VSTR() macro Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 22/63] target/arm: Replace MO_TE -> mo_endian() for MVE helpers Peter Maydell
` (42 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20260414005348.4767-6-philmd@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/internals.h | 6 ++++++
target/arm/tcg/mve_helper.c | 3 ++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index af5e9a1acf..06655409e5 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -28,6 +28,7 @@
#include "exec/hwaddr.h"
#include "exec/vaddr.h"
#include "exec/breakpoint.h"
+#include "exec/memop.h"
#include "accel/tcg/tb-cpu-state.h"
#include "hw/core/registerfields.h"
#include "tcg/tcg-gvec-desc.h"
@@ -46,6 +47,11 @@
#define BANK_HYP 6
#define BANK_MON 7
+static inline MemOp mo_endian(CPUARMState *env)
+{
+ return EX_TBFLAG_ANY(env->hflags, BE_DATA) ? MO_BE : MO_LE;
+}
+
static inline int arm_env_mmu_index(CPUARMState *env)
{
return EX_TBFLAG_ANY(env->hflags, MMUIDX);
diff --git a/target/arm/tcg/mve_helper.c b/target/arm/tcg/mve_helper.c
index 4bea0991de..a5a23c9705 100644
--- a/target/arm/tcg/mve_helper.c
+++ b/target/arm/tcg/mve_helper.c
@@ -299,7 +299,8 @@ DO_VSTR(vstrh_w, MO_UW, 2, stw, 4, int32_t)
unsigned e; \
uint32_t addr; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN, \
+ mmu_idx); \
for (e = 0; e < 16 / 4; e++, mask >>= 4, eci_mask >>= 4) { \
if (!(eci_mask & 1)) { \
continue; \
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 22/63] target/arm: Replace MO_TE -> mo_endian() for MVE helpers
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (20 preceding siblings ...)
2026-04-27 12:46 ` [PULL 21/63] target/arm: Introduce mo_endian() helper Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 23/63] target/arm: Compile mve_helper.c once Peter Maydell
` (41 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20260414005348.4767-7-philmd@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/tcg/mve_helper.c | 47 +++++++++++++++++++++++--------------
1 file changed, 30 insertions(+), 17 deletions(-)
diff --git a/target/arm/tcg/mve_helper.c b/target/arm/tcg/mve_helper.c
index a5a23c9705..64ab804abc 100644
--- a/target/arm/tcg/mve_helper.c
+++ b/target/arm/tcg/mve_helper.c
@@ -160,7 +160,7 @@ static void mve_advance_vpt(CPUARMState *env)
uint16_t eci_mask = mve_eci_mask(env); \
unsigned b, e; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MFLAG | MO_ALIGN, \
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MFLAG | MO_ALIGN, \
mmu_idx); \
/* \
* R_SXTM allows the dest reg to become UNKNOWN for abandoned \
@@ -184,7 +184,7 @@ static void mve_advance_vpt(CPUARMState *env)
uint16_t mask = mve_element_mask(env); \
unsigned b, e; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MFLAG | MO_ALIGN, \
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MFLAG | MO_ALIGN, \
mmu_idx); \
for (b = 0, e = 0; b < 16; b += ESIZE, e++) { \
if (mask & (1 << b)) { \
@@ -235,7 +235,7 @@ DO_VSTR(vstrh_w, MO_UW, 2, stw, 4, int32_t)
unsigned e; \
uint32_t addr; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MFLAG | MO_ALIGN, \
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MFLAG | MO_ALIGN, \
mmu_idx); \
for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE, eci_mask >>= ESIZE) { \
if (!(eci_mask & 1)) { \
@@ -263,7 +263,7 @@ DO_VSTR(vstrh_w, MO_UW, 2, stw, 4, int32_t)
unsigned e; \
uint32_t addr; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MFLAG | MO_ALIGN, \
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MFLAG | MO_ALIGN, \
mmu_idx); \
for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE, eci_mask >>= ESIZE) { \
if (!(eci_mask & 1)) { \
@@ -326,7 +326,8 @@ DO_VSTR(vstrh_w, MO_UW, 2, stw, 4, int32_t)
unsigned e; \
uint32_t addr; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN, \
+ mmu_idx); \
for (e = 0; e < 16 / 4; e++, mask >>= 4, eci_mask >>= 4) { \
if (!(eci_mask & 1)) { \
continue; \
@@ -413,7 +414,8 @@ DO_VSTR64_SG(vstrd_sg_wb_ud, ADDR_ADD, true)
static const uint8_t off[4] = { O1, O2, O3, O4 }; \
uint32_t addr, data; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN, \
+ mmu_idx); \
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -439,7 +441,8 @@ DO_VSTR64_SG(vstrd_sg_wb_ud, ADDR_ADD, true)
int y; /* y counts 0 2 0 2 */ \
uint16_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN, \
+ mmu_idx); \
for (beat = 0, y = 0; beat < 4; beat++, mask >>= 4, y ^= 2) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -466,7 +469,8 @@ DO_VSTR64_SG(vstrd_sg_wb_ud, ADDR_ADD, true)
uint32_t *qd; \
int y; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN, \
+ mmu_idx); \
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -505,7 +509,8 @@ DO_VLD4W(vld43w, 6, 7, 8, 9)
uint32_t addr, data; \
uint8_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN, \
+ mmu_idx); \
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -531,7 +536,8 @@ DO_VLD4W(vld43w, 6, 7, 8, 9)
int e; \
uint16_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN, \
+ mmu_idx); \
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -556,7 +562,8 @@ DO_VLD4W(vld43w, 6, 7, 8, 9)
uint32_t addr, data; \
uint32_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN, \
+ mmu_idx); \
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -587,7 +594,8 @@ DO_VLD2W(vld21w, 8, 12, 16, 20)
static const uint8_t off[4] = { O1, O2, O3, O4 }; \
uint32_t addr, data; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN, \
+ mmu_idx); \
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -614,7 +622,8 @@ DO_VLD2W(vld21w, 8, 12, 16, 20)
int y; /* y counts 0 2 0 2 */ \
uint16_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN, \
+ mmu_idx); \
for (beat = 0, y = 0; beat < 4; beat++, mask >>= 4, y ^= 2) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -640,7 +649,8 @@ DO_VLD2W(vld21w, 8, 12, 16, 20)
uint32_t *qd; \
int y; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN, \
+ mmu_idx); \
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -679,7 +689,8 @@ DO_VST4W(vst43w, 6, 7, 8, 9)
uint32_t addr, data; \
uint8_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN, \
+ mmu_idx); \
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -706,7 +717,8 @@ DO_VST4W(vst43w, 6, 7, 8, 9)
int e; \
uint16_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN, \
+ mmu_idx); \
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
@@ -732,7 +744,8 @@ DO_VST4W(vst43w, 6, 7, 8, 9)
uint32_t addr, data; \
uint32_t *qd; \
int mmu_idx = arm_to_core_mmu_idx(arm_mmu_idx(env)); \
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN, mmu_idx);\
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN, \
+ mmu_idx); \
for (beat = 0; beat < 4; beat++, mask >>= 4) { \
if ((mask & 1) == 0) { \
/* ECI says skip this beat */ \
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 23/63] target/arm: Compile mve_helper.c once
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (21 preceding siblings ...)
2026-04-27 12:46 ` [PULL 22/63] target/arm: Replace MO_TE -> mo_endian() for MVE helpers Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 24/63] target/arm: Replace MO_TE -> mo_endian() for Cortex-M helpers Peter Maydell
` (40 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20260414005348.4767-8-philmd@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/tcg/meson.build | 3 ++-
target/arm/tcg/mve_helper.c | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
index 506f031f1a..95e9da151e 100644
--- a/target/arm/tcg/meson.build
+++ b/target/arm/tcg/meson.build
@@ -33,7 +33,6 @@ arm_ss.add(when: 'TARGET_AARCH64', if_false: files('stubs32.c'))
arm_ss.add(files(
'cpu32.c',
'm_helper.c',
- 'mve_helper.c',
))
arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
@@ -71,6 +70,7 @@ arm_common_system_ss.add(
'debug.c',
'hflags.c',
'gengvec.c',
+ 'mve_helper.c',
'neon_helper.c',
'op_helper.c',
'psci.c',
@@ -94,6 +94,7 @@ arm_user_ss.add(
'debug.c',
'gengvec.c',
'hflags.c',
+ 'mve_helper.c',
'neon_helper.c',
'op_helper.c',
'tlb_helper.c',
diff --git a/target/arm/tcg/mve_helper.c b/target/arm/tcg/mve_helper.c
index 64ab804abc..09ae233416 100644
--- a/target/arm/tcg/mve_helper.c
+++ b/target/arm/tcg/mve_helper.c
@@ -23,7 +23,7 @@
#include "helper-mve.h"
#include "internals.h"
#include "vec_internal.h"
-#include "accel/tcg/cpu-ldst.h"
+#include "accel/tcg/cpu-ldst-common.h"
#include "tcg/tcg.h"
#include "fpu/softfloat.h"
#include "crypto/clmul.h"
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 24/63] target/arm: Replace MO_TE -> mo_endian() for Cortex-M helpers
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (22 preceding siblings ...)
2026-04-27 12:46 ` [PULL 23/63] target/arm: Compile mve_helper.c once Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:46 ` [PULL 25/63] target/arm: Compile m_helper.c once Peter Maydell
` (39 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20260414005348.4767-9-philmd@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/tcg/m_helper.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/target/arm/tcg/m_helper.c b/target/arm/tcg/m_helper.c
index f5954ce9bf..1bec8e9aea 100644
--- a/target/arm/tcg/m_helper.c
+++ b/target/arm/tcg/m_helper.c
@@ -634,7 +634,7 @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
/* Note that these stores can throw exceptions on MPU faults */
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN,
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN,
arm_to_core_mmu_idx(mmu_idx));
cpu_stl_mmu(env, sp, nextinst, oi, GETPC());
cpu_stl_mmu(env, sp + 4, saved_psr, oi, GETPC());
@@ -1055,7 +1055,7 @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK;
uintptr_t ra = GETPC();
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN,
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN,
arm_to_core_mmu_idx(mmu_idx));
assert(env->v7m.secure);
@@ -1131,7 +1131,7 @@ void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
ARMCPU *cpu = env_archcpu(env);
uintptr_t ra = GETPC();
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
- MemOpIdx oi = make_memop_idx(MO_TE | MO_UL | MO_ALIGN,
+ MemOpIdx oi = make_memop_idx(mo_endian(env) | MO_UL | MO_ALIGN,
arm_to_core_mmu_idx(mmu_idx));
/* fptr is the value of Rn, the frame pointer we load the FP regs from */
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 25/63] target/arm: Compile m_helper.c once
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (23 preceding siblings ...)
2026-04-27 12:46 ` [PULL 24/63] target/arm: Replace MO_TE -> mo_endian() for Cortex-M helpers Peter Maydell
@ 2026-04-27 12:46 ` Peter Maydell
2026-04-27 12:47 ` [PULL 26/63] hw/arm: Remove hw_error() for the unimplemented CM_LMBUSCNT register Peter Maydell
` (38 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:46 UTC (permalink / raw)
To: qemu-devel
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20260414005348.4767-10-philmd@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/tcg/m_helper.c | 2 +-
target/arm/tcg/meson.build | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/target/arm/tcg/m_helper.c b/target/arm/tcg/m_helper.c
index 1bec8e9aea..f2059ed8b0 100644
--- a/target/arm/tcg/m_helper.c
+++ b/target/arm/tcg/m_helper.c
@@ -17,7 +17,7 @@
#include "qemu/log.h"
#include "exec/page-protection.h"
#ifdef CONFIG_TCG
-#include "accel/tcg/cpu-ldst.h"
+#include "accel/tcg/cpu-ldst-common.h"
#include "semihosting/common-semi.h"
#endif
#if !defined(CONFIG_USER_ONLY)
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
index 95e9da151e..02774409e5 100644
--- a/target/arm/tcg/meson.build
+++ b/target/arm/tcg/meson.build
@@ -32,7 +32,6 @@ arm_ss.add(when: 'TARGET_AARCH64', if_false: files('stubs32.c'))
arm_ss.add(files(
'cpu32.c',
- 'm_helper.c',
))
arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
@@ -70,6 +69,7 @@ arm_common_system_ss.add(
'debug.c',
'hflags.c',
'gengvec.c',
+ 'm_helper.c',
'mve_helper.c',
'neon_helper.c',
'op_helper.c',
@@ -94,6 +94,7 @@ arm_user_ss.add(
'debug.c',
'gengvec.c',
'hflags.c',
+ 'm_helper.c',
'mve_helper.c',
'neon_helper.c',
'op_helper.c',
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 26/63] hw/arm: Remove hw_error() for the unimplemented CM_LMBUSCNT register
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (24 preceding siblings ...)
2026-04-27 12:46 ` [PULL 25/63] target/arm: Compile m_helper.c once Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 27/63] hw: Move ARM_SYSCTL_GPIO definitions to arm sysctl specific header Peter Maydell
` (37 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Thomas Huth <thuth@redhat.com>
When writing to this register, QEMU currently aborts:
$ echo "readl 0x10000018" | ./qemu-system-arm -audiodev none,id=snd0 \
-M integratorcp,accel=qtest,audiodev=snd0 -display none -qtest stdio
[I 0.000000] OPENED
[R +0.001907] readl 0x10000018
qemu: hardware error: integratorcm_read: CM_LMBUSCNT
[...]
Aborted (core dumped)
This is bad, a guest should ideally never be able to kill QEMU like this.
Now, according to the "Intergrator/CP User Guide" from:
https://developer.arm.com/documentation/dui0159/b/porting-integrator-ap-and-im-pd1/registers
"The Integrator/AP CM_LMBUSCNT has been removed."
That means this register does not seem to be implemented on real CP boards
at all, only for older AP boards. Thus it should be fine if we simply
ignore this register in QEMU and handle it like all other unimplemented
registers in the "default" handler of the case statement.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3407
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20260420064933.64765-1-thuth@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/integratorcp.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index 03633f3d4f..164af03f7b 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -106,9 +106,6 @@ static uint64_t integratorcm_read(void *opaque, hwaddr offset,
} else {
return s->cm_lock;
}
- case 6: /* CM_LMBUSCNT */
- /* ??? High frequency timer. */
- hw_error("integratorcm_read: CM_LMBUSCNT");
case 7: /* CM_AUXOSC */
return s->cm_auxosc;
case 8: /* CM_SDRAM */
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 27/63] hw: Move ARM_SYSCTL_GPIO definitions to arm sysctl specific header
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (25 preceding siblings ...)
2026-04-27 12:47 ` [PULL 26/63] hw/arm: Remove hw_error() for the unimplemented CM_LMBUSCNT register Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 28/63] target/arm: Clear AArch64 ID regs from ARMISARegisters if AArch64 disabled Peter Maydell
` (36 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
include/hw/arm/primecell.h used to be more expansive, but now the
only thing it defines is the ARM_SYSCTL_GPIO_* constants for the GPIO
lines for the arm-sysctl system-control device used on the Realview,
Versatile and Versatile Express boards.
Replace it with a header file specific to that device.
virt.c and vmapple.c included primecell.h despite not using the
constants it defined; there we can simply drop the include entirely.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20260416172627.690396-1-peter.maydell@linaro.org
---
MAINTAINERS | 2 +-
hw/arm/realview.c | 2 +-
hw/arm/vexpress.c | 2 +-
hw/arm/virt.c | 1 -
hw/misc/arm_sysctl.c | 2 +-
hw/vmapple/vmapple.c | 1 -
include/hw/arm/primecell.h | 12 ------------
include/hw/misc/arm_sysctl.h | 16 ++++++++++++++++
8 files changed, 20 insertions(+), 18 deletions(-)
delete mode 100644 include/hw/arm/primecell.h
create mode 100644 include/hw/misc/arm_sysctl.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 8d980d6c40..50a8e161c6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -759,7 +759,6 @@ F: hw/ssi/pl022.c
F: include/hw/ssi/pl022.h
F: hw/rtc/pl031.c
F: include/hw/rtc/pl031.h
-F: include/hw/arm/primecell.h
F: hw/timer/cmsdk-apb-timer.c
F: include/hw/timer/cmsdk-apb-timer.h
F: tests/qtest/cmsdk-apb-timer-test.c
@@ -1113,6 +1112,7 @@ F: hw/*/versatile*
F: hw/i2c/arm_sbcon_i2c.c
F: include/hw/i2c/arm_sbcon_i2c.h
F: hw/misc/arm_sysctl.c
+F: include/hw/misc/arm_sysctl.h
F: docs/system/arm/versatile.rst
Virt
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 7c49995c80..2b9f3271d6 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -12,9 +12,9 @@
#include "target/arm/cpu.h"
#include "hw/core/sysbus.h"
#include "hw/arm/boot.h"
-#include "hw/arm/primecell.h"
#include "hw/arm/machines-qom.h"
#include "hw/core/split-irq.h"
+#include "hw/misc/arm_sysctl.h"
#include "hw/net/lan9118.h"
#include "hw/net/smc91c111.h"
#include "hw/pci/pci.h"
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index b178798085..f26d8c6f8d 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -26,8 +26,8 @@
#include "qemu/datadir.h"
#include "hw/core/sysbus.h"
#include "hw/arm/boot.h"
-#include "hw/arm/primecell.h"
#include "hw/arm/machines-qom.h"
+#include "hw/misc/arm_sysctl.h"
#include "hw/net/lan9118.h"
#include "hw/i2c/i2c.h"
#include "net/net.h"
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f62253e1ab..77891f0820 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -36,7 +36,6 @@
#include "monitor/qdev.h"
#include "hw/core/sysbus.h"
#include "hw/arm/boot.h"
-#include "hw/arm/primecell.h"
#include "hw/arm/virt.h"
#include "hw/arm/machines-qom.h"
#include "hw/block/flash.h"
diff --git a/hw/misc/arm_sysctl.c b/hw/misc/arm_sysctl.c
index 7b320f89c1..ebc95b9bb5 100644
--- a/hw/misc/arm_sysctl.c
+++ b/hw/misc/arm_sysctl.c
@@ -14,8 +14,8 @@
#include "system/runstate.h"
#include "qemu/bitops.h"
#include "hw/core/sysbus.h"
+#include "hw/misc/arm_sysctl.h"
#include "migration/vmstate.h"
-#include "hw/arm/primecell.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qom/object.h"
diff --git a/hw/vmapple/vmapple.c b/hw/vmapple/vmapple.c
index b1379eafef..607181f517 100644
--- a/hw/vmapple/vmapple.c
+++ b/hw/vmapple/vmapple.c
@@ -32,7 +32,6 @@
#include "hw/core/sysbus.h"
#include "hw/usb/usb.h"
#include "hw/arm/boot.h"
-#include "hw/arm/primecell.h"
#include "hw/char/pl011.h"
#include "hw/intc/arm_gic.h"
#include "hw/intc/arm_gicv3_common.h"
diff --git a/include/hw/arm/primecell.h b/include/hw/arm/primecell.h
deleted file mode 100644
index 7337c3b3ca..0000000000
--- a/include/hw/arm/primecell.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef PRIMECELL_H
-#define PRIMECELL_H
-
-/* Declarations for ARM PrimeCell based periperals. */
-/* Also includes some devices that are currently only used by the
- ARM boards. */
-
-/* arm_sysctl GPIO lines */
-#define ARM_SYSCTL_GPIO_MMC_WPROT 0
-#define ARM_SYSCTL_GPIO_MMC_CARDIN 1
-
-#endif
diff --git a/include/hw/misc/arm_sysctl.h b/include/hw/misc/arm_sysctl.h
new file mode 100644
index 0000000000..424069cd6e
--- /dev/null
+++ b/include/hw/misc/arm_sysctl.h
@@ -0,0 +1,16 @@
+/*
+ * Status and system control registers for ARM RealView/Versatile boards.
+ *
+ * Copyright (c) Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_MISC_ARM_SYSCTL_H
+#define HW_MISC_ARM_SYSCTL_H
+
+/* arm_sysctl inbound GPIO lines */
+#define ARM_SYSCTL_GPIO_MMC_WPROT 0
+#define ARM_SYSCTL_GPIO_MMC_CARDIN 1
+
+#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 28/63] target/arm: Clear AArch64 ID regs from ARMISARegisters if AArch64 disabled
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (26 preceding siblings ...)
2026-04-27 12:47 ` [PULL 27/63] hw: Move ARM_SYSCTL_GPIO definitions to arm sysctl specific header Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 29/63] target/arm: Allow 'aarch64=off' to be set for TCG CPUs Peter Maydell
` (35 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
If we create a normally-AArch64 CPU and configure it with
aarch64=off, this will by default leave all the AArch64 ID register
values in its ARMISARegisters struct untouched. That in turn means
that tests of cpu_isar_feature(aa64_something, cpu) will return true.
Until now we have had a design policy that you shouldn't check an
aa64_ feature unless you know that the CPU has AArch64; but this is
quite fragile as it's easy to forget and only causes a problem in the
corner case where AArch64 was turned off. In particular, when we
extend the ability to disable AArch64 from only KVM to also TCG there
are many more aa64 feature check points which we would otherwise have
to audit for whether they needed to be guarded with a check on
ARM_FEATURE_AARCH64.
Instead, make the CPU realize function zero out all the 64-bit ID
registers if a TCG CPU doesn't have AArch64; this will make aa64_
feature tests generally return false.
We only do this for TCG because only TCG really needs it, and for
KVM it might be confusing to have QEMU's idea of the ID registers
be different from KVM's.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20260416165353.589569-2-peter.maydell@linaro.org
---
target/arm/cpu.c | 35 +++++++++++++++++++++++++++++++++++
target/arm/cpu.h | 3 ++-
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index b62de8addf..6705ee9db7 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1606,6 +1606,27 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
}
}
+static void arm_clear_aarch64_idregs(ARMCPU *cpu)
+{
+ /* Zero out all the AArch64 ID registers in ARMISARegisters */
+ SET_IDREG(&cpu->isar, ID_AA64ISAR0, 0);
+ SET_IDREG(&cpu->isar, ID_AA64ISAR1, 0);
+ SET_IDREG(&cpu->isar, ID_AA64ISAR2, 0);
+ SET_IDREG(&cpu->isar, ID_AA64PFR0, 0);
+ SET_IDREG(&cpu->isar, ID_AA64PFR1, 0);
+ SET_IDREG(&cpu->isar, ID_AA64PFR2, 0);
+ SET_IDREG(&cpu->isar, ID_AA64MMFR0, 0);
+ SET_IDREG(&cpu->isar, ID_AA64MMFR1, 0);
+ SET_IDREG(&cpu->isar, ID_AA64MMFR2, 0);
+ SET_IDREG(&cpu->isar, ID_AA64MMFR3, 0);
+ SET_IDREG(&cpu->isar, ID_AA64DFR0, 0);
+ SET_IDREG(&cpu->isar, ID_AA64DFR1, 0);
+ SET_IDREG(&cpu->isar, ID_AA64AFR0, 0);
+ SET_IDREG(&cpu->isar, ID_AA64AFR1, 0);
+ SET_IDREG(&cpu->isar, ID_AA64ZFR0, 0);
+ SET_IDREG(&cpu->isar, ID_AA64SMFR0, 0);
+}
+
static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
@@ -1733,6 +1754,20 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
}
#endif
+ /*
+ * A TCG aarch64=off CPU has no AArch64 at all, so we clear out the
+ * ID registers to avoid cpu_isar_feature(aa64_something, cpu) tests
+ * incorrectly returning true. We don't do this for other accelerators
+ * (which in practice means "for KVM", since no others have AArch32
+ * guest support) because from KVM's point of view the AArch64 ID
+ * registers still exist and must have their correct values. So we
+ * avoid clearing them out so that we don't have QEMU and KVM with
+ * different ideas of the ID registers.
+ */
+ if (tcg_enabled() && !arm_feature(env, ARM_FEATURE_AARCH64)) {
+ arm_clear_aarch64_idregs(cpu);
+ }
+
#ifdef CONFIG_USER_ONLY
/*
* User mode relies on IC IVAU instructions to catch modification of
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 657ff4ab20..ab6bacf4aa 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1080,7 +1080,8 @@ struct ArchCPU {
* Note that if you add an ID register to the ARMISARegisters struct
* you need to also update the 32-bit and 64-bit versions of the
* kvm_arm_get_host_cpu_features() function to correctly populate the
- * field by reading the value from the KVM vCPU.
+ * field by reading the value from the KVM vCPU. If it is an AArch64
+ * ID register then you also must update arm_clear_aarch64_idregs().
*/
struct ARMISARegisters {
uint32_t mvfr0;
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 29/63] target/arm: Allow 'aarch64=off' to be set for TCG CPUs
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (27 preceding siblings ...)
2026-04-27 12:47 ` [PULL 28/63] target/arm: Clear AArch64 ID regs from ARMISARegisters if AArch64 disabled Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 30/63] tests/functional/aarch64: Add basic test of TCG aarch64=off Peter Maydell
` (34 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
Allow the 'aarch64=off' property, which is currently KVM-only, to
be set for TCG CPUs also.
Note that we don't permit it on the qemu-aarch64 user-mode binary:
this makes no sense as that executable can only handle AArch64
syscalls (and it would also assert at startup since it doesn't
compile in the A32-specific GDB xml files like arm-neon.xml).
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Clément Chigot <chigot@adacore.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20260416165353.589569-3-peter.maydell@linaro.org
---
docs/system/arm/cpu-features.rst | 10 +++++----
target/arm/cpu-features.h | 5 +++++
target/arm/cpu.c | 36 ++++++++++++++++++++++++++++----
tests/qtest/arm-cpu-features.c | 8 ++-----
4 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
index ce19ae6a04..10b0eff27e 100644
--- a/docs/system/arm/cpu-features.rst
+++ b/docs/system/arm/cpu-features.rst
@@ -23,10 +23,12 @@ not implement ARMv8-A, will not have the ``aarch64`` CPU property.
QEMU's support may be limited for some CPU features, only partially
supporting the feature or only supporting the feature under certain
configurations. For example, the ``aarch64`` CPU feature, which, when
-disabled, enables the optional AArch32 CPU feature, is only supported
-when using the KVM accelerator and when running on a host CPU type that
-supports the feature. While ``aarch64`` currently only works with KVM,
-it could work with TCG. CPU features that are specific to KVM are
+disabled, enables the optional AArch32 CPU feature, can only be set to
+``off`` on the TCG and KVM accelerators, and it cannot be set to
+``off`` under KVM unless running on a host CPU type that supports
+running guests in AArch32.
+
+CPU features that are inherently specific to KVM are
prefixed with "kvm-" and are described in "KVM VCPU Features".
CPU Feature Probing
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index b683c9551a..6e5212ff6c 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -1071,6 +1071,11 @@ static inline bool isar_feature_aa64_aa32_el2(const ARMISARegisters *id)
return FIELD_EX64_IDREG(id, ID_AA64PFR0, EL2) >= 2;
}
+static inline bool isar_feature_aa64_aa32_el3(const ARMISARegisters *id)
+{
+ return FIELD_EX64_IDREG(id, ID_AA64PFR0, EL3) >= 2;
+}
+
static inline bool isar_feature_aa64_ras(const ARMISARegisters *id)
{
return FIELD_EX64_IDREG(id, ID_AA64PFR0, RAS) != 0;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 6705ee9db7..9b80dda140 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1244,10 +1244,38 @@ static void aarch64_cpu_set_aarch64(Object *obj, bool value, Error **errp)
* uniform execution state like do_interrupt.
*/
if (value == false) {
- if (!kvm_enabled() || !kvm_arm_aarch32_supported()) {
- error_setg(errp, "'aarch64' feature cannot be disabled "
- "unless KVM is enabled and 32-bit EL1 "
- "is supported");
+ if (kvm_enabled()) {
+ if (!kvm_arm_aarch32_supported()) {
+ error_setg(errp, "'aarch64' feature cannot be disabled for KVM "
+ "because this host does not support 32-bit EL1");
+ return;
+ }
+ } else if (tcg_enabled()) {
+#ifdef CONFIG_USER_ONLY
+ error_setg(errp, "'aarch64' feature cannot be disabled for "
+ "usermode emulator qemu-aarch64; use qemu-arm instead");
+ return;
+#else
+ bool aa32_at_highest_el;
+ if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
+ aa32_at_highest_el = cpu_isar_feature(aa64_aa32_el3, cpu);
+ } else if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) {
+ aa32_at_highest_el = cpu_isar_feature(aa64_aa32_el2, cpu);
+ } else {
+ aa32_at_highest_el = cpu_isar_feature(aa64_aa32_el1, cpu);
+ }
+
+ if (!aa32_at_highest_el) {
+ error_setg(errp, "'aarch64' feature cannot be disabled for "
+ "this TCG CPU because it does not support 32-bit "
+ "execution at its highest implemented exception "
+ "level");
+ return;
+ }
+#endif
+ } else {
+ error_setg(errp, "'aarch64' feature cannot be disabled for "
+ "this accelerator");
return;
}
unset_feature(&cpu->env, ARM_FEATURE_AARCH64);
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
index bbdd89a81d..cb4d01fd46 100644
--- a/tests/qtest/arm-cpu-features.c
+++ b/tests/qtest/arm-cpu-features.c
@@ -493,12 +493,8 @@ static void test_query_cpu_model_expansion(const void *data)
sve_tests_default(qts, "max");
pauth_tests_default(qts, "max");
- /* Test that features that depend on KVM generate errors without. */
- assert_error(qts, "max",
- "'aarch64' feature cannot be disabled "
- "unless KVM is enabled and 32-bit EL1 "
- "is supported",
- "{ 'aarch64': false }");
+ /* TCG allows us to turn off AArch64 on the 'max' CPU type */
+ assert_set_feature(qts, "max", "aarch64", false);
}
qtest_quit(qts);
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 30/63] tests/functional/aarch64: Add basic test of TCG aarch64=off
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (28 preceding siblings ...)
2026-04-27 12:47 ` [PULL 29/63] target/arm: Allow 'aarch64=off' to be set for TCG CPUs Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 31/63] target/arm/cpu: Introduce the infrastructure for cpreg migration tolerances Peter Maydell
` (33 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
Add a basic test of the TCG 'aarch64=off' functionality; this is the
same as our existing arm/test_virt test, but it runs the AArch32
guest kernel on qemu-system-aarch64 with -cpu max,aarch64=off.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20260416165353.589569-4-peter.maydell@linaro.org
---
tests/functional/aarch64/meson.build | 1 +
.../aarch64/test_virt_aarch64_off.py | 37 +++++++++++++++++++
2 files changed, 38 insertions(+)
create mode 100755 tests/functional/aarch64/test_virt_aarch64_off.py
diff --git a/tests/functional/aarch64/meson.build b/tests/functional/aarch64/meson.build
index 1067f181f2..9803f66299 100644
--- a/tests/functional/aarch64/meson.build
+++ b/tests/functional/aarch64/meson.build
@@ -47,6 +47,7 @@ tests_aarch64_system_thorough = [
'tcg_plugins',
'tuxrun',
'virt',
+ 'virt_aarch64_off',
'virt_gpu',
'virt_vbsa',
'xen',
diff --git a/tests/functional/aarch64/test_virt_aarch64_off.py b/tests/functional/aarch64/test_virt_aarch64_off.py
new file mode 100755
index 0000000000..13d8b73b0d
--- /dev/null
+++ b/tests/functional/aarch64/test_virt_aarch64_off.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots an AArch32 Linux kernel and checks the console
+# on a TCG aarch64 CPU with aarch64=off. This is the same image etc
+# as we use in tests/functional/arm/test_virt.py.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import LinuxKernelTest, Asset
+
+class ArmVirtMachine(LinuxKernelTest):
+
+ ASSET_KERNEL = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
+ 'releases/29/Everything/armhfp/os/images/pxeboot/vmlinuz'),
+ '18dd5f1a9a28bd539f9d047f7c0677211bae528e8712b40ca5a229a4ad8e2591')
+
+ def test_arm_virt(self):
+ self.set_machine('virt')
+ # KVM aarch64=off requires a host CPU that supports it, so
+ # restrict the test to TCG only
+ self.require_accelerator('tcg')
+ self.vm.add_args('-cpu', 'max,aarch64=off')
+
+ kernel_path = self.ASSET_KERNEL.fetch()
+
+ self.vm.set_console()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+ 'console=ttyAMA0')
+ self.vm.add_args('-kernel', kernel_path,
+ '-append', kernel_command_line)
+ self.vm.launch()
+ console_pattern = 'Kernel command line: %s' % kernel_command_line
+ self.wait_for_console_pattern(console_pattern)
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 31/63] target/arm/cpu: Introduce the infrastructure for cpreg migration tolerances
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (29 preceding siblings ...)
2026-04-27 12:47 ` [PULL 30/63] tests/functional/aarch64: Add basic test of TCG aarch64=off Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 32/63] target/arm/machine: Handle ToleranceNotOnBothEnds " Peter Maydell
` (32 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Eric Auger <eric.auger@redhat.com>
We introduce a datatype for a tolerance with respect to a given
cpreg migration issue. The tolerance applies to a given cpreg kvm index,
and can be of different types:
a) mismatch in cpreg indexes
- ToleranceNotOnBothEnds (cpreg index is allowed to be only present
on one end)
- ToleranceOnlySrcTestValue (cpreg index is allowed to be only
present in source if its value @mask field matches @value)
b) mismatch in cpreg values
- ToleranceDiffInMask (value differences are allowed only within a mask)
- ToleranceFieldLT (incoming field value must be less than a given value)
- ToleranceFieldGT (incoming field value must be greater than a given value)
A QLIST of such tolerances can be populated using a new helper:
arm_register_cpreg_mig_tolerance() and arm_cpu_match_cpreg_mig_tolerance()
allows to check whether a tolerance exists for a given kvm index and its
criterion is matched.
callers for those helpers will be introduced in subsequent patches.
Only registration of migration tolerances related to cpreg index
mismatch is currently allowed.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Message-id: 20260420140552.104369-2-eric.auger@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/cpu.c | 82 ++++++++++++++++++++++++++++++++++++++++++
target/arm/cpu.h | 1 +
target/arm/internals.h | 54 ++++++++++++++++++++++++++++
3 files changed, 137 insertions(+)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 9b80dda140..10feb639c4 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -181,6 +181,82 @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
QLIST_INSERT_HEAD(&cpu->el_change_hooks, entry, node);
}
+static ARMCPRegMigTolerance *find_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx)
+{
+ ARMCPRegMigTolerance *t;
+ QLIST_FOREACH(t, &cpu->cpreg_mig_tolerances, node) {
+ if (t->kvmidx == kvmidx) {
+ return t;
+ }
+ }
+ return NULL;
+}
+
+void arm_register_cpreg_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
+ uint64_t mask, uint64_t value,
+ ARMCPRegMigToleranceType type)
+{
+ ARMCPRegMigTolerance *entry;
+
+ /* make sure the kvmidx has not tolerance already registered */
+ assert(!find_mig_tolerance(cpu, kvmidx));
+
+ assert(type == ToleranceNotOnBothEnds ||
+ type == ToleranceOnlySrcTestValue);
+
+ entry = g_new0(ARMCPRegMigTolerance, 1);
+
+ entry->kvmidx = kvmidx;
+ entry->mask = mask;
+ entry->value = value;
+ entry->type = type;
+
+ QLIST_INSERT_HEAD(&cpu->cpreg_mig_tolerances, entry, node);
+}
+
+bool arm_cpu_match_cpreg_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
+ uint64_t vmstate_value, uint64_t local_value,
+ ARMCPRegMigToleranceType type)
+{
+ ARMCPRegMigTolerance *t = find_mig_tolerance(cpu, kvmidx);
+ uint64_t diff, diff_outside_mask, field;
+
+ if (!t || t->type != type) {
+ return false;
+ }
+
+ if (type == ToleranceNotOnBothEnds) {
+ return true;
+ }
+
+ if (type == ToleranceOnlySrcTestValue &&
+ ((vmstate_value & t->mask) == t->value)) {
+ return true;
+ }
+
+ /* Need to check the mask */
+ diff = vmstate_value ^ local_value;
+ diff_outside_mask = diff & ~t->mask;
+
+ if (diff_outside_mask) {
+ /* there are differences outside of the mask */
+ return false;
+ }
+ if (type == ToleranceDiffInMask) {
+ /* differences only in the field, tolerance matched */
+ return true;
+ }
+ /* need to compare field value against authorized ones */
+ field = vmstate_value & t->mask;
+ if (type == ToleranceFieldLT && (field < t->value)) {
+ return true;
+ }
+ if (type == ToleranceFieldGT && (field > t->value)) {
+ return true;
+ }
+ return false;
+}
+
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
{
/* Reset a single ARMCPRegInfo register */
@@ -1102,6 +1178,7 @@ static void arm_cpu_initfn(Object *obj)
QLIST_INIT(&cpu->pre_el_change_hooks);
QLIST_INIT(&cpu->el_change_hooks);
+ QLIST_INIT(&cpu->cpreg_mig_tolerances);
#ifdef CONFIG_USER_ONLY
# ifdef TARGET_AARCH64
@@ -1574,6 +1651,7 @@ static void arm_cpu_finalizefn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
ARMELChangeHook *hook, *next;
+ ARMCPRegMigTolerance *t, *n;
g_hash_table_destroy(cpu->cp_regs);
@@ -1585,6 +1663,10 @@ static void arm_cpu_finalizefn(Object *obj)
QLIST_REMOVE(hook, node);
g_free(hook);
}
+ QLIST_FOREACH_SAFE(t, &cpu->cpreg_mig_tolerances, node, n) {
+ QLIST_REMOVE(t, node);
+ g_free(t);
+ }
#ifndef CONFIG_USER_ONLY
if (cpu->pmu_timer) {
timer_free(cpu->pmu_timer);
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index ab6bacf4aa..be14a47c35 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1140,6 +1140,7 @@ struct ArchCPU {
QLIST_HEAD(, ARMELChangeHook) pre_el_change_hooks;
QLIST_HEAD(, ARMELChangeHook) el_change_hooks;
+ QLIST_HEAD(, ARMCPRegMigTolerance) cpreg_mig_tolerances;
int32_t node_id; /* NUMA node this CPU belongs to */
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 06655409e5..a632584a4e 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1943,4 +1943,58 @@ int compare_u64(const void *a, const void *b);
/* Used in FEAT_MEC to set the MECIDWidthm1 field in the MECIDR_EL2 register. */
#define MECID_WIDTH 16
+typedef enum {
+ ToleranceNotOnBothEnds,
+ ToleranceOnlySrcTestValue,
+ ToleranceDiffInMask,
+ ToleranceFieldLT,
+ ToleranceFieldGT,
+} ARMCPRegMigToleranceType;
+
+typedef struct ARMCPRegMigTolerance {
+ uint64_t kvmidx;
+ uint64_t mask;
+ uint64_t value;
+ ARMCPRegMigToleranceType type;
+ QLIST_ENTRY(ARMCPRegMigTolerance) node;
+} ARMCPRegMigTolerance;
+
+/**
+ * arm_register_cpreg_mig_tolerance:
+ * Register a migration tolerance wrt one given cpreg identified by its
+ * @kvmidx. Calling this function twice for the same @kvmidx is a
+ * programming error and will cause an assertion failure.
+ *
+ * @cpu: vcpu to apply the migration tolerance on
+ * @kvmidx: kvm index of the cpreg the tolerance applies to
+ * @mask: bitmask where a difference is tolerated
+ * (relevant with ToleranceDiffInMask)
+ * @value: value the bitmask field is compared with
+ * (relevant with ToleranceFieldLT and ToleranceFieldGT)
+ * @type: type of the migration tolerance:
+ * - ToleranceNotOnBothEnds (cpreg index is allowed to be only present
+ * on one end)
+ * - ToleranceOnlySrcTestValue (cpreg index is allowed to be only
+ * present in source if its value @mask field matches @value)
+ * - ToleranceDiffInMask (mismatch in cpreg values are only tolerated
+ * if differences are within @mask)
+ * - ToleranceFieldLT (mismatch in cpreg values are only tolerated
+ * if incoming @bitmask field value is less than @value)
+ * - ToleranceFieldGT (mismatch in cpreg values are only tolerated
+ * if incoming @bitmask field value is greater than @value)
+ */
+void arm_register_cpreg_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
+ uint64_t mask, uint64_t value,
+ ARMCPRegMigToleranceType type);
+
+/**
+ * arm_cpu_match_cpreg_mig_tolerance:
+ * Check whether a tolerance of type @type exists for a given @kvmidx
+ * and the tolerance criterion is satisfied
+ */
+bool arm_cpu_match_cpreg_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
+ uint64_t vmstate_value, uint64_t local_value,
+ ARMCPRegMigToleranceType type);
+
+
#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 32/63] target/arm/machine: Handle ToleranceNotOnBothEnds migration tolerances
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (30 preceding siblings ...)
2026-04-27 12:47 ` [PULL 31/63] target/arm/cpu: Introduce the infrastructure for cpreg migration tolerances Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 33/63] target/arm/machine: Handle ToleranceOnlySrcTestValue migration tolerance Peter Maydell
` (31 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Eric Auger <eric.auger@redhat.com>
If there is a mismatch between the cpreg indexes found on both ends,
check whether a tolerance was registered for the given kvmidx. If any,
silence warning/errors.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20260420140552.104369-3-eric.auger@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/machine.c | 21 +++++++++++++++------
target/arm/trace-events | 2 ++
2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 50d80ffb68..b2bf129334 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -1063,25 +1063,34 @@ static void handle_cpreg_missing_in_incoming_stream(ARMCPU *cpu, uint64_t kvmidx
{
g_autofree gchar *name = print_register_name(kvmidx);
+ if (arm_cpu_match_cpreg_mig_tolerance(cpu, kvmidx,
+ 0, 0, ToleranceNotOnBothEnds)) {
+ trace_tolerate_cpreg_missing_in_incoming_stream(name);
+ return;
+ }
warn_report("%s: %s "
"expected by the destination but not in the incoming stream: "
"skip it", __func__, name);
}
/*
- * Handle the situation where @kvmidx is in the incoming stream
- * but not on destination. This currently fails the migration but
- * we plan to accomodate some exceptions, hence the boolean returned value.
+ * Handle the situation where @kvmidx is in the incoming
+ * stream but not on destination. This fails the migration if
+ * no cpreg mig tolerance is matched for this @kvmidx
+ * Return true if the migration should eventually fail
*/
static bool handle_cpreg_only_in_incoming_stream(ARMCPU *cpu, uint64_t kvmidx)
{
g_autofree gchar *name = print_register_name(kvmidx);
- bool fail = true;
+ if (arm_cpu_match_cpreg_mig_tolerance(cpu, kvmidx,
+ 0, 0, ToleranceNotOnBothEnds)) {
+ trace_tolerate_cpreg_only_in_incoming_stream(name);
+ return false;
+ }
error_report("%s: %s in the incoming stream but unknown on the "
"destination: fail migration", __func__, name);
-
- return fail;
+ return true;
}
static int cpu_post_load(void *opaque, int version_id)
diff --git a/target/arm/trace-events b/target/arm/trace-events
index 2de0406f78..8502fb3265 100644
--- a/target/arm/trace-events
+++ b/target/arm/trace-events
@@ -29,3 +29,5 @@ arm_psci_call(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint32_t cpuid
# machine.c
cpu_post_load(uint32_t cpreg_vmstate_array_len, uint32_t cpreg_array_len) "cpreg_vmstate_array_len=%d cpreg_array_len=%d"
+tolerate_cpreg_missing_in_incoming_stream(char *name) "%s is missing in incoming stream but this is explicitly tolerated"
+tolerate_cpreg_only_in_incoming_stream(char *name) "%s is in incoming stream but not on destination but this is explicitly tolerated"
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 33/63] target/arm/machine: Handle ToleranceOnlySrcTestValue migration tolerance
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (31 preceding siblings ...)
2026-04-27 12:47 ` [PULL 32/63] target/arm/machine: Handle ToleranceNotOnBothEnds " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 34/63] target/arm/cpu64: Mitigate migration failures due to spurious TCR_EL1, PIRE0_EL1 and PIR_EL1 Peter Maydell
` (30 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Eric Auger <eric.auger@redhat.com>
Pass the value of the incoming register to
handle_cpreg_only_in_incoming_stream and check whether there is
a matching ToleranceOnlySrcTestValue tolerance.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Message-id: 20260420140552.104369-4-eric.auger@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/machine.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/target/arm/machine.c b/target/arm/machine.c
index b2bf129334..8dc766d322 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -1079,12 +1079,15 @@ static void handle_cpreg_missing_in_incoming_stream(ARMCPU *cpu, uint64_t kvmidx
* no cpreg mig tolerance is matched for this @kvmidx
* Return true if the migration should eventually fail
*/
-static bool handle_cpreg_only_in_incoming_stream(ARMCPU *cpu, uint64_t kvmidx)
+static bool
+handle_cpreg_only_in_incoming_stream(ARMCPU *cpu, uint64_t kvmidx, uint64_t value)
{
g_autofree gchar *name = print_register_name(kvmidx);
if (arm_cpu_match_cpreg_mig_tolerance(cpu, kvmidx,
- 0, 0, ToleranceNotOnBothEnds)) {
+ 0, 0, ToleranceNotOnBothEnds) ||
+ arm_cpu_match_cpreg_mig_tolerance(cpu, kvmidx,
+ value, 0, ToleranceOnlySrcTestValue)) {
trace_tolerate_cpreg_only_in_incoming_stream(name);
return false;
}
@@ -1137,7 +1140,9 @@ static int cpu_post_load(void *opaque, int version_id)
}
if (cpu->cpreg_vmstate_indexes[v] < cpu->cpreg_indexes[i]) {
fail = handle_cpreg_only_in_incoming_stream(cpu,
- cpu->cpreg_vmstate_indexes[v++]);
+ cpu->cpreg_vmstate_indexes[v],
+ cpu->cpreg_vmstate_values[v]);
+ v++;
continue;
}
/* matching register, copy the value over */
@@ -1160,7 +1165,8 @@ static int cpu_post_load(void *opaque, int version_id)
*/
for ( ; v < cpu->cpreg_vmstate_array_len; v++) {
fail = handle_cpreg_only_in_incoming_stream(cpu,
- cpu->cpreg_vmstate_indexes[v]);
+ cpu->cpreg_vmstate_indexes[v],
+ cpu->cpreg_vmstate_values[v]);
}
if (fail) {
return -1;
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 34/63] target/arm/cpu64: Mitigate migration failures due to spurious TCR_EL1, PIRE0_EL1 and PIR_EL1
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (32 preceding siblings ...)
2026-04-27 12:47 ` [PULL 33/63] target/arm/machine: Handle ToleranceOnlySrcTestValue migration tolerance Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 35/63] target/arm/cpu64: Define cpreg migration tolerance for KVM_REG_ARM_VENDOR_HYP_BMAP_2 Peter Maydell
` (29 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Eric Auger <eric.auger@redhat.com>
Before linux v6.13 those registers were erroneously unconditionally
exposed and this was fixed by commits:
- 0fcb4eea5345 ("KVM: arm64: Hide TCR2_EL1 from userspace when
disabled for guests")
- a68cddbe47ef ("KVM: arm64: Hide S1PIE registers from userspace
when disabled for guests")
in v6.13.
This means if we migrate from an old kernel host to a >= 6.13 kernel
host, migration currently fails.
Declare cpreg migration tolerance for those registers.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Sebastian Ott <sebott@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20260420140552.104369-5-eric.auger@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/cpu64.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index d6feba220e..e7014022df 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -810,6 +810,33 @@ static void aarch64_a53_initfn(Object *obj)
define_cortex_a72_a57_a53_cp_reginfo(cpu);
}
+#if defined(CONFIG_KVM)
+static void kvm_arm_set_cpreg_mig_tolerances(ARMCPU *cpu)
+{
+ /*
+ * Registers that may be in the incoming stream and not exposed
+ * on the destination
+ */
+
+ /*
+ * TCR_EL1 was erroneously unconditionnally exposed before linux v6.13.
+ * See commit 0fcb4eea5345 ("KVM: arm64: Hide TCR2_EL1 from userspace
+ * when disabled for guests")
+ */
+ arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 2, 0, 3),
+ 0, 0, ToleranceNotOnBothEnds);
+ /*
+ * PIRE0_EL1 and PIR_EL1 were erroneously unconditionnally exposed
+ * before linux v6.13. See commit a68cddbe47ef ("KVM: arm64: Hide
+ * S1PIE registers from userspace when disabled for guests")
+ */
+ arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 10, 2, 2),
+ 0, 0, ToleranceNotOnBothEnds);
+ arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 10, 2, 3),
+ 0, 0, ToleranceNotOnBothEnds);
+}
+#endif
+
static void aarch64_host_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
@@ -822,6 +849,7 @@ static void aarch64_host_initfn(Object *obj)
#endif
#if defined(CONFIG_KVM)
+ kvm_arm_set_cpreg_mig_tolerances(cpu);
kvm_arm_set_cpu_features_from_host(cpu);
aarch64_add_sve_properties(obj);
#elif defined(CONFIG_HVF)
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 35/63] target/arm/cpu64: Define cpreg migration tolerance for KVM_REG_ARM_VENDOR_HYP_BMAP_2
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (33 preceding siblings ...)
2026-04-27 12:47 ` [PULL 34/63] target/arm/cpu64: Mitigate migration failures due to spurious TCR_EL1, PIRE0_EL1 and PIR_EL1 Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 36/63] target/arm/helper: Define cpreg migration tolerance for DGBDTR_EL0 Peter Maydell
` (28 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Eric Auger <eric.auger@redhat.com>
KVM_REG_ARM_VENDOR_HYP_BMAP_2 pseudo FW register is exposed
from v6.15 onwards. Backward migration from a >= v6.15 to an older
kernel would fail without cpreg migration tolerance definition
for this register. If the register is present on source but not
on destination, its value must be checked to make sure it matches
the reset value, ie. 0, meaning no service is exposed to the guest,
hence the choice of a ToleranceOnlySrcTestValue migration
tolerance.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20260420140552.104369-6-eric.auger@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/cpu64.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index e7014022df..a93ad2da5a 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -834,6 +834,17 @@ static void kvm_arm_set_cpreg_mig_tolerances(ARMCPU *cpu)
0, 0, ToleranceNotOnBothEnds);
arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 10, 2, 3),
0, 0, ToleranceNotOnBothEnds);
+
+ /*
+ * KVM_REG_ARM_VENDOR_HYP_BMAP_2 pseudo FW register is exposed
+ * from v6.15 onwards. Backward migration from a >= v6.15 to an older
+ * kernel would fail without cpreg migration tolerance definition.
+ * If the register is present on source but not on destination, make
+ * sure it has its reset value, ie. 0, meaning no service is exposed
+ * to the guest.
+ */
+ arm_register_cpreg_mig_tolerance(cpu, KVM_REG_ARM_FW_FEAT_BMAP_REG(3),
+ UINT64_MAX, 0, ToleranceOnlySrcTestValue);
}
#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 36/63] target/arm/helper: Define cpreg migration tolerance for DGBDTR_EL0
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (34 preceding siblings ...)
2026-04-27 12:47 ` [PULL 35/63] target/arm/cpu64: Define cpreg migration tolerance for KVM_REG_ARM_VENDOR_HYP_BMAP_2 Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 37/63] Revert "target/arm: Reinstate bogus AArch32 DBGDTRTX register for migration compat" Peter Maydell
` (27 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Eric Auger <eric.auger@redhat.com>
We want to remove AArch32 DBGDTRTX which was erroneously exposed.
This was attempted by 655659a74a36b ("target/arm: Correct encoding
of Debug Communications Channel registers") but it was discovered
that the removal of this debug register broke forward migration on
TCG. Now we have the cpreg migration tolerance infrastructure, we
can declare one for the DBGDTRTX. This allow to revert the reinstate
patch.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Sebastian Ott <sebott@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20260420140552.104369-7-eric.auger@redhat.com
[PMM: revised comment, included note about when we can drop
the workaround]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/helper.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 3ac88078aa..ccd6353190 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6349,9 +6349,32 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.fgt = FGT_CLIDR_EL1,
.resetvalue = GET_IDREG(isar, CLIDR)
};
+ uint64_t dbgtr_el0_kvmidx =
+ cpreg_to_kvm_id(ENCODE_CP_REG(14, 0, 1, 0, 5, 3, 0));
+
define_one_arm_cp_reg(cpu, &clidr);
define_arm_cp_regs(cpu, v7_cp_reginfo);
define_debug_regs(cpu);
+ /*
+ * We used to incorrectly expose a non-existent AArch32 "DBGDTRTX"
+ * register with this encoding. This has been fixed by commit
+ * 655659a74a36 ("target/arm: Correct encoding of Debug
+ * Communications Channel registers") by the introduction of correct
+ * separate cpreg definitions for AA64 and AA32 versions. However,
+ * the old cpreg definition couldn't be removed without breaking
+ * migration, so commit 4f2b82f604 reinstated the bogus encoding
+ * for migration data only.
+ *
+ * Now that we have migration tolerance infrastructure, we can use
+ * this to allow forward migration from the buggy QEMU versions,
+ * accepting and ignoring the bogus register if it is in the
+ * source data. QEMU 11.0 was the last version that sent the
+ * bogus encoding, so this workaround can be removed at the point
+ * where we no longer care about migration from that version
+ * (i.e. when we remove the "virt-11.0" machine type).
+ */
+ arm_register_cpreg_mig_tolerance(cpu, dbgtr_el0_kvmidx,
+ 0, 0, ToleranceNotOnBothEnds);
} else {
define_arm_cp_regs(cpu, not_v7_cp_reginfo);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 37/63] Revert "target/arm: Reinstate bogus AArch32 DBGDTRTX register for migration compat"
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (35 preceding siblings ...)
2026-04-27 12:47 ` [PULL 36/63] target/arm/helper: Define cpreg migration tolerance for DGBDTR_EL0 Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 38/63] hw/arm/raspi4b: NOP all DTB nodes when removing unimplemented devices Peter Maydell
` (26 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Eric Auger <eric.auger@redhat.com>
This reverts commit 4f2b82f60431 ("target/arm: Reinstate bogus AArch32
DBGDTRTX register for migration compat). We don't need that commit
anymore as the AArch32 DBGDTRTX register is declared to
be safe to ignore in the incoming migration stream.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Sebastian Ott <sebott@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20260420140552.104369-8-eric.auger@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/debug_helper.c | 29 -----------------------------
1 file changed, 29 deletions(-)
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
index 352c8e5c8e..8477ca5def 100644
--- a/target/arm/debug_helper.c
+++ b/target/arm/debug_helper.c
@@ -171,13 +171,6 @@ static void dbgclaimclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
env->cp15.dbgclaim &= ~(value & 0xFF);
}
-static CPAccessResult access_bogus(CPUARMState *env, const ARMCPRegInfo *ri,
- bool isread)
-{
- /* Always UNDEF, as if this cpreg didn't exist */
- return CP_ACCESS_UNDEFINED;
-}
-
static const ARMCPRegInfo debug_cp_reginfo[] = {
/*
* DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped
@@ -240,28 +233,6 @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
.opc0 = 2, .opc1 = 3, .crn = 0, .crm = 4, .opc2 = 0,
.access = PL0_RW, .accessfn = access_tdcc,
.type = ARM_CP_CONST, .resetvalue = 0 },
- /*
- * This is not a real AArch32 register. We used to incorrectly expose
- * this due to a QEMU bug; to avoid breaking migration compatibility we
- * need to continue to provide it so that we don't fail the inbound
- * migration when it tells us about a sysreg that we don't have.
- * We set an always-fails .accessfn, which means that the guest doesn't
- * actually see this register (it will always UNDEF, identically to if
- * there were no cpreg definition for it other than that we won't print
- * a LOG_UNIMP message about it), and we set the ARM_CP_NO_GDB flag so the
- * gdbstub won't see it either.
- * (We can't just set .access = 0, because add_cpreg_to_hashtable()
- * helpfully ignores cpregs which aren't accessible to the highest
- * implemented EL.)
- *
- * TODO: implement a system for being able to describe "this register
- * can be ignored if it appears in the inbound stream"; then we can
- * remove this temporary hack.
- */
- { .name = "BOGUS_DBGDTR_EL0", .state = ARM_CP_STATE_AA32,
- .cp = 14, .opc1 = 3, .crn = 0, .crm = 5, .opc2 = 0,
- .access = PL0_RW, .accessfn = access_bogus,
- .type = ARM_CP_CONST | ARM_CP_NO_GDB, .resetvalue = 0 },
/*
* OSECCR_EL1 provides a mechanism for an operating system
* to access the contents of EDECCR. EDECCR is not implemented though,
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 38/63] hw/arm/raspi4b: NOP all DTB nodes when removing unimplemented devices
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (36 preceding siblings ...)
2026-04-27 12:47 ` [PULL 37/63] Revert "target/arm: Reinstate bogus AArch32 DBGDTRTX register for migration compat" Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 39/63] hw/display: Add i.MX6UL LCDIF device model Peter Maydell
` (25 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Osama Abdelkader <osama.abdelkader@gmail.com>
fdt_node_offset_by_compatible(fdt, -1, compat) only finds the first match.
If the blob has more than one node with the same compatible string, extra
nodes will remain active. Remove all the matching nodes, using the same
loop as imx8mp-evk.c does for this purpose.
Signed-off-by: Osama Abdelkader <osama.abdelkader@gmail.com>
Message-id: 20260420162114.308519-1-osama.abdelkader@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/raspi4b.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c
index 3eeb8f447e..06aeb8db01 100644
--- a/hw/arm/raspi4b.c
+++ b/hw/arm/raspi4b.c
@@ -72,12 +72,14 @@ static void raspi4_modify_dtb(const struct arm_boot_info *info, void *fdt)
for (int i = 0; i < ARRAY_SIZE(nodes_to_remove); i++) {
const char *dev_str = nodes_to_remove[i];
+ int offset;
- int offset = fdt_node_offset_by_compatible(fdt, -1, dev_str);
- if (offset >= 0) {
- if (!fdt_nop_node(fdt, offset)) {
- warn_report("bcm2711 dtc: %s has been disabled!", dev_str);
+ offset = fdt_node_offset_by_compatible(fdt, -1, dev_str);
+ while (offset >= 0) {
+ if (fdt_nop_node(fdt, offset) == 0) {
+ warn_report("bcm2711 dtb: %s has been disabled!", dev_str);
}
+ offset = fdt_node_offset_by_compatible(fdt, offset, dev_str);
}
}
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 39/63] hw/display: Add i.MX6UL LCDIF device model
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (37 preceding siblings ...)
2026-04-27 12:47 ` [PULL 38/63] hw/arm/raspi4b: NOP all DTB nodes when removing unimplemented devices Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-05-20 16:33 ` Philippe Mathieu-Daudé
2026-04-27 12:47 ` [PULL 40/63] hw/arm/fsl-imx6ul: Wire in the " Peter Maydell
` (24 subsequent siblings)
63 siblings, 1 reply; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Yucai Liu <1486344514@qq.com>
Implement a basic i.MX6UL LCDIF controller model with MMIO registers,
frame-done interrupt behavior, and framebuffer-backed display updates
for RGB565 and XRGB8888 input formats.
Place the LCDIF device under hw/display and build it via a dedicated
CONFIG_IMX6UL_LCDIF symbol. Model register fields with
registerfields.h helpers and provide migration support via vmstate.
Signed-off-by: Yucai Liu <1486344514@qq.com>
Message-id: 20260412110240.93116-2-yangyanglan718@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
MAINTAINERS | 2 +
hw/display/Kconfig | 4 +
hw/display/imx6ul_lcdif.c | 453 ++++++++++++++++++++++++++++++
hw/display/meson.build | 1 +
include/hw/display/imx6ul_lcdif.h | 37 +++
5 files changed, 497 insertions(+)
create mode 100644 hw/display/imx6ul_lcdif.c
create mode 100644 include/hw/display/imx6ul_lcdif.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 50a8e161c6..a23ff5279e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -894,8 +894,10 @@ L: qemu-arm@nongnu.org
S: Odd Fixes
F: hw/arm/mcimx6ul-evk.c
F: hw/arm/fsl-imx6ul.c
+F: hw/display/imx6ul_lcdif.c
F: hw/misc/imx6ul_ccm.c
F: include/hw/arm/fsl-imx6ul.h
+F: include/hw/display/imx6ul_lcdif.h
F: include/hw/misc/imx6ul_ccm.h
F: docs/system/arm/mcimx6ul-evk.rst
diff --git a/hw/display/Kconfig b/hw/display/Kconfig
index 1e95ab28ef..b3593fe981 100644
--- a/hw/display/Kconfig
+++ b/hw/display/Kconfig
@@ -25,6 +25,10 @@ config PL110
bool
select FRAMEBUFFER
+config IMX6UL_LCDIF
+ bool
+ select FRAMEBUFFER
+
config SII9022
bool
depends on I2C
diff --git a/hw/display/imx6ul_lcdif.c b/hw/display/imx6ul_lcdif.c
new file mode 100644
index 0000000000..33cd00fbe1
--- /dev/null
+++ b/hw/display/imx6ul_lcdif.c
@@ -0,0 +1,453 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * i.MX6UL LCDIF controller
+ *
+ * Copyright (c) 2026 Yucai Liu <1486344514@qq.com>
+ */
+
+#include "qemu/osdep.h"
+#include "hw/display/imx6ul_lcdif.h"
+#include "hw/core/irq.h"
+#include "hw/core/registerfields.h"
+#include "hw/display/framebuffer.h"
+#include "migration/vmstate.h"
+#include "system/address-spaces.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+#include "ui/pixel_ops.h"
+
+#define LCDIF_MMIO_SIZE (16 * KiB)
+#define LCDIF_RESET_CTRL1 0x000f0000
+
+REG32(CTRL, 0x00)
+ FIELD(CTRL, RUN, 0, 1)
+ FIELD(CTRL, WORD_LENGTH, 8, 2)
+REG32(CTRL1, 0x10)
+ FIELD(CTRL1, CUR_FRAME_DONE_IRQ, 9, 1)
+ FIELD(CTRL1, CUR_FRAME_DONE_IRQ_EN, 13, 1)
+ FIELD(CTRL1, BYTE_PACKING_FORMAT, 16, 4)
+REG32(V4_TRANSFER_COUNT, 0x30)
+ FIELD(V4_TRANSFER_COUNT, H_COUNT, 0, 16)
+ FIELD(V4_TRANSFER_COUNT, V_COUNT, 16, 16)
+REG32(V4_CUR_BUF, 0x40)
+REG32(V4_NEXT_BUF, 0x50)
+REG32(AS_NEXT_BUF, 0x230)
+
+#define REG_SET 0x4
+#define REG_CLR 0x8
+#define REG_TOG 0xc
+
+#define CTRL_WORD_LENGTH_16 0
+#define CTRL_WORD_LENGTH_24 3
+
+#define FRAME_PERIOD_NS (16 * 1000 * 1000ULL)
+
+enum IMX6ULLCDIFReg {
+ IMX6UL_LCDIF_REG_CTRL = A_CTRL >> 4,
+ IMX6UL_LCDIF_REG_CTRL1 = A_CTRL1 >> 4,
+ IMX6UL_LCDIF_REG_V4_TRANSFER_COUNT = A_V4_TRANSFER_COUNT >> 4,
+ IMX6UL_LCDIF_REG_V4_CUR_BUF = A_V4_CUR_BUF >> 4,
+ IMX6UL_LCDIF_REG_V4_NEXT_BUF = A_V4_NEXT_BUF >> 4,
+ IMX6UL_LCDIF_REG_AS_NEXT_BUF = A_AS_NEXT_BUF >> 4,
+};
+
+static inline bool imx6ul_lcdif_reg_exists(hwaddr reg)
+{
+ return (reg >> 4) < IMX6UL_LCDIF_REGS_NUM;
+}
+
+static inline bool imx6ul_lcdif_reg_has_setclr(hwaddr reg)
+{
+ switch (reg) {
+ case A_CTRL:
+ case A_CTRL1:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static inline bool imx6ul_lcdif_is_running(IMX6ULLCDIFState *s)
+{
+ uint32_t ctrl = s->regs[IMX6UL_LCDIF_REG_CTRL];
+
+ return FIELD_EX32(ctrl, CTRL, RUN);
+}
+
+static inline bool imx6ul_lcdif_frame_done_pending(IMX6ULLCDIFState *s)
+{
+ uint32_t ctrl1 = s->regs[IMX6UL_LCDIF_REG_CTRL1];
+
+ return FIELD_EX32(ctrl1, CTRL1, CUR_FRAME_DONE_IRQ);
+}
+
+static void imx6ul_lcdif_schedule_frame(IMX6ULLCDIFState *s)
+{
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+
+ timer_mod(s->frame_timer, now + FRAME_PERIOD_NS);
+}
+
+static void imx6ul_lcdif_maybe_schedule_frame(IMX6ULLCDIFState *s)
+{
+ if (imx6ul_lcdif_is_running(s) && !imx6ul_lcdif_frame_done_pending(s)) {
+ imx6ul_lcdif_schedule_frame(s);
+ } else {
+ timer_del(s->frame_timer);
+ }
+}
+
+static void imx6ul_lcdif_update_irq(IMX6ULLCDIFState *s)
+{
+ uint32_t ctrl1 = s->regs[IMX6UL_LCDIF_REG_CTRL1];
+ bool level = FIELD_EX32(ctrl1, CTRL1, CUR_FRAME_DONE_IRQ_EN) &&
+ FIELD_EX32(ctrl1, CTRL1, CUR_FRAME_DONE_IRQ);
+
+ qemu_set_irq(s->irq, level);
+}
+
+static void imx6ul_lcdif_frame_done(IMX6ULLCDIFState *s)
+{
+ uint32_t ctrl1 = s->regs[IMX6UL_LCDIF_REG_CTRL1];
+
+ ctrl1 = FIELD_DP32(ctrl1, CTRL1, CUR_FRAME_DONE_IRQ, 1);
+ s->regs[IMX6UL_LCDIF_REG_CTRL1] = ctrl1;
+ imx6ul_lcdif_update_irq(s);
+}
+
+static void imx6ul_lcdif_draw_line_rgb565(void *opaque, uint8_t *dst,
+ const uint8_t *src, int width,
+ int dststep)
+{
+ uint32_t *dst32 = (uint32_t *)dst;
+ int i;
+
+ for (i = 0; i < width; i++) {
+ uint16_t pixel = lduw_le_p(src);
+ uint8_t r = ((pixel >> 11) & 0x1f) << 3;
+ uint8_t g = ((pixel >> 5) & 0x3f) << 2;
+ uint8_t b = (pixel & 0x1f) << 3;
+
+ *dst32++ = rgb_to_pixel32(r, g, b);
+ src += 2;
+ }
+}
+
+static void imx6ul_lcdif_draw_line_xrgb8888(void *opaque, uint8_t *dst,
+ const uint8_t *src, int width,
+ int dststep)
+{
+ uint32_t *dst32 = (uint32_t *)dst;
+ int i;
+
+ for (i = 0; i < width; i++) {
+ uint32_t pixel = ldl_le_p(src);
+ uint8_t r = (pixel >> 16) & 0xff;
+ uint8_t g = (pixel >> 8) & 0xff;
+ uint8_t b = pixel & 0xff;
+
+ *dst32++ = rgb_to_pixel32(r, g, b);
+ src += 4;
+ }
+}
+
+static void imx6ul_lcdif_update_display(void *opaque)
+{
+ IMX6ULLCDIFState *s = opaque;
+ DisplaySurface *surface = qemu_console_surface(s->con);
+ uint32_t transfer_count = s->regs[IMX6UL_LCDIF_REG_V4_TRANSFER_COUNT];
+ uint32_t width = FIELD_EX32(transfer_count, V4_TRANSFER_COUNT, H_COUNT);
+ uint32_t height = FIELD_EX32(transfer_count, V4_TRANSFER_COUNT, V_COUNT);
+ uint32_t ctrl = s->regs[IMX6UL_LCDIF_REG_CTRL];
+ uint32_t frame_base = s->regs[IMX6UL_LCDIF_REG_V4_CUR_BUF];
+ drawfn fn;
+ int first = 0;
+ int last = 0;
+ int src_width;
+
+ if (!imx6ul_lcdif_is_running(s) || width == 0 || height == 0) {
+ return;
+ }
+
+ switch (FIELD_EX32(ctrl, CTRL, WORD_LENGTH)) {
+ case CTRL_WORD_LENGTH_16:
+ s->src_bpp = 2;
+ fn = imx6ul_lcdif_draw_line_rgb565;
+ break;
+ case CTRL_WORD_LENGTH_24:
+ s->src_bpp = 4;
+ fn = imx6ul_lcdif_draw_line_xrgb8888;
+ break;
+ default:
+ return;
+ }
+
+ if (surface_width(surface) != width || surface_height(surface) != height) {
+ qemu_console_resize(s->con, width, height);
+ surface = qemu_console_surface(s->con);
+ s->invalidate = true;
+ }
+
+ src_width = width * s->src_bpp;
+ if (s->invalidate || s->fb_base != frame_base ||
+ s->src_width != src_width || s->rows != height) {
+ framebuffer_update_memory_section(&s->fbsection, get_system_memory(),
+ frame_base, height, src_width);
+ s->fb_base = frame_base;
+ s->src_width = src_width;
+ s->rows = height;
+ }
+
+ framebuffer_update_display(surface, &s->fbsection, width, height,
+ src_width, surface_stride(surface), 0,
+ s->invalidate, fn, s, &first, &last);
+ if (first >= 0) {
+ dpy_gfx_update(s->con, 0, first, width, last - first + 1);
+ }
+
+ s->invalidate = false;
+}
+
+static void imx6ul_lcdif_invalidate_display(void *opaque)
+{
+ IMX6ULLCDIFState *s = opaque;
+
+ s->invalidate = true;
+}
+
+static const GraphicHwOps imx6ul_lcdif_graphic_ops = {
+ .invalidate = imx6ul_lcdif_invalidate_display,
+ .gfx_update = imx6ul_lcdif_update_display,
+};
+
+static void imx6ul_lcdif_frame_timer_cb(void *opaque)
+{
+ IMX6ULLCDIFState *s = opaque;
+
+ if (!imx6ul_lcdif_is_running(s) || imx6ul_lcdif_frame_done_pending(s)) {
+ return;
+ }
+
+ imx6ul_lcdif_frame_done(s);
+}
+
+static uint64_t imx6ul_lcdif_read(void *opaque, hwaddr offset, unsigned size)
+{
+ IMX6ULLCDIFState *s = opaque;
+ hwaddr reg = offset & ~0xf;
+ uint32_t idx;
+
+ assert(size == 4);
+ assert(!(offset & 0x3));
+ assert(offset < LCDIF_MMIO_SIZE);
+
+ idx = reg >> 4;
+ if (idx >= ARRAY_SIZE(s->regs)) {
+ return 0;
+ }
+
+ return s->regs[idx];
+}
+
+static void imx6ul_lcdif_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+ IMX6ULLCDIFState *s = opaque;
+ hwaddr reg = offset & ~0xf;
+ uint32_t idx;
+ uint32_t oldv;
+
+ assert(size == 4);
+ assert(!(offset & 0x3));
+ assert(offset < LCDIF_MMIO_SIZE);
+
+ if (!imx6ul_lcdif_reg_exists(reg)) {
+ return;
+ }
+
+ idx = reg >> 4;
+ oldv = s->regs[idx];
+
+ switch (offset & 0xf) {
+ case 0:
+ s->regs[idx] = (uint32_t)value;
+ break;
+ case REG_SET:
+ if (!imx6ul_lcdif_reg_has_setclr(reg)) {
+ return;
+ }
+ s->regs[idx] = oldv | (uint32_t)value;
+ break;
+ case REG_CLR:
+ if (!imx6ul_lcdif_reg_has_setclr(reg)) {
+ return;
+ }
+ s->regs[idx] = oldv & ~(uint32_t)value;
+ break;
+ case REG_TOG:
+ if (!imx6ul_lcdif_reg_has_setclr(reg)) {
+ return;
+ }
+ s->regs[idx] = oldv ^ (uint32_t)value;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ switch (reg) {
+ case A_CTRL:
+ if (!FIELD_EX32(oldv, CTRL, RUN) &&
+ FIELD_EX32(s->regs[idx], CTRL, RUN)) {
+ s->invalidate = true;
+ graphic_hw_invalidate(s->con);
+ imx6ul_lcdif_maybe_schedule_frame(s);
+ break;
+ }
+ if (FIELD_EX32(oldv, CTRL, RUN) &&
+ !FIELD_EX32(s->regs[idx], CTRL, RUN)) {
+ timer_del(s->frame_timer);
+ }
+ break;
+ case A_CTRL1:
+ if (FIELD_EX32(oldv, CTRL1, CUR_FRAME_DONE_IRQ) &&
+ !FIELD_EX32(s->regs[idx], CTRL1, CUR_FRAME_DONE_IRQ)) {
+ imx6ul_lcdif_maybe_schedule_frame(s);
+ }
+ break;
+ case A_V4_TRANSFER_COUNT:
+ s->invalidate = true;
+ graphic_hw_invalidate(s->con);
+ break;
+ case A_V4_CUR_BUF:
+ s->invalidate = true;
+ graphic_hw_invalidate(s->con);
+ break;
+ case A_V4_NEXT_BUF:
+ s->regs[IMX6UL_LCDIF_REG_V4_CUR_BUF] = s->regs[idx];
+ imx6ul_lcdif_frame_done(s);
+ s->invalidate = true;
+ graphic_hw_invalidate(s->con);
+ imx6ul_lcdif_maybe_schedule_frame(s);
+ return;
+ case A_AS_NEXT_BUF:
+ imx6ul_lcdif_frame_done(s);
+ imx6ul_lcdif_maybe_schedule_frame(s);
+ return;
+ default:
+ break;
+ }
+
+ imx6ul_lcdif_update_irq(s);
+}
+
+static const MemoryRegionOps imx6ul_lcdif_ops = {
+ .read = imx6ul_lcdif_read,
+ .write = imx6ul_lcdif_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ .unaligned = false,
+ },
+};
+
+static void imx6ul_lcdif_reset(DeviceState *dev)
+{
+ IMX6ULLCDIFState *s = IMX6UL_LCDIF(dev);
+
+ memset(s->regs, 0, sizeof(s->regs));
+ s->regs[IMX6UL_LCDIF_REG_CTRL1] = LCDIF_RESET_CTRL1;
+ s->fb_base = 0;
+ s->src_width = 0;
+ s->rows = 0;
+ s->src_bpp = 0;
+ s->invalidate = true;
+ timer_del(s->frame_timer);
+ imx6ul_lcdif_update_irq(s);
+}
+
+static int imx6ul_lcdif_post_load(void *opaque, int version_id)
+{
+ IMX6ULLCDIFState *s = opaque;
+
+ s->fb_base = 0;
+ s->src_width = 0;
+ s->rows = 0;
+ s->src_bpp = 0;
+ s->invalidate = true;
+
+ imx6ul_lcdif_update_irq(s);
+ if (imx6ul_lcdif_is_running(s) &&
+ !imx6ul_lcdif_frame_done_pending(s) &&
+ !timer_pending(s->frame_timer)) {
+ imx6ul_lcdif_schedule_frame(s);
+ }
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_imx6ul_lcdif = {
+ .name = TYPE_IMX6UL_LCDIF,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .post_load = imx6ul_lcdif_post_load,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(regs, IMX6ULLCDIFState, IMX6UL_LCDIF_REGS_NUM),
+ VMSTATE_TIMER_PTR(frame_timer, IMX6ULLCDIFState),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static void imx6ul_lcdif_realize(DeviceState *dev, Error **errp)
+{
+ IMX6ULLCDIFState *s = IMX6UL_LCDIF(dev);
+
+ s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+ imx6ul_lcdif_frame_timer_cb, s);
+ s->invalidate = true;
+ memory_region_init_io(&s->iomem, OBJECT(dev), &imx6ul_lcdif_ops, s,
+ TYPE_IMX6UL_LCDIF, LCDIF_MMIO_SIZE);
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
+ s->con = graphic_console_init(dev, 0, &imx6ul_lcdif_graphic_ops, s);
+}
+
+static void imx6ul_lcdif_unrealize(DeviceState *dev)
+{
+ IMX6ULLCDIFState *s = IMX6UL_LCDIF(dev);
+
+ timer_del(s->frame_timer);
+ timer_free(s->frame_timer);
+ s->frame_timer = NULL;
+
+ if (s->con) {
+ graphic_console_close(s->con);
+ s->con = NULL;
+ }
+}
+
+static void imx6ul_lcdif_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->realize = imx6ul_lcdif_realize;
+ dc->unrealize = imx6ul_lcdif_unrealize;
+ dc->vmsd = &vmstate_imx6ul_lcdif;
+ device_class_set_legacy_reset(dc, imx6ul_lcdif_reset);
+ dc->desc = "i.MX6UL LCDIF";
+}
+
+static const TypeInfo imx6ul_lcdif_info = {
+ .name = TYPE_IMX6UL_LCDIF,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(IMX6ULLCDIFState),
+ .class_init = imx6ul_lcdif_class_init,
+};
+
+static void imx6ul_lcdif_register_types(void)
+{
+ type_register_static(&imx6ul_lcdif_info);
+}
+
+type_init(imx6ul_lcdif_register_types)
diff --git a/hw/display/meson.build b/hw/display/meson.build
index e730c289b1..ffecedbf70 100644
--- a/hw/display/meson.build
+++ b/hw/display/meson.build
@@ -12,6 +12,7 @@ system_ss.add(when: ['CONFIG_VGA_CIRRUS', 'CONFIG_VGA_ISA'], if_true: files('cir
system_ss.add(when: 'CONFIG_G364FB', if_true: files('g364fb.c'))
system_ss.add(when: 'CONFIG_JAZZ_LED', if_true: files('jazz_led.c'))
system_ss.add(when: 'CONFIG_PL110', if_true: files('pl110.c'))
+system_ss.add(when: 'CONFIG_IMX6UL_LCDIF', if_true: files('imx6ul_lcdif.c'))
system_ss.add(when: 'CONFIG_SII9022', if_true: files('sii9022.c'))
system_ss.add(when: 'CONFIG_SSD0303', if_true: files('ssd0303.c'))
system_ss.add(when: 'CONFIG_SSD0323', if_true: files('ssd0323.c'))
diff --git a/include/hw/display/imx6ul_lcdif.h b/include/hw/display/imx6ul_lcdif.h
new file mode 100644
index 0000000000..42fee2fd1d
--- /dev/null
+++ b/include/hw/display/imx6ul_lcdif.h
@@ -0,0 +1,37 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * i.MX6UL LCDIF controller
+ *
+ * Copyright (c) 2026 Yucai Liu <1486344514@qq.com>
+ */
+
+#ifndef IMX6UL_LCDIF_H
+#define IMX6UL_LCDIF_H
+
+#include "hw/core/sysbus.h"
+#include "qom/object.h"
+#include "qemu/timer.h"
+#include "ui/console.h"
+
+#define TYPE_IMX6UL_LCDIF "imx6ul-lcdif"
+#define IMX6UL_LCDIF_REGS_NUM ((0x230 >> 4) + 1)
+OBJECT_DECLARE_SIMPLE_TYPE(IMX6ULLCDIFState, IMX6UL_LCDIF)
+
+struct IMX6ULLCDIFState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion iomem;
+ MemoryRegionSection fbsection;
+ qemu_irq irq;
+ QemuConsole *con;
+ QEMUTimer *frame_timer;
+ uint32_t fb_base;
+ uint32_t src_width;
+ uint32_t rows;
+ uint8_t src_bpp;
+ bool invalidate;
+ uint32_t regs[IMX6UL_LCDIF_REGS_NUM];
+};
+
+#endif /* IMX6UL_LCDIF_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 40/63] hw/arm/fsl-imx6ul: Wire in the LCDIF device model
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (38 preceding siblings ...)
2026-04-27 12:47 ` [PULL 39/63] hw/display: Add i.MX6UL LCDIF device model Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 41/63] target/arm: migrate basic syndrome helpers to registerfields Peter Maydell
` (23 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Yucai Liu <1486344514@qq.com>
Instantiate LCDIF as a child object of the i.MX6UL SoC in init and
realize it in the SoC realize path before MMIO/IRQ hookup.
Also make FSL_IMX6UL select CONFIG_IMX6UL_LCDIF and map the LCDIF
region with a 16 KiB size to match the SoC memory map.
Signed-off-by: Yucai Liu <1486344514@qq.com>
Message-id: 20260412110240.93116-3-yangyanglan718@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/Kconfig | 1 +
hw/arm/fsl-imx6ul.c | 12 ++++++++++--
include/hw/arm/fsl-imx6ul.h | 4 +++-
3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index b940af9345..c31752e83a 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -656,6 +656,7 @@ config FSL_IMX6UL
imply I2C_DEVICES
select A15MPCORE
select IMX
+ select IMX6UL_LCDIF
select IMX_FEC
select IMX_I2C
select IMX_USBPHY
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
index 225e179126..1863558a0d 100644
--- a/hw/arm/fsl-imx6ul.c
+++ b/hw/arm/fsl-imx6ul.c
@@ -19,6 +19,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/arm/fsl-imx6ul.h"
+#include "hw/display/imx6ul_lcdif.h"
#include "hw/misc/unimp.h"
#include "hw/usb/imx-usb-phy.h"
#include "hw/core/boards.h"
@@ -136,6 +137,11 @@ static void fsl_imx6ul_init(Object *obj)
object_initialize_child(obj, name, &s->usb[i], TYPE_CHIPIDEA);
}
+ /*
+ * LCDIF
+ */
+ object_initialize_child(obj, "lcdif", &s->lcdif, TYPE_IMX6UL_LCDIF);
+
/*
* SDHCIs
*/
@@ -656,8 +662,10 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
/*
* LCD
*/
- create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR,
- FSL_IMX6UL_LCDIF_SIZE);
+ sysbus_realize(SYS_BUS_DEVICE(&s->lcdif), &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->lcdif), 0, FSL_IMX6UL_LCDIF_ADDR);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->lcdif), 0,
+ qdev_get_gpio_in(gic, FSL_IMX6UL_LCDIF_IRQ));
/*
* CSU
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
index f8f9c249a2..6205fe6b77 100644
--- a/include/hw/arm/fsl-imx6ul.h
+++ b/include/hw/arm/fsl-imx6ul.h
@@ -33,6 +33,7 @@
#include "hw/net/imx_fec.h"
#include "hw/usb/chipidea.h"
#include "hw/usb/imx-usb-phy.h"
+#include "hw/display/imx6ul_lcdif.h"
#include "system/memory.h"
#include "target/arm/cpu.h"
#include "qom/object.h"
@@ -84,6 +85,7 @@ struct FslIMX6ULState {
IMX2WdtState wdt[FSL_IMX6UL_NUM_WDTS];
IMXUSBPHYState usbphy[FSL_IMX6UL_NUM_USB_PHYS];
ChipideaState usb[FSL_IMX6UL_NUM_USBS];
+ IMX6ULLCDIFState lcdif;
MemoryRegion rom;
MemoryRegion caam;
MemoryRegion ocram;
@@ -143,7 +145,7 @@ enum FslIMX6ULMemoryMap {
FSL_IMX6UL_PXP_SIZE = (16 * KiB),
FSL_IMX6UL_LCDIF_ADDR = 0x021C8000,
- FSL_IMX6UL_LCDIF_SIZE = 0x100,
+ FSL_IMX6UL_LCDIF_SIZE = (16 * KiB),
FSL_IMX6UL_CSI_ADDR = 0x021C4000,
FSL_IMX6UL_CSI_SIZE = 0x100,
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 41/63] target/arm: migrate basic syndrome helpers to registerfields
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (39 preceding siblings ...)
2026-04-27 12:47 ` [PULL 40/63] hw/arm/fsl-imx6ul: Wire in the " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 42/63] target/arm: migrate system/cp trap syndromes " Peter Maydell
` (22 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
We have a registerfields interface which we can use for defining
fields alongside helpers to access them. Define the basic syndrome
layout and convert the helpers that take the imm16 data directly.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-2-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 75 ++++++++++++++++++++++++++++++++-----------
1 file changed, 57 insertions(+), 18 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index bff61f052c..517fb2368b 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -25,7 +25,7 @@
#ifndef TARGET_ARM_SYNDROME_H
#define TARGET_ARM_SYNDROME_H
-#include "qemu/bitops.h"
+#include "hw/core/registerfields.h"
/* Valid Syndrome Register EC field values */
enum arm_exception_class {
@@ -76,6 +76,11 @@ enum arm_exception_class {
EC_AA64_BKPT = 0x3c,
};
+/* Generic syndrome encoding layout for HSR and lower 32 bits of ESR_EL2 */
+FIELD(SYNDROME, EC, 26, 6)
+FIELD(SYNDROME, IL, 25, 1)
+FIELD(SYNDROME, ISS, 0, 25)
+
typedef enum {
SME_ET_AccessTrap,
SME_ET_Streaming,
@@ -113,12 +118,12 @@ typedef enum {
static inline uint32_t syn_get_ec(uint32_t syn)
{
- return syn >> ARM_EL_EC_SHIFT;
+ return FIELD_EX32(syn, SYNDROME, EC);
}
static inline uint32_t syn_set_ec(uint32_t syn, uint32_t ec)
{
- return deposit32(syn, ARM_EL_EC_SHIFT, ARM_EL_EC_LENGTH, ec);
+ return FIELD_DP32(syn, SYNDROME, EC, ec);
}
/*
@@ -133,49 +138,74 @@ static inline uint32_t syn_set_ec(uint32_t syn, uint32_t ec)
*/
static inline uint32_t syn_uncategorized(void)
{
- return (EC_UNCATEGORIZED << ARM_EL_EC_SHIFT) | ARM_EL_IL;
+ uint32_t res = syn_set_ec(0, EC_UNCATEGORIZED);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+ return res;
}
+FIELD(ISS_IMM16, IMM16, 0, 16)
+
static inline uint32_t syn_aa64_svc(uint32_t imm16)
{
- return (EC_AA64_SVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
+ uint32_t res = syn_set_ec(0, EC_AA64_SVC);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+ res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
+ return res;
}
static inline uint32_t syn_aa64_hvc(uint32_t imm16)
{
- return (EC_AA64_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
+ uint32_t res = syn_set_ec(0, EC_AA64_HVC);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+ res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
+ return res;
}
static inline uint32_t syn_aa64_smc(uint32_t imm16)
{
- return (EC_AA64_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
+ uint32_t res = syn_set_ec(0, EC_AA64_SMC);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+ res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
+ return res;
}
static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_16bit)
{
- return (EC_AA32_SVC << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
- | (is_16bit ? 0 : ARM_EL_IL);
+ uint32_t res = syn_set_ec(0, EC_AA32_SVC);
+ res = FIELD_DP32(res, SYNDROME, IL, is_16bit ? 0 : 1);
+ res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
+ return res;
}
static inline uint32_t syn_aa32_hvc(uint32_t imm16)
{
- return (EC_AA32_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
+ uint32_t res = syn_set_ec(0, EC_AA32_HVC);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+ res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
+ return res;
}
static inline uint32_t syn_aa32_smc(void)
{
- return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL;
+ uint32_t res = syn_set_ec(0, EC_AA32_SMC);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+ return res;
}
static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
{
- return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
+ uint32_t res = syn_set_ec(0, EC_AA64_BKPT);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+ res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
+ return res;
}
static inline uint32_t syn_aa32_bkpt(uint32_t imm16, bool is_16bit)
{
- return (EC_AA32_BKPT << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
- | (is_16bit ? 0 : ARM_EL_IL);
+ uint32_t res = syn_set_ec(0, EC_AA32_BKPT);
+ res = FIELD_DP32(res, SYNDROME, IL, is_16bit ? 0 : 1);
+ res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
+ return res;
}
static inline uint32_t syn_aa64_sysregtrap(int op0, int op1, int op2,
@@ -246,7 +276,9 @@ static inline uint32_t syn_simd_access_trap(int cv, int cond, bool is_16bit)
static inline uint32_t syn_sve_access_trap(void)
{
- return (EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL;
+ uint32_t res = syn_set_ec(0, EC_SVEACCESSTRAP);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+ return res;
}
/*
@@ -361,12 +393,16 @@ static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
static inline uint32_t syn_illegalstate(void)
{
- return (EC_ILLEGALSTATE << ARM_EL_EC_SHIFT) | ARM_EL_IL;
+ uint32_t res = syn_set_ec(0, EC_ILLEGALSTATE);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+ return res;
}
static inline uint32_t syn_pcalignment(void)
{
- return (EC_PCALIGNMENT << ARM_EL_EC_SHIFT) | ARM_EL_IL;
+ uint32_t res = syn_set_ec(0, EC_PCALIGNMENT);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+ return res;
}
static inline uint32_t syn_gcs_data_check(GCSInstructionType it, int rn)
@@ -388,7 +424,10 @@ static inline uint32_t syn_gcs_gcsstr(int ra, int rn)
static inline uint32_t syn_serror(uint32_t extra)
{
- return (EC_SERROR << ARM_EL_EC_SHIFT) | ARM_EL_IL | extra;
+ uint32_t res = syn_set_ec(0, EC_SERROR);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+ res = FIELD_DP32(res, SYNDROME, ISS, extra);
+ return res;
}
static inline uint32_t syn_mop(bool is_set, bool is_setg, int options,
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 42/63] target/arm: migrate system/cp trap syndromes to registerfields
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (40 preceding siblings ...)
2026-04-27 12:47 ` [PULL 41/63] target/arm: migrate basic syndrome helpers to registerfields Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 43/63] target/arm: migrate FP/SIMD " Peter Maydell
` (21 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
Migrate syn_aa64_sysregtrap and co-processor register trap syndromes
to the registerfields API. The co-processor syndromes are split
between single and duel register moves.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-3-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 124 ++++++++++++++++++++++++++++++++++--------
1 file changed, 102 insertions(+), 22 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 517fb2368b..29462aa103 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -78,7 +78,7 @@ enum arm_exception_class {
/* Generic syndrome encoding layout for HSR and lower 32 bits of ESR_EL2 */
FIELD(SYNDROME, EC, 26, 6)
-FIELD(SYNDROME, IL, 25, 1)
+FIELD(SYNDROME, IL, 25, 1) /* IL=1 for 32 bit instructions */
FIELD(SYNDROME, ISS, 0, 25)
typedef enum {
@@ -172,7 +172,7 @@ static inline uint32_t syn_aa64_smc(uint32_t imm16)
static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_16bit)
{
uint32_t res = syn_set_ec(0, EC_AA32_SVC);
- res = FIELD_DP32(res, SYNDROME, IL, is_16bit ? 0 : 1);
+ res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
return res;
}
@@ -203,58 +203,138 @@ static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
static inline uint32_t syn_aa32_bkpt(uint32_t imm16, bool is_16bit)
{
uint32_t res = syn_set_ec(0, EC_AA32_BKPT);
- res = FIELD_DP32(res, SYNDROME, IL, is_16bit ? 0 : 1);
+ res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
return res;
}
+/*
+ * ISS encoding for an exception from MSR, MRS, or System instruction
+ * in AArch64 state.
+ */
+FIELD(SYSREG_ISS, ISREAD, 0, 1) /* Direction, 1 is read */
+FIELD(SYSREG_ISS, CRM, 1, 4)
+FIELD(SYSREG_ISS, RT, 5, 5)
+FIELD(SYSREG_ISS, CRN, 10, 4)
+FIELD(SYSREG_ISS, OP1, 14, 3)
+FIELD(SYSREG_ISS, OP2, 17, 3)
+FIELD(SYSREG_ISS, OP0, 20, 2)
+
static inline uint32_t syn_aa64_sysregtrap(int op0, int op1, int op2,
int crn, int crm, int rt,
int isread)
{
- return (EC_SYSTEMREGISTERTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL
- | (op0 << 20) | (op2 << 17) | (op1 << 14) | (crn << 10) | (rt << 5)
- | (crm << 1) | isread;
+ uint32_t res = syn_set_ec(0, EC_SYSTEMREGISTERTRAP);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+
+ res = FIELD_DP32(res, SYSREG_ISS, OP0, op0);
+ res = FIELD_DP32(res, SYSREG_ISS, OP2, op2);
+ res = FIELD_DP32(res, SYSREG_ISS, OP1, op1);
+ res = FIELD_DP32(res, SYSREG_ISS, CRN, crn);
+ res = FIELD_DP32(res, SYSREG_ISS, RT, rt);
+ res = FIELD_DP32(res, SYSREG_ISS, CRM, crm);
+ res = FIELD_DP32(res, SYSREG_ISS, ISREAD, isread);
+
+ return res;
}
+/*
+ * ISS encoding for an exception from an MCR or MRC access
+ * (move to/from co-processor)
+ */
+FIELD(COPROC_ISS, ISREAD, 0, 1)
+FIELD(COPROC_ISS, CRM, 1, 4)
+FIELD(COPROC_ISS, RT, 5, 5)
+FIELD(COPROC_ISS, CRN, 10, 4)
+FIELD(COPROC_ISS, OP1, 14, 3)
+FIELD(COPROC_ISS, OP2, 17, 3)
+FIELD(COPROC_ISS, COND, 20, 4)
+FIELD(COPROC_ISS, CV, 24, 1)
+
static inline uint32_t syn_cp14_rt_trap(int cv, int cond, int opc1, int opc2,
int crn, int crm, int rt, int isread,
bool is_16bit)
{
- return (EC_CP14RTTRAP << ARM_EL_EC_SHIFT)
- | (is_16bit ? 0 : ARM_EL_IL)
- | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
- | (crn << 10) | (rt << 5) | (crm << 1) | isread;
+ uint32_t res = syn_set_ec(0, EC_CP14RTTRAP);
+ res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
+
+ res = FIELD_DP32(res, COPROC_ISS, CV, cv);
+ res = FIELD_DP32(res, COPROC_ISS, COND, cond);
+ res = FIELD_DP32(res, COPROC_ISS, OP2, opc2);
+ res = FIELD_DP32(res, COPROC_ISS, OP1, opc1);
+ res = FIELD_DP32(res, COPROC_ISS, CRN, crn);
+ res = FIELD_DP32(res, COPROC_ISS, RT, rt);
+ res = FIELD_DP32(res, COPROC_ISS, CRM, crm);
+ res = FIELD_DP32(res, COPROC_ISS, ISREAD, isread);
+
+ return res;
}
static inline uint32_t syn_cp15_rt_trap(int cv, int cond, int opc1, int opc2,
int crn, int crm, int rt, int isread,
bool is_16bit)
{
- return (EC_CP15RTTRAP << ARM_EL_EC_SHIFT)
- | (is_16bit ? 0 : ARM_EL_IL)
- | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
- | (crn << 10) | (rt << 5) | (crm << 1) | isread;
+ uint32_t res = syn_set_ec(0, EC_CP15RTTRAP);
+ res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
+
+ res = FIELD_DP32(res, COPROC_ISS, CV, cv);
+ res = FIELD_DP32(res, COPROC_ISS, COND, cond);
+ res = FIELD_DP32(res, COPROC_ISS, OP2, opc2);
+ res = FIELD_DP32(res, COPROC_ISS, OP1, opc1);
+ res = FIELD_DP32(res, COPROC_ISS, CRN, crn);
+ res = FIELD_DP32(res, COPROC_ISS, RT, rt);
+ res = FIELD_DP32(res, COPROC_ISS, CRM, crm);
+ res = FIELD_DP32(res, COPROC_ISS, ISREAD, isread);
+
+ return res;
}
+/*
+ * ISS encoding for an exception from an MCRR or MRRC access
+ * (move to/from co-processor with 2 regs)
+ */
+FIELD(COPROC_R2_ISS, ISREAD, 0, 1)
+FIELD(COPROC_R2_ISS, CRM, 1, 4)
+FIELD(COPROC_R2_ISS, RT, 5, 5)
+FIELD(COPROC_R2_ISS, RT2, 10, 5)
+FIELD(COPROC_R2_ISS, OP1, 16, 4)
+FIELD(COPROC_R2_ISS, COND, 20, 4)
+FIELD(COPROC_R2_ISS, CV, 24, 1)
+
static inline uint32_t syn_cp14_rrt_trap(int cv, int cond, int opc1, int crm,
int rt, int rt2, int isread,
bool is_16bit)
{
- return (EC_CP14RRTTRAP << ARM_EL_EC_SHIFT)
- | (is_16bit ? 0 : ARM_EL_IL)
- | (cv << 24) | (cond << 20) | (opc1 << 16)
- | (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
+ uint32_t res = syn_set_ec(0, EC_CP14RRTTRAP);
+ res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
+
+ res = FIELD_DP32(res, COPROC_R2_ISS, CV, cv);
+ res = FIELD_DP32(res, COPROC_R2_ISS, COND, cond);
+ res = FIELD_DP32(res, COPROC_R2_ISS, OP1, opc1);
+ res = FIELD_DP32(res, COPROC_R2_ISS, RT2, rt2);
+ res = FIELD_DP32(res, COPROC_R2_ISS, RT, rt);
+ res = FIELD_DP32(res, COPROC_R2_ISS, CRM, crm);
+ res = FIELD_DP32(res, COPROC_R2_ISS, ISREAD, isread);
+
+ return res;
}
static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm,
int rt, int rt2, int isread,
bool is_16bit)
{
- return (EC_CP15RRTTRAP << ARM_EL_EC_SHIFT)
- | (is_16bit ? 0 : ARM_EL_IL)
- | (cv << 24) | (cond << 20) | (opc1 << 16)
- | (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
+ uint32_t res = syn_set_ec(0, EC_CP15RRTTRAP);
+ res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
+
+ res = FIELD_DP32(res, COPROC_R2_ISS, CV, cv);
+ res = FIELD_DP32(res, COPROC_R2_ISS, COND, cond);
+ res = FIELD_DP32(res, COPROC_R2_ISS, OP1, opc1);
+ res = FIELD_DP32(res, COPROC_R2_ISS, RT2, rt2);
+ res = FIELD_DP32(res, COPROC_R2_ISS, RT, rt);
+ res = FIELD_DP32(res, COPROC_R2_ISS, CRM, crm);
+ res = FIELD_DP32(res, COPROC_R2_ISS, ISREAD, isread);
+
+ return res;
}
static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_16bit,
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 43/63] target/arm: migrate FP/SIMD trap syndromes to registerfields
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (41 preceding siblings ...)
2026-04-27 12:47 ` [PULL 42/63] target/arm: migrate system/cp trap syndromes " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 44/63] target/arm: migrate eret " Peter Maydell
` (20 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
The syn_simd_access trap was never used so remove it. We should only
see the COPROC encoding on v7 architectures.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-4-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 29462aa103..72051443d5 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -337,21 +337,26 @@ static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm,
return res;
}
+/*
+ * ISS encoding for an exception from an access to a register of
+ * instruction resulting from the FPEN or TFP traps.
+ */
+FIELD(FP_ISS, COPROC, 0, 4) /* ARMv7 only */
+FIELD(FP_ISS, COND, 20, 4)
+FIELD(FP_ISS, CV, 24, 1)
+
static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_16bit,
int coproc)
{
/* AArch32 FP trap or any AArch64 FP/SIMD trap: TA == 0 */
- return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
- | (is_16bit ? 0 : ARM_EL_IL)
- | (cv << 24) | (cond << 20) | coproc;
-}
+ uint32_t res = syn_set_ec(0, EC_ADVSIMDFPACCESSTRAP);
+ res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
-static inline uint32_t syn_simd_access_trap(int cv, int cond, bool is_16bit)
-{
- /* AArch32 SIMD trap: TA == 1 coproc == 0 */
- return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
- | (is_16bit ? 0 : ARM_EL_IL)
- | (cv << 24) | (cond << 20) | (1 << 5);
+ res = FIELD_DP32(res, FP_ISS, CV, cv);
+ res = FIELD_DP32(res, FP_ISS, COND, cond);
+ res = FIELD_DP32(res, FP_ISS, COPROC, coproc);
+
+ return res;
}
static inline uint32_t syn_sve_access_trap(void)
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 44/63] target/arm: migrate eret trap syndromes to registerfields
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (42 preceding siblings ...)
2026-04-27 12:47 ` [PULL 43/63] target/arm: migrate FP/SIMD " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 45/63] target/arm: migrate SME " Peter Maydell
` (19 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
For simplicity keep the OP as a two bit field rather than the two
interlinked fields in the docs (ERET/ERETA).
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-5-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 72051443d5..63c8e66ea9 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -367,12 +367,21 @@ static inline uint32_t syn_sve_access_trap(void)
}
/*
+ * ISS encoding for an exception from an ERET, ERETAA or ERETAB
+ * instructions.
+ *
* eret_op is bits [1:0] of the ERET instruction, so:
* 0 for ERET, 2 for ERETAA, 3 for ERETAB.
*/
+FIELD(ERET_ISS, OP, 0, 2)
+
static inline uint32_t syn_erettrap(int eret_op)
{
- return (EC_ERETTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL | eret_op;
+ uint32_t res = syn_set_ec(0, EC_ERETTRAP);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+ res = FIELD_DP32(res, ERET_ISS, OP, eret_op);
+
+ return res;
}
static inline uint32_t syn_smetrap(SMEExceptionType etype, bool is_16bit)
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 45/63] target/arm: migrate SME trap syndromes to registerfields
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (43 preceding siblings ...)
2026-04-27 12:47 ` [PULL 44/63] target/arm: migrate eret " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 46/63] target/arm: migrate PAC " Peter Maydell
` (18 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-6-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 63c8e66ea9..6105347598 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -384,10 +384,18 @@ static inline uint32_t syn_erettrap(int eret_op)
return res;
}
+/*
+ * ISS encoding for an exception due to SME functionality
+ */
+FIELD(SME_ISS, SMTC, 0, 2)
+
static inline uint32_t syn_smetrap(SMEExceptionType etype, bool is_16bit)
{
- return (EC_SMETRAP << ARM_EL_EC_SHIFT)
- | (is_16bit ? 0 : ARM_EL_IL) | etype;
+ uint32_t res = syn_set_ec(0, EC_SMETRAP);
+ res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
+ res = FIELD_DP32(res, SME_ISS, SMTC, etype);
+
+ return res;
}
static inline uint32_t syn_pacfail(bool data, int keynumber)
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 46/63] target/arm: migrate PAC trap syndromes to registerfields
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (44 preceding siblings ...)
2026-04-27 12:47 ` [PULL 45/63] target/arm: migrate SME " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 47/63] target/arm: migrate BTI " Peter Maydell
` (17 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
syn_pactrap is fairly simple as the ISS is all RES0.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-7-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 6105347598..fd8639d4f0 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -398,15 +398,32 @@ static inline uint32_t syn_smetrap(SMEExceptionType etype, bool is_16bit)
return res;
}
+/*
+ * ISS encoding for a PAC Fail exceptions
+ */
+FIELD(PACFAIL_ISS, BnA, 0, 1) /* B key or A key */
+FIELD(PACFAIL_ISS, DnI, 1, 1) /* Data or Instruction */
+
static inline uint32_t syn_pacfail(bool data, int keynumber)
{
- int error_code = (data << 1) | keynumber;
- return (EC_PACFAIL << ARM_EL_EC_SHIFT) | ARM_EL_IL | error_code;
+ uint32_t res = syn_set_ec(0, EC_PACFAIL);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+
+ res = FIELD_DP32(res, PACFAIL_ISS, DnI, data);
+ res = FIELD_DP32(res, PACFAIL_ISS, BnA, keynumber);
+
+ return res;
}
+/*
+ * ISS encoding for an exception from a trapped Pointer
+ * Authentication instruction is RES0
+ */
static inline uint32_t syn_pactrap(void)
{
- return (EC_PACTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL;
+ uint32_t res = syn_set_ec(0, EC_PACTRAP);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+ return res;
}
static inline uint32_t syn_btitrap(int btype)
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 47/63] target/arm: migrate BTI trap syndromes to registerfields
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (45 preceding siblings ...)
2026-04-27 12:47 ` [PULL 46/63] target/arm: migrate PAC " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 48/63] target/arm: migrate BXJ " Peter Maydell
` (16 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-8-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index fd8639d4f0..52a6745cb2 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -426,9 +426,18 @@ static inline uint32_t syn_pactrap(void)
return res;
}
+/*
+ * ISS encoding for an exception from a Branch Target Identification
+ * instruction.
+ */
+FIELD(BTI_ISS, BTYPE, 0, 2)
+
static inline uint32_t syn_btitrap(int btype)
{
- return (EC_BTITRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL | btype;
+ uint32_t res = syn_set_ec(0, EC_BTITRAP);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+ res = FIELD_DP32(res, BTI_ISS, BTYPE, btype);
+ return res;
}
static inline uint32_t syn_bxjtrap(int cv, int cond, int rm)
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 48/63] target/arm: migrate BXJ trap syndromes to registerfields
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (46 preceding siblings ...)
2026-04-27 12:47 ` [PULL 47/63] target/arm: migrate BTI " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 49/63] target/arm: migrate Granule Protection traps " Peter Maydell
` (15 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
This is an Armv7 specific syndrome for chips with Jazelle
functionality.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-9-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 52a6745cb2..6fcf0ac757 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -440,10 +440,26 @@ static inline uint32_t syn_btitrap(int btype)
return res;
}
+/*
+ * ISS encoding for trapped BXJ execution
+ *
+ * This is an Armv7 encoding.
+ */
+FIELD(BXJ_ISS, RM, 0, 4)
+/* bits 4:19 are Reserved, UNK/SBZP */
+FIELD(BXJ_ISS, COND, 20, 4)
+FIELD(BXJ_ISS, CV, 24, 1)
+
static inline uint32_t syn_bxjtrap(int cv, int cond, int rm)
{
- return (EC_BXJTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL |
- (cv << 24) | (cond << 20) | rm;
+ uint32_t res = syn_set_ec(0, EC_BXJTRAP);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+
+ res = FIELD_DP32(res, BXJ_ISS, CV, cv);
+ res = FIELD_DP32(res, BXJ_ISS, COND, cond);
+ res = FIELD_DP32(res, BXJ_ISS, RM, rm);
+
+ return res;
}
static inline uint32_t syn_gpc(int s2ptw, int ind, int gpcsc, int vncr,
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 49/63] target/arm: migrate Granule Protection traps to registerfields
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (47 preceding siblings ...)
2026-04-27 12:47 ` [PULL 48/63] target/arm: migrate BXJ " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 50/63] target/arm: migrate fault syndromes " Peter Maydell
` (14 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-10-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 30 +++++++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 6fcf0ac757..bc65106c61 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -462,12 +462,36 @@ static inline uint32_t syn_bxjtrap(int cv, int cond, int rm)
return res;
}
+/*
+ * ISS encoding for a Granule Protection Check exception
+ *
+ * These are only reported to EL3
+ */
+FIELD(GPC_ISS, xFSC, 0, 6)
+FIELD(GPC_ISS, WnR, 6, 1) /* Write not Read */
+FIELD(GPC_ISS, S1PTW, 7, 1)
+FIELD(GPC_ISS, CM, 8, 1)
+FIELD(GPC_ISS, VNCR, 13, 1)
+FIELD(GPC_ISS, GPCSC, 14, 6)
+FIELD(GPC_ISS, InD, 20, 1) /* Instruction not Data access */
+FIELD(GPC_ISS, S2PTW, 21, 1)
+
static inline uint32_t syn_gpc(int s2ptw, int ind, int gpcsc, int vncr,
int cm, int s1ptw, int wnr, int fsc)
{
- return (EC_GPC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (s2ptw << 21)
- | (ind << 20) | (gpcsc << 14) | (vncr << 13) | (cm << 8)
- | (s1ptw << 7) | (wnr << 6) | fsc;
+ uint32_t res = syn_set_ec(0, EC_GPC);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+
+ res = FIELD_DP32(res, GPC_ISS, S2PTW, s2ptw);
+ res = FIELD_DP32(res, GPC_ISS, InD, ind);
+ res = FIELD_DP32(res, GPC_ISS, GPCSC, gpcsc);
+ res = FIELD_DP32(res, GPC_ISS, VNCR, vncr);
+ res = FIELD_DP32(res, GPC_ISS, CM, cm);
+ res = FIELD_DP32(res, GPC_ISS, S1PTW, s1ptw);
+ res = FIELD_DP32(res, GPC_ISS, WnR, wnr);
+ res = FIELD_DP32(res, GPC_ISS, xFSC, fsc);
+
+ return res;
}
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 50/63] target/arm: migrate fault syndromes to registerfields
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (48 preceding siblings ...)
2026-04-27 12:47 ` [PULL 49/63] target/arm: migrate Granule Protection traps " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 51/63] target/arm: migrate debug " Peter Maydell
` (13 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
Migrate syn_insn_abort and syn_data_abort_* to the registerfields API.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20260422125250.1303100-11-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 87 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 74 insertions(+), 13 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index bc65106c61..2031b3704f 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -494,20 +494,64 @@ static inline uint32_t syn_gpc(int s2ptw, int ind, int gpcsc, int vncr,
return res;
}
+/*
+ * ISS encoding for an exception from an Instruction Abort
+ *
+ * (aka instruction abort)
+ */
+FIELD(IABORT_ISS, IFSC, 0, 6)
+FIELD(IABORT_ISS, S1PTW, 7, 1)
+FIELD(IABORT_ISS, EA, 9, 1)
+FIELD(IABORT_ISS, FnV, 10, 1) /* FAR not Valid */
+FIELD(IABORT_ISS, SET, 11, 2)
+FIELD(IABORT_ISS, PFV, 14, 1)
+FIELD(IABORT_ISS, TopLevel, 21, 1) /* FEAT_THE */
+
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
{
- return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
- | ARM_EL_IL | (ea << 9) | (s1ptw << 7) | fsc;
+ uint32_t res = syn_set_ec(0, EC_INSNABORT + same_el);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+
+ res = FIELD_DP32(res, IABORT_ISS, EA, ea);
+ res = FIELD_DP32(res, IABORT_ISS, S1PTW, s1ptw);
+ res = FIELD_DP32(res, IABORT_ISS, IFSC, fsc);
+
+ return res;
}
+/*
+ * ISS encoding for an exception from a Data Abort
+ */
+FIELD(DABORT_ISS, DFSC, 0, 6)
+FIELD(DABORT_ISS, WNR, 6, 1)
+FIELD(DABORT_ISS, S1PTW, 7, 1)
+FIELD(DABORT_ISS, CM, 8, 1)
+FIELD(DABORT_ISS, EA, 9, 1)
+FIELD(DABORT_ISS, FnV, 10, 1)
+FIELD(DABORT_ISS, LST, 11, 2)
+FIELD(DABORT_ISS, VNCR, 13, 1)
+FIELD(DABORT_ISS, AR, 14, 1)
+FIELD(DABORT_ISS, SF, 15, 1)
+FIELD(DABORT_ISS, SRT, 16, 5)
+FIELD(DABORT_ISS, SSE, 21, 1)
+FIELD(DABORT_ISS, SAS, 22, 2)
+FIELD(DABORT_ISS, ISV, 24, 1)
+
static inline uint32_t syn_data_abort_no_iss(int same_el, int fnv,
int ea, int cm, int s1ptw,
int wnr, int fsc)
{
- return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
- | ARM_EL_IL
- | (fnv << 10) | (ea << 9) | (cm << 8) | (s1ptw << 7)
- | (wnr << 6) | fsc;
+ uint32_t res = syn_set_ec(0, EC_DATAABORT + same_el);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+
+ res = FIELD_DP32(res, DABORT_ISS, FnV, fnv);
+ res = FIELD_DP32(res, DABORT_ISS, EA, ea);
+ res = FIELD_DP32(res, DABORT_ISS, CM, cm);
+ res = FIELD_DP32(res, DABORT_ISS, S1PTW, s1ptw);
+ res = FIELD_DP32(res, DABORT_ISS, WNR, wnr);
+ res = FIELD_DP32(res, DABORT_ISS, DFSC, fsc);
+
+ return res;
}
static inline uint32_t syn_data_abort_with_iss(int same_el,
@@ -517,11 +561,22 @@ static inline uint32_t syn_data_abort_with_iss(int same_el,
int wnr, int fsc,
bool is_16bit)
{
- return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
- | (is_16bit ? 0 : ARM_EL_IL)
- | ARM_EL_ISV | (sas << 22) | (sse << 21) | (srt << 16)
- | (sf << 15) | (ar << 14)
- | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
+ uint32_t res = syn_set_ec(0, EC_DATAABORT + same_el);
+ res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
+
+ res = FIELD_DP32(res, DABORT_ISS, ISV, 1);
+ res = FIELD_DP32(res, DABORT_ISS, SAS, sas);
+ res = FIELD_DP32(res, DABORT_ISS, SSE, sse);
+ res = FIELD_DP32(res, DABORT_ISS, SRT, srt);
+ res = FIELD_DP32(res, DABORT_ISS, SF, sf);
+ res = FIELD_DP32(res, DABORT_ISS, AR, ar);
+ res = FIELD_DP32(res, DABORT_ISS, EA, ea);
+ res = FIELD_DP32(res, DABORT_ISS, CM, cm);
+ res = FIELD_DP32(res, DABORT_ISS, S1PTW, s1ptw);
+ res = FIELD_DP32(res, DABORT_ISS, WNR, wnr);
+ res = FIELD_DP32(res, DABORT_ISS, DFSC, fsc);
+
+ return res;
}
/*
@@ -530,8 +585,14 @@ static inline uint32_t syn_data_abort_with_iss(int same_el,
*/
static inline uint32_t syn_data_abort_vncr(int ea, int wnr, int fsc)
{
- return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (1 << ARM_EL_EC_SHIFT)
- | ARM_EL_IL | ARM_EL_VNCR | (wnr << 6) | fsc;
+ uint32_t res = syn_set_ec(0, EC_DATAABORT_SAME_EL);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+
+ res = FIELD_DP32(res, DABORT_ISS, VNCR, 1);
+ res = FIELD_DP32(res, DABORT_ISS, WNR, wnr);
+ res = FIELD_DP32(res, DABORT_ISS, DFSC, fsc);
+
+ return res;
}
static inline uint32_t syn_swstep(int same_el, int isv, int ex)
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 51/63] target/arm: migrate debug syndromes to registerfields
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (49 preceding siblings ...)
2026-04-27 12:47 ` [PULL 50/63] target/arm: migrate fault syndromes " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 52/63] target/arm: migrate wfx " Peter Maydell
` (12 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
Migrate syn_swstep, syn_watchpoint and syn_breakpoint to the
registerfields API.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-12-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 54 ++++++++++++++++++++++++++++++++++++++-----
1 file changed, 48 insertions(+), 6 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 2031b3704f..2ad6b97aea 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -595,22 +595,64 @@ static inline uint32_t syn_data_abort_vncr(int ea, int wnr, int fsc)
return res;
}
+/*
+ * ISS encoding for an exception from a Software Step exception.
+ */
+FIELD(SOFTSTEP_ISS, IFSC, 0, 6)
+FIELD(SOFTSTEP_ISS, EX, 6, 1)
+FIELD(SOFTSTEP_ISS, ISV, 24, 1)
+
static inline uint32_t syn_swstep(int same_el, int isv, int ex)
{
- return (EC_SOFTWARESTEP << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
- | ARM_EL_IL | (isv << 24) | (ex << 6) | 0x22;
+ uint32_t res = syn_set_ec(0, EC_SOFTWARESTEP + same_el);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+
+ res = FIELD_DP32(res, SOFTSTEP_ISS, ISV, isv);
+ res = FIELD_DP32(res, SOFTSTEP_ISS, EX, ex);
+ res = FIELD_DP32(res, SOFTSTEP_ISS, IFSC, 0x22);
+
+ return res;
}
+/*
+ * ISS encoding for an exception from a Watchpoint exception
+ */
+FIELD(WATCHPOINT_ISS, DFSC, 0, 6)
+FIELD(WATCHPOINT_ISS, WNR, 6, 1)
+FIELD(WATCHPOINT_ISS, CM, 8, 1)
+FIELD(WATCHPOINT_ISS, FnV, 10, 1)
+FIELD(WATCHPOINT_ISS, VNCR, 13, 1) /* FEAT_NV2 */
+FIELD(WATCHPOINT_ISS, FnP, 15, 1)
+FIELD(WATCHPOINT_ISS, WPF, 16, 1)
+/* bellow mandatory from FEAT_Debugv8p9 */
+FIELD(WATCHPOINT_ISS, WPTV, 17, 1) /* FEAT_Debugv8p2 - WPT valid */
+FIELD(WATCHPOINT_ISS, WPT, 18, 6) /* FEAT_Debugv8p2 - missing WP number */
+
static inline uint32_t syn_watchpoint(int same_el, int cm, int wnr)
{
- return (EC_WATCHPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
- | ARM_EL_IL | (cm << 8) | (wnr << 6) | 0x22;
+ uint32_t res = syn_set_ec(0, EC_WATCHPOINT + same_el);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+
+ res = FIELD_DP32(res, WATCHPOINT_ISS, CM, cm);
+ res = FIELD_DP32(res, WATCHPOINT_ISS, WNR, wnr);
+ res = FIELD_DP32(res, WATCHPOINT_ISS, DFSC, 0x22);
+
+ return res;
}
+/*
+ * ISS encoding for an exception from a Breakpoint or a Vector Catch
+ * debug exception.
+ */
+FIELD(BREAKPOINT_ISS, IFSC, 0, 6)
+
static inline uint32_t syn_breakpoint(int same_el)
{
- return (EC_BREAKPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
- | ARM_EL_IL | 0x22;
+ uint32_t res = syn_set_ec(0, EC_BREAKPOINT + same_el);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+ res = FIELD_DP32(res, BREAKPOINT_ISS, IFSC, 0x22);
+
+ return res;
}
static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 52/63] target/arm: migrate wfx syndromes to registerfields
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (50 preceding siblings ...)
2026-04-27 12:47 ` [PULL 51/63] target/arm: migrate debug " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 53/63] target/arm: migrate gcs " Peter Maydell
` (11 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
This will help later when we expand the fields we report.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-13-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 2ad6b97aea..65d0de63a8 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -655,11 +655,25 @@ static inline uint32_t syn_breakpoint(int same_el)
return res;
}
+/*
+ * ISS encoding for an exception from a WF* instruction
+ */
+FIELD(WFX_ISS, TI, 0, 2)
+FIELD(WFX_ISS, RV, 2, 1)
+FIELD(WFX_ISS, RN, 5, 5)
+FIELD(WFX_ISS, COND, 20, 4)
+FIELD(WFX_ISS, CV, 24, 1)
+
static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
{
- return (EC_WFX_TRAP << ARM_EL_EC_SHIFT) |
- (is_16bit ? 0 : (1 << ARM_EL_IL_SHIFT)) |
- (cv << 24) | (cond << 20) | ti;
+ uint32_t res = syn_set_ec(0, EC_WFX_TRAP);
+ res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
+
+ res = FIELD_DP32(res, WFX_ISS, CV, cv);
+ res = FIELD_DP32(res, WFX_ISS, COND, cond);
+ res = FIELD_DP32(res, WFX_ISS, TI, ti);
+
+ return res;
}
static inline uint32_t syn_illegalstate(void)
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 53/63] target/arm: migrate gcs syndromes to registerfields
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (51 preceding siblings ...)
2026-04-27 12:47 ` [PULL 52/63] target/arm: migrate wfx " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 54/63] target/arm: migrate memory op " Peter Maydell
` (10 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
Tweak arg names to make it clear raddr is the data address register
number.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-14-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 39 +++++++++++++++++++++++++++++++++------
1 file changed, 33 insertions(+), 6 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 65d0de63a8..7ff8c30e2b 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -690,21 +690,48 @@ static inline uint32_t syn_pcalignment(void)
return res;
}
+/*
+ * ISS encoding for a GCS exception
+ *
+ * Field validity depends on EXTYPE
+ */
+FIELD(GCS_ISS, IT, 0, 5)
+FIELD(GCS_ISS, RN, 5, 5) /* only for non EXLOCK exceptions */
+FIELD(GCS_ISS, RADDR, 10, 5) /* only for GCSSTR/GCSSTTR traps */
+FIELD(GCS_ISS, EXTYPE, 20, 4)
+
static inline uint32_t syn_gcs_data_check(GCSInstructionType it, int rn)
{
- return ((EC_GCS << ARM_EL_EC_SHIFT) | ARM_EL_IL |
- (GCS_ET_DataCheck << 20) | (rn << 5) | it);
+ uint32_t res = syn_set_ec(0, EC_GCS);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+
+ res = FIELD_DP32(res, GCS_ISS, EXTYPE, GCS_ET_DataCheck);
+ res = FIELD_DP32(res, GCS_ISS, RN, rn);
+ res = FIELD_DP32(res, GCS_ISS, IT, it);
+
+ return res;
}
static inline uint32_t syn_gcs_exlock(void)
{
- return (EC_GCS << ARM_EL_EC_SHIFT) | ARM_EL_IL | (GCS_ET_EXLOCK << 20);
+ uint32_t res = syn_set_ec(0, EC_GCS);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+
+ res = FIELD_DP32(res, GCS_ISS, EXTYPE, GCS_ET_EXLOCK);
+
+ return res;
}
-static inline uint32_t syn_gcs_gcsstr(int ra, int rn)
+static inline uint32_t syn_gcs_gcsstr(int raddr, int rn)
{
- return ((EC_GCS << ARM_EL_EC_SHIFT) | ARM_EL_IL |
- (GCS_ET_GCSSTR_GCSSTTR << 20) | (ra << 10) | (rn << 5));
+ uint32_t res = syn_set_ec(0, EC_GCS);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+
+ res = FIELD_DP32(res, GCS_ISS, EXTYPE, GCS_ET_GCSSTR_GCSSTTR);
+ res = FIELD_DP32(res, GCS_ISS, RADDR, raddr);
+ res = FIELD_DP32(res, GCS_ISS, RN, rn);
+
+ return res;
}
static inline uint32_t syn_serror(uint32_t extra)
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 54/63] target/arm: migrate memory op syndromes to registerfields
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (52 preceding siblings ...)
2026-04-27 12:47 ` [PULL 53/63] target/arm: migrate gcs " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 55/63] target/arm: migrate check_hcr_el2_trap to use syndrome helper Peter Maydell
` (9 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-15-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 33 +++++++++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 7ff8c30e2b..841fd3292b 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -742,14 +742,39 @@ static inline uint32_t syn_serror(uint32_t extra)
return res;
}
+/*
+ * ISS encoding for an exception from the Memory Copy and Memory Set
+ * instructions.
+ */
+FIELD(MOP_ISS, SIZEREG, 0, 5)
+FIELD(MOP_ISS, SRCREG, 5, 5)
+FIELD(MOP_ISS, DESTREG, 10, 5)
+FIELD(MOP_ISS, FORMATOPT, 16, 2)
+FIELD(MOP_ISS, OPT_A, 16, 1)
+FIELD(MOP_ISS, WRONG_OPT, 17, 1)
+FIELD(MOP_ISS, EPILOGUE, 18, 1)
+FIELD(MOP_ISS, OPTIONS, 19, 4)
+FIELD(MOP_ISS, IS_SETG, 23, 1)
+FIELD(MOP_ISS, MEMINST, 24, 1)
+
static inline uint32_t syn_mop(bool is_set, bool is_setg, int options,
bool epilogue, bool wrong_option, bool option_a,
int destreg, int srcreg, int sizereg)
{
- return (EC_MOP << ARM_EL_EC_SHIFT) | ARM_EL_IL |
- (is_set << 24) | (is_setg << 23) | (options << 19) |
- (epilogue << 18) | (wrong_option << 17) | (option_a << 16) |
- (destreg << 10) | (srcreg << 5) | sizereg;
+ uint32_t res = syn_set_ec(0, EC_MOP);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+
+ res = FIELD_DP32(res, MOP_ISS, MEMINST, is_set);
+ res = FIELD_DP32(res, MOP_ISS, IS_SETG, is_setg);
+ res = FIELD_DP32(res, MOP_ISS, OPTIONS, options);
+ res = FIELD_DP32(res, MOP_ISS, EPILOGUE, epilogue);
+ res = FIELD_DP32(res, MOP_ISS, WRONG_OPT, wrong_option);
+ res = FIELD_DP32(res, MOP_ISS, OPT_A, option_a);
+ res = FIELD_DP32(res, MOP_ISS, DESTREG, destreg);
+ res = FIELD_DP32(res, MOP_ISS, SRCREG, srcreg);
+ res = FIELD_DP32(res, MOP_ISS, SIZEREG, sizereg);
+
+ return res;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 55/63] target/arm: migrate check_hcr_el2_trap to use syndrome helper
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (53 preceding siblings ...)
2026-04-27 12:47 ` [PULL 54/63] target/arm: migrate memory op " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 56/63] target/arm: use syndrome helpers in arm_cpu_do_interrupt_aarch32_hyp Peter Maydell
` (8 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
It shares the same COPROC_ISS encoding as the other CP traps although
not all the fields are used.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-16-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 16 ++++++++++++++++
target/arm/tcg/vfp_helper.c | 5 +----
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 841fd3292b..53137394e2 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -251,6 +251,22 @@ FIELD(COPROC_ISS, OP2, 17, 3)
FIELD(COPROC_ISS, COND, 20, 4)
FIELD(COPROC_ISS, CV, 24, 1)
+static inline uint32_t syn_cp10_rt_trap(int cv, int cond, int opc1,
+ int crn, int rt, int isread)
+{
+ uint32_t res = syn_set_ec(0, EC_FPIDTRAP);
+ res = FIELD_DP32(res, SYNDROME, IL, 1);
+
+ res = FIELD_DP32(res, COPROC_ISS, CV, cv);
+ res = FIELD_DP32(res, COPROC_ISS, COND, cond);
+ res = FIELD_DP32(res, COPROC_ISS, OP1, opc1);
+ res = FIELD_DP32(res, COPROC_ISS, CRN, crn);
+ res = FIELD_DP32(res, COPROC_ISS, RT, rt);
+ res = FIELD_DP32(res, COPROC_ISS, ISREAD, isread);
+
+ return res;
+}
+
static inline uint32_t syn_cp14_rt_trap(int cv, int cond, int opc1, int opc2,
int crn, int crm, int rt, int isread,
bool is_16bit)
diff --git a/target/arm/tcg/vfp_helper.c b/target/arm/tcg/vfp_helper.c
index 45f2eb0930..e692bc568b 100644
--- a/target/arm/tcg/vfp_helper.c
+++ b/target/arm/tcg/vfp_helper.c
@@ -1359,10 +1359,7 @@ void HELPER(check_hcr_el2_trap)(CPUARMState *env, uint32_t rt, uint32_t reg)
g_assert_not_reached();
}
- syndrome = ((EC_FPIDTRAP << ARM_EL_EC_SHIFT)
- | ARM_EL_IL
- | (1 << 24) | (0xe << 20) | (7 << 14)
- | (reg << 10) | (rt << 5) | 1);
+ syndrome = syn_cp10_rt_trap(1, 0xe, 7, reg, rt, 1);
raise_exception(env, EXCP_HYP_TRAP, syndrome, 2);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 56/63] target/arm: use syndrome helpers in arm_cpu_do_interrupt_aarch32_hyp
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (54 preceding siblings ...)
2026-04-27 12:47 ` [PULL 55/63] target/arm: migrate check_hcr_el2_trap to use syndrome helper Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 57/63] target/arm: use syndrome helpers to set SAME_EL EC bit Peter Maydell
` (7 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
One more step towards dropping the old #defines.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-17-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/helper.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index ccd6353190..7e7677a584 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8844,9 +8844,9 @@ static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
*/
if (cs->exception_index == EXCP_PREFETCH_ABORT ||
(cs->exception_index == EXCP_DATA_ABORT &&
- !(env->exception.syndrome & ARM_EL_ISV)) ||
+ !FIELD_EX32(env->exception.syndrome, SYNDROME, IL)) ||
syn_get_ec(env->exception.syndrome) == EC_UNCATEGORIZED) {
- env->exception.syndrome &= ~ARM_EL_IL;
+ env->exception.syndrome = FIELD_DP32(env->exception.syndrome, SYNDROME, IL, 0);
}
}
env->cp15.esr_el[2] = env->exception.syndrome;
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 57/63] target/arm: use syndrome helpers to set SAME_EL EC bit
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (55 preceding siblings ...)
2026-04-27 12:47 ` [PULL 56/63] target/arm: use syndrome helpers in arm_cpu_do_interrupt_aarch32_hyp Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 58/63] target/arm: make whpx use syndrome helpers for decode Peter Maydell
` (6 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
This removes the last use of ARM_EL_EC_SHIFT.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-18-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 1 -
target/arm/tcg/debug.c | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 53137394e2..d4dfab8cd1 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -107,7 +107,6 @@ typedef enum {
} GCSInstructionType;
#define ARM_EL_EC_LENGTH 6
-#define ARM_EL_EC_SHIFT 26
#define ARM_EL_IL_SHIFT 25
#define ARM_EL_ISV_SHIFT 24
#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
diff --git a/target/arm/tcg/debug.c b/target/arm/tcg/debug.c
index 5214e3c08a..07a52643e7 100644
--- a/target/arm/tcg/debug.c
+++ b/target/arm/tcg/debug.c
@@ -56,7 +56,7 @@ raise_exception_debug(CPUARMState *env, uint32_t excp, uint32_t syndrome)
* Similarly for watchpoint and breakpoint matches.
*/
assert(debug_el >= cur_el);
- syndrome |= (debug_el == cur_el) << ARM_EL_EC_SHIFT;
+ syndrome |= (debug_el == cur_el) << R_SYNDROME_EC_SHIFT;
raise_exception(env, excp, syndrome, debug_el);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 58/63] target/arm: make whpx use syndrome helpers for decode
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (56 preceding siblings ...)
2026-04-27 12:47 ` [PULL 57/63] target/arm: use syndrome helpers to set SAME_EL EC bit Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 59/63] target/arm: make hvf " Peter Maydell
` (5 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
Rather than open coding a bunch of shifts and masks we can use the
syndrome definitions. While we are at it assert it really is a
EC_DATAABORT.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-19-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/whpx/whpx-all.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/target/arm/whpx/whpx-all.c b/target/arm/whpx/whpx-all.c
index bbf0f6be96..4cfc7f9969 100644
--- a/target/arm/whpx/whpx-all.c
+++ b/target/arm/whpx/whpx-all.c
@@ -356,15 +356,16 @@ static int whpx_handle_mmio(CPUState *cpu, WHV_MEMORY_ACCESS_CONTEXT *ctx)
{
uint64_t syndrome = ctx->Syndrome;
- bool isv = syndrome & ARM_EL_ISV;
- bool iswrite = (syndrome >> 6) & 1;
- bool sse = (syndrome >> 21) & 1;
- uint32_t sas = (syndrome >> 22) & 3;
+ bool isv = FIELD_EX32(syndrome, DABORT_ISS, ISV);
+ bool iswrite = FIELD_EX32(syndrome, DABORT_ISS, WNR);
+ bool sse = FIELD_EX32(syndrome, DABORT_ISS, SSE);
+ uint32_t sas = FIELD_EX32(syndrome, DABORT_ISS, SAS);
uint32_t len = 1 << sas;
- uint32_t srt = (syndrome >> 16) & 0x1f;
- uint32_t cm = (syndrome >> 8) & 0x1;
+ uint32_t srt = FIELD_EX32(syndrome, DABORT_ISS, SRT);
+ uint32_t cm = FIELD_EX32(syndrome, DABORT_ISS, CM);
uint64_t val = 0;
+ assert(syn_get_ec(syndrome) == EC_DATAABORT);
assert(!cm);
assert(isv);
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 59/63] target/arm: make hvf use syndrome helpers for decode
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (57 preceding siblings ...)
2026-04-27 12:47 ` [PULL 58/63] target/arm: make whpx use syndrome helpers for decode Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 60/63] target/arm: use syndrome helpers in merge_syn_data_abort Peter Maydell
` (4 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
Rather than open coding a bunch of shifts and masks we can use the
syndrome definitions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20260422125250.1303100-20-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/hvf/hvf.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 678afe5c8e..ef4c3671e9 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -2123,14 +2123,14 @@ static int hvf_handle_exception(CPUState *cpu, hv_vcpu_exit_exception_t *excp)
break;
}
case EC_DATAABORT: {
- bool isv = syndrome & ARM_EL_ISV;
- bool iswrite = (syndrome >> 6) & 1;
- bool s1ptw = (syndrome >> 7) & 1;
- bool sse = (syndrome >> 21) & 1;
- uint32_t sas = (syndrome >> 22) & 3;
+ bool isv = FIELD_EX32(syndrome, DABORT_ISS, ISV);
+ bool iswrite = FIELD_EX32(syndrome, DABORT_ISS, WNR);
+ bool s1ptw = FIELD_EX32(syndrome, DABORT_ISS, S1PTW);
+ bool sse = FIELD_EX32(syndrome, DABORT_ISS, SSE);
+ uint32_t sas = FIELD_EX32(syndrome, DABORT_ISS, SAS);
uint32_t len = 1 << sas;
- uint32_t srt = (syndrome >> 16) & 0x1f;
- uint32_t cm = (syndrome >> 8) & 0x1;
+ uint32_t srt = FIELD_EX32(syndrome, DABORT_ISS, SRT);
+ uint32_t cm = FIELD_EX32(syndrome, DABORT_ISS, CM);
uint64_t val = 0;
uint64_t ipa = excp->physical_address;
AddressSpace *as = cpu_get_address_space(cpu, ARMASIdx_NS);
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 60/63] target/arm: use syndrome helpers in merge_syn_data_abort
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (58 preceding siblings ...)
2026-04-27 12:47 ` [PULL 59/63] target/arm: make hvf " Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 61/63] target/arm: use syndrome helpers to query VNCR bit Peter Maydell
` (3 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
One more step to removing the old defines.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-21-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/tcg/tlb_helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
index 565954269f..c74d8e785a 100644
--- a/target/arm/tcg/tlb_helper.c
+++ b/target/arm/tcg/tlb_helper.c
@@ -56,7 +56,7 @@ static inline uint64_t merge_syn_data_abort(uint32_t template_syn,
*/
assert(!fi->stage2);
syn = syn_data_abort_vncr(fi->ea, is_write, fsc);
- } else if (!(template_syn & ARM_EL_ISV) || target_el != 2
+ } else if (!FIELD_EX32(template_syn, DABORT_ISS, ISV) || target_el != 2
|| fi->s1ptw || !fi->stage2) {
syn = syn_data_abort_no_iss(same_el, 0,
fi->ea, 0, fi->s1ptw, is_write, fsc);
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 61/63] target/arm: use syndrome helpers to query VNCR bit
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (59 preceding siblings ...)
2026-04-27 12:47 ` [PULL 60/63] target/arm: use syndrome helpers in merge_syn_data_abort Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 62/63] target/arm: remove old syndrome defines Peter Maydell
` (2 subsequent siblings)
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
These are only valid for data abort syndromes.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-22-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/tcg/tlb_helper.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
index c74d8e785a..bbe1e70bc4 100644
--- a/target/arm/tcg/tlb_helper.c
+++ b/target/arm/tcg/tlb_helper.c
@@ -48,7 +48,7 @@ static inline uint64_t merge_syn_data_abort(uint32_t template_syn,
* ST64BV, or ST64BV0 insns report syndrome info even for stage-1
* faults and regardless of the target EL.
*/
- if (template_syn & ARM_EL_VNCR) {
+ if (FIELD_EX32(template_syn, DABORT_ISS, VNCR)) {
/*
* FEAT_NV2 faults on accesses via VNCR_EL2 are a special case:
* they are always reported as "same EL", even though we are going
@@ -190,7 +190,7 @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
* because we masked that out in disas_set_insn_syndrome())
*/
bool is_vncr = (access_type != MMU_INST_FETCH) &&
- (env->exception.syndrome & ARM_EL_VNCR);
+ FIELD_EX32(env->exception.syndrome, DABORT_ISS, VNCR);
if (is_vncr) {
/* FEAT_NV2 faults on accesses via VNCR_EL2 go to EL2 */
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 62/63] target/arm: remove old syndrome defines
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (60 preceding siblings ...)
2026-04-27 12:47 ` [PULL 61/63] target/arm: use syndrome helpers to query VNCR bit Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-27 12:47 ` [PULL 63/63] target/arm: report register in WFIT syndromes Peter Maydell
2026-04-28 12:02 ` [PULL 00/63] target-arm queue Stefan Hajnoczi
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
Now everything is defined with registerfields we can drop the old
defines.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-23-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index d4dfab8cd1..04a71eebcb 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -106,15 +106,6 @@ typedef enum {
GCS_IT_GCSPOPX = 9,
} GCSInstructionType;
-#define ARM_EL_EC_LENGTH 6
-#define ARM_EL_IL_SHIFT 25
-#define ARM_EL_ISV_SHIFT 24
-#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
-#define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT)
-
-/* In the Data Abort syndrome */
-#define ARM_EL_VNCR (1 << 13)
-
static inline uint32_t syn_get_ec(uint32_t syn)
{
return FIELD_EX32(syn, SYNDROME, EC);
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* [PULL 63/63] target/arm: report register in WFIT syndromes
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (61 preceding siblings ...)
2026-04-27 12:47 ` [PULL 62/63] target/arm: remove old syndrome defines Peter Maydell
@ 2026-04-27 12:47 ` Peter Maydell
2026-04-28 12:02 ` [PULL 00/63] target-arm queue Stefan Hajnoczi
63 siblings, 0 replies; 68+ messages in thread
From: Peter Maydell @ 2026-04-27 12:47 UTC (permalink / raw)
To: qemu-devel
From: Alex Bennée <alex.bennee@linaro.org>
Pass the register number (rd) to the wfit helper and report it in the
syndrome ISS.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20260422125250.1303100-24-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/syndrome.h | 11 ++++++++++-
target/arm/tcg/helper-defs.h | 2 +-
target/arm/tcg/op_helper.c | 7 ++++---
target/arm/tcg/translate-a64.c | 2 +-
4 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 04a71eebcb..4d1f1c529e 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -670,7 +670,14 @@ FIELD(WFX_ISS, RN, 5, 5)
FIELD(WFX_ISS, COND, 20, 4)
FIELD(WFX_ISS, CV, 24, 1)
-static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
+typedef enum {
+ WFI = 0b00,
+ WFE = 0b01,
+ WFIT = 0b10,
+ WFET = 0xb11
+} wfx_ti;
+
+static inline uint32_t syn_wfx(int cv, int cond, int rn, bool rv, wfx_ti ti, bool is_16bit)
{
uint32_t res = syn_set_ec(0, EC_WFX_TRAP);
res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
@@ -678,6 +685,8 @@ static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
res = FIELD_DP32(res, WFX_ISS, CV, cv);
res = FIELD_DP32(res, WFX_ISS, COND, cond);
res = FIELD_DP32(res, WFX_ISS, TI, ti);
+ res = FIELD_DP32(res, WFX_ISS, RN, rn);
+ res = FIELD_DP32(res, WFX_ISS, RV, rv);
return res;
}
diff --git a/target/arm/tcg/helper-defs.h b/target/arm/tcg/helper-defs.h
index 5a10a9fba3..a05f2258f2 100644
--- a/target/arm/tcg/helper-defs.h
+++ b/target/arm/tcg/helper-defs.h
@@ -55,7 +55,7 @@ DEF_HELPER_2(exception_pc_alignment, noreturn, env, vaddr)
DEF_HELPER_1(setend, void, env)
DEF_HELPER_2(wfi, void, env, i32)
DEF_HELPER_1(wfe, void, env)
-DEF_HELPER_2(wfit, void, env, i64)
+DEF_HELPER_2(wfit, void, env, i32)
DEF_HELPER_1(yield, void, env)
DEF_HELPER_1(pre_hvc, void, env)
DEF_HELPER_2(pre_smc, void, env, i32)
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
index 75ad53ec6c..e8f0996ed3 100644
--- a/target/arm/tcg/op_helper.c
+++ b/target/arm/tcg/op_helper.c
@@ -398,7 +398,7 @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
env->regs[15] -= insn_len;
}
- raise_exception(env, excp, syn_wfx(1, 0xe, 0, insn_len == 2),
+ raise_exception(env, excp, syn_wfx(1, 0xe, 0, false, WFI, insn_len == 2),
target_el);
}
@@ -408,7 +408,7 @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
#endif
}
-void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
+void HELPER(wfit)(CPUARMState *env, uint32_t rd)
{
#ifdef CONFIG_USER_ONLY
/*
@@ -427,6 +427,7 @@ void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
int target_el = check_wfx_trap(env, false, &excp);
/* The WFIT should time out when CNTVCT_EL0 >= the specified value. */
uint64_t cntval = gt_get_countervalue(env);
+ uint64_t timeout = env->xregs[rd];
/*
* We want the value that we would get if we read CNTVCT_EL0 from
* the current exception level, so the direct_access offset, not
@@ -447,7 +448,7 @@ void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
if (target_el) {
env->pc -= 4;
- raise_exception(env, excp, syn_wfx(1, 0xe, 2, false), target_el);
+ raise_exception(env, excp, syn_wfx(1, 0xe, rd, true, WFIT, false), target_el);
}
if (uadd64_overflow(timeout, offset, &nexttick)) {
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 48b5c57255..9a27c4c6ec 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -2065,7 +2065,7 @@ static bool trans_WFIT(DisasContext *s, arg_WFIT *a)
}
gen_a64_update_pc(s, 4);
- gen_helper_wfit(tcg_env, cpu_reg(s, a->rd));
+ gen_helper_wfit(tcg_env, tcg_constant_i32(a->rd));
/* Go back to the main loop to check for interrupts */
s->base.is_jmp = DISAS_EXIT;
return true;
--
2.43.0
^ permalink raw reply related [flat|nested] 68+ messages in thread
* Re: [PULL 00/63] target-arm queue
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
` (62 preceding siblings ...)
2026-04-27 12:47 ` [PULL 63/63] target/arm: report register in WFIT syndromes Peter Maydell
@ 2026-04-28 12:02 ` Stefan Hajnoczi
63 siblings, 0 replies; 68+ messages in thread
From: Stefan Hajnoczi @ 2026-04-28 12:02 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 116 bytes --]
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/11.1 for any user-visible changes.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 68+ messages in thread
* Re: [PULL 39/63] hw/display: Add i.MX6UL LCDIF device model
2026-04-27 12:47 ` [PULL 39/63] hw/display: Add i.MX6UL LCDIF device model Peter Maydell
@ 2026-05-20 16:33 ` Philippe Mathieu-Daudé
2026-05-20 16:45 ` Peter Maydell
0 siblings, 1 reply; 68+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-05-20 16:33 UTC (permalink / raw)
To: Peter Maydell, qemu-devel; +Cc: Yucai Liu
Hi Yucai,
On 27/4/26 14:47, Peter Maydell wrote:
> From: Yucai Liu <1486344514@qq.com>
>
> Implement a basic i.MX6UL LCDIF controller model with MMIO registers,
> frame-done interrupt behavior, and framebuffer-backed display updates
> for RGB565 and XRGB8888 input formats.
>
> Place the LCDIF device under hw/display and build it via a dedicated
> CONFIG_IMX6UL_LCDIF symbol. Model register fields with
> registerfields.h helpers and provide migration support via vmstate.
>
> Signed-off-by: Yucai Liu <1486344514@qq.com>
> Message-id: 20260412110240.93116-2-yangyanglan718@gmail.com
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> MAINTAINERS | 2 +
> hw/display/Kconfig | 4 +
> hw/display/imx6ul_lcdif.c | 453 ++++++++++++++++++++++++++++++
> hw/display/meson.build | 1 +
> include/hw/display/imx6ul_lcdif.h | 37 +++
> 5 files changed, 497 insertions(+)
> create mode 100644 hw/display/imx6ul_lcdif.c
> create mode 100644 include/hw/display/imx6ul_lcdif.h
> diff --git a/hw/display/imx6ul_lcdif.c b/hw/display/imx6ul_lcdif.c
> +static void imx6ul_lcdif_reset(DeviceState *dev)
> +{
> + IMX6ULLCDIFState *s = IMX6UL_LCDIF(dev);
> +
> + memset(s->regs, 0, sizeof(s->regs));
> + s->regs[IMX6UL_LCDIF_REG_CTRL1] = LCDIF_RESET_CTRL1;
> + s->fb_base = 0;
> + s->src_width = 0;
> + s->rows = 0;
> + s->src_bpp = 0;
> + s->invalidate = true;
> + timer_del(s->frame_timer);
> + imx6ul_lcdif_update_irq(s);
> +}
> +static void imx6ul_lcdif_class_init(ObjectClass *klass, const void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> +
> + dc->realize = imx6ul_lcdif_realize;
> + dc->unrealize = imx6ul_lcdif_unrealize;
> + dc->vmsd = &vmstate_imx6ul_lcdif;
> + device_class_set_legacy_reset(dc, imx6ul_lcdif_reset);
Please do not use the legacy API. See for example this commit
to convert to the newer API:
https://gitlab.com/qemu-project/qemu/-/commit/ce788d3740f
> + dc->desc = "i.MX6UL LCDIF";
> +}
^ permalink raw reply [flat|nested] 68+ messages in thread
* Re: [PULL 39/63] hw/display: Add i.MX6UL LCDIF device model
2026-05-20 16:33 ` Philippe Mathieu-Daudé
@ 2026-05-20 16:45 ` Peter Maydell
2026-05-20 17:14 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 68+ messages in thread
From: Peter Maydell @ 2026-05-20 16:45 UTC (permalink / raw)
To: Philippe Mathieu-Daudé; +Cc: qemu-devel, Yucai Liu
On Wed, 20 May 2026 at 17:33, Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
>
> Hi Yucai,
>
> On 27/4/26 14:47, Peter Maydell wrote:
> > +static void imx6ul_lcdif_class_init(ObjectClass *klass, const void *data)
> > +{
> > + DeviceClass *dc = DEVICE_CLASS(klass);
> > +
> > + dc->realize = imx6ul_lcdif_realize;
> > + dc->unrealize = imx6ul_lcdif_unrealize;
> > + dc->vmsd = &vmstate_imx6ul_lcdif;
> > + device_class_set_legacy_reset(dc, imx6ul_lcdif_reset);
>
> Please do not use the legacy API. See for example this commit
> to convert to the newer API:
> https://gitlab.com/qemu-project/qemu/-/commit/ce788d3740f
There's not really a problem with continuing to use the legacy
reset API for this kind of "leaf class" device. It has identical
semantics to just providing a 3-phase "hold" reset method, the
compatibility-code is trivial and not a big maintenance burden,
and we're unlikely to convert all 400+ existing users. (Unless
somebody figures out a Coccinelle script for it, in which case
it's just one more file being autoconverted. IIRC the hitch
I ran into was that you need to determine whether the reset
function is called by any other code -- those are probably
not autoconvertible in the way "function only used as the
argument to device_class_legacy_reset()" could be.)
thanks
-- PMM
^ permalink raw reply [flat|nested] 68+ messages in thread
* Re: [PULL 39/63] hw/display: Add i.MX6UL LCDIF device model
2026-05-20 16:45 ` Peter Maydell
@ 2026-05-20 17:14 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 68+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-05-20 17:14 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Yucai Liu
On 20/5/26 18:45, Peter Maydell wrote:
> On Wed, 20 May 2026 at 17:33, Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
>>
>> Hi Yucai,
>>
>> On 27/4/26 14:47, Peter Maydell wrote:
>>> +static void imx6ul_lcdif_class_init(ObjectClass *klass, const void *data)
>>> +{
>>> + DeviceClass *dc = DEVICE_CLASS(klass);
>>> +
>>> + dc->realize = imx6ul_lcdif_realize;
>>> + dc->unrealize = imx6ul_lcdif_unrealize;
>>> + dc->vmsd = &vmstate_imx6ul_lcdif;
>>> + device_class_set_legacy_reset(dc, imx6ul_lcdif_reset);
>>
>> Please do not use the legacy API. See for example this commit
>> to convert to the newer API:
>> https://gitlab.com/qemu-project/qemu/-/commit/ce788d3740f
>
> There's not really a problem with continuing to use the legacy
> reset API for this kind of "leaf class" device. It has identical
> semantics to just providing a 3-phase "hold" reset method, the
> compatibility-code is trivial and not a big maintenance burden,
> and we're unlikely to convert all 400+ existing users. (Unless
> somebody figures out a Coccinelle script for it, in which case
> it's just one more file being autoconverted. IIRC the hitch
> I ran into was that you need to determine whether the reset
> function is called by any other code -- those are probably
> not autoconvertible in the way "function only used as the
> argument to device_class_legacy_reset()" could be.)
Then I don't understand why we named it "legacy". Maybe rename
as device_class_set_leaf_reset()...
This is not about converting the 400 uses; I'd expect a legacy
API to not be re-introduced over and over.
What about gating this call via checkpatch.pl?
^ permalink raw reply [flat|nested] 68+ messages in thread
end of thread, other threads:[~2026-05-20 17:15 UTC | newest]
Thread overview: 68+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-27 12:46 [PULL 00/63] target-arm queue Peter Maydell
2026-04-27 12:46 ` [PULL 01/63] docs/system: add FEAT_AA32 and FEAT_AA64 to emulation list Peter Maydell
2026-04-27 12:46 ` [PULL 02/63] hw/arm: Add the i.MX 8MM EVK(Evaluation Kit) board Peter Maydell
2026-04-27 12:46 ` [PULL 03/63] hw/misc/imx8mp_analog: Add property to analog device Peter Maydell
2026-04-27 12:46 ` [PULL 04/63] hw/arm/fsl-imx8mm: Add Analog device IP to iMX8MM SOC Peter Maydell
2026-04-27 12:46 ` [PULL 05/63] hw/arm/fsl-imx8mm: Add Clock Control Module IP to iMX8MM Peter Maydell
2026-04-27 12:46 ` [PULL 06/63] hw/arm/fsl-imx8mm: Implemented support for SNVS Peter Maydell
2026-04-27 12:46 ` [PULL 07/63] hw/arm/fsl-imx8mm: Adding support for USDHC storage controllers Peter Maydell
2026-04-27 12:46 ` [PULL 08/63] hw/arm/fsl-imx8mm: Add PCIe support Peter Maydell
2026-04-27 12:46 ` [PULL 09/63] hw/arm/fsl-imx8mm: Add GPIO controllers Peter Maydell
2026-04-27 12:46 ` [PULL 10/63] hw/arm/fsl-imx8mm: Adding support for I2C emulation Peter Maydell
2026-04-27 12:46 ` [PULL 11/63] hw/arm/fsl-imx8mm: Adding support for SPI controller Peter Maydell
2026-04-27 12:46 ` [PULL 12/63] hw/arm/fsl-imx8mm: Adding support for Watchdog Timers Peter Maydell
2026-04-27 12:46 ` [PULL 13/63] hw/arm/fsl-imx8mm: Adding support for General Purpose Timers Peter Maydell
2026-04-27 12:46 ` [PULL 14/63] hw/arm/fsl-imx8mm: Adding support for ENET ethernet controller Peter Maydell
2026-04-27 12:46 ` [PULL 15/63] hw/arm/fsl-imx8mm: Adding support for USB controller Peter Maydell
2026-04-27 12:46 ` [PULL 16/63] hw/arm/fsl-imx8mm: Adding functional testing of iMX8MM emulation Peter Maydell
2026-04-27 12:46 ` [PULL 17/63] target/arm: Ignore endianness when setting MTE tags Peter Maydell
2026-04-27 12:46 ` [PULL 18/63] target/arm: Explode MO_TExx -> MO_TE | MO_xx Peter Maydell
2026-04-27 12:46 ` [PULL 19/63] target/arm: Hoist MO_TE into mve_advance_vpt() Peter Maydell
2026-04-27 12:46 ` [PULL 20/63] target/arm: Hoist MO_TE into MVE DO_VSTR() macro Peter Maydell
2026-04-27 12:46 ` [PULL 21/63] target/arm: Introduce mo_endian() helper Peter Maydell
2026-04-27 12:46 ` [PULL 22/63] target/arm: Replace MO_TE -> mo_endian() for MVE helpers Peter Maydell
2026-04-27 12:46 ` [PULL 23/63] target/arm: Compile mve_helper.c once Peter Maydell
2026-04-27 12:46 ` [PULL 24/63] target/arm: Replace MO_TE -> mo_endian() for Cortex-M helpers Peter Maydell
2026-04-27 12:46 ` [PULL 25/63] target/arm: Compile m_helper.c once Peter Maydell
2026-04-27 12:47 ` [PULL 26/63] hw/arm: Remove hw_error() for the unimplemented CM_LMBUSCNT register Peter Maydell
2026-04-27 12:47 ` [PULL 27/63] hw: Move ARM_SYSCTL_GPIO definitions to arm sysctl specific header Peter Maydell
2026-04-27 12:47 ` [PULL 28/63] target/arm: Clear AArch64 ID regs from ARMISARegisters if AArch64 disabled Peter Maydell
2026-04-27 12:47 ` [PULL 29/63] target/arm: Allow 'aarch64=off' to be set for TCG CPUs Peter Maydell
2026-04-27 12:47 ` [PULL 30/63] tests/functional/aarch64: Add basic test of TCG aarch64=off Peter Maydell
2026-04-27 12:47 ` [PULL 31/63] target/arm/cpu: Introduce the infrastructure for cpreg migration tolerances Peter Maydell
2026-04-27 12:47 ` [PULL 32/63] target/arm/machine: Handle ToleranceNotOnBothEnds " Peter Maydell
2026-04-27 12:47 ` [PULL 33/63] target/arm/machine: Handle ToleranceOnlySrcTestValue migration tolerance Peter Maydell
2026-04-27 12:47 ` [PULL 34/63] target/arm/cpu64: Mitigate migration failures due to spurious TCR_EL1, PIRE0_EL1 and PIR_EL1 Peter Maydell
2026-04-27 12:47 ` [PULL 35/63] target/arm/cpu64: Define cpreg migration tolerance for KVM_REG_ARM_VENDOR_HYP_BMAP_2 Peter Maydell
2026-04-27 12:47 ` [PULL 36/63] target/arm/helper: Define cpreg migration tolerance for DGBDTR_EL0 Peter Maydell
2026-04-27 12:47 ` [PULL 37/63] Revert "target/arm: Reinstate bogus AArch32 DBGDTRTX register for migration compat" Peter Maydell
2026-04-27 12:47 ` [PULL 38/63] hw/arm/raspi4b: NOP all DTB nodes when removing unimplemented devices Peter Maydell
2026-04-27 12:47 ` [PULL 39/63] hw/display: Add i.MX6UL LCDIF device model Peter Maydell
2026-05-20 16:33 ` Philippe Mathieu-Daudé
2026-05-20 16:45 ` Peter Maydell
2026-05-20 17:14 ` Philippe Mathieu-Daudé
2026-04-27 12:47 ` [PULL 40/63] hw/arm/fsl-imx6ul: Wire in the " Peter Maydell
2026-04-27 12:47 ` [PULL 41/63] target/arm: migrate basic syndrome helpers to registerfields Peter Maydell
2026-04-27 12:47 ` [PULL 42/63] target/arm: migrate system/cp trap syndromes " Peter Maydell
2026-04-27 12:47 ` [PULL 43/63] target/arm: migrate FP/SIMD " Peter Maydell
2026-04-27 12:47 ` [PULL 44/63] target/arm: migrate eret " Peter Maydell
2026-04-27 12:47 ` [PULL 45/63] target/arm: migrate SME " Peter Maydell
2026-04-27 12:47 ` [PULL 46/63] target/arm: migrate PAC " Peter Maydell
2026-04-27 12:47 ` [PULL 47/63] target/arm: migrate BTI " Peter Maydell
2026-04-27 12:47 ` [PULL 48/63] target/arm: migrate BXJ " Peter Maydell
2026-04-27 12:47 ` [PULL 49/63] target/arm: migrate Granule Protection traps " Peter Maydell
2026-04-27 12:47 ` [PULL 50/63] target/arm: migrate fault syndromes " Peter Maydell
2026-04-27 12:47 ` [PULL 51/63] target/arm: migrate debug " Peter Maydell
2026-04-27 12:47 ` [PULL 52/63] target/arm: migrate wfx " Peter Maydell
2026-04-27 12:47 ` [PULL 53/63] target/arm: migrate gcs " Peter Maydell
2026-04-27 12:47 ` [PULL 54/63] target/arm: migrate memory op " Peter Maydell
2026-04-27 12:47 ` [PULL 55/63] target/arm: migrate check_hcr_el2_trap to use syndrome helper Peter Maydell
2026-04-27 12:47 ` [PULL 56/63] target/arm: use syndrome helpers in arm_cpu_do_interrupt_aarch32_hyp Peter Maydell
2026-04-27 12:47 ` [PULL 57/63] target/arm: use syndrome helpers to set SAME_EL EC bit Peter Maydell
2026-04-27 12:47 ` [PULL 58/63] target/arm: make whpx use syndrome helpers for decode Peter Maydell
2026-04-27 12:47 ` [PULL 59/63] target/arm: make hvf " Peter Maydell
2026-04-27 12:47 ` [PULL 60/63] target/arm: use syndrome helpers in merge_syn_data_abort Peter Maydell
2026-04-27 12:47 ` [PULL 61/63] target/arm: use syndrome helpers to query VNCR bit Peter Maydell
2026-04-27 12:47 ` [PULL 62/63] target/arm: remove old syndrome defines Peter Maydell
2026-04-27 12:47 ` [PULL 63/63] target/arm: report register in WFIT syndromes Peter Maydell
2026-04-28 12:02 ` [PULL 00/63] target-arm queue Stefan Hajnoczi
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.