From bf55b84736d6b220dae11e3b1e7a670918d9daee Mon Sep 17 00:00:00 2001 From: Kuan-Wei Chiu Date: Wed, 7 Jan 2026 20:18:30 +0000 Subject: serial: Add Goldfish TTY driver 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 Reviewed-by: Yao Zi Tested-by: Daniel Palmer Acked-by: Heinrich Schuchardt Reviewed-by: Simon Glass Acked-by: Angelo Dureghello --- include/goldfish_tty.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 include/goldfish_tty.h (limited to 'include') diff --git a/include/goldfish_tty.h b/include/goldfish_tty.h new file mode 100644 index 00000000000..db49c8d6344 --- /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 + */ + +#ifndef _GOLDFISH_TTY_H_ +#define _GOLDFISH_TTY_H_ + +#include + +/* Platform data for the Goldfish TTY driver + * Used to pass hardware base address from Board to Driver + */ +struct goldfish_tty_plat { + phys_addr_t reg; +}; + +#endif /* _GOLDFISH_TTY_H_ */ -- cgit v1.3.1 From 909f717eaf299a97fb87307e8606f3fdc6cb0c14 Mon Sep 17 00:00:00 2001 From: Kuan-Wei Chiu Date: Wed, 7 Jan 2026 20:18:31 +0000 Subject: timer: Add Goldfish timer driver 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 Tested-by: Daniel Palmer Reviewed-by: Yao Zi Reviewed-by: Simon Glass Reviewed-by: Angelo Dureghello --- MAINTAINERS | 6 +++ drivers/timer/Kconfig | 8 ++++ drivers/timer/Makefile | 1 + drivers/timer/goldfish_timer.c | 89 ++++++++++++++++++++++++++++++++++++++++++ include/goldfish_timer.h | 13 ++++++ 5 files changed, 117 insertions(+) create mode 100644 drivers/timer/goldfish_timer.c create mode 100644 include/goldfish_timer.h (limited to 'include') 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 +S: Maintained +F: drivers/timer/goldfish_timer.c +F: include/goldfish_timer.h + INTERCONNECT: M: Neil Armstrong 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..70673bbd93c --- /dev/null +++ b/drivers/timer/goldfish_timer.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2025, Kuan-Wei Chiu + * + * Goldfish Timer driver + */ + +#include +#include +#include +#include +#include +#include + +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_of_to_plat(struct udevice *dev) +{ + struct goldfish_timer_plat *plat = dev_get_plat(dev); + fdt_addr_t addr; + + addr = dev_read_addr(dev); + if (addr != FDT_ADDR_T_NONE) + plat->reg = addr; + + return 0; +} + +static int goldfish_timer_probe(struct udevice *dev) +{ + struct goldfish_timer_plat *plat = dev_get_plat(dev); + struct goldfish_timer_priv *priv = dev_get_priv(dev); + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + if (!plat->reg) + return -EINVAL; + + priv->base = map_sysmem(plat->reg, 0x20); + + /* 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, + .of_to_plat = goldfish_timer_of_to_plat, + .plat_auto = sizeof(struct goldfish_timer_plat), + .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..acd3e460c5a --- /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 + */ + +#ifndef _GOLDFISH_TIMER_H_ +#define _GOLDFISH_TIMER_H_ + +struct goldfish_timer_plat { + phys_addr_t reg; +}; + +#endif /* _GOLDFISH_TIMER_H_ */ -- cgit v1.3.1 From b41c54488f6f8263c8b38a6cf97d106c3f9a65bb Mon Sep 17 00:00:00 2001 From: Kuan-Wei Chiu Date: Wed, 7 Jan 2026 20:18:32 +0000 Subject: rtc: goldfish: Support platform data for non-DT probing 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. Introduce a new .of_to_plat hook to handle device tree parsing and populate the platform data. Update the probe function to rely exclusively on this platform data, enabling support for both Device Tree and manual instantiation. Introduce a new header file include/goldfish_rtc.h to define the platform data structure. Signed-off-by: Kuan-Wei Chiu Reviewed-by: Heinrich Schuchardt --- drivers/rtc/goldfish_rtc.c | 23 +++++++++++++++++++---- include/goldfish_rtc.h | 15 +++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 include/goldfish_rtc.h (limited to 'include') diff --git a/drivers/rtc/goldfish_rtc.c b/drivers/rtc/goldfish_rtc.c index e63a2766c76..d2991ca6719 100644 --- a/drivers/rtc/goldfish_rtc.c +++ b/drivers/rtc/goldfish_rtc.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -74,15 +75,27 @@ static int goldfish_rtc_set(struct udevice *dev, const struct rtc_time *time) return 0; } -static int goldfish_rtc_probe(struct udevice *dev) +static int goldfish_rtc_of_to_plat(struct udevice *dev) { - struct goldfish_rtc *priv = dev_get_priv(dev); + struct goldfish_rtc_plat *plat = dev_get_plat(dev); fdt_addr_t addr; addr = dev_read_addr(dev); - if (addr == FDT_ADDR_T_NONE) + if (addr != FDT_ADDR_T_NONE) + plat->reg = addr; + + return 0; +} + +static int goldfish_rtc_probe(struct udevice *dev) +{ + struct goldfish_rtc_plat *plat = dev_get_plat(dev); + struct goldfish_rtc *priv = dev_get_priv(dev); + + if (!plat->reg) return -EINVAL; - priv->base = map_sysmem(addr, 0x20); + + priv->base = map_sysmem(plat->reg, 0x20); return 0; } @@ -103,5 +116,7 @@ U_BOOT_DRIVER(rtc_goldfish) = { .ops = &goldfish_rtc_ops, .probe = goldfish_rtc_probe, .of_match = goldfish_rtc_of_match, + .of_to_plat = goldfish_rtc_of_to_plat, + .plat_auto = sizeof(struct goldfish_rtc_plat), .priv_auto = sizeof(struct goldfish_rtc), }; diff --git a/include/goldfish_rtc.h b/include/goldfish_rtc.h new file mode 100644 index 00000000000..f0e6ba3d543 --- /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 + */ + +#ifndef _GOLDFISH_RTC_H_ +#define _GOLDFISH_RTC_H_ + +#include + +struct goldfish_rtc_plat { + phys_addr_t reg; +}; + +#endif /* _GOLDFISH_RTC_H_ */ -- cgit v1.3.1 From 0429298a1a76b971c0b0156918f927d6329e53bc Mon Sep 17 00:00:00 2001 From: Kuan-Wei Chiu Date: Wed, 7 Jan 2026 20:18:33 +0000 Subject: sysreset: Add QEMU virtual system controller driver Introduce a new sysreset driver for the QEMU Virtual System Controller. This device is found on QEMU "virt" machines (such as the m68k virt target) and provides a mechanism to trigger system reset and power-off events. The driver maps U-Boot sysreset types to the corresponding controller commands: - SYSRESET_WARM / SYSRESET_COLD -> VIRT_CTRL_CMD_RESET - SYSRESET_POWER_OFF -> VIRT_CTRL_CMD_HALT Signed-off-by: Kuan-Wei Chiu Reviewed-by: Simon Glass --- MAINTAINERS | 6 ++++ drivers/sysreset/Kconfig | 8 +++++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_qemu_virt_ctrl.c | 55 ++++++++++++++++++++++++++++++ include/qemu_virt_ctrl.h | 13 +++++++ 5 files changed, 83 insertions(+) create mode 100644 drivers/sysreset/sysreset_qemu_virt_ctrl.c create mode 100644 include/qemu_virt_ctrl.h (limited to 'include') diff --git a/MAINTAINERS b/MAINTAINERS index efecb213be7..34081769ecd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1598,6 +1598,12 @@ S: Maintained T: git https://source.denx.de/u-boot/custodians/u-boot-mpc85xx.git F: arch/powerpc/cpu/mpc85xx/ +QEMU VIRTUAL SYSTEM CONTROLLER +M: Kuan-Wei Chiu +S: Maintained +F: drivers/sysreset/sysreset_qemu_virt_ctrl.c +F: include/qemu_virt_ctrl.h + RAW NAND M: Dario Binacchi M: Michael Trimarchi diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index 0181f6cd581..120e7510f15 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -298,6 +298,14 @@ config SYSRESET_QCOM_PSHOLD help Add support for the system reboot on Qualcomm SoCs via PSHOLD. +config SYSRESET_QEMU_VIRT_CTRL + bool "QEMU Virtual System Controller support" + depends on SYSRESET + help + Enable support for the QEMU Virtual System Controller. + This device is used in QEMU machines (e.g. m68k virt) to trigger + system reset and poweroff events. + endif endmenu diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile index f5c78b25896..d18a5d52360 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -32,3 +32,4 @@ obj-$(CONFIG_$(PHASE_)SYSRESET_X86) += sysreset_x86.o obj-$(CONFIG_SYSRESET_RAA215300) += sysreset_raa215300.o obj-$(CONFIG_SYSRESET_QCOM_PSHOLD) += sysreset_qcom-pshold.o obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o +obj-$(CONFIG_SYSRESET_QEMU_VIRT_CTRL) += sysreset_qemu_virt_ctrl.o diff --git a/drivers/sysreset/sysreset_qemu_virt_ctrl.c b/drivers/sysreset/sysreset_qemu_virt_ctrl.c new file mode 100644 index 00000000000..e7cacc9b6e9 --- /dev/null +++ b/drivers/sysreset/sysreset_qemu_virt_ctrl.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2025, Kuan-Wei Chiu + * + * QEMU Virtual System Controller Driver + */ + +#include +#include +#include +#include +#include + +/* Register offsets */ +#define VIRT_CTRL_REG_FEATURES 0x00 +#define VIRT_CTRL_REG_CMD 0x04 + +/* Commands */ +#define VIRT_CTRL_CMD_NOOP 0x00 +#define VIRT_CTRL_CMD_RESET 0x01 +#define VIRT_CTRL_CMD_HALT 0x02 +#define VIRT_CTRL_CMD_PANIC 0x03 + +static int qemu_virt_ctrl_request(struct udevice *dev, enum sysreset_t type) +{ + struct qemu_virt_ctrl_plat *plat = dev_get_plat(dev); + u32 val; + + switch (type) { + case SYSRESET_WARM: + case SYSRESET_COLD: + val = VIRT_CTRL_CMD_RESET; + break; + case SYSRESET_POWER_OFF: + val = VIRT_CTRL_CMD_HALT; + break; + default: + return -EPROTONOSUPPORT; + } + + writel(val, plat->reg + VIRT_CTRL_REG_CMD); + + return -EINPROGRESS; +} + +static struct sysreset_ops qemu_virt_ctrl_ops = { + .request = qemu_virt_ctrl_request, +}; + +U_BOOT_DRIVER(sysreset_qemu_virt_ctrl) = { + .name = "sysreset_qemu_virt_ctrl", + .id = UCLASS_SYSRESET, + .ops = &qemu_virt_ctrl_ops, + .plat_auto = sizeof(struct qemu_virt_ctrl_plat), +}; diff --git a/include/qemu_virt_ctrl.h b/include/qemu_virt_ctrl.h new file mode 100644 index 00000000000..05aad82b767 --- /dev/null +++ b/include/qemu_virt_ctrl.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2025, Kuan-Wei Chiu + */ + +#ifndef _QEMU_VIRT_CTRL_H_ +#define _QEMU_VIRT_CTRL_H_ + +struct qemu_virt_ctrl_plat { + phys_addr_t reg; +}; + +#endif /* _QEMU_VIRT_CTRL_H_ */ -- cgit v1.3.1 From 516afc8f76268fceb98f6b891a653484e931b26a Mon Sep 17 00:00:00 2001 From: Kuan-Wei Chiu Date: Wed, 7 Jan 2026 20:18:35 +0000 Subject: 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 Tested-by: Daniel Palmer Reviewed-by: Simon Glass --- 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 | 117 ++++++++++++++++++++++++++++++++++ configs/qemu-m68k_defconfig | 20 ++++++ doc/board/emulation/index.rst | 1 + doc/board/emulation/qemu-m68k.rst | 39 ++++++++++++ include/configs/qemu-m68k.h | 18 ++++++ 9 files changed, 229 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 (limited to 'include') 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 */ -- cgit v1.3.1