1*b37042b2SHuacai Chen // SPDX-License-Identifier: GPL-2.0
2*b37042b2SHuacai Chen /*
3*b37042b2SHuacai Chen  * Copyright (C) 2022 Loongson Technology Corporation Limited
4*b37042b2SHuacai Chen  *
5*b37042b2SHuacai Chen  * Derived from MIPS:
6*b37042b2SHuacai Chen  * Copyright (C) 2013 Cavium, Inc.
7*b37042b2SHuacai Chen  */
8*b37042b2SHuacai Chen 
9*b37042b2SHuacai Chen #include <linux/perf_event.h>
10*b37042b2SHuacai Chen 
11*b37042b2SHuacai Chen #include <asm/ptrace.h>
12*b37042b2SHuacai Chen 
13*b37042b2SHuacai Chen #ifdef CONFIG_32BIT
perf_reg_abi(struct task_struct * tsk)14*b37042b2SHuacai Chen u64 perf_reg_abi(struct task_struct *tsk)
15*b37042b2SHuacai Chen {
16*b37042b2SHuacai Chen 	return PERF_SAMPLE_REGS_ABI_32;
17*b37042b2SHuacai Chen }
18*b37042b2SHuacai Chen #else /* Must be CONFIG_64BIT */
perf_reg_abi(struct task_struct * tsk)19*b37042b2SHuacai Chen u64 perf_reg_abi(struct task_struct *tsk)
20*b37042b2SHuacai Chen {
21*b37042b2SHuacai Chen 	if (test_tsk_thread_flag(tsk, TIF_32BIT_REGS))
22*b37042b2SHuacai Chen 		return PERF_SAMPLE_REGS_ABI_32;
23*b37042b2SHuacai Chen 	else
24*b37042b2SHuacai Chen 		return PERF_SAMPLE_REGS_ABI_64;
25*b37042b2SHuacai Chen }
26*b37042b2SHuacai Chen #endif /* CONFIG_32BIT */
27*b37042b2SHuacai Chen 
perf_reg_validate(u64 mask)28*b37042b2SHuacai Chen int perf_reg_validate(u64 mask)
29*b37042b2SHuacai Chen {
30*b37042b2SHuacai Chen 	if (!mask)
31*b37042b2SHuacai Chen 		return -EINVAL;
32*b37042b2SHuacai Chen 	if (mask & ~((1ull << PERF_REG_LOONGARCH_MAX) - 1))
33*b37042b2SHuacai Chen 		return -EINVAL;
34*b37042b2SHuacai Chen 	return 0;
35*b37042b2SHuacai Chen }
36*b37042b2SHuacai Chen 
perf_reg_value(struct pt_regs * regs,int idx)37*b37042b2SHuacai Chen u64 perf_reg_value(struct pt_regs *regs, int idx)
38*b37042b2SHuacai Chen {
39*b37042b2SHuacai Chen 	if (WARN_ON_ONCE((u32)idx >= PERF_REG_LOONGARCH_MAX))
40*b37042b2SHuacai Chen 		return 0;
41*b37042b2SHuacai Chen 
42*b37042b2SHuacai Chen 	if ((u32)idx == PERF_REG_LOONGARCH_PC)
43*b37042b2SHuacai Chen 		return regs->csr_era;
44*b37042b2SHuacai Chen 
45*b37042b2SHuacai Chen 	return regs->regs[idx];
46*b37042b2SHuacai Chen }
47*b37042b2SHuacai Chen 
perf_get_regs_user(struct perf_regs * regs_user,struct pt_regs * regs)48*b37042b2SHuacai Chen void perf_get_regs_user(struct perf_regs *regs_user,
49*b37042b2SHuacai Chen 			struct pt_regs *regs)
50*b37042b2SHuacai Chen {
51*b37042b2SHuacai Chen 	regs_user->regs = task_pt_regs(current);
52*b37042b2SHuacai Chen 	regs_user->abi = perf_reg_abi(current);
53*b37042b2SHuacai Chen }
54