[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v4 3/4] xen/arm: add i.MX8M platform support



Add platform glue for the NXP i.MX8M family (i.MX8MP/MQ/MM/MN).

When Linux is used as dom0 a number of drivers make SiP SMC calls into
TF-A to manage hardware: GPC power domains, SRC (M-core remoteproc),
SoC info and NoC QoS.  There is no public specification for these
calls; the function IDs and their subfunctions are taken from the
vendor kernel call sites.

Forward only the specific subfunctions the hardware domain issues,
following the whitelist model of the i.MX8QM platform.  Each service
with a fixed set of subfunctions (GPC, SRC, NoC) filters them with an
explicit switch on the subfunction id, and the SoC info call is a
read-only query.  CPU and DRAM frequency scaling are denied because
the hardware domain cannot make an informed decision about resources
shared with the other domains, and any unknown function ID is
rejected.

Signed-off-by: Wig Cheng <onlywig@xxxxxxxxx>
Reviewed-by: Michal Orzel <michal.orzel@xxxxxxx>
---
Changes in v4:
- SRC and NoC: filter the subfunction id with an explicit switch that
  lists each accepted subfunction, instead of a range check.
- NoC: accept only the QoS priority subfunction; the LCDIF subfunction
  has no caller in the vendor kernel.  Note that i.MX8MP issues no NoC
  call at boot (only i.MX8MQ does).
- Print the subfunction id as well when rejecting an unknown function
  id.
- Picked up Michal's Reviewed-by.

 xen/arch/arm/platforms/Makefile |   1 +
 xen/arch/arm/platforms/imx8m.c  | 161 ++++++++++++++++++++++++++++++++
 2 files changed, 162 insertions(+)
 create mode 100644 xen/arch/arm/platforms/imx8m.c

diff --git a/xen/arch/arm/platforms/Makefile b/xen/arch/arm/platforms/Makefile
index bec6e55d1f..cdf936c50d 100644
--- a/xen/arch/arm/platforms/Makefile
+++ b/xen/arch/arm/platforms/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_ALL_PLAT)   += sunxi.o
 obj-$(CONFIG_ALL64_PLAT) += thunderx.o
 obj-$(CONFIG_ALL64_PLAT) += xgene-storm.o
 obj-$(CONFIG_ALL64_PLAT) += brcm-raspberry-pi.o
+obj-$(CONFIG_ALL64_PLAT) += imx8m.o
 obj-$(CONFIG_ALL64_PLAT) += imx8qm.o
 obj-$(CONFIG_MPSOC_PLATFORM)  += xilinx-zynqmp.o
 obj-$(CONFIG_MPSOC_PLATFORM)  += xilinx-zynqmp-eemi.o
diff --git a/xen/arch/arm/platforms/imx8m.c b/xen/arch/arm/platforms/imx8m.c
new file mode 100644
index 0000000000..ad76935f5d
--- /dev/null
+++ b/xen/arch/arm/platforms/imx8m.c
@@ -0,0 +1,161 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * i.MX 8M family setup
+ *
+ * Copyright 2026 Open-EP (E-Paper) Community
+ */
+
+#include <xen/sched.h>
+#include <asm/platform.h>
+#include <asm/regs.h>
+#include <asm/smccc.h>
+
+static const char * const imx8m_dt_compat[] __initconst =
+{
+    "fsl,imx8mp",
+    "fsl,imx8mq",
+    "fsl,imx8mm",
+    "fsl,imx8mn",
+    NULL
+};
+
+#define IMX_SIP_FID(fid) \
+    ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+                       ARM_SMCCC_CONV_64, \
+                       ARM_SMCCC_OWNER_SIP, \
+                       (fid))
+
+/*
+ * SiP SMC function IDs used by the i.MX8M Linux drivers.  There is no
+ * public specification for these; the IDs and their subfunctions are
+ * extracted from the vendor kernel call sites (see drivers/soc/imx,
+ * drivers/devfreq, drivers/remoteproc).
+ */
+#define IMX_SIP_F_GPC       0x0   /* GPC power-domain control */
+#define IMX_SIP_F_CPUFREQ   0x1   /* CPU frequency scaling */
+#define IMX_SIP_F_DDR_DVFS  0x4   /* DRAM frequency scaling */
+#define IMX_SIP_F_SRC       0x5   /* SRC: M-core remoteproc start/stop */
+#define IMX_SIP_F_SOC_INFO  0x6   /* read-only SoC info query */
+#define IMX_SIP_F_NOC       0x8   /* NoC QoS priority setup */
+
+#define IMX_SIP_GPC_SF_PM_DOMAIN    0x03
+
+#define IMX_SIP_SRC_SF_M4_START     0x00
+#define IMX_SIP_SRC_SF_M4_STARTED   0x01
+#define IMX_SIP_SRC_SF_M4_STOP      0x02
+
+#define IMX_SIP_NOC_SF_PRIORITY     0x01
+
+static bool imx8m_smc(struct cpu_user_regs *regs)
+{
+    uint32_t function_id = get_user_reg(regs, 0);
+    uint32_t subfunction_id = get_user_reg(regs, 1);
+    struct arm_smccc_res res;
+
+    if ( !cpus_have_const_cap(ARM_SMCCC_1_1) )
+    {
+        printk_once(XENLOG_WARNING
+                    "imx8m: smc: no SMCCC 1.1 support. Disabling firmware 
calls\n");
+
+        return false;
+    }
+
+    /* Only the hardware domain may use the SiP calls */
+    if ( !is_hardware_domain(current->domain) )
+    {
+        gprintk(XENLOG_WARNING, "imx8m: smc: No access\n");
+        return false;
+    }
+
+    /*
+     * Forward only the subfunctions the dom0 kernel actually issues.  All
+     * of these manage hardware that belongs to the hardware domain (power
+     * domains, M-core, NoC) or are read-only queries.
+     */
+    switch ( function_id )
+    {
+    case IMX_SIP_FID(IMX_SIP_F_GPC):
+        if ( subfunction_id != IMX_SIP_GPC_SF_PM_DOMAIN )
+            return false;
+        break;
+
+    /*
+     * CPU and DRAM frequency scaling: the hardware domain does not see the
+     * whole system and cannot make an informed decision about resources
+     * shared with the other domains, so deny both (CPU frequency scaling
+     * is denied on the i.MX8QM platform for the same reason).
+     */
+    case IMX_SIP_FID(IMX_SIP_F_CPUFREQ):
+    case IMX_SIP_FID(IMX_SIP_F_DDR_DVFS):
+        return false;
+
+    case IMX_SIP_FID(IMX_SIP_F_SRC):
+        /* SRC: M-core remoteproc start, poll-started and stop. */
+        switch ( subfunction_id )
+        {
+        case IMX_SIP_SRC_SF_M4_START:
+        case IMX_SIP_SRC_SF_M4_STARTED:
+        case IMX_SIP_SRC_SF_M4_STOP:
+            break;
+
+        default:
+            return false;
+        }
+        break;
+
+    case IMX_SIP_FID(IMX_SIP_F_SOC_INFO):
+        break;
+
+    case IMX_SIP_FID(IMX_SIP_F_NOC):
+        /*
+         * NoC QoS priority setup.  Only i.MX8MQ issues this at boot;
+         * i.MX8MP issues no NoC call, but the platform covers both.
+         */
+        switch ( subfunction_id )
+        {
+        case IMX_SIP_NOC_SF_PRIORITY:
+            break;
+
+        default:
+            return false;
+        }
+        break;
+
+    default:
+        gprintk(XENLOG_WARNING,
+                "imx8m: smc: Unknown function id %x subfunction id %x\n",
+                function_id, subfunction_id);
+        return false;
+    }
+
+    arm_smccc_1_1_smc(function_id,
+                      subfunction_id,
+                      get_user_reg(regs, 2),
+                      get_user_reg(regs, 3),
+                      get_user_reg(regs, 4),
+                      get_user_reg(regs, 5),
+                      get_user_reg(regs, 6),
+                      get_user_reg(regs, 7),
+                      &res);
+
+    set_user_reg(regs, 0, res.a0);
+    set_user_reg(regs, 1, res.a1);
+    set_user_reg(regs, 2, res.a2);
+    set_user_reg(regs, 3, res.a3);
+
+    return true;
+}
+
+PLATFORM_START(imx8m, "i.MX 8M")
+    .compatible = imx8m_dt_compat,
+    .smc = imx8m_smc,
+PLATFORM_END
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.