summaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_runtime.c
diff options
context:
space:
mode:
authorRick Chen <rick@andestech.com>2018-05-28 19:06:37 +0800
committerAndes <uboot@andestech.com>2018-05-29 14:43:12 +0800
commit6836adbe753b241499430812ec5ef41ba61bdd83 (patch)
treebd91c1e2b9d9b4624f0f232d4f659c6da97bfcec /lib/efi_loader/efi_runtime.c
parent0979f7ce1eea73c80e6f858a803106660507d1e3 (diff)
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>
Diffstat (limited to 'lib/efi_loader/efi_runtime.c')
-rw-r--r--lib/efi_loader/efi_runtime.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index 042f9ae56f..241090f6b4 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -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) ||