* [PATCH v2 0/4] xen/arm: add i.MX8M platform and UART support
@ 2026-08-18 2:52 Wig Cheng
2026-08-18 2:52 ` [PATCH v2 1/4] xen/char: add classic i.MX UART driver Wig Cheng
` (4 more replies)
0 siblings, 5 replies; 12+ messages in thread
From: Wig Cheng @ 2026-08-18 2:52 UTC (permalink / raw)
To: xen-devel
Cc: Michal Orzel, Stefano Stabellini, Julien Grall, Bertrand Marquis,
Volodymyr Babchuk, John Ernberg, Peng Fan, Wig Cheng
Following Michal Orzel's review of v1, 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, the platform glue (SiP SMC whitelist for
the calls the dom0 kernel issues to TF-A), and a MAINTAINERS entry.
Tested on i.MX8MP (4x Cortex-A53, GICv3) with the vendor kernel 6.18:
dom0 boots to login on the hypervisor console, and a domU starts with a
PV disk and virtio devices running a full Wayland distro.
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 specific subfunctions the
dom0 kernel issues, extracted from the vendor kernel call sites.
DDR DVFS is left at service level because its reg1 is a frequency
setpoint rather than a fixed subfunction id. No call was denied at
runtime.
Changes since v1:
Patch 1 (UART driver):
- Documentation narrowed to the i.MX8M family (dropped i.MX6/7).
- Relicensed the new files as GPL-2.0-only.
- Dropped the stale file-path lines from the file headers.
- Renamed the header guard to ASM_IMX_UART_H.
- Removed unused register/bit macros; header is now asm-safe (BIT(n, U)).
- Also clear UCR1_TXMPTYEN on init; documented that the console is
driven entirely through UCR1.
Patch 2 (early printk):
- bne -> b.ne.
Patch 3 (platform):
- Build the SiP function IDs with ARM_SMCCC_CALL_VAL (IMX_SIP_FID),
matching the i.MX8QM platform.
- Whitelist per subfunction (GPC, SRC, NoC) instead of whole services;
DDR DVFS and SoC info kept at service level with a comment on why.
- Dropped the BBSM call, which is not issued on i.MX8M.
- Fixed the misleading "secure RTC" comment and a stray space.
Patch 4 (new):
- MAINTAINERS entry, as a separate patch.
v1: https://lore.kernel.org/xen-devel/20260814162535.331459-1-onlywig@gmail.com/
Wig Cheng (4):
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
MAINTAINERS: add myself as reviewer of i.MX8M related patches
MAINTAINERS | 7 +
xen/arch/arm/Kconfig.debug | 12 ++
xen/arch/arm/arm64/debug-imx-uart.inc | 37 +++++
xen/arch/arm/include/asm/imx-uart.h | 57 +++++++
xen/arch/arm/platforms/Makefile | 1 +
xen/arch/arm/platforms/imx8m.c | 152 +++++++++++++++++
xen/drivers/char/Kconfig | 8 +
xen/drivers/char/Makefile | 1 +
xen/drivers/char/imx-uart.c | 226 ++++++++++++++++++++++++++
9 files changed, 501 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] 12+ messages in thread
* [PATCH v2 1/4] xen/char: add classic i.MX UART driver
2026-08-18 2:52 [PATCH v2 0/4] xen/arm: add i.MX8M platform and UART support Wig Cheng
@ 2026-08-18 2:52 ` Wig Cheng
2026-08-18 7:06 ` Orzel, Michal
` (2 more replies)
2026-08-18 2:52 ` [PATCH v2 2/4] xen/arm64: add early printk for the classic i.MX UART Wig Cheng
` (3 subsequent siblings)
4 siblings, 3 replies; 12+ messages in thread
From: Wig Cheng @ 2026-08-18 2:52 UTC (permalink / raw)
To: xen-devel
Cc: Michal Orzel, Stefano Stabellini, Julien Grall, Bertrand Marquis,
Volodymyr Babchuk, John Ernberg, Peng Fan, Wig Cheng
Add a console driver for the classic i.MX UART IP ("fsl,imx6q-uart"
compatible), used as the console UART on the i.MX8M family. 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.
The i.MX8M family's UART IP differs from the LPUART used on
i.MX8QM/8QXP, so a separate driver is needed.
Signed-off-by: Wig Cheng <onlywig@gmail.com>
---
xen/arch/arm/include/asm/imx-uart.h | 57 +++++++
xen/drivers/char/Kconfig | 8 +
xen/drivers/char/Makefile | 1 +
xen/drivers/char/imx-uart.c | 226 ++++++++++++++++++++++++++++
4 files changed, 292 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..a3892020e6
--- /dev/null
+++ b/xen/arch/arm/include/asm/imx-uart.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Register definitions for the classic i.MX UART IP
+ * ("fsl,imx6q-uart" compatible), used as the console UART on the
+ * i.MX8M family.
+ *
+ * Register layout taken from Linux drivers/tty/serial/imx.c.
+ *
+ * Copyright 2026 Open-EP (E-Paper) Community
+ */
+
+#ifndef ASM_IMX_UART_H
+#define ASM_IMX_UART_H
+
+#include <xen/const.h>
+
+#define URXD0 0x00 /* Receiver Register */
+#define URTX0 0x40 /* Transmitter Register */
+#define UCR1 0x80 /* Control Register 1 */
+#define UCR2 0x84 /* Control Register 2 */
+#define USR1 0x94 /* Status Register 1 */
+#define USR2 0x98 /* Status Register 2 */
+#define UTS 0xb4 /* Test Register */
+
+#define URXD_RX_DATA 0xff
+
+#define UCR1_UARTEN BIT(0, U) /* UART enable */
+#define UCR1_ATDMAEN BIT(2, U) /* Aging DMA timer enable */
+#define UCR1_TXDMAEN BIT(3, U) /* Transmitter ready DMA enable */
+#define UCR1_TXMPTYEN BIT(6, U) /* Transmitter empty interrupt enable */
+#define UCR1_RXDMAEN BIT(8, U) /* Receiver ready DMA enable */
+#define UCR1_RRDYEN BIT(9, U) /* Receiver ready interrupt enable */
+#define UCR1_TRDYEN BIT(13, U) /* Transmitter ready interrupt enable */
+
+#define UCR2_SRST BIT(0, U) /* 0 = issue software reset */
+#define UCR2_RXEN BIT(1, U) /* Receiver enable */
+#define UCR2_TXEN BIT(2, U) /* Transmitter enable */
+
+#define USR1_TRDY BIT(13, U) /* Transmitter ready */
+
+#define USR2_RDR BIT(0, U) /* Receive data ready */
+#define USR2_ORE BIT(1, U) /* Overrun error */
+
+#define UTS_TXFULL BIT(4, U) /* TX FIFO full */
+#define UTS_RXEMPTY BIT(5, U) /* RX FIFO empty */
+#define UTS_TXEMPTY BIT(6, U) /* TX FIFO empty */
+
+#endif /* ASM_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..fd34b0cd11
--- /dev/null
+++ b/xen/drivers/char/imx-uart.c
@@ -0,0 +1,226 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Driver for the classic i.MX UART IP ("fsl,imx6q-uart"), used as the
+ * console UART on the i.MX8M family (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 settings; only enable the UART and both
+ * directions. The console uses UCR1 interrupts (RRDYEN/TRDYEN)
+ * exclusively, so just clear UCR1's interrupt and DMA enables.
+ */
+ ucr1 = imx_uart_read(uart, UCR1);
+ ucr1 &= ~(UCR1_RRDYEN | UCR1_TRDYEN | UCR1_TXMPTYEN | 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] 12+ messages in thread
* [PATCH v2 2/4] xen/arm64: add early printk for the classic i.MX UART
2026-08-18 2:52 [PATCH v2 0/4] xen/arm: add i.MX8M platform and UART support Wig Cheng
2026-08-18 2:52 ` [PATCH v2 1/4] xen/char: add classic i.MX UART driver Wig Cheng
@ 2026-08-18 2:52 ` Wig Cheng
2026-08-18 7:18 ` Orzel, Michal
2026-08-18 2:52 ` [PATCH v2 3/4] xen/arm: add i.MX8M platform support Wig Cheng
` (2 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Wig Cheng @ 2026-08-18 2:52 UTC (permalink / raw)
To: xen-devel
Cc: Michal Orzel, Stefano Stabellini, Julien Grall, Bertrand Marquis,
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 | 37 +++++++++++++++++++++++++++
2 files changed, 49 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..19b1679020
--- /dev/null
+++ b/xen/arch/arm/arm64/debug-imx-uart.inc
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Early printk for the classic i.MX UART IP (i.MX8M family).
+ * 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 */
+ b.ne 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] 12+ messages in thread
* [PATCH v2 3/4] xen/arm: add i.MX8M platform support
2026-08-18 2:52 [PATCH v2 0/4] xen/arm: add i.MX8M platform and UART support Wig Cheng
2026-08-18 2:52 ` [PATCH v2 1/4] xen/char: add classic i.MX UART driver Wig Cheng
2026-08-18 2:52 ` [PATCH v2 2/4] xen/arm64: add early printk for the classic i.MX UART Wig Cheng
@ 2026-08-18 2:52 ` Wig Cheng
2026-08-18 7:18 ` Orzel, Michal
2026-08-18 2:52 ` [PATCH v2 4/4] MAINTAINERS: add myself as reviewer of i.MX8M related patches Wig Cheng
2026-08-18 6:28 ` [PATCH v2 0/4] xen/arm: add i.MX8M platform and UART support Orzel, Michal
4 siblings, 1 reply; 12+ messages in thread
From: Wig Cheng @ 2026-08-18 2:52 UTC (permalink / raw)
To: xen-devel
Cc: Michal Orzel, Stefano Stabellini, Julien Grall, Bertrand Marquis,
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 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. Where a service
has a fixed set of subfunctions (GPC, SRC, NoC) they are filtered; DDR
DVFS is left at service level because its reg1 is a frequency setpoint
rather than a fixed subfunction id, and the SoC info call is a read-only
query. 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 | 152 ++++++++++++++++++++++++++++++++
2 files changed, 153 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..fcf01298d8
--- /dev/null
+++ b/xen/arch/arm/platforms/imx8m.c
@@ -0,0 +1,152 @@
+/* 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/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
+#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_STOP 0x02
+
+#define IMX_SIP_NOC_SF_LCDIF 0x00
+#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, DRAM controller, 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 )
+ goto deny_subfunction;
+ break;
+
+ case IMX_SIP_FID(IMX_SIP_F_SRC):
+ if ( subfunction_id > IMX_SIP_SRC_SF_M4_STOP )
+ goto deny_subfunction;
+ break;
+
+ case IMX_SIP_FID(IMX_SIP_F_NOC):
+ if ( subfunction_id > IMX_SIP_NOC_SF_PRIORITY )
+ goto deny_subfunction;
+ break;
+
+ case IMX_SIP_FID(IMX_SIP_F_DDR_DVFS):
+ /*
+ * For DDR DVFS reg1 is a frequency setpoint index (or the
+ * GET_FREQ_COUNT / GET_FREQ_INFO query), not a fixed subfunction
+ * id, so it is not filtered here.
+ */
+ break;
+
+ case IMX_SIP_FID(IMX_SIP_F_SOC_INFO):
+ 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_FID(IMX_SIP_F_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,
+ 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;
+
+ deny_subfunction:
+ gprintk(XENLOG_WARNING,
+ "imx8m: smc: function %x: denied subfunction %x\n",
+ function_id, subfunction_id);
+ return false;
+}
+
+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] 12+ messages in thread
* [PATCH v2 4/4] MAINTAINERS: add myself as reviewer of i.MX8M related patches
2026-08-18 2:52 [PATCH v2 0/4] xen/arm: add i.MX8M platform and UART support Wig Cheng
` (2 preceding siblings ...)
2026-08-18 2:52 ` [PATCH v2 3/4] xen/arm: add i.MX8M platform support Wig Cheng
@ 2026-08-18 2:52 ` Wig Cheng
2026-08-18 7:19 ` Orzel, Michal
2026-08-18 6:28 ` [PATCH v2 0/4] xen/arm: add i.MX8M platform and UART support Orzel, Michal
4 siblings, 1 reply; 12+ messages in thread
From: Wig Cheng @ 2026-08-18 2:52 UTC (permalink / raw)
To: xen-devel
Cc: Michal Orzel, Stefano Stabellini, Julien Grall, Bertrand Marquis,
Volodymyr Babchuk, John Ernberg, Peng Fan, Wig Cheng
I wrote the i.MX8M platform and UART support and can help review
patches touching these areas.
Signed-off-by: Wig Cheng <onlywig@gmail.com>
---
MAINTAINERS | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index ed0ffa608f..0434377fe1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -364,6 +364,13 @@ F: tools/misc/xenhypfs.c
F: xen/common/hypfs.c
F: xen/include/xen/hypfs.h
+IMX8M SUPPORT
+R: Wig Cheng <onlywig@gmail.com>
+F: xen/arch/arm/arm64/debug-imx-uart.inc
+F: xen/arch/arm/include/asm/imx-uart.h
+F: xen/arch/arm/platforms/imx8m.c
+F: xen/drivers/char/imx-uart.c
+
IMX8QM/QXP SUPPORT
R: John Ernberg <john.ernberg@actia.se>
F: xen/arch/arm/platforms/imx8qm.c
--
2.43.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 0/4] xen/arm: add i.MX8M platform and UART support
2026-08-18 2:52 [PATCH v2 0/4] xen/arm: add i.MX8M platform and UART support Wig Cheng
` (3 preceding siblings ...)
2026-08-18 2:52 ` [PATCH v2 4/4] MAINTAINERS: add myself as reviewer of i.MX8M related patches Wig Cheng
@ 2026-08-18 6:28 ` Orzel, Michal
4 siblings, 0 replies; 12+ messages in thread
From: Orzel, Michal @ 2026-08-18 6:28 UTC (permalink / raw)
To: Wig Cheng, xen-devel
Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis,
Volodymyr Babchuk, John Ernberg, Peng Fan
On 18-Aug-26 04:52, Wig Cheng wrote:
> Following Michal Orzel's review of v1, 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, the platform glue (SiP SMC whitelist for
> the calls the dom0 kernel issues to TF-A), and a MAINTAINERS entry.
>
> Tested on i.MX8MP (4x Cortex-A53, GICv3) with the vendor kernel 6.18:
> dom0 boots to login on the hypervisor console, and a domU starts with a
> PV disk and virtio devices running a full Wayland distro.
>
> 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 specific subfunctions the
> dom0 kernel issues, extracted from the vendor kernel call sites.
> DDR DVFS is left at service level because its reg1 is a frequency
> setpoint rather than a fixed subfunction id. No call was denied at
> runtime.
>
> Changes since v1:
>
> Patch 1 (UART driver):
> - Documentation narrowed to the i.MX8M family (dropped i.MX6/7).
> - Relicensed the new files as GPL-2.0-only.
> - Dropped the stale file-path lines from the file headers.
> - Renamed the header guard to ASM_IMX_UART_H.
> - Removed unused register/bit macros; header is now asm-safe (BIT(n, U)).
> - Also clear UCR1_TXMPTYEN on init; documented that the console is
> driven entirely through UCR1.
For the future, please include the changeset in the individual patches. This way
it's easier for us to review without having to switch between e-mails.
~Michal
>
> Patch 2 (early printk):
> - bne -> b.ne.
>
> Patch 3 (platform):
> - Build the SiP function IDs with ARM_SMCCC_CALL_VAL (IMX_SIP_FID),
> matching the i.MX8QM platform.
> - Whitelist per subfunction (GPC, SRC, NoC) instead of whole services;
> DDR DVFS and SoC info kept at service level with a comment on why.
> - Dropped the BBSM call, which is not issued on i.MX8M.
> - Fixed the misleading "secure RTC" comment and a stray space.
>
> Patch 4 (new):
> - MAINTAINERS entry, as a separate patch.
>
> v1: https://lore.kernel.org/xen-devel/20260814162535.331459-1-onlywig@gmail.com/
>
>
> Wig Cheng (4):
> 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
> MAINTAINERS: add myself as reviewer of i.MX8M related patches
>
> MAINTAINERS | 7 +
> xen/arch/arm/Kconfig.debug | 12 ++
> xen/arch/arm/arm64/debug-imx-uart.inc | 37 +++++
> xen/arch/arm/include/asm/imx-uart.h | 57 +++++++
> xen/arch/arm/platforms/Makefile | 1 +
> xen/arch/arm/platforms/imx8m.c | 152 +++++++++++++++++
> xen/drivers/char/Kconfig | 8 +
> xen/drivers/char/Makefile | 1 +
> xen/drivers/char/imx-uart.c | 226 ++++++++++++++++++++++++++
> 9 files changed, 501 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
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/4] xen/char: add classic i.MX UART driver
2026-08-18 2:52 ` [PATCH v2 1/4] xen/char: add classic i.MX UART driver Wig Cheng
@ 2026-08-18 7:06 ` Orzel, Michal
2026-08-18 7:13 ` Orzel, Michal
2026-08-18 7:18 ` Orzel, Michal
2 siblings, 0 replies; 12+ messages in thread
From: Orzel, Michal @ 2026-08-18 7:06 UTC (permalink / raw)
To: Wig Cheng, xen-devel
Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis,
Volodymyr Babchuk, John Ernberg, Peng Fan
On 18-Aug-26 04:52, Wig Cheng wrote:
> Add a console driver for the classic i.MX UART IP ("fsl,imx6q-uart"
> compatible), used as the console UART on the i.MX8M family. 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.
>
> The i.MX8M family's UART IP differs from the LPUART used on
> i.MX8QM/8QXP, so a separate driver is needed.
>
> Signed-off-by: Wig Cheng <onlywig@gmail.com>
> ---
> xen/arch/arm/include/asm/imx-uart.h | 57 +++++++
> xen/drivers/char/Kconfig | 8 +
> xen/drivers/char/Makefile | 1 +
> xen/drivers/char/imx-uart.c | 226 ++++++++++++++++++++++++++++
You should add an entry to the MAINTAINERS file for imx-uart.c so that it falls
down under ARM maintainership. Your last patch makes you a reviewer but we still
need to be maintainers of it. See how it was done for IMX8QM.
> 4 files changed, 292 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..a3892020e6
> --- /dev/null
> +++ b/xen/arch/arm/include/asm/imx-uart.h
> @@ -0,0 +1,57 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Register definitions for the classic i.MX UART IP
> + * ("fsl,imx6q-uart" compatible), used as the console UART on the
> + * i.MX8M family.
> + *
> + * Register layout taken from Linux drivers/tty/serial/imx.c.
> + *
> + * Copyright 2026 Open-EP (E-Paper) Community
> + */
> +
> +#ifndef ASM_IMX_UART_H
> +#define ASM_IMX_UART_H
> +
> +#include <xen/const.h>
> +
> +#define URXD0 0x00 /* Receiver Register */
> +#define URTX0 0x40 /* Transmitter Register */
> +#define UCR1 0x80 /* Control Register 1 */
> +#define UCR2 0x84 /* Control Register 2 */
> +#define USR1 0x94 /* Status Register 1 */
> +#define USR2 0x98 /* Status Register 2 */
> +#define UTS 0xb4 /* Test Register */
> +
> +#define URXD_RX_DATA 0xff
> +
> +#define UCR1_UARTEN BIT(0, U) /* UART enable */
> +#define UCR1_ATDMAEN BIT(2, U) /* Aging DMA timer enable */
> +#define UCR1_TXDMAEN BIT(3, U) /* Transmitter ready DMA enable */
> +#define UCR1_TXMPTYEN BIT(6, U) /* Transmitter empty interrupt enable */
> +#define UCR1_RXDMAEN BIT(8, U) /* Receiver ready DMA enable */
> +#define UCR1_RRDYEN BIT(9, U) /* Receiver ready interrupt enable */
> +#define UCR1_TRDYEN BIT(13, U) /* Transmitter ready interrupt enable */
> +
> +#define UCR2_SRST BIT(0, U) /* 0 = issue software reset */
> +#define UCR2_RXEN BIT(1, U) /* Receiver enable */
> +#define UCR2_TXEN BIT(2, U) /* Transmitter enable */
> +
> +#define USR1_TRDY BIT(13, U) /* Transmitter ready */
> +
> +#define USR2_RDR BIT(0, U) /* Receive data ready */
> +#define USR2_ORE BIT(1, U) /* Overrun error */
> +
> +#define UTS_TXFULL BIT(4, U) /* TX FIFO full */
> +#define UTS_RXEMPTY BIT(5, U) /* RX FIFO empty */
> +#define UTS_TXEMPTY BIT(6, U) /* TX FIFO empty */
> +
> +#endif /* ASM_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..fd34b0cd11
> --- /dev/null
> +++ b/xen/drivers/char/imx-uart.c
> @@ -0,0 +1,226 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Driver for the classic i.MX UART IP ("fsl,imx6q-uart"), used as the
> + * console UART on the i.MX8M family (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 )
Looking at Linux's imx.c you should clear TRDY if TRDEN is not enabled to
prevent RX interrupt entering serial_tx_interrupt as TRDY is a raw status register.
> + 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 settings; only enable the UART and both
> + * directions. The console uses UCR1 interrupts (RRDYEN/TRDYEN)
> + * exclusively, so just clear UCR1's interrupt and DMA enables.
> + */
> + ucr1 = imx_uart_read(uart, UCR1);
> + ucr1 &= ~(UCR1_RRDYEN | UCR1_TRDYEN | UCR1_TXMPTYEN | 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);
uart->irq is unsigned, so s/%d/%u.
~Michal
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/4] xen/char: add classic i.MX UART driver
2026-08-18 2:52 ` [PATCH v2 1/4] xen/char: add classic i.MX UART driver Wig Cheng
2026-08-18 7:06 ` Orzel, Michal
@ 2026-08-18 7:13 ` Orzel, Michal
2026-08-18 7:18 ` Orzel, Michal
2 siblings, 0 replies; 12+ messages in thread
From: Orzel, Michal @ 2026-08-18 7:13 UTC (permalink / raw)
To: Wig Cheng, xen-devel
Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis,
Volodymyr Babchuk, John Ernberg, Peng Fan
On 18-Aug-26 04:52, Wig Cheng wrote:
> Add a console driver for the classic i.MX UART IP ("fsl,imx6q-uart"
> compatible), used as the console UART on the i.MX8M family. 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.
>
> The i.MX8M family's UART IP differs from the LPUART used on
> i.MX8QM/8QXP, so a separate driver is needed.
>
> Signed-off-by: Wig Cheng <onlywig@gmail.com>
> ---
> xen/arch/arm/include/asm/imx-uart.h | 57 +++++++
> xen/drivers/char/Kconfig | 8 +
> xen/drivers/char/Makefile | 1 +
> xen/drivers/char/imx-uart.c | 226 ++++++++++++++++++++++++++++
You should add an entry to the MAINTAINERS file for imx-uart.c so that it falls
down under ARM maintainership. Your last patch makes you a reviewer but we still
need to be maintainers of it. See how it was done for IMX8QM.
> 4 files changed, 292 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..a3892020e6
> --- /dev/null
> +++ b/xen/arch/arm/include/asm/imx-uart.h
> @@ -0,0 +1,57 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Register definitions for the classic i.MX UART IP
> + * ("fsl,imx6q-uart" compatible), used as the console UART on the
> + * i.MX8M family.
> + *
> + * Register layout taken from Linux drivers/tty/serial/imx.c.
> + *
> + * Copyright 2026 Open-EP (E-Paper) Community
> + */
> +
> +#ifndef ASM_IMX_UART_H
> +#define ASM_IMX_UART_H
> +
> +#include <xen/const.h>
> +
> +#define URXD0 0x00 /* Receiver Register */
> +#define URTX0 0x40 /* Transmitter Register */
> +#define UCR1 0x80 /* Control Register 1 */
> +#define UCR2 0x84 /* Control Register 2 */
> +#define USR1 0x94 /* Status Register 1 */
> +#define USR2 0x98 /* Status Register 2 */
> +#define UTS 0xb4 /* Test Register */
> +
> +#define URXD_RX_DATA 0xff
> +
> +#define UCR1_UARTEN BIT(0, U) /* UART enable */
> +#define UCR1_ATDMAEN BIT(2, U) /* Aging DMA timer enable */
> +#define UCR1_TXDMAEN BIT(3, U) /* Transmitter ready DMA enable */
> +#define UCR1_TXMPTYEN BIT(6, U) /* Transmitter empty interrupt enable */
> +#define UCR1_RXDMAEN BIT(8, U) /* Receiver ready DMA enable */
> +#define UCR1_RRDYEN BIT(9, U) /* Receiver ready interrupt enable */
> +#define UCR1_TRDYEN BIT(13, U) /* Transmitter ready interrupt enable */
> +
> +#define UCR2_SRST BIT(0, U) /* 0 = issue software reset */
> +#define UCR2_RXEN BIT(1, U) /* Receiver enable */
> +#define UCR2_TXEN BIT(2, U) /* Transmitter enable */
> +
> +#define USR1_TRDY BIT(13, U) /* Transmitter ready */
> +
> +#define USR2_RDR BIT(0, U) /* Receive data ready */
> +#define USR2_ORE BIT(1, U) /* Overrun error */
> +
> +#define UTS_TXFULL BIT(4, U) /* TX FIFO full */
> +#define UTS_RXEMPTY BIT(5, U) /* RX FIFO empty */
> +#define UTS_TXEMPTY BIT(6, U) /* TX FIFO empty */
> +
> +#endif /* ASM_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..fd34b0cd11
> --- /dev/null
> +++ b/xen/drivers/char/imx-uart.c
> @@ -0,0 +1,226 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Driver for the classic i.MX UART IP ("fsl,imx6q-uart"), used as the
> + * console UART on the i.MX8M family (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 )
Looking at Linux's imx.c you should clear TRDY if TRDEN is not enabled to
prevent RX interrupt entering serial_tx_interrupt as TRDY is a raw status register.
> + 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 settings; only enable the UART and both
> + * directions. The console uses UCR1 interrupts (RRDYEN/TRDYEN)
> + * exclusively, so just clear UCR1's interrupt and DMA enables.
> + */
> + ucr1 = imx_uart_read(uart, UCR1);
> + ucr1 &= ~(UCR1_RRDYEN | UCR1_TRDYEN | UCR1_TXMPTYEN | 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);
uart->irq is unsigned, so s/%d/%u.
~Michal
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/4] xen/char: add classic i.MX UART driver
2026-08-18 2:52 ` [PATCH v2 1/4] xen/char: add classic i.MX UART driver Wig Cheng
2026-08-18 7:06 ` Orzel, Michal
2026-08-18 7:13 ` Orzel, Michal
@ 2026-08-18 7:18 ` Orzel, Michal
2 siblings, 0 replies; 12+ messages in thread
From: Orzel, Michal @ 2026-08-18 7:18 UTC (permalink / raw)
To: Wig Cheng, xen-devel
Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis,
Volodymyr Babchuk, John Ernberg, Peng Fan
On 18-Aug-26 04:52, Wig Cheng wrote:
> Add a console driver for the classic i.MX UART IP ("fsl,imx6q-uart"
> compatible), used as the console UART on the i.MX8M family. 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.
>
> The i.MX8M family's UART IP differs from the LPUART used on
> i.MX8QM/8QXP, so a separate driver is needed.
>
> Signed-off-by: Wig Cheng <onlywig@gmail.com>
> ---
> xen/arch/arm/include/asm/imx-uart.h | 57 +++++++
> xen/drivers/char/Kconfig | 8 +
> xen/drivers/char/Makefile | 1 +
> xen/drivers/char/imx-uart.c | 226 ++++++++++++++++++++++++++++
You should add an entry to the MAINTAINERS file for imx-uart.c so that it falls
down under ARM maintainership. Your last patch makes you a reviewer but we still
need to be maintainers of it. See how it was done for IMX8QM.
> 4 files changed, 292 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..a3892020e6
> --- /dev/null
> +++ b/xen/arch/arm/include/asm/imx-uart.h
> @@ -0,0 +1,57 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Register definitions for the classic i.MX UART IP
> + * ("fsl,imx6q-uart" compatible), used as the console UART on the
> + * i.MX8M family.
> + *
> + * Register layout taken from Linux drivers/tty/serial/imx.c.
> + *
> + * Copyright 2026 Open-EP (E-Paper) Community
> + */
> +
> +#ifndef ASM_IMX_UART_H
> +#define ASM_IMX_UART_H
> +
> +#include <xen/const.h>
> +
> +#define URXD0 0x00 /* Receiver Register */
> +#define URTX0 0x40 /* Transmitter Register */
> +#define UCR1 0x80 /* Control Register 1 */
> +#define UCR2 0x84 /* Control Register 2 */
> +#define USR1 0x94 /* Status Register 1 */
> +#define USR2 0x98 /* Status Register 2 */
> +#define UTS 0xb4 /* Test Register */
> +
> +#define URXD_RX_DATA 0xff
> +
> +#define UCR1_UARTEN BIT(0, U) /* UART enable */
> +#define UCR1_ATDMAEN BIT(2, U) /* Aging DMA timer enable */
> +#define UCR1_TXDMAEN BIT(3, U) /* Transmitter ready DMA enable */
> +#define UCR1_TXMPTYEN BIT(6, U) /* Transmitter empty interrupt enable */
> +#define UCR1_RXDMAEN BIT(8, U) /* Receiver ready DMA enable */
> +#define UCR1_RRDYEN BIT(9, U) /* Receiver ready interrupt enable */
> +#define UCR1_TRDYEN BIT(13, U) /* Transmitter ready interrupt enable */
> +
> +#define UCR2_SRST BIT(0, U) /* 0 = issue software reset */
> +#define UCR2_RXEN BIT(1, U) /* Receiver enable */
> +#define UCR2_TXEN BIT(2, U) /* Transmitter enable */
> +
> +#define USR1_TRDY BIT(13, U) /* Transmitter ready */
> +
> +#define USR2_RDR BIT(0, U) /* Receive data ready */
> +#define USR2_ORE BIT(1, U) /* Overrun error */
> +
> +#define UTS_TXFULL BIT(4, U) /* TX FIFO full */
> +#define UTS_RXEMPTY BIT(5, U) /* RX FIFO empty */
> +#define UTS_TXEMPTY BIT(6, U) /* TX FIFO empty */
> +
> +#endif /* ASM_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..fd34b0cd11
> --- /dev/null
> +++ b/xen/drivers/char/imx-uart.c
> @@ -0,0 +1,226 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Driver for the classic i.MX UART IP ("fsl,imx6q-uart"), used as the
> + * console UART on the i.MX8M family (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 )
Looking at Linux's imx.c you should clear TRDY if TRDEN is not enabled to
prevent RX interrupt entering serial_tx_interrupt as TRDY is a raw status register.
> + 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 settings; only enable the UART and both
> + * directions. The console uses UCR1 interrupts (RRDYEN/TRDYEN)
> + * exclusively, so just clear UCR1's interrupt and DMA enables.
> + */
> + ucr1 = imx_uart_read(uart, UCR1);
> + ucr1 &= ~(UCR1_RRDYEN | UCR1_TRDYEN | UCR1_TXMPTYEN | 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);
uart->irq is unsigned, so s/%d/%u.
~Michal
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/4] xen/arm64: add early printk for the classic i.MX UART
2026-08-18 2:52 ` [PATCH v2 2/4] xen/arm64: add early printk for the classic i.MX UART Wig Cheng
@ 2026-08-18 7:18 ` Orzel, Michal
0 siblings, 0 replies; 12+ messages in thread
From: Orzel, Michal @ 2026-08-18 7:18 UTC (permalink / raw)
To: Wig Cheng, xen-devel
Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis,
Volodymyr Babchuk, John Ernberg, Peng Fan
On 18-Aug-26 04:52, Wig Cheng wrote:
> 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>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
~Michal
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/4] xen/arm: add i.MX8M platform support
2026-08-18 2:52 ` [PATCH v2 3/4] xen/arm: add i.MX8M platform support Wig Cheng
@ 2026-08-18 7:18 ` Orzel, Michal
0 siblings, 0 replies; 12+ messages in thread
From: Orzel, Michal @ 2026-08-18 7:18 UTC (permalink / raw)
To: Wig Cheng, xen-devel
Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis,
Volodymyr Babchuk, John Ernberg, Peng Fan
On 18-Aug-26 04:52, Wig Cheng wrote:
> 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 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. Where a service
> has a fixed set of subfunctions (GPC, SRC, NoC) they are filtered; DDR
> DVFS is left at service level because its reg1 is a frequency setpoint
> rather than a fixed subfunction id, and the SoC info call is a read-only
> query. 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 | 152 ++++++++++++++++++++++++++++++++
> 2 files changed, 153 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..fcf01298d8
> --- /dev/null
> +++ b/xen/arch/arm/platforms/imx8m.c
> @@ -0,0 +1,152 @@
> +/* 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/smccc.h>
You should also include asm/regs.h for `get/set_user_regs()`
> +
> +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
Why no description?
> +#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
This seems to be unused. Why?
> +#define IMX_SIP_SRC_SF_M4_STOP 0x02
> +
> +#define IMX_SIP_NOC_SF_LCDIF 0x00
This seems to be unused. Why?
> +#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, DRAM controller, 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 )
> + goto deny_subfunction;
> + break;
> +
> + case IMX_SIP_FID(IMX_SIP_F_SRC):
Please list the cases in an order (GPC, CPUFREQ ...)
> + if ( subfunction_id > IMX_SIP_SRC_SF_M4_STOP )
> + goto deny_subfunction;
> + break;
> +
> + case IMX_SIP_FID(IMX_SIP_F_NOC):
> + if ( subfunction_id > IMX_SIP_NOC_SF_PRIORITY )
> + goto deny_subfunction;
> + break;
> +
> + case IMX_SIP_FID(IMX_SIP_F_DDR_DVFS):
IMO the stated reason for CPUFREQ applies here as well and we should rather deny
this call. What makes it safe in your opinion to allow this call?
> + /*
> + * For DDR DVFS reg1 is a frequency setpoint index (or the
> + * GET_FREQ_COUNT / GET_FREQ_INFO query), not a fixed subfunction
> + * id, so it is not filtered here.
> + */
> + break;
> +
> + case IMX_SIP_FID(IMX_SIP_F_SOC_INFO):
> + 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_FID(IMX_SIP_F_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,
> + 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;
> +
> + deny_subfunction:
> + gprintk(XENLOG_WARNING,
> + "imx8m: smc: function %x: denied subfunction %x\n",
> + function_id, subfunction_id);
IMO just return false directly on deny, no need for goto and printk, given that
Xen will also print Unhandled SMC/HVC from `vsmccc_handle_call()`.
> + return false;
> +}
> +
> +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:
> + */
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 4/4] MAINTAINERS: add myself as reviewer of i.MX8M related patches
2026-08-18 2:52 ` [PATCH v2 4/4] MAINTAINERS: add myself as reviewer of i.MX8M related patches Wig Cheng
@ 2026-08-18 7:19 ` Orzel, Michal
0 siblings, 0 replies; 12+ messages in thread
From: Orzel, Michal @ 2026-08-18 7:19 UTC (permalink / raw)
To: Wig Cheng, xen-devel
Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis,
Volodymyr Babchuk, John Ernberg, Peng Fan
On 18-Aug-26 04:52, Wig Cheng wrote:
> I wrote the i.MX8M platform and UART support and can help review
> patches touching these areas.
>
> Signed-off-by: Wig Cheng <onlywig@gmail.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
~Michal
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-08-18 7:22 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-18 2:52 [PATCH v2 0/4] xen/arm: add i.MX8M platform and UART support Wig Cheng
2026-08-18 2:52 ` [PATCH v2 1/4] xen/char: add classic i.MX UART driver Wig Cheng
2026-08-18 7:06 ` Orzel, Michal
2026-08-18 7:13 ` Orzel, Michal
2026-08-18 7:18 ` Orzel, Michal
2026-08-18 2:52 ` [PATCH v2 2/4] xen/arm64: add early printk for the classic i.MX UART Wig Cheng
2026-08-18 7:18 ` Orzel, Michal
2026-08-18 2:52 ` [PATCH v2 3/4] xen/arm: add i.MX8M platform support Wig Cheng
2026-08-18 7:18 ` Orzel, Michal
2026-08-18 2:52 ` [PATCH v2 4/4] MAINTAINERS: add myself as reviewer of i.MX8M related patches Wig Cheng
2026-08-18 7:19 ` Orzel, Michal
2026-08-18 6:28 ` [PATCH v2 0/4] xen/arm: add i.MX8M platform and UART support Orzel, Michal
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.