18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
48c2ecf20Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
58c2ecf20Sopenharmony_ci * for more details.
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Some parts derived from x86 version of this file.
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * Copyright (C) 2013 Cavium, Inc.
108c2ecf20Sopenharmony_ci * Copyright (C) 2021 Loongson Technology Corporation Limited
118c2ecf20Sopenharmony_ci */
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include <linux/perf_event.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include <asm/ptrace.h>
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#ifdef CONFIG_32BIT
188c2ecf20Sopenharmony_ciu64 perf_reg_abi(struct task_struct *tsk)
198c2ecf20Sopenharmony_ci{
208c2ecf20Sopenharmony_ci	return PERF_SAMPLE_REGS_ABI_32;
218c2ecf20Sopenharmony_ci}
228c2ecf20Sopenharmony_ci#else /* Must be CONFIG_64BIT */
238c2ecf20Sopenharmony_ciu64 perf_reg_abi(struct task_struct *tsk)
248c2ecf20Sopenharmony_ci{
258c2ecf20Sopenharmony_ci	if (test_tsk_thread_flag(tsk, TIF_32BIT_REGS))
268c2ecf20Sopenharmony_ci		return PERF_SAMPLE_REGS_ABI_32;
278c2ecf20Sopenharmony_ci	else
288c2ecf20Sopenharmony_ci		return PERF_SAMPLE_REGS_ABI_64;
298c2ecf20Sopenharmony_ci}
308c2ecf20Sopenharmony_ci#endif /* CONFIG_32BIT */
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ciint perf_reg_validate(u64 mask)
338c2ecf20Sopenharmony_ci{
348c2ecf20Sopenharmony_ci	if (!mask)
358c2ecf20Sopenharmony_ci		return -EINVAL;
368c2ecf20Sopenharmony_ci	if (mask & ~((1ull << PERF_REG_LOONGARCH_MAX) - 1))
378c2ecf20Sopenharmony_ci		return -EINVAL;
388c2ecf20Sopenharmony_ci	return 0;
398c2ecf20Sopenharmony_ci}
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ciu64 perf_reg_value(struct pt_regs *regs, int idx)
428c2ecf20Sopenharmony_ci{
438c2ecf20Sopenharmony_ci	if (WARN_ON_ONCE((u32)idx >= PERF_REG_LOONGARCH_MAX))
448c2ecf20Sopenharmony_ci		return 0;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	if ((u32)idx == PERF_REG_LOONGARCH_PC)
478c2ecf20Sopenharmony_ci		return regs->csr_era;
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	return regs->regs[idx];
508c2ecf20Sopenharmony_ci}
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_civoid perf_get_regs_user(struct perf_regs *regs_user,
538c2ecf20Sopenharmony_ci			struct pt_regs *regs)
548c2ecf20Sopenharmony_ci{
558c2ecf20Sopenharmony_ci	regs_user->regs = task_pt_regs(current);
568c2ecf20Sopenharmony_ci	regs_user->abi = perf_reg_abi(current);
578c2ecf20Sopenharmony_ci}
58