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