[8/8] efi_loader: Enable RISC-V support

Message ID 20180418134030.55127-9-agraf@suse.de
State New
Headers show
Series
  • riscv: Enable efi_loader support
Related show

Commit Message

Alexander Graf April 18, 2018, 1:40 p.m.
We have almost all pieces needed to support RISC-V UEFI binaries in place
already. The only missing piece are ELF relocations for runtime code and
data.

This patch adds respective support in the linker script and the runtime
relocation code. It also allows users to enable the EFI_LOADER configuration
switch on RISC-V platforms.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 arch/riscv/cpu/nx25/u-boot.lds | 16 ++++++++++++++++
 lib/efi_loader/Kconfig         |  2 +-
 lib/efi_loader/efi_runtime.c   | 41 ++++++++++++++++++++++++++++++++++++-----
 3 files changed, 53 insertions(+), 6 deletions(-)

Comments

Heinrich Schuchardt April 19, 2018, 5:14 a.m. | #1
On 04/18/2018 03:40 PM, Alexander Graf wrote:
> We have almost all pieces needed to support RISC-V UEFI binaries in place
> already. The only missing piece are ELF relocations for runtime code and
> data.
> 
> This patch adds respective support in the linker script and the runtime
> relocation code. It also allows users to enable the EFI_LOADER configuration
> switch on RISC-V platforms.
> 
> Signed-off-by: Alexander Graf <agraf@suse.de>

The patch is not applicable after my pending patch for ARMV7_NONSEC.
Could you, please, have a look at

"efi_loader: no support for ARMV7_NONSEC=y"
https://patchwork.ozlabs.org/patch/896962/

and decide if you will accept it. This is only a question of sequence in
efi_next.

Best regards

Heinrich

> ---
>  arch/riscv/cpu/nx25/u-boot.lds | 16 ++++++++++++++++
>  lib/efi_loader/Kconfig         |  2 +-
>  lib/efi_loader/efi_runtime.c   | 41 ++++++++++++++++++++++++++++++++++++-----
>  3 files changed, 53 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/riscv/cpu/nx25/u-boot.lds b/arch/riscv/cpu/nx25/u-boot.lds
> index 936fd779aa..508fa7e58d 100644
> --- a/arch/riscv/cpu/nx25/u-boot.lds
> +++ b/arch/riscv/cpu/nx25/u-boot.lds
> @@ -38,6 +38,22 @@ SECTIONS
>  		KEEP(*(SORT(.u_boot_list*)));
>  	}
>  
> +	. = ALIGN(4);
> +
> +	.efi_runtime : {
> +                __efi_runtime_start = .;
> +		*(efi_runtime_text)
> +		*(efi_runtime_data)
> +                __efi_runtime_stop = .;
> +	}
> +
> +	.efi_runtime_rel : {
> +                __efi_runtime_rel_start = .;
> +		*(.relaefi_runtime_text)
> +		*(.relaefi_runtime_data)
> +                __efi_runtime_rel_stop = .;
> +	}
> +
>      . = ALIGN(4);
>  
>      /DISCARD/ : { *(.rela.plt*) }
> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> index 83d75c4fdc..9de58bb012 100644
> --- a/lib/efi_loader/Kconfig
> +++ b/lib/efi_loader/Kconfig
> @@ -1,6 +1,6 @@
>  config EFI_LOADER
>  	bool "Support running EFI Applications in U-Boot"
> -	depends on (ARM || X86) && OF_LIBFDT
> +	depends on (ARM || X86 || RISCV) && OF_LIBFDT
>  	# We need EFI_STUB_64BIT to be set on x86_64 with EFI_STUB
>  	depends on !EFI_STUB || !X86_64 || EFI_STUB_64BIT
>  	# We need EFI_STUB_32BIT to be set on x86_32 with EFI_STUB
> diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
> index 573a5d6ac1..33bbc8d6cc 100644
> --- a/lib/efi_loader/efi_runtime.c
> +++ b/lib/efi_loader/efi_runtime.c
> @@ -41,6 +41,25 @@ static efi_status_t __efi_runtime EFIAPI efi_invalid_parameter(void);
>  #include <asm/elf.h>
>  #define R_RELATIVE	R_386_RELATIVE
>  #define R_MASK		0xffULL
> +#elif defined(CONFIG_RISCV)
> +#include <elf.h>
> +#define R_RELATIVE	R_RISCV_RELATIVE
> +#define R_MASK		0xffULL
> +#define IS_RELA		1
> +
> +struct dyn_sym {
> +	ulong foo1;
> +	ulong addr;
> +	u32 foo2;
> +	u32 foo3;
> +};
> +#ifdef CONFIG_CPU_RISCV_32
> +#define R_ABSOLUTE	R_RISCV_32
> +#define SYM_INDEX	8
> +#else
> +#define R_ABSOLUTE	R_RISCV_64
> +#define SYM_INDEX	32
> +#endif
>  #else
>  #error Need to add relocation awareness
>  #endif
> @@ -247,15 +266,27 @@ void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map)
>  
>  		p = (void*)((ulong)rel->offset - base) + gd->relocaddr;
>  
> -		if ((rel->info & R_MASK) != R_RELATIVE) {
> -			continue;
> -		}
> +		debug("%s: rel->info=%#lx *p=%#lx rel->offset=%p\n", __func__, rel->info, *p, rel->offset);
>  
> +		switch (rel->info & R_MASK) {
> +		case R_RELATIVE:
>  #ifdef IS_RELA
> -		newaddr = rel->addend + offset - CONFIG_SYS_TEXT_BASE;
> +			newaddr = rel->addend + offset - CONFIG_SYS_TEXT_BASE;
>  #else
> -		newaddr = *p - lastoff + offset;
> +			newaddr = *p - lastoff + offset;
>  #endif
> +			break;
> +#ifdef R_ABSOLUTE
> +		case R_ABSOLUTE: {
> +			ulong symidx = rel->info >> SYM_INDEX;
> +			extern struct dyn_sym __dyn_sym_start[];
> +			newaddr = __dyn_sym_start[symidx].addr + offset;
> +			break;
> +		}
> +#endif
> +		default:
> +			continue;
> +		}
>  
>  		/* Check if the relocation is inside bounds */
>  		if (map && ((newaddr < map->virtual_start) ||
>

Patch

diff --git a/arch/riscv/cpu/nx25/u-boot.lds b/arch/riscv/cpu/nx25/u-boot.lds
index 936fd779aa..508fa7e58d 100644
--- a/arch/riscv/cpu/nx25/u-boot.lds
+++ b/arch/riscv/cpu/nx25/u-boot.lds
@@ -38,6 +38,22 @@  SECTIONS
 		KEEP(*(SORT(.u_boot_list*)));
 	}
 
+	. = ALIGN(4);
+
+	.efi_runtime : {
+                __efi_runtime_start = .;
+		*(efi_runtime_text)
+		*(efi_runtime_data)
+                __efi_runtime_stop = .;
+	}
+
+	.efi_runtime_rel : {
+                __efi_runtime_rel_start = .;
+		*(.relaefi_runtime_text)
+		*(.relaefi_runtime_data)
+                __efi_runtime_rel_stop = .;
+	}
+
     . = ALIGN(4);
 
     /DISCARD/ : { *(.rela.plt*) }
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 83d75c4fdc..9de58bb012 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -1,6 +1,6 @@ 
 config EFI_LOADER
 	bool "Support running EFI Applications in U-Boot"
-	depends on (ARM || X86) && OF_LIBFDT
+	depends on (ARM || X86 || RISCV) && OF_LIBFDT
 	# We need EFI_STUB_64BIT to be set on x86_64 with EFI_STUB
 	depends on !EFI_STUB || !X86_64 || EFI_STUB_64BIT
 	# We need EFI_STUB_32BIT to be set on x86_32 with EFI_STUB
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index 573a5d6ac1..33bbc8d6cc 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -41,6 +41,25 @@  static efi_status_t __efi_runtime EFIAPI efi_invalid_parameter(void);
 #include <asm/elf.h>
 #define R_RELATIVE	R_386_RELATIVE
 #define R_MASK		0xffULL
+#elif defined(CONFIG_RISCV)
+#include <elf.h>
+#define R_RELATIVE	R_RISCV_RELATIVE
+#define R_MASK		0xffULL
+#define IS_RELA		1
+
+struct dyn_sym {
+	ulong foo1;
+	ulong addr;
+	u32 foo2;
+	u32 foo3;
+};
+#ifdef CONFIG_CPU_RISCV_32
+#define R_ABSOLUTE	R_RISCV_32
+#define SYM_INDEX	8
+#else
+#define R_ABSOLUTE	R_RISCV_64
+#define SYM_INDEX	32
+#endif
 #else
 #error Need to add relocation awareness
 #endif
@@ -247,15 +266,27 @@  void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map)
 
 		p = (void*)((ulong)rel->offset - base) + gd->relocaddr;
 
-		if ((rel->info & R_MASK) != R_RELATIVE) {
-			continue;
-		}
+		debug("%s: rel->info=%#lx *p=%#lx rel->offset=%p\n", __func__, rel->info, *p, rel->offset);
 
+		switch (rel->info & R_MASK) {
+		case R_RELATIVE:
 #ifdef IS_RELA
-		newaddr = rel->addend + offset - CONFIG_SYS_TEXT_BASE;
+			newaddr = rel->addend + offset - CONFIG_SYS_TEXT_BASE;
 #else
-		newaddr = *p - lastoff + offset;
+			newaddr = *p - lastoff + offset;
 #endif
+			break;
+#ifdef R_ABSOLUTE
+		case R_ABSOLUTE: {
+			ulong symidx = rel->info >> SYM_INDEX;
+			extern struct dyn_sym __dyn_sym_start[];
+			newaddr = __dyn_sym_start[symidx].addr + offset;
+			break;
+		}
+#endif
+		default:
+			continue;
+		}
 
 		/* Check if the relocation is inside bounds */
 		if (map && ((newaddr < map->virtual_start) ||