^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Copyright (C) 2017 Andes Technology Corporation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #ifndef _ASM_RISCV_FTRACE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #define _ASM_RISCV_FTRACE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * The graph frame test is not possible if CONFIG_FRAME_POINTER is not enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Check arch/riscv/kernel/mcount.S for detail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #if defined(CONFIG_FUNCTION_GRAPH_TRACER) && defined(CONFIG_FRAME_POINTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define HAVE_FUNCTION_GRAPH_FP_TEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Clang prior to 13 had "mcount" instead of "_mcount":
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * https://reviews.llvm.org/D98881
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #if defined(CONFIG_CC_IS_GCC) || CONFIG_CLANG_VERSION >= 130000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define MCOUNT_NAME _mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define MCOUNT_NAME mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define ARCH_SUPPORTS_FTRACE_OPS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #ifndef __ASSEMBLY__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) void MCOUNT_NAME(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static inline unsigned long ftrace_call_adjust(unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct dyn_arch_ftrace {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #ifdef CONFIG_DYNAMIC_FTRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * A general call in RISC-V is a pair of insts:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * 1) auipc: setting high-20 pc-related bits to ra register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * 2) jalr: setting low-12 offset to ra, jump to ra, and set ra to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * return address (original pc + 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * Dynamic ftrace generates probes to call sites, so we must deal with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * both auipc and jalr at the same time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define MCOUNT_ADDR ((unsigned long)MCOUNT_NAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define JALR_SIGN_MASK (0x00000800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define JALR_OFFSET_MASK (0x00000fff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define AUIPC_OFFSET_MASK (0xfffff000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define AUIPC_PAD (0x00001000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define JALR_SHIFT 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define JALR_BASIC (0x000080e7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define AUIPC_BASIC (0x00000097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define NOP4 (0x00000013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define make_call(caller, callee, call) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) call[0] = to_auipc_insn((unsigned int)((unsigned long)callee - \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) (unsigned long)caller)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) call[1] = to_jalr_insn((unsigned int)((unsigned long)callee - \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) (unsigned long)caller)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define to_jalr_insn(offset) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) (((offset & JALR_OFFSET_MASK) << JALR_SHIFT) | JALR_BASIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define to_auipc_insn(offset) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ((offset & JALR_SIGN_MASK) ? \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) (((offset & AUIPC_OFFSET_MASK) + AUIPC_PAD) | AUIPC_BASIC) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ((offset & AUIPC_OFFSET_MASK) | AUIPC_BASIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * Let auipc+jalr be the basic *mcount unit*, so we make it 8 bytes here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define MCOUNT_INSN_SIZE 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #ifndef __ASSEMBLY__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct dyn_ftrace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define ftrace_init_nop ftrace_init_nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #endif /* _ASM_RISCV_FTRACE_H */