From 307666be28db0d89cbdcfafd2cf0e0cf5bf386db Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Sun, 27 Apr 2025 14:50:11 +0000 Subject: riscv: Access gd with inline assembly when building with LTO or Clang Similar to AArch64's case, Clang may wrongly fold accesses to gd pointer which is defined with register qualifier into constants, breaking various components. This patch defines gd as a macro when building with Clang or LTO, which expands to get_gd() that accesses gp pointer in assembly, making RISC-V ports function properly and preparing for introduction of LTO in the future. Board initialization code is also adapted for non-assignable gd. Reported-by: Nathaniel Hourt Signed-off-by: Yao Zi Reviewed-by: Leo Yu-Chi Liang --- arch/riscv/include/asm/global_data.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'arch/riscv/include/asm/global_data.h') diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h index d356752a56a..47b5e2cfc8f 100644 --- a/arch/riscv/include/asm/global_data.h +++ b/arch/riscv/include/asm/global_data.h @@ -14,6 +14,7 @@ #include #include #include +#include /* Architecture-specific global data */ struct arch_global_data { @@ -47,8 +48,26 @@ struct arch_global_data { #include +#if defined(__clang__) || CONFIG_IS_ENABLED(LTO) + +#define DECLARE_GLOBAL_DATA_PTR +#define gd get_gd() + +static inline gd_t *get_gd(void) +{ + gd_t *gd_ptr; + + __asm__ volatile ("mv %0, gp\n" : "=r" (gd_ptr)); + + return gd_ptr; +} + +#else + #define DECLARE_GLOBAL_DATA_PTR register gd_t *gd asm ("gp") +#endif + static inline void set_gd(volatile gd_t *gd_ptr) { #ifdef CONFIG_64BIT -- cgit v1.2.3