diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index f5c0dc037b4..774b119cb4b 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -194,6 +194,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 @@ -222,6 +230,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 +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 + +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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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, +}; diff --git a/configs/qemu-m68k_defconfig b/configs/qemu-m68k_defconfig new file mode 100644 index 00000000000..d667791d93b --- /dev/null +++ b/configs/qemu-m68k_defconfig @@ -0,0 +1,20 @@ +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 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 + +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 + */ + +#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 */