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