18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* Copyright (C) 2017 Andes Technology Corporation */ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#ifndef _ASM_RISCV_FTRACE_H 58c2ecf20Sopenharmony_ci#define _ASM_RISCV_FTRACE_H 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci/* 88c2ecf20Sopenharmony_ci * The graph frame test is not possible if CONFIG_FRAME_POINTER is not enabled. 98c2ecf20Sopenharmony_ci * Check arch/riscv/kernel/mcount.S for detail. 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci#if defined(CONFIG_FUNCTION_GRAPH_TRACER) && defined(CONFIG_FRAME_POINTER) 128c2ecf20Sopenharmony_ci#define HAVE_FUNCTION_GRAPH_FP_TEST 138c2ecf20Sopenharmony_ci#endif 148c2ecf20Sopenharmony_ci#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* 178c2ecf20Sopenharmony_ci * Clang prior to 13 had "mcount" instead of "_mcount": 188c2ecf20Sopenharmony_ci * https://reviews.llvm.org/D98881 198c2ecf20Sopenharmony_ci */ 208c2ecf20Sopenharmony_ci#if defined(CONFIG_CC_IS_GCC) || CONFIG_CLANG_VERSION >= 130000 218c2ecf20Sopenharmony_ci#define MCOUNT_NAME _mcount 228c2ecf20Sopenharmony_ci#else 238c2ecf20Sopenharmony_ci#define MCOUNT_NAME mcount 248c2ecf20Sopenharmony_ci#endif 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#define ARCH_SUPPORTS_FTRACE_OPS 1 278c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 288c2ecf20Sopenharmony_civoid MCOUNT_NAME(void); 298c2ecf20Sopenharmony_cistatic inline unsigned long ftrace_call_adjust(unsigned long addr) 308c2ecf20Sopenharmony_ci{ 318c2ecf20Sopenharmony_ci return addr; 328c2ecf20Sopenharmony_ci} 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistruct dyn_arch_ftrace { 358c2ecf20Sopenharmony_ci}; 368c2ecf20Sopenharmony_ci#endif 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci#ifdef CONFIG_DYNAMIC_FTRACE 398c2ecf20Sopenharmony_ci/* 408c2ecf20Sopenharmony_ci * A general call in RISC-V is a pair of insts: 418c2ecf20Sopenharmony_ci * 1) auipc: setting high-20 pc-related bits to ra register 428c2ecf20Sopenharmony_ci * 2) jalr: setting low-12 offset to ra, jump to ra, and set ra to 438c2ecf20Sopenharmony_ci * return address (original pc + 4) 448c2ecf20Sopenharmony_ci * 458c2ecf20Sopenharmony_ci * Dynamic ftrace generates probes to call sites, so we must deal with 468c2ecf20Sopenharmony_ci * both auipc and jalr at the same time. 478c2ecf20Sopenharmony_ci */ 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#define MCOUNT_ADDR ((unsigned long)MCOUNT_NAME) 508c2ecf20Sopenharmony_ci#define JALR_SIGN_MASK (0x00000800) 518c2ecf20Sopenharmony_ci#define JALR_OFFSET_MASK (0x00000fff) 528c2ecf20Sopenharmony_ci#define AUIPC_OFFSET_MASK (0xfffff000) 538c2ecf20Sopenharmony_ci#define AUIPC_PAD (0x00001000) 548c2ecf20Sopenharmony_ci#define JALR_SHIFT 20 558c2ecf20Sopenharmony_ci#define JALR_BASIC (0x000080e7) 568c2ecf20Sopenharmony_ci#define AUIPC_BASIC (0x00000097) 578c2ecf20Sopenharmony_ci#define NOP4 (0x00000013) 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci#define make_call(caller, callee, call) \ 608c2ecf20Sopenharmony_cido { \ 618c2ecf20Sopenharmony_ci call[0] = to_auipc_insn((unsigned int)((unsigned long)callee - \ 628c2ecf20Sopenharmony_ci (unsigned long)caller)); \ 638c2ecf20Sopenharmony_ci call[1] = to_jalr_insn((unsigned int)((unsigned long)callee - \ 648c2ecf20Sopenharmony_ci (unsigned long)caller)); \ 658c2ecf20Sopenharmony_ci} while (0) 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci#define to_jalr_insn(offset) \ 688c2ecf20Sopenharmony_ci (((offset & JALR_OFFSET_MASK) << JALR_SHIFT) | JALR_BASIC) 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci#define to_auipc_insn(offset) \ 718c2ecf20Sopenharmony_ci ((offset & JALR_SIGN_MASK) ? \ 728c2ecf20Sopenharmony_ci (((offset & AUIPC_OFFSET_MASK) + AUIPC_PAD) | AUIPC_BASIC) : \ 738c2ecf20Sopenharmony_ci ((offset & AUIPC_OFFSET_MASK) | AUIPC_BASIC)) 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci/* 768c2ecf20Sopenharmony_ci * Let auipc+jalr be the basic *mcount unit*, so we make it 8 bytes here. 778c2ecf20Sopenharmony_ci */ 788c2ecf20Sopenharmony_ci#define MCOUNT_INSN_SIZE 8 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 818c2ecf20Sopenharmony_cistruct dyn_ftrace; 828c2ecf20Sopenharmony_ciint ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec); 838c2ecf20Sopenharmony_ci#define ftrace_init_nop ftrace_init_nop 848c2ecf20Sopenharmony_ci#endif 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci#endif /* CONFIG_DYNAMIC_FTRACE */ 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci#endif /* _ASM_RISCV_FTRACE_H */ 89