All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] xen/arm: add i.MX8M platform and UART support
@ 2026-08-14 16:25 Wig Cheng
  2026-08-14 16:25 ` [PATCH 1/3] xen/char: add classic i.MX UART driver Wig Cheng
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Wig Cheng @ 2026-08-14 16:25 UTC (permalink / raw)
  To: xen-devel
  Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel,
	Volodymyr Babchuk, John Ernberg, Peng Fan, Wig Cheng

This series adds Xen support for the NXP i.MX8M family (i.MX8MP / MQ /
MM / MN).  It provides the console UART driver, its early printk, and
the platform glue (SiP SMC whitelist for the calls the dom0 kernel
issues to TF-A).

Tested on i.MX8MP (4x Cortex-A53, GICv3): dom0 boots to login on the
hypervisor console, and a domU starts with a PV disk and virtio
devices running a full Wayland distro.  This addresses the concern
raised on the 2019 i.MX8MQ RFC that only a ramfs dom0 had been shown.

Notes for reviewers:

- Unlike i.MX8MQ, the i.MX8MP device tree uses the GIC as the root
  interrupt controller (interrupt-parent = <&gic>), so no device-tree
  workaround is needed and power domains keep working.

- The i.MX8M family has no SMMU, so device passthrough relies on the
  1:1 direct-mapped hardware domain.

- The SiP SMC whitelist forwards only the function IDs the dom0 kernel
  actually issues (extracted from the upstream and vendor kernels);
  no call outside the whitelist was observed at runtime.


Wig Cheng (3):
  xen/char: add classic i.MX UART driver
  xen/arm64: add early printk for the classic i.MX UART
  xen/arm: add i.MX8M platform support

 xen/arch/arm/Kconfig.debug            |  12 ++
 xen/arch/arm/arm64/debug-imx-uart.inc |  39 +++++
 xen/arch/arm/include/asm/imx-uart.h   |  62 +++++++
 xen/arch/arm/platforms/Makefile       |   1 +
 xen/arch/arm/platforms/imx8m.c        | 116 +++++++++++++
 xen/drivers/char/Kconfig              |   8 +
 xen/drivers/char/Makefile             |   1 +
 xen/drivers/char/imx-uart.c           | 227 ++++++++++++++++++++++++++
 8 files changed, 466 insertions(+)
 create mode 100644 xen/arch/arm/arm64/debug-imx-uart.inc
 create mode 100644 xen/arch/arm/include/asm/imx-uart.h
 create mode 100644 xen/arch/arm/platforms/imx8m.c
 create mode 100644 xen/drivers/char/imx-uart.c

-- 
2.43.0



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] xen/char: add classic i.MX UART driver
  2026-08-14 16:25 [PATCH 0/3] xen/arm: add i.MX8M platform and UART support Wig Cheng
@ 2026-08-14 16:25 ` Wig Cheng
  2026-08-14 16:25 ` [PATCH 2/3] xen/arm64: add early printk for the classic i.MX UART Wig Cheng
  2026-08-14 16:25 ` [PATCH 3/3] xen/arm: add i.MX8M platform support Wig Cheng
  2 siblings, 0 replies; 4+ messages in thread
From: Wig Cheng @ 2026-08-14 16:25 UTC (permalink / raw)
  To: xen-devel
  Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel,
	Volodymyr Babchuk, John Ernberg, Peng Fan, Wig Cheng

Add a console driver for the classic i.MX UART IP ("fsl,imx6q-uart"
compatible), as found on the i.MX6/7/8M families.  Baudrate and pin
configuration are inherited from the bootloader; the driver only
enables the transmitter/receiver and wires up the RX/TX interrupts,
mirroring the existing imx-lpuart driver.

This is needed for the i.MX8M family, whose UART IP differs from the
LPUART used on i.MX8QM/8QXP.

Signed-off-by: Wig Cheng <onlywig@gmail.com>
---
 xen/arch/arm/include/asm/imx-uart.h |  62 ++++++++
 xen/drivers/char/Kconfig            |   8 +
 xen/drivers/char/Makefile           |   1 +
 xen/drivers/char/imx-uart.c         | 227 ++++++++++++++++++++++++++++
 4 files changed, 298 insertions(+)
 create mode 100644 xen/arch/arm/include/asm/imx-uart.h
 create mode 100644 xen/drivers/char/imx-uart.c

diff --git a/xen/arch/arm/include/asm/imx-uart.h b/xen/arch/arm/include/asm/imx-uart.h
new file mode 100644
index 0000000000..ad4b0b06ff
--- /dev/null
+++ b/xen/arch/arm/include/asm/imx-uart.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * xen/arch/arm/include/asm/imx-uart.h
+ *
+ * Register definitions for the classic i.MX UART IP
+ * ("fsl,imx6q-uart" compatible, used on i.MX6/7/8M families).
+ *
+ * Register layout taken from Linux drivers/tty/serial/imx.c.
+ *
+ * Copyright 2026 Open-EP (E-Paper) Community
+ */
+
+#ifndef __ASM_ARM_IMX_UART_H__
+#define __ASM_ARM_IMX_UART_H__
+
+#define URXD0           0x00   /* Receiver Register */
+#define URTX0           0x40   /* Transmitter Register */
+#define UCR1            0x80   /* Control Register 1 */
+#define UCR2            0x84   /* Control Register 2 */
+#define UCR3            0x88   /* Control Register 3 */
+#define UCR4            0x8c   /* Control Register 4 */
+#define UFCR            0x90   /* FIFO Control Register */
+#define USR1            0x94   /* Status Register 1 */
+#define USR2            0x98   /* Status Register 2 */
+#define UTS             0xb4   /* Test Register */
+
+#define URXD_CHARRDY    (1U << 15)
+#define URXD_RX_DATA    0xff
+
+#define UCR1_UARTEN     (1U << 0)
+#define UCR1_RRDYEN     (1U << 9)   /* Receiver ready interrupt enable */
+#define UCR1_TRDYEN     (1U << 13)  /* Transmitter ready interrupt enable */
+#define UCR1_RXDMAEN    (1U << 8)
+#define UCR1_TXDMAEN    (1U << 3)
+#define UCR1_ATDMAEN    (1U << 2)
+
+#define UCR2_SRST       (1U << 0)   /* 0 = issue software reset */
+#define UCR2_RXEN       (1U << 1)
+#define UCR2_TXEN       (1U << 2)
+
+#define USR1_RRDY       (1U << 9)   /* Receiver ready */
+#define USR1_TRDY       (1U << 13)  /* Transmitter ready */
+
+#define USR2_RDR        (1U << 0)   /* Receive data ready */
+#define USR2_ORE        (1U << 1)   /* Overrun error */
+#define USR2_TXDC       (1U << 3)   /* Transmission complete */
+#define USR2_TXFE       (1U << 14)  /* Transmit FIFO empty */
+
+#define UTS_TXFULL      (1U << 4)
+#define UTS_RXEMPTY     (1U << 5)
+#define UTS_TXEMPTY     (1U << 6)
+
+#endif /* __ASM_ARM_IMX_UART_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/drivers/char/Kconfig b/xen/drivers/char/Kconfig
index 8e49a52c73..f237c0220d 100644
--- a/xen/drivers/char/Kconfig
+++ b/xen/drivers/char/Kconfig
@@ -30,6 +30,14 @@ config HAS_IMX_LPUART
 	help
 	  This selects the i.MX LPUART. If you have i.MX8QM based board, say Y.
 
+config HAS_IMX_UART
+	bool "i.MX UART driver"
+	default y
+	depends on ARM_64
+	help
+	  This selects the classic i.MX UART. If you have an i.MX8M family
+	  based board, say Y.
+
 config HAS_MVEBU
 	bool "Marvell MVEBU UART driver"
 	default y
diff --git a/xen/drivers/char/Makefile b/xen/drivers/char/Makefile
index 8cbbffdca8..039f566926 100644
--- a/xen/drivers/char/Makefile
+++ b/xen/drivers/char/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_HAS_SCIF) += scif-uart.o
 obj-$(CONFIG_HAS_EHCI) += ehci-dbgp.o
 obj-$(CONFIG_XHCI) += xhci-dbc.o
 obj-$(CONFIG_HAS_IMX_LPUART) += imx-lpuart.o
+obj-$(CONFIG_HAS_IMX_UART) += imx-uart.o
 obj-$(CONFIG_HAS_LINFLEX) += linflex-uart.o
 obj-$(CONFIG_GENERIC_UART_INIT) += uart-init.o
 obj-y += serial.o
diff --git a/xen/drivers/char/imx-uart.c b/xen/drivers/char/imx-uart.c
new file mode 100644
index 0000000000..5ae8c13c40
--- /dev/null
+++ b/xen/drivers/char/imx-uart.c
@@ -0,0 +1,227 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * xen/drivers/char/imx-uart.c
+ *
+ * Driver for the classic i.MX UART IP ("fsl,imx6q-uart"), as found on
+ * the i.MX6/7/8M families (e.g. i.MX8MP).
+ *
+ * Baudrate and pin configuration are inherited from the bootloader.
+ *
+ * Copyright 2026 Open-EP (E-Paper) Community
+ */
+
+#include <xen/errno.h>
+#include <xen/init.h>
+#include <xen/irq.h>
+#include <xen/mm.h>
+#include <xen/serial.h>
+#include <asm/device.h>
+#include <asm/imx-uart.h>
+#include <asm/io.h>
+
+#define imx_uart_read(uart, off)       readl((uart)->regs + (off))
+#define imx_uart_write(uart, off, val) writel((val), (uart)->regs + (off))
+
+static struct imx_uart {
+    uint32_t irq;
+    char __iomem *regs;
+    struct irqaction irqaction;
+    struct vuart_info vuart;
+} imx8m_com;
+
+static void imx_uart_interrupt(int irq, void *data)
+{
+    struct serial_port *port = data;
+    struct imx_uart *uart = port->uart;
+
+    if ( imx_uart_read(uart, USR2) & USR2_RDR )
+        serial_rx_interrupt(port);
+
+    if ( imx_uart_read(uart, USR1) & USR1_TRDY )
+        serial_tx_interrupt(port);
+}
+
+static void __init imx_uart_init_preirq(struct serial_port *port)
+{
+    struct imx_uart *uart = port->uart;
+    uint32_t ucr1, ucr2;
+
+    /*
+     * Reuse the bootloader baudrate/format settings: only make sure the
+     * UART and both directions are enabled, DMA and interrupts are off.
+     */
+    ucr1 = imx_uart_read(uart, UCR1);
+    ucr1 &= ~(UCR1_RRDYEN | UCR1_TRDYEN | UCR1_RXDMAEN | UCR1_TXDMAEN |
+              UCR1_ATDMAEN);
+    ucr1 |= UCR1_UARTEN;
+    imx_uart_write(uart, UCR1, ucr1);
+
+    ucr2 = imx_uart_read(uart, UCR2);
+    ucr2 |= UCR2_SRST | UCR2_RXEN | UCR2_TXEN;
+    imx_uart_write(uart, UCR2, ucr2);
+}
+
+static void __init imx_uart_init_postirq(struct serial_port *port)
+{
+    struct imx_uart *uart = port->uart;
+    uint32_t ucr1;
+
+    uart->irqaction.handler = imx_uart_interrupt;
+    uart->irqaction.name = "imx_uart";
+    uart->irqaction.dev_id = port;
+
+    if ( setup_irq(uart->irq, 0, &uart->irqaction) != 0 )
+    {
+        dprintk(XENLOG_ERR, "Failed to allocate imx_uart IRQ %d\n", uart->irq);
+        return;
+    }
+
+    /* Enable the receiver ready interrupt */
+    ucr1 = imx_uart_read(uart, UCR1);
+    ucr1 |= UCR1_RRDYEN;
+    imx_uart_write(uart, UCR1, ucr1);
+}
+
+static int imx_uart_tx_ready(struct serial_port *port)
+{
+    struct imx_uart *uart = port->uart;
+
+    return !(imx_uart_read(uart, UTS) & UTS_TXFULL);
+}
+
+static void imx_uart_putc(struct serial_port *port, char c)
+{
+    struct imx_uart *uart = port->uart;
+
+    while ( imx_uart_read(uart, UTS) & UTS_TXFULL )
+        cpu_relax();
+
+    imx_uart_write(uart, URTX0, c);
+}
+
+static int imx_uart_getc(struct serial_port *port, char *pc)
+{
+    struct imx_uart *uart = port->uart;
+
+    if ( !(imx_uart_read(uart, USR2) & USR2_RDR) )
+        return 0;
+
+    *pc = imx_uart_read(uart, URXD0) & URXD_RX_DATA;
+
+    if ( imx_uart_read(uart, USR2) & USR2_ORE )
+        imx_uart_write(uart, USR2, USR2_ORE);
+
+    return 1;
+}
+
+static int __init imx_uart_irq(struct serial_port *port)
+{
+    struct imx_uart *uart = port->uart;
+
+    return ((uart->irq > 0) ? uart->irq : -1);
+}
+
+static const struct vuart_info *imx_uart_vuart_info(struct serial_port *port)
+{
+    struct imx_uart *uart = port->uart;
+
+    return &uart->vuart;
+}
+
+static void imx_uart_start_tx(struct serial_port *port)
+{
+    struct imx_uart *uart = port->uart;
+    uint32_t ucr1;
+
+    ucr1 = imx_uart_read(uart, UCR1);
+    imx_uart_write(uart, UCR1, ucr1 | UCR1_TRDYEN);
+}
+
+static void imx_uart_stop_tx(struct serial_port *port)
+{
+    struct imx_uart *uart = port->uart;
+    uint32_t ucr1;
+
+    ucr1 = imx_uart_read(uart, UCR1);
+    imx_uart_write(uart, UCR1, ucr1 & ~UCR1_TRDYEN);
+}
+
+static struct uart_driver __read_mostly imx_uart_driver = {
+    .init_preirq = imx_uart_init_preirq,
+    .init_postirq = imx_uart_init_postirq,
+    .tx_ready = imx_uart_tx_ready,
+    .putc = imx_uart_putc,
+    .getc = imx_uart_getc,
+    .irq = imx_uart_irq,
+    .start_tx = imx_uart_start_tx,
+    .stop_tx = imx_uart_stop_tx,
+    .vuart_info = imx_uart_vuart_info,
+};
+
+static int __init imx_uart_init(struct dt_device_node *dev, const void *data)
+{
+    const char *config = data;
+    struct imx_uart *uart;
+    int res;
+    paddr_t addr, size;
+
+    if ( strcmp(config, "") )
+        printk("WARNING: UART configuration is not supported\n");
+
+    uart = &imx8m_com;
+
+    res = dt_device_get_paddr(dev, 0, &addr, &size);
+    if ( res )
+    {
+        printk("imx-uart: Unable to retrieve the base address of the UART\n");
+        return res;
+    }
+
+    res = platform_get_irq(dev, 0);
+    if ( res < 0 )
+    {
+        printk("imx-uart: Unable to retrieve the IRQ\n");
+        return -EINVAL;
+    }
+    uart->irq = res;
+
+    uart->regs = ioremap_nocache(addr, size);
+    if ( !uart->regs )
+    {
+        printk("imx-uart: Unable to map the UART memory\n");
+        return -ENOMEM;
+    }
+
+    uart->vuart.base_addr = addr;
+    uart->vuart.size = size;
+    uart->vuart.data_off = URTX0;
+    uart->vuart.status_off = UTS;
+    uart->vuart.status = UTS_TXEMPTY | UTS_RXEMPTY;
+
+    /* Register with generic serial driver */
+    serial_register_uart(SERHND_DTUART, &imx_uart_driver, uart);
+
+    dt_device_set_used_by(dev, DOMID_XEN);
+
+    return 0;
+}
+
+static const struct dt_device_match imx_uart_dt_compat[] __initconst =
+{
+    DT_MATCH_COMPATIBLE("fsl,imx6q-uart"),
+    { /* sentinel */ },
+};
+
+DT_DEVICE_START(imx_uart, "i.MX UART", DEVICE_SERIAL)
+    .dt_match = imx_uart_dt_compat,
+    .init = imx_uart_init,
+DT_DEVICE_END
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] xen/arm64: add early printk for the classic i.MX UART
  2026-08-14 16:25 [PATCH 0/3] xen/arm: add i.MX8M platform and UART support Wig Cheng
  2026-08-14 16:25 ` [PATCH 1/3] xen/char: add classic i.MX UART driver Wig Cheng
@ 2026-08-14 16:25 ` Wig Cheng
  2026-08-14 16:25 ` [PATCH 3/3] xen/arm: add i.MX8M platform support Wig Cheng
  2 siblings, 0 replies; 4+ messages in thread
From: Wig Cheng @ 2026-08-14 16:25 UTC (permalink / raw)
  To: xen-devel
  Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel,
	Volodymyr Babchuk, John Ernberg, Peng Fan, Wig Cheng

Add an early printk implementation for the classic i.MX UART IP,
selectable via EARLY_UART_CHOICE_IMX_UART.  The UART is expected to be
fully initialized by the bootloader.

Signed-off-by: Wig Cheng <onlywig@gmail.com>
---
 xen/arch/arm/Kconfig.debug            | 12 +++++++++
 xen/arch/arm/arm64/debug-imx-uart.inc | 39 +++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)
 create mode 100644 xen/arch/arm/arm64/debug-imx-uart.inc

diff --git a/xen/arch/arm/Kconfig.debug b/xen/arch/arm/Kconfig.debug
index 5a03b220ac..63a34b813a 100644
--- a/xen/arch/arm/Kconfig.debug
+++ b/xen/arch/arm/Kconfig.debug
@@ -44,6 +44,14 @@ choice
 		  Say Y here if you wish the early printk to direct their
 		  output to a i.MX LPUART.
 
+	config EARLY_UART_CHOICE_IMX_UART
+		select EARLY_UART_IMX_UART
+		depends on ARM_64
+		bool "Early printk via i.MX UART"
+		help
+		  Say Y here if you wish the early printk to direct their
+		  output to the classic i.MX UART (i.MX8M family).
+
 	config EARLY_UART_CHOICE_LINFLEX
 		select EARLY_UART_LINFLEX
 		depends on ARM_64
@@ -97,6 +105,9 @@ config EARLY_UART_EXYNOS4210
 config EARLY_UART_IMX_LPUART
 	select EARLY_PRINTK
 	bool
+config EARLY_UART_IMX_UART
+	select EARLY_PRINTK
+	bool
 config EARLY_UART_LINFLEX
 	select EARLY_PRINTK
 	bool
@@ -185,6 +196,7 @@ config EARLY_PRINTK_INC
 	default "debug-cadence.inc" if EARLY_UART_CADENCE
 	default "debug-exynos4210.inc" if EARLY_UART_EXYNOS4210
 	default "debug-imx-lpuart.inc" if EARLY_UART_IMX_LPUART
+	default "debug-imx-uart.inc" if EARLY_UART_IMX_UART
 	default "debug-linflex.inc" if EARLY_UART_LINFLEX
 	default "debug-meson.inc" if EARLY_UART_MESON
 	default "debug-mvebu.inc" if EARLY_UART_MVEBU
diff --git a/xen/arch/arm/arm64/debug-imx-uart.inc b/xen/arch/arm/arm64/debug-imx-uart.inc
new file mode 100644
index 0000000000..80ac647f5e
--- /dev/null
+++ b/xen/arch/arm/arm64/debug-imx-uart.inc
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * xen/arch/arm/arm64/debug-imx-uart.inc
+ *
+ * Early printk for the classic i.MX UART IP (i.MX6/7/8M families).
+ * The UART is expected to be fully initialized by the bootloader.
+ *
+ * Copyright 2026 Open-EP (E-Paper) Community
+ */
+
+#include <asm/imx-uart.h>
+
+/*
+ * Wait for the UART to be ready to transmit
+ * xb: register which contains the UART base address
+ * c: scratch register
+ */
+.macro early_uart_ready xb, c
+1:
+        ldr   w\c, [\xb, #UTS]        /* <- Test register */
+        tst   w\c, #UTS_TXFULL        /* Check TX FIFO full bit */
+        bne   1b                      /* Wait until there is room */
+.endm
+
+/*
+ * UART transmit character
+ * xb: register which contains the UART base address
+ * wt: register which contains the character to transmit
+ */
+.macro early_uart_transmit xb, wt
+        str   \wt, [\xb, #URTX0]      /* -> Transmitter register */
+.endm
+
+/*
+ * Local variables:
+ * mode: ASM
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] xen/arm: add i.MX8M platform support
  2026-08-14 16:25 [PATCH 0/3] xen/arm: add i.MX8M platform and UART support Wig Cheng
  2026-08-14 16:25 ` [PATCH 1/3] xen/char: add classic i.MX UART driver Wig Cheng
  2026-08-14 16:25 ` [PATCH 2/3] xen/arm64: add early printk for the classic i.MX UART Wig Cheng
@ 2026-08-14 16:25 ` Wig Cheng
  2 siblings, 0 replies; 4+ messages in thread
From: Wig Cheng @ 2026-08-14 16:25 UTC (permalink / raw)
  To: xen-devel
  Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel,
	Volodymyr Babchuk, John Ernberg, Peng Fan, Wig Cheng

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, DDR frequency scaling, SRC
(M-core remoteproc), SoC info, NoC QoS and BBSM tamper status.  There
is no public specification for these calls; the function IDs are taken
from the upstream and vendor kernels.

Forward this reviewed set of calls from the hardware domain, following
the whitelist model of the i.MX8QM platform.  CPU frequency scaling is
denied because the hardware domain cannot make an informed decision,
and any unknown function ID is rejected.

Signed-off-by: Wig Cheng <onlywig@gmail.com>
---
 xen/arch/arm/platforms/Makefile |   1 +
 xen/arch/arm/platforms/imx8m.c  | 116 ++++++++++++++++++++++++++++++++
 2 files changed, 117 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..dc49e754ee
--- /dev/null
+++ b/xen/arch/arm/platforms/imx8m.c
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * xen/arch/arm/platforms/imx8m.c
+ *
+ * i.MX 8M family setup
+ *
+ * Copyright 2026 Open-EP (E-Paper) Community
+ */
+
+#include <xen/sched.h>
+#include <asm/platform.h>
+#include <asm/smccc.h>
+
+static const char * const imx8m_dt_compat[] __initconst =
+{
+    "fsl,imx8mp",
+    "fsl,imx8mq",
+    "fsl,imx8mm",
+    "fsl,imx8mn",
+    NULL
+};
+
+/*
+ * SiP SMC function IDs used by the i.MX8M Linux drivers.  There is no
+ * public specification for these; the IDs and names are extracted from
+ * the upstream and vendor kernels (see drivers/soc/imx, drivers/devfreq,
+ * drivers/remoteproc, drivers/firmware/imx).
+ */
+#define IMX_SIP_GPC         0xC2000000  /* GPC power-domain control */
+#define IMX_SIP_CPUFREQ     0xC2000001
+#define IMX_SIP_DDR_DVFS    0xC2000004  /* DRAM frequency scaling */
+#define IMX_SIP_SRC         0xC2000005  /* SRC: M-core remoteproc start/stop */
+#define IMX_SIP_GET_SOC_INFO 0xC2000006
+#define IMX_SIP_NOC         0xC2000008  /* NoC QoS priority setup */
+#define IMX_SIP_BBSM        0xC200000D  /* BBSM tamper status */
+
+static bool imx8m_smc(struct cpu_user_regs *regs)
+{
+    uint32_t function_id = get_user_reg(regs, 0);
+    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;
+    }
+
+    switch ( function_id )
+    {
+    /*
+     * All of these manage hardware that belongs to the hardware domain
+     * (power domains, DRAM controller, M-core, NoC, secure RTC) or are
+     * read-only queries.  Forward them.
+     */
+    case IMX_SIP_GPC:
+    case IMX_SIP_DDR_DVFS:
+    case IMX_SIP_SRC:
+    case IMX_SIP_GET_SOC_INFO:
+    case IMX_SIP_NOC:
+    case IMX_SIP_BBSM:
+        break;
+
+    /*
+     * CPU frequency scaling: the hardware domain does not see the whole
+     * system and cannot make an informed decision, so deny it (matches
+     * the i.MX8QM platform).
+     */
+    case IMX_SIP_CPUFREQ:
+        return false;
+
+    default:
+        gprintk(XENLOG_WARNING, "imx8m: smc: Unknown function id %x\n",
+                function_id);
+        return false;
+    }
+
+    arm_smccc_1_1_smc(function_id,
+                      get_user_reg(regs, 1),
+                      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



^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-08-14 17:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-14 16:25 [PATCH 0/3] xen/arm: add i.MX8M platform and UART support Wig Cheng
2026-08-14 16:25 ` [PATCH 1/3] xen/char: add classic i.MX UART driver Wig Cheng
2026-08-14 16:25 ` [PATCH 2/3] xen/arm64: add early printk for the classic i.MX UART Wig Cheng
2026-08-14 16:25 ` [PATCH 3/3] xen/arm: add i.MX8M platform support Wig Cheng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.