efi_loader: Enable RISC-V support

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>
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index 042f9ae..241090f 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -40,6 +40,25 @@
 #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 @@
 
 		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) ||