summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorKuan-Wei Chiu <[email protected]>2026-01-07 20:18:35 +0000
committerTom Rini <[email protected]>2026-02-02 14:24:41 -0600
commit516afc8f76268fceb98f6b891a653484e931b26a (patch)
treecbf02d6ef5a4cf4ae8c433e2f8f36ec937004ed2 /board
parentc69b6aeaa35550d386c142302b852d6b72aea76f (diff)
board: Add QEMU m68k virt board support
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 <[email protected]> Tested-by: Daniel Palmer <[email protected]> Reviewed-by: Simon Glass <[email protected]>
Diffstat (limited to 'board')
-rw-r--r--board/emulation/qemu-m68k/Kconfig12
-rw-r--r--board/emulation/qemu-m68k/MAINTAINERS8
-rw-r--r--board/emulation/qemu-m68k/Makefile5
-rw-r--r--board/emulation/qemu-m68k/qemu-m68k.c117
4 files changed, 142 insertions, 0 deletions
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 <[email protected]>
+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 <[email protected]>
+
+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..d3527aee112
--- /dev/null
+++ b/board/emulation/qemu-m68k/qemu-m68k.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025, Kuan-Wei Chiu <[email protected]>
+ */
+
+#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,
+};