efi_loader: Enable RISC-V support
authorRick Chen <rick@andestech.com>
Mon, 28 May 2018 11:06:37 +0000 (19:06 +0800)
committerAndes <uboot@andestech.com>
Tue, 29 May 2018 06:43:12 +0000 (14:43 +0800)
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
cmd/Kconfig
lib/efi_loader/Kconfig
lib/efi_loader/efi_runtime.c

index 86ebc9f4bb4c059d8b1c4b3e7021cd41310d9e2f..c53829a07ce93f97a5ae954e08907cb9bdb6c1ee 100644 (file)
@@ -37,6 +37,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*) }
index d532c9fc41c05f8b43ee2553c2d441d43ebed211..1a1ca60237dfe672f5a89ce00cf601a096a1a647 100644 (file)
@@ -228,7 +228,7 @@ config CMD_BOOTEFI
 
 config CMD_BOOTEFI_HELLO_COMPILE
        bool "Compile a standard EFI hello world binary for testing"
-       depends on CMD_BOOTEFI && (ARM || X86)
+       depends on CMD_BOOTEFI && (ARM || X86 || RISCV)
        default y
        help
          This compiles a standard EFI hello world application with U-Boot so
index d38780b604e504d0af2fa0ed784db96c2cdad447..2909e7696080d8ffb711e0f96ba28e5ead6848c1 100644 (file)
@@ -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 do not support bootefi booting ARMv7 in non-secure mode
        depends on !ARMV7_NONSEC
        # We need EFI_STUB_64BIT to be set on x86_64 with EFI_STUB
index 042f9ae56f421b04c1ce186b06380c0b184357cd..241090f6b4842639b2911032b1e0a731df27de97 100644 (file)
@@ -40,6 +40,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
@@ -246,15 +265,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;
 #else
                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) ||