1eacbfce1SSven Schnelle // SPDX-License-Identifier: GPL-2.0 2eacbfce1SSven Schnelle /* 3eacbfce1SSven Schnelle * PA-RISC KGDB support 4eacbfce1SSven Schnelle * 5eacbfce1SSven Schnelle * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org> 6*c1c72d9bSHelge Deller * Copyright (c) 2022 Helge Deller <deller@gmx.de> 7eacbfce1SSven Schnelle * 8eacbfce1SSven Schnelle */ 9eacbfce1SSven Schnelle 10eacbfce1SSven Schnelle #include <linux/kgdb.h> 11eacbfce1SSven Schnelle #include <linux/string.h> 12eacbfce1SSven Schnelle #include <linux/sched.h> 13eacbfce1SSven Schnelle #include <linux/notifier.h> 14eacbfce1SSven Schnelle #include <linux/kdebug.h> 15eacbfce1SSven Schnelle #include <linux/uaccess.h> 16eacbfce1SSven Schnelle #include <asm/ptrace.h> 17eacbfce1SSven Schnelle #include <asm/traps.h> 18eacbfce1SSven Schnelle #include <asm/processor.h> 19eacbfce1SSven Schnelle #include <asm/patch.h> 20eacbfce1SSven Schnelle #include <asm/cacheflush.h> 21eacbfce1SSven Schnelle 22eacbfce1SSven Schnelle const struct kgdb_arch arch_kgdb_ops = { 23eacbfce1SSven Schnelle .gdb_bpt_instr = { 0x03, 0xff, 0xa0, 0x1f } 24eacbfce1SSven Schnelle }; 25eacbfce1SSven Schnelle 26eacbfce1SSven Schnelle static int __kgdb_notify(struct die_args *args, unsigned long cmd) 27eacbfce1SSven Schnelle { 28eacbfce1SSven Schnelle struct pt_regs *regs = args->regs; 29eacbfce1SSven Schnelle 30eacbfce1SSven Schnelle if (kgdb_handle_exception(1, args->signr, cmd, regs)) 31eacbfce1SSven Schnelle return NOTIFY_DONE; 32eacbfce1SSven Schnelle return NOTIFY_STOP; 33eacbfce1SSven Schnelle } 34eacbfce1SSven Schnelle 35eacbfce1SSven Schnelle static int kgdb_notify(struct notifier_block *self, 36eacbfce1SSven Schnelle unsigned long cmd, void *ptr) 37eacbfce1SSven Schnelle { 38eacbfce1SSven Schnelle unsigned long flags; 39eacbfce1SSven Schnelle int ret; 40eacbfce1SSven Schnelle 41eacbfce1SSven Schnelle local_irq_save(flags); 42eacbfce1SSven Schnelle ret = __kgdb_notify(ptr, cmd); 43eacbfce1SSven Schnelle local_irq_restore(flags); 44eacbfce1SSven Schnelle 45eacbfce1SSven Schnelle return ret; 46eacbfce1SSven Schnelle } 47eacbfce1SSven Schnelle 48eacbfce1SSven Schnelle static struct notifier_block kgdb_notifier = { 49eacbfce1SSven Schnelle .notifier_call = kgdb_notify, 50eacbfce1SSven Schnelle .priority = -INT_MAX, 51eacbfce1SSven Schnelle }; 52eacbfce1SSven Schnelle 53eacbfce1SSven Schnelle int kgdb_arch_init(void) 54eacbfce1SSven Schnelle { 55eacbfce1SSven Schnelle return register_die_notifier(&kgdb_notifier); 56eacbfce1SSven Schnelle } 57eacbfce1SSven Schnelle 58eacbfce1SSven Schnelle void kgdb_arch_exit(void) 59eacbfce1SSven Schnelle { 60eacbfce1SSven Schnelle unregister_die_notifier(&kgdb_notifier); 61eacbfce1SSven Schnelle } 62eacbfce1SSven Schnelle 63eacbfce1SSven Schnelle void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) 64eacbfce1SSven Schnelle { 65eacbfce1SSven Schnelle struct parisc_gdb_regs *gr = (struct parisc_gdb_regs *)gdb_regs; 66eacbfce1SSven Schnelle 67eacbfce1SSven Schnelle memset(gr, 0, sizeof(struct parisc_gdb_regs)); 68eacbfce1SSven Schnelle 69eacbfce1SSven Schnelle memcpy(gr->gpr, regs->gr, sizeof(gr->gpr)); 70eacbfce1SSven Schnelle memcpy(gr->fr, regs->fr, sizeof(gr->fr)); 71eacbfce1SSven Schnelle 72eacbfce1SSven Schnelle gr->sr0 = regs->sr[0]; 73eacbfce1SSven Schnelle gr->sr1 = regs->sr[1]; 74eacbfce1SSven Schnelle gr->sr2 = regs->sr[2]; 75eacbfce1SSven Schnelle gr->sr3 = regs->sr[3]; 76eacbfce1SSven Schnelle gr->sr4 = regs->sr[4]; 77eacbfce1SSven Schnelle gr->sr5 = regs->sr[5]; 78eacbfce1SSven Schnelle gr->sr6 = regs->sr[6]; 79eacbfce1SSven Schnelle gr->sr7 = regs->sr[7]; 80eacbfce1SSven Schnelle 81eacbfce1SSven Schnelle gr->sar = regs->sar; 82eacbfce1SSven Schnelle gr->iir = regs->iir; 83eacbfce1SSven Schnelle gr->isr = regs->isr; 84eacbfce1SSven Schnelle gr->ior = regs->ior; 85eacbfce1SSven Schnelle gr->ipsw = regs->ipsw; 86eacbfce1SSven Schnelle gr->cr27 = regs->cr27; 87eacbfce1SSven Schnelle 88eacbfce1SSven Schnelle gr->iaoq_f = regs->iaoq[0]; 89eacbfce1SSven Schnelle gr->iasq_f = regs->iasq[0]; 90eacbfce1SSven Schnelle 91eacbfce1SSven Schnelle gr->iaoq_b = regs->iaoq[1]; 92eacbfce1SSven Schnelle gr->iasq_b = regs->iasq[1]; 93eacbfce1SSven Schnelle } 94eacbfce1SSven Schnelle 95eacbfce1SSven Schnelle void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) 96eacbfce1SSven Schnelle { 97eacbfce1SSven Schnelle struct parisc_gdb_regs *gr = (struct parisc_gdb_regs *)gdb_regs; 98eacbfce1SSven Schnelle 99eacbfce1SSven Schnelle 100eacbfce1SSven Schnelle memcpy(regs->gr, gr->gpr, sizeof(regs->gr)); 101eacbfce1SSven Schnelle memcpy(regs->fr, gr->fr, sizeof(regs->fr)); 102eacbfce1SSven Schnelle 103eacbfce1SSven Schnelle regs->sr[0] = gr->sr0; 104eacbfce1SSven Schnelle regs->sr[1] = gr->sr1; 105eacbfce1SSven Schnelle regs->sr[2] = gr->sr2; 106eacbfce1SSven Schnelle regs->sr[3] = gr->sr3; 107eacbfce1SSven Schnelle regs->sr[4] = gr->sr4; 108eacbfce1SSven Schnelle regs->sr[5] = gr->sr5; 109eacbfce1SSven Schnelle regs->sr[6] = gr->sr6; 110eacbfce1SSven Schnelle regs->sr[7] = gr->sr7; 111eacbfce1SSven Schnelle 112eacbfce1SSven Schnelle regs->sar = gr->sar; 113eacbfce1SSven Schnelle regs->iir = gr->iir; 114eacbfce1SSven Schnelle regs->isr = gr->isr; 115eacbfce1SSven Schnelle regs->ior = gr->ior; 116eacbfce1SSven Schnelle regs->ipsw = gr->ipsw; 117eacbfce1SSven Schnelle regs->cr27 = gr->cr27; 118eacbfce1SSven Schnelle 119eacbfce1SSven Schnelle regs->iaoq[0] = gr->iaoq_f; 120eacbfce1SSven Schnelle regs->iasq[0] = gr->iasq_f; 121eacbfce1SSven Schnelle 122eacbfce1SSven Schnelle regs->iaoq[1] = gr->iaoq_b; 123eacbfce1SSven Schnelle regs->iasq[1] = gr->iasq_b; 124eacbfce1SSven Schnelle } 125eacbfce1SSven Schnelle 126eacbfce1SSven Schnelle void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, 127eacbfce1SSven Schnelle struct task_struct *task) 128eacbfce1SSven Schnelle { 129eacbfce1SSven Schnelle struct pt_regs *regs = task_pt_regs(task); 130eacbfce1SSven Schnelle unsigned long gr30, iaoq; 131eacbfce1SSven Schnelle 132eacbfce1SSven Schnelle gr30 = regs->gr[30]; 133eacbfce1SSven Schnelle iaoq = regs->iaoq[0]; 134eacbfce1SSven Schnelle 135eacbfce1SSven Schnelle regs->gr[30] = regs->ksp; 136eacbfce1SSven Schnelle regs->iaoq[0] = regs->kpc; 137eacbfce1SSven Schnelle pt_regs_to_gdb_regs(gdb_regs, regs); 138eacbfce1SSven Schnelle 139eacbfce1SSven Schnelle regs->gr[30] = gr30; 140eacbfce1SSven Schnelle regs->iaoq[0] = iaoq; 141eacbfce1SSven Schnelle 142eacbfce1SSven Schnelle } 143eacbfce1SSven Schnelle 144eacbfce1SSven Schnelle static void step_instruction_queue(struct pt_regs *regs) 145eacbfce1SSven Schnelle { 146eacbfce1SSven Schnelle regs->iaoq[0] = regs->iaoq[1]; 147eacbfce1SSven Schnelle regs->iaoq[1] += 4; 148eacbfce1SSven Schnelle } 149eacbfce1SSven Schnelle 150eacbfce1SSven Schnelle void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) 151eacbfce1SSven Schnelle { 152eacbfce1SSven Schnelle regs->iaoq[0] = ip; 153eacbfce1SSven Schnelle regs->iaoq[1] = ip + 4; 154eacbfce1SSven Schnelle } 155eacbfce1SSven Schnelle 156eacbfce1SSven Schnelle int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) 157eacbfce1SSven Schnelle { 158fe557319SChristoph Hellwig int ret = copy_from_kernel_nofault(bpt->saved_instr, 159fe557319SChristoph Hellwig (char *)bpt->bpt_addr, BREAK_INSTR_SIZE); 160eacbfce1SSven Schnelle if (ret) 161eacbfce1SSven Schnelle return ret; 162eacbfce1SSven Schnelle 163eacbfce1SSven Schnelle __patch_text((void *)bpt->bpt_addr, 164eacbfce1SSven Schnelle *(unsigned int *)&arch_kgdb_ops.gdb_bpt_instr); 165eacbfce1SSven Schnelle return ret; 166eacbfce1SSven Schnelle } 167eacbfce1SSven Schnelle 168eacbfce1SSven Schnelle int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) 169eacbfce1SSven Schnelle { 170eacbfce1SSven Schnelle __patch_text((void *)bpt->bpt_addr, *(unsigned int *)&bpt->saved_instr); 171eacbfce1SSven Schnelle return 0; 172eacbfce1SSven Schnelle } 173eacbfce1SSven Schnelle 174eacbfce1SSven Schnelle int kgdb_arch_handle_exception(int trap, int signo, 175eacbfce1SSven Schnelle int err_code, char *inbuf, char *outbuf, 176eacbfce1SSven Schnelle struct pt_regs *regs) 177eacbfce1SSven Schnelle { 178eacbfce1SSven Schnelle unsigned long addr; 179eacbfce1SSven Schnelle char *p = inbuf + 1; 180eacbfce1SSven Schnelle 181eacbfce1SSven Schnelle switch (inbuf[0]) { 182eacbfce1SSven Schnelle case 'D': 183eacbfce1SSven Schnelle case 'c': 184eacbfce1SSven Schnelle case 'k': 185eacbfce1SSven Schnelle kgdb_contthread = NULL; 186eacbfce1SSven Schnelle kgdb_single_step = 0; 187eacbfce1SSven Schnelle 188eacbfce1SSven Schnelle if (kgdb_hex2long(&p, &addr)) 189eacbfce1SSven Schnelle kgdb_arch_set_pc(regs, addr); 190eacbfce1SSven Schnelle else if (trap == 9 && regs->iir == 191eacbfce1SSven Schnelle PARISC_KGDB_COMPILED_BREAK_INSN) 192eacbfce1SSven Schnelle step_instruction_queue(regs); 193eacbfce1SSven Schnelle return 0; 194eacbfce1SSven Schnelle case 's': 195eacbfce1SSven Schnelle kgdb_single_step = 1; 196eacbfce1SSven Schnelle if (kgdb_hex2long(&p, &addr)) { 197eacbfce1SSven Schnelle kgdb_arch_set_pc(regs, addr); 198eacbfce1SSven Schnelle } else if (trap == 9 && regs->iir == 199eacbfce1SSven Schnelle PARISC_KGDB_COMPILED_BREAK_INSN) { 200eacbfce1SSven Schnelle step_instruction_queue(regs); 201eacbfce1SSven Schnelle mtctl(-1, 0); 202eacbfce1SSven Schnelle } else { 203eacbfce1SSven Schnelle mtctl(0, 0); 204eacbfce1SSven Schnelle } 205eacbfce1SSven Schnelle regs->gr[0] |= PSW_R; 206eacbfce1SSven Schnelle return 0; 207eacbfce1SSven Schnelle 208eacbfce1SSven Schnelle } 209eacbfce1SSven Schnelle return -1; 210eacbfce1SSven Schnelle } 211*c1c72d9bSHelge Deller 212*c1c72d9bSHelge Deller /* KGDB console driver which uses PDC to read chars from keyboard */ 213*c1c72d9bSHelge Deller 214*c1c72d9bSHelge Deller static void kgdb_pdc_write_char(u8 chr) 215*c1c72d9bSHelge Deller { 216*c1c72d9bSHelge Deller /* no need to print char. kgdb will do it. */ 217*c1c72d9bSHelge Deller } 218*c1c72d9bSHelge Deller 219*c1c72d9bSHelge Deller static struct kgdb_io kgdb_pdc_io_ops = { 220*c1c72d9bSHelge Deller .name = "kgdb_pdc", 221*c1c72d9bSHelge Deller .read_char = pdc_iodc_getc, 222*c1c72d9bSHelge Deller .write_char = kgdb_pdc_write_char, 223*c1c72d9bSHelge Deller }; 224*c1c72d9bSHelge Deller 225*c1c72d9bSHelge Deller static int __init kgdb_pdc_init(void) 226*c1c72d9bSHelge Deller { 227*c1c72d9bSHelge Deller kgdb_register_io_module(&kgdb_pdc_io_ops); 228*c1c72d9bSHelge Deller return 0; 229*c1c72d9bSHelge Deller } 230*c1c72d9bSHelge Deller early_initcall(kgdb_pdc_init); 231