Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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, &current->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(&current->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) }