1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org>
9 #include <linux/kgdb.h>
10 #include <linux/string.h>
11 #include <linux/sched.h>
12 #include <linux/notifier.h>
13 #include <linux/kdebug.h>
14 #include <linux/uaccess.h>
15 #include <asm/ptrace.h>
16 #include <asm/traps.h>
17 #include <asm/processor.h>
18 #include <asm/patch.h>
19 #include <asm/cacheflush.h>
21 const struct kgdb_arch arch_kgdb_ops
= {
22 .gdb_bpt_instr
= { 0x03, 0xff, 0xa0, 0x1f }
25 static int __kgdb_notify(struct die_args
*args
, unsigned long cmd
)
27 struct pt_regs
*regs
= args
->regs
;
29 if (kgdb_handle_exception(1, args
->signr
, cmd
, regs
))
34 static int kgdb_notify(struct notifier_block
*self
,
35 unsigned long cmd
, void *ptr
)
40 local_irq_save(flags
);
41 ret
= __kgdb_notify(ptr
, cmd
);
42 local_irq_restore(flags
);
47 static struct notifier_block kgdb_notifier
= {
48 .notifier_call
= kgdb_notify
,
52 int kgdb_arch_init(void)
54 return register_die_notifier(&kgdb_notifier
);
57 void kgdb_arch_exit(void)
59 unregister_die_notifier(&kgdb_notifier
);
62 void pt_regs_to_gdb_regs(unsigned long *gdb_regs
, struct pt_regs
*regs
)
64 struct parisc_gdb_regs
*gr
= (struct parisc_gdb_regs
*)gdb_regs
;
66 memset(gr
, 0, sizeof(struct parisc_gdb_regs
));
68 memcpy(gr
->gpr
, regs
->gr
, sizeof(gr
->gpr
));
69 memcpy(gr
->fr
, regs
->fr
, sizeof(gr
->fr
));
71 gr
->sr0
= regs
->sr
[0];
72 gr
->sr1
= regs
->sr
[1];
73 gr
->sr2
= regs
->sr
[2];
74 gr
->sr3
= regs
->sr
[3];
75 gr
->sr4
= regs
->sr
[4];
76 gr
->sr5
= regs
->sr
[5];
77 gr
->sr6
= regs
->sr
[6];
78 gr
->sr7
= regs
->sr
[7];
84 gr
->ipsw
= regs
->ipsw
;
85 gr
->cr27
= regs
->cr27
;
87 gr
->iaoq_f
= regs
->iaoq
[0];
88 gr
->iasq_f
= regs
->iasq
[0];
90 gr
->iaoq_b
= regs
->iaoq
[1];
91 gr
->iasq_b
= regs
->iasq
[1];
94 void gdb_regs_to_pt_regs(unsigned long *gdb_regs
, struct pt_regs
*regs
)
96 struct parisc_gdb_regs
*gr
= (struct parisc_gdb_regs
*)gdb_regs
;
99 memcpy(regs
->gr
, gr
->gpr
, sizeof(regs
->gr
));
100 memcpy(regs
->fr
, gr
->fr
, sizeof(regs
->fr
));
102 regs
->sr
[0] = gr
->sr0
;
103 regs
->sr
[1] = gr
->sr1
;
104 regs
->sr
[2] = gr
->sr2
;
105 regs
->sr
[3] = gr
->sr3
;
106 regs
->sr
[4] = gr
->sr4
;
107 regs
->sr
[5] = gr
->sr5
;
108 regs
->sr
[6] = gr
->sr6
;
109 regs
->sr
[7] = gr
->sr7
;
115 regs
->ipsw
= gr
->ipsw
;
116 regs
->cr27
= gr
->cr27
;
118 regs
->iaoq
[0] = gr
->iaoq_f
;
119 regs
->iasq
[0] = gr
->iasq_f
;
121 regs
->iaoq
[1] = gr
->iaoq_b
;
122 regs
->iasq
[1] = gr
->iasq_b
;
125 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs
,
126 struct task_struct
*task
)
128 struct pt_regs
*regs
= task_pt_regs(task
);
129 unsigned long gr30
, iaoq
;
132 iaoq
= regs
->iaoq
[0];
134 regs
->gr
[30] = regs
->ksp
;
135 regs
->iaoq
[0] = regs
->kpc
;
136 pt_regs_to_gdb_regs(gdb_regs
, regs
);
139 regs
->iaoq
[0] = iaoq
;
143 static void step_instruction_queue(struct pt_regs
*regs
)
145 regs
->iaoq
[0] = regs
->iaoq
[1];
149 void kgdb_arch_set_pc(struct pt_regs
*regs
, unsigned long ip
)
152 regs
->iaoq
[1] = ip
+ 4;
155 int kgdb_arch_set_breakpoint(struct kgdb_bkpt
*bpt
)
157 int ret
= copy_from_kernel_nofault(bpt
->saved_instr
,
158 (char *)bpt
->bpt_addr
, BREAK_INSTR_SIZE
);
162 __patch_text((void *)bpt
->bpt_addr
,
163 *(unsigned int *)&arch_kgdb_ops
.gdb_bpt_instr
);
167 int kgdb_arch_remove_breakpoint(struct kgdb_bkpt
*bpt
)
169 __patch_text((void *)bpt
->bpt_addr
, *(unsigned int *)&bpt
->saved_instr
);
173 int kgdb_arch_handle_exception(int trap
, int signo
,
174 int err_code
, char *inbuf
, char *outbuf
,
175 struct pt_regs
*regs
)
184 kgdb_contthread
= NULL
;
185 kgdb_single_step
= 0;
187 if (kgdb_hex2long(&p
, &addr
))
188 kgdb_arch_set_pc(regs
, addr
);
189 else if (trap
== 9 && regs
->iir
==
190 PARISC_KGDB_COMPILED_BREAK_INSN
)
191 step_instruction_queue(regs
);
194 kgdb_single_step
= 1;
195 if (kgdb_hex2long(&p
, &addr
)) {
196 kgdb_arch_set_pc(regs
, addr
);
197 } else if (trap
== 9 && regs
->iir
==
198 PARISC_KGDB_COMPILED_BREAK_INSN
) {
199 step_instruction_queue(regs
);
204 regs
->gr
[0] |= PSW_R
;