Skip to contentSkip to conversation

hw/arm: Adding Cortex-M7 Asymmetric Multiprocessing boot support for i.MX8MP

PATCH In review Gaurav Sharma 2 participants 16 messages Oct 7 – Nov 11

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

v4 cover hw/arm: Adding Cortex-M7 Asymmetric Multiprocessing boot support for i.MX8MP

Changes in v1:

This series adds Asymmetric Multiprocessing (AMP) boot support for the Cortex-M7 core on the i.MX8MP SoC. The M7 firmware can be loaded and started from Linux running on the Cortex-A53 cores via the remoteproc framework.

The series introduces the following peripheral models needed for AMP:
- GPC (General Power Controller)
- GPR (General Purpose Registers)
- SRC (System Reset Controller) authored by Bernhard Beschow <[email protected]>
- MU (Messaging Unit)
- Extends the CCM with M7 clock outputs and wires into the i.MX8MP SoC
- Enable Cortex-M7 boot in i.MX8MP EVK functional test

Changes in v2:

- Removed the usage of device_class_set_legacy_reset in imx8mp gpc,gpr,mu and src.
- Removed the usage of 'smp' , 'maxcpus' and 'enable-cm7' to make the invocation simpler.
- Cleaned up imx8mp_src by removing redundant/unused code.
- Updated Maintainers and improved the imx8mp documentation

Changes in v3:

- Added a new patch for smp removal from test_imx8mp_evk.py.
- Added a new patch to introduce IRQ splitting for i.MX8MP AMP interrupt routing.
- Added a new patch to rename FSL_IMX8MP_NUM_CPUS to FSL_IMX8MP_NUM_A53, since M7 is being introduced now.
- In GPR, parent_phases moved from global variable to class struct
- M7 reset handling moved from the machine to SRC device model.
- Added ITCM and DTCM memory regions to support zephyr firmware loading.

Changes in v4:

- Move independent MAINTAINERS, CPU renaming and functional-test cleanups to the beginning of the series
- Created a separate patch for ITCM and DTCM modeling.
- Move IRQ splitter infrastructure before Cortex-M7 integration

Gaurav Sharma (11):
MAINTAINERS: Merge MCIMX8MM-EVK and MCIMX8MP-EVK entries hw/arm: Rename FSL_IMX8MP_NUM_CPUS to FSL_IMX8MP_NUM_A53 tests/functional: Fix i.MX8MP EVK SMP configuration hw/misc: Add i.MX8MP GPC (General Power Controller) IP hw/misc: Add GPR (General Purpose Register) IP to iMX8MP hw/misc: Add SRC (System Reset Controller) to i.MX8MP hw/misc: Add MU (Messaging Unit) IP to i.MX8MP device model hw/misc: Extend i.MX8MP CCM with Cortex-M7 clock outputs hw/arm: Add ITCM and DTCM memory regions to i.MX8MP hw/arm: Add IRQ splitter for i.MX8MP AMP interrupt routing hw/arm: Enable Cortex-M7 AMP boot on i.MX8MP

 MAINTAINERS                                 |  13 +-
 docs/system/arm/imx8m.rst                   | 186 +++++++++
 hw/arm/Kconfig                              |   4 +
 hw/arm/fsl-imx8mp.c                         | 229 +++++++++--
 hw/arm/imx8mp-evk.c                         |   5 +-
 hw/misc/Kconfig                             |  12 +
 hw/misc/imx8mp_ccm.c                        |   9 +
 hw/misc/imx8mp_gpc.c                        | 146 +++++++
 hw/misc/imx8mp_gpr.c                        | 155 ++++++++
 hw/misc/imx8mp_mu.c                         | 346 +++++++++++++++++
 hw/misc/imx8mp_src.c                        | 397 ++++++++++++++++++++
 hw/misc/meson.build                         |   4 +
 hw/misc/trace-events                        |   5 +
 include/hw/arm/fsl-imx8mp.h                 |  32 +-
 include/hw/misc/imx8mp_ccm.h                |   3 +
 include/hw/misc/imx8mp_gpc.h                |  34 ++
 include/hw/misc/imx8mp_gpr.h                |  62 +++
 include/hw/misc/imx8mp_mu.h                 |  53 +++
 include/hw/misc/imx8mp_src.h                |  47 +++
 tests/functional/aarch64/test_imx8mp_evk.py |   1 -
 20 files changed, 1696 insertions(+), 47 deletions(-)
 create mode 100644 hw/misc/imx8mp_gpc.c
 create mode 100644 hw/misc/imx8mp_gpr.c
 create mode 100644 hw/misc/imx8mp_mu.c
 create mode 100644 hw/misc/imx8mp_src.c
 create mode 100644 include/hw/misc/imx8mp_gpc.h
 create mode 100644 include/hw/misc/imx8mp_gpr.h
 create mode 100644 include/hw/misc/imx8mp_mu.h
 create mode 100644 include/hw/misc/imx8mp_src.h
Signature · 1 line
2.34.1
#1 lore raw

PATCH v4 1/11 MAINTAINERS: Merge MCIMX8MM-EVK and MCIMX8MP-EVK entries

Merge the separate MCIMX8MM-EVK and MCIMX8MP-EVK MAINTAINERS entries into a single combined entry covering both SoC families.

---
 MAINTAINERS | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)
MAINTAINERS +4 -9
index 6be9c5725b..7120784ec7 100644
@@ -933,29 +933,24 @@ F: hw/pci-host/designware.c
 F: include/hw/pci-host/designware.h
 F: docs/system/arm/mcimx7d-sabre.rst
 
-MCIMX8MM-EVK / iMX8MM
+MCIMX8MP-EVK / MCIMX8MM-EVK
+M: Bernhard Beschow <[email protected]>
 M: Gaurav Sharma <[email protected]>
 L: [email protected]
 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
-F: tests/functional/aarch64/test_imx8mm_evk.py
-
-MCIMX8MP-EVK / i.MX8MP
-M: Bernhard Beschow <[email protected]>
-L: [email protected]
-S: Maintained
 F: hw/arm/imx8mp-evk.c
 F: hw/arm/fsl-imx8mp.c
 F: hw/misc/imx8mp_*.c
 F: hw/pci-host/fsl_imx8m_phy.c
 F: hw/rtc/rs5c372.c
+F: include/hw/arm/fsl-imx8mm.h
 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/imx8m.rst
+F: tests/functional/aarch64/test_imx8mm_evk.py
 F: tests/functional/aarch64/test_imx8mp_evk.py
 F: tests/qtest/rs5c372-test.c
 
Signature · 1 line
2.34.1
#2 lore raw

PATCH v4 2/11 hw/arm: Rename FSL_IMX8MP_NUM_CPUS to FSL_IMX8MP_NUM_A53

In reply to Gaurav Sharma

This is a mechanical rename with no functional change. The existing CPU count and cpu array describe only the Cortex-A53 cores.

---
 hw/arm/fsl-imx8mp.c         | 4 ++--
 hw/arm/imx8mp-evk.c         | 2 +-
 include/hw/arm/fsl-imx8mp.h | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)
hw/arm/fsl-imx8mp.c +2 -2
index bcd91739d9..f599e5e0a2 100644
@@ -266,9 +266,9 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
     const char *cpu_type = ms->cpu_type ?: ARM_CPU_TYPE_NAME("cortex-a53");
     int i;
 
-    if (ms->smp.cpus > FSL_IMX8MP_NUM_CPUS) {
+    if (ms->smp.cpus > FSL_IMX8MP_NUM_A53) {
         error_setg(errp, "%s: Only %d CPUs are supported (%d requested)",
-                   TYPE_FSL_IMX8MP, FSL_IMX8MP_NUM_CPUS, ms->smp.cpus);
+                   TYPE_FSL_IMX8MP, FSL_IMX8MP_NUM_A53, ms->smp.cpus);
         return;
     }
 
hw/arm/imx8mp-evk.c +1 -1
index 3f376f86d9..f19d80b796 100644
@@ -148,7 +148,7 @@ static void imx8mp_evk_machine_class_init(ObjectClass *oc, const void *data)
     mc->desc = "NXP i.MX 8M Plus EVK Board";
     mc->init = imx8mp_evk_init;
     mc->default_cpus = 4;
-    mc->max_cpus = FSL_IMX8MP_NUM_CPUS;
+    mc->max_cpus = FSL_IMX8MP_NUM_A53;
     mc->default_ram_id = "imx8mp-evk.ram";
     mc->default_ram_size = 6 * GiB;
     mc->get_default_cpu_type = imx8mp_evk_get_default_cpu_type;
include/hw/arm/fsl-imx8mp.h +2 -2
index 2be3c51af5..6f9bd8d2ce 100644
@@ -39,7 +39,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mpState, FSL_IMX8MP)
 
 enum FslImx8mpConfiguration {
     FSL_IMX8MP_NUM_CANS         = 2,
-    FSL_IMX8MP_NUM_CPUS         = 4,
+    FSL_IMX8MP_NUM_A53          = 4,
     FSL_IMX8MP_NUM_ECSPIS       = 3,
     FSL_IMX8MP_NUM_GPIOS        = 5,
     FSL_IMX8MP_NUM_GPTS         = 6,
@@ -54,7 +54,7 @@ enum FslImx8mpConfiguration {
 struct FslImx8mpState {
     SysBusDevice   parent_obj;
 
-    ARMCPU             cpu[FSL_IMX8MP_NUM_CPUS];
+    ARMCPU             cpu[FSL_IMX8MP_NUM_A53];
     GICv3State         gic;
     IMXGPTState        gpt[FSL_IMX8MP_NUM_GPTS];
     IMXGPIOState       gpio[FSL_IMX8MP_NUM_GPIOS];
Signature · 1 line
2.34.1
Reviewed-by on v4 2/11
#3 lore raw

Re: [PATCHv4 02/11] hw/arm: Rename FSL_IMX8MP_NUM_CPUS to FSL_IMX8MP_NUM_A53

Am 7. Oktober 2026 10:10:56 UTC schrieb Gaurav Sharma <[email protected]>:

Quoted 54 lines

This is a mechanical rename with no functional change. The existing CPU count and cpu array describe only the Cortex-A53 cores.

---

hw/arm/fsl-imx8mp.c         | 4 ++--
hw/arm/imx8mp-evk.c         | 2 +-
include/hw/arm/fsl-imx8mp.h | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
hw/arm/fsl-imx8mp.c +2 -2
index bcd91739d9..f599e5e0a2 100644
@@ -266,9 +266,9 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
    const char *cpu_type = ms->cpu_type ?: ARM_CPU_TYPE_NAME("cortex-a53");
    int i;
 
-    if (ms->smp.cpus > FSL_IMX8MP_NUM_CPUS) {
+    if (ms->smp.cpus > FSL_IMX8MP_NUM_A53) {
        error_setg(errp, "%s: Only %d CPUs are supported (%d requested)",
-                   TYPE_FSL_IMX8MP, FSL_IMX8MP_NUM_CPUS, ms->smp.cpus);
+                   TYPE_FSL_IMX8MP, FSL_IMX8MP_NUM_A53, ms->smp.cpus);
        return;
    }
 
hw/arm/imx8mp-evk.c +1 -1
index 3f376f86d9..f19d80b796 100644
@@ -148,7 +148,7 @@ static void imx8mp_evk_machine_class_init(ObjectClass *oc, const void *data)
    mc->desc = "NXP i.MX 8M Plus EVK Board";
    mc->init = imx8mp_evk_init;
    mc->default_cpus = 4;
-    mc->max_cpus = FSL_IMX8MP_NUM_CPUS;
+    mc->max_cpus = FSL_IMX8MP_NUM_A53;
    mc->default_ram_id = "imx8mp-evk.ram";
    mc->default_ram_size = 6 * GiB;
    mc->get_default_cpu_type = imx8mp_evk_get_default_cpu_type;
include/hw/arm/fsl-imx8mp.h +1 -1
index 2be3c51af5..6f9bd8d2ce 100644
@@ -39,7 +39,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mpState, FSL_IMX8MP)
 
 enum FslImx8mpConfiguration {
    FSL_IMX8MP_NUM_CANS         = 2,
-    FSL_IMX8MP_NUM_CPUS         = 4,
+    FSL_IMX8MP_NUM_A53          = 4,
    FSL_IMX8MP_NUM_ECSPIS       = 3,
    FSL_IMX8MP_NUM_GPIOS        = 5,
    FSL_IMX8MP_NUM_GPTS         = 6,

include/hw/arm/fsl-imx8mp.h enum FslImx8mpConfiguration { · line 60

Quoted 8 lines
include/hw/arm/fsl-imx8mp.h +1 -1
@@ -54,7 +54,7 @@ enum FslImx8mpConfiguration {
 struct FslImx8mpState {
    SysBusDevice   parent_obj;
 
-    ARMCPU             cpu[FSL_IMX8MP_NUM_CPUS];
+    ARMCPU             cpu[FSL_IMX8MP_NUM_A53];
    GICv3State         gic;
    IMXGPTState        gpt[FSL_IMX8MP_NUM_GPTS];
    IMXGPIOState       gpio[FSL_IMX8MP_NUM_GPIOS];
#4 lore raw

PATCH v4 3/11 tests/functional: Fix i.MX8MP EVK SMP configuration

In reply to Gaurav Sharma

Remove the explicit '-smp 4' argument from the functional test. The SMP CPU count is now fixed internally via mc->default_cpus and no longer needs to be specified by the caller.

---
 tests/functional/aarch64/test_imx8mp_evk.py | 1 -
 1 file changed, 1 deletion(-)
tests/functional/aarch64/test_imx8mp_evk.py +0 -1
index 99ddcdef83..6046c573d5 100755
@@ -53,7 +53,6 @@ def test_aarch64_imx8mp_evk_usdhc(self):
         self.set_machine('imx8mp-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,
Signature · 1 line
2.34.1
#5 lore raw

Re: [PATCHv4 03/11] tests/functional: Fix i.MX8MP EVK SMP configuration

Am 7. Oktober 2026 10:10:57 UTC schrieb Gaurav Sharma <[email protected]>:

Quoted 14 lines

Remove the explicit '-smp 4' argument from the functional test. The SMP CPU count is now fixed internally via mc->default_cpus and no longer needs to be specified by the caller.

---
tests/functional/aarch64/test_imx8mp_evk.py | 1 -

1 file changed, 1 deletion(-)
tests/functional/aarch64/test_imx8mp_evk.py +0 -0
index 99ddcdef83..6046c573d5 100755

tests/functional/aarch64/test_imx8mp_evk.py def test_aarch64_imx8mp_evk_usdhc(self): · line 56

Quoted 4 lines
tests/functional/aarch64/test_imx8mp_evk.py +0 -1
@@ -53,7 +53,6 @@ def test_aarch64_imx8mp_evk_usdhc(self):
        self.set_machine('imx8mp-evk')
        self.vm.set_console(console_index=1)
        self.vm.add_args('-m', '2G',
-                         '-smp', '4',

The -m and -smp parameters are both removed in current master. However, this patch is not obsolete: It should contain the smp hardcoding to 4 which is still mixed into patch "[PATCHv4 11/11] hw/arm: Enable Cortex-M7 AMP boot on i.MX8MP".

Best regards,
Bernhard

Quoted 3 lines
tests/functional/aarch64/test_imx8mp_evk.py +0 -0
                         '-kernel', self.kernel_path,
                         '-initrd', self.initrd_path,
                         '-dtb', self.dtb_path,
#6 lore raw

PATCH v4 4/11 hw/misc: Add i.MX8MP GPC (General Power Controller) IP

In reply to Gaurav Sharma

Add a minimal emulation of the i.MX8MP General Power Controller
and wire it into the i.MX8MP SoC model.
The GPC manages power domains and clock-gating behavior for cores on the i.MX8MP SoC. This is needed to support AMP boot of the Cortex-M7 core from Linux.

---
 docs/system/arm/imx8m.rst    |   1 +
 hw/arm/Kconfig               |   1 +
 hw/arm/fsl-imx8mp.c          |  10 +++
 hw/misc/Kconfig              |   3 +
 hw/misc/imx8mp_gpc.c         | 146 +++++++++++++++++++++++++++++++++++
 hw/misc/meson.build          |   1 +
 include/hw/arm/fsl-imx8mp.h  |   2 +
 include/hw/misc/imx8mp_gpc.h |  34 ++++++++
 8 files changed, 198 insertions(+)
 create mode 100644 hw/misc/imx8mp_gpc.c
 create mode 100644 include/hw/misc/imx8mp_gpc.h
docs/system/arm/imx8m.rst +1 -0
index 1bcb8255be..e9e970ce64 100644
@@ -26,6 +26,7 @@ following devices:
  * 6 General Purpose Timers
  * Secure Non-Volatile Storage (SNVS) including an RTC
  * Clock Tree
+ * General Power Controller (GPC)
 
 Boot options
 ------------
hw/arm/Kconfig +1 -0
index eae06369b0..17450256db 100644
@@ -594,6 +594,7 @@ config FSL_IMX8MP
     select CAN_FLEXCAN
     select FSL_IMX8MP_ANALOG
     select FSL_IMX8MP_CCM
+    select FSL_IMX8MP_GPC
     select IMX
     select IMX_FEC
     select IMX_I2C
hw/arm/fsl-imx8mp.c +10 -0
index f599e5e0a2..cc5f7080c2 100644
@@ -204,6 +204,8 @@ static void fsl_imx8mp_init(Object *obj)
 
     object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
 
+    object_initialize_child(obj, "gpc", &s->gpc, TYPE_IMX8MP_GPC);
+
     for (i = 0; i < FSL_IMX8MP_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);
@@ -427,6 +429,13 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
                            qdev_get_gpio_in(gicdev, serial_table[i].irq));
     }
 
+    /* GPC */
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpc), errp)) {
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpc), 0,
+                    fsl_imx8mp_memmap[FSL_IMX8MP_GPC].addr);
+
     /* GPTs */
     object_property_set_int(OBJECT(&s->gpt5_gpt6_irq), "num-lines", 2,
                             &error_abort);
@@ -720,6 +729,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
         case FSL_IMX8MP_FLEXCAN1 ... FSL_IMX8MP_FLEXCAN2:
         case FSL_IMX8MP_GIC_DIST:
         case FSL_IMX8MP_GIC_REDIST:
+        case FSL_IMX8MP_GPC:
         case FSL_IMX8MP_GPIO1 ... FSL_IMX8MP_GPIO5:
         case FSL_IMX8MP_GPT1 ... FSL_IMX8MP_GPT6:
         case FSL_IMX8MP_ECSPI1 ... FSL_IMX8MP_ECSPI3:
hw/misc/Kconfig +3 -0
index 46e3c03cc8..c17275441c 100644
@@ -101,6 +101,9 @@ config FSL_IMX8MP_ANALOG
 config FSL_IMX8MP_CCM
     bool
 
+config FSL_IMX8MP_GPC
+    bool
+
 config STM32_RCC
     bool
 
hw/misc/imx8mp_gpc.c new file +146 -0

146 lines not on this page · raw message

hw/misc/meson.build +1 -0
index 9790afa104..ba9d586ec9 100644
@@ -62,6 +62,7 @@ system_ss.add(when: 'CONFIG_ECCMEMCTL', if_true: files('eccmemctl.c'))
 system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_pmu.c', 'exynos4210_clk.c', 'exynos4210_rng.c'))
 system_ss.add(when: 'CONFIG_FSL_IMX8MP_ANALOG', if_true: files('imx8mp_analog.c'))
 system_ss.add(when: 'CONFIG_FSL_IMX8MP_CCM', if_true: files('imx8mp_ccm.c'))
+system_ss.add(when: 'CONFIG_FSL_IMX8MP_GPC', if_true: files('imx8mp_gpc.c'))
 system_ss.add(when: 'CONFIG_IMX', if_true: files(
   'imx25_ccm.c',
   'imx31_ccm.c',
include/hw/arm/fsl-imx8mp.h +2 -0
index 6f9bd8d2ce..7c13943afc 100644
@@ -17,6 +17,7 @@
 #include "hw/misc/imx7_snvs.h"
 #include "hw/misc/imx8mp_analog.h"
 #include "hw/misc/imx8mp_ccm.h"
+#include "hw/misc/imx8mp_gpc.h"
 #include "hw/net/flexcan.h"
 #include "hw/net/imx_fec.h"
 #include "hw/core/or-irq.h"
@@ -56,6 +57,7 @@ struct FslImx8mpState {
 
     ARMCPU             cpu[FSL_IMX8MP_NUM_A53];
     GICv3State         gic;
+    IMX8MPGPCState     gpc;
     IMXGPTState        gpt[FSL_IMX8MP_NUM_GPTS];
     IMXGPIOState       gpio[FSL_IMX8MP_NUM_GPIOS];
     IMX8MPCCMState     ccm;
include/hw/misc/imx8mp_gpc.h new file +34 -0
new file mode 100644
index 0000000000..49a040e0c9
@@ -0,0 +1,34 @@
+/*
+ * i.MX 8M Plus GPC(General Power Controller)
+ *
+ * Copyright (c) 2026, NXP Semiconductors
+ * Author: Gaurav Sharma <[email protected]>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+
+#ifndef IMX8MP_GPC_H
+#define IMX8MP_GPC_H
+
+#include "hw/core/sysbus.h"
+#include "qom/object.h"
+
+#define IMX8MP_GPC_MMIO_SIZE 0x1000
+
+#define TYPE_IMX8MP_GPC "imx8mp.gpc"
+
+OBJECT_DECLARE_SIMPLE_TYPE(IMX8MPGPCState, IMX8MP_GPC)
+
+enum IMX8MPGPCRegisters {
+    IMX8MP_GPC_PU_PGC_SW_PUP_REQ = 0x0D8 / 4,
+    IMX8MP_GPC_POLL_REG          = 0x190 / 4,
+};
+
+struct IMX8MPGPCState {
+    SysBusDevice parent_obj;
+    MemoryRegion iomem;
+    uint32_t regs[IMX8MP_GPC_MMIO_SIZE / 4];
+};
+
+#endif /* IMX8MP_GPC_H */
Signature · 1 line
2.34.1
#7 lore raw

PATCH v4 5/11 hw/misc: Add GPR (General Purpose Register) IP to iMX8MP

In reply to Gaurav Sharma

Add IOMUXC General Purpose Registers IP and wire it into the i.MX8MP SoC model. The GPR block provides system-level configuration registers on the i.MX8MP SoC. It provides general purpose control bits and Cortex-M7 CPUWAIT gate needed for AMP boot

---
 docs/system/arm/imx8m.rst    |   1 +
 hw/arm/Kconfig               |   1 +
 hw/arm/fsl-imx8mp.c          |  10 +++
 hw/misc/Kconfig              |   3 +
 hw/misc/imx8mp_gpr.c         | 155 +++++++++++++++++++++++++++++++++++
 hw/misc/meson.build          |   1 +
 include/hw/arm/fsl-imx8mp.h  |   2 +
 include/hw/misc/imx8mp_gpr.h |  62 ++++++++++++++
 8 files changed, 235 insertions(+)
 create mode 100644 hw/misc/imx8mp_gpr.c
 create mode 100644 include/hw/misc/imx8mp_gpr.h
docs/system/arm/imx8m.rst +1 -0
index e9e970ce64..7813469154 100644
@@ -27,6 +27,7 @@ following devices:
  * Secure Non-Volatile Storage (SNVS) including an RTC
  * Clock Tree
  * General Power Controller (GPC)
+ * General Purpose Register (GPR)
 
 Boot options
 ------------
hw/arm/Kconfig +1 -0
index 17450256db..7b7378110c 100644
@@ -595,6 +595,7 @@ config FSL_IMX8MP
     select FSL_IMX8MP_ANALOG
     select FSL_IMX8MP_CCM
     select FSL_IMX8MP_GPC
+    select FSL_IMX8MP_GPR
     select IMX
     select IMX_FEC
     select IMX_I2C
hw/arm/fsl-imx8mp.c +10 -0
index cc5f7080c2..75860d360c 100644
@@ -206,6 +206,8 @@ static void fsl_imx8mp_init(Object *obj)
 
     object_initialize_child(obj, "gpc", &s->gpc, TYPE_IMX8MP_GPC);
 
+    object_initialize_child(obj, "gpr", &s->gpr, TYPE_IMX8MP_GPR);
+
     for (i = 0; i < FSL_IMX8MP_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);
@@ -436,6 +438,13 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpc), 0,
                     fsl_imx8mp_memmap[FSL_IMX8MP_GPC].addr);
 
+    /* GPR */
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpr), errp)) {
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0,
+                    fsl_imx8mp_memmap[FSL_IMX8MP_IOMUXC_GPR].addr);
+
     /* GPTs */
     object_property_set_int(OBJECT(&s->gpt5_gpt6_irq), "num-lines", 2,
                             &error_abort);
@@ -735,6 +744,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
         case FSL_IMX8MP_ECSPI1 ... FSL_IMX8MP_ECSPI3:
         case FSL_IMX8MP_ENET1:
         case FSL_IMX8MP_I2C1 ... FSL_IMX8MP_I2C6:
+        case FSL_IMX8MP_IOMUXC_GPR:
         case FSL_IMX8MP_OCRAM:
         case FSL_IMX8MP_PCIE1:
         case FSL_IMX8MP_PCIE_PHY1:
hw/misc/Kconfig +3 -0
index c17275441c..5c2945200e 100644
@@ -104,6 +104,9 @@ config FSL_IMX8MP_CCM
 config FSL_IMX8MP_GPC
     bool
 
+config FSL_IMX8MP_GPR
+    bool
+
 config STM32_RCC
     bool
 
hw/misc/imx8mp_gpr.c new file +155 -0

155 lines not on this page · raw message

hw/misc/meson.build +1 -0
index ba9d586ec9..5eda094d34 100644
@@ -63,6 +63,7 @@ system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_pmu.c', 'exynos
 system_ss.add(when: 'CONFIG_FSL_IMX8MP_ANALOG', if_true: files('imx8mp_analog.c'))
 system_ss.add(when: 'CONFIG_FSL_IMX8MP_CCM', if_true: files('imx8mp_ccm.c'))
 system_ss.add(when: 'CONFIG_FSL_IMX8MP_GPC', if_true: files('imx8mp_gpc.c'))
+system_ss.add(when: 'CONFIG_FSL_IMX8MP_GPR', if_true: files('imx8mp_gpr.c'))
 system_ss.add(when: 'CONFIG_IMX', if_true: files(
   'imx25_ccm.c',
   'imx31_ccm.c',
include/hw/arm/fsl-imx8mp.h +2 -0
index 7c13943afc..aacfbfd3a4 100644
@@ -18,6 +18,7 @@
 #include "hw/misc/imx8mp_analog.h"
 #include "hw/misc/imx8mp_ccm.h"
 #include "hw/misc/imx8mp_gpc.h"
+#include "hw/misc/imx8mp_gpr.h"
 #include "hw/net/flexcan.h"
 #include "hw/net/imx_fec.h"
 #include "hw/core/or-irq.h"
@@ -58,6 +59,7 @@ struct FslImx8mpState {
     ARMCPU             cpu[FSL_IMX8MP_NUM_A53];
     GICv3State         gic;
     IMX8MPGPCState     gpc;
+    IMX8MPGPRState     gpr;
     IMXGPTState        gpt[FSL_IMX8MP_NUM_GPTS];
     IMXGPIOState       gpio[FSL_IMX8MP_NUM_GPIOS];
     IMX8MPCCMState     ccm;
include/hw/misc/imx8mp_gpr.h new file +62 -0

62 lines not on this page · raw message

Signature · 1 line
2.34.1
#8 lore raw

PATCH v4 6/11 hw/misc: Add SRC (System Reset Controller) to i.MX8MP

In reply to Gaurav Sharma

Add emulation of the i.MX8MP System Reset Controller.
The SRC manages reset control for various subsystems on the i.MX8MP SoC. SRC registers are used to start/stop/poll the M7 core, hence needed for AMP boot.

---
 docs/system/arm/imx8m.rst    |   5 +-
 hw/arm/Kconfig               |   1 +
 hw/arm/fsl-imx8mp.c          |  10 +
 hw/misc/Kconfig              |   3 +
 hw/misc/imx8mp_src.c         | 397 +++++++++++++++++++++++++++++++++++
 hw/misc/meson.build          |   1 +
 hw/misc/trace-events         |   5 +
 include/hw/arm/fsl-imx8mp.h  |   2 +
 include/hw/misc/imx8mp_src.h |  47 +++++
 9 files changed, 469 insertions(+), 2 deletions(-)
 create mode 100644 hw/misc/imx8mp_src.c
 create mode 100644 include/hw/misc/imx8mp_src.h
docs/system/arm/imx8m.rst +3 -2
index 7813469154..38f4e31443 100644
@@ -26,8 +26,9 @@ following devices:
  * 6 General Purpose Timers
  * Secure Non-Volatile Storage (SNVS) including an RTC
  * Clock Tree
- * General Power Controller (GPC)
- * General Purpose Register (GPR)
+ * General Power Controller
+ * General Purpose Register
+ * System Reset Controller
 
 Boot options
 ------------
hw/arm/Kconfig +1 -0
index 7b7378110c..2ab57b7c53 100644
@@ -596,6 +596,7 @@ config FSL_IMX8MP
     select FSL_IMX8MP_CCM
     select FSL_IMX8MP_GPC
     select FSL_IMX8MP_GPR
+    select FSL_IMX8MP_SRC
     select IMX
     select IMX_FEC
     select IMX_I2C
hw/arm/fsl-imx8mp.c +10 -0
index 75860d360c..63513b3ff3 100644
@@ -208,6 +208,8 @@ static void fsl_imx8mp_init(Object *obj)
 
     object_initialize_child(obj, "gpr", &s->gpr, TYPE_IMX8MP_GPR);
 
+    object_initialize_child(obj, "src", &s->src, TYPE_IMX8MP_SRC);
+
     for (i = 0; i < FSL_IMX8MP_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);
@@ -431,6 +433,13 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
                            qdev_get_gpio_in(gicdev, serial_table[i].irq));
     }
 
+    /* SRC */
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->src), errp)) {
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0,
+                    fsl_imx8mp_memmap[FSL_IMX8MP_SRC].addr);
+
     /* GPC */
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpc), errp)) {
         return;
@@ -750,6 +759,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
         case FSL_IMX8MP_PCIE_PHY1:
         case FSL_IMX8MP_RAM:
         case FSL_IMX8MP_SNVS_HP:
+        case FSL_IMX8MP_SRC:
         case FSL_IMX8MP_UART1 ... FSL_IMX8MP_UART4:
         case FSL_IMX8MP_USB1 ... FSL_IMX8MP_USB2:
         case FSL_IMX8MP_USDHC1 ... FSL_IMX8MP_USDHC3:
hw/misc/Kconfig +3 -0
index 5c2945200e..d9e904ae2f 100644
@@ -107,6 +107,9 @@ config FSL_IMX8MP_GPC
 config FSL_IMX8MP_GPR
     bool
 
+config FSL_IMX8MP_SRC
+    bool
+
 config STM32_RCC
     bool
 
hw/misc/imx8mp_src.c new file +397 -0

397 lines not on this page · raw message

hw/misc/meson.build +1 -0
index 5eda094d34..79954586e8 100644
@@ -64,6 +64,7 @@ system_ss.add(when: 'CONFIG_FSL_IMX8MP_ANALOG', if_true: files('imx8mp_analog.c'
 system_ss.add(when: 'CONFIG_FSL_IMX8MP_CCM', if_true: files('imx8mp_ccm.c'))
 system_ss.add(when: 'CONFIG_FSL_IMX8MP_GPC', if_true: files('imx8mp_gpc.c'))
 system_ss.add(when: 'CONFIG_FSL_IMX8MP_GPR', if_true: files('imx8mp_gpr.c'))
+system_ss.add(when: 'CONFIG_FSL_IMX8MP_SRC', if_true: files('imx8mp_src.c'))
 system_ss.add(when: 'CONFIG_IMX', if_true: files(
   'imx25_ccm.c',
   'imx31_ccm.c',
hw/misc/trace-events +5 -0
index 6db4934dc5..6239200f37 100644
@@ -131,6 +131,11 @@ imx7_gpr_write(uint64_t offset, uint64_t value) "addr 0x%08" PRIx64 "value 0x%08
 imx7_snvs_read(uint64_t offset, uint64_t value, unsigned size) "i.MX SNVS read: offset 0x%08" PRIx64 " value 0x%08" PRIx64 " size %u"
 imx7_snvs_write(uint64_t offset, uint64_t value, unsigned size) "i.MX SNVS write: offset 0x%08" PRIx64 " value 0x%08" PRIx64 " size %u"
 
+# imx8mp_src.c
+fsl_imx8mp_src_read(uint64_t offset, const char *reg_name, uint32_t value) "[0x%" PRIx64 "%s] <- 0x%" PRIx32
+fsl_imx8mp_src_write(uint64_t offset, const char *reg_name, uint64_t value) "[0x%" PRIx64 "%s] <- 0x%" PRIx64
+fsl_imx8mp_src_clear_reset_bit(const char *reg_name, uint32_t value) "reg[%s] <= 0x%" PRIx32
+
 # mos6522.c
 mos6522_set_counter(int index, unsigned int val) "T%d.counter=%d"
 mos6522_get_next_irq_time(uint16_t latch, int64_t d, int64_t delta) "latch=%d counter=0x%"PRIx64 " delta_next=0x%"PRIx64
include/hw/arm/fsl-imx8mp.h +2 -0
index aacfbfd3a4..9b626e5d98 100644
@@ -19,6 +19,7 @@
 #include "hw/misc/imx8mp_ccm.h"
 #include "hw/misc/imx8mp_gpc.h"
 #include "hw/misc/imx8mp_gpr.h"
+#include "hw/misc/imx8mp_src.h"
 #include "hw/net/flexcan.h"
 #include "hw/net/imx_fec.h"
 #include "hw/core/or-irq.h"
@@ -66,6 +67,7 @@ struct FslImx8mpState {
     IMX8MPAnalogState  analog;
     IMX7SNVSState      snvs;
     IMXSPIState        spi[FSL_IMX8MP_NUM_ECSPIS];
+    FslImx8mpSrcState  src;
     IMXI2CState        i2c[FSL_IMX8MP_NUM_I2CS];
     IMXSerialState     uart[FSL_IMX8MP_NUM_UARTS];
     IMXFECState        enet;
include/hw/misc/imx8mp_src.h new file +47 -0

47 lines not on this page · raw message

Signature · 1 line
2.34.1
#9 lore raw

PATCH v4 7/11 hw/misc: Add MU (Messaging Unit) IP to i.MX8MP device model

In reply to Gaurav Sharma

Add emulation of the Messaging Unit and wire it into the i.MX8MP SoC model. The MU provides inter-processor communication between the Cortex-A53 and Cortex-M7 cores on the i.MX8MP SoC. It is used by the Linux remoteproc framework as a mailbox for lifecycle management and message passing with the Cortex-M7 in an AMP configuration.

---
 docs/system/arm/imx8m.rst   |   1 +
 hw/arm/Kconfig              |   1 +
 hw/arm/fsl-imx8mp.c         |  41 +++++
 hw/misc/Kconfig             |   3 +
 hw/misc/imx8mp_mu.c         | 346 ++++++++++++++++++++++++++++++++++++
 hw/misc/meson.build         |   1 +
 include/hw/arm/fsl-imx8mp.h |  11 ++
 include/hw/misc/imx8mp_mu.h |  53 ++++++
 8 files changed, 457 insertions(+)
 create mode 100644 hw/misc/imx8mp_mu.c
 create mode 100644 include/hw/misc/imx8mp_mu.h
docs/system/arm/imx8m.rst +1 -0
index 38f4e31443..cdf862a456 100644
@@ -29,6 +29,7 @@ following devices:
  * General Power Controller
  * General Purpose Register
  * System Reset Controller
+ * Messaging Unit
 
 Boot options
 ------------
hw/arm/Kconfig +1 -0
index 2ab57b7c53..d92239fd4e 100644
@@ -597,6 +597,7 @@ config FSL_IMX8MP
     select FSL_IMX8MP_GPC
     select FSL_IMX8MP_GPR
     select FSL_IMX8MP_SRC
+    select FSL_IMX8MP_MU
     select IMX
     select IMX_FEC
     select IMX_I2C
hw/arm/fsl-imx8mp.c +41 -0

59 lines not on this page · raw message

hw/misc/Kconfig +3 -0
index d9e904ae2f..1e3b14b2a9 100644
@@ -110,6 +110,9 @@ config FSL_IMX8MP_GPR
 config FSL_IMX8MP_SRC
     bool
 
+config FSL_IMX8MP_MU
+    bool
+
 config STM32_RCC
     bool
 
hw/misc/imx8mp_mu.c new file +346 -0

346 lines not on this page · raw message

hw/misc/meson.build +1 -0
index 79954586e8..e9c21f06bb 100644
@@ -65,6 +65,7 @@ system_ss.add(when: 'CONFIG_FSL_IMX8MP_CCM', if_true: files('imx8mp_ccm.c'))
 system_ss.add(when: 'CONFIG_FSL_IMX8MP_GPC', if_true: files('imx8mp_gpc.c'))
 system_ss.add(when: 'CONFIG_FSL_IMX8MP_GPR', if_true: files('imx8mp_gpr.c'))
 system_ss.add(when: 'CONFIG_FSL_IMX8MP_SRC', if_true: files('imx8mp_src.c'))
+system_ss.add(when: 'CONFIG_FSL_IMX8MP_MU', if_true: files('imx8mp_mu.c'))
 system_ss.add(when: 'CONFIG_IMX', if_true: files(
   'imx25_ccm.c',
   'imx31_ccm.c',
include/hw/arm/fsl-imx8mp.h +11 -0
index 9b626e5d98..f3e134cdc0 100644
@@ -20,6 +20,7 @@
 #include "hw/misc/imx8mp_gpc.h"
 #include "hw/misc/imx8mp_gpr.h"
 #include "hw/misc/imx8mp_src.h"
+#include "hw/misc/imx8mp_mu.h"
 #include "hw/net/flexcan.h"
 #include "hw/net/imx_fec.h"
 #include "hw/core/or-irq.h"
@@ -40,6 +41,9 @@ OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mpState, FSL_IMX8MP)
 #define FSL_IMX8MP_RAM_START        0x40000000
 #define FSL_IMX8MP_RAM_SIZE_MAX     (8 * GiB)
 
+#define FSL_IMX8MP_MU1_A_IRQ  88
+#define FSL_IMX8MP_MU1_B_IRQ  97
+
 enum FslImx8mpConfiguration {
     FSL_IMX8MP_NUM_CANS         = 2,
     FSL_IMX8MP_NUM_A53          = 4,
@@ -48,12 +52,18 @@ enum FslImx8mpConfiguration {
     FSL_IMX8MP_NUM_GPTS         = 6,
     FSL_IMX8MP_NUM_I2CS         = 6,
     FSL_IMX8MP_NUM_IRQS         = 160,
+    FSL_IMX8MP_NUM_MU           = 3,
     FSL_IMX8MP_NUM_UARTS        = 4,
     FSL_IMX8MP_NUM_USBS         = 2,
     FSL_IMX8MP_NUM_USDHCS       = 3,
     FSL_IMX8MP_NUM_WDTS         = 3,
 };
 
+typedef struct IMX8MPMUPair {
+    IMX8MPMUState a;
+    IMX8MPMUState b;
+} IMX8MPMUPair;
+
 struct FslImx8mpState {
     SysBusDevice   parent_obj;
 
@@ -67,6 +77,7 @@ struct FslImx8mpState {
     IMX8MPAnalogState  analog;
     IMX7SNVSState      snvs;
     IMXSPIState        spi[FSL_IMX8MP_NUM_ECSPIS];
+    IMX8MPMUPair       mu[FSL_IMX8MP_NUM_MU];
     FslImx8mpSrcState  src;
     IMXI2CState        i2c[FSL_IMX8MP_NUM_I2CS];
     IMXSerialState     uart[FSL_IMX8MP_NUM_UARTS];
include/hw/misc/imx8mp_mu.h new file +53 -0

53 lines not on this page · raw message

Signature · 1 line
2.34.1
#10 lore raw

PATCH v4 8/11 hw/misc: Extend i.MX8MP CCM with Cortex-M7 clock outputs

In reply to Gaurav Sharma

Add cm7_cpuclk (24 MHz) and cm7_refclk (32.768 kHz) clock outputs to the i.MX8MP CCM. These are required by the ARMv7M model to boot the Cortex-M7 core in an AMP configuration.

---
 hw/misc/imx8mp_ccm.c         | 9 +++++++++
 include/hw/misc/imx8mp_ccm.h | 3 +++
 2 files changed, 12 insertions(+)
hw/misc/imx8mp_ccm.c +9 -0
index 97d363e79d..41746e1eeb 100644
@@ -12,17 +12,24 @@
 #include "qemu/log.h"
 
 #include "hw/misc/imx8mp_ccm.h"
+#include "hw/core/qdev-clock.h"
 #include "migration/vmstate.h"
 
 #include "trace.h"
 
 #define CKIH_FREQ 16000000 /* 16MHz crystal input */
 
+#define IMX8MP_CM7_CPUCLK_HZ 24000000ULL   /* osc_24m */
+#define IMX8MP_CM7_REFCLK_HZ 32768ULL      /* osc_32k */
+
 static void imx8mp_ccm_reset(DeviceState *dev)
 {
     IMX8MPCCMState *s = IMX8MP_CCM(dev);
 
     memset(s->ccm, 0, sizeof(s->ccm));
+
+    clock_set_hz(s->cm7_cpuclk, IMX8MP_CM7_CPUCLK_HZ);
+    clock_set_hz(s->cm7_refclk, IMX8MP_CM7_REFCLK_HZ);
 }
 
 #define CCM_INDEX(offset)   (((offset) & ~(hwaddr)0xF) / sizeof(uint32_t))
@@ -88,6 +95,8 @@ static void imx8mp_ccm_init(Object *obj)
     SysBusDevice *sd = SYS_BUS_DEVICE(obj);
     IMX8MPCCMState *s = IMX8MP_CCM(obj);
 
+    s->cm7_cpuclk = qdev_init_clock_out(DEVICE(obj), "cm7_cpuclk");
+    s->cm7_refclk = qdev_init_clock_out(DEVICE(obj), "cm7_refclk");
     memory_region_init_io(&s->iomem,
                           obj,
                           &imx8mp_set_clr_tog_ops,
include/hw/misc/imx8mp_ccm.h +3 -0
index 685c8582ff..c6ede6928c 100644
@@ -9,6 +9,7 @@
 #ifndef IMX8MP_CCM_H
 #define IMX8MP_CCM_H
 
+#include "hw/core/clock.h"
 #include "hw/misc/imx_ccm.h"
 #include "qom/object.h"
 
@@ -25,6 +26,8 @@ struct IMX8MPCCMState {
     MemoryRegion iomem;
 
     uint32_t ccm[CCM_MAX];
+    Clock *cm7_cpuclk;
+    Clock *cm7_refclk;
 };
 
 #endif /* IMX8MP_CCM_H */
Signature · 1 line
2.34.1
#11 lore raw

PATCH v4 9/11 hw/arm: Add ITCM and DTCM memory regions to i.MX8MP

In reply to Gaurav Sharma

Add the 128 KiB ITCM and DTCM used by the i.MX8MP Cortex-M7 subsystem.

Expose ITCM and DTCM using the system-bus windows available to the Cortex-A53, and add the Cortex-M7-visible aliases at 0x00000000 and 0x20000000 respectively.

---
 hw/arm/fsl-imx8mp.c         | 33 +++++++++++++++++++++++++++++++++
 include/hw/arm/fsl-imx8mp.h |  4 ++++
 2 files changed, 37 insertions(+)
hw/arm/fsl-imx8mp.c +33 -0
index c168c97d1a..18d2b17ca8 100644
@@ -779,6 +779,37 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
                                 fsl_imx8mp_memmap[FSL_IMX8MP_OCRAM].addr,
                                 &s->ocram);
 
+    if (!memory_region_init_ram(&s->itcm, OBJECT(dev), "imx8mp.itcm",
+                                fsl_imx8mp_memmap[FSL_IMX8MP_TCM_ITCM].size,
+                                errp)) {
+        return;
+    }
+    memory_region_add_subregion(get_system_memory(),
+                                fsl_imx8mp_memmap[FSL_IMX8MP_TCM_ITCM].addr,
+                                &s->itcm);
+
+    if (!memory_region_init_ram(&s->dtcm, OBJECT(dev), "imx8mp.dtcm",
+                                fsl_imx8mp_memmap[FSL_IMX8MP_TCM_DTCM].size,
+                                errp)) {
+        return;
+    }
+    memory_region_add_subregion(get_system_memory(),
+                                fsl_imx8mp_memmap[FSL_IMX8MP_TCM_DTCM].addr,
+                                &s->dtcm);
+
+    /* M7-view aliases: ITCM@0x0, DTCM@0x20000000 */
+    memory_region_init_alias(&s->itcm_alias, OBJECT(dev), "imx8mp.itcm-alias",
+                             &s->itcm, 0,
+                             fsl_imx8mp_memmap[FSL_IMX8MP_TCM_ITCM].size);
+    memory_region_add_subregion_overlap(get_system_memory(),
+                                        0x00000000, &s->itcm_alias, 1);
+
+    memory_region_init_alias(&s->dtcm_alias, OBJECT(dev), "imx8mp.dtcm-alias",
+                             &s->dtcm, 0,
+                             fsl_imx8mp_memmap[FSL_IMX8MP_TCM_DTCM].size);
+    memory_region_add_subregion_overlap(get_system_memory(),
+                                        0x20000000, &s->dtcm_alias, 1);
+
     /* Unimplemented devices */
     for (i = 0; i < ARRAY_SIZE(fsl_imx8mp_memmap); i++) {
         switch (i) {
@@ -796,6 +827,8 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
         case FSL_IMX8MP_IOMUXC_GPR:
         case FSL_IMX8MP_MU_1_A ... FSL_IMX8MP_MU_3_B:
         case FSL_IMX8MP_OCRAM:
+        case FSL_IMX8MP_TCM_ITCM:
+        case FSL_IMX8MP_TCM_DTCM:
         case FSL_IMX8MP_PCIE1:
         case FSL_IMX8MP_PCIE_PHY1:
         case FSL_IMX8MP_RAM:
include/hw/arm/fsl-imx8mp.h +4 -0
index f3e134cdc0..f547cbae42 100644
@@ -90,6 +90,10 @@ struct FslImx8mpState {
     FlexcanState       flexcan[FSL_IMX8MP_NUM_CANS];
     OrIRQState         gpt5_gpt6_irq;
     MemoryRegion       ocram;
+    MemoryRegion       itcm;
+    MemoryRegion       dtcm;
+    MemoryRegion       itcm_alias;
+    MemoryRegion       dtcm_alias;
 
     uint32_t           phy_num;
     bool               phy_connected;
Signature · 1 line
2.34.1
#12 lore raw

Re: [PATCHv4 09/11] hw/arm: Add ITCM and DTCM memory regions to i.MX8MP

Am 7. Oktober 2026 10:11:03 UTC schrieb Gaurav Sharma <[email protected]>:

Quoted 6 lines

Add the 128 KiB ITCM and DTCM used by the i.MX8MP Cortex-M7 subsystem.

Expose ITCM and DTCM using the system-bus windows available to the Cortex-A53, and add the Cortex-M7-visible aliases at 0x00000000 and 0x20000000 respectively.

We need a dedicated AddressSpace for the M7 where the aliases would be mapped. From the top of my head I think there is a link property in the cortex-A7 CPU model's SysBusDevice named "memory" where the address map should be linked. See e.g. "[PATCH v2 06/10] hw/riscv/atlantis: Add the RCPU to the Atlantis SoC" for inspiration.

However, the address map should be added in the patch adding the M7 CPU. This patch should only deal with the A53 memory map, and it could therefore be moved somewhere in front of patch "[PATCH 04/11] hw/misc: Add i.MX8MP GPC (General Power Controller) IP".

Best regards,
Bernhard

Quoted 73 lines

---
hw/arm/fsl-imx8mp.c | 33 +++++++++++++++++++++++++++++++++
include/hw/arm/fsl-imx8mp.h | 4 ++++

2 files changed, 37 insertions(+)
hw/arm/fsl-imx8mp.c +33 -0
index c168c97d1a..18d2b17ca8 100644
@@ -779,6 +779,37 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
                                fsl_imx8mp_memmap[FSL_IMX8MP_OCRAM].addr,
                                &s->ocram);
 
+    if (!memory_region_init_ram(&s->itcm, OBJECT(dev), "imx8mp.itcm",
+                                fsl_imx8mp_memmap[FSL_IMX8MP_TCM_ITCM].size,
+                                errp)) {
+        return;
+    }
+    memory_region_add_subregion(get_system_memory(),
+                                fsl_imx8mp_memmap[FSL_IMX8MP_TCM_ITCM].addr,
+                                &s->itcm);
+
+    if (!memory_region_init_ram(&s->dtcm, OBJECT(dev), "imx8mp.dtcm",
+                                fsl_imx8mp_memmap[FSL_IMX8MP_TCM_DTCM].size,
+                                errp)) {
+        return;
+    }
+    memory_region_add_subregion(get_system_memory(),
+                                fsl_imx8mp_memmap[FSL_IMX8MP_TCM_DTCM].addr,
+                                &s->dtcm);
+
+    /* M7-view aliases: ITCM@0x0, DTCM@0x20000000 */
+    memory_region_init_alias(&s->itcm_alias, OBJECT(dev), "imx8mp.itcm-alias",
+                             &s->itcm, 0,
+                             fsl_imx8mp_memmap[FSL_IMX8MP_TCM_ITCM].size);
+    memory_region_add_subregion_overlap(get_system_memory(),
+                                        0x00000000, &s->itcm_alias, 1);
+
+    memory_region_init_alias(&s->dtcm_alias, OBJECT(dev), "imx8mp.dtcm-alias",
+                             &s->dtcm, 0,
+                             fsl_imx8mp_memmap[FSL_IMX8MP_TCM_DTCM].size);
+    memory_region_add_subregion_overlap(get_system_memory(),
+                                        0x20000000, &s->dtcm_alias, 1);
+
    /* Unimplemented devices */
    for (i = 0; i < ARRAY_SIZE(fsl_imx8mp_memmap); i++) {
        switch (i) {
@@ -796,6 +827,8 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
        case FSL_IMX8MP_IOMUXC_GPR:
        case FSL_IMX8MP_MU_1_A ... FSL_IMX8MP_MU_3_B:
        case FSL_IMX8MP_OCRAM:
+        case FSL_IMX8MP_TCM_ITCM:
+        case FSL_IMX8MP_TCM_DTCM:
        case FSL_IMX8MP_PCIE1:
        case FSL_IMX8MP_PCIE_PHY1:
        case FSL_IMX8MP_RAM:
include/hw/arm/fsl-imx8mp.h +4 -0
index f3e134cdc0..f547cbae42 100644
@@ -90,6 +90,10 @@ struct FslImx8mpState {
    FlexcanState       flexcan[FSL_IMX8MP_NUM_CANS];
    OrIRQState         gpt5_gpt6_irq;
    MemoryRegion       ocram;
+    MemoryRegion       itcm;
+    MemoryRegion       dtcm;
+    MemoryRegion       itcm_alias;
+    MemoryRegion       dtcm_alias;
 
    uint32_t           phy_num;
    bool               phy_connected;
#13 lore raw

PATCH v4 10/11 hw/arm: Add IRQ splitter for i.MX8MP AMP interrupt routing

In reply to Gaurav Sharma

Route the i.MX8MP peripheral interrupt sources through two-output SplitIRQ devices.
Connect the first splitter output to the Cortex-A53 GIC. The second output will be connected to the Cortex-M7 NVIC when CM7 support is added.

---
 hw/arm/fsl-imx8mp.c         | 56 ++++++++++++++++++++++++-------------
 include/hw/arm/fsl-imx8mp.h |  2 ++
 2 files changed, 38 insertions(+), 20 deletions(-)
hw/arm/fsl-imx8mp.c +36 -20
index 18d2b17ca8..395356bc13 100644
@@ -196,6 +196,12 @@ static void fsl_imx8mp_init(Object *obj)
     FslImx8mpState *s = FSL_IMX8MP(obj);
     int i;
 
+    for (i = 0; i < FSL_IMX8MP_NUM_IRQS; i++) {
+        g_autofree char *name = g_strdup_printf("irq-splitter%d", i);
+        object_initialize_child(obj, name, &s->cpu_irq_splitter[i],
+                                TYPE_SPLIT_IRQ);
+    }
+
     object_initialize_child(obj, "gic", &s->gic, gicv3_class_name());
 
     object_initialize_child(obj, "ccm", &s->ccm, TYPE_IMX8MP_CCM);
@@ -280,6 +286,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
     FslImx8mpState *s = FSL_IMX8MP(dev);
     DeviceState *gicdev = DEVICE(&s->gic);
     const char *cpu_type = ms->cpu_type ?: ARM_CPU_TYPE_NAME("cortex-a53");
+    qemu_irq spi_irq[FSL_IMX8MP_NUM_IRQS];
     int i;
 
     if (ms->smp.cpus > FSL_IMX8MP_NUM_A53) {
@@ -407,6 +414,15 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
         }
     }
 
+    for (i = 0; i < FSL_IMX8MP_NUM_IRQS; i++) {
+        DeviceState *splitter = DEVICE(&s->cpu_irq_splitter[i]);
+        qdev_prop_set_uint16(splitter, "num-lines", 2);
+        qdev_realize(splitter, NULL, &error_abort);
+        spi_irq[i] = qdev_get_gpio_in(splitter, 0);
+        qdev_connect_gpio_out(splitter, 0,
+                              qdev_get_gpio_in(gicdev, i));
+    }
+
     /* CCM */
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->ccm), errp)) {
         return;
@@ -440,7 +456,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
 
         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));
+                           spi_irq[serial_table[i].irq]);
     }
 
     /* SRC */
@@ -472,7 +488,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
     }
 
     qdev_connect_gpio_out(DEVICE(&s->gpt5_gpt6_irq), 0,
-                          qdev_get_gpio_in(gicdev, FSL_IMX8MP_GPT5_GPT6_IRQ));
+                          spi_irq[FSL_IMX8MP_GPT5_GPT6_IRQ]);
 
     for (i = 0; i < FSL_IMX8MP_NUM_GPTS; i++) {
         hwaddr gpt_addrs[FSL_IMX8MP_NUM_GPTS] = {
@@ -501,7 +517,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
             };
 
             sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
-                               qdev_get_gpio_in(gicdev, gpt_irqs[i]));
+                               spi_irq[gpt_irqs[i]]);
         } else {
             int irq = i - FSL_IMX8MP_NUM_GPTS + 2;
 
@@ -536,9 +552,9 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
     }
 
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->mu[0].a), 0,
-                       qdev_get_gpio_in(gicdev, FSL_IMX8MP_MU1_A_IRQ));
+                       spi_irq[FSL_IMX8MP_MU1_A_IRQ]);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->mu[0].b), 0,
-                       qdev_get_gpio_in(gicdev, FSL_IMX8MP_MU1_B_IRQ));
+                       spi_irq[FSL_IMX8MP_MU1_B_IRQ]);
 
     /* I2Cs */
     for (i = 0; i < FSL_IMX8MP_NUM_I2CS; i++) {
@@ -560,7 +576,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
 
         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));
+                           spi_irq[i2c_table[i].irq]);
     }
 
     /* GPIOs */
@@ -607,9 +623,9 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
 
         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));
+                           spi_irq[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));
+                           spi_irq[gpio_table[i].irq_high]);
     }
 
     /* USDHCs */
@@ -629,7 +645,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
 
         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));
+                           spi_irq[usdhc_table[i].irq]);
     }
 
     /* USBs */
@@ -650,7 +666,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
         }
         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));
+                           spi_irq[usb_table[i].irq]);
     }
 
     /* ECSPIs */
@@ -670,7 +686,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
 
         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));
+                           spi_irq[spi_table[i].irq]);
     }
 
     /* ENET1 */
@@ -684,9 +700,9 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->enet), 0,
                     fsl_imx8mp_memmap[FSL_IMX8MP_ENET1].addr);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->enet), 0,
-                       qdev_get_gpio_in(gicdev, FSL_IMX8MP_ENET1_MAC_IRQ));
+                       spi_irq[FSL_IMX8MP_ENET1_MAC_IRQ]);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->enet), 1,
-                       qdev_get_gpio_in(gicdev, FSL_IMX6_ENET1_MAC_1588_IRQ));
+                       spi_irq[FSL_IMX6_ENET1_MAC_1588_IRQ]);
 
     /* SNVS */
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->snvs), errp)) {
@@ -714,7 +730,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
 
         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));
+                           spi_irq[wdog_table[i].irq]);
     }
 
     /* PCIe */
@@ -725,15 +741,15 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
                     fsl_imx8mp_memmap[FSL_IMX8MP_PCIE1].addr);
 
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0,
-                       qdev_get_gpio_in(gicdev, FSL_IMX8MP_PCI_INTA_IRQ));
+                       spi_irq[FSL_IMX8MP_PCI_INTA_IRQ]);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1,
-                       qdev_get_gpio_in(gicdev, FSL_IMX8MP_PCI_INTB_IRQ));
+                       spi_irq[FSL_IMX8MP_PCI_INTB_IRQ]);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2,
-                       qdev_get_gpio_in(gicdev, FSL_IMX8MP_PCI_INTC_IRQ));
+                       spi_irq[FSL_IMX8MP_PCI_INTC_IRQ]);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3,
-                       qdev_get_gpio_in(gicdev, FSL_IMX8MP_PCI_INTD_IRQ));
+                       spi_irq[FSL_IMX8MP_PCI_INTD_IRQ]);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 4,
-                       qdev_get_gpio_in(gicdev, FSL_IMX8MP_PCI_MSI_IRQ));
+                       spi_irq[FSL_IMX8MP_PCI_MSI_IRQ]);
 
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->pcie_phy), errp)) {
         return;
@@ -766,7 +782,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
         sysbus_mmio_map(SYS_BUS_DEVICE(&s->flexcan[i]), 0,
                         flexcan_table[i].addr);
         sysbus_connect_irq(SYS_BUS_DEVICE(&s->flexcan[i]), 0,
-                           qdev_get_gpio_in(gicdev, flexcan_table[i].irq));
+                           spi_irq[flexcan_table[i].irq]);
     }
 
     /* On-Chip RAM */
include/hw/arm/fsl-imx8mp.h +2 -0
index f547cbae42..2824f38355 100644
@@ -24,6 +24,7 @@
 #include "hw/net/flexcan.h"
 #include "hw/net/imx_fec.h"
 #include "hw/core/or-irq.h"
+#include "hw/core/split-irq.h"
 #include "hw/pci-host/designware.h"
 #include "hw/pci-host/fsl_imx8m_phy.h"
 #include "hw/sd/sdhci.h"
@@ -89,6 +90,7 @@ struct FslImx8mpState {
     FslImx8mPciePhyState   pcie_phy;
     FlexcanState       flexcan[FSL_IMX8MP_NUM_CANS];
     OrIRQState         gpt5_gpt6_irq;
+    SplitIRQ           cpu_irq_splitter[FSL_IMX8MP_NUM_IRQS];
     MemoryRegion       ocram;
     MemoryRegion       itcm;
     MemoryRegion       dtcm;
Signature · 1 line
2.34.1
#14 lore raw

PATCH v4 11/11 hw/arm: Enable Cortex-M7 AMP boot on i.MX8MP

In reply to Gaurav Sharma

Configure the i.MX8MP to boot the Cortex-M7 core alongside the Cortex-A53 cores in an Asymmetric Multiprocessing (AMP) configuration. The M7 firmware can be loaded and started from Linux running on the A53 cores via the remoteproc framework.

CM7 boot is made optional. A GPR IRQ is connected to a cpuwait handler. The handler translates the CPUWAIT into STOP and RUN.

---
 docs/system/arm/imx8m.rst   | 182 ++++++++++++++++++++++++++++++++++++
 hw/arm/fsl-imx8mp.c         |  87 ++++++++++++-----
 hw/arm/imx8mp-evk.c         |   5 +-
 include/hw/arm/fsl-imx8mp.h |   5 +
 4 files changed, 255 insertions(+), 24 deletions(-)
docs/system/arm/imx8m.rst +182 -0
index cdf862a456..1472468df2 100644
@@ -12,6 +12,7 @@ The ``imx8mp-evk`` and ``imx8mm-evk`` machines implement the
 following devices:
 
  * Up to 4 Cortex-A53 cores
+ * 1 Cortex-M7 core (``imx8mp-evk`` only)
  * Generic Interrupt Controller (GICv3)
  * 4 UARTs
  * 3 USDHC Storage Controllers
@@ -37,6 +38,187 @@ Boot options
 The ``imx8mp-evk`` and ``imx8mm-evk`` machines can start a Linux
 kernel directly using the standard ``-kernel`` functionality.
 
+
+Asymmetric Multiprocessing (AMP) Boot Recipe (``imx8mp-evk`` only)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The ``imx8mp-evk`` machine includes a Cortex-M7 core alongside the
+Cortex-A53 cores, enabling Asymmetric Multiprocessing (AMP). The M7
+firmware can be loaded from Linux using the remoteproc framework.
+
+There are 2 control paths for Cortex-M7 on iMX8MP:-
+1. Firmware-mediated (via SMC/ATF)
+2. MMIO driven path (via SRC and GPR access)
+
+``fsl,imx8mp-cm7-mmio`` exists specifically to select the MMIO path and avoid dependence on firmware interfaces that aren’t guaranteed in qemu.
+This mode uses the SRC syscon block and the IOMUXC GPR for start/stop control.
+
+Memory carveouts for resource table, vrings need to be specified in the ``imx8mp-evk-rpmsg.dts``.
+Follow this application note to make the necessary changes - https://www.nxp.com/docs/en/application-note/AN5317.pdf
+
+When Linux boots CM7 via remoteproc, the typical flow is:
+
+1. Linux booted with imx8mp-evk-rpmsg.dtb
+2. Linux loads the CM7 ELF into a reserved DDR region
+3. Linux toggles the CM7 start/stop control (SRC/GPR CPUWAIT, etc.)
+4. CM7 starts executing from that DDR entry
+
+
+Prerequisites
+~~~~~~~~~~~~~
+
+To manually test Cortex-M7 firmware loading from Linux, the following
+components are needed:
+
+1. Linux kernel configuration to enable i.MX remoteproc support.
+2. ``imx8mp-evk-rpmsg.dtb`` -  device tree that enables the Cortex-M7 remoteproc node, reserves DDR memory regions
+   for the Cortex-M7 firmware, resource table,vrings and buffers.
+3. A Cortex-M7 ELF firmware image linked to execute from DDR.
+
+NXP application note AN5317 describes the required remoteproc and reserved-memory setup
+for loading Cortex-M firmware from Linux.
+
+
+Linux kernel configuration
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The guest kernel needs remoteproc support. On official linux-imx kernels, this support is enabled by default.
+When using Buildroot, verify that the kernel configuration enables the remoteproc and rpmsg options needed by the
+i.MX remoteproc driver, for example:
+
+.. code-block:: none
+
+  CONFIG_REMOTEPROC=y
+  CONFIG_IMX_REMOTEPROC=y
+  CONFIG_RPMSG=y
+  CONFIG_VIRTIO_RPMSG_BUS=y
+  CONFIG_RPMSG_CHAR=y
+
+Depending on the kernel version and configuration, some options may be selected
+automatically by the i.MX remoteproc driver.
+
+
+
+Device tree preparation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+1. Refer to ``9.1 i.MX Linux rproc support`` of application note AN5317 to add the
+   following nodes in ``imx8mp-evk-rpmsg.dts`` :-
+
+   m7_ddr_alias
+   m7_itcm
+   m7_dtcm
+
+2. Modify the compatible string of ``imx8mp-cm7`` node from ``fsl,imx8mn-cm7`` to ``fsl,imx8mp-cm7-mmio``
+3. Add the following properties to the ``imx8mp-cm7`` node :-
+
+   ``syscon = <&src>;``
+   ``fsl,iomuxc-gpr = <&gpr>;``
+
+   These references are needed by imx_rproc_mmio_detect_mode in i.MX remoteproc driver
+   for M7 boot mode detection.
+
+
+   Build ``imx8mp-evk-rpmsg.dtb`` from the above dts changes.
+
+
+
+Building a Cortex-M7 ELF firmware
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A simple manual test is the MCUXpresso SDK UART polling example for the i.MX8MP
+EVK. It prints to a UART and is therefore easy to observe from QEMU.
+
+1. Follow this guide to set up MCUXpresso SDK for i.MX8MPEVK :- MCUXSDKIMX8MPGSUG[https://share.google/qD4D09FCkkydTurqp]
+2. Build a DDR-linked Cortex-M7 ELF using the ARM GNU toolchain from the MCUXpresso SDK:-
+
+
+.. code-block:: bash
+
+  $ cd ${MCUX_SDK}/boards/evkmimx8mp/driver_examples/uart/polling/armgcc
+  $ ./build_ddr_release.sh
+
+As a result, ``iuart_polling_cm7.elf`` will be generated  in ``ddr_release`` folder.
+
+Boot qemu i.MX8MP EVK machine with the updated linux kernel and ``imx8mp-evk-rpmsg.dtb``
+
+3. Copy the ``iuart_polling_cm7.elf`` to ``/lib/firmware/`` path inside iMX8MPEVK qemu emulation.
+
+
+Serial ports (UARTs)
+''''''''''''''''''''
+
+The i.MX 8M Plus EVK model provides four UARTs. QEMU connects each UART to a
+host character backend using the ``-serial`` option. This option can be used
+multiple times to create and wire multiple serial ports.
+
+The ``-serial`` options are positional:
+
+* the 1st ``-serial ...`` maps to ``serial0`` (UART1)
+* the 2nd ``-serial ...`` maps to ``serial1`` (UART2)
+* the 3rd ``-serial ...`` maps to ``serial2`` (UART3)
+* the 4th ``-serial ...`` maps to ``serial3`` (UART4)
+
+Example usage:- To enable serial console for the official M7 mcuxpresso sdk driver example - driver_examples/uart/polling which uses UART4, use:-
+
+.. code-block:: bash
+
+  -serial null -serial stdio -serial null -serial pty:/tmp/imx8mp-uart4
+
+This will create a symlink /tmp/imx8mp-uart4 pointed to the allocated PTY. On a different tab the console for UART4 can be opened using the following:-
+
+.. code-block:: bash
+
+  $ screen /tmp/imx8mp-uart4 115200
+
+
+Starting QEMU for Cortex-M7 remoteproc testing
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+1. Execute the following command to start i.MX8MPEVK emulation:-
+
+.. code-block:: bash
+
+  $ qemu-system-aarch64 -M imx8mp-evk \
+      -display none -serial null -serial stdio -serial null -serial /tmp/imx8mp-uart4 \
+      -kernel Image \
+      -dtb imx8mp-evk-rpmsg.dtb \
+      -append "root=/dev/mmcblk2p2" \
+      -drive file=sdcard.img,if=sd,bus=2,format=raw,id=mmcblk2
+
+2. On a new tab execute the following to open a console:-
+
+.. code-block:: bash
+
+  $ screen /tmp/imx8mp-uart4 115200
+
+3. Execute the following commands inside emulation to load the firmware elf:-
+
+.. code-block:: bash
+
+   $ echo iuart_polling_cm7.elf > /sys/class/remoteproc/remoteproc0/firmware
+   $ echo start > /sys/class/remoteproc/remoteproc0/state
+
+
+On the tab where the console is opened, you will observe the UART logs. The characters
+typed from the keyboard will echo on the console.
+
+
+Note:-
+
+Only DDR-linked bare-metal ELF images are currently supported by QEMU
+emulation. If the firmware is linked for a vector table base address other than
+``0x80000000``, configure the Cortex-M7 vector base using the SoC property
+``cm7-vector-base``:-
+
+.. code-block:: bash
+
+  -global fsl-imx8mp.cm7-vector-base=0x80000000
+
+If this property is not provided, QEMU uses ``0x80000000`` by default.
+
+
+
 Direct Linux Kernel Boot
 ''''''''''''''''''''''''
 
hw/arm/fsl-imx8mp.c +65 -22

158 lines not on this page · raw message

hw/arm/imx8mp-evk.c +3 -2
index f19d80b796..432a146efd 100644
@@ -147,8 +147,9 @@ static void imx8mp_evk_machine_class_init(ObjectClass *oc, const void *data)
 
     mc->desc = "NXP i.MX 8M Plus EVK Board";
     mc->init = imx8mp_evk_init;
-    mc->default_cpus = 4;
-    mc->max_cpus = FSL_IMX8MP_NUM_A53;
+    mc->default_cpus = FSL_IMX8MP_NUM_A53 + FSL_IMX8MP_NUM_M7;
+    mc->min_cpus = FSL_IMX8MP_NUM_A53 + FSL_IMX8MP_NUM_M7;
+    mc->max_cpus = FSL_IMX8MP_NUM_A53 + FSL_IMX8MP_NUM_M7;
     mc->default_ram_id = "imx8mp-evk.ram";
     mc->default_ram_size = 6 * GiB;
     mc->get_default_cpu_type = imx8mp_evk_get_default_cpu_type;
include/hw/arm/fsl-imx8mp.h +5 -0
index 2824f38355..6662579dcf 100644
@@ -10,6 +10,7 @@
 #define FSL_IMX8MP_H
 
 #include "target/arm/cpu.h"
+#include "hw/arm/armv7m.h"
 #include "hw/char/imx_serial.h"
 #include "hw/gpio/imx_gpio.h"
 #include "hw/i2c/imx_i2c.h"
@@ -48,6 +49,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mpState, FSL_IMX8MP)
 enum FslImx8mpConfiguration {
     FSL_IMX8MP_NUM_CANS         = 2,
     FSL_IMX8MP_NUM_A53          = 4,
+    FSL_IMX8MP_NUM_M7           = 1,
     FSL_IMX8MP_NUM_ECSPIS       = 3,
     FSL_IMX8MP_NUM_GPIOS        = 5,
     FSL_IMX8MP_NUM_GPTS         = 6,
@@ -69,6 +71,9 @@ struct FslImx8mpState {
     SysBusDevice   parent_obj;
 
     ARMCPU             cpu[FSL_IMX8MP_NUM_A53];
+    ARMv7MState        cm7;
+    bool               enable_cm7;
+    uint32_t           cm7_vector_base;
     GICv3State         gic;
     IMX8MPGPCState     gpc;
     IMX8MPGPRState     gpr;
Signature · 1 line
2.34.1
#15 lore raw
In reply to Gaurav Sharma

Ping. Just checking if anyone got a chance to review this patch series.

NXP Confidential

Quoted 102 lines

-----Original Message-----
From: Gaurav Sharma <[email protected]>
Sent: 07 October 2026 15:41
To: [email protected]
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Gaurav Sharma <[email protected]>
Subject: [PATCHv4 00/11] hw/arm: Adding Cortex-M7 Asymmetric Multiprocessing boot support for i.MX8MP

Changes in v1:

This series adds Asymmetric Multiprocessing (AMP) boot support for the Cortex-M7 core on the i.MX8MP SoC. The M7 firmware can be loaded and started from Linux running on the Cortex-A53 cores via the remoteproc framework.

The series introduces the following peripheral models needed for AMP:
- GPC (General Power Controller)
- GPR (General Purpose Registers)
- SRC (System Reset Controller) authored by Bernhard Beschow
<[email protected]>
- MU (Messaging Unit)
- Extends the CCM with M7 clock outputs and wires into the i.MX8MP SoC
- Enable Cortex-M7 boot in i.MX8MP EVK functional test

Changes in v2:

- Removed the usage of device_class_set_legacy_reset in imx8mp gpc,gpr,mu and
src.
- Removed the usage of 'smp' , 'maxcpus' and 'enable-cm7' to make the invocation simpler.
- Cleaned up imx8mp_src by removing redundant/unused code.
- Updated Maintainers and improved the imx8mp documentation

Changes in v3:

- Added a new patch for smp removal from test_imx8mp_evk.py.
- Added a new patch to introduce IRQ splitting for i.MX8MP AMP interrupt routing.
- Added a new patch to rename FSL_IMX8MP_NUM_CPUS to FSL_IMX8MP_NUM_A53,
since M7 is being introduced now.
- In GPR, parent_phases moved from global variable to class struct
- M7 reset handling moved from the machine to SRC device model.
- Added ITCM and DTCM memory regions to support zephyr firmware loading.

Changes in v4:

- Move independent MAINTAINERS, CPU renaming and functional-test cleanups to the beginning of the series
- Created a separate patch for ITCM and DTCM modeling.
- Move IRQ splitter infrastructure before Cortex-M7 integration

Gaurav Sharma (11):
MAINTAINERS: Merge MCIMX8MM-EVK and MCIMX8MP-EVK entries hw/arm: Rename FSL_IMX8MP_NUM_CPUS to FSL_IMX8MP_NUM_A53 tests/functional: Fix i.MX8MP EVK SMP configuration hw/misc: Add i.MX8MP GPC (General Power Controller) IP hw/misc: Add GPR (General Purpose Register) IP to iMX8MP hw/misc: Add SRC (System Reset Controller) to i.MX8MP hw/misc: Add MU (Messaging Unit) IP to i.MX8MP device model hw/misc: Extend i.MX8MP CCM with Cortex-M7 clock outputs hw/arm: Add ITCM and DTCM memory regions to i.MX8MP hw/arm: Add IRQ splitter for i.MX8MP AMP interrupt routing hw/arm: Enable Cortex-M7 AMP boot on i.MX8MP

 MAINTAINERS                                 |  13 +-
 docs/system/arm/imx8m.rst                   | 186 +++++++++
 hw/arm/Kconfig                              |   4 +
 hw/arm/fsl-imx8mp.c                         | 229 +++++++++--
 hw/arm/imx8mp-evk.c                         |   5 +-
 hw/misc/Kconfig                             |  12 +
 hw/misc/imx8mp_ccm.c                        |   9 +
 hw/misc/imx8mp_gpc.c                        | 146 +++++++
 hw/misc/imx8mp_gpr.c                        | 155 ++++++++
 hw/misc/imx8mp_mu.c                         | 346 +++++++++++++++++
 hw/misc/imx8mp_src.c                        | 397 ++++++++++++++++++++
 hw/misc/meson.build                         |   4 +
 hw/misc/trace-events                        |   5 +
 include/hw/arm/fsl-imx8mp.h                 |  32 +-
 include/hw/misc/imx8mp_ccm.h                |   3 +
 include/hw/misc/imx8mp_gpc.h                |  34 ++
 include/hw/misc/imx8mp_gpr.h                |  62 +++
 include/hw/misc/imx8mp_mu.h                 |  53 +++
 include/hw/misc/imx8mp_src.h                |  47 +++
 tests/functional/aarch64/test_imx8mp_evk.py |   1 -
 20 files changed, 1696 insertions(+), 47 deletions(-)  create mode 100644

hw/misc/imx8mp_gpc.c create mode 100644 hw/misc/imx8mp_gpr.c create mode 100644 hw/misc/imx8mp_mu.c create mode 100644 hw/misc/imx8mp_src.c create mode 100644 include/hw/misc/imx8mp_gpc.h create mode 100644 include/hw/misc/imx8mp_gpr.h create mode 100644 include/hw/misc/imx8mp_mu.h create mode 100644 include/hw/misc/imx8mp_src.h

--
2.34.1