[PATCH v3 14/19] board: emulation: Add qemu-loongarch

Yao Zi <[email protected]>
Newsgroups org.u-boot-project.lists.u-boot
Message-ID <[email protected]>
From: Jiaxun Yang <[email protected]>

Yet another generic QEMU VIRT machine.

LoongArch QEMU splits the main RAM into two parts: the first 512M is
placed at 0x0, and the rest is placed at 0x8000000. FDT locates at
0x100000. BIOS is mapped to the first flash mapped to 0x1c000000, where
U-Boot starts execution.

Signed-off-by: Jiaxun Yang <[email protected]>
Signed-off-by: Yao Zi <[email protected]>
---

Changed from v2
- Add board-level documentation for qemu-loongarch
- Mention the memory layout and booting process in commit message
- Move TARGET_QEMU_LOONGARCH_VIRT to
  board/emulation/qemu-loongarch/Kconfig
- Drop duplicated selection of BOARD_LATE_INIT in
  TARGET_QEMU_LOONGARCH_VIRT
- Explain why RAM is limited to the lowest 4GiB
- Drop unused board_init()
- Rework comment in board_fdt_blob_setup()
- Define FDT address, 0x100000, as a meaningful constant
- Clarify how CFG_SYS_INIT_RAM_[ADDR,SIZE] are chosen
- Add myself to MAINTAINERS

Changed from v1
- Remove dynamic setup for environment variables

 arch/loongarch/Kconfig                        |  4 ++
 arch/loongarch/dts/qemu-loongarch64.dts       |  9 +++
 board/emulation/qemu-loongarch/Kconfig        | 68 +++++++++++++++++++
 board/emulation/qemu-loongarch/MAINTAINERS    |  9 +++
 board/emulation/qemu-loongarch/Makefile       |  6 ++
 .../emulation/qemu-loongarch/qemu-loongarch.c | 67 ++++++++++++++++++
 .../qemu-loongarch/qemu-loongarch.env         |  5 ++
 configs/qemu-loongarch64_defconfig            | 36 ++++++++++
 doc/board/emulation/index.rst                 |  1 +
 doc/board/emulation/qemu-loongarch.rst        | 39 +++++++++++
 include/configs/qemu-loongarch.h              | 17 +++++
 11 files changed, 261 insertions(+)
 create mode 100644 arch/loongarch/dts/qemu-loongarch64.dts
 create mode 100644 board/emulation/qemu-loongarch/Kconfig
 create mode 100644 board/emulation/qemu-loongarch/MAINTAINERS
 create mode 100644 board/emulation/qemu-loongarch/Makefile
 create mode 100644 board/emulation/qemu-loongarch/qemu-loongarch.c
 create mode 100644 board/emulation/qemu-loongarch/qemu-loongarch.env
 create mode 100644 configs/qemu-loongarch64_defconfig
 create mode 100644 doc/board/emulation/qemu-loongarch.rst
 create mode 100644 include/configs/qemu-loongarch.h

diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index c5ef82b583b1..ca7f0adb1496 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -7,9 +7,13 @@ config SYS_ARCH
 choice
 	prompt "Target select"
 
+config TARGET_QEMU_LOONGARCH_VIRT
+	bool "Support QEMU Virt Board"
+
 endchoice
 
 # board-specific options below
+source "board/emulation/qemu-loongarch/Kconfig"
 
 # platform-specific options below
 source "arch/loongarch/cpu/generic/Kconfig"
diff --git a/arch/loongarch/dts/qemu-loongarch64.dts b/arch/loongarch/dts/qemu-loongarch64.dts
new file mode 100644
index 000000000000..39d303798fcb
--- /dev/null
+++ b/arch/loongarch/dts/qemu-loongarch64.dts
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Jiaxun Yang <[email protected]>
+ */
+
+/dts-v1/;
+
+/ {
+};
diff --git a/board/emulation/qemu-loongarch/Kconfig b/board/emulation/qemu-loongarch/Kconfig
new file mode 100644
index 000000000000..94f42091e0be
--- /dev/null
+++ b/board/emulation/qemu-loongarch/Kconfig
@@ -0,0 +1,68 @@
+if TARGET_QEMU_LOONGARCH_VIRT
+
+config SYS_BOARD
+	default "qemu-loongarch"
+
+config SYS_VENDOR
+	default "emulation"
+
+config SYS_CPU
+	default "generic"
+
+config SYS_CONFIG_NAME
+	default "qemu-loongarch"
+
+config TEXT_BASE
+	default 0x1c000000
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+	select GENERIC_LOONGARCH
+	imply AHCI
+	imply PCI_INIT_R
+	imply CMD_PCI
+	imply CMD_POWEROFF
+	imply CMD_SCSI
+	imply CMD_PING
+	imply CMD_EXT2
+	imply CMD_EXT4
+	imply CMD_FAT
+	imply CMD_FS_GENERIC
+	imply DOS_PARTITION
+	imply ISO_PARTITION
+	imply EFI_PARTITION
+	imply SCSI_AHCI
+	imply AHCI_PCI
+	imply E1000
+	imply PCI
+	imply NVME_PCI
+	imply PCIE_ECAM_GENERIC
+	imply DM_RNG
+	imply DM_RTC
+	imply QFW
+	imply QFW_MMIO
+	imply SCSI
+	imply SYS_NS16550
+	imply SYSRESET
+	imply SYSRESET_CMD_POWEROFF
+	imply SYSRESET_SYSCON
+	imply VIRTIO_MMIO
+	imply VIRTIO_PCI
+	imply VIRTIO_NET
+	imply VIRTIO_BLK
+	imply MTD_NOR_FLASH
+	imply CFI_FLASH
+	imply OF_HAS_PRIOR_STAGE
+	imply VIDEO
+	imply VIDEO_BOCHS
+	imply SYS_WHITE_ON_BLACK
+	imply USB
+	imply USB_XHCI_HCD
+	imply USB_XHCI_PCI
+	imply USB_KEYBOARD
+	imply CMD_USB
+	imply UFS
+	imply UFS_PCI
+	imply BOARD_LATE_INIT
+
+endif
diff --git a/board/emulation/qemu-loongarch/MAINTAINERS b/board/emulation/qemu-loongarch/MAINTAINERS
new file mode 100644
index 000000000000..cd9636d6dc9b
--- /dev/null
+++ b/board/emulation/qemu-loongarch/MAINTAINERS
@@ -0,0 +1,9 @@
+QEMU LOONGARCH 'VIRT' BOARD
+M:	Jiaxun Yang <[email protected]>
+M:	Yao Zi <[email protected]>
+S:	Maintained
+F:	board/emulation/qemu-loongarch/
+F:	board/emulation/common/
+F:	include/configs/qemu-loongarch.h
+F:	configs/qemu-loongarch64_defconfig
+F:	doc/board/emulation/qemu-loongarch.rst
diff --git a/board/emulation/qemu-loongarch/Makefile b/board/emulation/qemu-loongarch/Makefile
new file mode 100644
index 000000000000..a928b90780e9
--- /dev/null
+++ b/board/emulation/qemu-loongarch/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2024 Jiaxun yang <[email protected]>
+#
+
+obj-y	+= qemu-loongarch.o
diff --git a/board/emulation/qemu-loongarch/qemu-loongarch.c b/board/emulation/qemu-loongarch/qemu-loongarch.c
new file mode 100644
index 000000000000..56e83fa17be0
--- /dev/null
+++ b/board/emulation/qemu-loongarch/qemu-loongarch.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Jiaxun Yang <[email protected]>
+ */
+
+#include <dm.h>
+#include <dm/ofnode.h>
+#include <env.h>
+#include <fdtdec.h>
+#include <image.h>
+#include <linux/sizes.h>
+#include <lmb.h>
+#include <log.h>
+#include <spl.h>
+#include <init.h>
+#include <usb.h>
+#include <virtio_types.h>
+#include <virtio.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define VIRT_FDT_BASE 0x100000
+
+#if IS_ENABLED(CONFIG_MTD_NOR_FLASH)
+int is_flash_available(void)
+{
+	if (!ofnode_equal(ofnode_by_compatible(ofnode_null(), "cfi-flash"),
+			  ofnode_null()))
+		return 1;
+
+	return 0;
+}
+#endif
+
+phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
+{
+	/*
+	 * Limit RAM used by U-Boot to 4GiB to keep compatible with 32-bit-only
+	 * DMA peripherals, for example, emulated PCI cards.
+	 */
+	if (gd->ram_top > 0x10000000)
+		return 0x10000000;
+
+	return gd->ram_top;
+}
+
+int board_late_init(void)
+{
+	/* start usb so that usb keyboard can be used as input device */
+	if (CONFIG_IS_ENABLED(USB_KEYBOARD))
+		usb_init();
+
+	/*
+	 * Make sure virtio bus is enumerated so that peripherals
+	 * on the virtio bus can be discovered by their drivers
+	 */
+	virtio_init();
+
+	return 0;
+}
+
+int board_fdt_blob_setup(void **fdtp)
+{
+	/* QEMU stores the DTB to 0x100000 */
+	*fdtp = (void *)VIRT_FDT_BASE;
+	return 0;
+}
diff --git a/board/emulation/qemu-loongarch/qemu-loongarch.env b/board/emulation/qemu-loongarch/qemu-loongarch.env
new file mode 100644
index 000000000000..7655f26d8d6b
--- /dev/null
+++ b/board/emulation/qemu-loongarch/qemu-loongarch.env
@@ -0,0 +1,5 @@
+stdin=serial,usbkbd
+stdout=serial,vidconsole
+stderr=serial,vidconsole
+
+boot_targets=qfw usb scsi virtio nvme dhcp
diff --git a/configs/qemu-loongarch64_defconfig b/configs/qemu-loongarch64_defconfig
new file mode 100644
index 000000000000..d7f9c4338486
--- /dev/null
+++ b/configs/qemu-loongarch64_defconfig
@@ -0,0 +1,36 @@
+CONFIG_LOONGARCH=y
+CONFIG_SYS_MALLOC_LEN=0x800000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=8
+CONFIG_ENV_SIZE=0x20000
+CONFIG_DEFAULT_DEVICE_TREE="qemu-loongarch64"
+CONFIG_DM_RESET=y
+CONFIG_SYS_LOAD_ADDR=0x02000000
+CONFIG_SHOW_REGS=y
+# CONFIG_OF_BOARD_FIXUP is not set
+CONFIG_SYS_PCI_64BIT=y
+CONFIG_FIT=y
+CONFIG_BOOTSTD_FULL=y
+CONFIG_SYS_BOOTM_LEN=0x4000000
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS_SUBST=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DISPLAY_BOARDINFO=y
+# CONFIG_CMD_MII is not set
+CONFIG_CMD_2048=y
+CONFIG_CMD_RTC=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_SYSBOOT=y
+CONFIG_CMD_QFW=y
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_BLKMAP=y
+CONFIG_EFI_MEDIA=y
+CONFIG_DM_MMC=y
+CONFIG_DM_MTD=y
+CONFIG_FLASH_SHOW_PROGRESS=0
+CONFIG_SYS_MAX_FLASH_BANKS=2
+CONFIG_PCI_REGION_MULTI_ENTRY=y
+CONFIG_DM_REBOOT_MODE=y
+CONFIG_RESET_SYSCON=y
+CONFIG_HEXDUMP=y
diff --git a/doc/board/emulation/index.rst b/doc/board/emulation/index.rst
index 5d0dd83d8aca..a142cd3360ac 100644
--- a/doc/board/emulation/index.rst
+++ b/doc/board/emulation/index.rst
@@ -11,6 +11,7 @@ Emulation
    network
    video
    qemu-arm
+   qemu-loongarch
    qemu-mips
    qemu-ppce500
    qemu-riscv
diff --git a/doc/board/emulation/qemu-loongarch.rst b/doc/board/emulation/qemu-loongarch.rst
new file mode 100644
index 000000000000..0d97dc7df797
--- /dev/null
+++ b/doc/board/emulation/qemu-loongarch.rst
@@ -0,0 +1,39 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+.. Copyright (C) 2026 Yao Zi <[email protected]>
+
+QEMU LoongArch
+==============
+
+QEMU for LoongArch supports a special 'virt' machine designed for emulation
+and virtualization purpose. This document describes how to run U-Boot under it.
+Only 64-bit LoongArch is supported at this time.
+
+The 'virt' platform provides the following as the basic functionality:
+
+    - A freely configurable amount of CPU cores
+    - U-Boot loaded and executing in the emulated flash, mapped to 0x1c000000.
+    - A generated device tree blob placed at 0x100000.
+    - A freely configurable amount of RAM, described by the DTB, starting at
+      0x0. RAM above 512MiB is placed at 0x80000000.
+    - A NS16550A serial port, discoverable via the DTB.
+    - An in-core constant frequency timer.
+    - syscon-reboot and syscon-poweroff for powering off and rebooting the
+      system.
+    - A generic ECAM-based PCI host controller, discoverable via the DTB.
+
+Additionally, a number of optional peripherals can be added to the PCI bus.
+
+See :doc:`../../develop/devicetree/dt_qemu` for information on how to see the
+devicetree actually generated by QEMU.
+
+Building and Running
+--------------------
+
+Set the CROSS_COMPILE environment variable as usual, and run::
+
+    make qemu-loongarch64_defconfig
+    make
+
+The minimal QEMU command line to get U-Boot up and running is::
+
+    qemu-system-loongarch64 -M virt -nographic -bios u-boot.bin
diff --git a/include/configs/qemu-loongarch.h b/include/configs/qemu-loongarch.h
new file mode 100644
index 000000000000..7103dc1b02ef
--- /dev/null
+++ b/include/configs/qemu-loongarch.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2024 Jiaxun Yang <[email protected]>
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * LoongArch QEMU always places a part of the RAM at 0x0. These options are only
+ * intended to specify the initial stack pointer address, and can be replaced
+ * with CUSTOM_SYS_INIT_SP_ADDR when it's supported in the future.
+ */
+#define CFG_SYS_INIT_RAM_ADDR	0x0
+#define CFG_SYS_INIT_RAM_SIZE	0x80000
+
+#endif
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.