|
| 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 */ |
0 commit comments