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