This series adds a QEMU machine for the NXP i.MX 95 19x19 LPDDR5 EVK
(machine name "imx95-19x19-evk"). The i.MX 95 is a heterogeneous SoC;
the machine models a fixed topology of 6 Cortex-A55 application cores,
one Cortex-M33 that runs NXP's System Manager (SM) firmware, and one
Cortex-M7 real-time core that the SM boots and manages.
What it does
============
It boots an arm64 Linux kernel to a userspace shell on the A55 cluster
(both a mainline arm64-defconfig kernel and the NXP BSP kernel work).
The defining property of this SoC -- and the reason the machine is
shaped the way it is -- is that the System Manager firmware, running on
the M33, is the *only* SCMI provider. Linux's clock, power,
performance-domain, sensor and reset operations are all served by the SM
over a shared mailbox (MU2); there is no SCMI implementation inside QEMU.
The machine models the mailbox cross-connect and the SM's bring-up
peripherals (LPUART, MU, System Counter, ANATOP/SRC/GPC, ELE, LPI2C +
PMIC, uSDHC, ...) faithfully enough that the *real, unmodified* SM
firmware runs on the emulated M33 and answers Linux's SCMI traffic.
A consequence worth stating plainly up front: booting Linux on this
machine requires the SM firmware image as an input, loaded onto the M33
with "-device loader,file=m33_image.elf,cpu-num=6". Without it the M33
stays halted, nothing answers SCMI, and Linux hangs at arm-scmi probe.
The SM is open source (https://github.com/nxp-imx/imx-sm) and builds
with an arm-none-eabi toolchain; docs/system/arm/imx95-evk.rst walks
through obtaining every required artifact.
Scope (headless v1)
===================
This is a deliberately minimal first machine: it boots to a serial
console. It is headless -- the DPU (display controller) is a
probe-completing stub, and the GPU (Mali-G310), VPU (Amphion) and NPU
(Neutron) are MMIO stubs that Linux enumerates but that perform no
rendering, codec or inference. Real display + Wayland output, the NETC
networking complex, and the multimedia blocks are intended as follow-on
series on top of this base.
The blocks that are modelled are exactly those on the Linux+SM bring-up
critical path; everything else that the stock EVK device tree probes is
a logging stub so that enabling those nodes degrades gracefully rather
than faulting on the first access.
How to test
===========
$ qemu-system-aarch64 -M imx95-19x19-evk -m 2G -display none \
-kernel Image -dtb imx95-19x19-evk.dtb -initrd initramfs.cpio.gz \
-device loader,file=m33_image.elf,cpu-num=6 \
-append "earlycon=lpuart32,mmio32,0x44380010 console=ttyLP0,115200 \
cpuidle.off=1" -serial mon:stdio
A functional test is included (tests/functional/aarch64/test_imx95_evk.py).
Because the SM firmware and a matching kernel/dtb are external inputs
that are not redistributable, the test is gated on QEMU_TEST_IMX95_*
environment variables and skips cleanly when they are unset -- so it
will SKIP in upstream CI as posted. I would appreciate guidance on the
preferred convention here: I am happy to host a redistributable
kernel+dtb (and exercise the SM path separately) as an Asset() so CI
actually runs the machine, if that is wanted.
Prerequisites (patches 01-04)
=============================
The first four patches are generic, non-i.MX95 changes that the machine
depends on. They are separate commits so they can be reviewed (and
taken) on their own merits:
01 hw/sd/sdhci: two opt-in uSDHC quirk bits (SDCLK_AUTO_GATE,
NO_SDMA_BOUNDARY). The i.MX (u)SDHC issues commands with SDCLK
auto-gated and its SDMA does not honour the 512 KiB ADMA boundary
the generic core assumes.
02 hw/arm/boot: let a board preset info->initrd_start, so a board
with a reserved-memory carveout can keep the initrd clear of it.
03 target/arm: an opt-in "pmsav7-rbar-align-down" CPU property that
aligns down a PMSAv7 MPU region base not aligned to its size,
instead of the architectural UNPREDICTABLE drop. An earlier version
of this fix changed that behaviour unconditionally and was rightly
not taken; this reworks it as a property that defaults to false (so
no existing behaviour changes) and is only registered on PMSAv7
(v7-M / v7-R) CPUs. The NXP i.MX 95 Cortex-M7 SDK firmware relies on
the align-down for one of its MPU regions.
04 hw/arm/armv7m: forward that property to the CPU object, following
the existing init-svtor / vfp / dsp forwarding, so an SoC can enable
it on an affected core. (The i.MX 95 SoC enables it on the M7 only;
the M33 is a v8-M / PMSAv8 core and needs no such quirk.)
Series layout
=============
01-04 generic prerequisites (above)
05 hw/char: i.MX LPUART
06 hw/i2c: i.MX LPI2C
07 hw/misc: i.MX Messaging Unit (MU v2)
08 hw/misc: NXP EdgeLock Enclave (ELE) responder
09 hw/timer: i.MX 95 system counter
10 hw/misc: i.MX 95 watchdog
11 hw/misc: ANATOP/AONMIX/GPC/SRC power & clock blocks
12 hw/misc: PMIC (PF09/PF53/PCAL6408A) + xcache
13 hw/misc: DPU command-sequencer stub (headless)
14 hw/arm: i.MX 95 SoC container (fsl-imx95)
15 hw/arm: i.MX 95 19x19 EVK board
16 docs, MAINTAINERS, tests/functional
Every patch builds on its own (the series is bisectable), device state
carries migration vmsd + reset, and checkpatch is clean.
46 files changed, 6529 insertions(+), 13 deletions(-)
Thanks for reviewing.
Kyle Fox (16):
hw/sd/sdhci: add i.MX uSDHC SDCLK_AUTO_GATE and NO_SDMA_BOUNDARY
quirks
hw/arm/boot: let a board preset initrd_start
target/arm: opt-in align-down for a misaligned PMSAv7 MPU RBAR
hw/arm/armv7m: forward pmsav7-rbar-align-down to the CPU
hw/char: add i.MX LPUART
hw/i2c: add i.MX LPI2C
hw/misc: add i.MX Messaging Unit (MU v2)
hw/misc: add NXP EdgeLock Enclave (ELE) responder
hw/timer: add i.MX 95 system counter
hw/misc: add i.MX 95 watchdog
hw/misc: add i.MX 95 ANATOP/AONMIX/GPC/SRC power and clock blocks
hw/misc: add i.MX 95 PMIC (PF09/PF53/PCAL6408A) and xcache controllers
hw/misc: add i.MX 95 DPU command-sequencer stub (headless)
hw/arm: add i.MX 95 SoC container (fsl-imx95)
hw/arm: add i.MX 95 19x19 EVK board
docs, MAINTAINERS, tests/functional: add i.MX 95 EVK
MAINTAINERS | 18 +
docs/system/arm/imx95-evk.rst | 242 +++
docs/system/target-arm.rst | 1 +
hw/arm/Kconfig | 26 +
hw/arm/armv7m.c | 8 +
hw/arm/boot.c | 12 +-
hw/arm/fsl-imx95.c | 1646 ++++++++++++++++++++
hw/arm/imx95-evk.c | 136 ++
hw/arm/meson.build | 2 +
hw/char/Kconfig | 3 +
hw/char/imx_lpuart.c | 382 +++++
hw/char/meson.build | 1 +
hw/char/trace-events | 3 +
hw/i2c/Kconfig | 4 +
hw/i2c/imx_lpi2c.c | 296 ++++
hw/i2c/meson.build | 1 +
hw/i2c/trace-events | 4 +
hw/misc/Kconfig | 32 +
hw/misc/imx95_anatop.c | 201 +++
hw/misc/imx95_aonmix.c | 160 ++
hw/misc/imx95_dpu.c | 117 ++
hw/misc/imx95_ele_server.c | 284 ++++
hw/misc/imx95_gpc.c | 160 ++
hw/misc/imx95_pmic.c | 357 +++++
hw/misc/imx95_src.c | 228 +++
hw/misc/imx95_wdog.c | 198 +++
hw/misc/imx95_xcache.c | 185 +++
hw/misc/imx_mu.c | 454 ++++++
hw/misc/meson.build | 10 +
hw/misc/trace-events | 25 +
hw/sd/sdhci.c | 67 +-
hw/timer/Kconfig | 3 +
hw/timer/imx95_sysctr.c | 241 +++
hw/timer/meson.build | 1 +
hw/timer/trace-events | 2 +
include/hw/arm/armv7m.h | 4 +
include/hw/arm/fsl-imx95.h | 481 ++++++
include/hw/char/imx_lpuart.h | 123 ++
include/hw/misc/imx95_ele_server.h | 47 +
include/hw/misc/imx_mu.h | 144 ++
include/hw/sd/sdhci.h | 21 +
target/arm/cpu.c | 19 +
target/arm/cpu.h | 6 +
target/arm/ptw.c | 28 +-
tests/functional/aarch64/meson.build | 2 +
tests/functional/aarch64/test_imx95_evk.py | 157 ++
46 files changed, 6529 insertions(+), 13 deletions(-)
create mode 100644 docs/system/arm/imx95-evk.rst
create mode 100644 hw/arm/fsl-imx95.c
create mode 100644 hw/arm/imx95-evk.c
create mode 100644 hw/char/imx_lpuart.c
create mode 100644 hw/i2c/imx_lpi2c.c
create mode 100644 hw/misc/imx95_anatop.c
create mode 100644 hw/misc/imx95_aonmix.c
create mode 100644 hw/misc/imx95_dpu.c
create mode 100644 hw/misc/imx95_ele_server.c
create mode 100644 hw/misc/imx95_gpc.c
create mode 100644 hw/misc/imx95_pmic.c
create mode 100644 hw/misc/imx95_src.c
create mode 100644 hw/misc/imx95_wdog.c
create mode 100644 hw/misc/imx95_xcache.c
create mode 100644 hw/misc/imx_mu.c
create mode 100644 hw/timer/imx95_sysctr.c
create mode 100644 include/hw/arm/fsl-imx95.h
create mode 100644 include/hw/char/imx_lpuart.h
create mode 100644 include/hw/misc/imx95_ele_server.h
create mode 100644 include/hw/misc/imx_mu.h
create mode 100644 tests/functional/aarch64/test_imx95_evk.py
base-commit: ae4f3443209ab154b48b706a146e5f557ab147cb
--
2.34.1