1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright (C) 2025 Chen Miao 4 * 5 * Based on arch/arm/include/asm/jump_label.h 6 */ 7 #ifndef __ASM_OPENRISC_JUMP_LABEL_H 8 #define __ASM_OPENRISC_JUMP_LABEL_H 9 10 #ifndef __ASSEMBLER__ 11 12 #include <linux/types.h> 13 #include <asm/insn-def.h> 14 15 #define HAVE_JUMP_LABEL_BATCH 16 17 #define JUMP_LABEL_NOP_SIZE OPENRISC_INSN_SIZE 18 19 /** 20 * JUMP_TABLE_ENTRY - Create a jump table entry 21 * @key: Jump key identifier (typically a symbol address) 22 * @label: Target label address 23 * 24 * This macro creates a jump table entry in the dedicated kernel section (__jump_table). 25 * Each entry contains the following information: 26 * Offset from current instruction to jump instruction (1b - .) 27 * Offset from current instruction to target label (label - .) 28 * Offset from current instruction to key identifier (key - .) 29 */ 30 #define JUMP_TABLE_ENTRY(key, label) \ 31 ".pushsection __jump_table, \"aw\" \n\t" \ 32 ".align 4 \n\t" \ 33 ".long 1b - ., " label " - . \n\t" \ 34 ".long " key " - . \n\t" \ 35 ".popsection \n\t" 36 37 #define ARCH_STATIC_BRANCH_ASM(key, label) \ 38 ".align 4 \n\t" \ 39 "1: l.nop \n\t" \ 40 " l.nop \n\t" \ 41 JUMP_TABLE_ENTRY(key, label) 42 43 static __always_inline bool arch_static_branch(struct static_key *const key, 44 const bool branch) 45 { 46 asm goto (ARCH_STATIC_BRANCH_ASM("%0", "%l[l_yes]") 47 ::"i"(&((char *)key)[branch])::l_yes); 48 49 return false; 50 l_yes: 51 return true; 52 } 53 54 #define ARCH_STATIC_BRANCH_JUMP_ASM(key, label) \ 55 ".align 4 \n\t" \ 56 "1: l.j " label " \n\t" \ 57 " l.nop \n\t" \ 58 JUMP_TABLE_ENTRY(key, label) 59 60 static __always_inline bool 61 arch_static_branch_jump(struct static_key *const key, const bool branch) 62 { 63 asm goto (ARCH_STATIC_BRANCH_JUMP_ASM("%0", "%l[l_yes]") 64 ::"i"(&((char *)key)[branch])::l_yes); 65 66 return false; 67 l_yes: 68 return true; 69 } 70 71 #endif /* __ASSEMBLER__ */ 72 #endif /* __ASM_OPENRISC_JUMP_LABEL_H */ 73