1 /* SPDX-License-Identifier: GPL-2.0 */ 2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 3 4 #ifndef __ASM_CSKY_PTRACE_H 5 #define __ASM_CSKY_PTRACE_H 6 7 #include <uapi/asm/ptrace.h> 8 #include <asm/traps.h> 9 #include <linux/types.h> 10 #include <linux/compiler.h> 11 12 #ifndef __ASSEMBLY__ 13 14 #define PS_S 0x80000000 /* Supervisor Mode */ 15 16 #define USR_BKPT 0x1464 17 18 #define arch_has_single_step() (1) 19 #define current_pt_regs() \ 20 ({ (struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1; }) 21 22 #define user_stack_pointer(regs) ((regs)->usp) 23 24 #define user_mode(regs) (!((regs)->sr & PS_S)) 25 #define instruction_pointer(regs) ((regs)->pc) 26 #define profile_pc(regs) instruction_pointer(regs) 27 #define trap_no(regs) ((regs->sr >> 16) & 0xff) 28 29 static inline void instruction_pointer_set(struct pt_regs *regs, 30 unsigned long val) 31 { 32 regs->pc = val; 33 } 34 35 #if defined(__CSKYABIV2__) 36 #define MAX_REG_OFFSET offsetof(struct pt_regs, dcsr) 37 #else 38 #define MAX_REG_OFFSET offsetof(struct pt_regs, regs[9]) 39 #endif 40 41 static inline bool in_syscall(struct pt_regs const *regs) 42 { 43 return ((regs->sr >> 16) & 0xff) == VEC_TRAP0; 44 } 45 46 static inline void forget_syscall(struct pt_regs *regs) 47 { 48 regs->sr &= ~(0xff << 16); 49 } 50 51 static inline unsigned long regs_return_value(struct pt_regs *regs) 52 { 53 return regs->a0; 54 } 55 56 static inline void regs_set_return_value(struct pt_regs *regs, 57 unsigned long val) 58 { 59 regs->a0 = val; 60 } 61 62 /* Valid only for Kernel mode traps. */ 63 static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) 64 { 65 return regs->usp; 66 } 67 68 static inline unsigned long frame_pointer(struct pt_regs *regs) 69 { 70 return regs->regs[4]; 71 } 72 static inline void frame_pointer_set(struct pt_regs *regs, 73 unsigned long val) 74 { 75 regs->regs[4] = val; 76 } 77 78 extern int regs_query_register_offset(const char *name); 79 extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, 80 unsigned int n); 81 82 /* 83 * regs_get_register() - get register value from its offset 84 * @regs: pt_regs from which register value is gotten 85 * @offset: offset of the register. 86 * 87 * regs_get_register returns the value of a register whose offset from @regs. 88 * The @offset is the offset of the register in struct pt_regs. 89 * If @offset is bigger than MAX_REG_OFFSET, this returns 0. 90 */ 91 static inline unsigned long regs_get_register(struct pt_regs *regs, 92 unsigned int offset) 93 { 94 if (unlikely(offset > MAX_REG_OFFSET)) 95 return 0; 96 97 return *(unsigned long *)((unsigned long)regs + offset); 98 } 99 100 #endif /* __ASSEMBLY__ */ 101 #endif /* __ASM_CSKY_PTRACE_H */ 102