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