18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#ifndef __ASM_CSKY_PTRACE_H 58c2ecf20Sopenharmony_ci#define __ASM_CSKY_PTRACE_H 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <uapi/asm/ptrace.h> 88c2ecf20Sopenharmony_ci#include <asm/traps.h> 98c2ecf20Sopenharmony_ci#include <linux/types.h> 108c2ecf20Sopenharmony_ci#include <linux/compiler.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#define PS_S 0x80000000 /* Supervisor Mode */ 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#define USR_BKPT 0x1464 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#define arch_has_single_step() (1) 198c2ecf20Sopenharmony_ci#define current_pt_regs() \ 208c2ecf20Sopenharmony_ci({ (struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1; }) 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#define user_stack_pointer(regs) ((regs)->usp) 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define user_mode(regs) (!((regs)->sr & PS_S)) 258c2ecf20Sopenharmony_ci#define instruction_pointer(regs) ((regs)->pc) 268c2ecf20Sopenharmony_ci#define profile_pc(regs) instruction_pointer(regs) 278c2ecf20Sopenharmony_ci#define trap_no(regs) ((regs->sr >> 16) & 0xff) 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistatic inline void instruction_pointer_set(struct pt_regs *regs, 308c2ecf20Sopenharmony_ci unsigned long val) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci regs->pc = val; 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#if defined(__CSKYABIV2__) 368c2ecf20Sopenharmony_ci#define MAX_REG_OFFSET offsetof(struct pt_regs, dcsr) 378c2ecf20Sopenharmony_ci#else 388c2ecf20Sopenharmony_ci#define MAX_REG_OFFSET offsetof(struct pt_regs, regs[9]) 398c2ecf20Sopenharmony_ci#endif 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic inline bool in_syscall(struct pt_regs const *regs) 428c2ecf20Sopenharmony_ci{ 438c2ecf20Sopenharmony_ci return ((regs->sr >> 16) & 0xff) == VEC_TRAP0; 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic inline void forget_syscall(struct pt_regs *regs) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci regs->sr &= ~(0xff << 16); 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cistatic inline unsigned long regs_return_value(struct pt_regs *regs) 528c2ecf20Sopenharmony_ci{ 538c2ecf20Sopenharmony_ci return regs->a0; 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic inline void regs_set_return_value(struct pt_regs *regs, 578c2ecf20Sopenharmony_ci unsigned long val) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci regs->a0 = val; 608c2ecf20Sopenharmony_ci} 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci/* Valid only for Kernel mode traps. */ 638c2ecf20Sopenharmony_cistatic inline unsigned long kernel_stack_pointer(struct pt_regs *regs) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci return regs->usp; 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cistatic inline unsigned long frame_pointer(struct pt_regs *regs) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci return regs->regs[4]; 718c2ecf20Sopenharmony_ci} 728c2ecf20Sopenharmony_cistatic inline void frame_pointer_set(struct pt_regs *regs, 738c2ecf20Sopenharmony_ci unsigned long val) 748c2ecf20Sopenharmony_ci{ 758c2ecf20Sopenharmony_ci regs->regs[4] = val; 768c2ecf20Sopenharmony_ci} 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ciextern int regs_query_register_offset(const char *name); 798c2ecf20Sopenharmony_ciextern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, 808c2ecf20Sopenharmony_ci unsigned int n); 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci/* 838c2ecf20Sopenharmony_ci * regs_get_register() - get register value from its offset 848c2ecf20Sopenharmony_ci * @regs: pt_regs from which register value is gotten 858c2ecf20Sopenharmony_ci * @offset: offset of the register. 868c2ecf20Sopenharmony_ci * 878c2ecf20Sopenharmony_ci * regs_get_register returns the value of a register whose offset from @regs. 888c2ecf20Sopenharmony_ci * The @offset is the offset of the register in struct pt_regs. 898c2ecf20Sopenharmony_ci * If @offset is bigger than MAX_REG_OFFSET, this returns 0. 908c2ecf20Sopenharmony_ci */ 918c2ecf20Sopenharmony_cistatic inline unsigned long regs_get_register(struct pt_regs *regs, 928c2ecf20Sopenharmony_ci unsigned int offset) 938c2ecf20Sopenharmony_ci{ 948c2ecf20Sopenharmony_ci if (unlikely(offset > MAX_REG_OFFSET)) 958c2ecf20Sopenharmony_ci return 0; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci return *(unsigned long *)((unsigned long)regs + offset); 988c2ecf20Sopenharmony_ci} 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */ 1018c2ecf20Sopenharmony_ci#endif /* __ASM_CSKY_PTRACE_H */ 102