aboutsummaryrefslogtreecommitdiff
path: root/firmware/fw_base.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/fw_base.S')
-rw-r--r--firmware/fw_base.S62
1 files changed, 61 insertions, 1 deletions
diff --git a/firmware/fw_base.S b/firmware/fw_base.S
index 6cc5f88..2ce3851 100644
--- a/firmware/fw_base.S
+++ b/firmware/fw_base.S
@@ -9,6 +9,7 @@
#include <sbi/riscv_asm.h>
#include <sbi/riscv_encoding.h>
+#include <sbi/riscv_elf.h>
#include <sbi/sbi_platform.h>
#include <sbi/sbi_scratch.h>
#include <sbi/sbi_trap.h>
@@ -67,6 +68,58 @@ _try_lottery:
lla t1, _start
REG_S t1, 0(t0)
+#ifdef FW_PIC
+ /* relocate the global table content */
+ lla t0, _link_start
+ REG_L t0, 0(t0)
+ /* t1 shall has the address of _start */
+ sub t2, t1, t0
+ lla t3, _runtime_offset
+ REG_S t2, (t3)
+ lla t0, __rel_dyn_start
+ lla t1, __rel_dyn_end
+ beq t0, t1, _relocate_done
+ j 5f
+2:
+ REG_L t5, -(REGBYTES*2)(t0) /* t5 <-- relocation info:type */
+ li t3, R_RISCV_RELATIVE /* reloc type R_RISCV_RELATIVE */
+ bne t5, t3, 3f
+ REG_L t3, -(REGBYTES*3)(t0)
+ REG_L t5, -(REGBYTES)(t0) /* t5 <-- addend */
+ add t5, t5, t2
+ add t3, t3, t2
+ REG_S t5, 0(t3) /* store runtime address to the GOT entry */
+ j 5f
+
+3:
+ lla t4, __dyn_sym_start
+
+4:
+ REG_L t5, -(REGBYTES*2)(t0) /* t5 <-- relocation info:type */
+ srli t6, t5, SYM_INDEX /* t6 <--- sym table index */
+ andi t5, t5, 0xFF /* t5 <--- relocation type */
+ li t3, RELOC_TYPE
+ bne t5, t3, 5f
+
+ /* address R_RISCV_64 or R_RISCV_32 cases*/
+ REG_L t3, -(REGBYTES*3)(t0)
+ li t5, SYM_SIZE
+ mul t6, t6, t5
+ add s5, t4, t6
+ REG_L t6, -(REGBYTES)(t0) /* t0 <-- addend */
+ REG_L t5, REGBYTES(s5)
+ add t5, t5, t6
+ add t5, t5, t2 /* t5 <-- location to fix up in RAM */
+ add t3, t3, t2 /* t3 <-- location to fix up in RAM */
+ REG_S t5, 0(t3) /* store runtime address to the variable */
+
+5:
+ addi t0, t0, (REGBYTES*3)
+ ble t0, t1, 2b
+ j _relocate_done
+_wait_relocate_copy_done:
+ j _wait_for_boot_hart
+#else
/* Relocate if load address != link address */
_relocate:
lla t0, _link_start
@@ -137,6 +190,7 @@ _wait_relocate_copy_done:
nop
bgt t4, t5, 1b
jr t3
+#endif
_relocate_done:
/*
@@ -144,12 +198,14 @@ _relocate_done:
* Use _boot_status copy relative to the load address
*/
lla t0, _boot_status
+#ifndef FW_PIC
lla t1, _link_start
REG_L t1, 0(t1)
lla t2, _load_start
REG_L t2, 0(t2)
sub t0, t0, t1
add t0, t0, t2
+#endif
li t1, BOOT_STATUS_RELOCATE_DONE
REG_S t1, 0(t0)
fence rw, rw
@@ -446,6 +502,10 @@ _skip_trap_exit_rv32_hyp:
j _start_hang
.align 3
+#ifdef FW_PIC
+_runtime_offset:
+ RISCV_PTR 0
+#endif
_relocate_lottery:
RISCV_PTR 0
_boot_status:
@@ -453,7 +513,7 @@ _boot_status:
_load_start:
RISCV_PTR _fw_start
_link_start:
- RISCV_PTR _fw_start
+ RISCV_PTR FW_TEXT_START
_link_end:
RISCV_PTR _fw_reloc_end