RISC-V: fix global pointer assignment at boot

As part of the RISC-V ABI, the gp register is expected to initialized
with the address of __global_pointer$ as early as possible. This allows
loads and stores from .sdata to be relaxed based on the value of gp. In
locore.S we do this initialization twice, once each for va and mpva.
However, in both cases the initialization is preceded by an la
instruction, which in theory could be relaxed by the linker.

Move the initialization of gp to be slightly earlier (before la
cpu_exception_handler), and add an additional gp initialization at the
very beginning of _start, before virtual memory is set up.

Reported by:	jrtc27
Reviewed by:	jrtc27
Differential Revision:	https://reviews.freebsd.org/D23139
This commit is contained in:
mhorne 2020-01-17 17:03:25 +00:00
parent ca0c40ca14
commit 5b79f9b0e2

View File

@ -53,6 +53,12 @@
.text
.globl _start
_start:
/* Set the global pointer */
.option push
.option norelax
lla gp, __global_pointer$
.option pop
/* Get the physical address kernel loaded to */
lla t0, virt_map
ld t1, 0(t0)
@ -168,6 +174,11 @@ _start:
.align 2
va:
/* Set the global pointer again, this time with the virtual address. */
.option push
.option norelax
lla gp, __global_pointer$
.option pop
/* Setup supervisor trap vector */
la t0, cpu_exception_handler
@ -177,12 +188,6 @@ va:
li t0, 0
csrw sscratch, t0
/* Set the global pointer */
.option push
.option norelax
la gp, __global_pointer$
.option pop
/* Initialize stack pointer */
la s3, initstack_end
mv sp, s3
@ -322,6 +327,12 @@ ENTRY(mpentry)
.align 2
mpva:
/* Set the global pointer again, this time with the virtual address. */
.option push
.option norelax
lla gp, __global_pointer$
.option pop
/* Setup supervisor trap vector */
la t0, cpu_exception_handler
csrw stvec, t0
@ -330,12 +341,6 @@ mpva:
li t0, 0
csrw sscratch, t0
/* Set the global pointer */
.option push
.option norelax
la gp, __global_pointer$
.option pop
call init_secondary
END(mpentry)
#endif