From nobody Sun Jul 26 11:04:01 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=nxp.com Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783355383817436.46959078750194; Mon, 6 Jul 2026 09:29:43 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wgmC0-0007L1-HP; Mon, 06 Jul 2026 12:29:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgmBy-0007Jh-HS for qemu-devel@nongnu.org; Mon, 06 Jul 2026 12:29:10 -0400 Received: from inva020.nxp.com ([92.121.34.13]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgmBv-0002Mp-IJ for qemu-devel@nongnu.org; Mon, 06 Jul 2026 12:29:10 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id A46201A0095; Mon, 6 Jul 2026 18:29:03 +0200 (CEST) Received: from aprdc01srsp001v.ap-rdc01.nxp.com (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 6A8841A0087; Mon, 6 Jul 2026 18:29:03 +0200 (CEST) Received: from lsv031015.swis.in-blr01.nxp.com (lsv031015.swis.in-blr01.nxp.com [10.12.177.77]) by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id 8D9C3180004C; Tue, 7 Jul 2026 00:29:02 +0800 (+08) From: Gaurav Sharma To: qemu-devel@nongnu.org Cc: pbonzini@redhat.com, peter.maydell@linaro.org, Gaurav Sharma Subject: [PATCHv2 1/7] hw/misc: Add i.MX8MP GPC (General Power Controller) IP Date: Mon, 6 Jul 2026 21:58:53 +0530 Message-Id: <20260706162859.3361063-2-gaurav.sharma_7@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260706162859.3361063-1-gaurav.sharma_7@nxp.com> References: <20260706162859.3361063-1-gaurav.sharma_7@nxp.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Virus-Scanned: ClamAV using ClamSMTP Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=92.121.34.13; envelope-from=gaurav.sharma_7@nxp.com; helo=inva020.nxp.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1783355385572158500 Content-Type: text/plain; charset="utf-8" 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. Signed-off-by: Gaurav Sharma --- 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 diff --git a/docs/system/arm/imx8m.rst b/docs/system/arm/imx8m.rst index afbc33b2f4..00325c2413 100644 --- a/docs/system/arm/imx8m.rst +++ b/docs/system/arm/imx8m.rst @@ -25,6 +25,7 @@ following devices: * 6 General Purpose Timers * Secure Non-Volatile Storage (SNVS) including an RTC * Clock Tree + * General Power Controller (GPC) =20 Boot options ------------ diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 5f5c4899ad..0205a279d9 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -602,6 +602,7 @@ config FSL_IMX8MP select ARM_GIC select FSL_IMX8MP_ANALOG select FSL_IMX8MP_CCM + select FSL_IMX8MP_GPC select IMX select IMX_FEC select IMX_I2C diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c index 7c03ed3c34..d68d816bf1 100644 --- a/hw/arm/fsl-imx8mp.c +++ b/hw/arm/fsl-imx8mp.c @@ -204,6 +204,8 @@ static void fsl_imx8mp_init(Object *obj) =20 object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS); =20 + object_initialize_child(obj, "gpc", &s->gpc, TYPE_IMX8MP_GPC); + for (i =3D 0; i < FSL_IMX8MP_NUM_UARTS; i++) { g_autofree char *name =3D g_strdup_printf("uart%d", i + 1); object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL); @@ -422,6 +424,13 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error= **errp) qdev_get_gpio_in(gicdev, serial_table[i].irq)); } =20 + /* 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); @@ -686,6 +695,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error = **errp) case FSL_IMX8MP_CCM: 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: diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index 1543ee6653..7aedca3614 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -101,6 +101,9 @@ config FSL_IMX8MP_ANALOG config FSL_IMX8MP_CCM bool =20 +config FSL_IMX8MP_GPC + bool + config STM32_RCC bool =20 diff --git a/hw/misc/imx8mp_gpc.c b/hw/misc/imx8mp_gpc.c new file mode 100644 index 0000000000..9d8b93779d --- /dev/null +++ b/hw/misc/imx8mp_gpc.c @@ -0,0 +1,146 @@ +/* + * i.MX 8M Plus GPC(General Power Controller) + * + * Copyright (c) 2026, NXP Semiconductors + * Author: Gaurav Sharma + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + + +#include "qemu/osdep.h" +#include "hw/core/resettable.h" +#include "hw/misc/imx8mp_gpc.h" +#include "migration/vmstate.h" + +#define IMX8MP_GPC_ACK_BIT31 0x80000000u + +#define IMX8MP_GPC_STAT_BUSY_BIT (1u << 5) + +static uint64_t imx8mp_gpc_read(void *opaque, hwaddr offset, unsigned size) +{ + IMX8MPGPCState *s =3D opaque; + uint32_t idx =3D offset >> 2; + + if (size !=3D 4 || (offset & 3) || offset >=3D IMX8MP_GPC_MMIO_SIZE) { + return 0; + } + + /* + * CM7 firmware polls GPC+0xD8 and loops while bit5 is 1. + * Emulate "ready" by forcing bit5 low on reads. + */ + if (idx =3D=3D IMX8MP_GPC_PU_PGC_SW_PUP_REQ) { + return s->regs[idx] & ~IMX8MP_GPC_STAT_BUSY_BIT; + } + + return s->regs[idx]; +} + +static void imx8mp_gpc_write(void *opaque, hwaddr offset, uint64_t value, = unsigned size) +{ + IMX8MPGPCState *s =3D opaque; + uint32_t idx =3D offset >> 2; + + if (size !=3D 4 || (offset & 3) || offset >=3D IMX8MP_GPC_MMIO_SIZE) { + return; + } + + /* + * CM7 firmware sets bit15 in GPC+0x190 and then polls until the value + * becomes negative (bit31 set). Emulate the hardware ACK by forcing + * bit31 high on writes to this register. + */ + if (idx =3D=3D IMX8MP_GPC_POLL_REG) { + s->regs[idx] =3D ((uint32_t)value) | IMX8MP_GPC_ACK_BIT31; + } else { + s->regs[idx] =3D (uint32_t)value; + } + +} + +static const MemoryRegionOps imx8mp_gpc_ops =3D { + .read =3D imx8mp_gpc_read, + .write =3D imx8mp_gpc_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + .unaligned =3D false, + }, +}; + +static ResettablePhases imx8mp_gpc_parent_phases; + +static void imx8mp_gpc_reset_enter(Object *obj, ResetType type) +{ + IMX8MPGPCState *s =3D IMX8MP_GPC(obj); + + if (imx8mp_gpc_parent_phases.enter) { + imx8mp_gpc_parent_phases.enter(obj, type); + } + + memset(s->regs, 0, sizeof(s->regs)); + + /* + * Unblock CM7 firmware polling loop: return a negative value at 0x190. + * Any value with bit31 set works. + */ + s->regs[IMX8MP_GPC_POLL_REG] =3D IMX8MP_GPC_ACK_BIT31; + + /* Default "ready" for the earlier poll at 0xD8: ensure busy bit is cl= ear */ + s->regs[IMX8MP_GPC_PU_PGC_SW_PUP_REQ] =3D 0x00000000; + +} + +static void imx8mp_gpc_reset_hold(Object *obj, ResetType type) +{ + if (imx8mp_gpc_parent_phases.hold) { + imx8mp_gpc_parent_phases.hold(obj, type); + } +} + +static const VMStateDescription imx8mp_gpc_vmstate =3D { + .name =3D TYPE_IMX8MP_GPC, + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, IMX8MPGPCState, IMX8MP_GPC_MMIO_SIZE / = 4), + VMSTATE_END_OF_LIST() + }, +}; + +static void imx8mp_gpc_init(Object *obj) +{ + IMX8MPGPCState *s =3D IMX8MP_GPC(obj); + memory_region_init_io(&s->iomem, obj, &imx8mp_gpc_ops, s, + TYPE_IMX8MP_GPC, IMX8MP_GPC_MMIO_SIZE); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem); +} + +static void imx8mp_gpc_class_init(ObjectClass *oc, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(oc); + ResettableClass *rc =3D RESETTABLE_CLASS(oc); + + resettable_class_set_parent_phases(rc, + imx8mp_gpc_reset_enter, + imx8mp_gpc_reset_hold, + NULL, + &imx8mp_gpc_parent_phases); + + dc->vmsd =3D &imx8mp_gpc_vmstate; + dc->desc =3D "i.MX8MP GPC(General Power Controller)"; +} + +static const TypeInfo imx8mp_gpc_info[] =3D { + { + .name =3D TYPE_IMX8MP_GPC, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(IMX8MPGPCState), + .instance_init =3D imx8mp_gpc_init, + .class_init =3D imx8mp_gpc_class_init, + } +}; + +DEFINE_TYPES(imx8mp_gpc_info); diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 23265f6035..849da705dd 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -59,6 +59,7 @@ system_ss.add(when: 'CONFIG_ECCMEMCTL', if_true: files('e= ccmemctl.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_ana= log.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', diff --git a/include/hw/arm/fsl-imx8mp.h b/include/hw/arm/fsl-imx8mp.h index 3b6183ed1d..51630cfd3b 100644 --- a/include/hw/arm/fsl-imx8mp.h +++ b/include/hw/arm/fsl-imx8mp.h @@ -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/imx_fec.h" #include "hw/core/or-irq.h" #include "hw/pci-host/designware.h" @@ -54,6 +55,7 @@ struct FslImx8mpState { =20 ARMCPU cpu[FSL_IMX8MP_NUM_CPUS]; GICv3State gic; + IMX8MPGPCState gpc; IMXGPTState gpt[FSL_IMX8MP_NUM_GPTS]; IMXGPIOState gpio[FSL_IMX8MP_NUM_GPIOS]; IMX8MPCCMState ccm; diff --git a/include/hw/misc/imx8mp_gpc.h b/include/hw/misc/imx8mp_gpc.h new file mode 100644 index 0000000000..49a040e0c9 --- /dev/null +++ b/include/hw/misc/imx8mp_gpc.h @@ -0,0 +1,34 @@ +/* + * i.MX 8M Plus GPC(General Power Controller) + * + * Copyright (c) 2026, NXP Semiconductors + * Author: Gaurav Sharma + * + * 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 =3D 0x0D8 / 4, + IMX8MP_GPC_POLL_REG =3D 0x190 / 4, +}; + +struct IMX8MPGPCState { + SysBusDevice parent_obj; + MemoryRegion iomem; + uint32_t regs[IMX8MP_GPC_MMIO_SIZE / 4]; +}; + +#endif /* IMX8MP_GPC_H */ --=20 2.34.1 From nobody Sun Jul 26 11:04:01 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=nxp.com Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783355396886897.9573204015798; Mon, 6 Jul 2026 09:29:56 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wgmBz-0007Kb-Df; Mon, 06 Jul 2026 12:29:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgmBy-0007Jp-KN for qemu-devel@nongnu.org; Mon, 06 Jul 2026 12:29:10 -0400 Received: from inva020.nxp.com ([92.121.34.13]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgmBv-0002Mt-IJ for qemu-devel@nongnu.org; Mon, 06 Jul 2026 12:29:10 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 03E1F1A009C; Mon, 6 Jul 2026 18:29:04 +0200 (CEST) Received: from aprdc01srsp001v.ap-rdc01.nxp.com (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id C12AB1A0087; Mon, 6 Jul 2026 18:29:03 +0200 (CEST) Received: from lsv031015.swis.in-blr01.nxp.com (lsv031015.swis.in-blr01.nxp.com [10.12.177.77]) by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id E02BB180007B; Tue, 7 Jul 2026 00:29:02 +0800 (+08) From: Gaurav Sharma To: qemu-devel@nongnu.org Cc: pbonzini@redhat.com, peter.maydell@linaro.org, Gaurav Sharma Subject: [PATCHv2 2/7] hw/misc: Add GPR (General Purpose Register) IP to iMX8MP Date: Mon, 6 Jul 2026 21:58:54 +0530 Message-Id: <20260706162859.3361063-3-gaurav.sharma_7@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260706162859.3361063-1-gaurav.sharma_7@nxp.com> References: <20260706162859.3361063-1-gaurav.sharma_7@nxp.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Virus-Scanned: ClamAV using ClamSMTP Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=92.121.34.13; envelope-from=gaurav.sharma_7@nxp.com; helo=inva020.nxp.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1783355399410158500 Content-Type: text/plain; charset="utf-8" Add IOMUXC General Purpose Registers IP and wire it into the i.MX8MP SoC mo= del. 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 Signed-off-by: Gaurav Sharma --- 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 | 153 +++++++++++++++++++++++++++++++++++ hw/misc/meson.build | 1 + include/hw/arm/fsl-imx8mp.h | 2 + include/hw/misc/imx8mp_gpr.h | 56 +++++++++++++ 8 files changed, 227 insertions(+) create mode 100644 hw/misc/imx8mp_gpr.c create mode 100644 include/hw/misc/imx8mp_gpr.h diff --git a/docs/system/arm/imx8m.rst b/docs/system/arm/imx8m.rst index 00325c2413..1e110bc810 100644 --- a/docs/system/arm/imx8m.rst +++ b/docs/system/arm/imx8m.rst @@ -26,6 +26,7 @@ following devices: * Secure Non-Volatile Storage (SNVS) including an RTC * Clock Tree * General Power Controller (GPC) + * General Purpose Register (GPR) =20 Boot options ------------ diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 0205a279d9..382819fb7b 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -603,6 +603,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 diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c index d68d816bf1..c4aafbdc1c 100644 --- a/hw/arm/fsl-imx8mp.c +++ b/hw/arm/fsl-imx8mp.c @@ -206,6 +206,8 @@ static void fsl_imx8mp_init(Object *obj) =20 object_initialize_child(obj, "gpc", &s->gpc, TYPE_IMX8MP_GPC); =20 + object_initialize_child(obj, "gpr", &s->gpr, TYPE_IMX8MP_GPR); + for (i =3D 0; i < FSL_IMX8MP_NUM_UARTS; i++) { g_autofree char *name =3D 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) sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpc), 0, fsl_imx8mp_memmap[FSL_IMX8MP_GPC].addr); =20 + /* 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); @@ -701,6 +710,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: diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index 7aedca3614..1d09474545 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -104,6 +104,9 @@ config FSL_IMX8MP_CCM config FSL_IMX8MP_GPC bool =20 +config FSL_IMX8MP_GPR + bool + config STM32_RCC bool =20 diff --git a/hw/misc/imx8mp_gpr.c b/hw/misc/imx8mp_gpr.c new file mode 100644 index 0000000000..d79476104b --- /dev/null +++ b/hw/misc/imx8mp_gpr.c @@ -0,0 +1,153 @@ +/* + * i.MX 8M Plus IOMUXC GPR + * + * Copyright (c) 2026, NXP Semiconductors + * Author: Gaurav Sharma + + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/misc/imx8mp_gpr.h" +#include "hw/core/irq.h" +#include "hw/core/resettable.h" +#include "migration/vmstate.h" + +#define IMX8MP_GPR22_OFF 0x58 +#define IMX8MP_GPR22_CM7_CPUWAIT_BIT (1u << 0) + +static inline void imx8mp_gpr_update_cm7_run(IMX8MPGPRState *s, uint32_t g= pr22) +{ + /* CPUWAIT=3D0 =3D> run, CPUWAIT=3D1 =3D> stop */ + bool run =3D ((gpr22 & IMX8MP_GPR22_CM7_CPUWAIT_BIT) =3D=3D 0); + qemu_set_irq(s->cm7_run_irq, run); +} + +static uint64_t imx8mp_gpr_read(void *opaque, hwaddr offset, unsigned size) +{ + IMX8MPGPRState *s =3D opaque; + + return s->gpr[offset >> 2]; +} + +static void imx8mp_gpr_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + IMX8MPGPRState *s =3D opaque; + + s->gpr[offset >> 2] =3D (uint32_t)value; + + /* Watch GPR22 bit0 (CM7_CPUWAIT) transitions */ + if (offset =3D=3D IMX8MP_GPR22_OFF) { + imx8mp_gpr_update_cm7_run(s, s->gpr[IMX8MP_GPR22_OFF >> 2]); + } + +} + +static const MemoryRegionOps imx8mp_gpr_ops =3D { + .read =3D imx8mp_gpr_read, + .write =3D imx8mp_gpr_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .impl =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + .unaligned =3D false, + }, +}; + +static ResettablePhases imx8mp_gpr_parent_phases; + +static void imx8mp_gpr_reset_enter(Object *obj, ResetType type) +{ + IMX8MPGPRState *s =3D IMX8MP_GPR(obj); + + if (imx8mp_gpr_parent_phases.enter) { + imx8mp_gpr_parent_phases.enter(obj, type); + } + + memset(s->gpr, 0, sizeof(s->gpr)); + + s->gpr[IOMUXC_GPR_GPR0] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR1] =3D 0x00010000; + s->gpr[IOMUXC_GPR_GPR2] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR3] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR4] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR5] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR6] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR7] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR8] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR9] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR10] =3D 0x00000008; + s->gpr[IOMUXC_GPR_GPR11] =3D 0x00000200; + s->gpr[IOMUXC_GPR_GPR12] =3D 0x00004000; + s->gpr[IOMUXC_GPR_GPR13] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR14] =3D 0x03494000; + s->gpr[IOMUXC_GPR_GPR15] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR16] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR17] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR18] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR19] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR20] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR21] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR22] =3D 0x00000001; + s->gpr[IOMUXC_GPR_GPR23] =3D 0x00000000; + s->gpr[IOMUXC_GPR_GPR24] =3D 0x00000000; +} + +static void imx8mp_gpr_reset_hold(Object *obj, ResetType type) +{ + IMX8MPGPRState *s =3D IMX8MP_GPR(obj); + + if (imx8mp_gpr_parent_phases.hold) { + imx8mp_gpr_parent_phases.hold(obj, type); + } + + /* Drive cm7_run_irq output to match reset value of CPUWAIT */ + imx8mp_gpr_update_cm7_run(s, s->gpr[IMX8MP_GPR22_OFF >> 2]); +} + +static const VMStateDescription imx8mp_gpr_vmstate =3D { + .name =3D TYPE_IMX8MP_GPR, + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32_ARRAY(gpr, IMX8MPGPRState, IOMUXC_GPR_MAX), + VMSTATE_END_OF_LIST() + }, +}; + +static void imx8mp_gpr_init(Object *obj) +{ + IMX8MPGPRState *s =3D IMX8MP_GPR(obj); + memory_region_init_io(&s->mmio, obj, &imx8mp_gpr_ops, s, + TYPE_IMX8MP_GPR, sizeof(s->gpr)); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->cm7_run_irq); +} + +static void imx8mp_gpr_class_init(ObjectClass *oc, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(oc); + ResettableClass *rc =3D RESETTABLE_CLASS(oc); + + resettable_class_set_parent_phases(rc, + imx8mp_gpr_reset_enter, + imx8mp_gpr_reset_hold, + NULL, + &imx8mp_gpr_parent_phases); + + dc->vmsd =3D &imx8mp_gpr_vmstate; + dc->desc =3D "i.MX8MP IOMUXC GPR"; +} + +static const TypeInfo imx8mp_gpr_info[] =3D { + { + .name =3D TYPE_IMX8MP_GPR, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(IMX8MPGPRState), + .instance_init =3D imx8mp_gpr_init, + .class_init =3D imx8mp_gpr_class_init, + } +}; + +DEFINE_TYPES(imx8mp_gpr_info); diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 849da705dd..bc2996c165 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -60,6 +60,7 @@ system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exy= nos4210_pmu.c', 'exynos system_ss.add(when: 'CONFIG_FSL_IMX8MP_ANALOG', if_true: files('imx8mp_ana= log.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', diff --git a/include/hw/arm/fsl-imx8mp.h b/include/hw/arm/fsl-imx8mp.h index 51630cfd3b..b3aca1f692 100644 --- a/include/hw/arm/fsl-imx8mp.h +++ b/include/hw/arm/fsl-imx8mp.h @@ -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/imx_fec.h" #include "hw/core/or-irq.h" #include "hw/pci-host/designware.h" @@ -56,6 +57,7 @@ struct FslImx8mpState { ARMCPU cpu[FSL_IMX8MP_NUM_CPUS]; GICv3State gic; IMX8MPGPCState gpc; + IMX8MPGPRState gpr; IMXGPTState gpt[FSL_IMX8MP_NUM_GPTS]; IMXGPIOState gpio[FSL_IMX8MP_NUM_GPIOS]; IMX8MPCCMState ccm; diff --git a/include/hw/misc/imx8mp_gpr.h b/include/hw/misc/imx8mp_gpr.h new file mode 100644 index 0000000000..4a0c7d8583 --- /dev/null +++ b/include/hw/misc/imx8mp_gpr.h @@ -0,0 +1,56 @@ +/* + * i.MX 8M Plus IOMUXC GPR + * + * Copyright (c) 2026, NXP Semiconductors + * Author: Gaurav Sharma + + * SPDX-License-Identifier: GPL-2.0-or-later + */ + + +#ifndef IMX8MP_GPR_H +#define IMX8MP_GPR_H + +#include "hw/core/sysbus.h" +#include "qom/object.h" + +#define TYPE_IMX8MP_GPR "imx8mp.gpr" +OBJECT_DECLARE_SIMPLE_TYPE(IMX8MPGPRState, IMX8MP_GPR) + +enum IMX8MPGPRRegisters { + IOMUXC_GPR_GPR0 =3D 0x000 / 4, + IOMUXC_GPR_GPR1 =3D 0x004 / 4, + IOMUXC_GPR_GPR2 =3D 0x008 / 4, + IOMUXC_GPR_GPR3 =3D 0x00C / 4, + IOMUXC_GPR_GPR4 =3D 0x010 / 4, + IOMUXC_GPR_GPR5 =3D 0x014 / 4, + IOMUXC_GPR_GPR6 =3D 0x018 / 4, + IOMUXC_GPR_GPR7 =3D 0x01C / 4, + IOMUXC_GPR_GPR8 =3D 0x020 / 4, + IOMUXC_GPR_GPR9 =3D 0x024 / 4, + IOMUXC_GPR_GPR10 =3D 0x028 / 4, + IOMUXC_GPR_GPR11 =3D 0x02C / 4, + IOMUXC_GPR_GPR12 =3D 0x030 / 4, + IOMUXC_GPR_GPR13 =3D 0x034 / 4, + IOMUXC_GPR_GPR14 =3D 0x038 / 4, + IOMUXC_GPR_GPR15 =3D 0x03C / 4, + IOMUXC_GPR_GPR16 =3D 0x040 / 4, + IOMUXC_GPR_GPR17 =3D 0x044 / 4, + IOMUXC_GPR_GPR18 =3D 0x048 / 4, + IOMUXC_GPR_GPR19 =3D 0x04C / 4, + IOMUXC_GPR_GPR20 =3D 0x050 / 4, + IOMUXC_GPR_GPR21 =3D 0x054 / 4, + IOMUXC_GPR_GPR22 =3D 0x058 / 4, + IOMUXC_GPR_GPR23 =3D 0x05C / 4, + IOMUXC_GPR_GPR24 =3D 0x060 / 4, + IOMUXC_GPR_MAX, +}; + +struct IMX8MPGPRState { + SysBusDevice parent_obj; + MemoryRegion mmio; + qemu_irq cm7_run_irq; + uint32_t gpr[IOMUXC_GPR_MAX]; +}; + +#endif /* IMX8MP_GPR_H */ --=20 2.34.1 From nobody Sun Jul 26 11:04:01 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=nxp.com Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783355395004156.24860204999038; Mon, 6 Jul 2026 09:29:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wgmC0-0007L6-T0; Mon, 06 Jul 2026 12:29:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgmBz-0007KK-0w for qemu-devel@nongnu.org; Mon, 06 Jul 2026 12:29:11 -0400 Received: from inva020.nxp.com ([92.121.34.13]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgmBv-0002N0-IL for qemu-devel@nongnu.org; Mon, 06 Jul 2026 12:29:10 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 92FD81A00A2; Mon, 6 Jul 2026 18:29:04 +0200 (CEST) Received: from aprdc01srsp001v.ap-rdc01.nxp.com (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 3288C1A0087; Mon, 6 Jul 2026 18:29:04 +0200 (CEST) Received: from lsv031015.swis.in-blr01.nxp.com (lsv031015.swis.in-blr01.nxp.com [10.12.177.77]) by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id 40C301800086; Tue, 7 Jul 2026 00:29:03 +0800 (+08) From: Gaurav Sharma To: qemu-devel@nongnu.org Cc: pbonzini@redhat.com, peter.maydell@linaro.org, Bernhard Beschow , Gaurav Sharma Subject: [PATCHv2 3/7] hw/misc: Add SRC (System Reset Controller) to i.MX8MP Date: Mon, 6 Jul 2026 21:58:55 +0530 Message-Id: <20260706162859.3361063-4-gaurav.sharma_7@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260706162859.3361063-1-gaurav.sharma_7@nxp.com> References: <20260706162859.3361063-1-gaurav.sharma_7@nxp.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Virus-Scanned: ClamAV using ClamSMTP Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=92.121.34.13; envelope-from=gaurav.sharma_7@nxp.com; helo=inva020.nxp.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1783355397193158500 Content-Type: text/plain; charset="utf-8" From: Bernhard Beschow 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. Signed-off-by: Bernhard Beschow Signed-off-by: Gaurav Sharma --- docs/system/arm/imx8m.rst | 1 + hw/arm/Kconfig | 1 + hw/arm/fsl-imx8mp.c | 10 ++ hw/misc/Kconfig | 3 + hw/misc/imx8mp_src.c | 275 +++++++++++++++++++++++++++++++++++ hw/misc/meson.build | 1 + hw/misc/trace-events | 5 + include/hw/arm/fsl-imx8mp.h | 2 + include/hw/misc/imx8mp_src.h | 31 ++++ 9 files changed, 329 insertions(+) create mode 100644 hw/misc/imx8mp_src.c create mode 100644 include/hw/misc/imx8mp_src.h diff --git a/docs/system/arm/imx8m.rst b/docs/system/arm/imx8m.rst index 1e110bc810..49c100c4b1 100644 --- a/docs/system/arm/imx8m.rst +++ b/docs/system/arm/imx8m.rst @@ -27,6 +27,7 @@ following devices: * Clock Tree * General Power Controller (GPC) * General Purpose Register (GPR) + * System Reset Controller (SRC) =20 Boot options ------------ diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 382819fb7b..382b454b49 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -604,6 +604,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 diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c index c4aafbdc1c..168fcb0334 100644 --- a/hw/arm/fsl-imx8mp.c +++ b/hw/arm/fsl-imx8mp.c @@ -208,6 +208,8 @@ static void fsl_imx8mp_init(Object *obj) =20 object_initialize_child(obj, "gpr", &s->gpr, TYPE_IMX8MP_GPR); =20 + object_initialize_child(obj, "src", &s->src, TYPE_IMX8MP_SRC); + for (i =3D 0; i < FSL_IMX8MP_NUM_UARTS; i++) { g_autofree char *name =3D g_strdup_printf("uart%d", i + 1); object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL); @@ -426,6 +428,13 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error= **errp) qdev_get_gpio_in(gicdev, serial_table[i].irq)); } =20 + /* 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; @@ -716,6 +725,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: diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index 1d09474545..0f63a85924 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -107,6 +107,9 @@ config FSL_IMX8MP_GPC config FSL_IMX8MP_GPR bool =20 +config FSL_IMX8MP_SRC + bool + config STM32_RCC bool =20 diff --git a/hw/misc/imx8mp_src.c b/hw/misc/imx8mp_src.c new file mode 100644 index 0000000000..8e5e357775 --- /dev/null +++ b/hw/misc/imx8mp_src.c @@ -0,0 +1,275 @@ +/* + * i.MX 8M Plus System Reset Controller + * + * Copyright (c) 2025 Bernhard Beschow + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/misc/imx8mp_src.h" +#include "hw/core/resettable.h" +#include "hw/core/registerfields.h" +#include "migration/vmstate.h" +#include "qemu/log.h" +#include "trace.h" + +REG32(SRC_SCR, 0x0000) + +REG32(SRC_A53RCR0, 0x0004) + +REG32(SRC_A53RCR1, 0x0008) + +REG32(SRC_M7RCR, 0x000c) +REG32(SRC_SUPERMIX_RCR, 0x0018) +REG32(SRC_AUDIOMIX_RCR, 0x001c) +REG32(SRC_USBPHY1_RCR, 0x0020) +REG32(SRC_USBPHY2_RCR, 0x0024) +REG32(SRC_MLMIX_RCR, 0x0028) +REG32(SRC_PCIEPHY_RCR, 0x002c) +REG32(SRC_HDMI_RCR, 0x0030) +REG32(SRC_MEDIA_RCR, 0x0034) +REG32(SRC_GPU2D_RCR, 0x0038) +REG32(SRC_GPU3D_RCR, 0x003c) +REG32(SRC_GPU_RCR, 0x0040) +REG32(SRC_VPU_RCR, 0x0044) +REG32(SRC_VPU_G1_RCR, 0x0048) +REG32(SRC_VPU_G2_RCR, 0x004c) +REG32(SRC_VPUVC8KE_RCR, 0x0050) +REG32(SRC_NOC_RCR, 0x0054) +REG32(SRC_SBMR1, 0x0058) +REG32(SRC_SRSR, 0x005c) +REG32(SRC_SISR, 0x0068) +REG32(SRC_SIMR, 0x006c) + +REG32(SRC_SBMR2, 0x0070) + +REG32(SRC_GPR1, 0x0074) +REG32(SRC_GPR2, 0x0078) +REG32(SRC_GPR3, 0x007c) +REG32(SRC_GPR4, 0x0080) +REG32(SRC_GPR5, 0x0084) +REG32(SRC_GPR6, 0x0088) +REG32(SRC_GPR7, 0x008c) +REG32(SRC_GPR8, 0x0090) +REG32(SRC_GPR9, 0x0094) +REG32(SRC_GPR10, 0x0098) +REG32(SRC_DDRC_RCR, 0x1000) +REG32(SRC_HDMIPHY_RCR, 0x1008) +REG32(SRC_MIPIPHY1_RCR, 0x100c) +REG32(SRC_MIPIPHY2_RCR, 0x1010) +REG32(SRC_HSIO_RCR, 0x1014) +REG32(SRC_MEDIAISPDWP_RCR, 0x1018) + +static const char *fsl_imx8mp_src_reg_name(uint32_t reg) +{ + switch (reg) { + case R_SRC_SCR: + return " (SRC_SCR)"; + case R_SRC_A53RCR0: + return " (SRC_A53RCR0)"; + case R_SRC_A53RCR1: + return " (SRC_A53RCR1)"; + case R_SRC_M7RCR: + return " (SRC_M7RCR)"; + case R_SRC_SUPERMIX_RCR: + return " (SRC_SUPERMIX_RCR)"; + case R_SRC_AUDIOMIX_RCR: + return " (SRC_AUDIOMIX_RCR)"; + case R_SRC_USBPHY1_RCR: + return " (SRC_USBPHY1_RCR)"; + case R_SRC_USBPHY2_RCR: + return " (SRC_USBPHY2_RCR)"; + case R_SRC_MLMIX_RCR: + return " (SRC_MLMIX_RCR)"; + case R_SRC_PCIEPHY_RCR: + return " (SRC_PCIEPHY_RCR)"; + case R_SRC_HDMI_RCR: + return " (SRC_HDMI_RCR)"; + case R_SRC_MEDIA_RCR: + return " (SRC_MEDIA_RCR)"; + case R_SRC_GPU2D_RCR: + return " (SRC_GPU2D_RCR)"; + case R_SRC_GPU3D_RCR: + return " (SRC_GPU3D_RCR)"; + case R_SRC_GPU_RCR: + return " (SRC_GPU_RCR)"; + case R_SRC_VPU_RCR: + return " (SRC_VPU_RCR)"; + case R_SRC_VPU_G1_RCR: + return " (SRC_VPU_G1_RCR)"; + case R_SRC_VPU_G2_RCR: + return " (SRC_VPU_G2_RCR)"; + case R_SRC_VPUVC8KE_RCR: + return " (SRC_VPUVC8KE_RCR)"; + case R_SRC_NOC_RCR: + return " (SRC_NOC_RCR)"; + case R_SRC_SBMR1: + return " (SRC_SBMR1)"; + case R_SRC_SRSR: + return " (SRC_SRSR)"; + case R_SRC_SISR: + return " (SRC_SISR)"; + case R_SRC_SIMR: + return " (SRC_SIMR)"; + case R_SRC_SBMR2: + return " (SRC_SBMR2)"; + case R_SRC_GPR1: + return " (SRC_GPR1)"; + case R_SRC_GPR2: + return " (SRC_GPR2)"; + case R_SRC_GPR3: + return " (SRC_GPR3)"; + case R_SRC_GPR4: + return " (SRC_GPR4)"; + case R_SRC_GPR5: + return " (SRC_GPR5)"; + case R_SRC_GPR6: + return " (SRC_GPR6)"; + case R_SRC_GPR7: + return " (SRC_GPR7)"; + case R_SRC_GPR8: + return " (SRC_GPR8)"; + case R_SRC_GPR9: + return " (SRC_GPR9)"; + case R_SRC_GPR10: + return " (SRC_GPR10)"; + case R_SRC_DDRC_RCR: + return " (SRC_DDRC_RCR)"; + case R_SRC_HDMIPHY_RCR: + return " (SRC_HDMIPHY_RCR)"; + case R_SRC_MIPIPHY1_RCR: + return " (SRC_MIPIPHY1_RCR)"; + case R_SRC_MIPIPHY2_RCR: + return " (SRC_MIPIPHY2_RCR)"; + case R_SRC_HSIO_RCR: + return " (SRC_HSIO_RCR)"; + case R_SRC_MEDIAISPDWP_RCR: + return " (SRC_MEDIAISPDWP_RCR)"; + default: + return " (reserved)"; + } +} + +static uint64_t fsl_imx8mp_src_read(void *opaque, hwaddr offset, + unsigned size) +{ + FslImx8mpSrcState *s =3D opaque; + const uint32_t reg =3D offset / 4; + uint32_t value =3D 0; + + switch (reg) { + default: + if (reg < FSL_IMX8MP_SRC_NUM_REGS) { + value =3D s->regs[reg]; + } + qemu_log_mask(LOG_UNIMP, "[%s]%s: Unimplemented register at offset= 0x%" + HWADDR_PRIx "\n", TYPE_IMX8MP_SRC, __func__, + offset); + break; + } + + trace_fsl_imx8mp_src_read(offset, fsl_imx8mp_src_reg_name(reg), value); + + return value; +} + +static ResettablePhases imx8mp_src_parent_phases; + +static void imx8mp_src_reset_enter(Object *obj, ResetType type) +{ + FslImx8mpSrcState *s =3D IMX8MP_SRC(obj); + + if (imx8mp_src_parent_phases.enter) { + imx8mp_src_parent_phases.enter(obj, type); + } + + memset(s->regs, 0, sizeof(s->regs)); + + /* + * Default CM7 STOP state for Linux imx-rproc MMIO mode detection. + */ + s->regs[R_SRC_M7RCR] =3D 0x000000A8; +} + +static void fsl_imx8mp_src_write(void *opaque, hwaddr offset, uint64_t val= ue, + unsigned size) +{ + FslImx8mpSrcState *s =3D opaque; + const uint32_t reg =3D offset / 4; + + switch (reg) { + default: + if (reg < FSL_IMX8MP_SRC_NUM_REGS) { + s->regs[reg] =3D value; + } + qemu_log_mask(LOG_UNIMP, "[%s]%s: Unimplemented register at offset= 0x%" + HWADDR_PRIx "\n", TYPE_IMX8MP_SRC, __func__, + offset); + break; + } + + trace_fsl_imx8mp_src_write(offset, fsl_imx8mp_src_reg_name(reg), value= ); +} + +static const struct MemoryRegionOps imx8mp_src_ops =3D { + .read =3D fsl_imx8mp_src_read, + .write =3D fsl_imx8mp_src_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid =3D { + /* + * Our device would not work correctly if the guest was doing + * unaligned access. This might not be a limitation on the real + * device but in practice there is no reason for a guest to access + * this device unaligned. + */ + .min_access_size =3D 4, + .max_access_size =3D 4, + .unaligned =3D false, + }, +}; + +static void imx8mp_src_realize(DeviceState *dev, Error **errp) +{ + FslImx8mpSrcState *s =3D IMX8MP_SRC(dev); + + memory_region_init_io(&s->iomem, OBJECT(dev), &imx8mp_src_ops, s, + TYPE_IMX8MP_SRC, 0x1000); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); +} + +static const VMStateDescription imx8mp_src_vmstate =3D { + .name =3D TYPE_IMX8MP_SRC, + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, FslImx8mpSrcState, FSL_IMX8MP_SRC_NUM_R= EGS), + VMSTATE_END_OF_LIST() + }, +}; + +static void imx8mp_src_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + + resettable_class_set_parent_phases(rc, + imx8mp_src_reset_enter, + NULL, + NULL, + &imx8mp_src_parent_phases); + dc->realize =3D imx8mp_src_realize; + dc->vmsd =3D &imx8mp_src_vmstate; + dc->desc =3D "i.MX 8M Plus System Reset Controller"; +} + +static const TypeInfo imx8mp_src_types[] =3D { + { + .name =3D TYPE_IMX8MP_SRC, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(FslImx8mpSrcState), + .class_init =3D imx8mp_src_class_init, + }, +}; + +DEFINE_TYPES(imx8mp_src_types) diff --git a/hw/misc/meson.build b/hw/misc/meson.build index bc2996c165..f71323bde7 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -61,6 +61,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', diff --git a/hw/misc/trace-events b/hw/misc/trace-events index 99910fc068..7e67e52ea3 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -129,6 +129,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" =20 +# 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] <=3D 0x%" PRIx32 + # mos6522.c mos6522_set_counter(int index, unsigned int val) "T%d.counter=3D%d" mos6522_get_next_irq_time(uint16_t latch, int64_t d, int64_t delta) "latch= =3D%d counter=3D0x%"PRIx64 " delta_next=3D0x%"PRIx64 diff --git a/include/hw/arm/fsl-imx8mp.h b/include/hw/arm/fsl-imx8mp.h index b3aca1f692..c6c133cc05 100644 --- a/include/hw/arm/fsl-imx8mp.h +++ b/include/hw/arm/fsl-imx8mp.h @@ -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/imx_fec.h" #include "hw/core/or-irq.h" #include "hw/pci-host/designware.h" @@ -64,6 +65,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; diff --git a/include/hw/misc/imx8mp_src.h b/include/hw/misc/imx8mp_src.h new file mode 100644 index 0000000000..2a8c1ca2bd --- /dev/null +++ b/include/hw/misc/imx8mp_src.h @@ -0,0 +1,31 @@ +/* + * i.MX 8M Plus System Reset Controller + * + * Copyright (c) 2025 Bernhard Beschow + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef FSL_IMX8MP_SRC_H +#define FSL_IMX8MP_SRC_H + +#include "hw/core/sysbus.h" +#include "system/memory.h" +#include "qom/object.h" + +#define TYPE_IMX8MP_SRC "fsl-imx8mp-src" +OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mpSrcState, IMX8MP_SRC) + +#define FSL_IMX8MP_SRC_NUM_REGS (0x100 / 4) + +struct FslImx8mpSrcState { + SysBusDevice parent_obj; + + MemoryRegion iomem; + + uint32_t regs[FSL_IMX8MP_SRC_NUM_REGS]; +}; + +void imx8mp_src_start_cpu(FslImx8mpSrcState *s, int cpuid); + +#endif /* FSL_IMX8MP_SRC_H */ --=20 2.34.1 From nobody Sun Jul 26 11:04:01 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=nxp.com Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783355417281844.1369809219486; Mon, 6 Jul 2026 09:30:17 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wgmBz-0007KH-0M; Mon, 06 Jul 2026 12:29:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgmBx-0007JX-KD for qemu-devel@nongnu.org; Mon, 06 Jul 2026 12:29:09 -0400 Received: from inva020.nxp.com ([92.121.34.13]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgmBv-0002N4-0P for qemu-devel@nongnu.org; Mon, 06 Jul 2026 12:29:09 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id E577B1A00A8; Mon, 6 Jul 2026 18:29:04 +0200 (CEST) Received: from aprdc01srsp001v.ap-rdc01.nxp.com (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 853B61A00A0; Mon, 6 Jul 2026 18:29:04 +0200 (CEST) Received: from lsv031015.swis.in-blr01.nxp.com (lsv031015.swis.in-blr01.nxp.com [10.12.177.77]) by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id A89B71800087; Tue, 7 Jul 2026 00:29:03 +0800 (+08) From: Gaurav Sharma To: qemu-devel@nongnu.org Cc: pbonzini@redhat.com, peter.maydell@linaro.org, Gaurav Sharma Subject: [PATCHv2 4/7] hw/misc: Add MU (Messaging Unit) IP to i.MX8MP device model Date: Mon, 6 Jul 2026 21:58:56 +0530 Message-Id: <20260706162859.3361063-5-gaurav.sharma_7@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260706162859.3361063-1-gaurav.sharma_7@nxp.com> References: <20260706162859.3361063-1-gaurav.sharma_7@nxp.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Virus-Scanned: ClamAV using ClamSMTP Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=92.121.34.13; envelope-from=gaurav.sharma_7@nxp.com; helo=inva020.nxp.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1783355419322158500 Content-Type: text/plain; charset="utf-8" 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. Signed-off-by: Gaurav Sharma --- docs/system/arm/imx8m.rst | 1 + hw/arm/Kconfig | 1 + hw/arm/fsl-imx8mp.c | 39 +++++ hw/misc/Kconfig | 3 + hw/misc/imx8mp_mu.c | 328 ++++++++++++++++++++++++++++++++++++ hw/misc/meson.build | 1 + include/hw/arm/fsl-imx8mp.h | 10 ++ include/hw/misc/imx8mp_mu.h | 53 ++++++ 8 files changed, 436 insertions(+) create mode 100644 hw/misc/imx8mp_mu.c create mode 100644 include/hw/misc/imx8mp_mu.h diff --git a/docs/system/arm/imx8m.rst b/docs/system/arm/imx8m.rst index 49c100c4b1..c482bf180f 100644 --- a/docs/system/arm/imx8m.rst +++ b/docs/system/arm/imx8m.rst @@ -28,6 +28,7 @@ following devices: * General Power Controller (GPC) * General Purpose Register (GPR) * System Reset Controller (SRC) + * Messaging Unit (MU) =20 Boot options ------------ diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 382b454b49..71abcb7ef1 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -605,6 +605,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 diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c index 168fcb0334..eec83deced 100644 --- a/hw/arm/fsl-imx8mp.c +++ b/hw/arm/fsl-imx8mp.c @@ -210,6 +210,16 @@ static void fsl_imx8mp_init(Object *obj) =20 object_initialize_child(obj, "src", &s->src, TYPE_IMX8MP_SRC); =20 + /* + * MU instances: MU_1..MU_3, each with A/B endpoints + */ + for (i =3D 0; i < FSL_IMX8MP_NUM_MU; i++) { + g_autofree char *name_a =3D g_strdup_printf("mu%d_a", i + 1); + g_autofree char *name_b =3D g_strdup_printf("mu%d_b", i + 1); + object_initialize_child(obj, name_a, &s->mu[i].a, TYPE_IMX8MP_MU); + object_initialize_child(obj, name_b, &s->mu[i].b, TYPE_IMX8MP_MU); + } + for (i =3D 0; i < FSL_IMX8MP_NUM_UARTS; i++) { g_autofree char *name =3D g_strdup_printf("uart%d", i + 1); object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL); @@ -495,6 +505,34 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error= **errp) } } =20 + /* MU */ + static const int mu_mmio_map[FSL_IMX8MP_NUM_MU][2] =3D { + [0] =3D { FSL_IMX8MP_MU_1_A, FSL_IMX8MP_MU_1_B }, + [1] =3D { FSL_IMX8MP_MU_2_A, FSL_IMX8MP_MU_2_B }, + [2] =3D { FSL_IMX8MP_MU_3_A, FSL_IMX8MP_MU_3_B }, + }; + + for (i =3D 0; i < FSL_IMX8MP_NUM_MU; i++) { + hwaddr addr_a =3D fsl_imx8mp_memmap[mu_mmio_map[i][0]].addr; + hwaddr addr_b =3D fsl_imx8mp_memmap[mu_mmio_map[i][1]].addr; + + if (!sysbus_realize(SYS_BUS_DEVICE(&s->mu[i].a), errp)) { + return; + } + sysbus_mmio_map(SYS_BUS_DEVICE(&s->mu[i].a), 0, addr_a); + + if (!sysbus_realize(SYS_BUS_DEVICE(&s->mu[i].b), errp)) { + return; + } + sysbus_mmio_map(SYS_BUS_DEVICE(&s->mu[i].b), 0, addr_b); + + s->mu[i].a.peer =3D &s->mu[i].b; + s->mu[i].b.peer =3D &s->mu[i].a; + } + + sysbus_connect_irq(SYS_BUS_DEVICE(&s->mu[0].a), 0, + qdev_get_gpio_in(gicdev, FSL_IMX8MP_MU1_A_IRQ)); + /* I2Cs */ for (i =3D 0; i < FSL_IMX8MP_NUM_I2CS; i++) { struct { @@ -720,6 +758,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error = **errp) case FSL_IMX8MP_ENET1: case FSL_IMX8MP_I2C1 ... FSL_IMX8MP_I2C6: case FSL_IMX8MP_IOMUXC_GPR: + case FSL_IMX8MP_MU_1_A ... FSL_IMX8MP_MU_3_B: case FSL_IMX8MP_OCRAM: case FSL_IMX8MP_PCIE1: case FSL_IMX8MP_PCIE_PHY1: diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index 0f63a85924..c1437ad233 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -110,6 +110,9 @@ config FSL_IMX8MP_GPR config FSL_IMX8MP_SRC bool =20 +config FSL_IMX8MP_MU + bool + config STM32_RCC bool =20 diff --git a/hw/misc/imx8mp_mu.c b/hw/misc/imx8mp_mu.c new file mode 100644 index 0000000000..adaaf26eca --- /dev/null +++ b/hw/misc/imx8mp_mu.c @@ -0,0 +1,328 @@ +/* + * NXP i.MX Messaging Unit (MU) + * + * Copyright (c) 2026, NXP Semiconductors + * Author: Gaurav Sharma + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + + +#include "qemu/osdep.h" +#include "qemu/log.h" + +#include "hw/misc/imx8mp_mu.h" +#include "hw/core/irq.h" +#include "hw/core/qdev-properties.h" +#include "hw/core/resettable.h" +#include "migration/vmstate.h" + + +#define MU_SR_RFn_V1(x) (1u << (24 + (3 - (x)))) +#define MU_SR_TEn_V1(x) (1u << (20 + (3 - (x)))) +#define MU_SR_GIPn_V1(x) (1u << (28 + (3 - (x)))) +#define MU_CR_RIEn_V1(x) (1u << (24 + (3 - (x)))) +#define MU_CR_TIEn_V1(x) (1u << (20 + (3 - (x)))) +#define MU_CR_GIEn_V1(x) (1u << (28 + (3 - (x)))) +#define MU_CR_GIRn_V1(x) (1u << (16 + (3 - (x)))) + + +static inline IMX8MPMUState *imx8mp_mu_peer(IMX8MPMUState *s) +{ + return s->peer; +} + +static void imx8mp_mu_update_irq(IMX8MPMUState *s) +{ + + bool pending =3D false; + uint32_t sr =3D s->mu[MU_SR]; + uint32_t cr =3D s->mu[MU_CR]; + + for (int i =3D 0; i < 4; i++) { + /* TX done interrupt (TEn + TIEn) */ + if ((sr & MU_SR_TEn_V1(i)) && (cr & MU_CR_TIEn_V1(i))) { + pending =3D true; + break; + } + + /* RX data interrupt (RFn + RIEn) */ + if ((sr & MU_SR_RFn_V1(i)) && (cr & MU_CR_RIEn_V1(i))) { + pending =3D true; + break; + } + + /* Doorbell interrupt (GIPn + GIEn) - keep for completeness */ + if ((sr & MU_SR_GIPn_V1(i)) && (cr & MU_CR_GIEn_V1(i))) { + pending =3D true; + break; + } + } + qemu_set_irq(s->irq, pending); +} + +static uint64_t imx8mp_mu_read(void *opaque, hwaddr offset, unsigned size) +{ + IMX8MPMUState *s =3D opaque; + + if (size !=3D 4) { + qemu_log_mask(LOG_GUEST_ERROR, + "imx8mp_mu: invalid read size %u @0x%" HWADDR_PRIx "= \n", + size, offset); + return 0; + } + + if (offset & 3) { + qemu_log_mask(LOG_GUEST_ERROR, + "imx8mp_mu: unaligned read @0x%" + HWADDR_PRIx "\n", offset); + return 0; + } + + if (offset < MU_RR0) { + unsigned tr =3D offset >> 2; + if (s->strict_access) { + qemu_log_mask(LOG_GUEST_ERROR, + "imx8mp_mu: strict: read from TR%u" + " @0x%" HWADDR_PRIx "\n", tr, offset); + return 0; + } + return s->mu[MU_TR0 + tr]; + } + + if (offset >=3D MU_RR0 && offset < MU_SR) { + unsigned rr =3D (offset - MU_RR0) >> 2; + uint32_t v =3D s->mu[MU_RR0 + rr]; + IMX8MPMUState *p =3D imx8mp_mu_peer(s); + + if (s->strict_access && !(s->mu[MU_SR] & MU_SR_RFn_V1(rr))) { + qemu_log_mask(LOG_GUEST_ERROR, + "imx8mp_mu: strict: read from empty RR%u" + " @0x%" HWADDR_PRIx "\n", rr, offset); + return 0; + } + + if (s->mu[MU_SR] & MU_SR_RFn_V1(rr)) { + s->mu[MU_SR] &=3D ~MU_SR_RFn_V1(rr); + if (p) { + p->mu[MU_SR] |=3D MU_SR_TEn_V1(rr); + imx8mp_mu_update_irq(p); + } + } + imx8mp_mu_update_irq(s); + return v; + } + + switch (offset) { + case MU_SR: + return s->mu[MU_SR]; + case MU_CR: + return s->mu[MU_CR]; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "imx8mp_mu: bad read @0x%" HWADDR_PRIx "\n", offset); + return 0; + } +} + +static void imx8mp_mu_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + IMX8MPMUState *s =3D opaque; + + if (size !=3D 4) { + qemu_log_mask(LOG_GUEST_ERROR, + "imx8mp_mu: invalid write size %u @0x%" HWADDR_PRIx = "\n", + size, offset); + return; + } + + if (offset & 3) { + qemu_log_mask(LOG_GUEST_ERROR, + "imx8mp_mu: unaligned write @0x%" + HWADDR_PRIx "\n", offset); + return; + } + + /* TR0..TR3 */ + if (offset < MU_RR0) { + unsigned tr =3D offset >> 2; + uint32_t v =3D (uint32_t)value; + IMX8MPMUState *p =3D imx8mp_mu_peer(s); + + if (s->strict_access && !(s->mu[MU_SR] & MU_SR_TEn_V1(tr))) { + qemu_log_mask(LOG_GUEST_ERROR, + "imx8mp_mu: strict: write to non-empty" + " TR%u @0x%" HWADDR_PRIx "\n", + tr, offset); + return; + } + + s->mu[MU_TR0 + tr] =3D v; + + /* + * Writing TR consumes local TX-empty (TE=3D0) and delivers the wo= rd + * into peer RR while setting peer RX-full (RF=3D1). + * + */ + s->mu[MU_SR] &=3D ~MU_SR_TEn_V1(tr); /* TE=3D0 */ + if (p) { + p->mu[MU_RR0 + tr] =3D v; + p->mu[MU_SR] |=3D MU_SR_RFn_V1(tr); /* RF=3D1 */ + imx8mp_mu_update_irq(p); + } + + imx8mp_mu_update_irq(s); + return; + } + + /* RR are read-only from this side */ + if (offset >=3D MU_RR0 && offset < MU_SR) { + unsigned rr =3D (offset - MU_RR0) >> 2; + qemu_log_mask(LOG_GUEST_ERROR, + "imx8mp_mu: write to RR%d ignored\n", rr); + return; + } + + switch (offset) { + case MU_CR: { + uint32_t v =3D (uint32_t)value; + IMX8MPMUState *p =3D imx8mp_mu_peer(s); + uint32_t gir_mask =3D 0; + + for (int i =3D 0; i < 4; i++) { + gir_mask |=3D MU_CR_GIRn_V1(i); + } + + if (p) { + for (int i =3D 0; i < 4; i++) { + if (v & MU_CR_GIRn_V1(i)) { + /* Set peer doorbell pending */ + p->mu[MU_SR] |=3D MU_SR_GIPn_V1(i); + } + } + imx8mp_mu_update_irq(p); + } + + /* + * Model GIRn as write-to-trigger (self-clearing) and keep other CR + * bits latched. + */ + v &=3D ~gir_mask; + + s->mu[MU_CR] =3D v; + imx8mp_mu_update_irq(s); + return; + } + + case MU_SR:{ + + /* Write-1-to-clear for doorbell bits */ + uint32_t v =3D (uint32_t)value; + for (int i =3D 0; i < 4; i++) { + if (v & MU_SR_GIPn_V1(i)) { + s->mu[MU_SR] &=3D ~MU_SR_GIPn_V1(i); + } + } + imx8mp_mu_update_irq(s); + return; + } + + default: + qemu_log_mask(LOG_GUEST_ERROR, + "imx8mp_mu: bad write @0x%" HWADDR_PRIx + " =3D 0x%08" PRIx64 "\n", offset, value); + return; + } +} + +static ResettablePhases imx8mp_mu_parent_phases; + +static void imx8mp_mu_reset_enter(Object *obj, ResetType type) +{ + IMX8MPMUState *s =3D IMX8MP_MU(obj); + + if (imx8mp_mu_parent_phases.enter) { + imx8mp_mu_parent_phases.enter(obj, type); + } + memset(s->mu, 0, sizeof(s->mu)); + + s->mu[MU_SR] =3D 0x00F00080; +} + +static void imx8mp_mu_reset_hold(Object *obj, ResetType type) +{ + IMX8MPMUState *s =3D IMX8MP_MU(obj); + if (imx8mp_mu_parent_phases.hold) { + imx8mp_mu_parent_phases.hold(obj, type); + } + + imx8mp_mu_update_irq(s); +} + +static const MemoryRegionOps imx8mp_mu_ops =3D { + .read =3D imx8mp_mu_read, + .write =3D imx8mp_mu_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .impl =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + .unaligned =3D false, + }, +}; + +static const VMStateDescription imx8mp_mu_vmstate =3D { + .name =3D TYPE_IMX8MP_MU, + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32_ARRAY(mu, IMX8MPMUState, MU_MAX), + VMSTATE_END_OF_LIST() + }, +}; + +static void imx8mp_mu_init(Object *obj) +{ + IMX8MPMUState *s =3D IMX8MP_MU(obj); + SysBusDevice *sd =3D SYS_BUS_DEVICE(obj); + + /* Default to strict hardware-like access semantics. */ + s->strict_access =3D true; + + memory_region_init(&s->mmio.container, obj, TYPE_IMX8MP_MU, + IMX8MP_MU_MMIO_SIZE); + + /* Implemented subset as an IO subregion at offset 0 */ + memory_region_init_io(&s->mmio.regs, obj, &imx8mp_mu_ops, s, + TYPE_IMX8MP_MU ".regs", sizeof(s->mu)); + memory_region_add_subregion(&s->mmio.container, 0, &s->mmio.regs); + + sysbus_init_mmio(sd, &s->mmio.container); + sysbus_init_irq(sd, &s->irq); +} + +static void imx8mp_mu_class_init(ObjectClass *oc, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(oc); + ResettableClass *rc =3D RESETTABLE_CLASS(oc); + + resettable_class_set_parent_phases(rc, + imx8mp_mu_reset_enter, + imx8mp_mu_reset_hold, + NULL, + &imx8mp_mu_parent_phases); + dc->vmsd =3D &imx8mp_mu_vmstate; + dc->desc =3D "i.MX 8M Plus Messaging Unit"; +} + +static const TypeInfo imx8mp_mu_type_info[] =3D { + { + .name =3D TYPE_IMX8MP_MU, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(IMX8MPMUState), + .instance_init =3D imx8mp_mu_init, + .class_init =3D imx8mp_mu_class_init, + } +}; + +DEFINE_TYPES(imx8mp_mu_type_info); diff --git a/hw/misc/meson.build b/hw/misc/meson.build index f71323bde7..2b6bf4638a 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -62,6 +62,7 @@ system_ss.add(when: 'CONFIG_FSL_IMX8MP_CCM', if_true: fil= es('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', diff --git a/include/hw/arm/fsl-imx8mp.h b/include/hw/arm/fsl-imx8mp.h index c6c133cc05..94d198b932 100644 --- a/include/hw/arm/fsl-imx8mp.h +++ b/include/hw/arm/fsl-imx8mp.h @@ -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/imx_fec.h" #include "hw/core/or-irq.h" #include "hw/pci-host/designware.h" @@ -39,6 +40,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mpState, FSL_IMX8MP) #define FSL_IMX8MP_RAM_START 0x40000000 #define FSL_IMX8MP_RAM_SIZE_MAX (8 * GiB) =20 +#define FSL_IMX8MP_MU1_A_IRQ 88 + enum FslImx8mpConfiguration { FSL_IMX8MP_NUM_CPUS =3D 4, FSL_IMX8MP_NUM_ECSPIS =3D 3, @@ -46,12 +49,18 @@ enum FslImx8mpConfiguration { FSL_IMX8MP_NUM_GPTS =3D 6, FSL_IMX8MP_NUM_I2CS =3D 6, FSL_IMX8MP_NUM_IRQS =3D 160, + FSL_IMX8MP_NUM_MU =3D 3, FSL_IMX8MP_NUM_UARTS =3D 4, FSL_IMX8MP_NUM_USBS =3D 2, FSL_IMX8MP_NUM_USDHCS =3D 3, FSL_IMX8MP_NUM_WDTS =3D 3, }; =20 +typedef struct IMX8MPMUPair { + IMX8MPMUState a; + IMX8MPMUState b; +} IMX8MPMUPair; + struct FslImx8mpState { SysBusDevice parent_obj; =20 @@ -65,6 +74,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]; diff --git a/include/hw/misc/imx8mp_mu.h b/include/hw/misc/imx8mp_mu.h new file mode 100644 index 0000000000..4801708402 --- /dev/null +++ b/include/hw/misc/imx8mp_mu.h @@ -0,0 +1,53 @@ +/* + * NXP i.MX 8M Plus Messaging Unit (MU) + * + * Copyright (c) 2026, NXP Semiconductors + * Author: Gaurav Sharma + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + + +#ifndef IMX8MP_MU_H +#define IMX8MP_MU_H + +#include "hw/core/sysbus.h" +#include "qom/object.h" + +#define IMX8MP_MU_MMIO_SIZE 0x10000 + +enum IMX8MPMURegisters { + MU_TR0 =3D 0x000 / 4, + MU_TR1 =3D 0x004 / 4, + MU_TR2 =3D 0x008 / 4, + MU_TR3 =3D 0x00C / 4, + MU_RR0 =3D 0x010 / 4, + MU_RR1 =3D 0x014 / 4, + MU_RR2 =3D 0x018 / 4, + MU_RR3 =3D 0x01C / 4, + MU_SR =3D 0x020 / 4, + MU_CR =3D 0x024 / 4, + MU_MAX, +}; + +#define TYPE_IMX8MP_MU "imx8mp-mu" +OBJECT_DECLARE_SIMPLE_TYPE(IMX8MPMUState, IMX8MP_MU) + +typedef struct IMX8MPMUState { + SysBusDevice parent_obj; + + struct { + MemoryRegion container; + MemoryRegion regs; + } mmio; + + qemu_irq irq; + + struct IMX8MPMUState *peer; + uint32_t mu[MU_MAX]; + + bool strict_access; + +} IMX8MPMUState; + +#endif /* IMX8MP_MU_H */ --=20 2.34.1 From nobody Sun Jul 26 11:04:01 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=nxp.com Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783355431752198.07531651103102; Mon, 6 Jul 2026 09:30:31 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wgmC2-0007Lj-CF; Mon, 06 Jul 2026 12:29:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgmBz-0007KL-2x for qemu-devel@nongnu.org; Mon, 06 Jul 2026 12:29:11 -0400 Received: from inva020.nxp.com ([92.121.34.13]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgmBx-0002NL-I6 for qemu-devel@nongnu.org; Mon, 06 Jul 2026 12:29:10 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 1BA061A00A9; Mon, 6 Jul 2026 18:29:05 +0200 (CEST) Received: from aprdc01srsp001v.ap-rdc01.nxp.com (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id E39761A00A5; Mon, 6 Jul 2026 18:29:04 +0200 (CEST) Received: from lsv031015.swis.in-blr01.nxp.com (lsv031015.swis.in-blr01.nxp.com [10.12.177.77]) by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id 081871800071; Tue, 7 Jul 2026 00:29:03 +0800 (+08) From: Gaurav Sharma To: qemu-devel@nongnu.org Cc: pbonzini@redhat.com, peter.maydell@linaro.org, Gaurav Sharma , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCHv2 5/7] hw/misc: Extend i.MX8MP CCM with Cortex-M7 clock outputs Date: Mon, 6 Jul 2026 21:58:57 +0530 Message-Id: <20260706162859.3361063-6-gaurav.sharma_7@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260706162859.3361063-1-gaurav.sharma_7@nxp.com> References: <20260706162859.3361063-1-gaurav.sharma_7@nxp.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Virus-Scanned: ClamAV using ClamSMTP Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=92.121.34.13; envelope-from=gaurav.sharma_7@nxp.com; helo=inva020.nxp.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1783355433571158500 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. Signed-off-by: Gaurav Sharma Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- hw/misc/imx8mp_ccm.c | 9 +++++++++ include/hw/misc/imx8mp_ccm.h | 3 +++ 2 files changed, 12 insertions(+) diff --git a/hw/misc/imx8mp_ccm.c b/hw/misc/imx8mp_ccm.c index 911911ed86..5530c924b5 100644 --- a/hw/misc/imx8mp_ccm.c +++ b/hw/misc/imx8mp_ccm.c @@ -12,17 +12,24 @@ #include "qemu/log.h" =20 #include "hw/misc/imx8mp_ccm.h" +#include "hw/core/qdev-clock.h" #include "migration/vmstate.h" =20 #include "trace.h" =20 #define CKIH_FREQ 16000000 /* 16MHz crystal input */ =20 +#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 =3D IMX8MP_CCM(dev); =20 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); } =20 #define CCM_INDEX(offset) (((offset) & ~(hwaddr)0xF) / sizeof(uint32_t)) @@ -88,6 +95,8 @@ static void imx8mp_ccm_init(Object *obj) SysBusDevice *sd =3D SYS_BUS_DEVICE(obj); IMX8MPCCMState *s =3D IMX8MP_CCM(obj); =20 + s->cm7_cpuclk =3D qdev_init_clock_out(DEVICE(obj), "cm7_cpuclk"); + s->cm7_refclk =3D qdev_init_clock_out(DEVICE(obj), "cm7_refclk"); memory_region_init_io(&s->iomem, obj, &imx8mp_set_clr_tog_ops, diff --git a/include/hw/misc/imx8mp_ccm.h b/include/hw/misc/imx8mp_ccm.h index 685c8582ff..c6ede6928c 100644 --- a/include/hw/misc/imx8mp_ccm.h +++ b/include/hw/misc/imx8mp_ccm.h @@ -9,6 +9,7 @@ #ifndef IMX8MP_CCM_H #define IMX8MP_CCM_H =20 +#include "hw/core/clock.h" #include "hw/misc/imx_ccm.h" #include "qom/object.h" =20 @@ -25,6 +26,8 @@ struct IMX8MPCCMState { MemoryRegion iomem; =20 uint32_t ccm[CCM_MAX]; + Clock *cm7_cpuclk; + Clock *cm7_refclk; }; =20 #endif /* IMX8MP_CCM_H */ --=20 2.34.1 From nobody Sun Jul 26 11:04:01 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=nxp.com Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783355389906408.27617009693904; Mon, 6 Jul 2026 09:29:49 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wgmC2-0007Ly-Nt; Mon, 06 Jul 2026 12:29:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgmC0-0007L4-Re for qemu-devel@nongnu.org; Mon, 06 Jul 2026 12:29:12 -0400 Received: from inva020.nxp.com ([92.121.34.13]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgmBx-0002NN-Kd for qemu-devel@nongnu.org; Mon, 06 Jul 2026 12:29:12 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 255481A00B2; Mon, 6 Jul 2026 18:29:05 +0200 (CEST) Received: from aprdc01srsp001v.ap-rdc01.nxp.com (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id E4C281A00A6; Mon, 6 Jul 2026 18:29:04 +0200 (CEST) Received: from lsv031015.swis.in-blr01.nxp.com (lsv031015.swis.in-blr01.nxp.com [10.12.177.77]) by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id 65C3B1800088; Tue, 7 Jul 2026 00:29:04 +0800 (+08) From: Gaurav Sharma To: qemu-devel@nongnu.org Cc: pbonzini@redhat.com, peter.maydell@linaro.org, Gaurav Sharma Subject: [PATCHv2 6/7] hw/arm: Enable Cortex-M7 AMP boot on i.MX8MP Date: Mon, 6 Jul 2026 21:58:58 +0530 Message-Id: <20260706162859.3361063-7-gaurav.sharma_7@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260706162859.3361063-1-gaurav.sharma_7@nxp.com> References: <20260706162859.3361063-1-gaurav.sharma_7@nxp.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Virus-Scanned: ClamAV using ClamSMTP Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=92.121.34.13; envelope-from=gaurav.sharma_7@nxp.com; helo=inva020.nxp.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1783355391234158500 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.It follows the classic Cortex-M boot sequence: initial SP and reset vector taken from the vector table. Signed-off-by: Gaurav Sharma --- docs/system/arm/imx8m.rst | 184 +++++++++++++++++++++++++++++++++++- hw/arm/fsl-imx8mp.c | 151 ++++++++++++++++++++++++++--- hw/arm/imx8mp-evk.c | 3 +- include/hw/arm/fsl-imx8mp.h | 13 ++- 4 files changed, 333 insertions(+), 18 deletions(-) diff --git a/docs/system/arm/imx8m.rst b/docs/system/arm/imx8m.rst index c482bf180f..294c333127 100644 --- a/docs/system/arm/imx8m.rst +++ b/docs/system/arm/imx8m.rst @@ -12,6 +12,7 @@ The ``imx8mp-evk`` and ``imx8mm-evk`` machines implement = the following devices: =20 * Up to 4 Cortex-A53 cores + * 1 Cortex-M7 core (``imx8mp-evk`` only) * Generic Interrupt Controller (GICv3) * 4 UARTs * 3 USDHC Storage Controllers @@ -36,6 +37,187 @@ Boot options The ``imx8mp-evk`` and ``imx8mm-evk`` machines can start a Linux kernel directly using the standard ``-kernel`` functionality. =20 + +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 av= oid dependence on firmware interfaces that aren=E2=80=99t guaranteed in qem= u. +This mode uses the SRC syscon block and the IOMUXC GPR for start/stop cont= rol. + +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.n= xp.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 remo= teproc 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 rem= oteproc and rpmsg options needed by the +i.MX remoteproc driver, for example: + +.. code-block:: none + + CONFIG_REMOTEPROC=3Dy + CONFIG_IMX_REMOTEPROC=3Dy + CONFIG_RPMSG=3Dy + CONFIG_VIRTIO_RPMSG_BUS=3Dy + CONFIG_RPMSG_CHAR=3Dy + +Depending on the kernel version and configuration, some options may be sel= ected +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-c= m7`` to ``fsl,imx8mp-cm7-mmio`` +3. Add the following properties to the ``imx8mp-cm7`` node :- + + ``syscon =3D <&src>;`` + ``fsl,iomuxc-gpr =3D <&gpr>;`` + + These references are needed by imx_rproc_mmio_detect_mode in i.MX remot= eproc 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 :- MCUXSDKIMX= 8MPGSUG[https://share.google/qD4D09FCkkydTurqp] +2. Build a DDR-linked Cortex-M7 ELF using the ARM GNU toolchain from the M= CUXpresso 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-e= vk-rpmsg.dtb`` + +3. Copy the ``iuart_polling_cm7.elf`` to ``/lib/firmware/`` path inside iM= X8MPEVK 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 us= ed +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 sd= k 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/i= mx8mp-uart4 \ + -kernel Image \ + -dtb imx8mp-evk-rpmsg.dtb \ + -append "root=3D/dev/mmcblk2p2" \ + -drive file=3Dsdcard.img,if=3Dsd,bus=3D2,format=3Draw,id=3Dmmcblk2 + +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 el= f:- + +.. code-block:: bash + + $ echo iuart_polling_cm7.elf > /sys/class/remoteproc/remoteproc0/firmwa= re + $ echo start > /sys/class/remoteproc/remoteproc0/state + + +On the tab where the console is opened, you will observe the UART logs. Th= e 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=3D0x80000000 + +If this property is not provided, QEMU uses ``0x80000000`` by default. + + + Direct Linux Kernel Boot '''''''''''''''''''''''' =20 @@ -72,7 +254,7 @@ For i.MX 8M Plus EVK: .. code-block:: bash =20 $ qemu-system-aarch64 -M imx8mp-evk \ - -display none -serial null -serial stdio \ + -display none -serial null -serial stdio -serial null -serial /tmp/i= mx8mp-uart4 \ -kernel Image \ -dtb imx8mp-evk.dtb \ -append "root=3D/dev/mmcblk2p2" \ diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c index eec83deced..8d6a1c3f4d 100644 --- a/hw/arm/fsl-imx8mp.c +++ b/hw/arm/fsl-imx8mp.c @@ -22,6 +22,8 @@ #include "qapi/error.h" #include "qobject/qlist.h" =20 +#define IMX8MP_NUM_A53 4 + static const struct { hwaddr addr; size_t size; @@ -196,6 +198,10 @@ static void fsl_imx8mp_init(Object *obj) FslImx8mpState *s =3D FSL_IMX8MP(obj); int i; =20 + s->cm7_booted =3D false; + + object_initialize_child(obj, "cm7", &s->cm7, TYPE_ARMV7M); + object_initialize_child(obj, "gic", &s->gic, gicv3_class_name()); =20 object_initialize_child(obj, "ccm", &s->ccm, TYPE_IMX8MP_CCM); @@ -269,6 +275,93 @@ static void fsl_imx8mp_init(Object *obj) TYPE_FSL_IMX8M_PCIE_PHY); } =20 +static inline void imx8mp_cm7_halt(CPUState *m7cs) +{ + cpu_interrupt(m7cs, CPU_INTERRUPT_HALT); + m7cs->halted =3D 1; + qemu_cpu_kick(m7cs); +} + +static inline void imx8mp_cm7_resume(CPUState *m7cs) +{ + /* Clear HALT interrupt (from STOP) and resume */ + cpu_reset_interrupt(m7cs, CPU_INTERRUPT_HALT); + m7cs->halted =3D 0; + m7cs->stopped =3D 0; + cpu_resume(m7cs); + cpu_interrupt(m7cs, CPU_INTERRUPT_EXITTB); + qemu_cpu_kick(m7cs); +} + +static void imx8mp_cm7_ctrl_apply(CPUState *cpu, run_on_cpu_data data) +{ + struct CM7CtlReq *r =3D data.host_ptr; + FslImx8mpState *s =3D r->s; + ARMCPU *m7 =3D s->cm7.cpu; + CPUState *m7cs =3D CPU(m7); + + if (!r->run) { + /* STOP: halt the M7 */ + imx8mp_cm7_halt(m7cs); + goto out; + } + + /* + * RUN: + * CPUWAIT is modeled as a run/stop gate. On first RUN, boot from vect= or + * table. Subsequent RUN resumes execution without resetting CM7 state. + */ + if (s->cm7_booted) { + imx8mp_cm7_resume(m7cs); + goto out; + } + + uint32_t msp_le =3D 0, pc_le =3D 0; + uint32_t msp, pc; + hwaddr vbase =3D s->cm7_vector_base; + + address_space_read(&address_space_memory, vbase, + MEMTXATTRS_UNSPECIFIED, &msp_le, sizeof(msp_le)); + address_space_read(&address_space_memory, vbase + 4, + MEMTXATTRS_UNSPECIFIED, &pc_le, sizeof(pc_le)); + msp =3D le32_to_cpu(msp_le); + pc =3D le32_to_cpu(pc_le); + + + /* Clear Thumb indicator bit (bit0) */ + pc &=3D ~1u; + + cpu_reset(m7cs); + + /* Set SP (R13) and PC (R15). Cortex-M uses Thumb */ + m7->env.regs[13] =3D msp; + m7->env.regs[15] =3D pc; + m7->env.thumb =3D 1; + + imx8mp_cm7_resume(m7cs); + + s->cm7_booted =3D true; +out: + g_free(r); +}; + +static void imx8mp_cm7_cpuwait_handler(void *opaque, int n, int level) +{ + FslImx8mpState *s =3D opaque; + (void)n; + + if (!s->cm7.cpu) { + return; + } + + struct CM7CtlReq *r =3D g_new0(struct CM7CtlReq, 1); + r->s =3D s; + r->run =3D !!level; + + async_run_on_cpu(CPU(s->cm7.cpu), imx8mp_cm7_ctrl_apply, + RUN_ON_CPU_HOST_PTR(r)); +} + static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) { MachineState *ms =3D MACHINE(qdev_get_machine()); @@ -277,21 +370,15 @@ static void fsl_imx8mp_realize(DeviceState *dev, Erro= r **errp) const char *cpu_type =3D ms->cpu_type ?: ARM_CPU_TYPE_NAME("cortex-a53= "); int i; =20 - if (ms->smp.cpus > FSL_IMX8MP_NUM_CPUS) { - error_setg(errp, "%s: Only %d CPUs are supported (%d requested)", - TYPE_FSL_IMX8MP, FSL_IMX8MP_NUM_CPUS, ms->smp.cpus); - return; - } - - for (i =3D 0; i < ms->smp.cpus; i++) { + for (i =3D 0; i < IMX8MP_NUM_A53; i++) { g_autofree char *name =3D g_strdup_printf("cpu%d", i); object_initialize_child(OBJECT(dev), name, &s->cpu[i], cpu_type); } =20 /* CPUs */ - for (i =3D 0; i < ms->smp.cpus; i++) { + for (i =3D 0; i < IMX8MP_NUM_A53; i++) { /* On uniprocessor, the CBAR is set to 0 */ - if (ms->smp.cpus > 1 && + if (IMX8MP_NUM_A53 > 1 && object_property_find(OBJECT(&s->cpu[i]), "reset-cbar")) { object_property_set_int(OBJECT(&s->cpu[i]), "reset-cbar", fsl_imx8mp_memmap[FSL_IMX8MP_GIC_DIST]= .addr, @@ -334,11 +421,11 @@ static void fsl_imx8mp_realize(DeviceState *dev, Erro= r **errp) QList *redist_region_count; bool pmu =3D object_property_get_bool(OBJECT(first_cpu), "pmu", NU= LL); =20 - qdev_prop_set_uint32(gicdev, "num-cpu", ms->smp.cpus); + qdev_prop_set_uint32(gicdev, "num-cpu", IMX8MP_NUM_A53); qdev_prop_set_uint32(gicdev, "num-irq", FSL_IMX8MP_NUM_IRQS + GIC_INTERNAL); redist_region_count =3D qlist_new(); - qlist_append_int(redist_region_count, ms->smp.cpus); + qlist_append_int(redist_region_count, IMX8MP_NUM_A53); qdev_prop_set_array(gicdev, "redist-region-count", redist_region_c= ount); object_property_set_link(OBJECT(&s->gic), "sysmem", OBJECT(get_system_memory()), &error_fatal= ); @@ -353,7 +440,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error = **errp) * maintenance interrupt signal to the appropriate GIC PPI inputs,= and * the GIC's IRQ/FIQ interrupt outputs to the CPU's inputs. */ - for (i =3D 0; i < ms->smp.cpus; i++) { + for (i =3D 0; i < IMX8MP_NUM_A53; i++) { DeviceState *cpudev =3D DEVICE(&s->cpu[i]); int intidbase =3D FSL_IMX8MP_NUM_IRQS + i * GIC_INTERNAL; qemu_irq irq; @@ -383,11 +470,11 @@ static void fsl_imx8mp_realize(DeviceState *dev, Erro= r **errp) =20 sysbus_connect_irq(gicsbd, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ)); - sysbus_connect_irq(gicsbd, i + ms->smp.cpus, + sysbus_connect_irq(gicsbd, i + IMX8MP_NUM_A53, qdev_get_gpio_in(cpudev, ARM_CPU_FIQ)); - sysbus_connect_irq(gicsbd, i + 2 * ms->smp.cpus, + sysbus_connect_irq(gicsbd, i + 2 * IMX8MP_NUM_A53, qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ)); - sysbus_connect_irq(gicsbd, i + 3 * ms->smp.cpus, + sysbus_connect_irq(gicsbd, i + 3 * IMX8MP_NUM_A53, qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ)); =20 if (kvm_enabled()) { @@ -459,6 +546,38 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error= **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, fsl_imx8mp_memmap[FSL_IMX8MP_IOMUXC_GPR].addr); =20 + sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpr), 0, + qemu_allocate_irq(imx8mp_cm7_cpuwait_handler, s, 0)); + + /* Realize Cortex-M7 subsystem */ + { + DeviceState *cm7dev =3D DEVICE(&s->cm7); + DeviceState *ccmdev =3D DEVICE(&s->ccm); + qdev_prop_set_string(cm7dev, "cpu-type", + ARM_CPU_TYPE_NAME("cortex-m7")); + qdev_prop_set_uint32(cm7dev, "num-irq", 64); + qdev_prop_set_bit(cm7dev, "enable-bitband", true); + + /* CM7 vector table base (configurable) */ + qdev_prop_set_uint32(cm7dev, "init-nsvtor", s->cm7_vector_base); + + /* Connect CM7 clocks from CCM exported outputs */ + qdev_connect_clock_in(cm7dev, "cpuclk", + qdev_get_clock_out(ccmdev, "cm7_cpuclk")); + qdev_connect_clock_in(cm7dev, "refclk", + qdev_get_clock_out(ccmdev, "cm7_refclk")); + object_property_set_link(OBJECT(&s->cm7), "memory", + OBJECT(get_system_memory()), &error_abort= ); + + if (!sysbus_realize(SYS_BUS_DEVICE(&s->cm7), errp)) { + return; + } + + CPUState *m7cs =3D CPU(s->cm7.cpu); + cpu_interrupt(m7cs, CPU_INTERRUPT_HALT); + m7cs->halted =3D 1; + } + /* GPTs */ object_property_set_int(OBJECT(&s->gpt5_gpt6_irq), "num-lines", 2, &error_abort); @@ -784,6 +903,8 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error = **errp) static const Property fsl_imx8mp_properties[] =3D { DEFINE_PROP_UINT32("fec1-phy-num", FslImx8mpState, phy_num, 0), DEFINE_PROP_BOOL("fec1-phy-connected", FslImx8mpState, phy_connected, = true), + DEFINE_PROP_UINT32("cm7-vector-base", FslImx8mpState, + cm7_vector_base, 0x80000000), }; =20 static void fsl_imx8mp_class_init(ObjectClass *oc, const void *data) diff --git a/hw/arm/imx8mp-evk.c b/hw/arm/imx8mp-evk.c index b84ac91a17..0f92bf5dc8 100644 --- a/hw/arm/imx8mp-evk.c +++ b/hw/arm/imx8mp-evk.c @@ -117,7 +117,8 @@ static void imx8mp_evk_machine_init(MachineClass *mc) { mc->desc =3D "NXP i.MX 8M Plus EVK Board"; mc->init =3D imx8mp_evk_init; - mc->default_cpus =3D 4; + mc->default_cpus =3D 5; + mc->min_cpus =3D 5; mc->max_cpus =3D FSL_IMX8MP_NUM_CPUS; mc->default_ram_id =3D "imx8mp-evk.ram"; mc->default_ram_size =3D 6 * GiB; diff --git a/include/hw/arm/fsl-imx8mp.h b/include/hw/arm/fsl-imx8mp.h index 94d198b932..335e4beb6c 100644 --- a/include/hw/arm/fsl-imx8mp.h +++ b/include/hw/arm/fsl-imx8mp.h @@ -10,6 +10,7 @@ #define FSL_IMX8MP_H =20 #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" @@ -30,6 +31,7 @@ #include "hw/timer/imx_gpt.h" #include "hw/usb/hcd-dwc3.h" #include "hw/watchdog/wdt_imx2.h" +#include "hw/core/qdev-clock.h" #include "hw/core/sysbus.h" #include "qom/object.h" #include "qemu/units.h" @@ -43,7 +45,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mpState, FSL_IMX8MP) #define FSL_IMX8MP_MU1_A_IRQ 88 =20 enum FslImx8mpConfiguration { - FSL_IMX8MP_NUM_CPUS =3D 4, + FSL_IMX8MP_NUM_CPUS =3D 5, FSL_IMX8MP_NUM_ECSPIS =3D 3, FSL_IMX8MP_NUM_GPIOS =3D 5, FSL_IMX8MP_NUM_GPTS =3D 6, @@ -65,6 +67,10 @@ struct FslImx8mpState { SysBusDevice parent_obj; =20 ARMCPU cpu[FSL_IMX8MP_NUM_CPUS]; + ARMv7MState cm7; + bool enable_cm7; + bool cm7_booted; + uint32_t cm7_vector_base; GICv3State gic; IMX8MPGPCState gpc; IMX8MPGPRState gpr; @@ -91,6 +97,11 @@ struct FslImx8mpState { bool phy_connected; }; =20 +struct CM7CtlReq { + FslImx8mpState *s; + bool run; +}; + enum FslImx8mpMemoryRegions { FSL_IMX8MP_A53_DAP, FSL_IMX8MP_AIPS1_CONFIGURATION, --=20 2.34.1 From nobody Sun Jul 26 11:04:01 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=nxp.com Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 178335538371541.616635864797104; Mon, 6 Jul 2026 09:29:43 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wgmC0-0007L2-MQ; Mon, 06 Jul 2026 12:29:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgmBz-0007Ke-Ok for qemu-devel@nongnu.org; Mon, 06 Jul 2026 12:29:11 -0400 Received: from inva020.nxp.com ([92.121.34.13]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgmBy-0002NZ-BB for qemu-devel@nongnu.org; Mon, 06 Jul 2026 12:29:11 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 6FA191A00AC; Mon, 6 Jul 2026 18:29:05 +0200 (CEST) Received: from aprdc01srsp001v.ap-rdc01.nxp.com (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 438001A00B6; Mon, 6 Jul 2026 18:29:05 +0200 (CEST) Received: from lsv031015.swis.in-blr01.nxp.com (lsv031015.swis.in-blr01.nxp.com [10.12.177.77]) by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id B9852180008C; Tue, 7 Jul 2026 00:29:04 +0800 (+08) From: Gaurav Sharma To: qemu-devel@nongnu.org Cc: pbonzini@redhat.com, peter.maydell@linaro.org, Gaurav Sharma Subject: [PATCHv2 7/7] tests/functional: Enable Cortex-M7 boot in i.MX8MP EVK functional test Date: Mon, 6 Jul 2026 21:58:59 +0530 Message-Id: <20260706162859.3361063-8-gaurav.sharma_7@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260706162859.3361063-1-gaurav.sharma_7@nxp.com> References: <20260706162859.3361063-1-gaurav.sharma_7@nxp.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Virus-Scanned: ClamAV using ClamSMTP Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=92.121.34.13; envelope-from=gaurav.sharma_7@nxp.com; helo=inva020.nxp.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1783355385476158500 Content-Type: text/plain; charset="utf-8" Update the i.MX8MP EVK functional test to enable the Cortex-M7 core by setting maxcpus=3D5 and enabling the fsl-imx8mp.enable-cm7 property The i.MX8MP SoC model makes the Cortex-M7 optional and disabled by default. Signed-off-by: Gaurav Sharma --- MAINTAINERS | 13 ++++--------- tests/functional/aarch64/test_imx8mp_evk.py | 1 - 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 97dcc78ded..fe921a28de 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -921,29 +921,24 @@ F: hw/pci-host/designware.c F: include/hw/pci-host/designware.h F: docs/system/arm/mcimx7d-sabre.rst =20 -MCIMX8MM-EVK / iMX8MM +MCIMX8MP-EVK / MCIMX8MM-EVK +M: Bernhard Beschow M: Gaurav Sharma 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 -F: tests/functional/aarch64/test_imx8mm_evk.py - -MCIMX8MP-EVK / i.MX8MP -M: Bernhard Beschow -L: qemu-arm@nongnu.org -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 =20 diff --git a/tests/functional/aarch64/test_imx8mp_evk.py b/tests/functional= /aarch64/test_imx8mp_evk.py index 99ddcdef83..6046c573d5 100755 --- a/tests/functional/aarch64/test_imx8mp_evk.py +++ b/tests/functional/aarch64/test_imx8mp_evk.py @@ -53,7 +53,6 @@ def test_aarch64_imx8mp_evk_usdhc(self): self.set_machine('imx8mp-evk') self.vm.set_console(console_index=3D1) self.vm.add_args('-m', '2G', - '-smp', '4', '-kernel', self.kernel_path, '-initrd', self.initrd_path, '-dtb', self.dtb_path, --=20 2.34.1