root/arch/parisc/kernel/kgdb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __kgdb_notify
  2. kgdb_notify
  3. kgdb_arch_init
  4. kgdb_arch_exit
  5. pt_regs_to_gdb_regs
  6. gdb_regs_to_pt_regs
  7. sleeping_thread_to_gdb_regs
  8. step_instruction_queue
  9. kgdb_arch_set_pc
  10. kgdb_arch_set_breakpoint
  11. kgdb_arch_remove_breakpoint
  12. kgdb_arch_handle_exception

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * PA-RISC KGDB support
   4  *
   5  * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org>
   6  *
   7  */
   8 
   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>
  20 
  21 const struct kgdb_arch arch_kgdb_ops = {
  22         .gdb_bpt_instr = { 0x03, 0xff, 0xa0, 0x1f }
  23 };
  24 
  25 static int __kgdb_notify(struct die_args *args, unsigned long cmd)
  26 {
  27         struct pt_regs *regs = args->regs;
  28 
  29         if (kgdb_handle_exception(1, args->signr, cmd, regs))
  30                 return NOTIFY_DONE;
  31         return NOTIFY_STOP;
  32 }
  33 
  34 static int kgdb_notify(struct notifier_block *self,
  35                        unsigned long cmd, void *ptr)
  36 {
  37         unsigned long flags;
  38         int ret;
  39 
  40         local_irq_save(flags);
  41         ret = __kgdb_notify(ptr, cmd);
  42         local_irq_restore(flags);
  43 
  44         return ret;
  45 }
  46 
  47 static struct notifier_block kgdb_notifier = {
  48         .notifier_call  = kgdb_notify,
  49         .priority       = -INT_MAX,
  50 };
  51 
  52 int kgdb_arch_init(void)
  53 {
  54         return register_die_notifier(&kgdb_notifier);
  55 }
  56 
  57 void kgdb_arch_exit(void)
  58 {
  59         unregister_die_notifier(&kgdb_notifier);
  60 }
  61 
  62 void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
  63 {
  64         struct parisc_gdb_regs *gr = (struct parisc_gdb_regs *)gdb_regs;
  65 
  66         memset(gr, 0, sizeof(struct parisc_gdb_regs));
  67 
  68         memcpy(gr->gpr, regs->gr, sizeof(gr->gpr));
  69         memcpy(gr->fr, regs->fr, sizeof(gr->fr));
  70 
  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];
  79 
  80         gr->sar = regs->sar;
  81         gr->iir = regs->iir;
  82         gr->isr = regs->isr;
  83         gr->ior = regs->ior;
  84         gr->ipsw = regs->ipsw;
  85         gr->cr27 = regs->cr27;
  86 
  87         gr->iaoq_f = regs->iaoq[0];
  88         gr->iasq_f = regs->iasq[0];
  89 
  90         gr->iaoq_b = regs->iaoq[1];
  91         gr->iasq_b = regs->iasq[1];
  92 }
  93 
  94 void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
  95 {
  96         struct parisc_gdb_regs *gr = (struct parisc_gdb_regs *)gdb_regs;
  97 
  98 
  99         memcpy(regs->gr, gr->gpr, sizeof(regs->gr));
 100         memcpy(regs->fr, gr->fr, sizeof(regs->fr));
 101 
 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;
 110 
 111         regs->sar = gr->sar;
 112         regs->iir = gr->iir;
 113         regs->isr = gr->isr;
 114         regs->ior = gr->ior;
 115         regs->ipsw = gr->ipsw;
 116         regs->cr27 = gr->cr27;
 117 
 118         regs->iaoq[0] = gr->iaoq_f;
 119         regs->iasq[0] = gr->iasq_f;
 120 
 121         regs->iaoq[1] = gr->iaoq_b;
 122         regs->iasq[1] = gr->iasq_b;
 123 }
 124 
 125 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs,
 126                                 struct task_struct *task)
 127 {
 128         struct pt_regs *regs = task_pt_regs(task);
 129         unsigned long gr30, iaoq;
 130 
 131         gr30 = regs->gr[30];
 132         iaoq = regs->iaoq[0];
 133 
 134         regs->gr[30] = regs->ksp;
 135         regs->iaoq[0] = regs->kpc;
 136         pt_regs_to_gdb_regs(gdb_regs, regs);
 137 
 138         regs->gr[30] = gr30;
 139         regs->iaoq[0] = iaoq;
 140 
 141 }
 142 
 143 static void step_instruction_queue(struct pt_regs *regs)
 144 {
 145         regs->iaoq[0] = regs->iaoq[1];
 146         regs->iaoq[1] += 4;
 147 }
 148 
 149 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
 150 {
 151         regs->iaoq[0] = ip;
 152         regs->iaoq[1] = ip + 4;
 153 }
 154 
 155 int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
 156 {
 157         int ret = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
 158                                 BREAK_INSTR_SIZE);
 159         if (ret)
 160                 return ret;
 161 
 162         __patch_text((void *)bpt->bpt_addr,
 163                         *(unsigned int *)&arch_kgdb_ops.gdb_bpt_instr);
 164         return ret;
 165 }
 166 
 167 int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
 168 {
 169         __patch_text((void *)bpt->bpt_addr, *(unsigned int *)&bpt->saved_instr);
 170         return 0;
 171 }
 172 
 173 int kgdb_arch_handle_exception(int trap, int signo,
 174                 int err_code, char *inbuf, char *outbuf,
 175                 struct pt_regs *regs)
 176 {
 177         unsigned long addr;
 178         char *p = inbuf + 1;
 179 
 180         switch (inbuf[0]) {
 181         case 'D':
 182         case 'c':
 183         case 'k':
 184                 kgdb_contthread = NULL;
 185                 kgdb_single_step = 0;
 186 
 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);
 192                 return 0;
 193         case 's':
 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);
 200                         mtctl(-1, 0);
 201                 } else {
 202                         mtctl(0, 0);
 203                 }
 204                 regs->gr[0] |= PSW_R;
 205                 return 0;
 206 
 207         }
 208         return -1;
 209 }

/* [<][>][^][v][top][bottom][index][help] */