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
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"
--- /dev/null
+if TARGET_QEMU_M68K
+
+config SYS_BOARD
+ default "qemu-m68k"
+
+config SYS_VENDOR
+ default "emulation"
+
+config SYS_CONFIG_NAME
+ default "qemu-m68k"
+
+endif
--- /dev/null
+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
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+
+obj-y += qemu-m68k.o
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
+ */
+
+#include <config.h>
+#include <goldfish_rtc.h>
+#include <goldfish_timer.h>
+#include <goldfish_tty.h>
+#include <init.h>
+#include <qemu_virt_ctrl.h>
+#include <serial.h>
+#include <asm-generic/sections.h>
+#include <asm/bootinfo.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <dm/platdata.h>
+#include <linux/errno.h>
+#include <linux/sizes.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct goldfish_tty_plat serial_plat;
+static struct goldfish_rtc_plat rtc_plat;
+static struct goldfish_timer_plat timer_plat;
+static struct qemu_virt_ctrl_plat reset_plat;
+
+/*
+ * 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
+
+static void parse_bootinfo(void)
+{
+ struct bi_record *record;
+ ulong addr;
+ int loops = 0;
+
+ /* 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;
+
+ while (record->tag != BI_LAST) {
+ phys_addr_t base = record->data[0];
+
+ if (++loops > MAX_BOOTINFO_RECORDS)
+ panic("Bootinfo loop exceeded");
+
+ switch (record->tag) {
+ case BI_VIRT_GF_TTY_BASE:
+ serial_plat.reg = base;
+ break;
+ case BI_VIRT_GF_RTC_BASE:
+ rtc_plat.reg = base;
+ timer_plat.reg = base;
+ break;
+ case BI_VIRT_CTRL_BASE:
+ reset_plat.reg = base;
+ break;
+ case BI_MEMCHUNK:
+ gd->ram_size = record->data[1];
+ break;
+ }
+ record = (struct bi_record *)((ulong)record + record->size);
+ }
+}
+
+int board_early_init_f(void)
+{
+ parse_bootinfo();
+
+ return 0;
+}
+
+int checkboard(void)
+{
+ puts("Board: QEMU m68k virt\n");
+
+ return 0;
+}
+
+int dram_init(void)
+{
+ /* Default: 16MB */
+ if (!gd->ram_size)
+ gd->ram_size = SZ_16M;
+
+ return 0;
+}
+
+U_BOOT_DRVINFO(goldfish_rtc) = {
+ .name = "rtc_goldfish",
+ .plat = &rtc_plat,
+};
+
+U_BOOT_DRVINFO(goldfish_timer) = {
+ .name = "goldfish_timer",
+ .plat = &timer_plat,
+};
+
+U_BOOT_DRVINFO(goldfish_serial) = {
+ .name = "serial_goldfish",
+ .plat = &serial_plat,
+};
+
+U_BOOT_DRVINFO(sysreset_qemu_virt_ctrl) = {
+ .name = "sysreset_qemu_virt_ctrl",
+ .plat = &reset_plat,
+};
--- /dev/null
+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_CMD_POWEROFF=y
+CONFIG_DM_RTC=y
+CONFIG_RTC_GOLDFISH=y
+CONFIG_DM_SERIAL=y
+CONFIG_SERIAL_GOLDFISH=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_CMD_POWEROFF=y
+CONFIG_SYSRESET_QEMU_VIRT_CTRL=y
+CONFIG_TIMER=y
+CONFIG_GOLDFISH_TIMER=y
qemu-sbsa
qemu-x86
qemu-xtensa
+ qemu-m68k
Also see
--- /dev/null
+.. 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)
--- /dev/null
+/* 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 */