18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _ASM_POWERPC_FTRACE
38c2ecf20Sopenharmony_ci#define _ASM_POWERPC_FTRACE
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <asm/types.h>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#ifdef CONFIG_FUNCTION_TRACER
88c2ecf20Sopenharmony_ci#define MCOUNT_ADDR		((unsigned long)(_mcount))
98c2ecf20Sopenharmony_ci#define MCOUNT_INSN_SIZE	4 /* sizeof mcount call */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#ifdef __ASSEMBLY__
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci/* Based off of objdump optput from glibc */
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#define MCOUNT_SAVE_FRAME			\
188c2ecf20Sopenharmony_ci	stwu	r1,-48(r1);			\
198c2ecf20Sopenharmony_ci	stw	r3, 12(r1);			\
208c2ecf20Sopenharmony_ci	stw	r4, 16(r1);			\
218c2ecf20Sopenharmony_ci	stw	r5, 20(r1);			\
228c2ecf20Sopenharmony_ci	stw	r6, 24(r1);			\
238c2ecf20Sopenharmony_ci	mflr	r3;				\
248c2ecf20Sopenharmony_ci	lwz	r4, 52(r1);			\
258c2ecf20Sopenharmony_ci	mfcr	r5;				\
268c2ecf20Sopenharmony_ci	stw	r7, 28(r1);			\
278c2ecf20Sopenharmony_ci	stw	r8, 32(r1);			\
288c2ecf20Sopenharmony_ci	stw	r9, 36(r1);			\
298c2ecf20Sopenharmony_ci	stw	r10,40(r1);			\
308c2ecf20Sopenharmony_ci	stw	r3, 44(r1);			\
318c2ecf20Sopenharmony_ci	stw	r5, 8(r1)
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci#define MCOUNT_RESTORE_FRAME			\
348c2ecf20Sopenharmony_ci	lwz	r6, 8(r1);			\
358c2ecf20Sopenharmony_ci	lwz	r0, 44(r1);			\
368c2ecf20Sopenharmony_ci	lwz	r3, 12(r1);			\
378c2ecf20Sopenharmony_ci	mtctr	r0;				\
388c2ecf20Sopenharmony_ci	lwz	r4, 16(r1);			\
398c2ecf20Sopenharmony_ci	mtcr	r6;				\
408c2ecf20Sopenharmony_ci	lwz	r5, 20(r1);			\
418c2ecf20Sopenharmony_ci	lwz	r6, 24(r1);			\
428c2ecf20Sopenharmony_ci	lwz	r0, 52(r1);			\
438c2ecf20Sopenharmony_ci	lwz	r7, 28(r1);			\
448c2ecf20Sopenharmony_ci	lwz	r8, 32(r1);			\
458c2ecf20Sopenharmony_ci	mtlr	r0;				\
468c2ecf20Sopenharmony_ci	lwz	r9, 36(r1);			\
478c2ecf20Sopenharmony_ci	lwz	r10,40(r1);			\
488c2ecf20Sopenharmony_ci	addi	r1, r1, 48
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci#else /* !__ASSEMBLY__ */
518c2ecf20Sopenharmony_ciextern void _mcount(void);
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_cistatic inline unsigned long ftrace_call_adjust(unsigned long addr)
548c2ecf20Sopenharmony_ci{
558c2ecf20Sopenharmony_ci       /* reloction of mcount call site is the same as the address */
568c2ecf20Sopenharmony_ci       return addr;
578c2ecf20Sopenharmony_ci}
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cistruct dyn_arch_ftrace {
608c2ecf20Sopenharmony_ci	struct module *mod;
618c2ecf20Sopenharmony_ci};
628c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
658c2ecf20Sopenharmony_ci#define ARCH_SUPPORTS_FTRACE_OPS 1
668c2ecf20Sopenharmony_ci#endif
678c2ecf20Sopenharmony_ci#endif /* CONFIG_FUNCTION_TRACER */
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__
708c2ecf20Sopenharmony_ci#ifdef CONFIG_FTRACE_SYSCALLS
718c2ecf20Sopenharmony_ci/*
728c2ecf20Sopenharmony_ci * Some syscall entry functions on powerpc start with "ppc_" (fork and clone,
738c2ecf20Sopenharmony_ci * for instance) or ppc32_/ppc64_. We should also match the sys_ variant with
748c2ecf20Sopenharmony_ci * those.
758c2ecf20Sopenharmony_ci */
768c2ecf20Sopenharmony_ci#define ARCH_HAS_SYSCALL_MATCH_SYM_NAME
778c2ecf20Sopenharmony_ci#ifdef PPC64_ELF_ABI_v1
788c2ecf20Sopenharmony_cistatic inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
798c2ecf20Sopenharmony_ci{
808c2ecf20Sopenharmony_ci	/* We need to skip past the initial dot, and the __se_sys alias */
818c2ecf20Sopenharmony_ci	return !strcmp(sym + 1, name) ||
828c2ecf20Sopenharmony_ci		(!strncmp(sym, ".__se_sys", 9) && !strcmp(sym + 6, name)) ||
838c2ecf20Sopenharmony_ci		(!strncmp(sym, ".ppc_", 5) && !strcmp(sym + 5, name + 4)) ||
848c2ecf20Sopenharmony_ci		(!strncmp(sym, ".ppc32_", 7) && !strcmp(sym + 7, name + 4)) ||
858c2ecf20Sopenharmony_ci		(!strncmp(sym, ".ppc64_", 7) && !strcmp(sym + 7, name + 4));
868c2ecf20Sopenharmony_ci}
878c2ecf20Sopenharmony_ci#else
888c2ecf20Sopenharmony_cistatic inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
898c2ecf20Sopenharmony_ci{
908c2ecf20Sopenharmony_ci	return !strcmp(sym, name) ||
918c2ecf20Sopenharmony_ci		(!strncmp(sym, "__se_sys", 8) && !strcmp(sym + 5, name)) ||
928c2ecf20Sopenharmony_ci		(!strncmp(sym, "ppc_", 4) && !strcmp(sym + 4, name + 4)) ||
938c2ecf20Sopenharmony_ci		(!strncmp(sym, "ppc32_", 6) && !strcmp(sym + 6, name + 4)) ||
948c2ecf20Sopenharmony_ci		(!strncmp(sym, "ppc64_", 6) && !strcmp(sym + 6, name + 4));
958c2ecf20Sopenharmony_ci}
968c2ecf20Sopenharmony_ci#endif /* PPC64_ELF_ABI_v1 */
978c2ecf20Sopenharmony_ci#endif /* CONFIG_FTRACE_SYSCALLS */
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci#if defined(CONFIG_PPC64) && defined(CONFIG_FUNCTION_TRACER)
1008c2ecf20Sopenharmony_ci#include <asm/paca.h>
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_cistatic inline void this_cpu_disable_ftrace(void)
1038c2ecf20Sopenharmony_ci{
1048c2ecf20Sopenharmony_ci	get_paca()->ftrace_enabled = 0;
1058c2ecf20Sopenharmony_ci}
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_cistatic inline void this_cpu_enable_ftrace(void)
1088c2ecf20Sopenharmony_ci{
1098c2ecf20Sopenharmony_ci	get_paca()->ftrace_enabled = 1;
1108c2ecf20Sopenharmony_ci}
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci/* Disable ftrace on this CPU if possible (may not be implemented) */
1138c2ecf20Sopenharmony_cistatic inline void this_cpu_set_ftrace_enabled(u8 ftrace_enabled)
1148c2ecf20Sopenharmony_ci{
1158c2ecf20Sopenharmony_ci	get_paca()->ftrace_enabled = ftrace_enabled;
1168c2ecf20Sopenharmony_ci}
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_cistatic inline u8 this_cpu_get_ftrace_enabled(void)
1198c2ecf20Sopenharmony_ci{
1208c2ecf20Sopenharmony_ci	return get_paca()->ftrace_enabled;
1218c2ecf20Sopenharmony_ci}
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_civoid ftrace_free_init_tramp(void);
1248c2ecf20Sopenharmony_ci#else /* CONFIG_PPC64 */
1258c2ecf20Sopenharmony_cistatic inline void this_cpu_disable_ftrace(void) { }
1268c2ecf20Sopenharmony_cistatic inline void this_cpu_enable_ftrace(void) { }
1278c2ecf20Sopenharmony_cistatic inline void this_cpu_set_ftrace_enabled(u8 ftrace_enabled) { }
1288c2ecf20Sopenharmony_cistatic inline u8 this_cpu_get_ftrace_enabled(void) { return 1; }
1298c2ecf20Sopenharmony_cistatic inline void ftrace_free_init_tramp(void) { }
1308c2ecf20Sopenharmony_ci#endif /* CONFIG_PPC64 */
1318c2ecf20Sopenharmony_ci#endif /* !__ASSEMBLY__ */
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci#endif /* _ASM_POWERPC_FTRACE */
134