From: Simon Glass <simon.glass@canonical.com>
Add support for building U-Boot as a 64-bit RISC-V EFI application.
This allows U-Boot to run on top of UEFI firmware (e.g. EDK2) on
RISC-V platforms.
Follow the same pattern as the existing ARM and x86 EFI application
boards. Merge the Kconfig choice block into a single block with
per-entry arch dependencies, replacing the previous separate per-arch
choice blocks.
Include a timer node for the RISC-V architectural timer and a /cpus
node with timebase-frequency for QEMU virt (10 MHz) in the device
tree.
Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---
arch/riscv/Kconfig | 8 ++++
arch/riscv/dts/efi-riscv_app.dts | 49 ++++++++++++++++++++
board/efi/Kconfig | 42 ++++++++++-------
board/efi/efi-riscv_app/Kconfig | 26 +++++++++++
board/efi/efi-riscv_app/MAINTAINERS | 7 +++
board/efi/efi-riscv_app/Makefile | 5 +++
board/efi/efi-riscv_app/board.c | 51 +++++++++++++++++++++
board/efi/efi-riscv_app/config.mk | 6 +++
board/efi/efi-riscv_app/efi-riscv_app.env | 12 +++++
configs/efi-riscv_app64_defconfig | 55 +++++++++++++++++++++++
lib/efi_client/Kconfig | 6 +--
11 files changed, 248 insertions(+), 19 deletions(-)
create mode 100644 arch/riscv/dts/efi-riscv_app.dts
create mode 100644 board/efi/efi-riscv_app/Kconfig
create mode 100644 board/efi/efi-riscv_app/MAINTAINERS
create mode 100644 board/efi/efi-riscv_app/Makefile
create mode 100644 board/efi/efi-riscv_app/board.c
create mode 100644 board/efi/efi-riscv_app/config.mk
create mode 100644 board/efi/efi-riscv_app/efi-riscv_app.env
create mode 100644 configs/efi-riscv_app64_defconfig
@@ -55,6 +55,14 @@ config TARGET_XILINX_MBV
config TARGET_ASPEED_AST2700_IBEX
bool "Support Ibex RISC-V cores on Aspeed AST2700 SoC"
+config ARCH_EFI_RISCV
+ bool "efi"
+ select ARCH_EFI
+ help
+ Indicates that this board uses EFI as its underlying base, i.e.
+ that it does not have bare-metal code and can only run as an EFI
+ application.
+
endchoice
config SYS_ICACHE_OFF
new file mode 100644
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 Canonical Ltd
+ * Written by Simon Glass <simon.glass@canonical.com>
+ */
+
+/dts-v1/;
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ model = "EFI RISC-V Application";
+ compatible = "efi,riscv-app";
+
+ chosen {
+ stdout-path = &serial;
+ };
+
+ serial: serial {
+ compatible = "efi,uart";
+ };
+
+ reset {
+ compatible = "efi,reset";
+ bootph-all;
+ };
+
+ efi-fb {
+ compatible = "efi-fb";
+ bootph-some-ram;
+ };
+
+ keyboard {
+ compatible = "efi-keyboard";
+ };
+
+ mouse {
+ compatible = "efi,mouse";
+ };
+
+ cpus {
+ timebase-frequency = <10000000>;
+ };
+
+ timer {
+ compatible = "riscv,timer";
+ };
+
+};
@@ -5,14 +5,13 @@ config ARCH_EFI
if ARCH_EFI
-if X86
-
choice
prompt "Mainboard model"
optional
config TARGET_EFI_X86_APP32
bool "32-bit efi application"
+ depends on X86
select EFI_APP
help
This target is used for running U-Boot on top of EFI. In
@@ -22,6 +21,7 @@ config TARGET_EFI_X86_APP32
config TARGET_EFI_X86_APP64
bool "64-bit efi application"
+ depends on X86
select EFI_APP
select X86_64 if X86
help
@@ -32,27 +32,16 @@ config TARGET_EFI_X86_APP64
config TARGET_EFI_X86_PAYLOAD
bool "efi payload"
+ depends on X86
help
This target is used for running U-Boot on top of EFI. In
this case EFI does the early initialisation, and U-Boot
takes over once the RAM, video and CPU are fully running.
U-Boot is loaded as a payload from EFI.
-endchoice
-
-source "board/efi/efi-x86_app/Kconfig"
-source "board/efi/efi-x86_payload/Kconfig"
-
-endif # X86
-
-if ARM
-
-choice
- prompt "Mainboard model"
- optional
-
config TARGET_EFI_ARM_APP64
bool "64-bit efi application"
+ depends on ARM
select EFI_APP
select SYS_CUSTOM_LDSCRIPT
select ARM64
@@ -62,10 +51,31 @@ config TARGET_EFI_ARM_APP64
starts once the RAM, video and CPU are fully running.
U-Boot is loaded as an application from EFI.
+config TARGET_EFI_RISCV_APP64
+ bool "64-bit efi application"
+ depends on RISCV
+ select EFI_APP
+ select SYS_CUSTOM_LDSCRIPT
+ select ARCH_RV64I
+ help
+ This target is used for running U-Boot on top of EFI in 64-bit mode.
+ In this case EFI does the early initialisation, and U-Boot
+ starts once the RAM, video and CPU are fully running.
+ U-Boot is loaded as an application from EFI.
+
endchoice
+if X86
+source "board/efi/efi-x86_app/Kconfig"
+source "board/efi/efi-x86_payload/Kconfig"
+endif
+
+if ARM
source "board/efi/efi-arm_app/Kconfig"
+endif
-endif # ARM
+if RISCV
+source "board/efi/efi-riscv_app/Kconfig"
+endif
endif # ARCH_EFI
new file mode 100644
@@ -0,0 +1,26 @@
+# Copyright 2026 Canonical Ltd
+# Written by Simon Glass <simon.glass@canonical.com>
+
+if EFI_APP
+
+config SYS_BOARD
+ default "efi-riscv_app"
+
+config SYS_VENDOR
+ default "efi"
+
+config SYS_SOC
+ default "efi"
+
+config SYS_CPU
+ default "generic"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select GENERIC_RISCV
+ imply VIDEO_EFI
+
+config SYS_LDSCRIPT
+ default "arch/riscv/lib/elf_riscv64_efi_app.lds"
+
+endif
new file mode 100644
@@ -0,0 +1,7 @@
+EFI-RISCV_APP64 BOARD
+M: Simon Glass <simon.glass@canonical.com>
+M: Simon Glass <sjg@chromium.org>
+S: Maintained
+F: board/efi/Kconfig
+F: board/efi/efi-riscv_app/
+F: configs/efi-riscv_app64_defconfig
new file mode 100644
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2026 Canonical Ltd
+# Written by Simon Glass <simon.glass@canonical.com>
+
+obj-y += board.o
new file mode 100644
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 Canonical Ltd
+ * Written by Simon Glass <simon.glass@canonical.com>
+ */
+
+#include <bootm.h>
+#include <efi.h>
+#include <event.h>
+#include <init.h>
+
+int print_cpuinfo(void)
+{
+ return 0;
+}
+
+int board_init(void)
+{
+ return 0;
+}
+
+int board_exit_boot_services(void *ctx, struct event *evt)
+{
+ struct efi_priv *priv = efi_get_priv();
+ struct efi_mem_desc *desc;
+ int desc_size;
+ uint version;
+ int size;
+ uint key;
+ int ret;
+
+ if (evt->data.bootm_final.flags & BOOTM_FINAL_FAKE) {
+ printf("Not exiting EFI (fake go)\n");
+ return 0;
+ }
+ printf("Exiting EFI\n");
+ ret = efi_get_mmap(&desc, &size, &key, &desc_size, &version);
+ if (ret) {
+ printf("efi: Failed to get memory map\n");
+ return -EFAULT;
+ }
+
+ ret = efi_app_exit_boot_services(priv, key);
+ if (ret)
+ return ret;
+
+ /* no console output after here as there are no EFI drivers! */
+
+ return 0;
+}
+EVENT_SPY_FULL(EVT_BOOTM_FINAL, board_exit_boot_services);
new file mode 100644
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2026 Canonical Ltd
+# Written by Simon Glass <simon.glass@canonical.com>
+
+BUILD_CFLAGS += -shared
+PLATFORM_CPPFLAGS += $(CFLAGS_EFI)
new file mode 100644
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Environment file for RISC-V EFI app
+ * Copyright 2026 Canonical Ltd
+ * Written by Simon Glass <simon.glass@canonical.com>
+ */
+
+/* common console settings */
+fdt_addr=40000000
+stdin=serial
+stdout=serial,vidconsole
+stderr=serial,vidconsole
new file mode 100644
@@ -0,0 +1,55 @@
+CONFIG_RISCV=y
+CONFIG_NR_DRAM_BANKS=8
+CONFIG_ENV_SIZE=0x1000
+CONFIG_DEFAULT_DEVICE_TREE="efi-riscv_app"
+CONFIG_DEBUG_UART_BASE=0x0
+CONFIG_DEBUG_UART_CLOCK=0
+CONFIG_ARCH_EFI_RISCV=y
+CONFIG_ARCH_RV64I=y
+CONFIG_RISCV_SMODE=y
+CONFIG_TARGET_EFI_RISCV_APP64=y
+CONFIG_EFI_CLIENT=y
+CONFIG_EFI_APP_64BIT=y
+CONFIG_EFI_RAM_SIZE=0x20000000
+CONFIG_FIT=y
+CONFIG_BOOTSTD_FULL=y
+CONFIG_SHOW_BOOT_PROGRESS=y
+CONFIG_OF_SYSTEM_SETUP=y
+CONFIG_FDT_SIMPLEFB=y
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTCOMMAND="bootflow scan -lbp"
+CONFIG_SYS_PBSIZE=532
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+CONFIG_LOG=y
+CONFIG_LOGF_FUNC=y
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_CYCLIC_MAX_CPU_TIME_US=50000
+CONFIG_BOARD_EARLY_INIT_R=y
+CONFIG_CMD_SMBIOS=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MEMINFO_MAP=y
+CONFIG_CMD_LSBLK=y
+CONFIG_CMD_CAT=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_KASLRSEED=y
+CONFIG_CMD_HASH=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_MAC_PARTITION=y
+CONFIG_OF_LIVE=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_USE_BOOTFILE=y
+CONFIG_BOOTFILE="Image"
+CONFIG_NO_NET=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_DM_RNG=y
+CONFIG_DEBUG_EFI_CONSOLE=y
+CONFIG_SYSRESET=y
+CONFIG_VIDEO=y
+CONFIG_CONSOLE_TRUETYPE=y
+CONFIG_SYS_WHITE_ON_BLACK=y
+CONFIG_CONSOLE_SCROLL_LINES=5
+CONFIG_FAT_WRITE=y
+CONFIG_CMD_DHRYSTONE=y
@@ -1,9 +1,9 @@
menu "U-Boot as UEFI application"
- depends on X86 || ARM
+ depends on X86 || ARM || RISCV
config EFI_CLIENT
bool "Support running U-Boot from EFI"
- depends on X86 || ARM
+ depends on X86 || ARM || RISCV
imply DISPLAY_BOARDINFO
imply X86_TSC_READ_BASE
select EFI
@@ -19,7 +19,7 @@ choice
config EFI_APP
bool "Support running as an EFI application"
- depends on X86 || ARM
+ depends on X86 || ARM || RISCV
select CHARSET
select EVENT
imply CONSOLE_MUX