* [PATCH v5 0/7] m68k: Add support for QEMU virt machine
@ 2026-01-05 16:52 Kuan-Wei Chiu
2026-01-05 16:52 ` [PATCH v5 1/7] serial: Add Goldfish TTY driver Kuan-Wei Chiu
` (6 more replies)
0 siblings, 7 replies; 26+ messages in thread
From: Kuan-Wei Chiu @ 2026-01-05 16:52 UTC (permalink / raw)
To: alison.wang, angelo, trini
Cc: me, daniel, heinrich.schuchardt, jserv, eleanor15x, u-boot,
Kuan-Wei Chiu
Add support for the QEMU 'virt' machine on the m68k architecture. The
QEMU virt machine models a generic system utilizing Goldfish virtual
peripherals and is capable of emulating various classic 68k CPUs.
Currently, U-Boot's m68k architecture support focuses on ColdFire
variants. Expand this to include the classic M680x0 architecture,
implementing the necessary exception vectors, startup code, and a
bootinfo parser compatible with the QEMU interface. A driver for the
Goldfish TTY is also added to enable serial console output.
The implementation has been verified on QEMU targeting the M68040 CPU,
confirming successful hardware initialization and boot to the U-Boot
command shell. Additionally, the CI configuration was verified locally
using gitlab-ci-local "qemu_m68k_virt test.py", resulting in
PASS qemu_m68k_virt test.py.
---
Changes in v5:
- Rebase on u-boot/next branch.
- Add 'imply CMD_DM' to TARGET_QEMU_M68K in Kconfig.
- Add a new patch to update the M68K entry in MAINTAINERS and add myself
as a co-maintainer.
Changes in v4:
- Support DT probing with platform data as a fallback. (serial & timer)
- Fix sandbox build warnings by removing incorrect type casting.
- Add comment explaining read latching behavior in the timer driver.
- Sort headers alphabetically in the timer driver.
Changes in v3:
- Add Goldfish timer driver.
- Update Goldfish RTC driver to support non-DT probing.
- Enable Goldfish RTC and Timer support in board configuration.
- Add safety loop limit to bootinfo parsing in dram_init.
- Remove dummy timer functions from architecture code.
- Remove unnecessary type casts in Goldfish TTY driver.
- Remove TEST_PY_ID from CI job definitions.
- Update documentation to include new RTC support.
Changes in v2:
- Refactor Goldfish TTY driver to use priv data for the RX buffer and
ensure single-byte reads.
- Rename arch/m68k/cpu/m68040 to arch/m68k/cpu/m680x0 to separate the
architecture family from the specific CPU model.
- Introduce M680x0 Kconfig symbol and separate MAINTAINERS entries for
the architecture and the board.
- Regenerate qemu-m68k_defconfig using make savedefconfig and add the
board to the documentation index.
- Add a new patch to enable CI testing on GitLab and Azure Pipelines.
- Update SPDX identifiers to GPL-2.0-or-later.
- Sort headers alphabetically.
- Fix tabs vs spaces.
v4: https://lore.kernel.org/u-boot/20260101175420.4118024-1-visitorckw@gmail.com/
v3: https://lore.kernel.org/u-boot/20251230160112.3045527-1-visitorckw@gmail.com/
v2: https://lore.kernel.org/u-boot/20251226175400.1154417-1-visitorckw@gmail.com/
v1: https://lore.kernel.org/u-boot/20251218185252.957388-1-visitorckw@gmail.com/
Kuan-Wei Chiu (7):
serial: Add Goldfish TTY driver
timer: Add Goldfish timer driver
rtc: goldfish: Support platform data for non-DT probing
m68k: Add support for M68040 CPU
board: Add QEMU m68k virt board support
CI: Add test jobs for QEMU m68k virt machine
MAINTAINERS: Update m68k entry
.azure-pipelines.yml | 3 +
.gitlab-ci.yml | 6 ++
MAINTAINERS | 21 ++++-
arch/m68k/Kconfig | 25 ++++++
arch/m68k/Makefile | 1 +
arch/m68k/config.mk | 10 ++-
arch/m68k/cpu/m680x0/Makefile | 6 ++
arch/m68k/cpu/m680x0/cpu.c | 72 ++++++++++++++++
arch/m68k/cpu/m680x0/start.S | 73 ++++++++++++++++
arch/m68k/cpu/m680x0/u-boot.lds | 47 +++++++++++
arch/m68k/include/asm/bootinfo.h | 31 +++++++
arch/m68k/lib/Makefile | 9 +-
board/emulation/qemu-m68k/Kconfig | 12 +++
board/emulation/qemu-m68k/MAINTAINERS | 8 ++
board/emulation/qemu-m68k/Makefile | 5 ++
board/emulation/qemu-m68k/qemu-m68k.c | 115 ++++++++++++++++++++++++++
configs/qemu-m68k_defconfig | 16 ++++
doc/board/emulation/index.rst | 1 +
doc/board/emulation/qemu-m68k.rst | 39 +++++++++
drivers/rtc/goldfish_rtc.c | 13 ++-
drivers/serial/Kconfig | 8 ++
drivers/serial/Makefile | 1 +
drivers/serial/serial_goldfish.c | 109 ++++++++++++++++++++++++
drivers/timer/Kconfig | 8 ++
drivers/timer/Makefile | 1 +
drivers/timer/goldfish_timer.c | 81 ++++++++++++++++++
include/configs/qemu-m68k.h | 18 ++++
include/goldfish_rtc.h | 15 ++++
include/goldfish_timer.h | 13 +++
include/goldfish_tty.h | 18 ++++
30 files changed, 773 insertions(+), 12 deletions(-)
create mode 100644 arch/m68k/cpu/m680x0/Makefile
create mode 100644 arch/m68k/cpu/m680x0/cpu.c
create mode 100644 arch/m68k/cpu/m680x0/start.S
create mode 100644 arch/m68k/cpu/m680x0/u-boot.lds
create mode 100644 arch/m68k/include/asm/bootinfo.h
create mode 100644 board/emulation/qemu-m68k/Kconfig
create mode 100644 board/emulation/qemu-m68k/MAINTAINERS
create mode 100644 board/emulation/qemu-m68k/Makefile
create mode 100644 board/emulation/qemu-m68k/qemu-m68k.c
create mode 100644 configs/qemu-m68k_defconfig
create mode 100644 doc/board/emulation/qemu-m68k.rst
create mode 100644 drivers/serial/serial_goldfish.c
create mode 100644 drivers/timer/goldfish_timer.c
create mode 100644 include/configs/qemu-m68k.h
create mode 100644 include/goldfish_rtc.h
create mode 100644 include/goldfish_timer.h
create mode 100644 include/goldfish_tty.h
--
2.52.0.358.g0dd7633a29-goog
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v5 1/7] serial: Add Goldfish TTY driver
2026-01-05 16:52 [PATCH v5 0/7] m68k: Add support for QEMU virt machine Kuan-Wei Chiu
@ 2026-01-05 16:52 ` Kuan-Wei Chiu
2026-01-05 23:30 ` Simon Glass
2026-01-07 10:59 ` Angelo Dureghello
2026-01-05 16:52 ` [PATCH v5 2/7] timer: Add Goldfish timer driver Kuan-Wei Chiu
` (5 subsequent siblings)
6 siblings, 2 replies; 26+ messages in thread
From: Kuan-Wei Chiu @ 2026-01-05 16:52 UTC (permalink / raw)
To: alison.wang, angelo, trini
Cc: me, daniel, heinrich.schuchardt, jserv, eleanor15x, u-boot,
Kuan-Wei Chiu
Add support for the Google Goldfish TTY serial device. This virtual
device is commonly used in QEMU virtual machines (such as the m68k
virt machine) and Android emulators.
The driver implements basic console output and input polling using the
Goldfish MMIO interface.
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
Reviewed-by: Yao Zi <me@ziyao.cc>
Tested-by: Daniel Palmer <daniel@0x0f.com>
Acked-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
---
Changes in v5:
- Rebase on u-boot/next branch.
MAINTAINERS | 6 ++
drivers/serial/Kconfig | 8 +++
drivers/serial/Makefile | 1 +
drivers/serial/serial_goldfish.c | 109 +++++++++++++++++++++++++++++++
include/goldfish_tty.h | 18 +++++
5 files changed, 142 insertions(+)
create mode 100644 drivers/serial/serial_goldfish.c
create mode 100644 include/goldfish_tty.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 27ce73d83f4..8f884ff495a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1260,6 +1260,12 @@ S: Maintained
F: drivers/misc/gsc.c
F: include/gsc.h
+GOLDFISH SERIAL DRIVER
+M: Kuan-Wei Chiu <visitorckw@gmail.com>
+S: Maintained
+F: drivers/serial/serial_goldfish.c
+F: include/goldfish_tty.h
+
INTERCONNECT:
M: Neil Armstrong <neil.armstrong@linaro.org>
S: Maintained
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 371d7aa5bba..b84cb9ec781 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1193,4 +1193,12 @@ config SYS_SDMR
depends on MPC8XX_CONS
default 0x0
+config SERIAL_GOLDFISH
+ bool "Goldfish TTY support"
+ depends on DM_SERIAL
+ help
+ Select this to enable support for the Goldfish TTY serial port.
+ This virtual device is commonly used by QEMU virtual machines
+ (e.g. m68k virt) for console output.
+
endif
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 8eaae62b0fc..fe8d23be512 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -63,3 +63,4 @@ obj-$(CONFIG_XTENSA_SEMIHOSTING_SERIAL) += serial_xtensa_semihosting.o
obj-$(CONFIG_S5P4418_PL011_SERIAL) += serial_s5p4418_pl011.o
obj-$(CONFIG_UART4_SERIAL) += serial_adi_uart4.o
+obj-$(CONFIG_SERIAL_GOLDFISH) += serial_goldfish.o
diff --git a/drivers/serial/serial_goldfish.c b/drivers/serial/serial_goldfish.c
new file mode 100644
index 00000000000..278d0cf3e0d
--- /dev/null
+++ b/drivers/serial/serial_goldfish.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+ * Goldfish TTY driver for U-Boot
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <goldfish_tty.h>
+#include <linux/types.h>
+#include <mapmem.h>
+#include <serial.h>
+
+/* Goldfish TTY Register Offsets */
+#define GOLDFISH_TTY_PUT_CHAR 0x00
+#define GOLDFISH_TTY_BYTES_READY 0x04
+#define GOLDFISH_TTY_CMD 0x08
+#define GOLDFISH_TTY_DATA_PTR 0x10
+#define GOLDFISH_TTY_DATA_LEN 0x14
+#define GOLDFISH_TTY_DATA_PTR_HIGH 0x18
+#define GOLDFISH_TTY_VERSION 0x20
+
+/* Commands */
+#define CMD_WRITE_BUFFER 2
+#define CMD_READ_BUFFER 3
+
+struct goldfish_tty_priv {
+ void __iomem *base;
+ u8 rx_buf;
+};
+
+static int goldfish_serial_getc(struct udevice *dev)
+{
+ struct goldfish_tty_priv *priv = dev_get_priv(dev);
+ unsigned long paddr;
+ u32 count;
+
+ count = __raw_readl(priv->base + GOLDFISH_TTY_BYTES_READY);
+ if (count == 0)
+ return -EAGAIN;
+
+ paddr = virt_to_phys((void *)&priv->rx_buf);
+
+ __raw_writel(0, priv->base + GOLDFISH_TTY_DATA_PTR_HIGH);
+ __raw_writel(paddr, priv->base + GOLDFISH_TTY_DATA_PTR);
+ __raw_writel(1, priv->base + GOLDFISH_TTY_DATA_LEN);
+ __raw_writel(CMD_READ_BUFFER, priv->base + GOLDFISH_TTY_CMD);
+
+ return priv->rx_buf;
+}
+
+static int goldfish_serial_putc(struct udevice *dev, const char ch)
+{
+ struct goldfish_tty_priv *priv = dev_get_priv(dev);
+
+ __raw_writel(ch, priv->base + GOLDFISH_TTY_PUT_CHAR);
+
+ return 0;
+}
+
+static int goldfish_serial_pending(struct udevice *dev, bool input)
+{
+ struct goldfish_tty_priv *priv = dev_get_priv(dev);
+
+ if (input)
+ return __raw_readl(priv->base + GOLDFISH_TTY_BYTES_READY);
+
+ return 0;
+}
+
+static int goldfish_serial_probe(struct udevice *dev)
+{
+ struct goldfish_tty_priv *priv = dev_get_priv(dev);
+ struct goldfish_tty_plat *plat = dev_get_plat(dev);
+ fdt_addr_t addr;
+
+ addr = dev_read_addr(dev);
+ if (addr != FDT_ADDR_T_NONE) {
+ priv->base = map_sysmem(addr, 0x1000);
+ } else {
+ plat = dev_get_plat(dev);
+ if (!plat)
+ return -EINVAL;
+ priv->base = plat->base;
+ }
+
+ return 0;
+}
+
+static const struct dm_serial_ops goldfish_serial_ops = {
+ .putc = goldfish_serial_putc,
+ .pending = goldfish_serial_pending,
+ .getc = goldfish_serial_getc,
+};
+
+static const struct udevice_id goldfish_serial_ids[] = {
+ { .compatible = "google,goldfish-tty" },
+ { }
+};
+
+U_BOOT_DRIVER(serial_goldfish) = {
+ .name = "serial_goldfish",
+ .id = UCLASS_SERIAL,
+ .of_match = goldfish_serial_ids,
+ .probe = goldfish_serial_probe,
+ .ops = &goldfish_serial_ops,
+ .priv_auto = sizeof(struct goldfish_tty_priv),
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/include/goldfish_tty.h b/include/goldfish_tty.h
new file mode 100644
index 00000000000..8777da4942d
--- /dev/null
+++ b/include/goldfish_tty.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+ */
+
+#ifndef _GOLDFISH_TTY_H_
+#define _GOLDFISH_TTY_H_
+
+#include <linux/types.h>
+
+/* Platform data for the Goldfish TTY driver
+ * Used to pass hardware base address from Board to Driver
+ */
+struct goldfish_tty_plat {
+ void __iomem *base;
+};
+
+#endif /* _GOLDFISH_TTY_H_ */
--
2.52.0.358.g0dd7633a29-goog
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v5 2/7] timer: Add Goldfish timer driver
2026-01-05 16:52 [PATCH v5 0/7] m68k: Add support for QEMU virt machine Kuan-Wei Chiu
2026-01-05 16:52 ` [PATCH v5 1/7] serial: Add Goldfish TTY driver Kuan-Wei Chiu
@ 2026-01-05 16:52 ` Kuan-Wei Chiu
2026-01-05 23:30 ` Simon Glass
2026-01-07 11:07 ` Angelo Dureghello
2026-01-05 16:52 ` [PATCH v5 3/7] rtc: goldfish: Support platform data for non-DT probing Kuan-Wei Chiu
` (4 subsequent siblings)
6 siblings, 2 replies; 26+ messages in thread
From: Kuan-Wei Chiu @ 2026-01-05 16:52 UTC (permalink / raw)
To: alison.wang, angelo, trini
Cc: me, daniel, heinrich.schuchardt, jserv, eleanor15x, u-boot,
Kuan-Wei Chiu
Add support for the Goldfish timer driver. This driver utilizes the
Goldfish RTC hardware to provide a nanosecond-resolution timer. This
virtual device is commonly found in QEMU virtual machines (such as the
m68k virt machine) and Android emulators.
The driver implements the standard U-Boot timer UCLASS interface,
exposing a 64-bit monotonically increasing counter with a 1GHz clock
rate derived from the RTC registers.
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
Tested-by: Daniel Palmer <daniel@0x0f.com>
Reviewed-by: Yao Zi <me@ziyao.cc>
---
Changes in v5:
- Rebase on u-boot/next branch.
MAINTAINERS | 6 +++
drivers/timer/Kconfig | 8 ++++
drivers/timer/Makefile | 1 +
drivers/timer/goldfish_timer.c | 81 ++++++++++++++++++++++++++++++++++
include/goldfish_timer.h | 13 ++++++
5 files changed, 109 insertions(+)
create mode 100644 drivers/timer/goldfish_timer.c
create mode 100644 include/goldfish_timer.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 8f884ff495a..efecb213be7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1266,6 +1266,12 @@ S: Maintained
F: drivers/serial/serial_goldfish.c
F: include/goldfish_tty.h
+GOLDFISH TIMER DRIVER
+M: Kuan-Wei Chiu <visitorckw@gmail.com>
+S: Maintained
+F: drivers/timer/goldfish_timer.c
+F: include/goldfish_timer.h
+
INTERCONNECT:
M: Neil Armstrong <neil.armstrong@linaro.org>
S: Maintained
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index f9511503b02..a84a0dc0539 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -340,4 +340,12 @@ config STARFIVE_TIMER
Select this to enable support for the timer found on
Starfive SoC.
+config GOLDFISH_TIMER
+ bool "Goldfish Timer support"
+ depends on TIMER
+ help
+ Select this to enable support for the Goldfish Timer.
+ It uses the Goldfish RTC hardware to provide a nanosecond-resolution
+ timer, commonly found in QEMU virt machines.
+
endmenu
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index a72e411fb2f..d8b3f2b65d4 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -36,3 +36,4 @@ obj-$(CONFIG_MCHP_PIT64B_TIMER) += mchp-pit64b-timer.o
obj-$(CONFIG_IMX_GPT_TIMER) += imx-gpt-timer.o
obj-$(CONFIG_XILINX_TIMER) += xilinx-timer.o
obj-$(CONFIG_STARFIVE_TIMER) += starfive-timer.o
+obj-$(CONFIG_GOLDFISH_TIMER) += goldfish_timer.o
diff --git a/drivers/timer/goldfish_timer.c b/drivers/timer/goldfish_timer.c
new file mode 100644
index 00000000000..63946b9ed97
--- /dev/null
+++ b/drivers/timer/goldfish_timer.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+ *
+ * Goldfish Timer driver
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <goldfish_timer.h>
+#include <linux/errno.h>
+#include <mapmem.h>
+#include <timer.h>
+
+struct goldfish_timer_priv {
+ void __iomem *base;
+};
+
+/* Goldfish RTC registers used as Timer */
+#define TIMER_TIME_LOW 0x00
+#define TIMER_TIME_HIGH 0x04
+
+static u64 goldfish_timer_get_count(struct udevice *dev)
+{
+ struct goldfish_timer_priv *priv = dev_get_priv(dev);
+ u32 low, high;
+ u64 time;
+
+ /*
+ * TIMER_TIME_HIGH is only updated when TIMER_TIME_LOW is read.
+ * We must read LOW before HIGH to latch the high 32-bit value
+ * and ensure a consistent 64-bit timestamp.
+ */
+ low = readl(priv->base + TIMER_TIME_LOW);
+ high = readl(priv->base + TIMER_TIME_HIGH);
+
+ time = ((u64)high << 32) | low;
+
+ return time;
+}
+
+static int goldfish_timer_probe(struct udevice *dev)
+{
+ struct goldfish_timer_priv *priv = dev_get_priv(dev);
+ struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct goldfish_timer_plat *plat;
+ fdt_addr_t addr;
+
+ addr = dev_read_addr(dev);
+ if (addr != FDT_ADDR_T_NONE) {
+ priv->base = map_sysmem(addr, 0x20);
+ } else {
+ plat = dev_get_plat(dev);
+ if (!plat)
+ return -EINVAL;
+ priv->base = plat->base;
+ }
+
+ /* Goldfish RTC counts in nanoseconds, so the rate is 1GHz */
+ uc_priv->clock_rate = 1000000000;
+
+ return 0;
+}
+
+static const struct timer_ops goldfish_timer_ops = {
+ .get_count = goldfish_timer_get_count,
+};
+
+static const struct udevice_id goldfish_timer_ids[] = {
+ { .compatible = "google,goldfish-rtc" },
+ { }
+};
+
+U_BOOT_DRIVER(goldfish_timer) = {
+ .name = "goldfish_timer",
+ .id = UCLASS_TIMER,
+ .of_match = goldfish_timer_ids,
+ .ops = &goldfish_timer_ops,
+ .probe = goldfish_timer_probe,
+ .priv_auto = sizeof(struct goldfish_timer_priv),
+};
diff --git a/include/goldfish_timer.h b/include/goldfish_timer.h
new file mode 100644
index 00000000000..2ea28170759
--- /dev/null
+++ b/include/goldfish_timer.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+ */
+
+#ifndef _GOLDFISH_TIMER_H_
+#define _GOLDFISH_TIMER_H_
+
+struct goldfish_timer_plat {
+ void __iomem *base;
+};
+
+#endif /* _GOLDFISH_TIMER_H_ */
--
2.52.0.358.g0dd7633a29-goog
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v5 3/7] rtc: goldfish: Support platform data for non-DT probing
2026-01-05 16:52 [PATCH v5 0/7] m68k: Add support for QEMU virt machine Kuan-Wei Chiu
2026-01-05 16:52 ` [PATCH v5 1/7] serial: Add Goldfish TTY driver Kuan-Wei Chiu
2026-01-05 16:52 ` [PATCH v5 2/7] timer: Add Goldfish timer driver Kuan-Wei Chiu
@ 2026-01-05 16:52 ` Kuan-Wei Chiu
2026-01-05 23:30 ` Simon Glass
2026-01-05 16:52 ` [PATCH v5 4/7] m68k: Add support for M68040 CPU Kuan-Wei Chiu
` (3 subsequent siblings)
6 siblings, 1 reply; 26+ messages in thread
From: Kuan-Wei Chiu @ 2026-01-05 16:52 UTC (permalink / raw)
To: alison.wang, angelo, trini
Cc: me, daniel, heinrich.schuchardt, jserv, eleanor15x, u-boot,
Kuan-Wei Chiu
Currently, the Goldfish RTC driver exclusively relies on device tree
to retrieve the base address, failing immediately if dev_read_addr()
returns FDT_ADDR_T_NONE. This restriction prevents the driver from
being used on platforms that instantiate devices via U_BOOT_DRVINFO()
instead of device tree, such as the QEMU m68k virt machine.
Add support for platform data to address this limitation. Update the
probe function to fall back to retrieving the base address from
struct goldfish_rtc_plat if the device tree address is unavailable.
Introduce a new header file include/goldfish_rtc.h to define the
platform data structure.
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
---
Changes in v5:
- Rebase on u-boot/next branch.
drivers/rtc/goldfish_rtc.c | 13 ++++++++++---
include/goldfish_rtc.h | 15 +++++++++++++++
2 files changed, 25 insertions(+), 3 deletions(-)
create mode 100644 include/goldfish_rtc.h
diff --git a/drivers/rtc/goldfish_rtc.c b/drivers/rtc/goldfish_rtc.c
index e63a2766c76..f6316896595 100644
--- a/drivers/rtc/goldfish_rtc.c
+++ b/drivers/rtc/goldfish_rtc.c
@@ -9,6 +9,7 @@
#include <div64.h>
#include <dm.h>
+#include <goldfish_rtc.h>
#include <mapmem.h>
#include <rtc.h>
#include <linux/io.h>
@@ -77,12 +78,18 @@ static int goldfish_rtc_set(struct udevice *dev, const struct rtc_time *time)
static int goldfish_rtc_probe(struct udevice *dev)
{
struct goldfish_rtc *priv = dev_get_priv(dev);
+ struct goldfish_rtc_plat *plat;
fdt_addr_t addr;
addr = dev_read_addr(dev);
- if (addr == FDT_ADDR_T_NONE)
- return -EINVAL;
- priv->base = map_sysmem(addr, 0x20);
+ if (addr != FDT_ADDR_T_NONE) {
+ priv->base = map_sysmem(addr, 0x20);
+ } else {
+ plat = dev_get_plat(dev);
+ if (!plat)
+ return -EINVAL;
+ priv->base = plat->base;
+ }
return 0;
}
diff --git a/include/goldfish_rtc.h b/include/goldfish_rtc.h
new file mode 100644
index 00000000000..bb113a0bd79
--- /dev/null
+++ b/include/goldfish_rtc.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+ */
+
+#ifndef _GOLDFISH_RTC_H_
+#define _GOLDFISH_RTC_H_
+
+#include <linux/types.h>
+
+struct goldfish_rtc_plat {
+ void __iomem *base;
+};
+
+#endif /* _GOLDFISH_RTC_H_ */
--
2.52.0.358.g0dd7633a29-goog
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v5 4/7] m68k: Add support for M68040 CPU
2026-01-05 16:52 [PATCH v5 0/7] m68k: Add support for QEMU virt machine Kuan-Wei Chiu
` (2 preceding siblings ...)
2026-01-05 16:52 ` [PATCH v5 3/7] rtc: goldfish: Support platform data for non-DT probing Kuan-Wei Chiu
@ 2026-01-05 16:52 ` Kuan-Wei Chiu
2026-01-05 23:30 ` Simon Glass
2026-01-05 16:52 ` [PATCH v5 5/7] board: Add QEMU m68k virt board support Kuan-Wei Chiu
` (2 subsequent siblings)
6 siblings, 1 reply; 26+ messages in thread
From: Kuan-Wei Chiu @ 2026-01-05 16:52 UTC (permalink / raw)
To: alison.wang, angelo, trini
Cc: me, daniel, heinrich.schuchardt, jserv, eleanor15x, u-boot,
Kuan-Wei Chiu
Add support for the Motorola 68040 architecture. Currently, m68k
support in U-Boot is primarily focused on ColdFire variants. Introduce
the necessary infrastructure to support the classic M680x0 series,
specifically targeting the M68040 as emulated by QEMU.
The implementation includes exception vectors, early startup code, and
minimal CPU initialization and relocation stubs. It also defines the
standard m68k boot information structure used for passing hardware
information to the operating system. To ensure compatibility, ColdFire-
specific library objects such as cache and interrupt handling are
excluded from the build when M68040 is selected.
Additionally, apply a specific workaround during the early memory
reservation stage. Use a manual loop to clear global data instead of
the standard memset() function, as utilizing memset() at this point was
observed to cause a hang on the QEMU platform.
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
Changes in v5:
- Rebase on u-boot/next branch.
MAINTAINERS | 6 +++
arch/m68k/Kconfig | 16 +++++++
arch/m68k/Makefile | 1 +
arch/m68k/config.mk | 10 ++++-
arch/m68k/cpu/m680x0/Makefile | 6 +++
arch/m68k/cpu/m680x0/cpu.c | 72 +++++++++++++++++++++++++++++++
arch/m68k/cpu/m680x0/start.S | 73 ++++++++++++++++++++++++++++++++
arch/m68k/cpu/m680x0/u-boot.lds | 47 ++++++++++++++++++++
arch/m68k/include/asm/bootinfo.h | 31 ++++++++++++++
arch/m68k/lib/Makefile | 9 ++--
10 files changed, 263 insertions(+), 8 deletions(-)
create mode 100644 arch/m68k/cpu/m680x0/Makefile
create mode 100644 arch/m68k/cpu/m680x0/cpu.c
create mode 100644 arch/m68k/cpu/m680x0/start.S
create mode 100644 arch/m68k/cpu/m680x0/u-boot.lds
create mode 100644 arch/m68k/include/asm/bootinfo.h
diff --git a/MAINTAINERS b/MAINTAINERS
index efecb213be7..bf85f642a8d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1324,6 +1324,12 @@ F: lib/getopt.c
F: test/log/
F: test/py/tests/test_log.py
+M680X0 ARCHITECTURE
+M: Kuan-Wei Chiu <visitorckw@gmail.com>
+S: Maintained
+F: arch/m68k/cpu/m680x0/
+F: arch/m68k/include/asm/bootinfo.h
+
MALI DISPLAY PROCESSORS
M: Liviu Dudau <liviu.dudau@foss.arm.com>
S: Supported
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 8ade6f7b9d1..de7c673c376 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -56,6 +56,9 @@ config MCF5441x
select DM_SERIAL
bool
+config M680x0
+ bool
+
# processor type
config M5208
bool
@@ -110,6 +113,10 @@ config M54418
bool
select MCF5441x
+config M68040
+ bool
+ select M680x0
+
# peripherals
config CF_DSPI
bool
@@ -178,6 +185,15 @@ config TARGET_STMARK2
endchoice
+config SYS_CPU
+ string
+ default "mcf52x2" if MCF52x2
+ default "mcf523x" if MCF523x
+ default "mcf530x" if MCF530x
+ default "mcf532x" if MCF532x
+ default "mcf5445x" if MCF5445x
+ default "m680x0" if M680x0
+
source "board/BuS/eb_cpu5282/Kconfig"
source "board/cobra5272/Kconfig"
source "board/freescale/m5208evbe/Kconfig"
diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile
index 4a7960bbeb4..bb57cf9ac63 100644
--- a/arch/m68k/Makefile
+++ b/arch/m68k/Makefile
@@ -17,6 +17,7 @@ cpuflags-$(CONFIG_M5307) := -mcpu=5307
cpuflags-$(CONFIG_MCF5301x) := -mcpu=53015 -fPIC
cpuflags-$(CONFIG_MCF532x) := -mcpu=5329 -fPIC
cpuflags-$(CONFIG_MCF5441x) := -mcpu=54418 -fPIC
+cpuflags-$(CONFIG_M68040) := -mcpu=68040 -fno-pic
PLATFORM_CPPFLAGS += $(cpuflags-y)
diff --git a/arch/m68k/config.mk b/arch/m68k/config.mk
index 643b7d1d35d..458953f9712 100644
--- a/arch/m68k/config.mk
+++ b/arch/m68k/config.mk
@@ -3,8 +3,14 @@
# (C) Copyright 2000-2002
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-PLATFORM_CPPFLAGS += -D__M68K__ -fPIC
+PLATFORM_CPPFLAGS += -D__M68K__
+ifneq ($(CONFIG_M680x0),y)
+PLATFORM_CPPFLAGS += -fPIC
+endif
KBUILD_LDFLAGS += -n -pie
PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
-PLATFORM_RELFLAGS += -ffixed-d7 -msep-data
+PLATFORM_RELFLAGS += -ffixed-d7
+ifneq ($(CONFIG_M680x0),y)
+PLATFORM_RELFLAGS += -msep-data
+endif
LDFLAGS_FINAL += --gc-sections -pie
diff --git a/arch/m68k/cpu/m680x0/Makefile b/arch/m68k/cpu/m680x0/Makefile
new file mode 100644
index 00000000000..f6e0c9a46c0
--- /dev/null
+++ b/arch/m68k/cpu/m680x0/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+
+extra-y += start.o
+obj-y += cpu.o
diff --git a/arch/m68k/cpu/m680x0/cpu.c b/arch/m68k/cpu/m680x0/cpu.c
new file mode 100644
index 00000000000..e2974560f4d
--- /dev/null
+++ b/arch/m68k/cpu/m680x0/cpu.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * CPU specific code for m68040
+ *
+ * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+ */
+
+#include <asm/global_data.h>
+#include <config.h>
+#include <cpu_func.h>
+#include <init.h>
+#include <linux/types.h>
+#include <stdio.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void m68k_virt_init_reserve(ulong base)
+{
+ struct global_data *gd_ptr = (struct global_data *)base;
+ char *p = (char *)gd_ptr;
+ unsigned int i;
+
+ /* FIXME: usage of memset() here caused a hang on QEMU m68k virt. */
+ for (i = 0; i < sizeof(*gd_ptr); i++)
+ p[i] = 0;
+
+ gd = gd_ptr;
+
+ gd->malloc_base = base + sizeof(*gd_ptr);
+}
+
+int print_cpuinfo(void)
+{
+ puts("CPU: M68040 (QEMU Virt)\n");
+ return 0;
+}
+
+int get_clocks(void)
+{
+ return 0;
+}
+
+int cpu_init_r(void)
+{
+ return 0;
+}
+
+/*
+ * Relocation Stub
+ * We skip actual relocation for this QEMU bring-up and jump directly
+ * to board_init_r.
+ */
+
+void relocate_code(ulong sp, struct global_data *new_gd, ulong relocaddr)
+{
+ board_init_r(new_gd, relocaddr);
+}
+
+/* Stubs for Standard Facilities (Cache, Interrupts) */
+
+int disable_interrupts(void) { return 0; }
+void enable_interrupts(void) { return; }
+int interrupt_init(void) { return 0; }
+
+void icache_enable(void) {}
+void icache_disable(void) {}
+int icache_status(void) { return 0; }
+void dcache_enable(void) {}
+void dcache_disable(void) {}
+int dcache_status(void) { return 0; }
+void flush_cache(unsigned long start, unsigned long size) {}
+void flush_dcache_range(unsigned long start, unsigned long stop) {}
diff --git a/arch/m68k/cpu/m680x0/start.S b/arch/m68k/cpu/m680x0/start.S
new file mode 100644
index 00000000000..0802ca1fca2
--- /dev/null
+++ b/arch/m68k/cpu/m680x0/start.S
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Startup code for m68040
+ *
+ * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+
+.section .text
+
+/*
+ * Vector Table
+ * m68k uses the first 1KB for the exception vector table.
+ */
+.balign 4
+.global _vectors
+_vectors:
+ .long CFG_SYS_INIT_SP_ADDR /* 0x00: Initial SP */
+ .long _start /* 0x04: Initial PC (Reset) */
+ .long _fault /* 0x08: Bus Error */
+ .long _fault /* 0x0C: Address Error */
+ .long _fault /* 0x10: Illegal Instruction */
+ .long _fault /* 0x14: Zero Divide */
+ .long _fault /* 0x18: CHK */
+ .long _fault /* 0x1C: TRAPV */
+ .long _fault /* 0x20: Privilege */
+ .long _fault /* 0x24: Trace */
+ .long _fault /* 0x28: Line 1010 */
+ .long _fault /* 0x2C: Line 1111 */
+ .fill 0x400 - (.-_vectors), 1, 0
+
+/*
+ * Entry Point
+ */
+ENTRY(_start)
+ /* Disable Interrupts */
+ move.w #0x2700, %sr
+
+ /* Setup initial stack pointer */
+ move.l #CFG_SYS_INIT_SP_ADDR, %sp
+
+ /*
+ * Allocate Global Data (GD)
+ * board_init_f_alloc_reserve(top) returns the new top of stack in %d0
+ */
+ move.l %sp, -(%sp)
+ bsr.l board_init_f_alloc_reserve
+ addq.l #4, %sp
+
+ /* Update Stack Pointer and set GD register */
+ move.l %d0, %sp
+ move.l %d0, %d7 /* %d7 is the gd register */
+
+ /* Initialize Reserved Memory. */
+ move.l %d0, -(%sp)
+ bsr.l m68k_virt_init_reserve
+ addq.l #4, %sp
+
+ /* Enter board_init_f(0) */
+ clr.l -(%sp)
+ bsr.l board_init_f
+ addq.l #4, %sp
+
+ /* Should not return */
+hang:
+ bra.s hang
+ENDPROC(_start)
+
+_fault:
+ bra.s _fault
diff --git a/arch/m68k/cpu/m680x0/u-boot.lds b/arch/m68k/cpu/m680x0/u-boot.lds
new file mode 100644
index 00000000000..ae102c32833
--- /dev/null
+++ b/arch/m68k/cpu/m680x0/u-boot.lds
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Linker Script for m68040
+ *
+ * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+ */
+
+OUTPUT_ARCH(m68k)
+ENTRY(_start)
+
+SECTIONS
+{
+ . = 0x00000000;
+ __text_start = .;
+
+ .text :
+ {
+ arch/m68k/cpu/m680x0/start.o (.text*)
+ *(.text*)
+ }
+
+ . = ALIGN(16);
+ .rodata : { *(.rodata*) }
+
+ . = ALIGN(16);
+ .data : { *(.data*) }
+
+ . = ALIGN(4);
+ .u_boot_list : {
+ KEEP(*(SORT(*u_boot_list*)));
+ }
+
+ . = ALIGN(4);
+ __image_copy_end = .;
+ __init_end = .;
+
+ . = ALIGN(16);
+ __bss_start = .;
+ .bss :
+ {
+ *(.bss*)
+ . = ALIGN(16);
+ }
+ __bss_end = .;
+
+ _end = .;
+}
diff --git a/arch/m68k/include/asm/bootinfo.h b/arch/m68k/include/asm/bootinfo.h
new file mode 100644
index 00000000000..3d2ec818257
--- /dev/null
+++ b/arch/m68k/include/asm/bootinfo.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+ *
+ * Definitions for the m68k bootinfo interface.
+ */
+
+#ifndef _ASM_M68K_BOOTINFO_H
+#define _ASM_M68K_BOOTINFO_H
+
+#ifndef __ASSEMBLY__
+
+struct bi_record {
+ unsigned short tag; /* tag ID */
+ unsigned short size; /* size of record (in bytes) */
+ unsigned long data[0]; /* data */
+};
+
+#endif /* __ASSEMBLY__ */
+
+/* Bootinfo Tag IDs */
+#define BI_LAST 0x0000
+#define BI_MACHTYPE 0x0001
+#define BI_CPUTYPE 0x0002
+#define BI_FPUTYPE 0x0003
+#define BI_MMUTYPE 0x0004
+#define BI_MEMCHUNK 0x0005
+#define BI_RAMDISK 0x0006
+#define BI_COMMAND_LINE 0x0007
+
+#endif /* _ASM_M68K_BOOTINFO_H */
diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile
index 6e1fd938f52..e62de51f260 100644
--- a/arch/m68k/lib/Makefile
+++ b/arch/m68k/lib/Makefile
@@ -7,10 +7,7 @@
## if the user asked for it
lib-$(CONFIG_USE_PRIVATE_LIBGCC) += lshrdi3.o muldi3.o ashldi3.o ashrdi3.o
-obj-y += bdinfo.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
-obj-y += cache.o
-obj-y += interrupts.o
-obj-y += time.o
-obj-y += traps.o
-obj-y += fec.o
+ifndef CONFIG_M680x0
+obj-y += cache.o interrupts.o time.o traps.o bdinfo.o fec.o
+endif
--
2.52.0.358.g0dd7633a29-goog
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v5 5/7] board: Add QEMU m68k virt board support
2026-01-05 16:52 [PATCH v5 0/7] m68k: Add support for QEMU virt machine Kuan-Wei Chiu
` (3 preceding siblings ...)
2026-01-05 16:52 ` [PATCH v5 4/7] m68k: Add support for M68040 CPU Kuan-Wei Chiu
@ 2026-01-05 16:52 ` Kuan-Wei Chiu
2026-01-05 23:30 ` Simon Glass
2026-01-05 16:52 ` [PATCH v5 6/7] CI: Add test jobs for QEMU m68k virt machine Kuan-Wei Chiu
2026-01-05 16:52 ` [PATCH v5 7/7] MAINTAINERS: Update m68k entry Kuan-Wei Chiu
6 siblings, 1 reply; 26+ messages in thread
From: Kuan-Wei Chiu @ 2026-01-05 16:52 UTC (permalink / raw)
To: alison.wang, angelo, trini
Cc: me, daniel, heinrich.schuchardt, jserv, eleanor15x, u-boot,
Kuan-Wei Chiu
Add support for the QEMU 'virt' machine on the m68k architecture. This
board emulates a generic machine based on the Motorola 68040 CPU
equipped with Goldfish virtual peripherals.
Introduce the necessary board configuration and initialization
infrastructure. The implementation includes logic to parse the QEMU
bootinfo interface, enabling dynamic detection of system RAM size to
adapt to the virtual machine's configuration.
Enable the Goldfish TTY driver for serial console output. Additionally,
enable Goldfish RTC and timer drivers to support real-time clock
functionality and nanosecond-resolution delays. Include comprehensive
documentation covering build instructions and usage examples.
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
Tested-by: Daniel Palmer <daniel@0x0f.com>
---
Changes in v5:
- Rebase on u-boot/next branch.
- Add 'imply CMD_DM' to TARGET_QEMU_M68K.
arch/m68k/Kconfig | 9 ++
board/emulation/qemu-m68k/Kconfig | 12 +++
board/emulation/qemu-m68k/MAINTAINERS | 8 ++
board/emulation/qemu-m68k/Makefile | 5 ++
board/emulation/qemu-m68k/qemu-m68k.c | 115 ++++++++++++++++++++++++++
configs/qemu-m68k_defconfig | 16 ++++
doc/board/emulation/index.rst | 1 +
doc/board/emulation/qemu-m68k.rst | 39 +++++++++
include/configs/qemu-m68k.h | 18 ++++
9 files changed, 223 insertions(+)
create mode 100644 board/emulation/qemu-m68k/Kconfig
create mode 100644 board/emulation/qemu-m68k/MAINTAINERS
create mode 100644 board/emulation/qemu-m68k/Makefile
create mode 100644 board/emulation/qemu-m68k/qemu-m68k.c
create mode 100644 configs/qemu-m68k_defconfig
create mode 100644 doc/board/emulation/qemu-m68k.rst
create mode 100644 include/configs/qemu-m68k.h
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index de7c673c376..0cf632729da 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -183,6 +183,14 @@ config TARGET_STMARK2
select CF_DSPI
select M54418
+config TARGET_QEMU_M68K
+ bool "Support QEMU m68k virt"
+ select M68040
+ imply CMD_DM
+ help
+ This target supports the QEMU m68k virtual machine (-M virt).
+ It simulates a Motorola 68040 CPU with Goldfish peripherals.
+
endchoice
config SYS_CPU
@@ -208,6 +216,7 @@ source "board/freescale/m5329evb/Kconfig"
source "board/freescale/m5373evb/Kconfig"
source "board/sysam/amcore/Kconfig"
source "board/sysam/stmark2/Kconfig"
+source "board/emulation/qemu-m68k/Kconfig"
config M68K_QEMU
bool "Build with workarounds for incomplete QEMU emulation"
diff --git a/board/emulation/qemu-m68k/Kconfig b/board/emulation/qemu-m68k/Kconfig
new file mode 100644
index 00000000000..aae6dfe400f
--- /dev/null
+++ b/board/emulation/qemu-m68k/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_QEMU_M68K
+
+config SYS_BOARD
+ default "qemu-m68k"
+
+config SYS_VENDOR
+ default "emulation"
+
+config SYS_CONFIG_NAME
+ default "qemu-m68k"
+
+endif
diff --git a/board/emulation/qemu-m68k/MAINTAINERS b/board/emulation/qemu-m68k/MAINTAINERS
new file mode 100644
index 00000000000..90414c58465
--- /dev/null
+++ b/board/emulation/qemu-m68k/MAINTAINERS
@@ -0,0 +1,8 @@
+QEMU M68K VIRT BOARD
+M: Kuan-Wei Chiu <visitorckw@gmail.com>
+S: Maintained
+F: board/emulation/qemu-m68k/
+F: board/emulation/common/
+F: include/configs/qemu-m68k.h
+F: configs/qemu-m68k_defconfig
+F: doc/board/emulation/qemu-m68k.rst
diff --git a/board/emulation/qemu-m68k/Makefile b/board/emulation/qemu-m68k/Makefile
new file mode 100644
index 00000000000..5cb2886ff5a
--- /dev/null
+++ b/board/emulation/qemu-m68k/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+
+obj-y += qemu-m68k.o
diff --git a/board/emulation/qemu-m68k/qemu-m68k.c b/board/emulation/qemu-m68k/qemu-m68k.c
new file mode 100644
index 00000000000..3b911b95343
--- /dev/null
+++ b/board/emulation/qemu-m68k/qemu-m68k.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+ */
+
+#include <asm-generic/sections.h>
+#include <asm/bootinfo.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <config.h>
+#include <dm/platdata.h>
+#include <goldfish_rtc.h>
+#include <goldfish_timer.h>
+#include <goldfish_tty.h>
+#include <init.h>
+#include <linux/errno.h>
+#include <serial.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* QEMU Virt Machine Hardware Map */
+#define VIRT_GF_RTC_MMIO_BASE 0xff007000
+#define VIRT_GF_TTY_MMIO_BASE 0xff008000
+#define VIRT_CTRL_MMIO_BASE 0xff009000
+#define VIRT_CTRL_RESET 0x01
+
+/*
+ * Theoretical limit derivation:
+ * Max Bootinfo Size (Standard Page) = 4096 bytes
+ * Min Record Size (Tag + Size) = 4 bytes
+ * Max Records = 4096 / 4 = 1024
+ */
+#define MAX_BOOTINFO_RECORDS 1024
+
+int board_early_init_f(void)
+{
+ return 0;
+}
+
+int checkboard(void)
+{
+ puts("Board: QEMU m68k virt\n");
+ return 0;
+}
+
+int dram_init(void)
+{
+ struct bi_record *record;
+ ulong addr;
+ int loops = 0;
+
+ /* Default: 16MB */
+ gd->ram_size = 0x01000000;
+
+ /* QEMU places bootinfo after _end, aligned to 2 bytes */
+ addr = (ulong)&_end;
+ addr = ALIGN(addr, 2);
+
+ record = (struct bi_record *)addr;
+
+ if (record->tag != BI_MACHTYPE)
+ return 0;
+
+ while (record->tag != BI_LAST) {
+ if (++loops > MAX_BOOTINFO_RECORDS)
+ panic("Bootinfo loop exceeded");
+ if (record->tag == BI_MEMCHUNK) {
+ gd->ram_size = record->data[1];
+ break;
+ }
+ record = (struct bi_record *)((ulong)record + record->size);
+ }
+
+ return 0;
+}
+
+void reset_cpu(unsigned long addr)
+{
+ writel(VIRT_CTRL_RESET, VIRT_CTRL_MMIO_BASE);
+ while (1)
+ ;
+}
+
+int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ reset_cpu(0);
+ return 0;
+}
+
+static const struct goldfish_rtc_plat rtc_plat = {
+ .base = (void __iomem *)VIRT_GF_RTC_MMIO_BASE,
+};
+
+U_BOOT_DRVINFO(goldfish_rtc) = {
+ .name = "rtc_goldfish",
+ .plat = &rtc_plat,
+};
+
+static const struct goldfish_timer_plat timer_plat = {
+ .base = (void __iomem *)VIRT_GF_RTC_MMIO_BASE,
+};
+
+U_BOOT_DRVINFO(goldfish_timer) = {
+ .name = "goldfish_timer",
+ .plat = &timer_plat,
+};
+
+static const struct goldfish_tty_plat serial_plat = {
+ .base = (void __iomem *)VIRT_GF_TTY_MMIO_BASE,
+};
+
+U_BOOT_DRVINFO(goldfish_serial) = {
+ .name = "serial_goldfish",
+ .plat = &serial_plat,
+};
diff --git a/configs/qemu-m68k_defconfig b/configs/qemu-m68k_defconfig
new file mode 100644
index 00000000000..f9294218429
--- /dev/null
+++ b/configs/qemu-m68k_defconfig
@@ -0,0 +1,16 @@
+CONFIG_M68K=y
+CONFIG_TEXT_BASE=0x00000000
+CONFIG_SYS_MALLOC_LEN=0x20000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SYS_MONITOR_LEN=262144
+CONFIG_SYS_BOOTM_LEN=0x1000000
+CONFIG_SYS_LOAD_ADDR=0x00000000
+CONFIG_TARGET_QEMU_M68K=y
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_DM_RTC=y
+CONFIG_RTC_GOLDFISH=y
+CONFIG_DM_SERIAL=y
+CONFIG_SERIAL_GOLDFISH=y
+CONFIG_TIMER=y
+CONFIG_GOLDFISH_TIMER=y
diff --git a/doc/board/emulation/index.rst b/doc/board/emulation/index.rst
index f8908166276..4f7c812d493 100644
--- a/doc/board/emulation/index.rst
+++ b/doc/board/emulation/index.rst
@@ -15,6 +15,7 @@ Emulation
qemu-sbsa
qemu-x86
qemu-xtensa
+ qemu-m68k
Also see
diff --git a/doc/board/emulation/qemu-m68k.rst b/doc/board/emulation/qemu-m68k.rst
new file mode 100644
index 00000000000..6c4de54cf6a
--- /dev/null
+++ b/doc/board/emulation/qemu-m68k.rst
@@ -0,0 +1,39 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+.. Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+
+QEMU m68k
+=========
+
+QEMU for m68k supports a special 'virt' machine designed for emulation and
+virtualization purposes. This document describes how to run U-Boot under it.
+
+The QEMU virt machine models a generic m68k virtual machine with Goldfish
+interfaces. It supports the Motorola 68040 CPU architecture.
+
+Building U-Boot
+---------------
+Set the CROSS_COMPILE environment variable to your m68k toolchain, and run:
+
+.. code-block:: bash
+
+ export CROSS_COMPILE=m68k-linux-gnu-
+ make qemu-m68k_defconfig
+ make
+
+Running U-Boot
+--------------
+The minimal QEMU command line to get U-Boot up and running is:
+
+.. code-block:: bash
+
+ qemu-system-m68k -M virt -cpu m68040 -nographic -kernel u-boot
+
+Note that the `-nographic` option is used to redirect the console to stdio,
+which connects to the emulated Goldfish TTY device.
+
+Hardware Support
+----------------
+The following QEMU virt peripherals are supported in U-Boot:
+
+* Goldfish TTY (Serial Console)
+* Goldfish RTC (Real Time Clock)
diff --git a/include/configs/qemu-m68k.h b/include/configs/qemu-m68k.h
new file mode 100644
index 00000000000..1d8aa92fe80
--- /dev/null
+++ b/include/configs/qemu-m68k.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+ */
+
+#ifndef __QEMU_M68K_H
+#define __QEMU_M68K_H
+
+/* Memory Configuration */
+#define CFG_SYS_SDRAM_BASE 0x00000000
+
+/*
+ * Initial Stack Pointer:
+ * Place the stack at 4MB offset to avoid overwriting U-Boot code/data.
+ */
+#define CFG_SYS_INIT_SP_ADDR (CFG_SYS_SDRAM_BASE + 0x400000)
+
+#endif /* __QEMU_M68K_H */
--
2.52.0.358.g0dd7633a29-goog
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v5 6/7] CI: Add test jobs for QEMU m68k virt machine
2026-01-05 16:52 [PATCH v5 0/7] m68k: Add support for QEMU virt machine Kuan-Wei Chiu
` (4 preceding siblings ...)
2026-01-05 16:52 ` [PATCH v5 5/7] board: Add QEMU m68k virt board support Kuan-Wei Chiu
@ 2026-01-05 16:52 ` Kuan-Wei Chiu
2026-01-05 23:30 ` Simon Glass
2026-01-05 16:52 ` [PATCH v5 7/7] MAINTAINERS: Update m68k entry Kuan-Wei Chiu
6 siblings, 1 reply; 26+ messages in thread
From: Kuan-Wei Chiu @ 2026-01-05 16:52 UTC (permalink / raw)
To: alison.wang, angelo, trini
Cc: me, daniel, heinrich.schuchardt, jserv, eleanor15x, u-boot,
Kuan-Wei Chiu
Enable CI testing for the newly introduced QEMU m68k 'virt' board on
both GitLab CI and Azure Pipelines. This ensures the new M68040
architecture support is built and booted correctly in the emulated
environment.
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
---
Changes in v5:
- Rebase on u-boot/next branch.
.azure-pipelines.yml | 3 +++
.gitlab-ci.yml | 6 ++++++
2 files changed, 9 insertions(+)
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
index 81a36da7114..e9fee478117 100644
--- a/.azure-pipelines.yml
+++ b/.azure-pipelines.yml
@@ -520,6 +520,9 @@ stages:
TEST_PY_ID: "--id qemu"
TEST_PY_TEST_SPEC: "not sleep and not efi"
OVERRIDE: "-a CONFIG_M68K_QEMU=y -a ~CONFIG_MCFTMR"
+ qemu_m68k_virt:
+ TEST_PY_BD: "qemu-m68k"
+ TEST_PY_TEST_SPEC: "not sleep"
qemu_malta:
TEST_PY_BD: "malta"
TEST_PY_ID: "--id qemu"
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 28a32f9f4d3..ff805fae054 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -417,6 +417,12 @@ qemu_m68k test.py:
OVERRIDE: "-a CONFIG_M68K_QEMU=y -a ~CONFIG_MCFTMR"
<<: *buildman_and_testpy_dfn
+qemu_m68k_virt test.py:
+ variables:
+ TEST_PY_BD: "qemu-m68k"
+ TEST_PY_TEST_SPEC: "not sleep"
+ <<: *buildman_and_testpy_dfn
+
qemu_malta test.py:
variables:
TEST_PY_BD: "malta"
--
2.52.0.358.g0dd7633a29-goog
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v5 7/7] MAINTAINERS: Update m68k entry
2026-01-05 16:52 [PATCH v5 0/7] m68k: Add support for QEMU virt machine Kuan-Wei Chiu
` (5 preceding siblings ...)
2026-01-05 16:52 ` [PATCH v5 6/7] CI: Add test jobs for QEMU m68k virt machine Kuan-Wei Chiu
@ 2026-01-05 16:52 ` Kuan-Wei Chiu
2026-01-07 14:37 ` Angelo Dureghello
2026-01-08 18:52 ` Maciej W. Rozycki
6 siblings, 2 replies; 26+ messages in thread
From: Kuan-Wei Chiu @ 2026-01-05 16:52 UTC (permalink / raw)
To: alison.wang, angelo, trini
Cc: me, daniel, heinrich.schuchardt, jserv, eleanor15x, u-boot,
Kuan-Wei Chiu
Rename the "COLDFIRE" entry to "M68K" to reflect that the architecture
support now encompasses traditional m680x0 CPUs (e.g., M68040) in
addition to ColdFire platforms.
Add myself as a co-maintainer to assist with reviewing and testing
m68k-related patches.
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
Changes in v5:
- New patch.
MAINTAINERS | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index bf85f642a8d..57e8fd5bd8f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1045,9 +1045,10 @@ T: git https://source.denx.de/u-boot/custodians/u-boot-clk.git
F: drivers/clk/
F: drivers/clk/imx/
-COLDFIRE
+M68K
M: Huan Wang <alison.wang@nxp.com>
M: Angelo Dureghello <angelo@kernel-space.org>
+M: Kuan-Wei Chiu <visitorckw@gmail.com>
S: Maintained
T: git https://source.denx.de/u-boot/custodians/u-boot-coldfire.git
F: arch/m68k/
--
2.52.0.358.g0dd7633a29-goog
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v5 2/7] timer: Add Goldfish timer driver
2026-01-05 16:52 ` [PATCH v5 2/7] timer: Add Goldfish timer driver Kuan-Wei Chiu
@ 2026-01-05 23:30 ` Simon Glass
2026-01-07 11:07 ` Angelo Dureghello
1 sibling, 0 replies; 26+ messages in thread
From: Simon Glass @ 2026-01-05 23:30 UTC (permalink / raw)
To: Kuan-Wei Chiu
Cc: alison.wang, angelo, trini, me, daniel, heinrich.schuchardt,
jserv, eleanor15x, u-boot
On Mon, 5 Jan 2026 at 11:20, Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
>
> Add support for the Goldfish timer driver. This driver utilizes the
> Goldfish RTC hardware to provide a nanosecond-resolution timer. This
> virtual device is commonly found in QEMU virtual machines (such as the
> m68k virt machine) and Android emulators.
>
> The driver implements the standard U-Boot timer UCLASS interface,
> exposing a 64-bit monotonically increasing counter with a 1GHz clock
> rate derived from the RTC registers.
>
> Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> Tested-by: Daniel Palmer <daniel@0x0f.com>
> Reviewed-by: Yao Zi <me@ziyao.cc>
> ---
> Changes in v5:
> - Rebase on u-boot/next branch.
>
> MAINTAINERS | 6 +++
> drivers/timer/Kconfig | 8 ++++
> drivers/timer/Makefile | 1 +
> drivers/timer/goldfish_timer.c | 81 ++++++++++++++++++++++++++++++++++
> include/goldfish_timer.h | 13 ++++++
> 5 files changed, 109 insertions(+)
> create mode 100644 drivers/timer/goldfish_timer.c
> create mode 100644 include/goldfish_timer.h
Reviewed-by: Simon Glass <simon.glass@canonical.com>
You can also implement timer_get_boot_us() if you want to use bootstage.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 3/7] rtc: goldfish: Support platform data for non-DT probing
2026-01-05 16:52 ` [PATCH v5 3/7] rtc: goldfish: Support platform data for non-DT probing Kuan-Wei Chiu
@ 2026-01-05 23:30 ` Simon Glass
2026-01-05 23:47 ` Tom Rini
0 siblings, 1 reply; 26+ messages in thread
From: Simon Glass @ 2026-01-05 23:30 UTC (permalink / raw)
To: Kuan-Wei Chiu
Cc: alison.wang, angelo, trini, me, daniel, heinrich.schuchardt,
jserv, eleanor15x, u-boot
Hi Kuan-Wei,
On Mon, 5 Jan 2026 at 11:20, Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
>
> Currently, the Goldfish RTC driver exclusively relies on device tree
> to retrieve the base address, failing immediately if dev_read_addr()
> returns FDT_ADDR_T_NONE. This restriction prevents the driver from
> being used on platforms that instantiate devices via U_BOOT_DRVINFO()
> instead of device tree, such as the QEMU m68k virt machine.
>
> Add support for platform data to address this limitation. Update the
> probe function to fall back to retrieving the base address from
> struct goldfish_rtc_plat if the device tree address is unavailable.
> Introduce a new header file include/goldfish_rtc.h to define the
> platform data structure.
>
> Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
> ---
> Changes in v5:
> - Rebase on u-boot/next branch.
>
> drivers/rtc/goldfish_rtc.c | 13 ++++++++++---
> include/goldfish_rtc.h | 15 +++++++++++++++
> 2 files changed, 25 insertions(+), 3 deletions(-)
> create mode 100644 include/goldfish_rtc.h
>
You can package your own devicetree in the U-Boot source, to handle
what you need.
> diff --git a/drivers/rtc/goldfish_rtc.c b/drivers/rtc/goldfish_rtc.c
> index e63a2766c76..f6316896595 100644
> --- a/drivers/rtc/goldfish_rtc.c
> +++ b/drivers/rtc/goldfish_rtc.c
> @@ -9,6 +9,7 @@
>
> #include <div64.h>
> #include <dm.h>
> +#include <goldfish_rtc.h>
> #include <mapmem.h>
> #include <rtc.h>
> #include <linux/io.h>
> @@ -77,12 +78,18 @@ static int goldfish_rtc_set(struct udevice *dev, const struct rtc_time *time)
> static int goldfish_rtc_probe(struct udevice *dev)
> {
> struct goldfish_rtc *priv = dev_get_priv(dev);
> + struct goldfish_rtc_plat *plat;
> fdt_addr_t addr;
>
> addr = dev_read_addr(dev);
> - if (addr == FDT_ADDR_T_NONE)
> - return -EINVAL;
> - priv->base = map_sysmem(addr, 0x20);
> + if (addr != FDT_ADDR_T_NONE) {
> + priv->base = map_sysmem(addr, 0x20);
> + } else {
> + plat = dev_get_plat(dev);
> + if (!plat)
> + return -EINVAL;
> + priv->base = plat->base;
> + }
>
> return 0;
> }
> diff --git a/include/goldfish_rtc.h b/include/goldfish_rtc.h
> new file mode 100644
> index 00000000000..bb113a0bd79
> --- /dev/null
> +++ b/include/goldfish_rtc.h
> @@ -0,0 +1,15 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> + */
> +
> +#ifndef _GOLDFISH_RTC_H_
> +#define _GOLDFISH_RTC_H_
> +
> +#include <linux/types.h>
> +
> +struct goldfish_rtc_plat {
> + void __iomem *base;
> +};
> +
> +#endif /* _GOLDFISH_RTC_H_ */
> --
> 2.52.0.358.g0dd7633a29-goog
>
Regards,
Simon
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 1/7] serial: Add Goldfish TTY driver
2026-01-05 16:52 ` [PATCH v5 1/7] serial: Add Goldfish TTY driver Kuan-Wei Chiu
@ 2026-01-05 23:30 ` Simon Glass
2026-01-06 19:25 ` Kuan-Wei Chiu
2026-01-07 10:59 ` Angelo Dureghello
1 sibling, 1 reply; 26+ messages in thread
From: Simon Glass @ 2026-01-05 23:30 UTC (permalink / raw)
To: Kuan-Wei Chiu
Cc: alison.wang, angelo, trini, me, daniel, heinrich.schuchardt,
jserv, eleanor15x, u-boot
Hi Kuan-Wei,
On Mon, 5 Jan 2026 at 11:21, Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
>
> Add support for the Google Goldfish TTY serial device. This virtual
> device is commonly used in QEMU virtual machines (such as the m68k
> virt machine) and Android emulators.
>
> The driver implements basic console output and input polling using the
> Goldfish MMIO interface.
>
> Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> Reviewed-by: Yao Zi <me@ziyao.cc>
> Tested-by: Daniel Palmer <daniel@0x0f.com>
> Acked-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
> ---
> Changes in v5:
> - Rebase on u-boot/next branch.
>
> MAINTAINERS | 6 ++
> drivers/serial/Kconfig | 8 +++
> drivers/serial/Makefile | 1 +
> drivers/serial/serial_goldfish.c | 109 +++++++++++++++++++++++++++++++
> include/goldfish_tty.h | 18 +++++
> 5 files changed, 142 insertions(+)
> create mode 100644 drivers/serial/serial_goldfish.c
> create mode 100644 include/goldfish_tty.h
>
Reviewed-by: Simon Glass <simon.glass@canonical.com>
One thought below.
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 27ce73d83f4..8f884ff495a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1260,6 +1260,12 @@ S: Maintained
> F: drivers/misc/gsc.c
> F: include/gsc.h
>
> +GOLDFISH SERIAL DRIVER
> +M: Kuan-Wei Chiu <visitorckw@gmail.com>
> +S: Maintained
> +F: drivers/serial/serial_goldfish.c
> +F: include/goldfish_tty.h
> +
> INTERCONNECT:
> M: Neil Armstrong <neil.armstrong@linaro.org>
> S: Maintained
> diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
> index 371d7aa5bba..b84cb9ec781 100644
> --- a/drivers/serial/Kconfig
> +++ b/drivers/serial/Kconfig
> @@ -1193,4 +1193,12 @@ config SYS_SDMR
> depends on MPC8XX_CONS
> default 0x0
>
> +config SERIAL_GOLDFISH
> + bool "Goldfish TTY support"
> + depends on DM_SERIAL
> + help
> + Select this to enable support for the Goldfish TTY serial port.
> + This virtual device is commonly used by QEMU virtual machines
> + (e.g. m68k virt) for console output.
> +
> endif
> diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
> index 8eaae62b0fc..fe8d23be512 100644
> --- a/drivers/serial/Makefile
> +++ b/drivers/serial/Makefile
> @@ -63,3 +63,4 @@ obj-$(CONFIG_XTENSA_SEMIHOSTING_SERIAL) += serial_xtensa_semihosting.o
> obj-$(CONFIG_S5P4418_PL011_SERIAL) += serial_s5p4418_pl011.o
>
> obj-$(CONFIG_UART4_SERIAL) += serial_adi_uart4.o
> +obj-$(CONFIG_SERIAL_GOLDFISH) += serial_goldfish.o
> diff --git a/drivers/serial/serial_goldfish.c b/drivers/serial/serial_goldfish.c
> new file mode 100644
> index 00000000000..278d0cf3e0d
> --- /dev/null
> +++ b/drivers/serial/serial_goldfish.c
> @@ -0,0 +1,109 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> + * Goldfish TTY driver for U-Boot
> + */
> +
> +#include <asm/io.h>
> +#include <dm.h>
> +#include <goldfish_tty.h>
> +#include <linux/types.h>
> +#include <mapmem.h>
> +#include <serial.h>
> +
> +/* Goldfish TTY Register Offsets */
> +#define GOLDFISH_TTY_PUT_CHAR 0x00
> +#define GOLDFISH_TTY_BYTES_READY 0x04
> +#define GOLDFISH_TTY_CMD 0x08
> +#define GOLDFISH_TTY_DATA_PTR 0x10
> +#define GOLDFISH_TTY_DATA_LEN 0x14
> +#define GOLDFISH_TTY_DATA_PTR_HIGH 0x18
> +#define GOLDFISH_TTY_VERSION 0x20
> +
> +/* Commands */
> +#define CMD_WRITE_BUFFER 2
> +#define CMD_READ_BUFFER 3
> +
> +struct goldfish_tty_priv {
> + void __iomem *base;
> + u8 rx_buf;
> +};
> +
> +static int goldfish_serial_getc(struct udevice *dev)
> +{
> + struct goldfish_tty_priv *priv = dev_get_priv(dev);
> + unsigned long paddr;
> + u32 count;
> +
> + count = __raw_readl(priv->base + GOLDFISH_TTY_BYTES_READY);
> + if (count == 0)
> + return -EAGAIN;
> +
> + paddr = virt_to_phys((void *)&priv->rx_buf);
> +
> + __raw_writel(0, priv->base + GOLDFISH_TTY_DATA_PTR_HIGH);
> + __raw_writel(paddr, priv->base + GOLDFISH_TTY_DATA_PTR);
> + __raw_writel(1, priv->base + GOLDFISH_TTY_DATA_LEN);
> + __raw_writel(CMD_READ_BUFFER, priv->base + GOLDFISH_TTY_CMD);
> +
> + return priv->rx_buf;
> +}
> +
> +static int goldfish_serial_putc(struct udevice *dev, const char ch)
> +{
> + struct goldfish_tty_priv *priv = dev_get_priv(dev);
> +
> + __raw_writel(ch, priv->base + GOLDFISH_TTY_PUT_CHAR);
> +
> + return 0;
> +}
> +
> +static int goldfish_serial_pending(struct udevice *dev, bool input)
> +{
> + struct goldfish_tty_priv *priv = dev_get_priv(dev);
> +
> + if (input)
> + return __raw_readl(priv->base + GOLDFISH_TTY_BYTES_READY);
> +
> + return 0;
> +}
> +
> +static int goldfish_serial_probe(struct udevice *dev)
> +{
> + struct goldfish_tty_priv *priv = dev_get_priv(dev);
> + struct goldfish_tty_plat *plat = dev_get_plat(dev);
> + fdt_addr_t addr;
> +
> + addr = dev_read_addr(dev);
> + if (addr != FDT_ADDR_T_NONE) {
> + priv->base = map_sysmem(addr, 0x1000);
> + } else {
> + plat = dev_get_plat(dev);
> + if (!plat)
> + return -EINVAL;
> + priv->base = plat->base;
> + }
> +
> + return 0;
> +}
Strictly speaking, reading the devicetree should be done in the
of_to_plat() method. So you would read the base address there.
Then probe() would convert that to a pointer (I suggest the same 'reg'
for registers, but it isn't that important).
> +
> +static const struct dm_serial_ops goldfish_serial_ops = {
> + .putc = goldfish_serial_putc,
> + .pending = goldfish_serial_pending,
> + .getc = goldfish_serial_getc,
> +};
> +
> +static const struct udevice_id goldfish_serial_ids[] = {
> + { .compatible = "google,goldfish-tty" },
> + { }
> +};
> +
> +U_BOOT_DRIVER(serial_goldfish) = {
> + .name = "serial_goldfish",
> + .id = UCLASS_SERIAL,
> + .of_match = goldfish_serial_ids,
> + .probe = goldfish_serial_probe,
> + .ops = &goldfish_serial_ops,
> + .priv_auto = sizeof(struct goldfish_tty_priv),
> + .flags = DM_FLAG_PRE_RELOC,
> +};
> diff --git a/include/goldfish_tty.h b/include/goldfish_tty.h
> new file mode 100644
> index 00000000000..8777da4942d
> --- /dev/null
> +++ b/include/goldfish_tty.h
> @@ -0,0 +1,18 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> + */
> +
> +#ifndef _GOLDFISH_TTY_H_
> +#define _GOLDFISH_TTY_H_
> +
> +#include <linux/types.h>
> +
> +/* Platform data for the Goldfish TTY driver
> + * Used to pass hardware base address from Board to Driver
> + */
> +struct goldfish_tty_plat {
> + void __iomem *base;
> +};
> +
> +#endif /* _GOLDFISH_TTY_H_ */
> --
> 2.52.0.358.g0dd7633a29-goog
>
Regards,
Simon
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 4/7] m68k: Add support for M68040 CPU
2026-01-05 16:52 ` [PATCH v5 4/7] m68k: Add support for M68040 CPU Kuan-Wei Chiu
@ 2026-01-05 23:30 ` Simon Glass
2026-01-06 19:38 ` Kuan-Wei Chiu
0 siblings, 1 reply; 26+ messages in thread
From: Simon Glass @ 2026-01-05 23:30 UTC (permalink / raw)
To: Kuan-Wei Chiu
Cc: alison.wang, angelo, trini, me, daniel, heinrich.schuchardt,
jserv, eleanor15x, u-boot
Hi Kuan-Wei,
On Mon, 5 Jan 2026 at 11:20, Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
>
> Add support for the Motorola 68040 architecture. Currently, m68k
> support in U-Boot is primarily focused on ColdFire variants. Introduce
> the necessary infrastructure to support the classic M680x0 series,
> specifically targeting the M68040 as emulated by QEMU.
>
> The implementation includes exception vectors, early startup code, and
> minimal CPU initialization and relocation stubs. It also defines the
> standard m68k boot information structure used for passing hardware
> information to the operating system. To ensure compatibility, ColdFire-
> specific library objects such as cache and interrupt handling are
> excluded from the build when M68040 is selected.
>
> Additionally, apply a specific workaround during the early memory
> reservation stage. Use a manual loop to clear global data instead of
> the standard memset() function, as utilizing memset() at this point was
> observed to cause a hang on the QEMU platform.
>
> Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> ---
> Changes in v5:
> - Rebase on u-boot/next branch.
>
> MAINTAINERS | 6 +++
> arch/m68k/Kconfig | 16 +++++++
> arch/m68k/Makefile | 1 +
> arch/m68k/config.mk | 10 ++++-
> arch/m68k/cpu/m680x0/Makefile | 6 +++
> arch/m68k/cpu/m680x0/cpu.c | 72 +++++++++++++++++++++++++++++++
> arch/m68k/cpu/m680x0/start.S | 73 ++++++++++++++++++++++++++++++++
> arch/m68k/cpu/m680x0/u-boot.lds | 47 ++++++++++++++++++++
> arch/m68k/include/asm/bootinfo.h | 31 ++++++++++++++
> arch/m68k/lib/Makefile | 9 ++--
> 10 files changed, 263 insertions(+), 8 deletions(-)
> create mode 100644 arch/m68k/cpu/m680x0/Makefile
> create mode 100644 arch/m68k/cpu/m680x0/cpu.c
> create mode 100644 arch/m68k/cpu/m680x0/start.S
> create mode 100644 arch/m68k/cpu/m680x0/u-boot.lds
> create mode 100644 arch/m68k/include/asm/bootinfo.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index efecb213be7..bf85f642a8d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1324,6 +1324,12 @@ F: lib/getopt.c
> F: test/log/
> F: test/py/tests/test_log.py
>
> +M680X0 ARCHITECTURE
> +M: Kuan-Wei Chiu <visitorckw@gmail.com>
> +S: Maintained
> +F: arch/m68k/cpu/m680x0/
> +F: arch/m68k/include/asm/bootinfo.h
> +
> MALI DISPLAY PROCESSORS
> M: Liviu Dudau <liviu.dudau@foss.arm.com>
> S: Supported
> diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
> index 8ade6f7b9d1..de7c673c376 100644
> --- a/arch/m68k/Kconfig
> +++ b/arch/m68k/Kconfig
> @@ -56,6 +56,9 @@ config MCF5441x
> select DM_SERIAL
> bool
>
> +config M680x0
> + bool
How about a comment as to what this is?
> +
> # processor type
> config M5208
> bool
> @@ -110,6 +113,10 @@ config M54418
> bool
> select MCF5441x
>
> +config M68040
> + bool
> + select M680x0
> +
> # peripherals
> config CF_DSPI
> bool
> @@ -178,6 +185,15 @@ config TARGET_STMARK2
>
> endchoice
>
> +config SYS_CPU
> + string
> + default "mcf52x2" if MCF52x2
> + default "mcf523x" if MCF523x
> + default "mcf530x" if MCF530x
> + default "mcf532x" if MCF532x
> + default "mcf5445x" if MCF5445x
> + default "m680x0" if M680x0
> +
> source "board/BuS/eb_cpu5282/Kconfig"
> source "board/cobra5272/Kconfig"
> source "board/freescale/m5208evbe/Kconfig"
> diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile
> index 4a7960bbeb4..bb57cf9ac63 100644
> --- a/arch/m68k/Makefile
> +++ b/arch/m68k/Makefile
> @@ -17,6 +17,7 @@ cpuflags-$(CONFIG_M5307) := -mcpu=5307
> cpuflags-$(CONFIG_MCF5301x) := -mcpu=53015 -fPIC
> cpuflags-$(CONFIG_MCF532x) := -mcpu=5329 -fPIC
> cpuflags-$(CONFIG_MCF5441x) := -mcpu=54418 -fPIC
> +cpuflags-$(CONFIG_M68040) := -mcpu=68040 -fno-pic
>
> PLATFORM_CPPFLAGS += $(cpuflags-y)
>
> diff --git a/arch/m68k/config.mk b/arch/m68k/config.mk
> index 643b7d1d35d..458953f9712 100644
> --- a/arch/m68k/config.mk
> +++ b/arch/m68k/config.mk
> @@ -3,8 +3,14 @@
> # (C) Copyright 2000-2002
> # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
>
> -PLATFORM_CPPFLAGS += -D__M68K__ -fPIC
> +PLATFORM_CPPFLAGS += -D__M68K__
> +ifneq ($(CONFIG_M680x0),y)
> +PLATFORM_CPPFLAGS += -fPIC
> +endif
> KBUILD_LDFLAGS += -n -pie
> PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
> -PLATFORM_RELFLAGS += -ffixed-d7 -msep-data
> +PLATFORM_RELFLAGS += -ffixed-d7
> +ifneq ($(CONFIG_M680x0),y)
> +PLATFORM_RELFLAGS += -msep-data
> +endif
> LDFLAGS_FINAL += --gc-sections -pie
> diff --git a/arch/m68k/cpu/m680x0/Makefile b/arch/m68k/cpu/m680x0/Makefile
> new file mode 100644
> index 00000000000..f6e0c9a46c0
> --- /dev/null
> +++ b/arch/m68k/cpu/m680x0/Makefile
> @@ -0,0 +1,6 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +#
> +# Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> +
> +extra-y += start.o
> +obj-y += cpu.o
> diff --git a/arch/m68k/cpu/m680x0/cpu.c b/arch/m68k/cpu/m680x0/cpu.c
> new file mode 100644
> index 00000000000..e2974560f4d
> --- /dev/null
> +++ b/arch/m68k/cpu/m680x0/cpu.c
> @@ -0,0 +1,72 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * CPU specific code for m68040
> + *
> + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> + */
> +
> +#include <asm/global_data.h>
> +#include <config.h>
> +#include <cpu_func.h>
> +#include <init.h>
> +#include <linux/types.h>
> +#include <stdio.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +void m68k_virt_init_reserve(ulong base)
> +{
> + struct global_data *gd_ptr = (struct global_data *)base;
> + char *p = (char *)gd_ptr;
> + unsigned int i;
> +
> + /* FIXME: usage of memset() here caused a hang on QEMU m68k virt. */
> + for (i = 0; i < sizeof(*gd_ptr); i++)
> + p[i] = 0;
Eek!
> +
> + gd = gd_ptr;
> +
> + gd->malloc_base = base + sizeof(*gd_ptr);
> +}
> +
> +int print_cpuinfo(void)
> +{
> + puts("CPU: M68040 (QEMU Virt)\n");
We normally put a blank line before the final return (unless it is the
only code in the function).
> + return 0;
> +}
> +
> +int get_clocks(void)
> +{
> + return 0;
> +}
> +
> +int cpu_init_r(void)
> +{
> + return 0;
> +}
> +
> +/*
> + * Relocation Stub
> + * We skip actual relocation for this QEMU bring-up and jump directly
> + * to board_init_r.
> + */
> +
> +void relocate_code(ulong sp, struct global_data *new_gd, ulong relocaddr)
> +{
> + board_init_r(new_gd, relocaddr);
Why skip relocation?
> +}
> +
> +/* Stubs for Standard Facilities (Cache, Interrupts) */
> +
> +int disable_interrupts(void) { return 0; }
> +void enable_interrupts(void) { return; }
> +int interrupt_init(void) { return 0; }
> +
> +void icache_enable(void) {}
> +void icache_disable(void) {}
> +int icache_status(void) { return 0; }
> +void dcache_enable(void) {}
> +void dcache_disable(void) {}
> +int dcache_status(void) { return 0; }
> +void flush_cache(unsigned long start, unsigned long size) {}
> +void flush_dcache_range(unsigned long start, unsigned long stop) {}
> diff --git a/arch/m68k/cpu/m680x0/start.S b/arch/m68k/cpu/m680x0/start.S
> new file mode 100644
> index 00000000000..0802ca1fca2
> --- /dev/null
> +++ b/arch/m68k/cpu/m680x0/start.S
> @@ -0,0 +1,73 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Startup code for m68040
> + *
> + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> + */
> +
> +#include <asm-offsets.h>
> +#include <config.h>
> +#include <linux/linkage.h>
> +
> +.section .text
> +
> +/*
> + * Vector Table
> + * m68k uses the first 1KB for the exception vector table.
> + */
> +.balign 4
> +.global _vectors
> +_vectors:
> + .long CFG_SYS_INIT_SP_ADDR /* 0x00: Initial SP */
> + .long _start /* 0x04: Initial PC (Reset) */
> + .long _fault /* 0x08: Bus Error */
> + .long _fault /* 0x0C: Address Error */
> + .long _fault /* 0x10: Illegal Instruction */
> + .long _fault /* 0x14: Zero Divide */
> + .long _fault /* 0x18: CHK */
> + .long _fault /* 0x1C: TRAPV */
> + .long _fault /* 0x20: Privilege */
> + .long _fault /* 0x24: Trace */
> + .long _fault /* 0x28: Line 1010 */
> + .long _fault /* 0x2C: Line 1111 */
> + .fill 0x400 - (.-_vectors), 1, 0
> +
> +/*
> + * Entry Point
> + */
> +ENTRY(_start)
> + /* Disable Interrupts */
> + move.w #0x2700, %sr
> +
> + /* Setup initial stack pointer */
> + move.l #CFG_SYS_INIT_SP_ADDR, %sp
> +
> + /*
> + * Allocate Global Data (GD)
> + * board_init_f_alloc_reserve(top) returns the new top of stack in %d0
> + */
> + move.l %sp, -(%sp)
> + bsr.l board_init_f_alloc_reserve
> + addq.l #4, %sp
> +
> + /* Update Stack Pointer and set GD register */
> + move.l %d0, %sp
> + move.l %d0, %d7 /* %d7 is the gd register */
> +
> + /* Initialize Reserved Memory. */
> + move.l %d0, -(%sp)
> + bsr.l m68k_virt_init_reserve
> + addq.l #4, %sp
> +
> + /* Enter board_init_f(0) */
> + clr.l -(%sp)
> + bsr.l board_init_f
> + addq.l #4, %sp
> +
> + /* Should not return */
> +hang:
> + bra.s hang
> +ENDPROC(_start)
> +
> +_fault:
> + bra.s _fault
> diff --git a/arch/m68k/cpu/m680x0/u-boot.lds b/arch/m68k/cpu/m680x0/u-boot.lds
> new file mode 100644
> index 00000000000..ae102c32833
> --- /dev/null
> +++ b/arch/m68k/cpu/m680x0/u-boot.lds
> @@ -0,0 +1,47 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Linker Script for m68040
> + *
> + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> + */
> +
> +OUTPUT_ARCH(m68k)
> +ENTRY(_start)
> +
> +SECTIONS
> +{
> + . = 0x00000000;
> + __text_start = .;
> +
> + .text :
> + {
> + arch/m68k/cpu/m680x0/start.o (.text*)
> + *(.text*)
> + }
> +
> + . = ALIGN(16);
> + .rodata : { *(.rodata*) }
> +
> + . = ALIGN(16);
> + .data : { *(.data*) }
> +
> + . = ALIGN(4);
> + .u_boot_list : {
> + KEEP(*(SORT(*u_boot_list*)));
> + }
> +
> + . = ALIGN(4);
> + __image_copy_end = .;
> + __init_end = .;
> +
> + . = ALIGN(16);
> + __bss_start = .;
> + .bss :
> + {
> + *(.bss*)
> + . = ALIGN(16);
> + }
> + __bss_end = .;
> +
> + _end = .;
> +}
> diff --git a/arch/m68k/include/asm/bootinfo.h b/arch/m68k/include/asm/bootinfo.h
> new file mode 100644
> index 00000000000..3d2ec818257
> --- /dev/null
> +++ b/arch/m68k/include/asm/bootinfo.h
> @@ -0,0 +1,31 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> + *
> + * Definitions for the m68k bootinfo interface.
> + */
> +
> +#ifndef _ASM_M68K_BOOTINFO_H
> +#define _ASM_M68K_BOOTINFO_H
> +
> +#ifndef __ASSEMBLY__
> +
> +struct bi_record {
> + unsigned short tag; /* tag ID */
> + unsigned short size; /* size of record (in bytes) */
> + unsigned long data[0]; /* data */
> +};
> +
> +#endif /* __ASSEMBLY__ */
> +
> +/* Bootinfo Tag IDs */
> +#define BI_LAST 0x0000
> +#define BI_MACHTYPE 0x0001
> +#define BI_CPUTYPE 0x0002
> +#define BI_FPUTYPE 0x0003
> +#define BI_MMUTYPE 0x0004
> +#define BI_MEMCHUNK 0x0005
> +#define BI_RAMDISK 0x0006
> +#define BI_COMMAND_LINE 0x0007
> +
> +#endif /* _ASM_M68K_BOOTINFO_H */
> diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile
> index 6e1fd938f52..e62de51f260 100644
> --- a/arch/m68k/lib/Makefile
> +++ b/arch/m68k/lib/Makefile
> @@ -7,10 +7,7 @@
> ## if the user asked for it
> lib-$(CONFIG_USE_PRIVATE_LIBGCC) += lshrdi3.o muldi3.o ashldi3.o ashrdi3.o
>
> -obj-y += bdinfo.o
> obj-$(CONFIG_CMD_BOOTM) += bootm.o
> -obj-y += cache.o
> -obj-y += interrupts.o
> -obj-y += time.o
> -obj-y += traps.o
> -obj-y += fec.o
> +ifndef CONFIG_M680x0
> +obj-y += cache.o interrupts.o time.o traps.o bdinfo.o fec.o
> +endif
Is there a Kconfig you could use to group these files? Then it could
be enabled if !M680x0
> --
> 2.52.0.358.g0dd7633a29-goog
>
Regards,
Simon
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 6/7] CI: Add test jobs for QEMU m68k virt machine
2026-01-05 16:52 ` [PATCH v5 6/7] CI: Add test jobs for QEMU m68k virt machine Kuan-Wei Chiu
@ 2026-01-05 23:30 ` Simon Glass
0 siblings, 0 replies; 26+ messages in thread
From: Simon Glass @ 2026-01-05 23:30 UTC (permalink / raw)
To: Kuan-Wei Chiu
Cc: alison.wang, angelo, trini, me, daniel, heinrich.schuchardt,
jserv, eleanor15x, u-boot
On Mon, 5 Jan 2026 at 11:20, Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
>
> Enable CI testing for the newly introduced QEMU m68k 'virt' board on
> both GitLab CI and Azure Pipelines. This ensures the new M68040
> architecture support is built and booted correctly in the emulated
> environment.
>
> Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> Reviewed-by: Tom Rini <trini@konsulko.com>
> ---
> Changes in v5:
> - Rebase on u-boot/next branch.
>
> .azure-pipelines.yml | 3 +++
> .gitlab-ci.yml | 6 ++++++
> 2 files changed, 9 insertions(+)
Reviewed-by: Simon Glass <simon.glass@canonical.com>
>
> diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
> index 81a36da7114..e9fee478117 100644
> --- a/.azure-pipelines.yml
> +++ b/.azure-pipelines.yml
> @@ -520,6 +520,9 @@ stages:
> TEST_PY_ID: "--id qemu"
> TEST_PY_TEST_SPEC: "not sleep and not efi"
> OVERRIDE: "-a CONFIG_M68K_QEMU=y -a ~CONFIG_MCFTMR"
> + qemu_m68k_virt:
> + TEST_PY_BD: "qemu-m68k"
> + TEST_PY_TEST_SPEC: "not sleep"
> qemu_malta:
> TEST_PY_BD: "malta"
> TEST_PY_ID: "--id qemu"
> diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
> index 28a32f9f4d3..ff805fae054 100644
> --- a/.gitlab-ci.yml
> +++ b/.gitlab-ci.yml
> @@ -417,6 +417,12 @@ qemu_m68k test.py:
> OVERRIDE: "-a CONFIG_M68K_QEMU=y -a ~CONFIG_MCFTMR"
> <<: *buildman_and_testpy_dfn
>
> +qemu_m68k_virt test.py:
> + variables:
> + TEST_PY_BD: "qemu-m68k"
> + TEST_PY_TEST_SPEC: "not sleep"
> + <<: *buildman_and_testpy_dfn
> +
> qemu_malta test.py:
> variables:
> TEST_PY_BD: "malta"
> --
> 2.52.0.358.g0dd7633a29-goog
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 5/7] board: Add QEMU m68k virt board support
2026-01-05 16:52 ` [PATCH v5 5/7] board: Add QEMU m68k virt board support Kuan-Wei Chiu
@ 2026-01-05 23:30 ` Simon Glass
2026-01-06 19:22 ` Kuan-Wei Chiu
0 siblings, 1 reply; 26+ messages in thread
From: Simon Glass @ 2026-01-05 23:30 UTC (permalink / raw)
To: Kuan-Wei Chiu
Cc: alison.wang, angelo, trini, me, daniel, heinrich.schuchardt,
jserv, eleanor15x, u-boot
Hi Kuan-Wei,
On Mon, 5 Jan 2026 at 11:21, Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
>
> Add support for the QEMU 'virt' machine on the m68k architecture. This
> board emulates a generic machine based on the Motorola 68040 CPU
> equipped with Goldfish virtual peripherals.
>
> Introduce the necessary board configuration and initialization
> infrastructure. The implementation includes logic to parse the QEMU
> bootinfo interface, enabling dynamic detection of system RAM size to
> adapt to the virtual machine's configuration.
>
> Enable the Goldfish TTY driver for serial console output. Additionally,
> enable Goldfish RTC and timer drivers to support real-time clock
> functionality and nanosecond-resolution delays. Include comprehensive
> documentation covering build instructions and usage examples.
>
> Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> Tested-by: Daniel Palmer <daniel@0x0f.com>
> ---
> Changes in v5:
> - Rebase on u-boot/next branch.
> - Add 'imply CMD_DM' to TARGET_QEMU_M68K.
>
> arch/m68k/Kconfig | 9 ++
> board/emulation/qemu-m68k/Kconfig | 12 +++
> board/emulation/qemu-m68k/MAINTAINERS | 8 ++
> board/emulation/qemu-m68k/Makefile | 5 ++
> board/emulation/qemu-m68k/qemu-m68k.c | 115 ++++++++++++++++++++++++++
> configs/qemu-m68k_defconfig | 16 ++++
> doc/board/emulation/index.rst | 1 +
> doc/board/emulation/qemu-m68k.rst | 39 +++++++++
> include/configs/qemu-m68k.h | 18 ++++
> 9 files changed, 223 insertions(+)
> create mode 100644 board/emulation/qemu-m68k/Kconfig
> create mode 100644 board/emulation/qemu-m68k/MAINTAINERS
> create mode 100644 board/emulation/qemu-m68k/Makefile
> create mode 100644 board/emulation/qemu-m68k/qemu-m68k.c
> create mode 100644 configs/qemu-m68k_defconfig
> create mode 100644 doc/board/emulation/qemu-m68k.rst
> create mode 100644 include/configs/qemu-m68k.h
>
Very nice patch.
> diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
> index de7c673c376..0cf632729da 100644
> --- a/arch/m68k/Kconfig
> +++ b/arch/m68k/Kconfig
> @@ -183,6 +183,14 @@ config TARGET_STMARK2
> select CF_DSPI
> select M54418
>
> +config TARGET_QEMU_M68K
> + bool "Support QEMU m68k virt"
> + select M68040
> + imply CMD_DM
> + help
> + This target supports the QEMU m68k virtual machine (-M virt).
> + It simulates a Motorola 68040 CPU with Goldfish peripherals.
> +
> endchoice
>
> config SYS_CPU
> @@ -208,6 +216,7 @@ source "board/freescale/m5329evb/Kconfig"
> source "board/freescale/m5373evb/Kconfig"
> source "board/sysam/amcore/Kconfig"
> source "board/sysam/stmark2/Kconfig"
> +source "board/emulation/qemu-m68k/Kconfig"
>
> config M68K_QEMU
> bool "Build with workarounds for incomplete QEMU emulation"
> diff --git a/board/emulation/qemu-m68k/Kconfig b/board/emulation/qemu-m68k/Kconfig
> new file mode 100644
> index 00000000000..aae6dfe400f
> --- /dev/null
> +++ b/board/emulation/qemu-m68k/Kconfig
> @@ -0,0 +1,12 @@
> +if TARGET_QEMU_M68K
> +
> +config SYS_BOARD
> + default "qemu-m68k"
> +
> +config SYS_VENDOR
> + default "emulation"
> +
> +config SYS_CONFIG_NAME
> + default "qemu-m68k"
> +
> +endif
> diff --git a/board/emulation/qemu-m68k/MAINTAINERS b/board/emulation/qemu-m68k/MAINTAINERS
> new file mode 100644
> index 00000000000..90414c58465
> --- /dev/null
> +++ b/board/emulation/qemu-m68k/MAINTAINERS
> @@ -0,0 +1,8 @@
> +QEMU M68K VIRT BOARD
> +M: Kuan-Wei Chiu <visitorckw@gmail.com>
> +S: Maintained
> +F: board/emulation/qemu-m68k/
> +F: board/emulation/common/
> +F: include/configs/qemu-m68k.h
> +F: configs/qemu-m68k_defconfig
> +F: doc/board/emulation/qemu-m68k.rst
> diff --git a/board/emulation/qemu-m68k/Makefile b/board/emulation/qemu-m68k/Makefile
> new file mode 100644
> index 00000000000..5cb2886ff5a
> --- /dev/null
> +++ b/board/emulation/qemu-m68k/Makefile
> @@ -0,0 +1,5 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +#
> +# Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> +
> +obj-y += qemu-m68k.o
> diff --git a/board/emulation/qemu-m68k/qemu-m68k.c b/board/emulation/qemu-m68k/qemu-m68k.c
> new file mode 100644
> index 00000000000..3b911b95343
> --- /dev/null
> +++ b/board/emulation/qemu-m68k/qemu-m68k.c
> @@ -0,0 +1,115 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> + */
> +
> +#include <asm-generic/sections.h>
> +#include <asm/bootinfo.h>
> +#include <asm/global_data.h>
> +#include <asm/io.h>
> +#include <config.h>
> +#include <dm/platdata.h>
> +#include <goldfish_rtc.h>
> +#include <goldfish_timer.h>
> +#include <goldfish_tty.h>
> +#include <init.h>
> +#include <linux/errno.h>
> +#include <serial.h>
Check header order:
https://docs.u-boot.org/en/v2024.01/develop/codingstyle.html#include-files
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +/* QEMU Virt Machine Hardware Map */
> +#define VIRT_GF_RTC_MMIO_BASE 0xff007000
> +#define VIRT_GF_TTY_MMIO_BASE 0xff008000
> +#define VIRT_CTRL_MMIO_BASE 0xff009000
> +#define VIRT_CTRL_RESET 0x01
> +
Could these move to devicetree? Or perhaps have an overall base + offsets?
> +/*
> + * Theoretical limit derivation:
> + * Max Bootinfo Size (Standard Page) = 4096 bytes
> + * Min Record Size (Tag + Size) = 4 bytes
> + * Max Records = 4096 / 4 = 1024
> + */
> +#define MAX_BOOTINFO_RECORDS 1024
> +
> +int board_early_init_f(void)
If you don't need this function, you could disable BOARD_EARLY_INIT_F
> +{
> + return 0;
> +}
> +
> +int checkboard(void)
> +{
> + puts("Board: QEMU m68k virt\n");
blank line here (and below)
> + return 0;
> +}
> +
> +int dram_init(void)
> +{
> + struct bi_record *record;
> + ulong addr;
> + int loops = 0;
> +
> + /* Default: 16MB */
> + gd->ram_size = 0x01000000;
or SZ_16M
> +
> + /* QEMU places bootinfo after _end, aligned to 2 bytes */
> + addr = (ulong)&_end;
> + addr = ALIGN(addr, 2);
> +
> + record = (struct bi_record *)addr;
> +
> + if (record->tag != BI_MACHTYPE)
> + return 0;
> +
> + while (record->tag != BI_LAST) {
> + if (++loops > MAX_BOOTINFO_RECORDS)
> + panic("Bootinfo loop exceeded");
> + if (record->tag == BI_MEMCHUNK) {
> + gd->ram_size = record->data[1];
> + break;
> + }
> + record = (struct bi_record *)((ulong)record + record->size);
> + }
> +
> + return 0;
> +}
> +
> +void reset_cpu(unsigned long addr)
> +{
> + writel(VIRT_CTRL_RESET, VIRT_CTRL_MMIO_BASE);
> + while (1)
> + ;
hang()? But if it prints a few characters of the message, you won't want it.
BTW this should really be a sysreset driver.
> +}
> +
> +int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
> +{
> + reset_cpu(0);
> + return 0;
> +}
> +
> +static const struct goldfish_rtc_plat rtc_plat = {
> + .base = (void __iomem *)VIRT_GF_RTC_MMIO_BASE,
> +};
> +
> +U_BOOT_DRVINFO(goldfish_rtc) = {
> + .name = "rtc_goldfish",
> + .plat = &rtc_plat,
> +};
> +
> +static const struct goldfish_timer_plat timer_plat = {
> + .base = (void __iomem *)VIRT_GF_RTC_MMIO_BASE,
> +};
> +
> +U_BOOT_DRVINFO(goldfish_timer) = {
> + .name = "goldfish_timer",
> + .plat = &timer_plat,
> +};
> +
> +static const struct goldfish_tty_plat serial_plat = {
> + .base = (void __iomem *)VIRT_GF_TTY_MMIO_BASE,
> +};
> +
> +U_BOOT_DRVINFO(goldfish_serial) = {
> + .name = "serial_goldfish",
> + .plat = &serial_plat,
> +};
This is what device tree is for. It would be trivial to set one up.
> diff --git a/configs/qemu-m68k_defconfig b/configs/qemu-m68k_defconfig
> new file mode 100644
> index 00000000000..f9294218429
> --- /dev/null
> +++ b/configs/qemu-m68k_defconfig
> @@ -0,0 +1,16 @@
> +CONFIG_M68K=y
> +CONFIG_TEXT_BASE=0x00000000
> +CONFIG_SYS_MALLOC_LEN=0x20000
> +CONFIG_SYS_MALLOC_F_LEN=0x2000
> +CONFIG_SYS_MONITOR_LEN=262144
> +CONFIG_SYS_BOOTM_LEN=0x1000000
> +CONFIG_SYS_LOAD_ADDR=0x00000000
> +CONFIG_TARGET_QEMU_M68K=y
> +# CONFIG_DISPLAY_BOARDINFO is not set
> +CONFIG_BOARD_EARLY_INIT_F=y
> +CONFIG_DM_RTC=y
> +CONFIG_RTC_GOLDFISH=y
> +CONFIG_DM_SERIAL=y
> +CONFIG_SERIAL_GOLDFISH=y
> +CONFIG_TIMER=y
> +CONFIG_GOLDFISH_TIMER=y
> diff --git a/doc/board/emulation/index.rst b/doc/board/emulation/index.rst
> index f8908166276..4f7c812d493 100644
> --- a/doc/board/emulation/index.rst
> +++ b/doc/board/emulation/index.rst
> @@ -15,6 +15,7 @@ Emulation
> qemu-sbsa
> qemu-x86
> qemu-xtensa
> + qemu-m68k
>
> Also see
>
> diff --git a/doc/board/emulation/qemu-m68k.rst b/doc/board/emulation/qemu-m68k.rst
> new file mode 100644
> index 00000000000..6c4de54cf6a
> --- /dev/null
> +++ b/doc/board/emulation/qemu-m68k.rst
> @@ -0,0 +1,39 @@
> +.. SPDX-License-Identifier: GPL-2.0-or-later
> +.. Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> +
> +QEMU m68k
> +=========
> +
> +QEMU for m68k supports a special 'virt' machine designed for emulation and
> +virtualization purposes. This document describes how to run U-Boot under it.
> +
> +The QEMU virt machine models a generic m68k virtual machine with Goldfish
> +interfaces. It supports the Motorola 68040 CPU architecture.
> +
> +Building U-Boot
> +---------------
> +Set the CROSS_COMPILE environment variable to your m68k toolchain, and run:
> +
> +.. code-block:: bash
> +
> + export CROSS_COMPILE=m68k-linux-gnu-
> + make qemu-m68k_defconfig
> + make
> +
> +Running U-Boot
> +--------------
> +The minimal QEMU command line to get U-Boot up and running is:
> +
> +.. code-block:: bash
> +
> + qemu-system-m68k -M virt -cpu m68040 -nographic -kernel u-boot
> +
> +Note that the `-nographic` option is used to redirect the console to stdio,
> +which connects to the emulated Goldfish TTY device.
> +
> +Hardware Support
> +----------------
> +The following QEMU virt peripherals are supported in U-Boot:
> +
> +* Goldfish TTY (Serial Console)
> +* Goldfish RTC (Real Time Clock)
> diff --git a/include/configs/qemu-m68k.h b/include/configs/qemu-m68k.h
> new file mode 100644
> index 00000000000..1d8aa92fe80
> --- /dev/null
> +++ b/include/configs/qemu-m68k.h
> @@ -0,0 +1,18 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> + */
> +
> +#ifndef __QEMU_M68K_H
> +#define __QEMU_M68K_H
> +
> +/* Memory Configuration */
> +#define CFG_SYS_SDRAM_BASE 0x00000000
> +
> +/*
> + * Initial Stack Pointer:
> + * Place the stack at 4MB offset to avoid overwriting U-Boot code/data.
> + */
> +#define CFG_SYS_INIT_SP_ADDR (CFG_SYS_SDRAM_BASE + 0x400000)
> +
> +#endif /* __QEMU_M68K_H */
> --
> 2.52.0.358.g0dd7633a29-goog
>
Regards,
Simon
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 3/7] rtc: goldfish: Support platform data for non-DT probing
2026-01-05 23:30 ` Simon Glass
@ 2026-01-05 23:47 ` Tom Rini
2026-01-06 0:58 ` Daniel Palmer
2026-01-06 16:22 ` Simon Glass
0 siblings, 2 replies; 26+ messages in thread
From: Tom Rini @ 2026-01-05 23:47 UTC (permalink / raw)
To: Simon Glass
Cc: Kuan-Wei Chiu, alison.wang, angelo, me, daniel,
heinrich.schuchardt, jserv, eleanor15x, u-boot
[-- Attachment #1: Type: text/plain, Size: 1600 bytes --]
On Mon, Jan 05, 2026 at 04:30:26PM -0700, Simon Glass wrote:
> Hi Kuan-Wei,
>
> On Mon, 5 Jan 2026 at 11:20, Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
> >
> > Currently, the Goldfish RTC driver exclusively relies on device tree
> > to retrieve the base address, failing immediately if dev_read_addr()
> > returns FDT_ADDR_T_NONE. This restriction prevents the driver from
> > being used on platforms that instantiate devices via U_BOOT_DRVINFO()
> > instead of device tree, such as the QEMU m68k virt machine.
> >
> > Add support for platform data to address this limitation. Update the
> > probe function to fall back to retrieving the base address from
> > struct goldfish_rtc_plat if the device tree address is unavailable.
> > Introduce a new header file include/goldfish_rtc.h to define the
> > platform data structure.
> >
> > Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> > Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
> > ---
> > Changes in v5:
> > - Rebase on u-boot/next branch.
> >
> > drivers/rtc/goldfish_rtc.c | 13 ++++++++++---
> > include/goldfish_rtc.h | 15 +++++++++++++++
> > 2 files changed, 25 insertions(+), 3 deletions(-)
> > create mode 100644 include/goldfish_rtc.h
> >
>
> You can package your own devicetree in the U-Boot source, to handle
> what you need.
That's not helpful feedback here, the correct path is to use the machine
as QEMU provides it and not start yet another pointless argument with
QEMU. And this probably applies to some of your other feedback as well,
thanks.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 3/7] rtc: goldfish: Support platform data for non-DT probing
2026-01-05 23:47 ` Tom Rini
@ 2026-01-06 0:58 ` Daniel Palmer
2026-01-06 1:49 ` Tom Rini
2026-01-06 16:22 ` Simon Glass
1 sibling, 1 reply; 26+ messages in thread
From: Daniel Palmer @ 2026-01-06 0:58 UTC (permalink / raw)
To: Tom Rini
Cc: Simon Glass, Kuan-Wei Chiu, alison.wang, angelo, me,
heinrich.schuchardt, jserv, eleanor15x, u-boot
Hi Tom, Simon,
On Tue, 6 Jan 2026 at 08:47, Tom Rini <trini@konsulko.com> wrote:
>
> On Mon, Jan 05, 2026 at 04:30:26PM -0700, Simon Glass wrote:
> > Hi Kuan-Wei,
> >
> > You can package your own devicetree in the U-Boot source, to handle
> > what you need.
>
> That's not helpful feedback here, the correct path is to use the machine
> as QEMU provides it and not start yet another pointless argument with
> QEMU. And this probably applies to some of your other feedback as well,
> thanks.
>
> --
> Tom
My version of this converts the bootinfo from QEMU to a devicetree
inside of u-boot and then u-boot uses that going forward.
I have suggested to the m68k kernel side that we allow bootinfo to
pass a devicetree pointer and/or use embedded devicetrees in the
kernel selected by the machine type in the bootinfo.
My plan is once this very basic part is merged I will rebase my stuff
onto this and then start spamming Kuan-Wei with patches to add in
devicetree etc. ;)
Cheers,
Daniel
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 3/7] rtc: goldfish: Support platform data for non-DT probing
2026-01-06 0:58 ` Daniel Palmer
@ 2026-01-06 1:49 ` Tom Rini
0 siblings, 0 replies; 26+ messages in thread
From: Tom Rini @ 2026-01-06 1:49 UTC (permalink / raw)
To: Daniel Palmer
Cc: Simon Glass, Kuan-Wei Chiu, alison.wang, angelo, me,
heinrich.schuchardt, jserv, eleanor15x, u-boot
[-- Attachment #1: Type: text/plain, Size: 1254 bytes --]
On Tue, Jan 06, 2026 at 09:58:30AM +0900, Daniel Palmer wrote:
> Hi Tom, Simon,
>
> On Tue, 6 Jan 2026 at 08:47, Tom Rini <trini@konsulko.com> wrote:
> >
> > On Mon, Jan 05, 2026 at 04:30:26PM -0700, Simon Glass wrote:
> > > Hi Kuan-Wei,
>
> > >
> > > You can package your own devicetree in the U-Boot source, to handle
> > > what you need.
> >
> > That's not helpful feedback here, the correct path is to use the machine
> > as QEMU provides it and not start yet another pointless argument with
> > QEMU. And this probably applies to some of your other feedback as well,
> > thanks.
> >
> > --
> > Tom
>
> My version of this converts the bootinfo from QEMU to a devicetree
> inside of u-boot and then u-boot uses that going forward.
> I have suggested to the m68k kernel side that we allow bootinfo to
> pass a devicetree pointer and/or use embedded devicetrees in the
> kernel selected by the machine type in the bootinfo.
>
> My plan is once this very basic part is merged I will rebase my stuff
> onto this and then start spamming Kuan-Wei with patches to add in
> devicetree etc. ;)
Getting all of the other parts of the system in agreement and then doing
that sounds like a good plan to me, thanks!
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 3/7] rtc: goldfish: Support platform data for non-DT probing
2026-01-05 23:47 ` Tom Rini
2026-01-06 0:58 ` Daniel Palmer
@ 2026-01-06 16:22 ` Simon Glass
2026-01-06 16:58 ` Tom Rini
1 sibling, 1 reply; 26+ messages in thread
From: Simon Glass @ 2026-01-06 16:22 UTC (permalink / raw)
To: Tom Rini
Cc: Kuan-Wei Chiu, alison.wang, angelo, me, daniel,
heinrich.schuchardt, jserv, eleanor15x, u-boot
Hi Tom,
On Mon, 5 Jan 2026 at 16:47, Tom Rini <trini@konsulko.com> wrote:
>
> On Mon, Jan 05, 2026 at 04:30:26PM -0700, Simon Glass wrote:
> > Hi Kuan-Wei,
> >
> > On Mon, 5 Jan 2026 at 11:20, Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
> > >
> > > Currently, the Goldfish RTC driver exclusively relies on device tree
> > > to retrieve the base address, failing immediately if dev_read_addr()
> > > returns FDT_ADDR_T_NONE. This restriction prevents the driver from
> > > being used on platforms that instantiate devices via U_BOOT_DRVINFO()
> > > instead of device tree, such as the QEMU m68k virt machine.
> > >
> > > Add support for platform data to address this limitation. Update the
> > > probe function to fall back to retrieving the base address from
> > > struct goldfish_rtc_plat if the device tree address is unavailable.
> > > Introduce a new header file include/goldfish_rtc.h to define the
> > > platform data structure.
> > >
> > > Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> > > Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
> > > ---
> > > Changes in v5:
> > > - Rebase on u-boot/next branch.
> > >
> > > drivers/rtc/goldfish_rtc.c | 13 ++++++++++---
> > > include/goldfish_rtc.h | 15 +++++++++++++++
> > > 2 files changed, 25 insertions(+), 3 deletions(-)
> > > create mode 100644 include/goldfish_rtc.h
> > >
> >
> > You can package your own devicetree in the U-Boot source, to handle
> > what you need.
>
> That's not helpful feedback here, the correct path is to use the machine
> as QEMU provides it and not start yet another pointless argument with
> QEMU. And this probably applies to some of your other feedback as well,
> thanks.
From what I understand, QEMU does not use DT for m68k. If it did, then
we would not be using platdata. Am I missing something here?
Regards,
Simon
PS: The QEMU thing was certainly not pointless, even if the 'argument'
resolved nothing. We still have this work-around in the docs, 4 years
and counting:
https://docs.u-boot.org/en/latest/develop/devicetree/dt_qemu.html#merging-in-u-boot-nodes-properties
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 3/7] rtc: goldfish: Support platform data for non-DT probing
2026-01-06 16:22 ` Simon Glass
@ 2026-01-06 16:58 ` Tom Rini
0 siblings, 0 replies; 26+ messages in thread
From: Tom Rini @ 2026-01-06 16:58 UTC (permalink / raw)
To: Simon Glass
Cc: Kuan-Wei Chiu, alison.wang, angelo, me, daniel,
heinrich.schuchardt, jserv, eleanor15x, u-boot
[-- Attachment #1: Type: text/plain, Size: 2637 bytes --]
On Tue, Jan 06, 2026 at 09:22:01AM -0700, Simon Glass wrote:
> Hi Tom,
>
> On Mon, 5 Jan 2026 at 16:47, Tom Rini <trini@konsulko.com> wrote:
> >
> > On Mon, Jan 05, 2026 at 04:30:26PM -0700, Simon Glass wrote:
> > > Hi Kuan-Wei,
> > >
> > > On Mon, 5 Jan 2026 at 11:20, Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
> > > >
> > > > Currently, the Goldfish RTC driver exclusively relies on device tree
> > > > to retrieve the base address, failing immediately if dev_read_addr()
> > > > returns FDT_ADDR_T_NONE. This restriction prevents the driver from
> > > > being used on platforms that instantiate devices via U_BOOT_DRVINFO()
> > > > instead of device tree, such as the QEMU m68k virt machine.
> > > >
> > > > Add support for platform data to address this limitation. Update the
> > > > probe function to fall back to retrieving the base address from
> > > > struct goldfish_rtc_plat if the device tree address is unavailable.
> > > > Introduce a new header file include/goldfish_rtc.h to define the
> > > > platform data structure.
> > > >
> > > > Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> > > > Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
> > > > ---
> > > > Changes in v5:
> > > > - Rebase on u-boot/next branch.
> > > >
> > > > drivers/rtc/goldfish_rtc.c | 13 ++++++++++---
> > > > include/goldfish_rtc.h | 15 +++++++++++++++
> > > > 2 files changed, 25 insertions(+), 3 deletions(-)
> > > > create mode 100644 include/goldfish_rtc.h
> > > >
> > >
> > > You can package your own devicetree in the U-Boot source, to handle
> > > what you need.
> >
> > That's not helpful feedback here, the correct path is to use the machine
> > as QEMU provides it and not start yet another pointless argument with
> > QEMU. And this probably applies to some of your other feedback as well,
> > thanks.
>
> From what I understand, QEMU does not use DT for m68k. If it did, then
> we would not be using platdata. Am I missing something here?
Yes, we don't want to add something here in U-Boot that won't be
generally useful. Since it sounds like Daniel has a plan to move
forward, that's the direction to head.
> Regards,
> Simon
>
> PS: The QEMU thing was certainly not pointless, even if the 'argument'
> resolved nothing. We still have this work-around in the docs, 4 years
> and counting:
>
> https://docs.u-boot.org/en/latest/develop/devicetree/dt_qemu.html#merging-in-u-boot-nodes-properties
I've not un-documented your specific workaround for your use-case, that
is true. I also don't know of anyone else using that.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 5/7] board: Add QEMU m68k virt board support
2026-01-05 23:30 ` Simon Glass
@ 2026-01-06 19:22 ` Kuan-Wei Chiu
0 siblings, 0 replies; 26+ messages in thread
From: Kuan-Wei Chiu @ 2026-01-06 19:22 UTC (permalink / raw)
To: Simon Glass
Cc: alison.wang, angelo, trini, me, daniel, heinrich.schuchardt,
jserv, eleanor15x, u-boot
Hi Simon,
On Mon, Jan 05, 2026 at 04:30:31PM -0700, Simon Glass wrote:
> Hi Kuan-Wei,
>
> On Mon, 5 Jan 2026 at 11:21, Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
> >
> > Add support for the QEMU 'virt' machine on the m68k architecture. This
> > board emulates a generic machine based on the Motorola 68040 CPU
> > equipped with Goldfish virtual peripherals.
> >
> > Introduce the necessary board configuration and initialization
> > infrastructure. The implementation includes logic to parse the QEMU
> > bootinfo interface, enabling dynamic detection of system RAM size to
> > adapt to the virtual machine's configuration.
> >
> > Enable the Goldfish TTY driver for serial console output. Additionally,
> > enable Goldfish RTC and timer drivers to support real-time clock
> > functionality and nanosecond-resolution delays. Include comprehensive
> > documentation covering build instructions and usage examples.
> >
> > Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> > Tested-by: Daniel Palmer <daniel@0x0f.com>
> > ---
> > Changes in v5:
> > - Rebase on u-boot/next branch.
> > - Add 'imply CMD_DM' to TARGET_QEMU_M68K.
> >
> > arch/m68k/Kconfig | 9 ++
> > board/emulation/qemu-m68k/Kconfig | 12 +++
> > board/emulation/qemu-m68k/MAINTAINERS | 8 ++
> > board/emulation/qemu-m68k/Makefile | 5 ++
> > board/emulation/qemu-m68k/qemu-m68k.c | 115 ++++++++++++++++++++++++++
> > configs/qemu-m68k_defconfig | 16 ++++
> > doc/board/emulation/index.rst | 1 +
> > doc/board/emulation/qemu-m68k.rst | 39 +++++++++
> > include/configs/qemu-m68k.h | 18 ++++
> > 9 files changed, 223 insertions(+)
> > create mode 100644 board/emulation/qemu-m68k/Kconfig
> > create mode 100644 board/emulation/qemu-m68k/MAINTAINERS
> > create mode 100644 board/emulation/qemu-m68k/Makefile
> > create mode 100644 board/emulation/qemu-m68k/qemu-m68k.c
> > create mode 100644 configs/qemu-m68k_defconfig
> > create mode 100644 doc/board/emulation/qemu-m68k.rst
> > create mode 100644 include/configs/qemu-m68k.h
> >
>
> Very nice patch.
Thanks. :)
>
> > diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
> > index de7c673c376..0cf632729da 100644
> > --- a/arch/m68k/Kconfig
> > +++ b/arch/m68k/Kconfig
> > @@ -183,6 +183,14 @@ config TARGET_STMARK2
> > select CF_DSPI
> > select M54418
> >
> > +config TARGET_QEMU_M68K
> > + bool "Support QEMU m68k virt"
> > + select M68040
> > + imply CMD_DM
> > + help
> > + This target supports the QEMU m68k virtual machine (-M virt).
> > + It simulates a Motorola 68040 CPU with Goldfish peripherals.
> > +
> > endchoice
> >
> > config SYS_CPU
> > @@ -208,6 +216,7 @@ source "board/freescale/m5329evb/Kconfig"
> > source "board/freescale/m5373evb/Kconfig"
> > source "board/sysam/amcore/Kconfig"
> > source "board/sysam/stmark2/Kconfig"
> > +source "board/emulation/qemu-m68k/Kconfig"
> >
> > config M68K_QEMU
> > bool "Build with workarounds for incomplete QEMU emulation"
> > diff --git a/board/emulation/qemu-m68k/Kconfig b/board/emulation/qemu-m68k/Kconfig
> > new file mode 100644
> > index 00000000000..aae6dfe400f
> > --- /dev/null
> > +++ b/board/emulation/qemu-m68k/Kconfig
> > @@ -0,0 +1,12 @@
> > +if TARGET_QEMU_M68K
> > +
> > +config SYS_BOARD
> > + default "qemu-m68k"
> > +
> > +config SYS_VENDOR
> > + default "emulation"
> > +
> > +config SYS_CONFIG_NAME
> > + default "qemu-m68k"
> > +
> > +endif
> > diff --git a/board/emulation/qemu-m68k/MAINTAINERS b/board/emulation/qemu-m68k/MAINTAINERS
> > new file mode 100644
> > index 00000000000..90414c58465
> > --- /dev/null
> > +++ b/board/emulation/qemu-m68k/MAINTAINERS
> > @@ -0,0 +1,8 @@
> > +QEMU M68K VIRT BOARD
> > +M: Kuan-Wei Chiu <visitorckw@gmail.com>
> > +S: Maintained
> > +F: board/emulation/qemu-m68k/
> > +F: board/emulation/common/
> > +F: include/configs/qemu-m68k.h
> > +F: configs/qemu-m68k_defconfig
> > +F: doc/board/emulation/qemu-m68k.rst
> > diff --git a/board/emulation/qemu-m68k/Makefile b/board/emulation/qemu-m68k/Makefile
> > new file mode 100644
> > index 00000000000..5cb2886ff5a
> > --- /dev/null
> > +++ b/board/emulation/qemu-m68k/Makefile
> > @@ -0,0 +1,5 @@
> > +# SPDX-License-Identifier: GPL-2.0-or-later
> > +#
> > +# Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> > +
> > +obj-y += qemu-m68k.o
> > diff --git a/board/emulation/qemu-m68k/qemu-m68k.c b/board/emulation/qemu-m68k/qemu-m68k.c
> > new file mode 100644
> > index 00000000000..3b911b95343
> > --- /dev/null
> > +++ b/board/emulation/qemu-m68k/qemu-m68k.c
> > @@ -0,0 +1,115 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> > + */
> > +
> > +#include <asm-generic/sections.h>
> > +#include <asm/bootinfo.h>
> > +#include <asm/global_data.h>
> > +#include <asm/io.h>
> > +#include <config.h>
> > +#include <dm/platdata.h>
> > +#include <goldfish_rtc.h>
> > +#include <goldfish_timer.h>
> > +#include <goldfish_tty.h>
> > +#include <init.h>
> > +#include <linux/errno.h>
> > +#include <serial.h>
>
> Check header order:
>
> https://docs.u-boot.org/en/v2024.01/develop/codingstyle.html#include-files
I will sort root headers and directory headers separately in v6.
>
> > +
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +/* QEMU Virt Machine Hardware Map */
> > +#define VIRT_GF_RTC_MMIO_BASE 0xff007000
> > +#define VIRT_GF_TTY_MMIO_BASE 0xff008000
> > +#define VIRT_CTRL_MMIO_BASE 0xff009000
> > +#define VIRT_CTRL_RESET 0x01
> > +
>
> Could these move to devicetree? Or perhaps have an overall base + offsets?
I will remove these macros. I plan to extract the bootinfo parsing
logic into a helper and call it in board_early_init_f to get addresses
dynamically.
>
> > +/*
> > + * Theoretical limit derivation:
> > + * Max Bootinfo Size (Standard Page) = 4096 bytes
> > + * Min Record Size (Tag + Size) = 4 bytes
> > + * Max Records = 4096 / 4 = 1024
> > + */
> > +#define MAX_BOOTINFO_RECORDS 1024
> > +
> > +int board_early_init_f(void)
>
> If you don't need this function, you could disable BOARD_EARLY_INIT_F
Ack.
>
> > +{
> > + return 0;
> > +}
> > +
> > +int checkboard(void)
> > +{
> > + puts("Board: QEMU m68k virt\n");
>
> blank line here (and below)
Ack.
>
> > + return 0;
> > +}
> > +
> > +int dram_init(void)
> > +{
> > + struct bi_record *record;
> > + ulong addr;
> > + int loops = 0;
> > +
> > + /* Default: 16MB */
> > + gd->ram_size = 0x01000000;
>
> or SZ_16M
Ack.
>
> > +
> > + /* QEMU places bootinfo after _end, aligned to 2 bytes */
> > + addr = (ulong)&_end;
> > + addr = ALIGN(addr, 2);
> > +
> > + record = (struct bi_record *)addr;
> > +
> > + if (record->tag != BI_MACHTYPE)
> > + return 0;
> > +
> > + while (record->tag != BI_LAST) {
> > + if (++loops > MAX_BOOTINFO_RECORDS)
> > + panic("Bootinfo loop exceeded");
> > + if (record->tag == BI_MEMCHUNK) {
> > + gd->ram_size = record->data[1];
> > + break;
> > + }
> > + record = (struct bi_record *)((ulong)record + record->size);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +void reset_cpu(unsigned long addr)
> > +{
> > + writel(VIRT_CTRL_RESET, VIRT_CTRL_MMIO_BASE);
> > + while (1)
> > + ;
>
> hang()? But if it prints a few characters of the message, you won't want it.
>
> BTW this should really be a sysreset driver.
I will add a sysreset driver for this in v6.
>
> > +}
> > +
> > +int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
> > +{
> > + reset_cpu(0);
> > + return 0;
> > +}
> > +
> > +static const struct goldfish_rtc_plat rtc_plat = {
> > + .base = (void __iomem *)VIRT_GF_RTC_MMIO_BASE,
> > +};
> > +
> > +U_BOOT_DRVINFO(goldfish_rtc) = {
> > + .name = "rtc_goldfish",
> > + .plat = &rtc_plat,
> > +};
> > +
> > +static const struct goldfish_timer_plat timer_plat = {
> > + .base = (void __iomem *)VIRT_GF_RTC_MMIO_BASE,
> > +};
> > +
> > +U_BOOT_DRVINFO(goldfish_timer) = {
> > + .name = "goldfish_timer",
> > + .plat = &timer_plat,
> > +};
> > +
> > +static const struct goldfish_tty_plat serial_plat = {
> > + .base = (void __iomem *)VIRT_GF_TTY_MMIO_BASE,
> > +};
> > +
> > +U_BOOT_DRVINFO(goldfish_serial) = {
> > + .name = "serial_goldfish",
> > + .plat = &serial_plat,
> > +};
>
> This is what device tree is for. It would be trivial to set one up.
Based on the discussion in patch #3, I plan to stick with the current
approach.
Regards,
Kuan-Wei
>
> > diff --git a/configs/qemu-m68k_defconfig b/configs/qemu-m68k_defconfig
> > new file mode 100644
> > index 00000000000..f9294218429
> > --- /dev/null
> > +++ b/configs/qemu-m68k_defconfig
> > @@ -0,0 +1,16 @@
> > +CONFIG_M68K=y
> > +CONFIG_TEXT_BASE=0x00000000
> > +CONFIG_SYS_MALLOC_LEN=0x20000
> > +CONFIG_SYS_MALLOC_F_LEN=0x2000
> > +CONFIG_SYS_MONITOR_LEN=262144
> > +CONFIG_SYS_BOOTM_LEN=0x1000000
> > +CONFIG_SYS_LOAD_ADDR=0x00000000
> > +CONFIG_TARGET_QEMU_M68K=y
> > +# CONFIG_DISPLAY_BOARDINFO is not set
> > +CONFIG_BOARD_EARLY_INIT_F=y
> > +CONFIG_DM_RTC=y
> > +CONFIG_RTC_GOLDFISH=y
> > +CONFIG_DM_SERIAL=y
> > +CONFIG_SERIAL_GOLDFISH=y
> > +CONFIG_TIMER=y
> > +CONFIG_GOLDFISH_TIMER=y
> > diff --git a/doc/board/emulation/index.rst b/doc/board/emulation/index.rst
> > index f8908166276..4f7c812d493 100644
> > --- a/doc/board/emulation/index.rst
> > +++ b/doc/board/emulation/index.rst
> > @@ -15,6 +15,7 @@ Emulation
> > qemu-sbsa
> > qemu-x86
> > qemu-xtensa
> > + qemu-m68k
> >
> > Also see
> >
> > diff --git a/doc/board/emulation/qemu-m68k.rst b/doc/board/emulation/qemu-m68k.rst
> > new file mode 100644
> > index 00000000000..6c4de54cf6a
> > --- /dev/null
> > +++ b/doc/board/emulation/qemu-m68k.rst
> > @@ -0,0 +1,39 @@
> > +.. SPDX-License-Identifier: GPL-2.0-or-later
> > +.. Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> > +
> > +QEMU m68k
> > +=========
> > +
> > +QEMU for m68k supports a special 'virt' machine designed for emulation and
> > +virtualization purposes. This document describes how to run U-Boot under it.
> > +
> > +The QEMU virt machine models a generic m68k virtual machine with Goldfish
> > +interfaces. It supports the Motorola 68040 CPU architecture.
> > +
> > +Building U-Boot
> > +---------------
> > +Set the CROSS_COMPILE environment variable to your m68k toolchain, and run:
> > +
> > +.. code-block:: bash
> > +
> > + export CROSS_COMPILE=m68k-linux-gnu-
> > + make qemu-m68k_defconfig
> > + make
> > +
> > +Running U-Boot
> > +--------------
> > +The minimal QEMU command line to get U-Boot up and running is:
> > +
> > +.. code-block:: bash
> > +
> > + qemu-system-m68k -M virt -cpu m68040 -nographic -kernel u-boot
> > +
> > +Note that the `-nographic` option is used to redirect the console to stdio,
> > +which connects to the emulated Goldfish TTY device.
> > +
> > +Hardware Support
> > +----------------
> > +The following QEMU virt peripherals are supported in U-Boot:
> > +
> > +* Goldfish TTY (Serial Console)
> > +* Goldfish RTC (Real Time Clock)
> > diff --git a/include/configs/qemu-m68k.h b/include/configs/qemu-m68k.h
> > new file mode 100644
> > index 00000000000..1d8aa92fe80
> > --- /dev/null
> > +++ b/include/configs/qemu-m68k.h
> > @@ -0,0 +1,18 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> > + */
> > +
> > +#ifndef __QEMU_M68K_H
> > +#define __QEMU_M68K_H
> > +
> > +/* Memory Configuration */
> > +#define CFG_SYS_SDRAM_BASE 0x00000000
> > +
> > +/*
> > + * Initial Stack Pointer:
> > + * Place the stack at 4MB offset to avoid overwriting U-Boot code/data.
> > + */
> > +#define CFG_SYS_INIT_SP_ADDR (CFG_SYS_SDRAM_BASE + 0x400000)
> > +
> > +#endif /* __QEMU_M68K_H */
> > --
> > 2.52.0.358.g0dd7633a29-goog
> >
>
> Regards,
> Simon
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 1/7] serial: Add Goldfish TTY driver
2026-01-05 23:30 ` Simon Glass
@ 2026-01-06 19:25 ` Kuan-Wei Chiu
0 siblings, 0 replies; 26+ messages in thread
From: Kuan-Wei Chiu @ 2026-01-06 19:25 UTC (permalink / raw)
To: Simon Glass
Cc: alison.wang, angelo, trini, me, daniel, heinrich.schuchardt,
jserv, eleanor15x, u-boot
Hi Simon,
On Mon, Jan 05, 2026 at 04:30:28PM -0700, Simon Glass wrote:
> Hi Kuan-Wei,
>
> On Mon, 5 Jan 2026 at 11:21, Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
> >
> > Add support for the Google Goldfish TTY serial device. This virtual
> > device is commonly used in QEMU virtual machines (such as the m68k
> > virt machine) and Android emulators.
> >
> > The driver implements basic console output and input polling using the
> > Goldfish MMIO interface.
> >
> > Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> > Reviewed-by: Yao Zi <me@ziyao.cc>
> > Tested-by: Daniel Palmer <daniel@0x0f.com>
> > Acked-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
> > ---
> > Changes in v5:
> > - Rebase on u-boot/next branch.
> >
> > MAINTAINERS | 6 ++
> > drivers/serial/Kconfig | 8 +++
> > drivers/serial/Makefile | 1 +
> > drivers/serial/serial_goldfish.c | 109 +++++++++++++++++++++++++++++++
> > include/goldfish_tty.h | 18 +++++
> > 5 files changed, 142 insertions(+)
> > create mode 100644 drivers/serial/serial_goldfish.c
> > create mode 100644 include/goldfish_tty.h
> >
>
> Reviewed-by: Simon Glass <simon.glass@canonical.com>
Thanks for your review!
>
> One thought below.
>
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 27ce73d83f4..8f884ff495a 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1260,6 +1260,12 @@ S: Maintained
> > F: drivers/misc/gsc.c
> > F: include/gsc.h
> >
> > +GOLDFISH SERIAL DRIVER
> > +M: Kuan-Wei Chiu <visitorckw@gmail.com>
> > +S: Maintained
> > +F: drivers/serial/serial_goldfish.c
> > +F: include/goldfish_tty.h
> > +
> > INTERCONNECT:
> > M: Neil Armstrong <neil.armstrong@linaro.org>
> > S: Maintained
> > diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
> > index 371d7aa5bba..b84cb9ec781 100644
> > --- a/drivers/serial/Kconfig
> > +++ b/drivers/serial/Kconfig
> > @@ -1193,4 +1193,12 @@ config SYS_SDMR
> > depends on MPC8XX_CONS
> > default 0x0
> >
> > +config SERIAL_GOLDFISH
> > + bool "Goldfish TTY support"
> > + depends on DM_SERIAL
> > + help
> > + Select this to enable support for the Goldfish TTY serial port.
> > + This virtual device is commonly used by QEMU virtual machines
> > + (e.g. m68k virt) for console output.
> > +
> > endif
> > diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
> > index 8eaae62b0fc..fe8d23be512 100644
> > --- a/drivers/serial/Makefile
> > +++ b/drivers/serial/Makefile
> > @@ -63,3 +63,4 @@ obj-$(CONFIG_XTENSA_SEMIHOSTING_SERIAL) += serial_xtensa_semihosting.o
> > obj-$(CONFIG_S5P4418_PL011_SERIAL) += serial_s5p4418_pl011.o
> >
> > obj-$(CONFIG_UART4_SERIAL) += serial_adi_uart4.o
> > +obj-$(CONFIG_SERIAL_GOLDFISH) += serial_goldfish.o
> > diff --git a/drivers/serial/serial_goldfish.c b/drivers/serial/serial_goldfish.c
> > new file mode 100644
> > index 00000000000..278d0cf3e0d
> > --- /dev/null
> > +++ b/drivers/serial/serial_goldfish.c
> > @@ -0,0 +1,109 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> > + * Goldfish TTY driver for U-Boot
> > + */
> > +
> > +#include <asm/io.h>
> > +#include <dm.h>
> > +#include <goldfish_tty.h>
> > +#include <linux/types.h>
> > +#include <mapmem.h>
> > +#include <serial.h>
> > +
> > +/* Goldfish TTY Register Offsets */
> > +#define GOLDFISH_TTY_PUT_CHAR 0x00
> > +#define GOLDFISH_TTY_BYTES_READY 0x04
> > +#define GOLDFISH_TTY_CMD 0x08
> > +#define GOLDFISH_TTY_DATA_PTR 0x10
> > +#define GOLDFISH_TTY_DATA_LEN 0x14
> > +#define GOLDFISH_TTY_DATA_PTR_HIGH 0x18
> > +#define GOLDFISH_TTY_VERSION 0x20
> > +
> > +/* Commands */
> > +#define CMD_WRITE_BUFFER 2
> > +#define CMD_READ_BUFFER 3
> > +
> > +struct goldfish_tty_priv {
> > + void __iomem *base;
> > + u8 rx_buf;
> > +};
> > +
> > +static int goldfish_serial_getc(struct udevice *dev)
> > +{
> > + struct goldfish_tty_priv *priv = dev_get_priv(dev);
> > + unsigned long paddr;
> > + u32 count;
> > +
> > + count = __raw_readl(priv->base + GOLDFISH_TTY_BYTES_READY);
> > + if (count == 0)
> > + return -EAGAIN;
> > +
> > + paddr = virt_to_phys((void *)&priv->rx_buf);
> > +
> > + __raw_writel(0, priv->base + GOLDFISH_TTY_DATA_PTR_HIGH);
> > + __raw_writel(paddr, priv->base + GOLDFISH_TTY_DATA_PTR);
> > + __raw_writel(1, priv->base + GOLDFISH_TTY_DATA_LEN);
> > + __raw_writel(CMD_READ_BUFFER, priv->base + GOLDFISH_TTY_CMD);
> > +
> > + return priv->rx_buf;
> > +}
> > +
> > +static int goldfish_serial_putc(struct udevice *dev, const char ch)
> > +{
> > + struct goldfish_tty_priv *priv = dev_get_priv(dev);
> > +
> > + __raw_writel(ch, priv->base + GOLDFISH_TTY_PUT_CHAR);
> > +
> > + return 0;
> > +}
> > +
> > +static int goldfish_serial_pending(struct udevice *dev, bool input)
> > +{
> > + struct goldfish_tty_priv *priv = dev_get_priv(dev);
> > +
> > + if (input)
> > + return __raw_readl(priv->base + GOLDFISH_TTY_BYTES_READY);
> > +
> > + return 0;
> > +}
> > +
> > +static int goldfish_serial_probe(struct udevice *dev)
> > +{
> > + struct goldfish_tty_priv *priv = dev_get_priv(dev);
> > + struct goldfish_tty_plat *plat = dev_get_plat(dev);
> > + fdt_addr_t addr;
> > +
> > + addr = dev_read_addr(dev);
> > + if (addr != FDT_ADDR_T_NONE) {
> > + priv->base = map_sysmem(addr, 0x1000);
> > + } else {
> > + plat = dev_get_plat(dev);
> > + if (!plat)
> > + return -EINVAL;
> > + priv->base = plat->base;
> > + }
> > +
> > + return 0;
> > +}
>
> Strictly speaking, reading the devicetree should be done in the
> of_to_plat() method. So you would read the base address there.
>
> Then probe() would convert that to a pointer (I suggest the same 'reg'
> for registers, but it isn't that important).
I will move the device tree reading to of_to_plat() and rename the
platform data member to reg (using phys_addr_t). The probe() function
will then handle the map_sysmem() conversion. I will also apply this
same pattern to the timer and rtc drivers.
Regards,
Kuan-Wei
>
> > +
> > +static const struct dm_serial_ops goldfish_serial_ops = {
> > + .putc = goldfish_serial_putc,
> > + .pending = goldfish_serial_pending,
> > + .getc = goldfish_serial_getc,
> > +};
> > +
> > +static const struct udevice_id goldfish_serial_ids[] = {
> > + { .compatible = "google,goldfish-tty" },
> > + { }
> > +};
> > +
> > +U_BOOT_DRIVER(serial_goldfish) = {
> > + .name = "serial_goldfish",
> > + .id = UCLASS_SERIAL,
> > + .of_match = goldfish_serial_ids,
> > + .probe = goldfish_serial_probe,
> > + .ops = &goldfish_serial_ops,
> > + .priv_auto = sizeof(struct goldfish_tty_priv),
> > + .flags = DM_FLAG_PRE_RELOC,
> > +};
> > diff --git a/include/goldfish_tty.h b/include/goldfish_tty.h
> > new file mode 100644
> > index 00000000000..8777da4942d
> > --- /dev/null
> > +++ b/include/goldfish_tty.h
> > @@ -0,0 +1,18 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> > + */
> > +
> > +#ifndef _GOLDFISH_TTY_H_
> > +#define _GOLDFISH_TTY_H_
> > +
> > +#include <linux/types.h>
> > +
> > +/* Platform data for the Goldfish TTY driver
> > + * Used to pass hardware base address from Board to Driver
> > + */
> > +struct goldfish_tty_plat {
> > + void __iomem *base;
> > +};
> > +
> > +#endif /* _GOLDFISH_TTY_H_ */
> > --
> > 2.52.0.358.g0dd7633a29-goog
> >
>
> Regards,
> Simon
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 4/7] m68k: Add support for M68040 CPU
2026-01-05 23:30 ` Simon Glass
@ 2026-01-06 19:38 ` Kuan-Wei Chiu
0 siblings, 0 replies; 26+ messages in thread
From: Kuan-Wei Chiu @ 2026-01-06 19:38 UTC (permalink / raw)
To: Simon Glass
Cc: alison.wang, angelo, trini, me, daniel, heinrich.schuchardt,
jserv, eleanor15x, u-boot
Hi Simon,
On Mon, Jan 05, 2026 at 04:30:29PM -0700, Simon Glass wrote:
> Hi Kuan-Wei,
>
> On Mon, 5 Jan 2026 at 11:20, Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
> >
> > Add support for the Motorola 68040 architecture. Currently, m68k
> > support in U-Boot is primarily focused on ColdFire variants. Introduce
> > the necessary infrastructure to support the classic M680x0 series,
> > specifically targeting the M68040 as emulated by QEMU.
> >
> > The implementation includes exception vectors, early startup code, and
> > minimal CPU initialization and relocation stubs. It also defines the
> > standard m68k boot information structure used for passing hardware
> > information to the operating system. To ensure compatibility, ColdFire-
> > specific library objects such as cache and interrupt handling are
> > excluded from the build when M68040 is selected.
> >
> > Additionally, apply a specific workaround during the early memory
> > reservation stage. Use a manual loop to clear global data instead of
> > the standard memset() function, as utilizing memset() at this point was
> > observed to cause a hang on the QEMU platform.
> >
> > Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> > ---
> > Changes in v5:
> > - Rebase on u-boot/next branch.
> >
> > MAINTAINERS | 6 +++
> > arch/m68k/Kconfig | 16 +++++++
> > arch/m68k/Makefile | 1 +
> > arch/m68k/config.mk | 10 ++++-
> > arch/m68k/cpu/m680x0/Makefile | 6 +++
> > arch/m68k/cpu/m680x0/cpu.c | 72 +++++++++++++++++++++++++++++++
> > arch/m68k/cpu/m680x0/start.S | 73 ++++++++++++++++++++++++++++++++
> > arch/m68k/cpu/m680x0/u-boot.lds | 47 ++++++++++++++++++++
> > arch/m68k/include/asm/bootinfo.h | 31 ++++++++++++++
> > arch/m68k/lib/Makefile | 9 ++--
> > 10 files changed, 263 insertions(+), 8 deletions(-)
> > create mode 100644 arch/m68k/cpu/m680x0/Makefile
> > create mode 100644 arch/m68k/cpu/m680x0/cpu.c
> > create mode 100644 arch/m68k/cpu/m680x0/start.S
> > create mode 100644 arch/m68k/cpu/m680x0/u-boot.lds
> > create mode 100644 arch/m68k/include/asm/bootinfo.h
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index efecb213be7..bf85f642a8d 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1324,6 +1324,12 @@ F: lib/getopt.c
> > F: test/log/
> > F: test/py/tests/test_log.py
> >
> > +M680X0 ARCHITECTURE
> > +M: Kuan-Wei Chiu <visitorckw@gmail.com>
> > +S: Maintained
> > +F: arch/m68k/cpu/m680x0/
> > +F: arch/m68k/include/asm/bootinfo.h
> > +
> > MALI DISPLAY PROCESSORS
> > M: Liviu Dudau <liviu.dudau@foss.arm.com>
> > S: Supported
> > diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
> > index 8ade6f7b9d1..de7c673c376 100644
> > --- a/arch/m68k/Kconfig
> > +++ b/arch/m68k/Kconfig
> > @@ -56,6 +56,9 @@ config MCF5441x
> > select DM_SERIAL
> > bool
> >
> > +config M680x0
> > + bool
>
> How about a comment as to what this is?
I will add help text to explain that this targets the classic Motorola
680x0 series.
>
> > +
> > # processor type
> > config M5208
> > bool
> > @@ -110,6 +113,10 @@ config M54418
> > bool
> > select MCF5441x
> >
> > +config M68040
> > + bool
> > + select M680x0
> > +
> > # peripherals
> > config CF_DSPI
> > bool
> > @@ -178,6 +185,15 @@ config TARGET_STMARK2
> >
> > endchoice
> >
> > +config SYS_CPU
> > + string
> > + default "mcf52x2" if MCF52x2
> > + default "mcf523x" if MCF523x
> > + default "mcf530x" if MCF530x
> > + default "mcf532x" if MCF532x
> > + default "mcf5445x" if MCF5445x
> > + default "m680x0" if M680x0
> > +
> > source "board/BuS/eb_cpu5282/Kconfig"
> > source "board/cobra5272/Kconfig"
> > source "board/freescale/m5208evbe/Kconfig"
> > diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile
> > index 4a7960bbeb4..bb57cf9ac63 100644
> > --- a/arch/m68k/Makefile
> > +++ b/arch/m68k/Makefile
> > @@ -17,6 +17,7 @@ cpuflags-$(CONFIG_M5307) := -mcpu=5307
> > cpuflags-$(CONFIG_MCF5301x) := -mcpu=53015 -fPIC
> > cpuflags-$(CONFIG_MCF532x) := -mcpu=5329 -fPIC
> > cpuflags-$(CONFIG_MCF5441x) := -mcpu=54418 -fPIC
> > +cpuflags-$(CONFIG_M68040) := -mcpu=68040 -fno-pic
> >
> > PLATFORM_CPPFLAGS += $(cpuflags-y)
> >
> > diff --git a/arch/m68k/config.mk b/arch/m68k/config.mk
> > index 643b7d1d35d..458953f9712 100644
> > --- a/arch/m68k/config.mk
> > +++ b/arch/m68k/config.mk
> > @@ -3,8 +3,14 @@
> > # (C) Copyright 2000-2002
> > # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
> >
> > -PLATFORM_CPPFLAGS += -D__M68K__ -fPIC
> > +PLATFORM_CPPFLAGS += -D__M68K__
> > +ifneq ($(CONFIG_M680x0),y)
> > +PLATFORM_CPPFLAGS += -fPIC
> > +endif
> > KBUILD_LDFLAGS += -n -pie
> > PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
> > -PLATFORM_RELFLAGS += -ffixed-d7 -msep-data
> > +PLATFORM_RELFLAGS += -ffixed-d7
> > +ifneq ($(CONFIG_M680x0),y)
> > +PLATFORM_RELFLAGS += -msep-data
> > +endif
> > LDFLAGS_FINAL += --gc-sections -pie
> > diff --git a/arch/m68k/cpu/m680x0/Makefile b/arch/m68k/cpu/m680x0/Makefile
> > new file mode 100644
> > index 00000000000..f6e0c9a46c0
> > --- /dev/null
> > +++ b/arch/m68k/cpu/m680x0/Makefile
> > @@ -0,0 +1,6 @@
> > +# SPDX-License-Identifier: GPL-2.0-or-later
> > +#
> > +# Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> > +
> > +extra-y += start.o
> > +obj-y += cpu.o
> > diff --git a/arch/m68k/cpu/m680x0/cpu.c b/arch/m68k/cpu/m680x0/cpu.c
> > new file mode 100644
> > index 00000000000..e2974560f4d
> > --- /dev/null
> > +++ b/arch/m68k/cpu/m680x0/cpu.c
> > @@ -0,0 +1,72 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * CPU specific code for m68040
> > + *
> > + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> > + */
> > +
> > +#include <asm/global_data.h>
> > +#include <config.h>
> > +#include <cpu_func.h>
> > +#include <init.h>
> > +#include <linux/types.h>
> > +#include <stdio.h>
> > +
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +void m68k_virt_init_reserve(ulong base)
> > +{
> > + struct global_data *gd_ptr = (struct global_data *)base;
> > + char *p = (char *)gd_ptr;
> > + unsigned int i;
> > +
> > + /* FIXME: usage of memset() here caused a hang on QEMU m68k virt. */
> > + for (i = 0; i < sizeof(*gd_ptr); i++)
> > + p[i] = 0;
>
> Eek!
>
> > +
> > + gd = gd_ptr;
> > +
> > + gd->malloc_base = base + sizeof(*gd_ptr);
> > +}
> > +
> > +int print_cpuinfo(void)
> > +{
> > + puts("CPU: M68040 (QEMU Virt)\n");
>
> We normally put a blank line before the final return (unless it is the
> only code in the function).
Ack. Will fix.
>
> > + return 0;
> > +}
> > +
> > +int get_clocks(void)
> > +{
> > + return 0;
> > +}
> > +
> > +int cpu_init_r(void)
> > +{
> > + return 0;
> > +}
> > +
> > +/*
> > + * Relocation Stub
> > + * We skip actual relocation for this QEMU bring-up and jump directly
> > + * to board_init_r.
> > + */
> > +
> > +void relocate_code(ulong sp, struct global_data *new_gd, ulong relocaddr)
> > +{
> > + board_init_r(new_gd, relocaddr);
>
> Why skip relocation?
As Daniel noted in his review of v2, he has a working implementation
for relocation.
To keep this initial port simple, we decided to defer the relocation
support. Since qemu loads U-Boot directly into ram, running in-place
works sufficient for now. We plan to integrate Daniel's relocation code
in a future patch series.
>
> > +}
> > +
> > +/* Stubs for Standard Facilities (Cache, Interrupts) */
> > +
> > +int disable_interrupts(void) { return 0; }
> > +void enable_interrupts(void) { return; }
> > +int interrupt_init(void) { return 0; }
> > +
> > +void icache_enable(void) {}
> > +void icache_disable(void) {}
> > +int icache_status(void) { return 0; }
> > +void dcache_enable(void) {}
> > +void dcache_disable(void) {}
> > +int dcache_status(void) { return 0; }
> > +void flush_cache(unsigned long start, unsigned long size) {}
> > +void flush_dcache_range(unsigned long start, unsigned long stop) {}
> > diff --git a/arch/m68k/cpu/m680x0/start.S b/arch/m68k/cpu/m680x0/start.S
> > new file mode 100644
> > index 00000000000..0802ca1fca2
> > --- /dev/null
> > +++ b/arch/m68k/cpu/m680x0/start.S
> > @@ -0,0 +1,73 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * Startup code for m68040
> > + *
> > + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> > + */
> > +
> > +#include <asm-offsets.h>
> > +#include <config.h>
> > +#include <linux/linkage.h>
> > +
> > +.section .text
> > +
> > +/*
> > + * Vector Table
> > + * m68k uses the first 1KB for the exception vector table.
> > + */
> > +.balign 4
> > +.global _vectors
> > +_vectors:
> > + .long CFG_SYS_INIT_SP_ADDR /* 0x00: Initial SP */
> > + .long _start /* 0x04: Initial PC (Reset) */
> > + .long _fault /* 0x08: Bus Error */
> > + .long _fault /* 0x0C: Address Error */
> > + .long _fault /* 0x10: Illegal Instruction */
> > + .long _fault /* 0x14: Zero Divide */
> > + .long _fault /* 0x18: CHK */
> > + .long _fault /* 0x1C: TRAPV */
> > + .long _fault /* 0x20: Privilege */
> > + .long _fault /* 0x24: Trace */
> > + .long _fault /* 0x28: Line 1010 */
> > + .long _fault /* 0x2C: Line 1111 */
> > + .fill 0x400 - (.-_vectors), 1, 0
> > +
> > +/*
> > + * Entry Point
> > + */
> > +ENTRY(_start)
> > + /* Disable Interrupts */
> > + move.w #0x2700, %sr
> > +
> > + /* Setup initial stack pointer */
> > + move.l #CFG_SYS_INIT_SP_ADDR, %sp
> > +
> > + /*
> > + * Allocate Global Data (GD)
> > + * board_init_f_alloc_reserve(top) returns the new top of stack in %d0
> > + */
> > + move.l %sp, -(%sp)
> > + bsr.l board_init_f_alloc_reserve
> > + addq.l #4, %sp
> > +
> > + /* Update Stack Pointer and set GD register */
> > + move.l %d0, %sp
> > + move.l %d0, %d7 /* %d7 is the gd register */
> > +
> > + /* Initialize Reserved Memory. */
> > + move.l %d0, -(%sp)
> > + bsr.l m68k_virt_init_reserve
> > + addq.l #4, %sp
> > +
> > + /* Enter board_init_f(0) */
> > + clr.l -(%sp)
> > + bsr.l board_init_f
> > + addq.l #4, %sp
> > +
> > + /* Should not return */
> > +hang:
> > + bra.s hang
> > +ENDPROC(_start)
> > +
> > +_fault:
> > + bra.s _fault
> > diff --git a/arch/m68k/cpu/m680x0/u-boot.lds b/arch/m68k/cpu/m680x0/u-boot.lds
> > new file mode 100644
> > index 00000000000..ae102c32833
> > --- /dev/null
> > +++ b/arch/m68k/cpu/m680x0/u-boot.lds
> > @@ -0,0 +1,47 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Linker Script for m68040
> > + *
> > + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> > + */
> > +
> > +OUTPUT_ARCH(m68k)
> > +ENTRY(_start)
> > +
> > +SECTIONS
> > +{
> > + . = 0x00000000;
> > + __text_start = .;
> > +
> > + .text :
> > + {
> > + arch/m68k/cpu/m680x0/start.o (.text*)
> > + *(.text*)
> > + }
> > +
> > + . = ALIGN(16);
> > + .rodata : { *(.rodata*) }
> > +
> > + . = ALIGN(16);
> > + .data : { *(.data*) }
> > +
> > + . = ALIGN(4);
> > + .u_boot_list : {
> > + KEEP(*(SORT(*u_boot_list*)));
> > + }
> > +
> > + . = ALIGN(4);
> > + __image_copy_end = .;
> > + __init_end = .;
> > +
> > + . = ALIGN(16);
> > + __bss_start = .;
> > + .bss :
> > + {
> > + *(.bss*)
> > + . = ALIGN(16);
> > + }
> > + __bss_end = .;
> > +
> > + _end = .;
> > +}
> > diff --git a/arch/m68k/include/asm/bootinfo.h b/arch/m68k/include/asm/bootinfo.h
> > new file mode 100644
> > index 00000000000..3d2ec818257
> > --- /dev/null
> > +++ b/arch/m68k/include/asm/bootinfo.h
> > @@ -0,0 +1,31 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> > + *
> > + * Definitions for the m68k bootinfo interface.
> > + */
> > +
> > +#ifndef _ASM_M68K_BOOTINFO_H
> > +#define _ASM_M68K_BOOTINFO_H
> > +
> > +#ifndef __ASSEMBLY__
> > +
> > +struct bi_record {
> > + unsigned short tag; /* tag ID */
> > + unsigned short size; /* size of record (in bytes) */
> > + unsigned long data[0]; /* data */
> > +};
> > +
> > +#endif /* __ASSEMBLY__ */
> > +
> > +/* Bootinfo Tag IDs */
> > +#define BI_LAST 0x0000
> > +#define BI_MACHTYPE 0x0001
> > +#define BI_CPUTYPE 0x0002
> > +#define BI_FPUTYPE 0x0003
> > +#define BI_MMUTYPE 0x0004
> > +#define BI_MEMCHUNK 0x0005
> > +#define BI_RAMDISK 0x0006
> > +#define BI_COMMAND_LINE 0x0007
> > +
> > +#endif /* _ASM_M68K_BOOTINFO_H */
> > diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile
> > index 6e1fd938f52..e62de51f260 100644
> > --- a/arch/m68k/lib/Makefile
> > +++ b/arch/m68k/lib/Makefile
> > @@ -7,10 +7,7 @@
> > ## if the user asked for it
> > lib-$(CONFIG_USE_PRIVATE_LIBGCC) += lshrdi3.o muldi3.o ashldi3.o ashrdi3.o
> >
> > -obj-y += bdinfo.o
> > obj-$(CONFIG_CMD_BOOTM) += bootm.o
> > -obj-y += cache.o
> > -obj-y += interrupts.o
> > -obj-y += time.o
> > -obj-y += traps.o
> > -obj-y += fec.o
> > +ifndef CONFIG_M680x0
> > +obj-y += cache.o interrupts.o time.o traps.o bdinfo.o fec.o
> > +endif
>
> Is there a Kconfig you could use to group these files? Then it could
> be enabled if !M680x0
Maybe let's add a new hidden Kconfig symbol CONFIG_ARCH_COLDFIRE which
will be selected by the existing coldfire platforms. Then I can use
obj-$(CONFIG_ARCH_COLDFIRE) to group these files.
Regards,
Kuan-Wei
> > --
> > 2.52.0.358.g0dd7633a29-goog
> >
>
> Regards,
> Simon
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 1/7] serial: Add Goldfish TTY driver
2026-01-05 16:52 ` [PATCH v5 1/7] serial: Add Goldfish TTY driver Kuan-Wei Chiu
2026-01-05 23:30 ` Simon Glass
@ 2026-01-07 10:59 ` Angelo Dureghello
1 sibling, 0 replies; 26+ messages in thread
From: Angelo Dureghello @ 2026-01-07 10:59 UTC (permalink / raw)
To: Kuan-Wei Chiu, alison.wang, trini
Cc: me, daniel, heinrich.schuchardt, jserv, eleanor15x, u-boot
Acked-by: Angelo Dureghello <angelo@kernel-space.org>
On 1/5/26 17:52, Kuan-Wei Chiu wrote:
> Add support for the Google Goldfish TTY serial device. This virtual
> device is commonly used in QEMU virtual machines (such as the m68k
> virt machine) and Android emulators.
>
> The driver implements basic console output and input polling using the
> Goldfish MMIO interface.
>
> Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> Reviewed-by: Yao Zi <me@ziyao.cc>
> Tested-by: Daniel Palmer <daniel@0x0f.com>
> Acked-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
> ---
> Changes in v5:
> - Rebase on u-boot/next branch.
>
> MAINTAINERS | 6 ++
> drivers/serial/Kconfig | 8 +++
> drivers/serial/Makefile | 1 +
> drivers/serial/serial_goldfish.c | 109 +++++++++++++++++++++++++++++++
> include/goldfish_tty.h | 18 +++++
> 5 files changed, 142 insertions(+)
> create mode 100644 drivers/serial/serial_goldfish.c
> create mode 100644 include/goldfish_tty.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 27ce73d83f4..8f884ff495a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1260,6 +1260,12 @@ S: Maintained
> F: drivers/misc/gsc.c
> F: include/gsc.h
>
> +GOLDFISH SERIAL DRIVER
> +M: Kuan-Wei Chiu <visitorckw@gmail.com>
> +S: Maintained
> +F: drivers/serial/serial_goldfish.c
> +F: include/goldfish_tty.h
> +
> INTERCONNECT:
> M: Neil Armstrong <neil.armstrong@linaro.org>
> S: Maintained
> diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
> index 371d7aa5bba..b84cb9ec781 100644
> --- a/drivers/serial/Kconfig
> +++ b/drivers/serial/Kconfig
> @@ -1193,4 +1193,12 @@ config SYS_SDMR
> depends on MPC8XX_CONS
> default 0x0
>
> +config SERIAL_GOLDFISH
> + bool "Goldfish TTY support"
> + depends on DM_SERIAL
> + help
> + Select this to enable support for the Goldfish TTY serial port.
> + This virtual device is commonly used by QEMU virtual machines
> + (e.g. m68k virt) for console output.
> +
> endif
> diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
> index 8eaae62b0fc..fe8d23be512 100644
> --- a/drivers/serial/Makefile
> +++ b/drivers/serial/Makefile
> @@ -63,3 +63,4 @@ obj-$(CONFIG_XTENSA_SEMIHOSTING_SERIAL) += serial_xtensa_semihosting.o
> obj-$(CONFIG_S5P4418_PL011_SERIAL) += serial_s5p4418_pl011.o
>
> obj-$(CONFIG_UART4_SERIAL) += serial_adi_uart4.o
> +obj-$(CONFIG_SERIAL_GOLDFISH) += serial_goldfish.o
> diff --git a/drivers/serial/serial_goldfish.c b/drivers/serial/serial_goldfish.c
> new file mode 100644
> index 00000000000..278d0cf3e0d
> --- /dev/null
> +++ b/drivers/serial/serial_goldfish.c
> @@ -0,0 +1,109 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> + * Goldfish TTY driver for U-Boot
> + */
> +
> +#include <asm/io.h>
> +#include <dm.h>
> +#include <goldfish_tty.h>
> +#include <linux/types.h>
> +#include <mapmem.h>
> +#include <serial.h>
> +
> +/* Goldfish TTY Register Offsets */
> +#define GOLDFISH_TTY_PUT_CHAR 0x00
> +#define GOLDFISH_TTY_BYTES_READY 0x04
> +#define GOLDFISH_TTY_CMD 0x08
> +#define GOLDFISH_TTY_DATA_PTR 0x10
> +#define GOLDFISH_TTY_DATA_LEN 0x14
> +#define GOLDFISH_TTY_DATA_PTR_HIGH 0x18
> +#define GOLDFISH_TTY_VERSION 0x20
> +
> +/* Commands */
> +#define CMD_WRITE_BUFFER 2
> +#define CMD_READ_BUFFER 3
> +
> +struct goldfish_tty_priv {
> + void __iomem *base;
> + u8 rx_buf;
> +};
> +
> +static int goldfish_serial_getc(struct udevice *dev)
> +{
> + struct goldfish_tty_priv *priv = dev_get_priv(dev);
> + unsigned long paddr;
> + u32 count;
> +
> + count = __raw_readl(priv->base + GOLDFISH_TTY_BYTES_READY);
> + if (count == 0)
> + return -EAGAIN;
> +
> + paddr = virt_to_phys((void *)&priv->rx_buf);
> +
> + __raw_writel(0, priv->base + GOLDFISH_TTY_DATA_PTR_HIGH);
> + __raw_writel(paddr, priv->base + GOLDFISH_TTY_DATA_PTR);
> + __raw_writel(1, priv->base + GOLDFISH_TTY_DATA_LEN);
> + __raw_writel(CMD_READ_BUFFER, priv->base + GOLDFISH_TTY_CMD);
> +
> + return priv->rx_buf;
> +}
> +
> +static int goldfish_serial_putc(struct udevice *dev, const char ch)
> +{
> + struct goldfish_tty_priv *priv = dev_get_priv(dev);
> +
> + __raw_writel(ch, priv->base + GOLDFISH_TTY_PUT_CHAR);
> +
> + return 0;
> +}
> +
> +static int goldfish_serial_pending(struct udevice *dev, bool input)
> +{
> + struct goldfish_tty_priv *priv = dev_get_priv(dev);
> +
> + if (input)
> + return __raw_readl(priv->base + GOLDFISH_TTY_BYTES_READY);
> +
> + return 0;
> +}
> +
> +static int goldfish_serial_probe(struct udevice *dev)
> +{
> + struct goldfish_tty_priv *priv = dev_get_priv(dev);
> + struct goldfish_tty_plat *plat = dev_get_plat(dev);
> + fdt_addr_t addr;
> +
> + addr = dev_read_addr(dev);
> + if (addr != FDT_ADDR_T_NONE) {
> + priv->base = map_sysmem(addr, 0x1000);
> + } else {
> + plat = dev_get_plat(dev);
> + if (!plat)
> + return -EINVAL;
> + priv->base = plat->base;
> + }
> +
> + return 0;
> +}
> +
> +static const struct dm_serial_ops goldfish_serial_ops = {
> + .putc = goldfish_serial_putc,
> + .pending = goldfish_serial_pending,
> + .getc = goldfish_serial_getc,
> +};
> +
> +static const struct udevice_id goldfish_serial_ids[] = {
> + { .compatible = "google,goldfish-tty" },
> + { }
> +};
> +
> +U_BOOT_DRIVER(serial_goldfish) = {
> + .name = "serial_goldfish",
> + .id = UCLASS_SERIAL,
> + .of_match = goldfish_serial_ids,
> + .probe = goldfish_serial_probe,
> + .ops = &goldfish_serial_ops,
> + .priv_auto = sizeof(struct goldfish_tty_priv),
> + .flags = DM_FLAG_PRE_RELOC,
> +};
> diff --git a/include/goldfish_tty.h b/include/goldfish_tty.h
> new file mode 100644
> index 00000000000..8777da4942d
> --- /dev/null
> +++ b/include/goldfish_tty.h
> @@ -0,0 +1,18 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> + */
> +
> +#ifndef _GOLDFISH_TTY_H_
> +#define _GOLDFISH_TTY_H_
> +
> +#include <linux/types.h>
> +
> +/* Platform data for the Goldfish TTY driver
> + * Used to pass hardware base address from Board to Driver
> + */
> +struct goldfish_tty_plat {
> + void __iomem *base;
> +};
> +
> +#endif /* _GOLDFISH_TTY_H_ */
-- Angelo
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 2/7] timer: Add Goldfish timer driver
2026-01-05 16:52 ` [PATCH v5 2/7] timer: Add Goldfish timer driver Kuan-Wei Chiu
2026-01-05 23:30 ` Simon Glass
@ 2026-01-07 11:07 ` Angelo Dureghello
1 sibling, 0 replies; 26+ messages in thread
From: Angelo Dureghello @ 2026-01-07 11:07 UTC (permalink / raw)
To: Kuan-Wei Chiu, alison.wang, trini
Cc: me, daniel, heinrich.schuchardt, jserv, eleanor15x, u-boot
Reviewed-by: Angelo Dureghello <angelo@kernel-space.org>
On 1/5/26 17:52, Kuan-Wei Chiu wrote:
> Add support for the Goldfish timer driver. This driver utilizes the
> Goldfish RTC hardware to provide a nanosecond-resolution timer. This
> virtual device is commonly found in QEMU virtual machines (such as the
> m68k virt machine) and Android emulators.
>
> The driver implements the standard U-Boot timer UCLASS interface,
> exposing a 64-bit monotonically increasing counter with a 1GHz clock
> rate derived from the RTC registers.
>
> Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> Tested-by: Daniel Palmer <daniel@0x0f.com>
> Reviewed-by: Yao Zi <me@ziyao.cc>
> ---
> Changes in v5:
> - Rebase on u-boot/next branch.
>
> MAINTAINERS | 6 +++
> drivers/timer/Kconfig | 8 ++++
> drivers/timer/Makefile | 1 +
> drivers/timer/goldfish_timer.c | 81 ++++++++++++++++++++++++++++++++++
> include/goldfish_timer.h | 13 ++++++
> 5 files changed, 109 insertions(+)
> create mode 100644 drivers/timer/goldfish_timer.c
> create mode 100644 include/goldfish_timer.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8f884ff495a..efecb213be7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1266,6 +1266,12 @@ S: Maintained
> F: drivers/serial/serial_goldfish.c
> F: include/goldfish_tty.h
>
> +GOLDFISH TIMER DRIVER
> +M: Kuan-Wei Chiu <visitorckw@gmail.com>
> +S: Maintained
> +F: drivers/timer/goldfish_timer.c
> +F: include/goldfish_timer.h
> +
> INTERCONNECT:
> M: Neil Armstrong <neil.armstrong@linaro.org>
> S: Maintained
> diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
> index f9511503b02..a84a0dc0539 100644
> --- a/drivers/timer/Kconfig
> +++ b/drivers/timer/Kconfig
> @@ -340,4 +340,12 @@ config STARFIVE_TIMER
> Select this to enable support for the timer found on
> Starfive SoC.
>
> +config GOLDFISH_TIMER
> + bool "Goldfish Timer support"
> + depends on TIMER
> + help
> + Select this to enable support for the Goldfish Timer.
> + It uses the Goldfish RTC hardware to provide a nanosecond-resolution
> + timer, commonly found in QEMU virt machines.
> +
> endmenu
> diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
> index a72e411fb2f..d8b3f2b65d4 100644
> --- a/drivers/timer/Makefile
> +++ b/drivers/timer/Makefile
> @@ -36,3 +36,4 @@ obj-$(CONFIG_MCHP_PIT64B_TIMER) += mchp-pit64b-timer.o
> obj-$(CONFIG_IMX_GPT_TIMER) += imx-gpt-timer.o
> obj-$(CONFIG_XILINX_TIMER) += xilinx-timer.o
> obj-$(CONFIG_STARFIVE_TIMER) += starfive-timer.o
> +obj-$(CONFIG_GOLDFISH_TIMER) += goldfish_timer.o
> diff --git a/drivers/timer/goldfish_timer.c b/drivers/timer/goldfish_timer.c
> new file mode 100644
> index 00000000000..63946b9ed97
> --- /dev/null
> +++ b/drivers/timer/goldfish_timer.c
> @@ -0,0 +1,81 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> + *
> + * Goldfish Timer driver
> + */
> +
> +#include <asm/io.h>
> +#include <dm.h>
> +#include <goldfish_timer.h>
> +#include <linux/errno.h>
> +#include <mapmem.h>
> +#include <timer.h>
> +
> +struct goldfish_timer_priv {
> + void __iomem *base;
> +};
> +
> +/* Goldfish RTC registers used as Timer */
> +#define TIMER_TIME_LOW 0x00
> +#define TIMER_TIME_HIGH 0x04
> +
> +static u64 goldfish_timer_get_count(struct udevice *dev)
> +{
> + struct goldfish_timer_priv *priv = dev_get_priv(dev);
> + u32 low, high;
> + u64 time;
> +
> + /*
> + * TIMER_TIME_HIGH is only updated when TIMER_TIME_LOW is read.
> + * We must read LOW before HIGH to latch the high 32-bit value
> + * and ensure a consistent 64-bit timestamp.
> + */
> + low = readl(priv->base + TIMER_TIME_LOW);
> + high = readl(priv->base + TIMER_TIME_HIGH);
> +
> + time = ((u64)high << 32) | low;
> +
> + return time;
> +}
> +
> +static int goldfish_timer_probe(struct udevice *dev)
> +{
> + struct goldfish_timer_priv *priv = dev_get_priv(dev);
> + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
> + struct goldfish_timer_plat *plat;
> + fdt_addr_t addr;
> +
> + addr = dev_read_addr(dev);
> + if (addr != FDT_ADDR_T_NONE) {
> + priv->base = map_sysmem(addr, 0x20);
> + } else {
> + plat = dev_get_plat(dev);
> + if (!plat)
> + return -EINVAL;
> + priv->base = plat->base;
> + }
> +
> + /* Goldfish RTC counts in nanoseconds, so the rate is 1GHz */
> + uc_priv->clock_rate = 1000000000;
> +
> + return 0;
> +}
> +
> +static const struct timer_ops goldfish_timer_ops = {
> + .get_count = goldfish_timer_get_count,
> +};
> +
> +static const struct udevice_id goldfish_timer_ids[] = {
> + { .compatible = "google,goldfish-rtc" },
> + { }
> +};
> +
> +U_BOOT_DRIVER(goldfish_timer) = {
> + .name = "goldfish_timer",
> + .id = UCLASS_TIMER,
> + .of_match = goldfish_timer_ids,
> + .ops = &goldfish_timer_ops,
> + .probe = goldfish_timer_probe,
> + .priv_auto = sizeof(struct goldfish_timer_priv),
> +};
> diff --git a/include/goldfish_timer.h b/include/goldfish_timer.h
> new file mode 100644
> index 00000000000..2ea28170759
> --- /dev/null
> +++ b/include/goldfish_timer.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
> + */
> +
> +#ifndef _GOLDFISH_TIMER_H_
> +#define _GOLDFISH_TIMER_H_
> +
> +struct goldfish_timer_plat {
> + void __iomem *base;
> +};
> +
> +#endif /* _GOLDFISH_TIMER_H_ */
-- Angelo
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 7/7] MAINTAINERS: Update m68k entry
2026-01-05 16:52 ` [PATCH v5 7/7] MAINTAINERS: Update m68k entry Kuan-Wei Chiu
@ 2026-01-07 14:37 ` Angelo Dureghello
2026-01-08 18:52 ` Maciej W. Rozycki
1 sibling, 0 replies; 26+ messages in thread
From: Angelo Dureghello @ 2026-01-07 14:37 UTC (permalink / raw)
To: Kuan-Wei Chiu, alison.wang, trini
Cc: me, daniel, heinrich.schuchardt, jserv, eleanor15x, u-boot
It's ok for me, not owning any m68k hw here.
Also, from my understanding, Alison Wang is out of the games now,
can probably be removed.
Acked-by: Angelo Dureghello <angelo@kernel-space.org>
On 1/5/26 17:52, Kuan-Wei Chiu wrote:
> Rename the "COLDFIRE" entry to "M68K" to reflect that the architecture
> support now encompasses traditional m680x0 CPUs (e.g., M68040) in
> addition to ColdFire platforms.
>
> Add myself as a co-maintainer to assist with reviewing and testing
> m68k-related patches.
>
> Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> ---
> Changes in v5:
> - New patch.
>
> MAINTAINERS | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index bf85f642a8d..57e8fd5bd8f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1045,9 +1045,10 @@ T: git https://source.denx.de/u-boot/custodians/u-boot-clk.git
> F: drivers/clk/
> F: drivers/clk/imx/
>
> -COLDFIRE
> +M68K
> M: Huan Wang <alison.wang@nxp.com>
> M: Angelo Dureghello <angelo@kernel-space.org>
> +M: Kuan-Wei Chiu <visitorckw@gmail.com>
> S: Maintained
> T: git https://source.denx.de/u-boot/custodians/u-boot-coldfire.git
> F: arch/m68k/
-- Angelo
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v5 7/7] MAINTAINERS: Update m68k entry
2026-01-05 16:52 ` [PATCH v5 7/7] MAINTAINERS: Update m68k entry Kuan-Wei Chiu
2026-01-07 14:37 ` Angelo Dureghello
@ 2026-01-08 18:52 ` Maciej W. Rozycki
1 sibling, 0 replies; 26+ messages in thread
From: Maciej W. Rozycki @ 2026-01-08 18:52 UTC (permalink / raw)
To: Kuan-Wei Chiu
Cc: alison.wang, angelo, trini, me, daniel, heinrich.schuchardt,
jserv, eleanor15x, u-boot
On Mon, 5 Jan 2026, Kuan-Wei Chiu wrote:
> diff --git a/MAINTAINERS b/MAINTAINERS
> index bf85f642a8d..57e8fd5bd8f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1045,9 +1045,10 @@ T: git https://source.denx.de/u-boot/custodians/u-boot-clk.git
> F: drivers/clk/
> F: drivers/clk/imx/
>
> -COLDFIRE
> +M68K
> M: Huan Wang <alison.wang@nxp.com>
> M: Angelo Dureghello <angelo@kernel-space.org>
> +M: Kuan-Wei Chiu <visitorckw@gmail.com>
> S: Maintained
> T: git https://source.denx.de/u-boot/custodians/u-boot-coldfire.git
> F: arch/m68k/
The list is sorted alphabetically, so you'd have to reorder entries on
this occasion, preferably in a separate step from adding yourself so that
the addition stands out rather than being buried in the move. Or perhaps
use "COLDFIRE, M68K" for the entry instead?
Maciej
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2026-01-08 18:52 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-05 16:52 [PATCH v5 0/7] m68k: Add support for QEMU virt machine Kuan-Wei Chiu
2026-01-05 16:52 ` [PATCH v5 1/7] serial: Add Goldfish TTY driver Kuan-Wei Chiu
2026-01-05 23:30 ` Simon Glass
2026-01-06 19:25 ` Kuan-Wei Chiu
2026-01-07 10:59 ` Angelo Dureghello
2026-01-05 16:52 ` [PATCH v5 2/7] timer: Add Goldfish timer driver Kuan-Wei Chiu
2026-01-05 23:30 ` Simon Glass
2026-01-07 11:07 ` Angelo Dureghello
2026-01-05 16:52 ` [PATCH v5 3/7] rtc: goldfish: Support platform data for non-DT probing Kuan-Wei Chiu
2026-01-05 23:30 ` Simon Glass
2026-01-05 23:47 ` Tom Rini
2026-01-06 0:58 ` Daniel Palmer
2026-01-06 1:49 ` Tom Rini
2026-01-06 16:22 ` Simon Glass
2026-01-06 16:58 ` Tom Rini
2026-01-05 16:52 ` [PATCH v5 4/7] m68k: Add support for M68040 CPU Kuan-Wei Chiu
2026-01-05 23:30 ` Simon Glass
2026-01-06 19:38 ` Kuan-Wei Chiu
2026-01-05 16:52 ` [PATCH v5 5/7] board: Add QEMU m68k virt board support Kuan-Wei Chiu
2026-01-05 23:30 ` Simon Glass
2026-01-06 19:22 ` Kuan-Wei Chiu
2026-01-05 16:52 ` [PATCH v5 6/7] CI: Add test jobs for QEMU m68k virt machine Kuan-Wei Chiu
2026-01-05 23:30 ` Simon Glass
2026-01-05 16:52 ` [PATCH v5 7/7] MAINTAINERS: Update m68k entry Kuan-Wei Chiu
2026-01-07 14:37 ` Angelo Dureghello
2026-01-08 18:52 ` Maciej W. Rozycki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox