Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * PowerPC backend to the KGDB stub.
0004  *
0005  * 1998 (c) Michael AK Tesch (tesch@cs.wisc.edu)
0006  * Copyright (C) 2003 Timesys Corporation.
0007  * Copyright (C) 2004-2006 MontaVista Software, Inc.
0008  * PPC64 Mods (C) 2005 Frank Rowand (frowand@mvista.com)
0009  * PPC32 support restored by Vitaly Wool <vwool@ru.mvista.com> and
0010  * Sergei Shtylyov <sshtylyov@ru.mvista.com>
0011  * Copyright (C) 2007-2008 Wind River Systems, Inc.
0012  */
0013 
0014 #include <linux/kernel.h>
0015 #include <linux/kgdb.h>
0016 #include <linux/smp.h>
0017 #include <linux/signal.h>
0018 #include <linux/ptrace.h>
0019 #include <linux/kdebug.h>
0020 #include <asm/current.h>
0021 #include <asm/processor.h>
0022 #include <asm/machdep.h>
0023 #include <asm/debug.h>
0024 #include <asm/code-patching.h>
0025 #include <linux/slab.h>
0026 #include <asm/inst.h>
0027 
0028 /*
0029  * This table contains the mapping between PowerPC hardware trap types, and
0030  * signals, which are primarily what GDB understands.  GDB and the kernel
0031  * don't always agree on values, so we use constants taken from gdb-6.2.
0032  */
0033 static struct hard_trap_info
0034 {
0035     unsigned int tt;        /* Trap type code for powerpc */
0036     unsigned char signo;        /* Signal that we map this trap into */
0037 } hard_trap_info[] = {
0038     { 0x0100, 0x02 /* SIGINT */  },     /* system reset */
0039     { 0x0200, 0x0b /* SIGSEGV */ },     /* machine check */
0040     { 0x0300, 0x0b /* SIGSEGV */ },     /* data access */
0041     { 0x0400, 0x0b /* SIGSEGV */ },     /* instruction access */
0042     { 0x0500, 0x02 /* SIGINT */  },     /* external interrupt */
0043     { 0x0600, 0x0a /* SIGBUS */  },     /* alignment */
0044     { 0x0700, 0x05 /* SIGTRAP */ },     /* program check */
0045     { 0x0800, 0x08 /* SIGFPE */  },     /* fp unavailable */
0046     { 0x0900, 0x0e /* SIGALRM */ },     /* decrementer */
0047     { 0x0c00, 0x14 /* SIGCHLD */ },     /* system call */
0048 #ifdef CONFIG_BOOKE_OR_40x
0049     { 0x2002, 0x05 /* SIGTRAP */ },     /* debug */
0050 #if defined(CONFIG_FSL_BOOKE)
0051     { 0x2010, 0x08 /* SIGFPE */  },     /* spe unavailable */
0052     { 0x2020, 0x08 /* SIGFPE */  },     /* spe unavailable */
0053     { 0x2030, 0x08 /* SIGFPE */  },     /* spe fp data */
0054     { 0x2040, 0x08 /* SIGFPE */  },     /* spe fp data */
0055     { 0x2050, 0x08 /* SIGFPE */  },     /* spe fp round */
0056     { 0x2060, 0x0e /* SIGILL */  },     /* performance monitor */
0057     { 0x2900, 0x08 /* SIGFPE */  },     /* apu unavailable */
0058     { 0x3100, 0x0e /* SIGALRM */ },     /* fixed interval timer */
0059     { 0x3200, 0x02 /* SIGINT */  },     /* watchdog */
0060 #else /* ! CONFIG_FSL_BOOKE */
0061     { 0x1000, 0x0e /* SIGALRM */ },     /* prog interval timer */
0062     { 0x1010, 0x0e /* SIGALRM */ },     /* fixed interval timer */
0063     { 0x1020, 0x02 /* SIGINT */  },     /* watchdog */
0064     { 0x2010, 0x08 /* SIGFPE */  },     /* fp unavailable */
0065     { 0x2020, 0x08 /* SIGFPE */  },     /* ap unavailable */
0066 #endif
0067 #else /* !CONFIG_BOOKE_OR_40x */
0068     { 0x0d00, 0x05 /* SIGTRAP */ },     /* single-step */
0069 #if defined(CONFIG_PPC_8xx)
0070     { 0x1000, 0x04 /* SIGILL */  },     /* software emulation */
0071 #else /* ! CONFIG_PPC_8xx */
0072     { 0x0f00, 0x04 /* SIGILL */  },     /* performance monitor */
0073     { 0x0f20, 0x08 /* SIGFPE */  },     /* altivec unavailable */
0074     { 0x1300, 0x05 /* SIGTRAP */ },     /* instruction address break */
0075 #if defined(CONFIG_PPC64)
0076     { 0x1200, 0x05 /* SIGILL */  },     /* system error */
0077     { 0x1500, 0x04 /* SIGILL */  },     /* soft patch */
0078     { 0x1600, 0x04 /* SIGILL */  },     /* maintenance */
0079     { 0x1700, 0x08 /* SIGFPE */  },     /* altivec assist */
0080     { 0x1800, 0x04 /* SIGILL */  },     /* thermal */
0081 #else /* ! CONFIG_PPC64 */
0082     { 0x1400, 0x02 /* SIGINT */  },     /* SMI */
0083     { 0x1600, 0x08 /* SIGFPE */  },     /* altivec assist */
0084     { 0x1700, 0x04 /* SIGILL */  },     /* TAU */
0085     { 0x2000, 0x05 /* SIGTRAP */ },     /* run mode */
0086 #endif
0087 #endif
0088 #endif
0089     { 0x0000, 0x00 }            /* Must be last */
0090 };
0091 
0092 static int computeSignal(unsigned int tt)
0093 {
0094     struct hard_trap_info *ht;
0095 
0096     for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
0097         if (ht->tt == tt)
0098             return ht->signo;
0099 
0100     return SIGHUP;      /* default for things we don't know about */
0101 }
0102 
0103 /**
0104  *
0105  *  kgdb_skipexception - Bail out of KGDB when we've been triggered.
0106  *  @exception: Exception vector number
0107  *  @regs: Current &struct pt_regs.
0108  *
0109  *  On some architectures we need to skip a breakpoint exception when
0110  *  it occurs after a breakpoint has been removed.
0111  *
0112  */
0113 int kgdb_skipexception(int exception, struct pt_regs *regs)
0114 {
0115     return kgdb_isremovedbreak(regs->nip);
0116 }
0117 
0118 static int kgdb_debugger_ipi(struct pt_regs *regs)
0119 {
0120     kgdb_nmicallback(raw_smp_processor_id(), regs);
0121     return 0;
0122 }
0123 
0124 #ifdef CONFIG_SMP
0125 void kgdb_roundup_cpus(void)
0126 {
0127     smp_send_debugger_break();
0128 }
0129 #endif
0130 
0131 /* KGDB functions to use existing PowerPC64 hooks. */
0132 static int kgdb_debugger(struct pt_regs *regs)
0133 {
0134     return !kgdb_handle_exception(1, computeSignal(TRAP(regs)),
0135                       DIE_OOPS, regs);
0136 }
0137 
0138 static int kgdb_handle_breakpoint(struct pt_regs *regs)
0139 {
0140     if (user_mode(regs))
0141         return 0;
0142 
0143     if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0)
0144         return 0;
0145 
0146     if (*(u32 *)regs->nip == BREAK_INSTR)
0147         regs_add_return_ip(regs, BREAK_INSTR_SIZE);
0148 
0149     return 1;
0150 }
0151 
0152 static int kgdb_singlestep(struct pt_regs *regs)
0153 {
0154     if (user_mode(regs))
0155         return 0;
0156 
0157     kgdb_handle_exception(0, SIGTRAP, 0, regs);
0158 
0159     return 1;
0160 }
0161 
0162 static int kgdb_iabr_match(struct pt_regs *regs)
0163 {
0164     if (user_mode(regs))
0165         return 0;
0166 
0167     if (kgdb_handle_exception(0, computeSignal(TRAP(regs)), 0, regs) != 0)
0168         return 0;
0169     return 1;
0170 }
0171 
0172 static int kgdb_break_match(struct pt_regs *regs)
0173 {
0174     if (user_mode(regs))
0175         return 0;
0176 
0177     if (kgdb_handle_exception(0, computeSignal(TRAP(regs)), 0, regs) != 0)
0178         return 0;
0179     return 1;
0180 }
0181 
0182 #define PACK64(ptr, src) do { *(ptr++) = (src); } while (0)
0183 
0184 #define PACK32(ptr, src) do {          \
0185     u32 *ptr32;                   \
0186     ptr32 = (u32 *)ptr;           \
0187     *(ptr32++) = (src);           \
0188     ptr = (unsigned long *)ptr32; \
0189     } while (0)
0190 
0191 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
0192 {
0193     struct pt_regs *regs = (struct pt_regs *)(p->thread.ksp +
0194                           STACK_FRAME_OVERHEAD);
0195     unsigned long *ptr = gdb_regs;
0196     int reg;
0197 
0198     memset(gdb_regs, 0, NUMREGBYTES);
0199 
0200     /* Regs GPR0-2 */
0201     for (reg = 0; reg < 3; reg++)
0202         PACK64(ptr, regs->gpr[reg]);
0203 
0204     /* Regs GPR3-13 are caller saved, not in regs->gpr[] */
0205     ptr += 11;
0206 
0207     /* Regs GPR14-31 */
0208     for (reg = 14; reg < 32; reg++)
0209         PACK64(ptr, regs->gpr[reg]);
0210 
0211 #ifdef CONFIG_FSL_BOOKE
0212 #ifdef CONFIG_SPE
0213     for (reg = 0; reg < 32; reg++)
0214         PACK64(ptr, p->thread.evr[reg]);
0215 #else
0216     ptr += 32;
0217 #endif
0218 #else
0219     /* fp registers not used by kernel, leave zero */
0220     ptr += 32 * 8 / sizeof(long);
0221 #endif
0222 
0223     PACK64(ptr, regs->nip);
0224     PACK64(ptr, regs->msr);
0225     PACK32(ptr, regs->ccr);
0226     PACK64(ptr, regs->link);
0227     PACK64(ptr, regs->ctr);
0228     PACK32(ptr, regs->xer);
0229 
0230     BUG_ON((unsigned long)ptr >
0231            (unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
0232 }
0233 
0234 #define GDB_SIZEOF_REG sizeof(unsigned long)
0235 #define GDB_SIZEOF_REG_U32 sizeof(u32)
0236 
0237 #ifdef CONFIG_FSL_BOOKE
0238 #define GDB_SIZEOF_FLOAT_REG sizeof(unsigned long)
0239 #else
0240 #define GDB_SIZEOF_FLOAT_REG sizeof(u64)
0241 #endif
0242 
0243 struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
0244 {
0245     { "r0", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[0]) },
0246     { "r1", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[1]) },
0247     { "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[2]) },
0248     { "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[3]) },
0249     { "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[4]) },
0250     { "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[5]) },
0251     { "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[6]) },
0252     { "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[7]) },
0253     { "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[8]) },
0254     { "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[9]) },
0255     { "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[10]) },
0256     { "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[11]) },
0257     { "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[12]) },
0258     { "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[13]) },
0259     { "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[14]) },
0260     { "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[15]) },
0261     { "r16", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[16]) },
0262     { "r17", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[17]) },
0263     { "r18", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[18]) },
0264     { "r19", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[19]) },
0265     { "r20", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[20]) },
0266     { "r21", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[21]) },
0267     { "r22", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[22]) },
0268     { "r23", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[23]) },
0269     { "r24", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[24]) },
0270     { "r25", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[25]) },
0271     { "r26", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[26]) },
0272     { "r27", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[27]) },
0273     { "r28", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[28]) },
0274     { "r29", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[29]) },
0275     { "r30", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[30]) },
0276     { "r31", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[31]) },
0277 
0278     { "f0", GDB_SIZEOF_FLOAT_REG, 0 },
0279     { "f1", GDB_SIZEOF_FLOAT_REG, 1 },
0280     { "f2", GDB_SIZEOF_FLOAT_REG, 2 },
0281     { "f3", GDB_SIZEOF_FLOAT_REG, 3 },
0282     { "f4", GDB_SIZEOF_FLOAT_REG, 4 },
0283     { "f5", GDB_SIZEOF_FLOAT_REG, 5 },
0284     { "f6", GDB_SIZEOF_FLOAT_REG, 6 },
0285     { "f7", GDB_SIZEOF_FLOAT_REG, 7 },
0286     { "f8", GDB_SIZEOF_FLOAT_REG, 8 },
0287     { "f9", GDB_SIZEOF_FLOAT_REG, 9 },
0288     { "f10", GDB_SIZEOF_FLOAT_REG, 10 },
0289     { "f11", GDB_SIZEOF_FLOAT_REG, 11 },
0290     { "f12", GDB_SIZEOF_FLOAT_REG, 12 },
0291     { "f13", GDB_SIZEOF_FLOAT_REG, 13 },
0292     { "f14", GDB_SIZEOF_FLOAT_REG, 14 },
0293     { "f15", GDB_SIZEOF_FLOAT_REG, 15 },
0294     { "f16", GDB_SIZEOF_FLOAT_REG, 16 },
0295     { "f17", GDB_SIZEOF_FLOAT_REG, 17 },
0296     { "f18", GDB_SIZEOF_FLOAT_REG, 18 },
0297     { "f19", GDB_SIZEOF_FLOAT_REG, 19 },
0298     { "f20", GDB_SIZEOF_FLOAT_REG, 20 },
0299     { "f21", GDB_SIZEOF_FLOAT_REG, 21 },
0300     { "f22", GDB_SIZEOF_FLOAT_REG, 22 },
0301     { "f23", GDB_SIZEOF_FLOAT_REG, 23 },
0302     { "f24", GDB_SIZEOF_FLOAT_REG, 24 },
0303     { "f25", GDB_SIZEOF_FLOAT_REG, 25 },
0304     { "f26", GDB_SIZEOF_FLOAT_REG, 26 },
0305     { "f27", GDB_SIZEOF_FLOAT_REG, 27 },
0306     { "f28", GDB_SIZEOF_FLOAT_REG, 28 },
0307     { "f29", GDB_SIZEOF_FLOAT_REG, 29 },
0308     { "f30", GDB_SIZEOF_FLOAT_REG, 30 },
0309     { "f31", GDB_SIZEOF_FLOAT_REG, 31 },
0310 
0311     { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, nip) },
0312     { "msr", GDB_SIZEOF_REG, offsetof(struct pt_regs, msr) },
0313     { "cr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ccr) },
0314     { "lr", GDB_SIZEOF_REG, offsetof(struct pt_regs, link) },
0315     { "ctr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ctr) },
0316     { "xer", GDB_SIZEOF_REG, offsetof(struct pt_regs, xer) },
0317 };
0318 
0319 char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
0320 {
0321     if (regno >= DBG_MAX_REG_NUM || regno < 0)
0322         return NULL;
0323 
0324     if (regno < 32 || regno >= 64)
0325         /* First 0 -> 31 gpr registers*/
0326         /* pc, msr, ls... registers 64 -> 69 */
0327         memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
0328                 dbg_reg_def[regno].size);
0329 
0330     if (regno >= 32 && regno < 64) {
0331         /* FP registers 32 -> 63 */
0332 #if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
0333         if (current)
0334             memcpy(mem, &current->thread.evr[regno-32],
0335                     dbg_reg_def[regno].size);
0336 #else
0337         /* fp registers not used by kernel, leave zero */
0338         memset(mem, 0, dbg_reg_def[regno].size);
0339 #endif
0340     }
0341 
0342     return dbg_reg_def[regno].name;
0343 }
0344 
0345 int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
0346 {
0347     if (regno >= DBG_MAX_REG_NUM || regno < 0)
0348         return -EINVAL;
0349 
0350     if (regno < 32 || regno >= 64)
0351         /* First 0 -> 31 gpr registers*/
0352         /* pc, msr, ls... registers 64 -> 69 */
0353         memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
0354                 dbg_reg_def[regno].size);
0355 
0356     if (regno >= 32 && regno < 64) {
0357         /* FP registers 32 -> 63 */
0358 #if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
0359         memcpy(&current->thread.evr[regno-32], mem,
0360                 dbg_reg_def[regno].size);
0361 #else
0362         /* fp registers not used by kernel, leave zero */
0363         return 0;
0364 #endif
0365     }
0366 
0367     return 0;
0368 }
0369 
0370 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
0371 {
0372     regs_set_return_ip(regs, pc);
0373 }
0374 
0375 /*
0376  * This function does PowerPC specific processing for interfacing to gdb.
0377  */
0378 int kgdb_arch_handle_exception(int vector, int signo, int err_code,
0379                    char *remcom_in_buffer, char *remcom_out_buffer,
0380                    struct pt_regs *linux_regs)
0381 {
0382     char *ptr = &remcom_in_buffer[1];
0383     unsigned long addr;
0384 
0385     switch (remcom_in_buffer[0]) {
0386         /*
0387          * sAA..AA   Step one instruction from AA..AA
0388          * This will return an error to gdb ..
0389          */
0390     case 's':
0391     case 'c':
0392         /* handle the optional parameter */
0393         if (kgdb_hex2long(&ptr, &addr))
0394             regs_set_return_ip(linux_regs, addr);
0395 
0396         atomic_set(&kgdb_cpu_doing_single_step, -1);
0397         /* set the trace bit if we're stepping */
0398         if (remcom_in_buffer[0] == 's') {
0399 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
0400             mtspr(SPRN_DBCR0,
0401                   mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
0402             regs_set_return_msr(linux_regs, linux_regs->msr | MSR_DE);
0403 #else
0404             regs_set_return_msr(linux_regs, linux_regs->msr | MSR_SE);
0405 #endif
0406             atomic_set(&kgdb_cpu_doing_single_step,
0407                    raw_smp_processor_id());
0408         }
0409         return 0;
0410     }
0411 
0412     return -1;
0413 }
0414 
0415 int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
0416 {
0417     u32 instr, *addr = (u32 *)bpt->bpt_addr;
0418     int err;
0419 
0420     err = get_kernel_nofault(instr, addr);
0421     if (err)
0422         return err;
0423 
0424     err = patch_instruction(addr, ppc_inst(BREAK_INSTR));
0425     if (err)
0426         return -EFAULT;
0427 
0428     *(u32 *)bpt->saved_instr = instr;
0429 
0430     return 0;
0431 }
0432 
0433 int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
0434 {
0435     int err;
0436     unsigned int instr = *(unsigned int *)bpt->saved_instr;
0437     u32 *addr = (u32 *)bpt->bpt_addr;
0438 
0439     err = patch_instruction(addr, ppc_inst(instr));
0440     if (err)
0441         return -EFAULT;
0442 
0443     return 0;
0444 }
0445 
0446 /*
0447  * Global data
0448  */
0449 const struct kgdb_arch arch_kgdb_ops;
0450 
0451 static int kgdb_not_implemented(struct pt_regs *regs)
0452 {
0453     return 0;
0454 }
0455 
0456 static void *old__debugger_ipi;
0457 static void *old__debugger;
0458 static void *old__debugger_bpt;
0459 static void *old__debugger_sstep;
0460 static void *old__debugger_iabr_match;
0461 static void *old__debugger_break_match;
0462 static void *old__debugger_fault_handler;
0463 
0464 int kgdb_arch_init(void)
0465 {
0466     old__debugger_ipi = __debugger_ipi;
0467     old__debugger = __debugger;
0468     old__debugger_bpt = __debugger_bpt;
0469     old__debugger_sstep = __debugger_sstep;
0470     old__debugger_iabr_match = __debugger_iabr_match;
0471     old__debugger_break_match = __debugger_break_match;
0472     old__debugger_fault_handler = __debugger_fault_handler;
0473 
0474     __debugger_ipi = kgdb_debugger_ipi;
0475     __debugger = kgdb_debugger;
0476     __debugger_bpt = kgdb_handle_breakpoint;
0477     __debugger_sstep = kgdb_singlestep;
0478     __debugger_iabr_match = kgdb_iabr_match;
0479     __debugger_break_match = kgdb_break_match;
0480     __debugger_fault_handler = kgdb_not_implemented;
0481 
0482     return 0;
0483 }
0484 
0485 void kgdb_arch_exit(void)
0486 {
0487     __debugger_ipi = old__debugger_ipi;
0488     __debugger = old__debugger;
0489     __debugger_bpt = old__debugger_bpt;
0490     __debugger_sstep = old__debugger_sstep;
0491     __debugger_iabr_match = old__debugger_iabr_match;
0492     __debugger_break_match = old__debugger_break_match;
0493     __debugger_fault_handler = old__debugger_fault_handler;
0494 }