[PATCH v2 1/9] riscv: Optimize source end address calculation in start.S

The __bss_start is the source end address hence load its address directly into register 't2' for optimization.
Signed-off-by: Bin Meng bmeng@tinylab.org Reviewed-by: Rick Chen rick@andestech.com ---
(no changes since v1)
arch/riscv/cpu/start.S | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 4687bca3c9..3c8344c345 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -283,9 +283,7 @@ stack_setup: beq t0, s4, clear_bss /* skip relocation */
mv t1, s4 /* t1 <- scratch for copy_loop */ - la t3, __bss_start - sub t3, t3, t0 /* t3 <- __bss_start_ofs */ - add t2, t0, t3 /* t2 <- source end address */ + la t2, __bss_start /* t2 <- source end address */
copy_loop: LREG t5, 0(t0)

't5' already contains relocation type so don't bother reloading it.
Signed-off-by: Bin Meng bmeng@tinylab.org Reviewed-by: Rick Chen rick@andestech.com ---
(no changes since v1)
arch/riscv/cpu/start.S | 1 - 1 file changed, 1 deletion(-)
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 3c8344c345..879bdc1803 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -323,7 +323,6 @@ fix_rela_dyn: add t4, t4, t6
9: - LREG t5, -(REGBYTES*2)(t1) /* t5 <-- relocation info:type */ srli t0, t5, SYM_INDEX /* t0 <--- sym table index */ andi t5, t5, 0xFF /* t5 <--- relocation type */ li t3, RELOC_TYPE

Some coding convention fixes.
Signed-off-by: Bin Meng bmeng@tinylab.org Reviewed-by: Rick Chen rick@andestech.com ---
(no changes since v1)
tools/prelink-riscv.inc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tools/prelink-riscv.inc b/tools/prelink-riscv.inc index f2b5467f5b..57c0f655d4 100644 --- a/tools/prelink-riscv.inc +++ b/tools/prelink-riscv.inc @@ -30,7 +30,7 @@ #define cpu_to_target32 CONCAT3(cpu_to_, PRELINK_BYTEORDER, 32) #define cpu_to_target64 CONCAT3(cpu_to_, PRELINK_BYTEORDER, 64)
-static void* get_offset_bonn (void* data, Elf_Phdr* phdrs, size_t phnum, Elf_Addr addr) +static void *get_offset_bonn(void *data, Elf_Phdr *phdrs, size_t phnum, Elf_Addr addr) { Elf_Phdr *p;
@@ -67,13 +67,13 @@ static void prelink_bonn(void *data) Elf_Rela *rela_dyn = NULL; size_t rela_count = 0; Elf_Sym *dynsym = NULL; - for (dyn = dyns;; ++dyn) { + for (dyn = dyns; ; ++dyn) { if (targetnn_to_cpu(dyn->d_tag) == DT_NULL) break; else if (targetnn_to_cpu(dyn->d_tag) == DT_RELA) rela_dyn = get_offset_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), + targetnn_to_cpu(dyn->d_un.d_ptr)); else if (targetnn_to_cpu(dyn->d_tag) == DT_RELASZ) - rela_count = targetnn_to_cpu(dyn->d_un.d_val) / sizeof(Elf_Rela); + rela_count = targetnn_to_cpu(dyn->d_un.d_val) / sizeof(Elf_Rela); else if (targetnn_to_cpu(dyn->d_tag) == DT_SYMTAB) dynsym = get_offset_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), + targetnn_to_cpu(dyn->d_un.d_ptr));
@@ -92,11 +92,11 @@ static void prelink_bonn(void *data) continue;
if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_RELATIVE) - *((uintnn_t*) buf) = r->r_addend; + *((uintnn_t *)buf) = r->r_addend; else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_32) - *((uint32_t*) buf) = cpu_to_target32(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend)); + *((uint32_t *)buf) = cpu_to_target32(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend)); else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_64) - *((uint64_t*) buf) = cpu_to_target64(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend)); + *((uint64_t *)buf) = cpu_to_target64(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend)); } }

The codes forget to call munmap() to unmap the ELF image that was mapped by previous mmap().
Signed-off-by: Bin Meng bmeng@tinylab.org Reviewed-by: Rick Chen rick@andestech.com ---
(no changes since v1)
tools/prelink-riscv.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/tools/prelink-riscv.c b/tools/prelink-riscv.c index b0467949eb..43d6412ee9 100644 --- a/tools/prelink-riscv.c +++ b/tools/prelink-riscv.c @@ -118,5 +118,7 @@ int main(int argc, const char *const *argv) prelink_le32(data); }
+ munmap(data, st.st_size); + return 0; }

The argv[2] is never used in prelink-riscv. Drop it.
Signed-off-by: Bin Meng bmeng@tinylab.org Reviewed-by: Rick Chen rick@andestech.com ---
(no changes since v1)
Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile index 5083beae35..eaaf7d267d 100644 --- a/Makefile +++ b/Makefile @@ -1761,7 +1761,7 @@ ifeq ($(CONFIG_KALLSYMS),y) endif
ifeq ($(CONFIG_RISCV),y) - @tools/prelink-riscv $@ 0 + @tools/prelink-riscv $@ endif
quiet_cmd_sym ?= SYM $@

The codes currently skip the very first relocation entry, and have an inaccurate comment "skip first reserved entry" indicating that the first entry is reserved, but later it references the elements in the first relocation entry using a minus offset.
Change to use a positive offset so that there is no need to skip the first relocation entry.
Signed-off-by: Bin Meng bmeng@tinylab.org ---
(no changes since v1)
arch/riscv/cpu/start.S | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 879bdc1803..c09d1cb412 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -302,17 +302,12 @@ fix_rela_dyn: add t1, t1, t6 /* t1 <- rela_dyn_start in RAM */ add t2, t2, t6 /* t2 <- rela_dyn_end in RAM */
-/* - * skip first reserved entry: address, type, addend - */ - j 10f - 6: - LREG t5, -(REGBYTES*2)(t1) /* t5 <-- relocation info:type */ + LREG t5, REGBYTES(t1) /* t5 <-- relocation info:type */ li t3, R_RISCV_RELATIVE /* reloc type R_RISCV_RELATIVE */ bne t5, t3, 8f /* skip non-RISCV_RELOC entries */ - LREG t3, -(REGBYTES*3)(t1) - LREG t5, -(REGBYTES)(t1) /* t5 <-- addend */ + LREG t3, 0(t1) + LREG t5, (REGBYTES * 2)(t1) /* t5 <-- addend */ add t5, t5, t6 /* t5 <-- location to fix up in RAM */ add t3, t3, t6 /* t3 <-- location to fix up in RAM */ SREG t5, 0(t3) @@ -328,19 +323,19 @@ fix_rela_dyn: li t3, RELOC_TYPE bne t5, t3, 10f /* skip non-addned entries */
- LREG t3, -(REGBYTES*3)(t1) + LREG t3, 0(t1) li t5, SYM_SIZE mul t0, t0, t5 add s5, t4, t0 - LREG t0, -(REGBYTES)(t1) /* t0 <-- addend */ + LREG t0, (REGBYTES * 2)(t1) /* t0 <-- addend */ LREG t5, REGBYTES(s5) add t5, t5, t0 add t5, t5, t6 /* t5 <-- location to fix up in RAM */ add t3, t3, t6 /* t3 <-- location to fix up in RAM */ SREG t5, 0(t3) 10: - addi t1, t1, (REGBYTES*3) - ble t1, t2, 6b + addi t1, t1, (REGBYTES * 3) + blt t1, t2, 6b
/* * trap update

On Thu, Apr 13, 2023 at 02:20:05PM +0800, Bin Meng wrote:
The codes currently skip the very first relocation entry, and have an inaccurate comment "skip first reserved entry" indicating that the first entry is reserved, but later it references the elements in the first relocation entry using a minus offset.
Change to use a positive offset so that there is no need to skip the first relocation entry.
Signed-off-by: Bin Meng bmeng@tinylab.org
(no changes since v1)
arch/riscv/cpu/start.S | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-)
Reviewed-by: Leo Yu-Chi Liang ycliang@andestech.com

board_init_r does not return for U-Boot SPL hence there is no need to update the link register when jumping to board_init_r.
Signed-off-by: Bin Meng bmeng@tinylab.org
---
Changes in v2: - new patch: "riscv: Avoid updating the link register"
arch/riscv/cpu/start.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index c09d1cb412..8cf25bb14a 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -250,7 +250,7 @@ spl_secondary_hart_stack_gd_setup: spl_call_board_init_r: mv a0, zero mv a1, zero - jal board_init_r + j board_init_r #endif
/*

On Thu, Apr 13, 2023 at 02:20:06PM +0800, Bin Meng wrote:
board_init_r does not return for U-Boot SPL hence there is no need to update the link register when jumping to board_init_r.
Signed-off-by: Bin Meng bmeng@tinylab.org
Changes in v2:
- new patch: "riscv: Avoid updating the link register"
arch/riscv/cpu/start.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Leo Yu-Chi Liang ycliang@andestech.com

U-Boot SPL is not relocable. Drop these relocation sections.
Signed-off-by: Bin Meng bmeng@tinylab.org
---
Changes in v2: - fix SPL build error
arch/riscv/cpu/start.S | 2 ++ arch/riscv/cpu/u-boot-spl.lds | 25 ------------------------- 2 files changed, 2 insertions(+), 25 deletions(-)
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 8cf25bb14a..dad22bfea8 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -253,6 +253,7 @@ spl_call_board_init_r: j board_init_r #endif
+#if !defined(CONFIG_SPL_BUILD) /* * void relocate_code(addr_sp, gd, addr_moni) * @@ -400,6 +401,7 @@ call_board_init_r: * jump to it ... */ jr t4 /* jump to board_init_r() */ +#endif /* !defined(CONFIG_SPL_BUILD) */
#if CONFIG_IS_ENABLED(SMP) hart_out_of_bounds_loop: diff --git a/arch/riscv/cpu/u-boot-spl.lds b/arch/riscv/cpu/u-boot-spl.lds index 993536302a..c3b4907905 100644 --- a/arch/riscv/cpu/u-boot-spl.lds +++ b/arch/riscv/cpu/u-boot-spl.lds @@ -32,14 +32,6 @@ SECTIONS } > .spl_mem . = ALIGN(4);
- .got : { - __got_start = .; - *(.got.plt) *(.got) - __got_end = .; - } > .spl_mem - - . = ALIGN(4); - __u_boot_list : { KEEP(*(SORT(__u_boot_list*))); } > .spl_mem @@ -54,23 +46,6 @@ SECTIONS
. = ALIGN(4);
- /DISCARD/ : { *(.rela.plt*) } - .rela.dyn : { - __rel_dyn_start = .; - *(.rela*) - __rel_dyn_end = .; - } > .spl_mem - - . = ALIGN(4); - - .dynsym : { - __dyn_sym_start = .; - *(.dynsym) - __dyn_sym_end = .; - } > .spl_mem - - . = ALIGN(4); - _end = .; _image_binary_end = .;

On Thu, Apr 13, 2023 at 02:20:07PM +0800, Bin Meng wrote:
U-Boot SPL is not relocable. Drop these relocation sections.
Signed-off-by: Bin Meng bmeng@tinylab.org
Changes in v2:
- fix SPL build error
arch/riscv/cpu/start.S | 2 ++ arch/riscv/cpu/u-boot-spl.lds | 25 ------------------------- 2 files changed, 2 insertions(+), 25 deletions(-)
Reviewed-by: Leo Yu-Chi Liang ycliang@andestech.com

Some sections in the linker scripts are aligned to 4 bytes, which may cause misaligned exception on some platforms, e.g.: clearing the bss section on 64-bit hardware if __bss_start does not start from a naturally 8 bytes aligned address.
Signed-off-by: Bin Meng bmeng@tinylab.org
---
(no changes since v1)
arch/riscv/cpu/u-boot-spl.lds | 2 +- arch/riscv/cpu/u-boot.lds | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/riscv/cpu/u-boot-spl.lds b/arch/riscv/cpu/u-boot-spl.lds index c3b4907905..d1113a59aa 100644 --- a/arch/riscv/cpu/u-boot-spl.lds +++ b/arch/riscv/cpu/u-boot-spl.lds @@ -44,7 +44,7 @@ SECTIONS __binman_sym_end = .; } > .spl_mem
- . = ALIGN(4); + . = ALIGN(8);
_end = .; _image_binary_end = .; diff --git a/arch/riscv/cpu/u-boot.lds b/arch/riscv/cpu/u-boot.lds index 1c937aebee..15b5cbc585 100644 --- a/arch/riscv/cpu/u-boot.lds +++ b/arch/riscv/cpu/u-boot.lds @@ -57,7 +57,7 @@ SECTIONS __efi_runtime_rel_stop = .; }
- . = ALIGN(4); + . = ALIGN(8);
/DISCARD/ : { *(.rela.plt*) } .rela.dyn : { @@ -66,7 +66,7 @@ SECTIONS __rel_dyn_end = .; }
- . = ALIGN(4); + . = ALIGN(8);
.dynsym : { __dyn_sym_start = .; @@ -74,7 +74,7 @@ SECTIONS __dyn_sym_end = .; }
- . = ALIGN(4); + . = ALIGN(8);
_end = .;

On Thu, Apr 13, 2023 at 02:20:08PM +0800, Bin Meng wrote:
Some sections in the linker scripts are aligned to 4 bytes, which may cause misaligned exception on some platforms, e.g.: clearing the bss section on 64-bit hardware if __bss_start does not start from a naturally 8 bytes aligned address.
Signed-off-by: Bin Meng bmeng@tinylab.org
(no changes since v1)
arch/riscv/cpu/u-boot-spl.lds | 2 +- arch/riscv/cpu/u-boot.lds | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
Reviewed-by: Leo Yu-Chi Liang ycliang@andestech.com

Hi Bin,
čt 13. 4. 2023 v 8:21 odesílatel Bin Meng bmeng@tinylab.org napsal:
Some sections in the linker scripts are aligned to 4 bytes, which may cause misaligned exception on some platforms, e.g.: clearing the bss section on 64-bit hardware if __bss_start does not start from a naturally 8 bytes aligned address.
Signed-off-by: Bin Meng bmeng@tinylab.org
(no changes since v1)
arch/riscv/cpu/u-boot-spl.lds | 2 +- arch/riscv/cpu/u-boot.lds | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/riscv/cpu/u-boot-spl.lds b/arch/riscv/cpu/u-boot-spl.lds index c3b4907905..d1113a59aa 100644 --- a/arch/riscv/cpu/u-boot-spl.lds +++ b/arch/riscv/cpu/u-boot-spl.lds @@ -44,7 +44,7 @@ SECTIONS __binman_sym_end = .; } > .spl_mem
. = ALIGN(4);
. = ALIGN(8); _end = .; _image_binary_end = .;
diff --git a/arch/riscv/cpu/u-boot.lds b/arch/riscv/cpu/u-boot.lds index 1c937aebee..15b5cbc585 100644 --- a/arch/riscv/cpu/u-boot.lds +++ b/arch/riscv/cpu/u-boot.lds @@ -57,7 +57,7 @@ SECTIONS __efi_runtime_rel_stop = .; }
. = ALIGN(4);
. = ALIGN(8); /DISCARD/ : { *(.rela.plt*) } .rela.dyn : {
@@ -66,7 +66,7 @@ SECTIONS __rel_dyn_end = .; }
. = ALIGN(4);
. = ALIGN(8); .dynsym : { __dyn_sym_start = .;
@@ -74,7 +74,7 @@ SECTIONS __dyn_sym_end = .; }
. = ALIGN(4);
. = ALIGN(8); _end = .;
This change has actually a side effect on SPL and its behavior. You are enforcing here that symbols _end or _image_binary_end are 8byte aligned but if previous section are only 4 bytes aligned you are forcing 4byte gap between the end of u-boot-nodtb.bin binary and symbol reference. It means when you want to attach dtb behind SPL you have a problem. DTBs should be 64bit aligned. It means alignment of 8bytes is fine but you need to also make sure that spl/u-boot-nodtb.bin is 8byte aligned.
Pretty much talking about change like below but it would require to change all u-boot-spl.lds to make sure that end symbols are 8byte aligned that appended DTB is 8byte aligned all the time.
Thanks, Michal
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index 407fc52376a5..486360f10176 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -320,7 +320,7 @@ endif endif
ifneq ($(build_dtb),) -$(obj)/$(SPL_BIN)-dtb.bin: $(obj)/$(SPL_BIN)-nodtb.bin \ +$(obj)/$(SPL_BIN)-dtb.bin: $(obj)/$(SPL_BIN)-nodtb-align.bin \ $(if $(CONFIG_$(SPL_TPL_)SEPARATE_BSS),,$(obj)/$(SPL_BIN)-pad.bin) \ $(FINAL_DTB_CONTAINER) FORCE $(call if_changed,cat) @@ -328,7 +328,7 @@ $(obj)/$(SPL_BIN)-dtb.bin: $(obj)/$(SPL_BIN)-nodtb.bin \ $(obj)/$(SPL_BIN).bin: $(obj)/$(SPL_BIN)-dtb.bin FORCE $(call if_changed,copy) else -$(obj)/$(SPL_BIN).bin: $(obj)/$(SPL_BIN)-nodtb.bin FORCE +$(obj)/$(SPL_BIN).bin: $(obj)/$(SPL_BIN)-nodtb-align.bin FORCE $(call if_changed,copy) endif
@@ -390,6 +390,9 @@ OBJCOPYFLAGS_$(SPL_BIN)-nodtb.bin = $(SPL_OBJCFLAGS) -O binary \ $(obj)/$(SPL_BIN)-nodtb.bin: $(obj)/$(SPL_BIN) FORCE $(call if_changed,objcopy)
+$(obj)/$(SPL_BIN)-nodtb-align.bin: $(obj)/$(SPL_BIN)-nodtb.bin + @dd if=$< of=$@ conv=block,sync bs=8 2>/dev/null; + OBJCOPYFLAGS_u-boot-x86-start16-spl.bin := -O binary -j .start16 $(obj)/u-boot-x86-start16-spl.bin: $(obj)/u-boot-spl FORCE $(call if_changed,objcopy)
Thanks, Michal
participants (3)
-
Bin Meng
-
Leo Liang
-
Michal Simek