1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * OpenRISC Linux
4  *
5  * Linux architectural port borrowing liberally from similar works of
6  * others.  All original copyrights apply as per the original source
7  * declaration.
8  *
9  * OpenRISC implementation:
10  * Copyright (C) 2003 Matjaz Breskvar <[email protected]>
11  * Copyright (C) 2010-2011 Jonas Bonn <[email protected]>
12  * et al.
13  */
14 #ifndef __ASM_OPENRISC_PTRACE_H
15 #define __ASM_OPENRISC_PTRACE_H
16 
17 
18 #include <asm/spr_defs.h>
19 #include <uapi/asm/ptrace.h>
20 #include <linux/compiler.h>
21 
22 /*
23  * Make kernel PTrace/register structures opaque to userspace... userspace can
24  * access thread state via the regset mechanism.  This allows us a bit of
25  * flexibility in how we order the registers on the stack, permitting some
26  * optimizations like packing call-clobbered registers together so that
27  * they share a cacheline (not done yet, though... future optimization).
28  */
29 
30 #ifndef __ASSEMBLY__
31 /*
32  * This struct describes how the registers are laid out on the kernel stack
33  * during a syscall or other kernel entry.
34  *
35  * This structure should always be cacheline aligned on the stack.
36  * FIXME: I don't think that's the case right now.  The alignment is
37  * taken care of elsewhere... head.S, process.c, etc.
38  */
39 
40 struct pt_regs {
41 	union {
42 		struct {
43 			/* Named registers */
44 			long  sr;	/* Stored in place of r0 */
45 			long  sp;	/* r1 */
46 			long  gpr2;
47 			long  gpr3;
48 			long  gpr4;
49 			long  gpr5;
50 			long  gpr6;
51 			long  gpr7;
52 			long  gpr8;
53 			long  gpr9;
54 			long  gpr10;
55 			long  gpr11;
56 			long  gpr12;
57 			long  gpr13;
58 			long  gpr14;
59 			long  gpr15;
60 			long  gpr16;
61 			long  gpr17;
62 			long  gpr18;
63 			long  gpr19;
64 			long  gpr20;
65 			long  gpr21;
66 			long  gpr22;
67 			long  gpr23;
68 			long  gpr24;
69 			long  gpr25;
70 			long  gpr26;
71 			long  gpr27;
72 			long  gpr28;
73 			long  gpr29;
74 			long  gpr30;
75 			long  gpr31;
76 		};
77 		struct {
78 			/* Old style */
79 			long offset[2];
80 			long gprs[30];
81 		};
82 		struct {
83 			/* New style */
84 			long gpr[32];
85 		};
86 	};
87 	long  pc;
88 	/* For restarting system calls:
89 	 * Set to syscall number for syscall exceptions,
90 	 * -1 for all other exceptions.
91 	 */
92 	long  orig_gpr11;	/* For restarting system calls */
93 	long dummy;		/* Cheap alignment fix */
94 	long dummy2;		/* Cheap alignment fix */
95 };
96 
97 /* TODO: Rename this to REDZONE because that's what it is */
98 #define STACK_FRAME_OVERHEAD  128  /* size of minimum stack frame */
99 
100 #define MAX_REG_OFFSET offsetof(struct pt_regs, orig_gpr11)
101 
102 /* Helpers for working with the instruction pointer */
instruction_pointer(struct pt_regs * regs)103 static inline unsigned long instruction_pointer(struct pt_regs *regs)
104 {
105 	return (unsigned long)regs->pc;
106 }
instruction_pointer_set(struct pt_regs * regs,unsigned long val)107 static inline void instruction_pointer_set(struct pt_regs *regs,
108 					   unsigned long val)
109 {
110 	regs->pc = val;
111 }
112 
113 #define user_mode(regs)			(((regs)->sr & SPR_SR_SM) == 0)
114 #define user_stack_pointer(regs)	((unsigned long)(regs)->sp)
115 #define profile_pc(regs)		instruction_pointer(regs)
116 
117 /* Valid only for Kernel mode traps. */
kernel_stack_pointer(struct pt_regs * regs)118 static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
119 {
120 	return (unsigned long)regs->sp;
121 }
122 
regs_return_value(struct pt_regs * regs)123 static inline long regs_return_value(struct pt_regs *regs)
124 {
125 	return regs->gpr[11];
126 }
127 
128 extern int regs_query_register_offset(const char *name);
129 extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
130 					       unsigned int n);
131 
132 /**
133  * regs_get_register() - get register value from its offset
134  * @regs:	pt_regs from which register value is gotten
135  * @offset:	offset of the register.
136  *
137  * regs_get_register returns the value of a register whose offset from @regs.
138  * The @offset is the offset of the register in struct pt_regs.
139  * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
140  */
regs_get_register(struct pt_regs * regs,unsigned int offset)141 static inline unsigned long regs_get_register(struct pt_regs *regs,
142 					      unsigned int offset)
143 {
144 	if (unlikely(offset > MAX_REG_OFFSET))
145 		return 0;
146 
147 	return *(unsigned long *)((unsigned long)regs + offset);
148 }
149 
150 #endif /* __ASSEMBLY__ */
151 
152 /*
153  * Offsets used by 'ptrace' system call interface.
154  */
155 #define PT_SR         0
156 #define PT_SP         4
157 #define PT_GPR2       8
158 #define PT_GPR3       12
159 #define PT_GPR4       16
160 #define PT_GPR5       20
161 #define PT_GPR6       24
162 #define PT_GPR7       28
163 #define PT_GPR8       32
164 #define PT_GPR9       36
165 #define PT_GPR10      40
166 #define PT_GPR11      44
167 #define PT_GPR12      48
168 #define PT_GPR13      52
169 #define PT_GPR14      56
170 #define PT_GPR15      60
171 #define PT_GPR16      64
172 #define PT_GPR17      68
173 #define PT_GPR18      72
174 #define PT_GPR19      76
175 #define PT_GPR20      80
176 #define PT_GPR21      84
177 #define PT_GPR22      88
178 #define PT_GPR23      92
179 #define PT_GPR24      96
180 #define PT_GPR25      100
181 #define PT_GPR26      104
182 #define PT_GPR27      108
183 #define PT_GPR28      112
184 #define PT_GPR29      116
185 #define PT_GPR30      120
186 #define PT_GPR31      124
187 #define PT_PC	      128
188 #define PT_ORIG_GPR11 132
189 
190 #endif /* __ASM_OPENRISC_PTRACE_H */
191