Skip to contentSkip to conversation

Add UEFI support for RISC-V

PATCH In review Ard Biesheuvel 4 participants 18 messages Apr 22, 2020 – Jun 23, 2020

Subsystems (4)
lore
Share & tools
lore

Ard Biesheuvel

author maintainer
#0 lore raw

v5 cover Add UEFI support for RISC-V

This is a rework of Atish's series [0] to add EFI stub loader support to the RISC-V port. The purpose is to split the code in a way that makes it amenable to being merged via different trees during the same cycle. While at it, I added a patch to disable initrd= loading for new ports, given that it is deprecated and replaced with a method based on a special UEFI device path.

My changes are logged in the individual patches.

I propose to take the first four patches via the EFI tree, and expose them via a stable tag so that the RISC-V maintainers can merge it before applying the remaining patches. That will ensure that both trees remain in a buildable state, with working EFI stub support on the riscv branch.

Cc Atish Patra <[email protected]>
Cc Palmer Dabbelt <[email protected]>
Cc Paul Walmsley <[email protected]>
Cc Albert Ou <[email protected]>

Ard Biesheuvel (1):
efi/libstub: Make initrd file loader configurable

Atish Patra (6):
efi/libstub: Move arm-stub to a common file efi/libstub/riscv: add arch specific efi.h header file
include: pe.h: Add RISC-V related PE definition
RISC-V: Define fixmap bindings for generic early ioremap support
RISC-V: Add PE/COFF header for EFI stub
RISC-V: Add EFI stub support.

 arch/arm/Kconfig                              |   2 +-
 arch/arm64/Kconfig                            |   2 +-
 arch/riscv/Kconfig                            |  21 ++++
 arch/riscv/Makefile                           |   1 +
 arch/riscv/configs/defconfig                  |   1 +
 arch/riscv/include/asm/Kbuild                 |   1 +
 arch/riscv/include/asm/efi.h                  |  41 +++++++
 arch/riscv/include/asm/fixmap.h               |  18 +++
 arch/riscv/include/asm/io.h                   |   1 +
 arch/riscv/include/asm/sections.h             |  13 +++
 arch/riscv/kernel/Makefile                    |   4 +
 arch/riscv/kernel/efi-header.S                | 100 ++++++++++++++++
 arch/riscv/kernel/head.S                      |  16 +++
 arch/riscv/kernel/image-vars.h                |  53 +++++++++
 arch/riscv/kernel/vmlinux.lds.S               |  22 +++-
 drivers/firmware/efi/Kconfig                  |  15 ++-
 drivers/firmware/efi/libstub/Makefile         |  22 +++-
 .../efi/libstub/{arm-stub.c => efi-stub.c}    |   0
 drivers/firmware/efi/libstub/file.c           |   3 +
 drivers/firmware/efi/libstub/riscv-stub.c     | 109 ++++++++++++++++++
 include/linux/pe.h                            |   3 +
 21 files changed, 436 insertions(+), 12 deletions(-)
 create mode 100644 arch/riscv/include/asm/efi.h
 create mode 100644 arch/riscv/include/asm/sections.h
 create mode 100644 arch/riscv/kernel/efi-header.S
 create mode 100644 arch/riscv/kernel/image-vars.h
 rename drivers/firmware/efi/libstub/{arm-stub.c => efi-stub.c} (100%)
 create mode 100644 drivers/firmware/efi/libstub/riscv-stub.c
Signature · 1 line
2.17.1
author maintainer
#1 lore raw

PATCH v5 1/7 efi/libstub: Move arm-stub to a common file

From: Atish Patra <[email protected]>

Most of the arm-stub code is written in an architecture independent manner. As a result, RISC-V can reuse most of the arm-stub code.

Rename the arm-stub.c to efi-stub.c so that ARM, ARM64 and RISC-V can use it. This patch doesn't introduce any functional changes.

---
 arch/arm/Kconfig                                        |  2 +-
 arch/arm64/Kconfig                                      |  2 +-
 drivers/firmware/efi/Kconfig                            |  4 ++--
 drivers/firmware/efi/libstub/Makefile                   | 12 ++++++------
 drivers/firmware/efi/libstub/{arm-stub.c => efi-stub.c} |  0
 5 files changed, 10 insertions(+), 10 deletions(-)
arch/arm/Kconfig +1 -1
index 66a04f6f4775..165987aa5bcd 100644
@@ -1954,7 +1954,7 @@ config EFI
 	select UCS2_STRING
 	select EFI_PARAMS_FROM_FDT
 	select EFI_STUB
-	select EFI_ARMSTUB
+	select EFI_GENERIC_STUB
 	select EFI_RUNTIME_WRAPPERS
 	---help---
 	  This option provides support for runtime services provided
arch/arm64/Kconfig +1 -1
index 40fb05d96c60..32d818c5ccda 100644
@@ -1785,7 +1785,7 @@ config EFI
 	select EFI_PARAMS_FROM_FDT
 	select EFI_RUNTIME_WRAPPERS
 	select EFI_STUB
-	select EFI_ARMSTUB
+	select EFI_GENERIC_STUB
 	default y
 	help
 	  This option provides support for runtime services provided
drivers/firmware/efi/Kconfig +2 -2
index 613828d3f106..2a2b2b96a1dc 100644
@@ -106,12 +106,12 @@ config EFI_PARAMS_FROM_FDT
 config EFI_RUNTIME_WRAPPERS
 	bool
 
-config EFI_ARMSTUB
+config EFI_GENERIC_STUB
 	bool
 
 config EFI_ARMSTUB_DTB_LOADER
 	bool "Enable the DTB loader"
-	depends on EFI_ARMSTUB
+	depends on EFI_GENERIC_STUB
 	default y
 	help
 	  Select this config option to add support for the dtb= command
drivers/firmware/efi/libstub/Makefile +6 -6
index 094eabdecfe6..75cb2c3a1519 100644
@@ -23,7 +23,7 @@ cflags-$(CONFIG_ARM)		:= $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
 				   -fno-builtin -fpic \
 				   $(call cc-option,-mno-single-pic-base)
 
-cflags-$(CONFIG_EFI_ARMSTUB)	+= -I$(srctree)/scripts/dtc/libfdt
+cflags-$(CONFIG_EFI_GENERIC_STUB) += -I$(srctree)/scripts/dtc/libfdt
 
 KBUILD_CFLAGS			:= $(cflags-y) -DDISABLE_BRANCH_PROFILING \
 				   -include $(srctree)/drivers/firmware/efi/libstub/hidden.h \
@@ -45,13 +45,13 @@ lib-y				:= efi-stub-helper.o gop.o secureboot.o tpm.o \
 				   skip_spaces.o lib-cmdline.o lib-ctype.o
 
 # include the stub's generic dependencies from lib/ when building for ARM/arm64
-arm-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c
+efi-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c
 
 $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
 	$(call if_changed_rule,cc_o_c)
 
-lib-$(CONFIG_EFI_ARMSTUB)	+= arm-stub.o fdt.o string.o \
-				   $(patsubst %.c,lib-%.o,$(arm-deps-y))
+lib-$(CONFIG_EFI_GENERIC_STUB)	+= efi-stub.o fdt.o string.o \
+				   $(patsubst %.c,lib-%.o,$(efi-deps-y))
 
 lib-$(CONFIG_ARM)		+= arm32-stub.o
 lib-$(CONFIG_ARM64)		+= arm64-stub.o
@@ -73,8 +73,8 @@ CFLAGS_arm64-stub.o		:= -DTEXT_OFFSET=$(TEXT_OFFSET)
 # a verification pass to see if any absolute relocations exist in any of the
 # object files.
 #
-extra-$(CONFIG_EFI_ARMSTUB)	:= $(lib-y)
-lib-$(CONFIG_EFI_ARMSTUB)	:= $(patsubst %.o,%.stub.o,$(lib-y))
+extra-$(CONFIG_EFI_GENERIC_STUB) := $(lib-y)
+lib-$(CONFIG_EFI_GENERIC_STUB)	:= $(patsubst %.o,%.stub.o,$(lib-y))
 
 STUBCOPY_FLAGS-$(CONFIG_ARM64)	+= --prefix-alloc-sections=.init \
 				   --prefix-symbols=__efistub_
drivers/firmware/efi/libstub/efi-stub.c renamed from drivers/firmware/efi/libstub/arm-stub.c +0 -0
similarity index 100%
rename from drivers/firmware/efi/libstub/arm-stub.c
rename to drivers/firmware/efi/libstub/efi-stub.c
Signature · 1 line
2.17.1
author maintainer
#2 lore raw

PATCH v5 2/7 efi/libstub: Make initrd file loader configurable

In reply to Ard Biesheuvel

Loading an initrd passed via the kernel command line is deprecated: it is limited to files that reside in the same volume as the one the kernel itself was loaded from, and we have more flexible ways to achieve the same. So make it configurable so new architectures can decide not to enable it.

---
 drivers/firmware/efi/Kconfig        | 11 +++++++++++
 drivers/firmware/efi/libstub/file.c |  3 +++
 2 files changed, 14 insertions(+)
drivers/firmware/efi/Kconfig +11 -0
index 2a2b2b96a1dc..4e788dd55b03 100644
@@ -124,6 +124,17 @@ config EFI_ARMSTUB_DTB_LOADER
 	  functionality for bootloaders that do not have such support
 	  this option is necessary.
 
+config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER
+	bool "Enable the command line initrd loader"
+	depends on EFI_GENERIC_STUB
+	default y
+	help
+	  Select this config option to add support for the initrd= command
+	  line parameter, allowing an initrd that resides on the same volume
+	  as the kernel image to be loaded into memory.
+
+	  This method is deprecated.
+
 config EFI_BOOTLOADER_CONTROL
 	tristate "EFI Bootloader Control"
 	depends on EFI_VARS
drivers/firmware/efi/libstub/file.c +3 -0
index ea66b1f16a79..ccdc36aaaa97 100644
@@ -254,6 +254,9 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image,
 			     unsigned long soft_limit,
 			     unsigned long hard_limit)
 {
+	if (!IS_ENABLED(CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER))
+		return EFI_SUCCESS;
+
 	return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2,
 				    soft_limit, hard_limit, load_addr, load_size);
 }
Signature · 1 line
2.17.1
#3 lore raw

Re: [PATCH v5 2/7] efi/libstub: Make initrd file loader configurable

Hi Ard,

Quoted 7 lines · Ard Biesheuvel

Loading an initrd passed via the kernel command line is deprecated: it is limited to files that reside in the same volume as the one the kernel itself was loaded from, and we have more flexible ways to achieve the same. So make it configurable so new architectures can decide not to enable it.

Thanks for your patch, which is now commit cf6b83664895a5c7 ("efi/libstub: Make initrd file loader configurable")!

Quoted 6 lines
drivers/firmware/efi/Kconfig +0 -0
@@ -124,6 +124,17 @@ config EFI_ARMSTUB_DTB_LOADER
          functionality for bootloaders that do not have such support
          this option is necessary.
 

drivers/firmware/efi/Kconfig config EFI_ARMSTUB_DTB_LOADER · line 136

Quoted 10 lines
drivers/firmware/efi/Kconfig +10 -0
+config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER
+       bool "Enable the command line initrd loader"
+       depends on EFI_GENERIC_STUB
+       default y
+       help
+         Select this config option to add support for the initrd= command
+         line parameter, allowing an initrd that resides on the same volume
+         as the kernel image to be loaded into memory.
+
+         This method is deprecated.

So why the default y?

Gr{oetje,eeting}s,

Geert

Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
author maintainer
#4 lore raw

Re: [PATCH v5 2/7] efi/libstub: Make initrd file loader configurable

Quoted 21 lines · Geert Uytterhoeven

Hi Ard,

Quoted 7 lines · Ard Biesheuvel

Loading an initrd passed via the kernel command line is deprecated: it is limited to files that reside in the same volume as the one the kernel itself was loaded from, and we have more flexible ways to achieve the same. So make it configurable so new architectures can decide not to enable it.

Thanks for your patch, which is now commit cf6b83664895a5c7 ("efi/libstub: Make initrd file loader configurable")!

Quoted 6 lines
drivers/firmware/efi/Kconfig +0 -0
@@ -124,6 +124,17 @@ config EFI_ARMSTUB_DTB_LOADER
          functionality for bootloaders that do not have such support
          this option is necessary.
 
Quoted 13 lines

drivers/firmware/efi/Kconfig config EFI_ARMSTUB_DTB_LOADER · line 136

Quoted 10 lines
drivers/firmware/efi/Kconfig +10 -0
+config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER
+       bool "Enable the command line initrd loader"
+       depends on EFI_GENERIC_STUB
+       default y
+       help
+         Select this config option to add support for the initrd= command
+         line parameter, allowing an initrd that resides on the same volume
+         as the kernel image to be loaded into memory.
+
+         This method is deprecated.

So why the default y?

Hallo Geert,

Every time I try to disable something like this, someone pops out of the woodwork to explain how the feature is so vitally important for their highly bespoke and vertically integrated boot flow that it has to be enabled by default for absolutely everybody.

But patches welcome :-)

#5 lore raw

Re: [PATCH v5 2/7] efi/libstub: Make initrd file loader configurable

Hoi Ard,

Quoted 32 lines · Ard Biesheuvel
Quoted 18 lines · Geert Uytterhoeven
Quoted 7 lines · Ard Biesheuvel

Loading an initrd passed via the kernel command line is deprecated: it is limited to files that reside in the same volume as the one the kernel itself was loaded from, and we have more flexible ways to achieve the same. So make it configurable so new architectures can decide not to enable it.

Thanks for your patch, which is now commit cf6b83664895a5c7 ("efi/libstub: Make initrd file loader configurable")!

Quoted 6 lines
drivers/firmware/efi/Kconfig +0 -0
@@ -124,6 +124,17 @@ config EFI_ARMSTUB_DTB_LOADER
          functionality for bootloaders that do not have such support
          this option is necessary.
 
Quoted 12 lines

drivers/firmware/efi/Kconfig config EFI_ARMSTUB_DTB_LOADER · line 136

Quoted 10 lines
drivers/firmware/efi/Kconfig +10 -0
+config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER
+       bool "Enable the command line initrd loader"
+       depends on EFI_GENERIC_STUB
+       default y
+       help
+         Select this config option to add support for the initrd= command
+         line parameter, allowing an initrd that resides on the same volume
+         as the kernel image to be loaded into memory.
+
+         This method is deprecated.

So why the default y?

Quoted 6 lines

Every time I try to disable something like this, someone pops out of the woodwork to explain how the feature is so vitally important for their highly bespoke and vertically integrated boot flow that it has to be enabled by default for absolutely everybody.

But patches welcome :-)

Done
https://lore.kernel.org/linux-efi/[email protected]/

Gr{oetje,eeting}s,

Geert

Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
author maintainer
#6 lore raw

PATCH v5 3/7 efi/libstub/riscv: add arch specific efi.h header file

In reply to Ard Biesheuvel

From: Atish Patra <[email protected]>

Add the arch specific efi.h header defining the RISC-V specific glue for the EFI stub code.

[ardb: - split off from 'RISC-V: Add EFI stub support'
- drop unused definition of VA_BITS_MIN ]

---
 arch/riscv/include/asm/efi.h | 41 ++++++++++++++++++++
 1 file changed, 41 insertions(+)
arch/riscv/include/asm/efi.h new file +41 -0
new file mode 100644
index 000000000000..3dc495a937da
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+#ifndef _ASM_EFI_H
+#define _ASM_EFI_H
+
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/ptrace.h>
+#include <asm/tlbflush.h>
+
+/* on RISC-V, the FDT may be located anywhere in system RAM */
+static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base)
+{
+	return ULONG_MAX;
+}
+
+/* Load initrd at enough distance from DRAM start */
+static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base,
+						    unsigned long image_addr)
+{
+	return dram_base + SZ_256M;
+}
+
+#define efi_bs_call(func, ...)	efi_system_table()->boottime->func(__VA_ARGS__)
+#define efi_rt_call(func, ...)	efi_system_table()->runtime->func(__VA_ARGS__)
+#define efi_is_native()		(true)
+
+#define efi_table_attr(inst, attr)	(inst->attr)
+
+#define efi_call_proto(inst, func, ...) inst->func(inst, ##__VA_ARGS__)
+
+#define alloc_screen_info(x...)		(&screen_info)
+extern char stext_offset[];
+
+static inline void free_screen_info(struct screen_info *si)
+{
+}
+
+#endif /* _ASM_EFI_H */
Signature · 1 line
2.17.1
author maintainer
#7 lore raw

PATCH v5 4/7 include: pe.h: Add RISC-V related PE definition

In reply to Ard Biesheuvel

From: Atish Patra <[email protected]>

Define RISC-V related machine types.

---
 include/linux/pe.h | 3 +++
 1 file changed, 3 insertions(+)
include/linux/pe.h +3 -0
index 8ad71d763a77..daf09ffffe38 100644
@@ -55,6 +55,9 @@
 #define	IMAGE_FILE_MACHINE_POWERPC	0x01f0
 #define	IMAGE_FILE_MACHINE_POWERPCFP	0x01f1
 #define	IMAGE_FILE_MACHINE_R4000	0x0166
+#define	IMAGE_FILE_MACHINE_RISCV32	0x5032
+#define	IMAGE_FILE_MACHINE_RISCV64	0x5064
+#define	IMAGE_FILE_MACHINE_RISCV128	0x5128
 #define	IMAGE_FILE_MACHINE_SH3		0x01a2
 #define	IMAGE_FILE_MACHINE_SH3DSP	0x01a3
 #define	IMAGE_FILE_MACHINE_SH3E		0x01a4
Signature · 1 line
2.17.1
author maintainer
#8 lore raw

PATCH v5 5/7 RISC-V: Define fixmap bindings for generic early ioremap support

In reply to Ard Biesheuvel

From: Atish Patra <[email protected]>

UEFI uses early IO or memory mappings for runtime services before normal ioremap() is usable. This patch only adds minimum necessary fixmap bindings and headers for generic ioremap support to work.

---
 arch/riscv/Kconfig              |  1 +
 arch/riscv/include/asm/Kbuild   |  1 +
 arch/riscv/include/asm/fixmap.h | 18 ++++++++++++++++++
 arch/riscv/include/asm/io.h     |  1 +
 4 files changed, 21 insertions(+)
arch/riscv/Kconfig +1 -0
index 62f7bfeb709e..f05dd09acd48 100644
@@ -68,6 +68,7 @@ config RISCV
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select HAVE_COPY_THREAD_TLS
 	select HAVE_ARCH_KASAN if MMU && 64BIT
+	select GENERIC_EARLY_IOREMAP
 
 config ARCH_MMAP_RND_BITS_MIN
 	default 18 if 64BIT
arch/riscv/include/asm/Kbuild +1 -0
index 3d9410bb4de0..59dd7be55005 100644
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
+generic-y += early_ioremap.h
 generic-y += extable.h
 generic-y += flat.h
 generic-y += kvm_para.h
arch/riscv/include/asm/fixmap.h +18 -0
index 2368d49eb4ef..ba5096d65fb0 100644
@@ -30,6 +30,24 @@ enum fixed_addresses {
 	FIX_TEXT_POKE1,
 	FIX_TEXT_POKE0,
 	FIX_EARLYCON_MEM_BASE,
+	/*
+	 * Make sure that it is 2MB aligned.
+	 */
+#define NR_FIX_SZ_2M	(SZ_2M / PAGE_SIZE)
+	FIX_THOLE = NR_FIX_SZ_2M - FIX_PMD - 1,
+
+	__end_of_permanent_fixed_addresses,
+	/*
+	 * Temporary boot-time mappings, used by early_ioremap(),
+	 * before ioremap() is functional.
+	 */
+#define NR_FIX_BTMAPS		(SZ_256K / PAGE_SIZE)
+#define FIX_BTMAPS_SLOTS	7
+#define TOTAL_FIX_BTMAPS	(NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
+
+	FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
+	FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1,
+
 	__end_of_fixed_addresses
 };
 
arch/riscv/include/asm/io.h +1 -0
index 0f477206a4ed..047f414b6948 100644
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <asm/mmiowb.h>
 #include <asm/pgtable.h>
+#include <asm/early_ioremap.h>
 
 /*
  * MMIO access functions are separated out to break dependency cycles
Signature · 1 line
2.17.1
author maintainer
#9 lore raw

PATCH v5 6/7 RISC-V: Add PE/COFF header for EFI stub

In reply to Ard Biesheuvel

From: Atish Patra <[email protected]>

Linux kernel Image can appear as an EFI application With appropriate PE/COFF header fields in the beginning of the Image header. An EFI application loader can directly load a Linux kernel Image and an EFI stub residing in kernel can boot Linux kernel directly.

Add the necessary PE/COFF header.

[ardb: - use C prefix for c.li to ensure the expected opcode is emitted
- align all image sections according to PE/COFF section alignment ]

---
 arch/riscv/include/asm/sections.h |  13 +++
 arch/riscv/kernel/Makefile        |   4 +
 arch/riscv/kernel/efi-header.S    | 100 ++++++++++++++++++++
 arch/riscv/kernel/head.S          |  16 ++++
 arch/riscv/kernel/image-vars.h    |  53 +++++++++++
 arch/riscv/kernel/vmlinux.lds.S   |  22 ++++-
 6 files changed, 206 insertions(+), 2 deletions(-)
arch/riscv/include/asm/sections.h new file +13 -0
new file mode 100644
index 000000000000..3a9971b1210f
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+#ifndef __ASM_SECTIONS_H
+#define __ASM_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+extern char _start[];
+extern char _start_kernel[];
+
+#endif /* __ASM_SECTIONS_H */
arch/riscv/kernel/Makefile +4 -0
index 86c83081044f..86ca755f8a9f 100644
@@ -32,6 +32,10 @@ obj-y	+= patch.o
 obj-$(CONFIG_MMU) += vdso.o vdso/
 
 obj-$(CONFIG_RISCV_M_MODE)	+= clint.o traps_misaligned.o
+OBJCOPYFLAGS := --prefix-symbols=__efistub_
+$(obj)/%.stub.o: $(obj)/%.o FORCE
+	$(call if_changed,objcopy)
+
 obj-$(CONFIG_FPU)		+= fpu.o
 obj-$(CONFIG_SMP)		+= smpboot.o
 obj-$(CONFIG_SMP)		+= smp.o
arch/riscv/kernel/efi-header.S new file +100 -0

100 lines not on this page · raw message

arch/riscv/kernel/head.S +16 -0
index 98a406474e7d..c31d32e81d39 100644
@@ -13,6 +13,7 @@
 #include <asm/csr.h>
 #include <asm/hwcap.h>
 #include <asm/image.h>
+#include "efi-header.S"
 
 __HEAD
 ENTRY(_start)
@@ -22,10 +23,18 @@ ENTRY(_start)
 	 * Do not modify it without modifying the structure and all bootloaders
 	 * that expects this header format!!
 	 */
+#ifdef CONFIG_EFI
+	/*
+	 * This instruction decodes to "MZ" ASCII required by UEFI.
+	 */
+	c.li s4,-13
+	j _start_kernel
+#else
 	/* jump to start kernel */
 	j _start_kernel
 	/* reserved */
 	.word 0
+#endif
 	.balign 8
 #if __riscv_xlen == 64
 	/* Image load offset(2MB) from start of RAM */
@@ -43,7 +52,14 @@ ENTRY(_start)
 	.ascii RISCV_IMAGE_MAGIC
 	.balign 4
 	.ascii RISCV_IMAGE_MAGIC2
+#ifdef CONFIG_EFI
+	.word pe_head_start - _start
+pe_head_start:
+
+	__EFI_PE_HEADER
+#else
 	.word 0
+#endif
 
 .align 2
 #ifdef CONFIG_MMU
arch/riscv/kernel/image-vars.h new file +53 -0

53 lines not on this page · raw message

arch/riscv/kernel/vmlinux.lds.S +20 -2
index 0339b6bbe11a..ae22057a3f55 100644
@@ -10,6 +10,7 @@
 #include <asm/cache.h>
 #include <asm/thread_info.h>
 #include <asm/set_memory.h>
+#include "image-vars.h"
 
 #include <linux/sizes.h>
 OUTPUT_ARCH(riscv)
@@ -17,6 +18,9 @@ ENTRY(_start)
 
 jiffies = jiffies_64;
 
+PECOFF_SECTION_ALIGNMENT = 0x1000;
+PECOFF_FILE_ALIGNMENT = 0x200;
+
 SECTIONS
 {
 	/* Beginning of code and text segment */
@@ -71,6 +75,10 @@ SECTIONS
 
 	EXCEPTION_TABLE(0x10)
 
+#ifdef CONFIG_EFI
+	. = ALIGN(PECOFF_SECTION_ALIGNMENT);
+	__pecoff_text_end = .;
+#endif
 	. = ALIGN(SECTION_ALIGN);
 	_data = .;
 
@@ -78,16 +86,26 @@ SECTIONS
 	.sdata : {
 		__global_pointer$ = . + 0x800;
 		*(.sdata*)
-		/* End of data section */
-		_edata = .;
 	}
 
+#ifdef CONFIG_EFI
+	.pecoff_edata_padding : { BYTE(0); . = ALIGN(PECOFF_FILE_ALIGNMENT); }
+	__pecoff_data_raw_size = ABSOLUTE(. - __pecoff_text_end);
+#endif
+
+	/* End of data section */
+	_edata = .;
+
 	BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 0)
 
 	.rel.dyn : {
 		*(.rel.dyn*)
 	}
 
+#ifdef CONFIG_EFI
+	. = ALIGN(PECOFF_SECTION_ALIGNMENT);
+	__pecoff_data_virt_size = ABSOLUTE(. - __pecoff_text_end);
+#endif
 	_end = .;
 
 	STABS_DEBUG
Signature · 1 line
2.17.1
author maintainer
#10 lore raw

PATCH v5 7/7 RISC-V: Add EFI stub support.

In reply to Ard Biesheuvel

From: Atish Patra <[email protected]>

Add a RISC-V architecture specific stub code that actually copies the actual kernel image to a valid address and jump to it after boot services are terminated. Enable UEFI related kernel configs as well for RISC-V.

[ardb: - move hartid fetch into check_platform_features()
- use image_size not reserve_size
- moved asm/efi.h addition into separate patch ]

---
 arch/riscv/Kconfig                        |  20 ++++
 arch/riscv/Makefile                       |   1 +
 arch/riscv/configs/defconfig              |   1 +
 drivers/firmware/efi/Kconfig              |   4 +-
 drivers/firmware/efi/libstub/Makefile     |  10 ++
 drivers/firmware/efi/libstub/riscv-stub.c | 109 ++++++++++++++++++++
 6 files changed, 143 insertions(+), 2 deletions(-)
arch/riscv/Kconfig +20 -0
index f05dd09acd48..54c78cafcd35 100644
@@ -379,10 +379,30 @@ config CMDLINE_FORCE
 
 endchoice
 
+config EFI_STUB
+	bool
+
+config EFI
+	bool "UEFI runtime support"
+	depends on OF
+	select LIBFDT
+	select UCS2_STRING
+	select EFI_PARAMS_FROM_FDT
+	select EFI_STUB
+	select EFI_GENERIC_STUB
+	default y
+	help
+	  This option provides support for runtime services provided
+	  by UEFI firmware (such as non-volatile variables, realtime
+	  clock, and platform reset). A UEFI stub is also provided to
+	  allow the kernel to be booted as an EFI application. This
+	  is only useful on systems that have UEFI firmware.
+
 endmenu
 
 menu "Power management options"
 
 source "kernel/power/Kconfig"
+source "drivers/firmware/Kconfig"
 
 endmenu
arch/riscv/Makefile +1 -0
index fb6e37db836d..079435804d6d 100644
@@ -80,6 +80,7 @@ head-y := arch/riscv/kernel/head.o
 core-y += arch/riscv/
 
 libs-y += arch/riscv/lib/
+core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
 
 PHONY += vdso_install
 vdso_install:
arch/riscv/configs/defconfig +1 -0
index 4da4886246a4..ae69e12d306a 100644
@@ -129,3 +129,4 @@ CONFIG_DEBUG_BLOCK_EXT_DEVT=y
 # CONFIG_RUNTIME_TESTING_MENU is not set
 CONFIG_MEMTEST=y
 # CONFIG_SYSFS_SYSCALL is not set
+CONFIG_EFI=y
drivers/firmware/efi/Kconfig +2 -2
index 4e788dd55b03..8bfc17381b29 100644
@@ -111,7 +111,7 @@ config EFI_GENERIC_STUB
 
 config EFI_ARMSTUB_DTB_LOADER
 	bool "Enable the DTB loader"
-	depends on EFI_GENERIC_STUB
+	depends on EFI_GENERIC_STUB && !RISCV
 	default y
 	help
 	  Select this config option to add support for the dtb= command
@@ -126,7 +126,7 @@ config EFI_ARMSTUB_DTB_LOADER
 
 config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER
 	bool "Enable the command line initrd loader"
-	depends on EFI_GENERIC_STUB
+	depends on EFI_GENERIC_STUB && !RISCV
 	default y
 	help
 	  Select this config option to add support for the initrd= command
drivers/firmware/efi/libstub/Makefile +10 -0
index 75cb2c3a1519..a4fd1b048e8c 100644
@@ -22,6 +22,8 @@ cflags-$(CONFIG_ARM64)		:= $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
 cflags-$(CONFIG_ARM)		:= $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
 				   -fno-builtin -fpic \
 				   $(call cc-option,-mno-single-pic-base)
+cflags-$(CONFIG_RISCV)		:= $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
+				   -fpic
 
 cflags-$(CONFIG_EFI_GENERIC_STUB) += -I$(srctree)/scripts/dtc/libfdt
 
@@ -56,6 +58,7 @@ lib-$(CONFIG_EFI_GENERIC_STUB)	+= efi-stub.o fdt.o string.o \
 lib-$(CONFIG_ARM)		+= arm32-stub.o
 lib-$(CONFIG_ARM64)		+= arm64-stub.o
 lib-$(CONFIG_X86)		+= x86-stub.o
+lib-$(CONFIG_RISCV)		+= riscv-stub.o
 CFLAGS_arm32-stub.o		:= -DTEXT_OFFSET=$(TEXT_OFFSET)
 CFLAGS_arm64-stub.o		:= -DTEXT_OFFSET=$(TEXT_OFFSET)
 
@@ -80,6 +83,13 @@ STUBCOPY_FLAGS-$(CONFIG_ARM64)	+= --prefix-alloc-sections=.init \
 				   --prefix-symbols=__efistub_
 STUBCOPY_RELOC-$(CONFIG_ARM64)	:= R_AARCH64_ABS
 
+# For RISC-V, we don't need anything special other than arm64. Keep all the
+# symbols in .init section and make sure that no absolute symbols references
+# doesn't exist.
+STUBCOPY_FLAGS-$(CONFIG_RISCV)	+= --prefix-alloc-sections=.init \
+				   --prefix-symbols=__efistub_
+STUBCOPY_RELOC-$(CONFIG_RISCV)	:= R_RISCV_HI20
+
 $(obj)/%.stub.o: $(obj)/%.o FORCE
 	$(call if_changed,stubcopy)
 
drivers/firmware/efi/libstub/riscv-stub.c new file +109 -0

109 lines not on this page · raw message

Signature · 1 line
2.17.1
#11 lore raw

Re: [PATCH v5 7/7] RISC-V: Add EFI stub support.

Quoted 33 lines · Ard Biesheuvel

From: Atish Patra <[email protected]>

Add a RISC-V architecture specific stub code that actually copies the actual kernel image to a valid address and jump to it after boot services
are terminated. Enable UEFI related kernel configs as well for RISC- V.

Link:
https://lore.kernel.org/r/[email protected]
[ardb: - move hartid fetch into check_platform_features()
- use image_size not reserve_size
- moved asm/efi.h addition into separate patch ]

---
 arch/riscv/Kconfig                        |  20 ++++
 arch/riscv/Makefile                       |   1 +
 arch/riscv/configs/defconfig              |   1 +
 drivers/firmware/efi/Kconfig              |   4 +-
 drivers/firmware/efi/libstub/Makefile     |  10 ++
 drivers/firmware/efi/libstub/riscv-stub.c | 109 ++++++++++++++++++++
 6 files changed, 143 insertions(+), 2 deletions(-)
arch/riscv/Kconfig +1 -0
index f05dd09acd48..54c78cafcd35 100644
@@ -379,10 +379,30 @@ config CMDLINE_FORCE
 
 endchoice
 
+config EFI_STUB

arch/riscv/Kconfig config CMDLINE_FORCE · line 392

Quoted 10 lines
arch/riscv/Kconfig +10 -0
+	bool
+
+config EFI
+	bool "UEFI runtime support"
+	depends on OF
+	select LIBFDT
+	select UCS2_STRING
+	select EFI_PARAMS_FROM_FDT
+	select EFI_STUB
+	select EFI_GENERIC_STUB

As palmer suggested RISCV_ISA_C should be selected here to avoid unintentional errors. Otherwise, every looks good.

Quoted 240 lines
arch/riscv/Kconfig +9 -0
+	default y
+	help
+	  This option provides support for runtime services provided
+	  by UEFI firmware (such as non-volatile variables, realtime
+	  clock, and platform reset). A UEFI stub is also provided to
+	  allow the kernel to be booted as an EFI application. This
+	  is only useful on systems that have UEFI firmware.
+
 endmenu
 
 menu "Power management options"
 
 source "kernel/power/Kconfig"
+source "drivers/firmware/Kconfig"
 
 endmenu
arch/riscv/Makefile +1 -0
index fb6e37db836d..079435804d6d 100644
@@ -80,6 +80,7 @@ head-y := arch/riscv/kernel/head.o
 core-y += arch/riscv/
 
 libs-y += arch/riscv/lib/
+core-$(CONFIG_EFI_STUB) +=

$(objtree)/drivers/firmware/efi/libstub/lib.a

PHONY += vdso_install
vdso_install:

arch/riscv/configs/defconfig +1 -0
index 4da4886246a4..ae69e12d306a 100644
@@ -129,3 +129,4 @@ CONFIG_DEBUG_BLOCK_EXT_DEVT=y
 # CONFIG_RUNTIME_TESTING_MENU is not set
 CONFIG_MEMTEST=y
 # CONFIG_SYSFS_SYSCALL is not set
+CONFIG_EFI=y
drivers/firmware/efi/Kconfig +2 -2
index 4e788dd55b03..8bfc17381b29 100644
@@ -111,7 +111,7 @@ config EFI_GENERIC_STUB
 
 config EFI_ARMSTUB_DTB_LOADER
 	bool "Enable the DTB loader"
-	depends on EFI_GENERIC_STUB
+	depends on EFI_GENERIC_STUB && !RISCV
 	default y
 	help
 	  Select this config option to add support for the dtb= command
@@ -126,7 +126,7 @@ config EFI_ARMSTUB_DTB_LOADER
 
 config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER
 	bool "Enable the command line initrd loader"
-	depends on EFI_GENERIC_STUB
+	depends on EFI_GENERIC_STUB && !RISCV
 	default y
 	help
 	  Select this config option to add support for the initrd=

command

drivers/firmware/efi/libstub/Makefile +1 -0
index 75cb2c3a1519..a4fd1b048e8c 100644
@@ -22,6 +22,8 @@ cflags-$(CONFIG_ARM64)		:= $(subst
 $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
 cflags-$(CONFIG_ARM)		:= $(subst
 $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
 				   -fno-builtin -fpic \
 				   $(call cc-option,-mno-single-pic-
 base)
+cflags-$(CONFIG_RISCV)		:= $(subst

$(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \

drivers/firmware/efi/libstub/Makefile +3 -0
+				   -fpic
 
 cflags-$(CONFIG_EFI_GENERIC_STUB) += -I$(srctree)/scripts/dtc/libfdt
@@ -56,6 +58,7 @@ lib-$(CONFIG_EFI_GENERIC_STUB)	+= efi-stub.o
 fdt.o string.o \
 lib-$(CONFIG_ARM)		+= arm32-stub.o
 lib-$(CONFIG_ARM64)		+= arm64-stub.o
 lib-$(CONFIG_X86)		+= x86-stub.o
+lib-$(CONFIG_RISCV)		+= riscv-stub.o
 CFLAGS_arm32-stub.o		:= -DTEXT_OFFSET=$(TEXT_OFFSET)
 CFLAGS_arm64-stub.o		:= -DTEXT_OFFSET=$(TEXT_OFFSET)
@@ -80,6 +83,13 @@ STUBCOPY_FLAGS-$(CONFIG_ARM64)	+= --prefix-
 alloc-sections=.init \
 				   --prefix-symbols=__efistub_
 STUBCOPY_RELOC-$(CONFIG_ARM64)	:= R_AARCH64_ABS
 
+# For RISC-V, we don't need anything special other than arm64. Keep

all the
+# symbols in .init section and make sure that no absolute symbols references

drivers/firmware/efi/libstub/Makefile +2 -0
+# doesn't exist.
+STUBCOPY_FLAGS-$(CONFIG_RISCV)	+= --prefix-alloc-

sections=.init \

drivers/firmware/efi/libstub/Makefile +3 -0
+				   --prefix-symbols=__efistub_
+STUBCOPY_RELOC-$(CONFIG_RISCV)	:= R_RISCV_HI20
+
 $(obj)/%.stub.o: $(obj)/%.o FORCE
 	$(call if_changed,stubcopy)
drivers/firmware/efi/libstub/riscv-stub.c new file +15 -0
new file mode 100644
index 000000000000..349646928e9b
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+
+#include <linux/efi.h>
+#include <linux/libfdt.h>
+
+#include <asm/efi.h>
+#include <asm/sections.h>
+
+#include "efistub.h"
+
+/*
+ * RISC-V requires the kernel image to placed 2 MB aligned base for

64 bit and
+ * 4MB for 32 bit.
+ */

drivers/firmware/efi/libstub/riscv-stub.c new file +7 -0
+#ifdef CONFIG_64BIT
+#define MIN_KIMG_ALIGN		SZ_2M
+#else
+#define MIN_KIMG_ALIGN		SZ_4M
+#endif
+
+typedef void __noreturn (*jump_kernel_func)(unsigned int, unsigned

long);

drivers/firmware/efi/libstub/riscv-stub.c new file +18 -0
+
+static u32 hartid;
+
+static u32 get_boot_hartid_from_fdt(void)
+{
+	const void *fdt;
+	int chosen_node, len;
+	const fdt32_t *prop;
+
+	fdt = get_efi_config_table(DEVICE_TREE_GUID);
+	if (!fdt)
+		return U32_MAX;
+
+	chosen_node = fdt_path_offset(fdt, "/chosen");
+	if (chosen_node < 0)
+		return U32_MAX;
+
+	prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid",

&len);

drivers/firmware/efi/libstub/riscv-stub.c new file +11 -0
+	if (!prop || len != sizeof(u32))
+		return U32_MAX;
+
+	return fdt32_to_cpu(*prop);
+}
+
+efi_status_t check_platform_features(void)
+{
+	hartid = get_boot_hartid_from_fdt();
+	if (hartid == U32_MAX) {
+		pr_efi_err("/chosen/boot-hartid missing or

invalid!\n");

drivers/firmware/efi/libstub/riscv-stub.c new file +6 -0
+		return EFI_UNSUPPORTED;
+	}
+	return EFI_SUCCESS;
+}
+
+void __noreturn efi_enter_kernel(unsigned long entrypoint, unsigned

long fdt,

drivers/firmware/efi/libstub/riscv-stub.c new file +3 -0
+				 unsigned long fdt_size)
+{
+	unsigned long kernel_entry = entrypoint + (unsigned

long)stext_offset;

drivers/firmware/efi/libstub/riscv-stub.c new file +29 -0
+	jump_kernel_func jump_kernel = (jump_kernel_func)kernel_entry;
+
+	/*
+	 * Jump to real kernel here with following constraints.
+	 * 1. MMU should be disabled.
+	 * 2. a0 should contain hartid
+	 * 3. a1 should DT address
+	 */
+	csr_write(CSR_SATP, 0);
+	jump_kernel(hartid, fdt);
+}
+
+efi_status_t handle_kernel_image(unsigned long *image_addr,
+				 unsigned long *image_size,
+				 unsigned long *reserve_addr,
+				 unsigned long *reserve_size,
+				 unsigned long dram_base,
+				 efi_loaded_image_t *image)
+{
+	unsigned long kernel_size = 0;
+	unsigned long preferred_addr;
+	efi_status_t status;
+
+	kernel_size = _edata - _start;
+	*image_addr = (unsigned long)_start;
+	*image_size = kernel_size + (_end - _edata);
+
+	/*
+	 * RISC-V kernel maps PAGE_OFFSET virtual address to the same

physical

drivers/firmware/efi/libstub/riscv-stub.c new file +1 -0
+	 * address where kernel is booted. That's why kernel should

boot from

drivers/firmware/efi/libstub/riscv-stub.c new file +1 -0
+	 * as low as possible to avoid wastage of memory. Currently,

dram_base

drivers/firmware/efi/libstub/riscv-stub.c new file +1 -0
+	 * is occupied by the firmware. So the preferred address for

kernel to

drivers/firmware/efi/libstub/riscv-stub.c new file +1 -0
+	 * boot is next aligned address. If preferred address is not

available,

drivers/firmware/efi/libstub/riscv-stub.c new file +1 -0
+	 * relocate_kernel will fall back to efi_low_alloc_above to

allocate

drivers/firmware/efi/libstub/riscv-stub.c new file +1 -0
+	 * lowest possible memory region as long as the address and

size meets

drivers/firmware/efi/libstub/riscv-stub.c new file +3 -0
+	 * the alignment constraints.
+	 */
+	preferred_addr = round_up(dram_base, MIN_KIMG_ALIGN) +

MIN_KIMG_ALIGN;

drivers/firmware/efi/libstub/riscv-stub.c new file +1 -0
+	status = efi_relocate_kernel(image_addr, kernel_size,

*image_size,

drivers/firmware/efi/libstub/riscv-stub.c new file +1 -0
+				     preferred_addr, MIN_KIMG_ALIGN,

dram_base);

drivers/firmware/efi/libstub/riscv-stub.c new file +7 -0
+
+	if (status != EFI_SUCCESS) {
+		pr_efi_err("Failed to relocate kernel\n");
+		*image_size = 0;
+	}
+	return status;
+}
Signature · 2 lines
Regards,
Atish
author maintainer
#12 lore raw

Re: [PATCH v5 7/7] RISC-V: Add EFI stub support.

Quoted 34 lines · Atish Patra
Quoted 32 lines · Ard Biesheuvel

From: Atish Patra <[email protected]>

Add a RISC-V architecture specific stub code that actually copies the actual kernel image to a valid address and jump to it after boot services
are terminated. Enable UEFI related kernel configs as well for RISC- V.

Link:
https://lore.kernel.org/r/[email protected]
[ardb: - move hartid fetch into check_platform_features()
- use image_size not reserve_size
- moved asm/efi.h addition into separate patch ]

---
 arch/riscv/Kconfig                        |  20 ++++
 arch/riscv/Makefile                       |   1 +
 arch/riscv/configs/defconfig              |   1 +
 drivers/firmware/efi/Kconfig              |   4 +-
 drivers/firmware/efi/libstub/Makefile     |  10 ++
 drivers/firmware/efi/libstub/riscv-stub.c | 109 ++++++++++++++++++++
 6 files changed, 143 insertions(+), 2 deletions(-)
arch/riscv/Kconfig +0 -0
index f05dd09acd48..54c78cafcd35 100644
@@ -379,10 +379,30 @@ config CMDLINE_FORCE
 
 endchoice
 
Quoted 15 lines

arch/riscv/Kconfig config CMDLINE_FORCE · line 392

Quoted 11 lines
arch/riscv/Kconfig +11 -0
+config EFI_STUB
+     bool
+
+config EFI
+     bool "UEFI runtime support"
+     depends on OF
+     select LIBFDT
+     select UCS2_STRING
+     select EFI_PARAMS_FROM_FDT
+     select EFI_STUB
+     select EFI_GENERIC_STUB

As palmer suggested RISCV_ISA_C should be selected here to avoid unintentional errors. Otherwise, every looks good.

Ah, I must have misunderstood. I thought using c.li instead of li was sufficient here.

In any case, once Palmer confirms that he is ok with the approach I suggested, he can fix that up when applying the patches.

Thanks,
Ard.

Quoted 244 lines
Quoted 233 lines
arch/riscv/Kconfig +9 -0
+     default y
+     help
+       This option provides support for runtime services provided
+       by UEFI firmware (such as non-volatile variables, realtime
+       clock, and platform reset). A UEFI stub is also provided to
+       allow the kernel to be booted as an EFI application. This
+       is only useful on systems that have UEFI firmware.
+
 endmenu
 
 menu "Power management options"
 
 source "kernel/power/Kconfig"
+source "drivers/firmware/Kconfig"
 
 endmenu
arch/riscv/Makefile +1 -0
index fb6e37db836d..079435804d6d 100644
@@ -80,6 +80,7 @@ head-y := arch/riscv/kernel/head.o
 core-y += arch/riscv/
 
 libs-y += arch/riscv/lib/
+core-$(CONFIG_EFI_STUB) +=

$(objtree)/drivers/firmware/efi/libstub/lib.a

PHONY += vdso_install
vdso_install:

arch/riscv/configs/defconfig +1 -0
index 4da4886246a4..ae69e12d306a 100644
@@ -129,3 +129,4 @@ CONFIG_DEBUG_BLOCK_EXT_DEVT=y
 # CONFIG_RUNTIME_TESTING_MENU is not set
 CONFIG_MEMTEST=y
 # CONFIG_SYSFS_SYSCALL is not set
+CONFIG_EFI=y
drivers/firmware/efi/Kconfig +2 -2
index 4e788dd55b03..8bfc17381b29 100644
@@ -111,7 +111,7 @@ config EFI_GENERIC_STUB
 
 config EFI_ARMSTUB_DTB_LOADER
      bool "Enable the DTB loader"
-     depends on EFI_GENERIC_STUB
+     depends on EFI_GENERIC_STUB && !RISCV
      default y
      help
        Select this config option to add support for the dtb= command
@@ -126,7 +126,7 @@ config EFI_ARMSTUB_DTB_LOADER
 
 config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER
      bool "Enable the command line initrd loader"
-     depends on EFI_GENERIC_STUB
+     depends on EFI_GENERIC_STUB && !RISCV
      default y
      help
        Select this config option to add support for the initrd=

command

drivers/firmware/efi/libstub/Makefile +1 -0
index 75cb2c3a1519..a4fd1b048e8c 100644
@@ -22,6 +22,8 @@ cflags-$(CONFIG_ARM64)              := $(subst
 $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
 cflags-$(CONFIG_ARM)         := $(subst
 $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
                                 -fno-builtin -fpic \
                                 $(call cc-option,-mno-single-pic-
 base)
+cflags-$(CONFIG_RISCV)               := $(subst

$(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \

drivers/firmware/efi/libstub/Makefile +3 -0
+                                -fpic
 
 cflags-$(CONFIG_EFI_GENERIC_STUB) += -I$(srctree)/scripts/dtc/libfdt
@@ -56,6 +58,7 @@ lib-$(CONFIG_EFI_GENERIC_STUB)      += efi-stub.o
 fdt.o string.o \
 lib-$(CONFIG_ARM)            += arm32-stub.o
 lib-$(CONFIG_ARM64)          += arm64-stub.o
 lib-$(CONFIG_X86)            += x86-stub.o
+lib-$(CONFIG_RISCV)          += riscv-stub.o
 CFLAGS_arm32-stub.o          := -DTEXT_OFFSET=$(TEXT_OFFSET)
 CFLAGS_arm64-stub.o          := -DTEXT_OFFSET=$(TEXT_OFFSET)
@@ -80,6 +83,13 @@ STUBCOPY_FLAGS-$(CONFIG_ARM64)     += --prefix-
 alloc-sections=.init \
                                 --prefix-symbols=__efistub_
 STUBCOPY_RELOC-$(CONFIG_ARM64)       := R_AARCH64_ABS
 
+# For RISC-V, we don't need anything special other than arm64. Keep

all the
+# symbols in .init section and make sure that no absolute symbols references

drivers/firmware/efi/libstub/Makefile +2 -0
+# doesn't exist.
+STUBCOPY_FLAGS-$(CONFIG_RISCV)       += --prefix-alloc-

sections=.init \

drivers/firmware/efi/libstub/Makefile +3 -0
+                                --prefix-symbols=__efistub_
+STUBCOPY_RELOC-$(CONFIG_RISCV)       := R_RISCV_HI20
+
 $(obj)/%.stub.o: $(obj)/%.o FORCE
      $(call if_changed,stubcopy)
drivers/firmware/efi/libstub/riscv-stub.c new file +15 -0
new file mode 100644
index 000000000000..349646928e9b
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+
+#include <linux/efi.h>
+#include <linux/libfdt.h>
+
+#include <asm/efi.h>
+#include <asm/sections.h>
+
+#include "efistub.h"
+
+/*
+ * RISC-V requires the kernel image to placed 2 MB aligned base for

64 bit and
+ * 4MB for 32 bit.
+ */

drivers/firmware/efi/libstub/riscv-stub.c new file +7 -0
+#ifdef CONFIG_64BIT
+#define MIN_KIMG_ALIGN               SZ_2M
+#else
+#define MIN_KIMG_ALIGN               SZ_4M
+#endif
+
+typedef void __noreturn (*jump_kernel_func)(unsigned int, unsigned

long);

drivers/firmware/efi/libstub/riscv-stub.c new file +18 -0
+
+static u32 hartid;
+
+static u32 get_boot_hartid_from_fdt(void)
+{
+     const void *fdt;
+     int chosen_node, len;
+     const fdt32_t *prop;
+
+     fdt = get_efi_config_table(DEVICE_TREE_GUID);
+     if (!fdt)
+             return U32_MAX;
+
+     chosen_node = fdt_path_offset(fdt, "/chosen");
+     if (chosen_node < 0)
+             return U32_MAX;
+
+     prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid",

&len);

drivers/firmware/efi/libstub/riscv-stub.c new file +11 -0
+     if (!prop || len != sizeof(u32))
+             return U32_MAX;
+
+     return fdt32_to_cpu(*prop);
+}
+
+efi_status_t check_platform_features(void)
+{
+     hartid = get_boot_hartid_from_fdt();
+     if (hartid == U32_MAX) {
+             pr_efi_err("/chosen/boot-hartid missing or

invalid!\n");

drivers/firmware/efi/libstub/riscv-stub.c new file +6 -0
+             return EFI_UNSUPPORTED;
+     }
+     return EFI_SUCCESS;
+}
+
+void __noreturn efi_enter_kernel(unsigned long entrypoint, unsigned

long fdt,

drivers/firmware/efi/libstub/riscv-stub.c new file +3 -0
+                              unsigned long fdt_size)
+{
+     unsigned long kernel_entry = entrypoint + (unsigned

long)stext_offset;

drivers/firmware/efi/libstub/riscv-stub.c new file +29 -0
+     jump_kernel_func jump_kernel = (jump_kernel_func)kernel_entry;
+
+     /*
+      * Jump to real kernel here with following constraints.
+      * 1. MMU should be disabled.
+      * 2. a0 should contain hartid
+      * 3. a1 should DT address
+      */
+     csr_write(CSR_SATP, 0);
+     jump_kernel(hartid, fdt);
+}
+
+efi_status_t handle_kernel_image(unsigned long *image_addr,
+                              unsigned long *image_size,
+                              unsigned long *reserve_addr,
+                              unsigned long *reserve_size,
+                              unsigned long dram_base,
+                              efi_loaded_image_t *image)
+{
+     unsigned long kernel_size = 0;
+     unsigned long preferred_addr;
+     efi_status_t status;
+
+     kernel_size = _edata - _start;
+     *image_addr = (unsigned long)_start;
+     *image_size = kernel_size + (_end - _edata);
+
+     /*
+      * RISC-V kernel maps PAGE_OFFSET virtual address to the same

physical
+ * address where kernel is booted. That's why kernel should
boot from
+ * as low as possible to avoid wastage of memory. Currently,
dram_base
+ * is occupied by the firmware. So the preferred address for
kernel to
+ * boot is next aligned address. If preferred address is not
available,
+ * relocate_kernel will fall back to efi_low_alloc_above to
allocate
+ * lowest possible memory region as long as the address and
size meets

drivers/firmware/efi/libstub/riscv-stub.c new file +3 -0
+      * the alignment constraints.
+      */
+     preferred_addr = round_up(dram_base, MIN_KIMG_ALIGN) +

MIN_KIMG_ALIGN;
+ status = efi_relocate_kernel(image_addr, kernel_size,
*image_size,
+ preferred_addr, MIN_KIMG_ALIGN,
dram_base);

drivers/firmware/efi/libstub/riscv-stub.c line 109

Quoted 7 lines
drivers/firmware/efi/libstub/riscv-stub.c new file +7 -0
+
+     if (status != EFI_SUCCESS) {
+             pr_efi_err("Failed to relocate kernel\n");
+             *image_size = 0;
+     }
+     return status;
+}

--
Regards,
Atish

author maintainer
#13 lore raw

Re: [PATCH v5 7/7] RISC-V: Add EFI stub support.

Quoted 52 lines · Ard Biesheuvel
Quoted 34 lines · Atish Patra
Quoted 32 lines · Ard Biesheuvel

From: Atish Patra <[email protected]>

Add a RISC-V architecture specific stub code that actually copies the actual kernel image to a valid address and jump to it after boot services
are terminated. Enable UEFI related kernel configs as well for RISC- V.

Link:
https://lore.kernel.org/r/[email protected]
[ardb: - move hartid fetch into check_platform_features()
- use image_size not reserve_size
- moved asm/efi.h addition into separate patch ]

---
 arch/riscv/Kconfig                        |  20 ++++
 arch/riscv/Makefile                       |   1 +
 arch/riscv/configs/defconfig              |   1 +
 drivers/firmware/efi/Kconfig              |   4 +-
 drivers/firmware/efi/libstub/Makefile     |  10 ++
 drivers/firmware/efi/libstub/riscv-stub.c | 109 ++++++++++++++++++++
 6 files changed, 143 insertions(+), 2 deletions(-)
arch/riscv/Kconfig +0 -0
index f05dd09acd48..54c78cafcd35 100644
@@ -379,10 +379,30 @@ config CMDLINE_FORCE
 
 endchoice
 
Quoted 15 lines

arch/riscv/Kconfig config CMDLINE_FORCE · line 392

Quoted 11 lines
arch/riscv/Kconfig +11 -0
+config EFI_STUB
+     bool
+
+config EFI
+     bool "UEFI runtime support"
+     depends on OF
+     select LIBFDT
+     select UCS2_STRING
+     select EFI_PARAMS_FROM_FDT
+     select EFI_STUB
+     select EFI_GENERIC_STUB

As palmer suggested RISCV_ISA_C should be selected here to avoid unintentional errors. Otherwise, every looks good.

Quoted 7 lines

Ah, I must have misunderstood. I thought using c.li instead of li was sufficient here.

In any case, once Palmer confirms that he is ok with the approach I suggested, he can fix that up when applying the patches.

Actually, I can do slightly better, and put the asm/efi.h patch back into this one.

I'll do a respin once we've agreed that this is the approach we are taking.

author maintainer
#14 lore raw
In reply to Ard Biesheuvel
Quoted 8 lines · Ard Biesheuvel

This is a rework of Atish's series [0] to add EFI stub loader support to the RISC-V port. The purpose is to split the code in a way that makes it amenable to being merged via different trees during the same cycle. While at it, I added a patch to disable initrd= loading for new ports, given that it is deprecated and replaced with a method based on a special UEFI device path.

Quoted 7 lines

My changes are logged in the individual patches.

I propose to take the first four patches via the EFI tree, and expose them via a stable tag so that the RISC-V maintainers can merge it before applying the remaining patches. That will ensure that both trees remain in a buildable state, with working EFI stub support on the riscv branch.

[0] https://lore.kernel.org/linux-efi/[email protected]/

#15 lore raw
In reply to Ard Biesheuvel
Quoted 10 lines · Ard Biesheuvel

This is a rework of Atish's series [0] to add EFI stub loader support to the RISC-V port. The purpose is to split the code in a way that makes
it amenable to being merged via different trees during the same cycle.
While at it, I added a patch to disable initrd= loading for new ports,
given that it is deprecated and replaced with a method based on a special UEFI device path.

Thanks for refactoring the series. I did not see this one and replied to the original comments :(. Everything looks good to me except the selecting the RISCV_ISA_C bit.

Quoted 10 lines

My changes are logged in the individual patches.

I propose to take the first four patches via the EFI tree, and expose them via a stable tag so that the RISC-V maintainers can merge it before
applying the remaining patches. That will ensure that both trees remain
in a buildable state, with working EFI stub support on the riscv branch.

Great.

Quoted 48 lines
Cc Atish Patra <[email protected]>
Cc Palmer Dabbelt <[email protected]>
Cc Paul Walmsley <[email protected]>
Cc Albert Ou <[email protected]>

Ard Biesheuvel (1):
efi/libstub: Make initrd file loader configurable

Atish Patra (6):
efi/libstub: Move arm-stub to a common file efi/libstub/riscv: add arch specific efi.h header file
include: pe.h: Add RISC-V related PE definition
RISC-V: Define fixmap bindings for generic early ioremap support
RISC-V: Add PE/COFF header for EFI stub
RISC-V: Add EFI stub support.

 arch/arm/Kconfig                              |   2 +-
 arch/arm64/Kconfig                            |   2 +-
 arch/riscv/Kconfig                            |  21 ++++
 arch/riscv/Makefile                           |   1 +
 arch/riscv/configs/defconfig                  |   1 +
 arch/riscv/include/asm/Kbuild                 |   1 +
 arch/riscv/include/asm/efi.h                  |  41 +++++++
 arch/riscv/include/asm/fixmap.h               |  18 +++
 arch/riscv/include/asm/io.h                   |   1 +
 arch/riscv/include/asm/sections.h             |  13 +++
 arch/riscv/kernel/Makefile                    |   4 +
 arch/riscv/kernel/efi-header.S                | 100 ++++++++++++++++
 arch/riscv/kernel/head.S                      |  16 +++
 arch/riscv/kernel/image-vars.h                |  53 +++++++++
 arch/riscv/kernel/vmlinux.lds.S               |  22 +++-
 drivers/firmware/efi/Kconfig                  |  15 ++-
 drivers/firmware/efi/libstub/Makefile         |  22 +++-
 .../efi/libstub/{arm-stub.c => efi-stub.c}    |   0
 drivers/firmware/efi/libstub/file.c           |   3 +
 drivers/firmware/efi/libstub/riscv-stub.c     | 109
++++++++++++++++++
 include/linux/pe.h                            |   3 +
 21 files changed, 436 insertions(+), 12 deletions(-)
 create mode 100644 arch/riscv/include/asm/efi.h
 create mode 100644 arch/riscv/include/asm/sections.h
 create mode 100644 arch/riscv/kernel/efi-header.S
 create mode 100644 arch/riscv/kernel/image-vars.h
 rename drivers/firmware/efi/libstub/{arm-stub.c => efi-stub.c}
(100%)
 create mode 100644 drivers/firmware/efi/libstub/riscv-stub.c
Signature · 2 lines
Regards,
Atish
maintainer
#16 lore raw
In reply to Ard Biesheuvel
Quoted 7 lines · On Wed, 22 Apr 2020 10:24:07 PDT (-0700), [email protected] wrote:

This is a rework of Atish's series [0] to add EFI stub loader support to the RISC-V port. The purpose is to split the code in a way that makes it amenable to being merged via different trees during the same cycle. While at it, I added a patch to disable initrd= loading for new ports, given that it is deprecated and replaced with a method based on a special UEFI device path.

Quoted 6 lines

My changes are logged in the individual patches.

I propose to take the first four patches via the EFI tree, and expose them via a stable tag so that the RISC-V maintainers can merge it before applying the remaining patches. That will ensure that both trees remain in a buildable state, with working EFI stub support on the riscv branch.

Works for me. Thanks!

Quoted 46 lines
Cc Atish Patra <[email protected]>
Cc Palmer Dabbelt <[email protected]>
Cc Paul Walmsley <[email protected]>
Cc Albert Ou <[email protected]>

Ard Biesheuvel (1):
efi/libstub: Make initrd file loader configurable

Atish Patra (6):
efi/libstub: Move arm-stub to a common file efi/libstub/riscv: add arch specific efi.h header file
include: pe.h: Add RISC-V related PE definition
RISC-V: Define fixmap bindings for generic early ioremap support
RISC-V: Add PE/COFF header for EFI stub
RISC-V: Add EFI stub support.

 arch/arm/Kconfig                              |   2 +-
 arch/arm64/Kconfig                            |   2 +-
 arch/riscv/Kconfig                            |  21 ++++
 arch/riscv/Makefile                           |   1 +
 arch/riscv/configs/defconfig                  |   1 +
 arch/riscv/include/asm/Kbuild                 |   1 +
 arch/riscv/include/asm/efi.h                  |  41 +++++++
 arch/riscv/include/asm/fixmap.h               |  18 +++
 arch/riscv/include/asm/io.h                   |   1 +
 arch/riscv/include/asm/sections.h             |  13 +++
 arch/riscv/kernel/Makefile                    |   4 +
 arch/riscv/kernel/efi-header.S                | 100 ++++++++++++++++
 arch/riscv/kernel/head.S                      |  16 +++
 arch/riscv/kernel/image-vars.h                |  53 +++++++++
 arch/riscv/kernel/vmlinux.lds.S               |  22 +++-
 drivers/firmware/efi/Kconfig                  |  15 ++-
 drivers/firmware/efi/libstub/Makefile         |  22 +++-
 .../efi/libstub/{arm-stub.c => efi-stub.c}    |   0
 drivers/firmware/efi/libstub/file.c           |   3 +
 drivers/firmware/efi/libstub/riscv-stub.c     | 109 ++++++++++++++++++
 include/linux/pe.h                            |   3 +
 21 files changed, 436 insertions(+), 12 deletions(-)
 create mode 100644 arch/riscv/include/asm/efi.h
 create mode 100644 arch/riscv/include/asm/sections.h
 create mode 100644 arch/riscv/kernel/efi-header.S
 create mode 100644 arch/riscv/kernel/image-vars.h
 rename drivers/firmware/efi/libstub/{arm-stub.c => efi-stub.c} (100%)
 create mode 100644 drivers/firmware/efi/libstub/riscv-stub.c
author maintainer
#17 lore raw
Quoted 9 lines · Palmer Dabbelt
Quoted 7 lines · On Wed, 22 Apr 2020 10:24:07 PDT (-0700), [email protected] wrote:

This is a rework of Atish's series [0] to add EFI stub loader support to the RISC-V port. The purpose is to split the code in a way that makes it amenable to being merged via different trees during the same cycle. While at it, I added a patch to disable initrd= loading for new ports, given that it is deprecated and replaced with a method based on a special UEFI device path.

Quoted 9 lines
Quoted 6 lines

My changes are logged in the individual patches.

I propose to take the first four patches via the EFI tree, and expose them via a stable tag so that the RISC-V maintainers can merge it before applying the remaining patches. That will ensure that both trees remain in a buildable state, with working EFI stub support on the riscv branch.

Works for me. Thanks!

OK. I'll resend the final versions of the remaining patches (with the ISA_C tweak added) to be taken into the RISC-V tree once the first few patches have landed in tip/efi/core