162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#include <errno.h> 362306a36Sopenharmony_ci#include <string.h> 462306a36Sopenharmony_ci#include "perf_regs.h" 562306a36Sopenharmony_ci#include "util/sample.h" 662306a36Sopenharmony_ci#include "debug.h" 762306a36Sopenharmony_ci 862306a36Sopenharmony_ciint __weak arch_sdt_arg_parse_op(char *old_op __maybe_unused, 962306a36Sopenharmony_ci char **new_op __maybe_unused) 1062306a36Sopenharmony_ci{ 1162306a36Sopenharmony_ci return SDT_ARG_SKIP; 1262306a36Sopenharmony_ci} 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ciuint64_t __weak arch__intr_reg_mask(void) 1562306a36Sopenharmony_ci{ 1662306a36Sopenharmony_ci return 0; 1762306a36Sopenharmony_ci} 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ciuint64_t __weak arch__user_reg_mask(void) 2062306a36Sopenharmony_ci{ 2162306a36Sopenharmony_ci return 0; 2262306a36Sopenharmony_ci} 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#ifdef HAVE_PERF_REGS_SUPPORT 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ciconst char *perf_reg_name(int id, const char *arch) 2762306a36Sopenharmony_ci{ 2862306a36Sopenharmony_ci const char *reg_name = NULL; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci if (!strcmp(arch, "csky")) 3162306a36Sopenharmony_ci reg_name = __perf_reg_name_csky(id); 3262306a36Sopenharmony_ci else if (!strcmp(arch, "loongarch")) 3362306a36Sopenharmony_ci reg_name = __perf_reg_name_loongarch(id); 3462306a36Sopenharmony_ci else if (!strcmp(arch, "mips")) 3562306a36Sopenharmony_ci reg_name = __perf_reg_name_mips(id); 3662306a36Sopenharmony_ci else if (!strcmp(arch, "powerpc")) 3762306a36Sopenharmony_ci reg_name = __perf_reg_name_powerpc(id); 3862306a36Sopenharmony_ci else if (!strcmp(arch, "riscv")) 3962306a36Sopenharmony_ci reg_name = __perf_reg_name_riscv(id); 4062306a36Sopenharmony_ci else if (!strcmp(arch, "s390")) 4162306a36Sopenharmony_ci reg_name = __perf_reg_name_s390(id); 4262306a36Sopenharmony_ci else if (!strcmp(arch, "x86")) 4362306a36Sopenharmony_ci reg_name = __perf_reg_name_x86(id); 4462306a36Sopenharmony_ci else if (!strcmp(arch, "arm")) 4562306a36Sopenharmony_ci reg_name = __perf_reg_name_arm(id); 4662306a36Sopenharmony_ci else if (!strcmp(arch, "arm64")) 4762306a36Sopenharmony_ci reg_name = __perf_reg_name_arm64(id); 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci return reg_name ?: "unknown"; 5062306a36Sopenharmony_ci} 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ciint perf_reg_value(u64 *valp, struct regs_dump *regs, int id) 5362306a36Sopenharmony_ci{ 5462306a36Sopenharmony_ci int i, idx = 0; 5562306a36Sopenharmony_ci u64 mask = regs->mask; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci if ((u64)id >= PERF_SAMPLE_REGS_CACHE_SIZE) 5862306a36Sopenharmony_ci return -EINVAL; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci if (regs->cache_mask & (1ULL << id)) 6162306a36Sopenharmony_ci goto out; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci if (!(mask & (1ULL << id))) 6462306a36Sopenharmony_ci return -EINVAL; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci for (i = 0; i < id; i++) { 6762306a36Sopenharmony_ci if (mask & (1ULL << i)) 6862306a36Sopenharmony_ci idx++; 6962306a36Sopenharmony_ci } 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci regs->cache_mask |= (1ULL << id); 7262306a36Sopenharmony_ci regs->cache_regs[id] = regs->regs[idx]; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ciout: 7562306a36Sopenharmony_ci *valp = regs->cache_regs[id]; 7662306a36Sopenharmony_ci return 0; 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ciuint64_t perf_arch_reg_ip(const char *arch) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci if (!strcmp(arch, "arm")) 8262306a36Sopenharmony_ci return __perf_reg_ip_arm(); 8362306a36Sopenharmony_ci else if (!strcmp(arch, "arm64")) 8462306a36Sopenharmony_ci return __perf_reg_ip_arm64(); 8562306a36Sopenharmony_ci else if (!strcmp(arch, "csky")) 8662306a36Sopenharmony_ci return __perf_reg_ip_csky(); 8762306a36Sopenharmony_ci else if (!strcmp(arch, "loongarch")) 8862306a36Sopenharmony_ci return __perf_reg_ip_loongarch(); 8962306a36Sopenharmony_ci else if (!strcmp(arch, "mips")) 9062306a36Sopenharmony_ci return __perf_reg_ip_mips(); 9162306a36Sopenharmony_ci else if (!strcmp(arch, "powerpc")) 9262306a36Sopenharmony_ci return __perf_reg_ip_powerpc(); 9362306a36Sopenharmony_ci else if (!strcmp(arch, "riscv")) 9462306a36Sopenharmony_ci return __perf_reg_ip_riscv(); 9562306a36Sopenharmony_ci else if (!strcmp(arch, "s390")) 9662306a36Sopenharmony_ci return __perf_reg_ip_s390(); 9762306a36Sopenharmony_ci else if (!strcmp(arch, "x86")) 9862306a36Sopenharmony_ci return __perf_reg_ip_x86(); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci pr_err("Fail to find IP register for arch %s, returns 0\n", arch); 10162306a36Sopenharmony_ci return 0; 10262306a36Sopenharmony_ci} 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ciuint64_t perf_arch_reg_sp(const char *arch) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci if (!strcmp(arch, "arm")) 10762306a36Sopenharmony_ci return __perf_reg_sp_arm(); 10862306a36Sopenharmony_ci else if (!strcmp(arch, "arm64")) 10962306a36Sopenharmony_ci return __perf_reg_sp_arm64(); 11062306a36Sopenharmony_ci else if (!strcmp(arch, "csky")) 11162306a36Sopenharmony_ci return __perf_reg_sp_csky(); 11262306a36Sopenharmony_ci else if (!strcmp(arch, "loongarch")) 11362306a36Sopenharmony_ci return __perf_reg_sp_loongarch(); 11462306a36Sopenharmony_ci else if (!strcmp(arch, "mips")) 11562306a36Sopenharmony_ci return __perf_reg_sp_mips(); 11662306a36Sopenharmony_ci else if (!strcmp(arch, "powerpc")) 11762306a36Sopenharmony_ci return __perf_reg_sp_powerpc(); 11862306a36Sopenharmony_ci else if (!strcmp(arch, "riscv")) 11962306a36Sopenharmony_ci return __perf_reg_sp_riscv(); 12062306a36Sopenharmony_ci else if (!strcmp(arch, "s390")) 12162306a36Sopenharmony_ci return __perf_reg_sp_s390(); 12262306a36Sopenharmony_ci else if (!strcmp(arch, "x86")) 12362306a36Sopenharmony_ci return __perf_reg_sp_x86(); 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci pr_err("Fail to find SP register for arch %s, returns 0\n", arch); 12662306a36Sopenharmony_ci return 0; 12762306a36Sopenharmony_ci} 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci#endif 130