diff options
Diffstat (limited to 'arch/riscv/include/asm')
| -rw-r--r-- | arch/riscv/include/asm/asm.h | 1 | ||||
| -rw-r--r-- | arch/riscv/include/asm/hwprobe.h | 7 | ||||
| -rw-r--r-- | arch/riscv/include/asm/runtime-const.h | 84 | ||||
| -rw-r--r-- | arch/riscv/include/asm/vdso/arch_data.h | 6 |
4 files changed, 67 insertions, 31 deletions
diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h index e9e8ba83e632..b8bf842d4c13 100644 --- a/arch/riscv/include/asm/asm.h +++ b/arch/riscv/include/asm/asm.h @@ -34,6 +34,7 @@ #define SZREG __REG_SEL(8, 4) #define LGREG __REG_SEL(3, 2) #define SRLI __REG_SEL(srliw, srli) +#define SLLI __REG_SEL(slliw, slli) #if __SIZEOF_POINTER__ == 8 #ifdef __ASSEMBLER__ diff --git a/arch/riscv/include/asm/hwprobe.h b/arch/riscv/include/asm/hwprobe.h index 8b9f5e1cf4cb..9b04377c0f98 100644 --- a/arch/riscv/include/asm/hwprobe.h +++ b/arch/riscv/include/asm/hwprobe.h @@ -43,11 +43,4 @@ static inline bool riscv_hwprobe_pair_cmp(struct riscv_hwprobe *pair, return pair->value == other_pair->value; } -#ifdef CONFIG_MMU -void riscv_hwprobe_register_async_probe(void); -void riscv_hwprobe_complete_async_probe(void); -#else -static inline void riscv_hwprobe_register_async_probe(void) {} -static inline void riscv_hwprobe_complete_async_probe(void) {} -#endif #endif diff --git a/arch/riscv/include/asm/runtime-const.h b/arch/riscv/include/asm/runtime-const.h index 900db0a103d0..ce2008bb5227 100644 --- a/arch/riscv/include/asm/runtime-const.h +++ b/arch/riscv/include/asm/runtime-const.h @@ -15,21 +15,24 @@ #include <linux/uaccess.h> +#define RUNTIME_MAGIC __ASM_STR(0x89ABCDEF) + #ifdef CONFIG_32BIT -#define runtime_const_ptr(sym) \ -({ \ - typeof(sym) __ret; \ - asm_inline(".option push\n\t" \ - ".option norvc\n\t" \ - "1:\t" \ - "lui %[__ret],0x89abd\n\t" \ - "addi %[__ret],%[__ret],-0x211\n\t" \ - ".option pop\n\t" \ - ".pushsection runtime_ptr_" #sym ",\"a\"\n\t" \ - ".long 1b - .\n\t" \ - ".popsection" \ - : [__ret] "=r" (__ret)); \ - __ret; \ +#define runtime_const_ptr(sym) \ +({ \ + typeof(sym) __ret; \ + asm_inline(".option push\n\t" \ + ".option norvc\n\t" \ + ".option norelax\n\t" \ + "1:\t" \ + "lui %[__ret], %%hi(" RUNTIME_MAGIC ")\n\t" \ + "addi %[__ret],%[__ret], %%lo(" RUNTIME_MAGIC ")\n\t" \ + ".option pop\n\t" \ + ".pushsection runtime_ptr_" #sym ",\"a\"\n\t" \ + ".long 1b - .\n\t" \ + ".popsection" \ + : [__ret] "=r" (__ret)); \ + __ret; \ }) #else /* @@ -45,11 +48,12 @@ #define RISCV_RUNTIME_CONST_64_PREAMBLE \ ".option push\n\t" \ ".option norvc\n\t" \ + ".option norelax\n\t" \ "1:\t" \ - "lui %[__ret],0x89abd\n\t" \ - "lui %[__tmp],0x1234\n\t" \ - "addiw %[__ret],%[__ret],-0x211\n\t" \ - "addiw %[__tmp],%[__tmp],0x567\n\t" \ + "lui %[__ret], %%hi(" RUNTIME_MAGIC ")\n\t" \ + "lui %[__tmp], %%hi(" RUNTIME_MAGIC ")\n\t" \ + "addiw %[__ret],%[__ret], %%lo(" RUNTIME_MAGIC ")\n\t" \ + "addiw %[__tmp],%[__tmp], %%lo(" RUNTIME_MAGIC ")\n\t" \ #define RISCV_RUNTIME_CONST_64_BASE \ "slli %[__tmp],%[__tmp],32\n\t" \ @@ -157,6 +161,23 @@ __ret; \ }) +#define runtime_const_mask_32(val, sym) \ +({ \ + u32 __ret; \ + asm_inline(".option push\n\t" \ + ".option norvc\n\t" \ + "1:\t" \ + SLLI " %[__ret],%[__val],12\n\t" \ + SRLI " %[__ret],%[__ret],12\n\t" \ + ".option pop\n\t" \ + ".pushsection runtime_mask_" #sym ",\"a\"\n\t" \ + ".long 1b - .\n\t" \ + ".popsection" \ + : [__ret] "=r" (__ret) \ + : [__val] "r" (val)); \ + __ret; \ +}) + #define runtime_const_init(type, sym) do { \ extern s32 __start_runtime_##type##_##sym[]; \ extern s32 __stop_runtime_##type##_##sym[]; \ @@ -260,6 +281,33 @@ static inline void __runtime_fixup_shift(void *where, unsigned long val) mutex_unlock(&text_mutex); } +static inline void __runtime_fixup_mask(void *where, unsigned long val) +{ + unsigned int width = (val) ? __fls(val) + 1 : 0; + + /* + * XXX: Current implementation only supports patching masks of + * form GENMASK(width, 0) (width >= 0) using a SRLI + SLLI + * sequence instead of LUI + ADDI + AND sequence to improve + * performance, density, and covers all the current use-cases. + * + * When the need arises to support any generic mask, and this + * BUG_ON() is tripped, consider using a: + * + * lui %[__ret], #imm16 + * addi %[__ret], #imm16 + * + * sequence to load the 32bit const mask, and perform a logical + * and outside the asm block before returning the result. Fixup + * can simply reuse the existing __runtime_fixup_32() to patch + * the LUI + ADDI sequence. + */ + BUG_ON(!val || width > 31 || (GENMASK(width - 1, 0) != val)); + + __runtime_fixup_shift(where, 32 - width); + __runtime_fixup_shift(where + 4, 32 - width); +} + static inline void runtime_const_fixup(void (*fn)(void *, unsigned long), unsigned long val, s32 *start, s32 *end) { diff --git a/arch/riscv/include/asm/vdso/arch_data.h b/arch/riscv/include/asm/vdso/arch_data.h index 88b37af55175..da57a3786f7a 100644 --- a/arch/riscv/include/asm/vdso/arch_data.h +++ b/arch/riscv/include/asm/vdso/arch_data.h @@ -12,12 +12,6 @@ struct vdso_arch_data { /* Boolean indicating all CPUs have the same static hwprobe values. */ __u8 homogeneous_cpus; - - /* - * A gate to check and see if the hwprobe data is actually ready, as - * probing is deferred to avoid boot slowdowns. - */ - __u8 ready; }; #endif /* __RISCV_ASM_VDSO_ARCH_DATA_H */ |
