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 diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 378a974f06c..24b264933bb 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -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 diff --git a/arch/riscv/dts/efi-riscv_app.dts b/arch/riscv/dts/efi-riscv_app.dts new file mode 100644 index 00000000000..092aec90087 --- /dev/null +++ b/arch/riscv/dts/efi-riscv_app.dts @@ -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"; + }; + +}; diff --git a/board/efi/Kconfig b/board/efi/Kconfig index 5237f58093e..d27baa4ccbb 100644 --- a/board/efi/Kconfig +++ b/board/efi/Kconfig @@ -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 diff --git a/board/efi/efi-riscv_app/Kconfig b/board/efi/efi-riscv_app/Kconfig new file mode 100644 index 00000000000..dba7789b7fa --- /dev/null +++ b/board/efi/efi-riscv_app/Kconfig @@ -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 diff --git a/board/efi/efi-riscv_app/MAINTAINERS b/board/efi/efi-riscv_app/MAINTAINERS new file mode 100644 index 00000000000..09babeeb811 --- /dev/null +++ b/board/efi/efi-riscv_app/MAINTAINERS @@ -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 diff --git a/board/efi/efi-riscv_app/Makefile b/board/efi/efi-riscv_app/Makefile new file mode 100644 index 00000000000..8864bcdd0cf --- /dev/null +++ b/board/efi/efi-riscv_app/Makefile @@ -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 diff --git a/board/efi/efi-riscv_app/board.c b/board/efi/efi-riscv_app/board.c new file mode 100644 index 00000000000..9efed36c7d2 --- /dev/null +++ b/board/efi/efi-riscv_app/board.c @@ -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); diff --git a/board/efi/efi-riscv_app/config.mk b/board/efi/efi-riscv_app/config.mk new file mode 100644 index 00000000000..07262dad634 --- /dev/null +++ b/board/efi/efi-riscv_app/config.mk @@ -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) diff --git a/board/efi/efi-riscv_app/efi-riscv_app.env b/board/efi/efi-riscv_app/efi-riscv_app.env new file mode 100644 index 00000000000..57c05d6ee51 --- /dev/null +++ b/board/efi/efi-riscv_app/efi-riscv_app.env @@ -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 diff --git a/configs/efi-riscv_app64_defconfig b/configs/efi-riscv_app64_defconfig new file mode 100644 index 00000000000..f18bfb653ad --- /dev/null +++ b/configs/efi-riscv_app64_defconfig @@ -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 diff --git a/lib/efi_client/Kconfig b/lib/efi_client/Kconfig index d1b4b3bfd8e..f00eea8e8ca 100644 --- a/lib/efi_client/Kconfig +++ b/lib/efi_client/Kconfig @@ -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 -- 2.43.0