1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
4 */
5
6#ifndef _ASM_ARC_UNWIND_H
7#define _ASM_ARC_UNWIND_H
8
9#ifdef CONFIG_ARC_DW2_UNWIND
10
11#include <linux/sched.h>
12
13struct arc700_regs {
14	unsigned long r0;
15	unsigned long r1;
16	unsigned long r2;
17	unsigned long r3;
18	unsigned long r4;
19	unsigned long r5;
20	unsigned long r6;
21	unsigned long r7;
22	unsigned long r8;
23	unsigned long r9;
24	unsigned long r10;
25	unsigned long r11;
26	unsigned long r12;
27	unsigned long r13;
28	unsigned long r14;
29	unsigned long r15;
30	unsigned long r16;
31	unsigned long r17;
32	unsigned long r18;
33	unsigned long r19;
34	unsigned long r20;
35	unsigned long r21;
36	unsigned long r22;
37	unsigned long r23;
38	unsigned long r24;
39	unsigned long r25;
40	unsigned long r26;
41	unsigned long r27;	/* fp */
42	unsigned long r28;	/* sp */
43	unsigned long r29;
44	unsigned long r30;
45	unsigned long r31;	/* blink */
46	unsigned long r63;	/* pc */
47};
48
49struct unwind_frame_info {
50	struct arc700_regs regs;
51	struct task_struct *task;
52	unsigned call_frame:1;
53};
54
55#define UNW_PC(frame)		((frame)->regs.r63)
56#define UNW_SP(frame)		((frame)->regs.r28)
57#define UNW_BLINK(frame)	((frame)->regs.r31)
58
59/* Rajesh FIXME */
60#ifdef CONFIG_FRAME_POINTER
61#define UNW_FP(frame)		((frame)->regs.r27)
62#define FRAME_RETADDR_OFFSET	4
63#define FRAME_LINK_OFFSET	0
64#define STACK_BOTTOM_UNW(tsk)	STACK_LIMIT((tsk)->thread.ksp)
65#define STACK_TOP_UNW(tsk)	((tsk)->thread.ksp)
66#else
67#define UNW_FP(frame)		((void)(frame), 0)
68#endif
69
70#define STACK_LIMIT(ptr)	(((ptr) - 1) & ~(THREAD_SIZE - 1))
71
72#define UNW_REGISTER_INFO \
73	PTREGS_INFO(r0), \
74	PTREGS_INFO(r1), \
75	PTREGS_INFO(r2), \
76	PTREGS_INFO(r3), \
77	PTREGS_INFO(r4), \
78	PTREGS_INFO(r5), \
79	PTREGS_INFO(r6), \
80	PTREGS_INFO(r7), \
81	PTREGS_INFO(r8), \
82	PTREGS_INFO(r9), \
83	PTREGS_INFO(r10), \
84	PTREGS_INFO(r11), \
85	PTREGS_INFO(r12), \
86	PTREGS_INFO(r13), \
87	PTREGS_INFO(r14), \
88	PTREGS_INFO(r15), \
89	PTREGS_INFO(r16), \
90	PTREGS_INFO(r17), \
91	PTREGS_INFO(r18), \
92	PTREGS_INFO(r19), \
93	PTREGS_INFO(r20), \
94	PTREGS_INFO(r21), \
95	PTREGS_INFO(r22), \
96	PTREGS_INFO(r23), \
97	PTREGS_INFO(r24), \
98	PTREGS_INFO(r25), \
99	PTREGS_INFO(r26), \
100	PTREGS_INFO(r27), \
101	PTREGS_INFO(r28), \
102	PTREGS_INFO(r29), \
103	PTREGS_INFO(r30), \
104	PTREGS_INFO(r31), \
105	PTREGS_INFO(r63)
106
107#define UNW_DEFAULT_RA(raItem, dataAlign) \
108	((raItem).where == Memory && !((raItem).value * (dataAlign) + 4))
109
110extern int arc_unwind(struct unwind_frame_info *frame);
111extern void arc_unwind_init(void);
112extern void *unwind_add_table(struct module *module, const void *table_start,
113			      unsigned long table_size);
114extern void unwind_remove_table(void *handle, int init_only);
115
116static inline int
117arch_unwind_init_running(struct unwind_frame_info *info,
118			 int (*callback) (struct unwind_frame_info *info,
119					  void *arg),
120			 void *arg)
121{
122	return 0;
123}
124
125static inline int arch_unw_user_mode(const struct unwind_frame_info *info)
126{
127	return 0;
128}
129
130static inline void arch_unw_init_blocked(struct unwind_frame_info *info)
131{
132	return;
133}
134
135static inline void arch_unw_init_frame_info(struct unwind_frame_info *info,
136					    struct pt_regs *regs)
137{
138	return;
139}
140
141#else
142
143#define UNW_PC(frame) ((void)(frame), 0)
144#define UNW_SP(frame) ((void)(frame), 0)
145#define UNW_FP(frame) ((void)(frame), 0)
146
147static inline void arc_unwind_init(void)
148{
149}
150
151#define unwind_add_table(a, b, c)
152#define unwind_remove_table(a, b)
153
154#endif /* CONFIG_ARC_DW2_UNWIND */
155
156#endif /* _ASM_ARC_UNWIND_H */
157