mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-02 09:46:37 +03:00
Merge patch series "m68k: Add support for QEMU virt machine"
Kuan-Wei Chiu <visitorckw@gmail.com> says: 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. This series expands support to include the classic M680x0 architecture, implementing the necessary exception vectors, startup code, and a bootinfo parser compatible with the QEMU interface. Drivers for Goldfish peripherals (TTY, Timer, RTC) and the QEMU Virtual System Controller (sysreset) are also added to enable serial console, timekeeping, and system reset functionality. 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. Link: https://lore.kernel.org/r/20260107201838.3448806-1-visitorckw@gmail.com [trini: Re-sort MAINTAINERS entries] Signed-off-by: Tom Rini <trini@konsulko.com>
This commit is contained in:
@@ -524,6 +524,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"
|
||||
|
||||
@@ -421,6 +421,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"
|
||||
|
||||
42
MAINTAINERS
42
MAINTAINERS
@@ -1048,15 +1048,6 @@ T: git https://source.denx.de/u-boot/custodians/u-boot-clk.git
|
||||
F: drivers/clk/
|
||||
F: drivers/clk/imx/
|
||||
|
||||
COLDFIRE
|
||||
M: Huan Wang <alison.wang@nxp.com>
|
||||
M: Angelo Dureghello <angelo@kernel-space.org>
|
||||
S: Maintained
|
||||
T: git https://source.denx.de/u-boot/custodians/u-boot-coldfire.git
|
||||
F: arch/m68k/
|
||||
F: doc/arch/m68k.rst
|
||||
F: drivers/watchdog/mcf_wdt.c
|
||||
|
||||
CPU
|
||||
M: Simon Glass <sjg@chromium.org>
|
||||
M: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
|
||||
@@ -1263,6 +1254,18 @@ 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
|
||||
|
||||
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
|
||||
@@ -1315,6 +1318,21 @@ 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
|
||||
|
||||
M68K
|
||||
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/
|
||||
F: doc/arch/m68k.rst
|
||||
F: drivers/watchdog/mcf_wdt.c
|
||||
|
||||
MALI DISPLAY PROCESSORS
|
||||
M: Liviu Dudau <liviu.dudau@foss.arm.com>
|
||||
S: Supported
|
||||
@@ -1589,6 +1607,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 <visitorckw@gmail.com>
|
||||
S: Maintained
|
||||
F: drivers/sysreset/sysreset_qemu_virt_ctrl.c
|
||||
F: include/qemu_virt_ctrl.h
|
||||
|
||||
RAW NAND
|
||||
M: Dario Binacchi <dario.binacchi@amarulasolutions.com>
|
||||
M: Michael Trimarchi <michael@amarulasolutions.com>
|
||||
|
||||
@@ -12,50 +12,64 @@ config MCF520x
|
||||
select OF_CONTROL
|
||||
select DM
|
||||
select DM_SERIAL
|
||||
select ARCH_COLDFIRE
|
||||
bool
|
||||
|
||||
config MCF52x2
|
||||
select OF_CONTROL
|
||||
select DM
|
||||
select DM_SERIAL
|
||||
select ARCH_COLDFIRE
|
||||
bool
|
||||
|
||||
config MCF523x
|
||||
select OF_CONTROL
|
||||
select DM
|
||||
select DM_SERIAL
|
||||
select ARCH_COLDFIRE
|
||||
bool
|
||||
|
||||
config MCF530x
|
||||
select OF_CONTROL
|
||||
select DM
|
||||
select DM_SERIAL
|
||||
select ARCH_COLDFIRE
|
||||
bool
|
||||
|
||||
config MCF5301x
|
||||
select OF_CONTROL
|
||||
select DM
|
||||
select DM_SERIAL
|
||||
select ARCH_COLDFIRE
|
||||
bool
|
||||
|
||||
config MCF532x
|
||||
select OF_CONTROL
|
||||
select DM
|
||||
select DM_SERIAL
|
||||
select ARCH_COLDFIRE
|
||||
bool
|
||||
|
||||
config MCF537x
|
||||
select OF_CONTROL
|
||||
select DM
|
||||
select DM_SERIAL
|
||||
select ARCH_COLDFIRE
|
||||
bool
|
||||
|
||||
config MCF5441x
|
||||
select OF_CONTROL
|
||||
select DM
|
||||
select DM_SERIAL
|
||||
select ARCH_COLDFIRE
|
||||
bool
|
||||
|
||||
config M680x0
|
||||
bool
|
||||
help
|
||||
This enables support for the classic Motorola 68000 family of
|
||||
processors.
|
||||
|
||||
# processor type
|
||||
config M5208
|
||||
bool
|
||||
@@ -110,6 +124,10 @@ config M54418
|
||||
bool
|
||||
select MCF5441x
|
||||
|
||||
config M68040
|
||||
bool
|
||||
select M680x0
|
||||
|
||||
# peripherals
|
||||
config CF_DSPI
|
||||
bool
|
||||
@@ -176,8 +194,28 @@ 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
|
||||
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
|
||||
|
||||
config ARCH_COLDFIRE
|
||||
bool
|
||||
|
||||
source "board/BuS/eb_cpu5282/Kconfig"
|
||||
source "board/cobra5272/Kconfig"
|
||||
source "board/nxp/m5208evbe/Kconfig"
|
||||
@@ -192,6 +230,7 @@ source "board/nxp/m5329evb/Kconfig"
|
||||
source "board/nxp/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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
6
arch/m68k/cpu/m680x0/Makefile
Normal file
6
arch/m68k/cpu/m680x0/Makefile
Normal file
@@ -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
|
||||
73
arch/m68k/cpu/m680x0/cpu.c
Normal file
73
arch/m68k/cpu/m680x0/cpu.c
Normal file
@@ -0,0 +1,73 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* CPU specific code for m68040
|
||||
*
|
||||
* Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <cpu_func.h>
|
||||
#include <init.h>
|
||||
#include <stdio.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <linux/types.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) {}
|
||||
73
arch/m68k/cpu/m680x0/start.S
Normal file
73
arch/m68k/cpu/m680x0/start.S
Normal file
@@ -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
|
||||
47
arch/m68k/cpu/m680x0/u-boot.lds
Normal file
47
arch/m68k/cpu/m680x0/u-boot.lds
Normal file
@@ -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 = .;
|
||||
}
|
||||
39
arch/m68k/include/asm/bootinfo.h
Normal file
39
arch/m68k/include/asm/bootinfo.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* 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
|
||||
|
||||
/* QEMU virt specific tags */
|
||||
#define BI_VIRT_QEMU_VERSION 0x8000
|
||||
#define BI_VIRT_GF_PIC_BASE 0x8001
|
||||
#define BI_VIRT_GF_RTC_BASE 0x8002
|
||||
#define BI_VIRT_GF_TTY_BASE 0x8003
|
||||
#define BI_VIRT_VIRTIO_BASE 0x8004
|
||||
#define BI_VIRT_CTRL_BASE 0x8005
|
||||
|
||||
#endif /* _ASM_M68K_BOOTINFO_H */
|
||||
@@ -7,10 +7,5 @@
|
||||
## 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
|
||||
obj-$(CONFIG_ARCH_COLDFIRE) += cache.o interrupts.o time.o traps.o bdinfo.o fec.o
|
||||
|
||||
12
board/emulation/qemu-m68k/Kconfig
Normal file
12
board/emulation/qemu-m68k/Kconfig
Normal file
@@ -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
|
||||
8
board/emulation/qemu-m68k/MAINTAINERS
Normal file
8
board/emulation/qemu-m68k/MAINTAINERS
Normal file
@@ -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
|
||||
5
board/emulation/qemu-m68k/Makefile
Normal file
5
board/emulation/qemu-m68k/Makefile
Normal file
@@ -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
|
||||
117
board/emulation/qemu-m68k/qemu-m68k.c
Normal file
117
board/emulation/qemu-m68k/qemu-m68k.c
Normal file
@@ -0,0 +1,117 @@
|
||||
// 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,
|
||||
};
|
||||
20
configs/qemu-m68k_defconfig
Normal file
20
configs/qemu-m68k_defconfig
Normal file
@@ -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
|
||||
@@ -17,6 +17,7 @@ Emulation
|
||||
qemu-sbsa
|
||||
qemu-x86
|
||||
qemu-xtensa
|
||||
qemu-m68k
|
||||
|
||||
Also see
|
||||
|
||||
|
||||
39
doc/board/emulation/qemu-m68k.rst
Normal file
39
doc/board/emulation/qemu-m68k.rst
Normal file
@@ -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)
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <div64.h>
|
||||
#include <dm.h>
|
||||
#include <goldfish_rtc.h>
|
||||
#include <mapmem.h>
|
||||
#include <rtc.h>
|
||||
#include <linux/io.h>
|
||||
@@ -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),
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
117
drivers/serial/serial_goldfish.c
Normal file
117
drivers/serial/serial_goldfish.c
Normal file
@@ -0,0 +1,117 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
|
||||
* Goldfish TTY driver for U-Boot
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
#include <goldfish_tty.h>
|
||||
#include <mapmem.h>
|
||||
#include <serial.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/types.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_of_to_plat(struct udevice *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)
|
||||
plat->reg = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int goldfish_serial_probe(struct udevice *dev)
|
||||
{
|
||||
struct goldfish_tty_plat *plat = dev_get_plat(dev);
|
||||
struct goldfish_tty_priv *priv = dev_get_priv(dev);
|
||||
|
||||
if (!plat->reg)
|
||||
return -EINVAL;
|
||||
|
||||
priv->base = map_sysmem(plat->reg, 0x1000);
|
||||
|
||||
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,
|
||||
.of_to_plat = goldfish_serial_of_to_plat,
|
||||
.plat_auto = sizeof(struct goldfish_tty_plat),
|
||||
.probe = goldfish_serial_probe,
|
||||
.ops = &goldfish_serial_ops,
|
||||
.priv_auto = sizeof(struct goldfish_tty_priv),
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
55
drivers/sysreset/sysreset_qemu_virt_ctrl.c
Normal file
55
drivers/sysreset/sysreset_qemu_virt_ctrl.c
Normal file
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
|
||||
*
|
||||
* QEMU Virtual System Controller Driver
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
#include <qemu_virt_ctrl.h>
|
||||
#include <sysreset.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
/* 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),
|
||||
};
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
89
drivers/timer/goldfish_timer.c
Normal file
89
drivers/timer/goldfish_timer.c
Normal file
@@ -0,0 +1,89 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
|
||||
*
|
||||
* Goldfish Timer driver
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
#include <goldfish_timer.h>
|
||||
#include <mapmem.h>
|
||||
#include <timer.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/errno.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_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),
|
||||
};
|
||||
18
include/configs/qemu-m68k.h
Normal file
18
include/configs/qemu-m68k.h
Normal file
@@ -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 */
|
||||
15
include/goldfish_rtc.h
Normal file
15
include/goldfish_rtc.h
Normal file
@@ -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 {
|
||||
phys_addr_t reg;
|
||||
};
|
||||
|
||||
#endif /* _GOLDFISH_RTC_H_ */
|
||||
13
include/goldfish_timer.h
Normal file
13
include/goldfish_timer.h
Normal file
@@ -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 {
|
||||
phys_addr_t reg;
|
||||
};
|
||||
|
||||
#endif /* _GOLDFISH_TIMER_H_ */
|
||||
18
include/goldfish_tty.h
Normal file
18
include/goldfish_tty.h
Normal file
@@ -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 {
|
||||
phys_addr_t reg;
|
||||
};
|
||||
|
||||
#endif /* _GOLDFISH_TTY_H_ */
|
||||
13
include/qemu_virt_ctrl.h
Normal file
13
include/qemu_virt_ctrl.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2025, Kuan-Wei Chiu <visitorckw@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _QEMU_VIRT_CTRL_H_
|
||||
#define _QEMU_VIRT_CTRL_H_
|
||||
|
||||
struct qemu_virt_ctrl_plat {
|
||||
phys_addr_t reg;
|
||||
};
|
||||
|
||||
#endif /* _QEMU_VIRT_CTRL_H_ */
|
||||
Reference in New Issue
Block a user