^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * PowerPC backend to the KGDB stub.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * 1998 (c) Michael AK Tesch (tesch@cs.wisc.edu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2003 Timesys Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2004-2006 MontaVista Software, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * PPC64 Mods (C) 2005 Frank Rowand (frowand@mvista.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * PPC32 support restored by Vitaly Wool <vwool@ru.mvista.com> and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Sergei Shtylyov <sshtylyov@ru.mvista.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2007-2008 Wind River Systems, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * This file is licensed under the terms of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * version 2. This program as licensed "as is" without any warranty of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * kind, whether express or implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/kgdb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/kdebug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/current.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/machdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/code-patching.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <asm/inst.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * This table contains the mapping between PowerPC hardware trap types, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * signals, which are primarily what GDB understands. GDB and the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * don't always agree on values, so we use constants taken from gdb-6.2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static struct hard_trap_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) unsigned int tt; /* Trap type code for powerpc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) unsigned char signo; /* Signal that we map this trap into */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) } hard_trap_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) { 0x0100, 0x02 /* SIGINT */ }, /* system reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) { 0x0200, 0x0b /* SIGSEGV */ }, /* machine check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) { 0x0300, 0x0b /* SIGSEGV */ }, /* data access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) { 0x0400, 0x0b /* SIGSEGV */ }, /* instruction access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) { 0x0500, 0x02 /* SIGINT */ }, /* external interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) { 0x0600, 0x0a /* SIGBUS */ }, /* alignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) { 0x0700, 0x05 /* SIGTRAP */ }, /* program check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) { 0x0800, 0x08 /* SIGFPE */ }, /* fp unavailable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) { 0x0900, 0x0e /* SIGALRM */ }, /* decrementer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) { 0x0c00, 0x14 /* SIGCHLD */ }, /* system call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) { 0x2002, 0x05 /* SIGTRAP */ }, /* debug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #if defined(CONFIG_FSL_BOOKE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) { 0x2010, 0x08 /* SIGFPE */ }, /* spe unavailable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) { 0x2020, 0x08 /* SIGFPE */ }, /* spe unavailable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) { 0x2030, 0x08 /* SIGFPE */ }, /* spe fp data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) { 0x2040, 0x08 /* SIGFPE */ }, /* spe fp data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) { 0x2050, 0x08 /* SIGFPE */ }, /* spe fp round */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) { 0x2060, 0x0e /* SIGILL */ }, /* performance monitor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) { 0x2900, 0x08 /* SIGFPE */ }, /* apu unavailable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) { 0x3100, 0x0e /* SIGALRM */ }, /* fixed interval timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) { 0x3200, 0x02 /* SIGINT */ }, /* watchdog */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #else /* ! CONFIG_FSL_BOOKE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) { 0x1000, 0x0e /* SIGALRM */ }, /* prog interval timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) { 0x1010, 0x0e /* SIGALRM */ }, /* fixed interval timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) { 0x1020, 0x02 /* SIGINT */ }, /* watchdog */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) { 0x2010, 0x08 /* SIGFPE */ }, /* fp unavailable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) { 0x2020, 0x08 /* SIGFPE */ }, /* ap unavailable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #else /* ! (defined(CONFIG_40x) || defined(CONFIG_BOOKE)) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) { 0x0d00, 0x05 /* SIGTRAP */ }, /* single-step */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #if defined(CONFIG_PPC_8xx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) { 0x1000, 0x04 /* SIGILL */ }, /* software emulation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #else /* ! CONFIG_PPC_8xx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) { 0x0f00, 0x04 /* SIGILL */ }, /* performance monitor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) { 0x0f20, 0x08 /* SIGFPE */ }, /* altivec unavailable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) { 0x1300, 0x05 /* SIGTRAP */ }, /* instruction address break */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #if defined(CONFIG_PPC64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) { 0x1200, 0x05 /* SIGILL */ }, /* system error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) { 0x1500, 0x04 /* SIGILL */ }, /* soft patch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) { 0x1600, 0x04 /* SIGILL */ }, /* maintenance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) { 0x1700, 0x08 /* SIGFPE */ }, /* altivec assist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) { 0x1800, 0x04 /* SIGILL */ }, /* thermal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #else /* ! CONFIG_PPC64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) { 0x1400, 0x02 /* SIGINT */ }, /* SMI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) { 0x1600, 0x08 /* SIGFPE */ }, /* altivec assist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) { 0x1700, 0x04 /* SIGILL */ }, /* TAU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) { 0x2000, 0x05 /* SIGTRAP */ }, /* run mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) { 0x0000, 0x00 } /* Must be last */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static int computeSignal(unsigned int tt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct hard_trap_info *ht;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (ht->tt == tt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return ht->signo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return SIGHUP; /* default for things we don't know about */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * kgdb_skipexception - Bail out of KGDB when we've been triggered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * @exception: Exception vector number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * @regs: Current &struct pt_regs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * On some architectures we need to skip a breakpoint exception when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * it occurs after a breakpoint has been removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int kgdb_skipexception(int exception, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return kgdb_isremovedbreak(regs->nip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static int kgdb_debugger_ipi(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) kgdb_nmicallback(raw_smp_processor_id(), regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) void kgdb_roundup_cpus(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) smp_send_debugger_break();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* KGDB functions to use existing PowerPC64 hooks. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static int kgdb_debugger(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return !kgdb_handle_exception(1, computeSignal(TRAP(regs)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) DIE_OOPS, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int kgdb_handle_breakpoint(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (*(u32 *)regs->nip == BREAK_INSTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) regs->nip += BREAK_INSTR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static int kgdb_singlestep(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) kgdb_handle_exception(0, SIGTRAP, 0, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static int kgdb_iabr_match(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (kgdb_handle_exception(0, computeSignal(TRAP(regs)), 0, regs) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int kgdb_break_match(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (kgdb_handle_exception(0, computeSignal(TRAP(regs)), 0, regs) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define PACK64(ptr, src) do { *(ptr++) = (src); } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #define PACK32(ptr, src) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) u32 *ptr32; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ptr32 = (u32 *)ptr; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) *(ptr32++) = (src); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) ptr = (unsigned long *)ptr32; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct pt_regs *regs = (struct pt_regs *)(p->thread.ksp +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) STACK_FRAME_OVERHEAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) unsigned long *ptr = gdb_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) memset(gdb_regs, 0, NUMREGBYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* Regs GPR0-2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) for (reg = 0; reg < 3; reg++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) PACK64(ptr, regs->gpr[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* Regs GPR3-13 are caller saved, not in regs->gpr[] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ptr += 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* Regs GPR14-31 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) for (reg = 14; reg < 32; reg++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) PACK64(ptr, regs->gpr[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #ifdef CONFIG_FSL_BOOKE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #ifdef CONFIG_SPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) for (reg = 0; reg < 32; reg++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) PACK64(ptr, p->thread.evr[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ptr += 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* fp registers not used by kernel, leave zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ptr += 32 * 8 / sizeof(long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) PACK64(ptr, regs->nip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) PACK64(ptr, regs->msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) PACK32(ptr, regs->ccr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) PACK64(ptr, regs->link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) PACK64(ptr, regs->ctr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) PACK32(ptr, regs->xer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) BUG_ON((unsigned long)ptr >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) (unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) #define GDB_SIZEOF_REG sizeof(unsigned long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #define GDB_SIZEOF_REG_U32 sizeof(u32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #ifdef CONFIG_FSL_BOOKE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #define GDB_SIZEOF_FLOAT_REG sizeof(unsigned long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #define GDB_SIZEOF_FLOAT_REG sizeof(u64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) { "r0", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[0]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) { "r1", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[1]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) { "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[2]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) { "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[3]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) { "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[4]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) { "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[5]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) { "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[6]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) { "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[7]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) { "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[8]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) { "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[9]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) { "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[10]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) { "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[11]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) { "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[12]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) { "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[13]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) { "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[14]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) { "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[15]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) { "r16", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[16]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) { "r17", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[17]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) { "r18", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[18]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) { "r19", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[19]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) { "r20", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[20]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) { "r21", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[21]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) { "r22", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[22]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) { "r23", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[23]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) { "r24", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[24]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) { "r25", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[25]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) { "r26", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[26]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) { "r27", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[27]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) { "r28", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[28]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) { "r29", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[29]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) { "r30", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[30]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) { "r31", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[31]) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) { "f0", GDB_SIZEOF_FLOAT_REG, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) { "f1", GDB_SIZEOF_FLOAT_REG, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) { "f2", GDB_SIZEOF_FLOAT_REG, 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) { "f3", GDB_SIZEOF_FLOAT_REG, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) { "f4", GDB_SIZEOF_FLOAT_REG, 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) { "f5", GDB_SIZEOF_FLOAT_REG, 5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) { "f6", GDB_SIZEOF_FLOAT_REG, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) { "f7", GDB_SIZEOF_FLOAT_REG, 7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) { "f8", GDB_SIZEOF_FLOAT_REG, 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) { "f9", GDB_SIZEOF_FLOAT_REG, 9 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) { "f10", GDB_SIZEOF_FLOAT_REG, 10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) { "f11", GDB_SIZEOF_FLOAT_REG, 11 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) { "f12", GDB_SIZEOF_FLOAT_REG, 12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) { "f13", GDB_SIZEOF_FLOAT_REG, 13 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) { "f14", GDB_SIZEOF_FLOAT_REG, 14 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) { "f15", GDB_SIZEOF_FLOAT_REG, 15 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) { "f16", GDB_SIZEOF_FLOAT_REG, 16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) { "f17", GDB_SIZEOF_FLOAT_REG, 17 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) { "f18", GDB_SIZEOF_FLOAT_REG, 18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) { "f19", GDB_SIZEOF_FLOAT_REG, 19 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) { "f20", GDB_SIZEOF_FLOAT_REG, 20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) { "f21", GDB_SIZEOF_FLOAT_REG, 21 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) { "f22", GDB_SIZEOF_FLOAT_REG, 22 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) { "f23", GDB_SIZEOF_FLOAT_REG, 23 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) { "f24", GDB_SIZEOF_FLOAT_REG, 24 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) { "f25", GDB_SIZEOF_FLOAT_REG, 25 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) { "f26", GDB_SIZEOF_FLOAT_REG, 26 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) { "f27", GDB_SIZEOF_FLOAT_REG, 27 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) { "f28", GDB_SIZEOF_FLOAT_REG, 28 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) { "f29", GDB_SIZEOF_FLOAT_REG, 29 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) { "f30", GDB_SIZEOF_FLOAT_REG, 30 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) { "f31", GDB_SIZEOF_FLOAT_REG, 31 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, nip) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) { "msr", GDB_SIZEOF_REG, offsetof(struct pt_regs, msr) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) { "cr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ccr) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) { "lr", GDB_SIZEOF_REG, offsetof(struct pt_regs, link) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) { "ctr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ctr) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) { "xer", GDB_SIZEOF_REG, offsetof(struct pt_regs, xer) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (regno >= DBG_MAX_REG_NUM || regno < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (regno < 32 || regno >= 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* First 0 -> 31 gpr registers*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /* pc, msr, ls... registers 64 -> 69 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) dbg_reg_def[regno].size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (regno >= 32 && regno < 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* FP registers 32 -> 63 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) #if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (current)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) memcpy(mem, ¤t->thread.evr[regno-32],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) dbg_reg_def[regno].size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /* fp registers not used by kernel, leave zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) memset(mem, 0, dbg_reg_def[regno].size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return dbg_reg_def[regno].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (regno >= DBG_MAX_REG_NUM || regno < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (regno < 32 || regno >= 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* First 0 -> 31 gpr registers*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* pc, msr, ls... registers 64 -> 69 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) dbg_reg_def[regno].size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (regno >= 32 && regno < 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* FP registers 32 -> 63 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) #if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) memcpy(¤t->thread.evr[regno-32], mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) dbg_reg_def[regno].size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* fp registers not used by kernel, leave zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) regs->nip = pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * This function does PowerPC specific procesing for interfacing to gdb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) int kgdb_arch_handle_exception(int vector, int signo, int err_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) char *remcom_in_buffer, char *remcom_out_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct pt_regs *linux_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) char *ptr = &remcom_in_buffer[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) switch (remcom_in_buffer[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * sAA..AA Step one instruction from AA..AA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * This will return an error to gdb ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) case 'c':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* handle the optional parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (kgdb_hex2long(&ptr, &addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) linux_regs->nip = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) atomic_set(&kgdb_cpu_doing_single_step, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* set the trace bit if we're stepping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (remcom_in_buffer[0] == 's') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) #ifdef CONFIG_PPC_ADV_DEBUG_REGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) mtspr(SPRN_DBCR0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) linux_regs->msr |= MSR_DE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) linux_regs->msr |= MSR_SE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) atomic_set(&kgdb_cpu_doing_single_step,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) raw_smp_processor_id());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) unsigned int instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) struct ppc_inst *addr = (struct ppc_inst *)bpt->bpt_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) err = get_kernel_nofault(instr, (unsigned *) addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) err = patch_instruction(addr, ppc_inst(BREAK_INSTR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) *(unsigned int *)bpt->saved_instr = instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) unsigned int instr = *(unsigned int *)bpt->saved_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct ppc_inst *addr = (struct ppc_inst *)bpt->bpt_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) err = patch_instruction(addr, ppc_inst(instr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * Global data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) const struct kgdb_arch arch_kgdb_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static int kgdb_not_implemented(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static void *old__debugger_ipi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static void *old__debugger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static void *old__debugger_bpt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static void *old__debugger_sstep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) static void *old__debugger_iabr_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static void *old__debugger_break_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static void *old__debugger_fault_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) int kgdb_arch_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) old__debugger_ipi = __debugger_ipi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) old__debugger = __debugger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) old__debugger_bpt = __debugger_bpt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) old__debugger_sstep = __debugger_sstep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) old__debugger_iabr_match = __debugger_iabr_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) old__debugger_break_match = __debugger_break_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) old__debugger_fault_handler = __debugger_fault_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) __debugger_ipi = kgdb_debugger_ipi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) __debugger = kgdb_debugger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) __debugger_bpt = kgdb_handle_breakpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) __debugger_sstep = kgdb_singlestep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) __debugger_iabr_match = kgdb_iabr_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) __debugger_break_match = kgdb_break_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) __debugger_fault_handler = kgdb_not_implemented;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) void kgdb_arch_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) __debugger_ipi = old__debugger_ipi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) __debugger = old__debugger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) __debugger_bpt = old__debugger_bpt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) __debugger_sstep = old__debugger_sstep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) __debugger_iabr_match = old__debugger_iabr_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) __debugger_break_match = old__debugger_break_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) __debugger_fault_handler = old__debugger_fault_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }