Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[linux-drm-fsl-dcu.git] / arch / sparc / kernel / kgdb_64.c
1 /* kgdb.c: KGDB support for 64-bit sparc.
2  *
3  * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
4  */
5
6 #include <linux/kgdb.h>
7 #include <linux/kdebug.h>
8 #include <linux/ftrace.h>
9 #include <linux/context_tracking.h>
10
11 #include <asm/cacheflush.h>
12 #include <asm/kdebug.h>
13 #include <asm/ptrace.h>
14 #include <asm/irq.h>
15
16 void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
17 {
18         struct reg_window *win;
19         int i;
20
21         gdb_regs[GDB_G0] = 0;
22         for (i = 0; i < 15; i++)
23                 gdb_regs[GDB_G1 + i] = regs->u_regs[UREG_G1 + i];
24
25         win = (struct reg_window *) (regs->u_regs[UREG_FP] + STACK_BIAS);
26         for (i = 0; i < 8; i++)
27                 gdb_regs[GDB_L0 + i] = win->locals[i];
28         for (i = 0; i < 8; i++)
29                 gdb_regs[GDB_I0 + i] = win->ins[i];
30
31         for (i = GDB_F0; i <= GDB_F62; i++)
32                 gdb_regs[i] = 0;
33
34         gdb_regs[GDB_PC] = regs->tpc;
35         gdb_regs[GDB_NPC] = regs->tnpc;
36         gdb_regs[GDB_STATE] = regs->tstate;
37         gdb_regs[GDB_FSR] = 0;
38         gdb_regs[GDB_FPRS] = 0;
39         gdb_regs[GDB_Y] = regs->y;
40 }
41
42 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
43 {
44         struct thread_info *t = task_thread_info(p);
45         extern unsigned int switch_to_pc;
46         extern unsigned int ret_from_fork;
47         struct reg_window *win;
48         unsigned long pc, cwp;
49         int i;
50
51         for (i = GDB_G0; i < GDB_G6; i++)
52                 gdb_regs[i] = 0;
53         gdb_regs[GDB_G6] = (unsigned long) t;
54         gdb_regs[GDB_G7] = (unsigned long) p;
55         for (i = GDB_O0; i < GDB_SP; i++)
56                 gdb_regs[i] = 0;
57         gdb_regs[GDB_SP] = t->ksp;
58         gdb_regs[GDB_O7] = 0;
59
60         win = (struct reg_window *) (t->ksp + STACK_BIAS);
61         for (i = 0; i < 8; i++)
62                 gdb_regs[GDB_L0 + i] = win->locals[i];
63         for (i = 0; i < 8; i++)
64                 gdb_regs[GDB_I0 + i] = win->ins[i];
65
66         for (i = GDB_F0; i <= GDB_F62; i++)
67                 gdb_regs[i] = 0;
68
69         if (t->new_child)
70                 pc = (unsigned long) &ret_from_fork;
71         else
72                 pc = (unsigned long) &switch_to_pc;
73
74         gdb_regs[GDB_PC] = pc;
75         gdb_regs[GDB_NPC] = pc + 4;
76
77         cwp = __thread_flag_byte_ptr(t)[TI_FLAG_BYTE_CWP];
78
79         gdb_regs[GDB_STATE] = (TSTATE_PRIV | TSTATE_IE | cwp);
80         gdb_regs[GDB_FSR] = 0;
81         gdb_regs[GDB_FPRS] = 0;
82         gdb_regs[GDB_Y] = 0;
83 }
84
85 void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
86 {
87         struct reg_window *win;
88         int i;
89
90         for (i = 0; i < 15; i++)
91                 regs->u_regs[UREG_G1 + i] = gdb_regs[GDB_G1 + i];
92
93         /* If the TSTATE register is changing, we have to preserve
94          * the CWP field, otherwise window save/restore explodes.
95          */
96         if (regs->tstate != gdb_regs[GDB_STATE]) {
97                 unsigned long cwp = regs->tstate & TSTATE_CWP;
98
99                 regs->tstate = (gdb_regs[GDB_STATE] & ~TSTATE_CWP) | cwp;
100         }
101
102         regs->tpc = gdb_regs[GDB_PC];
103         regs->tnpc = gdb_regs[GDB_NPC];
104         regs->y = gdb_regs[GDB_Y];
105
106         win = (struct reg_window *) (regs->u_regs[UREG_FP] + STACK_BIAS);
107         for (i = 0; i < 8; i++)
108                 win->locals[i] = gdb_regs[GDB_L0 + i];
109         for (i = 0; i < 8; i++)
110                 win->ins[i] = gdb_regs[GDB_I0 + i];
111 }
112
113 #ifdef CONFIG_SMP
114 void __irq_entry smp_kgdb_capture_client(int irq, struct pt_regs *regs)
115 {
116         unsigned long flags;
117
118         __asm__ __volatile__("rdpr      %%pstate, %0\n\t"
119                              "wrpr      %0, %1, %%pstate"
120                              : "=r" (flags)
121                              : "i" (PSTATE_IE));
122
123         flushw_all();
124
125         if (atomic_read(&kgdb_active) != -1)
126                 kgdb_nmicallback(raw_smp_processor_id(), regs);
127
128         __asm__ __volatile__("wrpr      %0, 0, %%pstate"
129                              : : "r" (flags));
130 }
131 #endif
132
133 int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
134                                char *remcomInBuffer, char *remcomOutBuffer,
135                                struct pt_regs *linux_regs)
136 {
137         unsigned long addr;
138         char *ptr;
139
140         switch (remcomInBuffer[0]) {
141         case 'c':
142                 /* try to read optional parameter, pc unchanged if no parm */
143                 ptr = &remcomInBuffer[1];
144                 if (kgdb_hex2long(&ptr, &addr)) {
145                         linux_regs->tpc = addr;
146                         linux_regs->tnpc = addr + 4;
147                 }
148                 /* fallthru */
149
150         case 'D':
151         case 'k':
152                 if (linux_regs->tpc == (unsigned long) arch_kgdb_breakpoint) {
153                         linux_regs->tpc = linux_regs->tnpc;
154                         linux_regs->tnpc += 4;
155                 }
156                 return 0;
157         }
158         return -1;
159 }
160
161 asmlinkage void kgdb_trap(unsigned long trap_level, struct pt_regs *regs)
162 {
163         enum ctx_state prev_state = exception_enter();
164         unsigned long flags;
165
166         if (user_mode(regs)) {
167                 bad_trap(regs, trap_level);
168                 goto out;
169         }
170
171         flushw_all();
172
173         local_irq_save(flags);
174         kgdb_handle_exception(0x172, SIGTRAP, 0, regs);
175         local_irq_restore(flags);
176 out:
177         exception_exit(prev_state);
178 }
179
180 int kgdb_arch_init(void)
181 {
182         return 0;
183 }
184
185 void kgdb_arch_exit(void)
186 {
187 }
188
189 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
190 {
191         regs->tpc = ip;
192         regs->tnpc = regs->tpc + 4;
193 }
194
195 struct kgdb_arch arch_kgdb_ops = {
196         /* Breakpoint instruction: ta 0x72 */
197         .gdb_bpt_instr          = { 0x91, 0xd0, 0x20, 0x72 },
198 };