[U-Boot] [PATCH 0/6] Small fixes for RISC-V

This patch series contains small fixes for RISC-V. It touches three areas.
- Patch 1 clarifies the error message on undefined exceptions. - Patch 2 removes the current dcache flush implementation. It uses the fence instruction, which does not directly affect the data cache and can therefore not be used to implement dcache flush and invalidation. - Patches 3-6 improve support for standalone applications. They add support for RV64I systems and fix a problem, where a callee-saved register is used without saving it beforehand. Patch 6 defines the standalone load address for qemu-riscv to allow it to run standalone applications.
Lukas Auer (6): riscv: clarify error message on undefined exceptions riscv: remove invalid dcache flush implementation riscv: remove RISC-V standalone linker script riscv: replace use of callee-saved register in standalone riscv: support standalone applications on RV64I systems riscv: qemu: define standalone load address
arch/riscv/config.mk | 3 +-- arch/riscv/lib/cache.c | 4 +--- arch/riscv/lib/interrupts.c | 3 ++- examples/standalone/riscv.lds | 40 ----------------------------------- examples/standalone/stubs.c | 21 +++++++++++++----- include/configs/qemu-riscv.h | 2 ++ 6 files changed, 22 insertions(+), 51 deletions(-) delete mode 100644 examples/standalone/riscv.lds

Undefined exceptions are treated as reserved. This is not clearly communicated to the user. Adjust the error message to clarify that a reserved exception has occurred and add additional details.
Fixes: e8b522b ("riscv: treat undefined exception codes as reserved") Signed-off-by: Lukas Auer lukas.auer@aisec.fraunhofer.de ---
arch/riscv/lib/interrupts.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c index e185933b01..74c1e561c7 100644 --- a/arch/riscv/lib/interrupts.c +++ b/arch/riscv/lib/interrupts.c @@ -37,7 +37,8 @@ static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs) printf("exception code: %ld , %s , epc %lx , ra %lx\n", code, exception_code[code], epc, regs->ra); } else { - printf("Reserved\n"); + printf("reserved exception code: %ld , epc %lx , ra %lx\n", + code, epc, regs->ra); }
hang();

On Mon, Dec 31, 2018 at 2:28 AM Lukas Auer lukas.auer@aisec.fraunhofer.de wrote:
Undefined exceptions are treated as reserved. This is not clearly communicated to the user. Adjust the error message to clarify that a reserved exception has occurred and add additional details.
Fixes: e8b522b ("riscv: treat undefined exception codes as reserved") Signed-off-by: Lukas Auer lukas.auer@aisec.fraunhofer.de
arch/riscv/lib/interrupts.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

The fence instruction is used to enforce device I/O and memory ordering constraints in RISC-V. It does not directly affect the data cache and particular cannot be used to flush or invalidate it. RISC-V does not have instructions for explicit cache control. Remove the flush_dcache_all implementation and its use in all dcache-specific functions in lib/cache.c.
This also adds a missing new line between flush_dcache_all and flush_dcache_range in lib/cache.c.
Signed-off-by: Lukas Auer lukas.auer@aisec.fraunhofer.de --- This patch only removes the implementation itself and its use in dcache-specific functions in lib/cache.c. There are more uses of it in arch/riscv/, which this patch does not remove.
arch/riscv/lib/cache.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/arch/riscv/lib/cache.c b/arch/riscv/lib/cache.c index ae5c60716f..203e287612 100644 --- a/arch/riscv/lib/cache.c +++ b/arch/riscv/lib/cache.c @@ -13,11 +13,10 @@ void invalidate_icache_all(void)
void flush_dcache_all(void) { - asm volatile ("fence" :::"memory"); } + void flush_dcache_range(unsigned long start, unsigned long end) { - flush_dcache_all(); }
void invalidate_icache_range(unsigned long start, unsigned long end) @@ -31,7 +30,6 @@ void invalidate_icache_range(unsigned long start, unsigned long end)
void invalidate_dcache_range(unsigned long start, unsigned long end) { - flush_dcache_all(); }
void cache_flush(void)

On Mon, Dec 31, 2018 at 2:28 AM Lukas Auer lukas.auer@aisec.fraunhofer.de wrote:
The fence instruction is used to enforce device I/O and memory ordering constraints in RISC-V. It does not directly affect the data cache and particular cannot be used to flush or invalidate it. RISC-V does not have instructions for explicit cache control. Remove the flush_dcache_all implementation and its use in all dcache-specific functions in lib/cache.c.
This also adds a missing new line between flush_dcache_all and flush_dcache_range in lib/cache.c.
Signed-off-by: Lukas Auer lukas.auer@aisec.fraunhofer.de
This patch only removes the implementation itself and its use in dcache-specific functions in lib/cache.c. There are more uses of it in arch/riscv/, which this patch does not remove.
arch/riscv/lib/cache.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

Standalone applications do not require a separate linker script and can use the default linker script of the compiler instead. Remove the RISC-V standalone linker script.
Signed-off-by: Lukas Auer lukas.auer@aisec.fraunhofer.de ---
arch/riscv/config.mk | 1 - examples/standalone/riscv.lds | 40 ----------------------------------- 2 files changed, 41 deletions(-) delete mode 100644 examples/standalone/riscv.lds
diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk index ff4fe64001..e484a3f0ef 100644 --- a/arch/riscv/config.mk +++ b/arch/riscv/config.mk @@ -24,7 +24,6 @@ EFI_LDS := elf_riscv64_efi.lds endif
CONFIG_STANDALONE_LOAD_ADDR = 0x00000000 -LDFLAGS_STANDALONE += -T $(srctree)/examples/standalone/riscv.lds
PLATFORM_CPPFLAGS += -ffixed-gp -fpic PLATFORM_RELFLAGS += -fno-common -gdwarf-2 -ffunction-sections \ diff --git a/examples/standalone/riscv.lds b/examples/standalone/riscv.lds deleted file mode 100644 index 9a25861052..0000000000 --- a/examples/standalone/riscv.lds +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (C) 2017 Andes Technology Corporation - * Rick Chen, Andes Technology Corporation rick@andestech.com - */ - -OUTPUT_ARCH(riscv) -ENTRY(_start) -SECTIONS -{ - . = ALIGN(4); - .text : - { - *(.text) - } - - . = ALIGN(4); - .data : { - __global_pointer$ = . + 0x800; - *(.data) - } - - . = ALIGN(4); - - .got : { - __got_start = .; - *(.got) - __got_end = .; - } - - . = ALIGN(4); - __bss_start = .; - .bss : { *(.bss) } - __bss_end = .; - - . = ALIGN(4); - .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } - - _end = .; -}

On Mon, Dec 31, 2018 at 2:31 AM Lukas Auer lukas.auer@aisec.fraunhofer.de wrote:
Standalone applications do not require a separate linker script and can use the default linker script of the compiler instead. Remove the RISC-V standalone linker script.
Signed-off-by: Lukas Auer lukas.auer@aisec.fraunhofer.de
arch/riscv/config.mk | 1 - examples/standalone/riscv.lds | 40 ----------------------------------- 2 files changed, 41 deletions(-) delete mode 100644 examples/standalone/riscv.lds
Reviewed-by: Bin Meng bmeng.cn@gmail.com Tested-by: Bin Meng bmeng.cn@gmail.com

Register x19 (s3) is a callee-saved register. It must not be used to load and jump to exported functions without saving it beforehand. Replace it with t0, a temporary and caller-saved register.
Change the code comment to reflect this and fix it to correctly list gp as the register with the pointer to global data.
Signed-off-by: Lukas Auer lukas.auer@aisec.fraunhofer.de ---
examples/standalone/stubs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c index fadde669fa..f37d209da6 100644 --- a/examples/standalone/stubs.c +++ b/examples/standalone/stubs.c @@ -174,16 +174,16 @@ gd_t *global_data; : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "$r16"); #elif defined(CONFIG_RISCV) /* - * t7 holds the pointer to the global_data. gp is call clobbered. + * gp holds the pointer to the global_data. t0 is call clobbered. */ #define EXPORT_FUNC(f, a, x, ...) \ asm volatile ( \ " .globl " #x "\n" \ #x ":\n" \ -" lw x19, %0(gp)\n" \ -" lw x19, %1(x19)\n" \ -" jr x19\n" \ - : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "x19"); +" lw t0, %0(gp)\n" \ +" lw t0, %1(t0)\n" \ +" jr t0\n" \ + : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t0"); #elif defined(CONFIG_ARC) /* * r25 holds the pointer to the global_data. r10 is call clobbered.

On Mon, Dec 31, 2018 at 2:30 AM Lukas Auer lukas.auer@aisec.fraunhofer.de wrote:
Register x19 (s3) is a callee-saved register. It must not be used to load and jump to exported functions without saving it beforehand. Replace it with t0, a temporary and caller-saved register.
Change the code comment to reflect this and fix it to correctly list gp as the register with the pointer to global data.
Signed-off-by: Lukas Auer lukas.auer@aisec.fraunhofer.de
examples/standalone/stubs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com Tested-by: Bin Meng bmeng.cn@gmail.com

Add an implementation of EXPORT_FUNC() for RV64I systems to support them in standalone applications.
Signed-off-by: Lukas Auer lukas.auer@aisec.fraunhofer.de ---
examples/standalone/stubs.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c index f37d209da6..0827bde35e 100644 --- a/examples/standalone/stubs.c +++ b/examples/standalone/stubs.c @@ -176,6 +176,16 @@ gd_t *global_data; /* * gp holds the pointer to the global_data. t0 is call clobbered. */ +#ifdef CONFIG_ARCH_RV64I +#define EXPORT_FUNC(f, a, x, ...) \ + asm volatile ( \ +" .globl " #x "\n" \ +#x ":\n" \ +" ld t0, %0(gp)\n" \ +" ld t0, %1(t0)\n" \ +" jr t0\n" \ + : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t0"); +#else #define EXPORT_FUNC(f, a, x, ...) \ asm volatile ( \ " .globl " #x "\n" \ @@ -184,6 +194,7 @@ gd_t *global_data; " lw t0, %1(t0)\n" \ " jr t0\n" \ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t0"); +#endif #elif defined(CONFIG_ARC) /* * r25 holds the pointer to the global_data. r10 is call clobbered.

On Mon, Dec 31, 2018 at 2:30 AM Lukas Auer lukas.auer@aisec.fraunhofer.de wrote:
Add an implementation of EXPORT_FUNC() for RV64I systems to support them in standalone applications.
Signed-off-by: Lukas Auer lukas.auer@aisec.fraunhofer.de
examples/standalone/stubs.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
Reviewed-by: Bin Meng bmeng.cn@gmail.com Tested-by: Bin Meng bmeng.cn@gmail.com

We need to define the standalone load address to use standalone application on qemu-riscv. Define it and set it equal to CONFIG_SYS_LOAD_ADDR.
To not overwrite it, change the assigned of CONFIG_STANDALONE_LOAD_ADDR in arch/riscv/config.mk to a conditional one.
Signed-off-by: Lukas Auer lukas.auer@aisec.fraunhofer.de ---
arch/riscv/config.mk | 2 +- include/configs/qemu-riscv.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk index e484a3f0ef..84654eb3ed 100644 --- a/arch/riscv/config.mk +++ b/arch/riscv/config.mk @@ -23,7 +23,7 @@ PLATFORM_LDFLAGS += -m $(64bit-emul) EFI_LDS := elf_riscv64_efi.lds endif
-CONFIG_STANDALONE_LOAD_ADDR = 0x00000000 +CONFIG_STANDALONE_LOAD_ADDR ?= 0x00000000
PLATFORM_CPPFLAGS += -ffixed-gp -fpic PLATFORM_RELFLAGS += -fno-common -gdwarf-2 -ffunction-sections \ diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h index b29d155d09..2588c5a0b2 100644 --- a/include/configs/qemu-riscv.h +++ b/include/configs/qemu-riscv.h @@ -17,6 +17,8 @@
#define CONFIG_SYS_BOOTM_LEN SZ_16M
+#define CONFIG_STANDALONE_LOAD_ADDR 0x80200000 + /* Environment options */ #define CONFIG_ENV_SIZE SZ_4K

On Mon, Dec 31, 2018 at 2:28 AM Lukas Auer lukas.auer@aisec.fraunhofer.de wrote:
We need to define the standalone load address to use standalone application on qemu-riscv. Define it and set it equal to CONFIG_SYS_LOAD_ADDR.
To not overwrite it, change the assigned of CONFIG_STANDALONE_LOAD_ADDR in arch/riscv/config.mk to a conditional one.
Signed-off-by: Lukas Auer lukas.auer@aisec.fraunhofer.de
arch/riscv/config.mk | 2 +- include/configs/qemu-riscv.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com Tested-by: Bin Meng bmeng.cn@gmail.com
participants (2)
-
Bin Meng
-
Lukas Auer