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)  * Kernel Debug Core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Maintainer: Jason Wessel <jason.wessel@windriver.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright (C) 2000-2001 VERITAS Software Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Copyright (C) 2002-2004 Timesys Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Copyright (C) 2003-2004 Amit S. Kale <amitkale@linsyssoft.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * Copyright (C) 2004 Pavel Machek <pavel@ucw.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * Copyright (C) 2004-2006 Tom Rini <trini@kernel.crashing.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * Copyright (C) 2004-2006 LinSysSoft Technologies Pvt. Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * Copyright (C) 2005-2009 Wind River Systems, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * Copyright (C) 2007 MontaVista Software, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  * Copyright (C) 2008 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  * Contributors at various stages not listed above:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  *  Jason Wessel ( jason.wessel@windriver.com )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *  George Anzinger <george@mvista.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  *  Anurekh Saxena (anurekh.saxena@timesys.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  *  Lake Stevens Instrument Division (Glenn Engel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  *  Jim Kingdon, Cygnus Support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  * Original KGDB stub: David Grothe <dave@gcom.com>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  * Tigran Aivazian <tigran@sco.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  * This file is licensed under the terms of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  * version 2. This program is licensed "as is" without any warranty of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)  * kind, whether express or implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <linux/kgdb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <linux/kdb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include "debug_core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define KGDB_MAX_THREAD_QUERY 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) /* Our I/O buffers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) static char			remcom_in_buffer[BUFMAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) static char			remcom_out_buffer[BUFMAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) static int			gdbstub_use_prev_in_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) static int			gdbstub_prev_in_buf_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) /* Storage for the registers, in GDB format. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) static unsigned long		gdb_regs[(NUMREGBYTES +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 					sizeof(unsigned long) - 1) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 					sizeof(unsigned long)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56)  * GDB remote protocol parser:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #ifdef CONFIG_KGDB_KDB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) static int gdbstub_read_wait(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	if (unlikely(gdbstub_use_prev_in_buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 		if (gdbstub_prev_in_buf_pos < gdbstub_use_prev_in_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 			return remcom_in_buffer[gdbstub_prev_in_buf_pos++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 			gdbstub_use_prev_in_buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	/* poll any additional I/O interfaces that are defined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	while (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 		for (i = 0; kdb_poll_funcs[i] != NULL; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 			ret = kdb_poll_funcs[i]();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 			if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) static int gdbstub_read_wait(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	int ret = dbg_io_ops->read_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	while (ret == NO_POLL_CHAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 		ret = dbg_io_ops->read_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) /* scan for the sequence $<data>#<checksum> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) static void get_packet(char *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	unsigned char checksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	unsigned char xmitcsum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	char ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 		 * Spin and wait around for the start character, ignore all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 		 * other characters:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 		while ((ch = (gdbstub_read_wait())) != '$')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 			/* nothing */;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 		kgdb_connected = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		checksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 		xmitcsum = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 		count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 		 * now, read until a # or end of buffer is found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 		while (count < (BUFMAX - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 			ch = gdbstub_read_wait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 			if (ch == '#')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 			checksum = checksum + ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 			buffer[count] = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 			count = count + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 		if (ch == '#') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 			xmitcsum = hex_to_bin(gdbstub_read_wait()) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 			xmitcsum += hex_to_bin(gdbstub_read_wait());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 			if (checksum != xmitcsum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 				/* failed checksum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 				dbg_io_ops->write_char('-');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 				/* successful transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 				dbg_io_ops->write_char('+');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 			if (dbg_io_ops->flush)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 				dbg_io_ops->flush();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 		buffer[count] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	} while (checksum != xmitcsum);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142)  * Send the packet in buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143)  * Check for gdb connection if asked for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) static void put_packet(char *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	unsigned char checksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	char ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	 * $<packet info>#<checksum>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 		dbg_io_ops->write_char('$');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 		checksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 		count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		while ((ch = buffer[count])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 			dbg_io_ops->write_char(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 			checksum += ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 			count++;
^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) 		dbg_io_ops->write_char('#');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 		dbg_io_ops->write_char(hex_asc_hi(checksum));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 		dbg_io_ops->write_char(hex_asc_lo(checksum));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 		if (dbg_io_ops->flush)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 			dbg_io_ops->flush();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		/* Now see what we get in reply. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 		ch = gdbstub_read_wait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 		if (ch == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 			ch = gdbstub_read_wait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 		/* If we get an ACK, we are done. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 		if (ch == '+')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		 * If we get the start of another packet, this means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		 * that GDB is attempting to reconnect.  We will NAK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		 * the packet being sent, and stop trying to send this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 		 * packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 		if (ch == '$') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 			dbg_io_ops->write_char('-');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 			if (dbg_io_ops->flush)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 				dbg_io_ops->flush();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) static char gdbmsgbuf[BUFMAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) void gdbstub_msg_write(const char *s, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	char *bufptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	int wcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		len = strlen(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	/* 'O'utput */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	gdbmsgbuf[0] = 'O';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	/* Fill and send buffers... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	while (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 		bufptr = gdbmsgbuf + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		/* Calculate how many this time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 		if ((len << 1) > (BUFMAX - 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 			wcount = (BUFMAX - 2) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 			wcount = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 		/* Pack in hex chars */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 		for (i = 0; i < wcount; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 			bufptr = hex_byte_pack(bufptr, s[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		*bufptr = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 		/* Move up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 		s += wcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 		len -= wcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 		/* Write packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		put_packet(gdbmsgbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235)  * Convert the memory pointed to by mem into hex, placing result in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236)  * buf.  Return a pointer to the last char put in buf (null). May
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237)  * return an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) char *kgdb_mem2hex(char *mem, char *buf, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	char *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	 * We use the upper half of buf as an intermediate buffer for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	 * raw memory copy.  Hex conversion will work against this one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	tmp = buf + count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	err = copy_from_kernel_nofault(tmp, mem, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	while (count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		buf = hex_byte_pack(buf, *tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		tmp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	*buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264)  * Convert the hex array pointed to by buf into binary to be placed in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265)  * mem.  Return a pointer to the character AFTER the last byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266)  * written.  May return an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) int kgdb_hex2mem(char *buf, char *mem, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	char *tmp_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	char *tmp_hex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	 * We use the upper half of buf as an intermediate buffer for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	 * raw memory that is converted from hex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	tmp_raw = buf + count * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	tmp_hex = tmp_raw - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	while (tmp_hex >= buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		tmp_raw--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 		*tmp_raw = hex_to_bin(*tmp_hex--);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 		*tmp_raw |= hex_to_bin(*tmp_hex--) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	return copy_to_kernel_nofault(mem, tmp_raw, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290)  * While we find nice hex chars, build a long_val.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291)  * Return number of chars processed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) int kgdb_hex2long(char **ptr, unsigned long *long_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	int hex_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	int num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	int negate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	*long_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	if (**ptr == '-') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 		negate = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		(*ptr)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	while (**ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		hex_val = hex_to_bin(**ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		if (hex_val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		*long_val = (*long_val << 4) | hex_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 		num++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 		(*ptr)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	if (negate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		*long_val = -*long_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	return num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) }
^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)  * Copy the binary array pointed to by buf into mem.  Fix $, #, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323)  * 0x7d escaped with 0x7d. Return -EFAULT on failure or 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324)  * The input buf is overwitten with the result to write to mem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) static int kgdb_ebin2mem(char *buf, char *mem, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	int size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	char *c = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	while (count-- > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		c[size] = *buf++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 		if (c[size] == 0x7d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 			c[size] = *buf++ ^ 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		size++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	return copy_to_kernel_nofault(mem, c, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) #if DBG_MAX_REG_NUM > 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	char *ptr = (char *)gdb_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	for (i = 0; i < DBG_MAX_REG_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		dbg_get_reg(i, ptr + idx, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		idx += dbg_reg_def[i].size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	char *ptr = (char *)gdb_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	for (i = 0; i < DBG_MAX_REG_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		dbg_set_reg(i, ptr + idx, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 		idx += dbg_reg_def[i].size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) #endif /* DBG_MAX_REG_NUM > 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) /* Write memory due to an 'M' or 'X' packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) static int write_mem_msg(int binary)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	char *ptr = &remcom_in_buffer[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	unsigned long length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	if (kgdb_hex2long(&ptr, &addr) > 0 && *(ptr++) == ',' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	    kgdb_hex2long(&ptr, &length) > 0 && *(ptr++) == ':') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		if (binary)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 			err = kgdb_ebin2mem(ptr, (char *)addr, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 			err = kgdb_hex2mem(ptr, (char *)addr, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		if (CACHE_FLUSH_IS_SAFE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 			flush_icache_range(addr, addr + length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) static void error_packet(char *pkt, int error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	error = -error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	pkt[0] = 'E';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	pkt[1] = hex_asc[(error / 10)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	pkt[2] = hex_asc[(error % 10)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	pkt[3] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401)  * Thread ID accessors. We represent a flat TID space to GDB, where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402)  * the per CPU idle threads (which under Linux all have PID 0) are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403)  * remapped to negative TIDs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) #define BUF_THREAD_ID_SIZE	8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) static char *pack_threadid(char *pkt, unsigned char *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	unsigned char *limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	int lzero = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	limit = id + (BUF_THREAD_ID_SIZE / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	while (id < limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		if (!lzero || *id != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 			pkt = hex_byte_pack(pkt, *id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 			lzero = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	if (lzero)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		pkt = hex_byte_pack(pkt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	return pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) static void int_to_threadref(unsigned char *id, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	put_unaligned_be32(value, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) static struct task_struct *getthread(struct pt_regs *regs, int tid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	 * Non-positive TIDs are remapped to the cpu shadow information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	if (tid == 0 || tid == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		tid = -atomic_read(&kgdb_active) - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	if (tid < -1 && tid > -NR_CPUS - 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		if (kgdb_info[-tid - 2].task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 			return kgdb_info[-tid - 2].task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 			return idle_task(-tid - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	if (tid <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		printk(KERN_ERR "KGDB: Internal thread select error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		dump_stack();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	 * find_task_by_pid_ns() does not take the tasklist lock anymore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	 * but is nicely RCU locked - hence is a pretty resilient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	 * thing to use:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	return find_task_by_pid_ns(tid, &init_pid_ns);
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462)  * Remap normal tasks to their real PID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463)  * CPU shadow threads are mapped to -CPU - 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) static inline int shadow_pid(int realpid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	if (realpid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		return realpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	return -raw_smp_processor_id() - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474)  * All the functions that start with gdb_cmd are the various
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475)  * operations to implement the handlers for the gdbserial protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476)  * where KGDB is communicating with an external debugger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) /* Handle the '?' status packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) static void gdb_cmd_status(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	 * We know that this packet is only sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	 * during initial connect.  So to be safe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	 * we clear out our breakpoints now in case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	 * GDB is reconnecting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	dbg_remove_all_break();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	remcom_out_buffer[0] = 'S';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	hex_byte_pack(&remcom_out_buffer[1], ks->signo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) static void gdb_get_regs_helper(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	struct task_struct *thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	void *local_debuggerinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	thread = kgdb_usethread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	if (!thread) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		thread = kgdb_info[ks->cpu].task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		local_debuggerinfo = kgdb_info[ks->cpu].debuggerinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		local_debuggerinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		for_each_online_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 			 * Try to find the task on some other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 			 * or possibly this node if we do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 			 * find the matching task then we try
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 			 * to approximate the results.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 			if (thread == kgdb_info[i].task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 				local_debuggerinfo = kgdb_info[i].debuggerinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	 * All threads that don't have debuggerinfo should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	 * in schedule() sleeping, since all other CPUs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	 * are in kgdb_wait, and thus have debuggerinfo.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	if (local_debuggerinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		pt_regs_to_gdb_regs(gdb_regs, local_debuggerinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		 * Pull stuff saved during switch_to; nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		 * else is accessible (or even particularly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		 * relevant).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		 * This should be enough for a stack trace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		sleeping_thread_to_gdb_regs(gdb_regs, thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) /* Handle the 'g' get registers request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) static void gdb_cmd_getregs(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	gdb_get_regs_helper(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	kgdb_mem2hex((char *)gdb_regs, remcom_out_buffer, NUMREGBYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) /* Handle the 'G' set registers request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) static void gdb_cmd_setregs(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	kgdb_hex2mem(&remcom_in_buffer[1], (char *)gdb_regs, NUMREGBYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	if (kgdb_usethread && kgdb_usethread != current) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 		error_packet(remcom_out_buffer, -EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		gdb_regs_to_pt_regs(gdb_regs, ks->linux_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 		strcpy(remcom_out_buffer, "OK");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) /* Handle the 'm' memory read bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) static void gdb_cmd_memread(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	char *ptr = &remcom_in_buffer[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	unsigned long length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	char *err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	if (kgdb_hex2long(&ptr, &addr) > 0 && *ptr++ == ',' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 					kgdb_hex2long(&ptr, &length) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		err = kgdb_mem2hex((char *)addr, remcom_out_buffer, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 		if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 			error_packet(remcom_out_buffer, -EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 		error_packet(remcom_out_buffer, -EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) /* Handle the 'M' memory write bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) static void gdb_cmd_memwrite(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	int err = write_mem_msg(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 		error_packet(remcom_out_buffer, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 		strcpy(remcom_out_buffer, "OK");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) #if DBG_MAX_REG_NUM > 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) static char *gdb_hex_reg_helper(int regnum, char *out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	int offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	for (i = 0; i < regnum; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		offset += dbg_reg_def[i].size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	return kgdb_mem2hex((char *)gdb_regs + offset, out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 			    dbg_reg_def[i].size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) /* Handle the 'p' individual regster get */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) static void gdb_cmd_reg_get(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	unsigned long regnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	char *ptr = &remcom_in_buffer[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	kgdb_hex2long(&ptr, &regnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	if (regnum >= DBG_MAX_REG_NUM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		error_packet(remcom_out_buffer, -EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	gdb_get_regs_helper(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	gdb_hex_reg_helper(regnum, remcom_out_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) /* Handle the 'P' individual regster set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) static void gdb_cmd_reg_set(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	unsigned long regnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	char *ptr = &remcom_in_buffer[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	kgdb_hex2long(&ptr, &regnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	if (*ptr++ != '=' ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	    !(!kgdb_usethread || kgdb_usethread == current) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	    !dbg_get_reg(regnum, gdb_regs, ks->linux_regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 		error_packet(remcom_out_buffer, -EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	memset(gdb_regs, 0, sizeof(gdb_regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	while (i < sizeof(gdb_regs) * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 		if (hex_to_bin(ptr[i]) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	i = i / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	kgdb_hex2mem(ptr, (char *)gdb_regs, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	dbg_set_reg(regnum, gdb_regs, ks->linux_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	strcpy(remcom_out_buffer, "OK");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) #endif /* DBG_MAX_REG_NUM > 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) /* Handle the 'X' memory binary write bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) static void gdb_cmd_binwrite(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	int err = write_mem_msg(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		error_packet(remcom_out_buffer, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		strcpy(remcom_out_buffer, "OK");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) /* Handle the 'D' or 'k', detach or kill packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) static void gdb_cmd_detachkill(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	/* The detach case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	if (remcom_in_buffer[0] == 'D') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		error = dbg_remove_all_break();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 			error_packet(remcom_out_buffer, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 			strcpy(remcom_out_buffer, "OK");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 			kgdb_connected = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		put_packet(remcom_out_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		 * Assume the kill case, with no exit code checking,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		 * trying to force detach the debugger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		dbg_remove_all_break();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		kgdb_connected = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) /* Handle the 'R' reboot packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) static int gdb_cmd_reboot(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	/* For now, only honor R0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	if (strcmp(remcom_in_buffer, "R0") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 		printk(KERN_CRIT "Executing emergency reboot\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 		strcpy(remcom_out_buffer, "OK");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 		put_packet(remcom_out_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		 * Execution should not return from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		 * machine_emergency_restart()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		machine_emergency_restart();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		kgdb_connected = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) /* Handle the 'q' query packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) static void gdb_cmd_query(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	struct task_struct *g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	struct task_struct *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	unsigned char thref[BUF_THREAD_ID_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	int finished = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	switch (remcom_in_buffer[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	case 'f':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		if (memcmp(remcom_in_buffer + 2, "ThreadInfo", 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 		i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 		remcom_out_buffer[0] = 'm';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 		ptr = remcom_out_buffer + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		if (remcom_in_buffer[1] == 'f') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 			/* Each cpu is a shadow thread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 			for_each_online_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 				ks->thr_query = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 				int_to_threadref(thref, -cpu - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 				ptr = pack_threadid(ptr, thref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 				*(ptr++) = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 				i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		for_each_process_thread(g, p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 			if (i >= ks->thr_query && !finished) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 				int_to_threadref(thref, p->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 				ptr = pack_threadid(ptr, thref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 				*(ptr++) = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 				ks->thr_query++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 				if (ks->thr_query % KGDB_MAX_THREAD_QUERY == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 					finished = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		*(--ptr) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	case 'C':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		/* Current thread id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		strcpy(remcom_out_buffer, "QC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		ks->threadid = shadow_pid(current->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		int_to_threadref(thref, ks->threadid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		pack_threadid(remcom_out_buffer + 2, thref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	case 'T':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		if (memcmp(remcom_in_buffer + 1, "ThreadExtraInfo,", 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		ks->threadid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		ptr = remcom_in_buffer + 17;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		kgdb_hex2long(&ptr, &ks->threadid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		if (!getthread(ks->linux_regs, ks->threadid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 			error_packet(remcom_out_buffer, -EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		if ((int)ks->threadid > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 			kgdb_mem2hex(getthread(ks->linux_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 					ks->threadid)->comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 					remcom_out_buffer, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 			static char tmpstr[23 + BUF_THREAD_ID_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 			sprintf(tmpstr, "shadowCPU%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 					(int)(-ks->threadid - 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 			kgdb_mem2hex(tmpstr, remcom_out_buffer, strlen(tmpstr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) #ifdef CONFIG_KGDB_KDB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	case 'R':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		if (strncmp(remcom_in_buffer, "qRcmd,", 6) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 			int len = strlen(remcom_in_buffer + 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 			if ((len % 2) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 				strcpy(remcom_out_buffer, "E01");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 			kgdb_hex2mem(remcom_in_buffer + 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 				     remcom_out_buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 			len = len / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 			remcom_out_buffer[len++] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 			kdb_common_init_state(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 			kdb_parse(remcom_out_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 			kdb_common_deinit_state();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 			strcpy(remcom_out_buffer, "OK");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) #ifdef CONFIG_HAVE_ARCH_KGDB_QXFER_PKT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	case 'S':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		if (!strncmp(remcom_in_buffer, "qSupported:", 11))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 			strcpy(remcom_out_buffer, kgdb_arch_gdb_stub_feature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	case 'X':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		if (!strncmp(remcom_in_buffer, "qXfer:", 6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 			kgdb_arch_handle_qxfer_pkt(remcom_in_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 						   remcom_out_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) /* Handle the 'H' task query packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) static void gdb_cmd_task(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	struct task_struct *thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	switch (remcom_in_buffer[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	case 'g':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		ptr = &remcom_in_buffer[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		kgdb_hex2long(&ptr, &ks->threadid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 		thread = getthread(ks->linux_regs, ks->threadid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		if (!thread && ks->threadid > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 			error_packet(remcom_out_buffer, -EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 		kgdb_usethread = thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 		ks->kgdb_usethreadid = ks->threadid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		strcpy(remcom_out_buffer, "OK");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	case 'c':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		ptr = &remcom_in_buffer[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 		kgdb_hex2long(&ptr, &ks->threadid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		if (!ks->threadid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 			kgdb_contthread = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 			thread = getthread(ks->linux_regs, ks->threadid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 			if (!thread && ks->threadid > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 				error_packet(remcom_out_buffer, -EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 			kgdb_contthread = thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		strcpy(remcom_out_buffer, "OK");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) /* Handle the 'T' thread query packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) static void gdb_cmd_thread(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	char *ptr = &remcom_in_buffer[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	struct task_struct *thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	kgdb_hex2long(&ptr, &ks->threadid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	thread = getthread(ks->linux_regs, ks->threadid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	if (thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 		strcpy(remcom_out_buffer, "OK");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		error_packet(remcom_out_buffer, -EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) /* Handle the 'z' or 'Z' breakpoint remove or set packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) static void gdb_cmd_break(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	 * Since GDB-5.3, it's been drafted that '0' is a software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	 * breakpoint, '1' is a hardware breakpoint, so let's do that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	char *bpt_type = &remcom_in_buffer[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	char *ptr = &remcom_in_buffer[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	unsigned long length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	if (arch_kgdb_ops.set_hw_breakpoint && *bpt_type >= '1') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		/* Unsupported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		if (*bpt_type > '4')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		if (*bpt_type != '0' && *bpt_type != '1')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 			/* Unsupported. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	 * Test if this is a hardware breakpoint, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	 * if we support it:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	if (*bpt_type == '1' && !(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		/* Unsupported. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	if (*(ptr++) != ',') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		error_packet(remcom_out_buffer, -EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	if (!kgdb_hex2long(&ptr, &addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		error_packet(remcom_out_buffer, -EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	if (*(ptr++) != ',' ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		!kgdb_hex2long(&ptr, &length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		error_packet(remcom_out_buffer, -EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	if (remcom_in_buffer[0] == 'Z' && *bpt_type == '0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		error = dbg_set_sw_break(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	else if (remcom_in_buffer[0] == 'z' && *bpt_type == '0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		error = dbg_remove_sw_break(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	else if (remcom_in_buffer[0] == 'Z')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 		error = arch_kgdb_ops.set_hw_breakpoint(addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 			(int)length, *bpt_type - '0');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	else if (remcom_in_buffer[0] == 'z')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		error = arch_kgdb_ops.remove_hw_breakpoint(addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 			(int) length, *bpt_type - '0');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	if (error == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 		strcpy(remcom_out_buffer, "OK");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 		error_packet(remcom_out_buffer, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) /* Handle the 'C' signal / exception passing packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) static int gdb_cmd_exception_pass(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	/* C09 == pass exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	 * C15 == detach kgdb, pass exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	if (remcom_in_buffer[1] == '0' && remcom_in_buffer[2] == '9') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		ks->pass_exception = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		remcom_in_buffer[0] = 'c';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	} else if (remcom_in_buffer[1] == '1' && remcom_in_buffer[2] == '5') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 		ks->pass_exception = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		remcom_in_buffer[0] = 'D';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		dbg_remove_all_break();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		kgdb_connected = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		gdbstub_msg_write("KGDB only knows signal 9 (pass)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 			" and 15 (pass and disconnect)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 			"Executing a continue without signal passing\n", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		remcom_in_buffer[0] = 'c';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	/* Indicate fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955)  * This function performs all gdbserial command procesing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) int gdb_serial_stub(struct kgdb_state *ks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	/* Initialize comm buffer and globals. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	memset(remcom_out_buffer, 0, sizeof(remcom_out_buffer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	kgdb_usethread = kgdb_info[ks->cpu].task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	ks->kgdb_usethreadid = shadow_pid(kgdb_info[ks->cpu].task->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	ks->pass_exception = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	if (kgdb_connected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		unsigned char thref[BUF_THREAD_ID_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		/* Reply to host that an exception has occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		ptr = remcom_out_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		*ptr++ = 'T';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		ptr = hex_byte_pack(ptr, ks->signo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 		ptr += strlen(strcpy(ptr, "thread:"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		int_to_threadref(thref, shadow_pid(current->pid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		ptr = pack_threadid(ptr, thref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 		*ptr++ = ';';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		put_packet(remcom_out_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		/* Clear the out buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		memset(remcom_out_buffer, 0, sizeof(remcom_out_buffer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		get_packet(remcom_in_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		switch (remcom_in_buffer[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		case '?': /* gdbserial status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 			gdb_cmd_status(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		case 'g': /* return the value of the CPU registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 			gdb_cmd_getregs(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		case 'G': /* set the value of the CPU registers - return OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 			gdb_cmd_setregs(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 		case 'm': /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 			gdb_cmd_memread(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA..AA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 			gdb_cmd_memwrite(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) #if DBG_MAX_REG_NUM > 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		case 'p': /* pXX Return gdb register XX (in hex) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 			gdb_cmd_reg_get(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		case 'P': /* PXX=aaaa Set gdb register XX to aaaa (in hex) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 			gdb_cmd_reg_set(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) #endif /* DBG_MAX_REG_NUM > 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		case 'X': /* XAA..AA,LLLL: Write LLLL bytes at address AA..AA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 			gdb_cmd_binwrite(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 			/* kill or detach. KGDB should treat this like a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 			 * continue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		case 'D': /* Debugger detach */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		case 'k': /* Debugger detach via kill */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 			gdb_cmd_detachkill(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 			goto default_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 		case 'R': /* Reboot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 			if (gdb_cmd_reboot(ks))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 				goto default_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		case 'q': /* query command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 			gdb_cmd_query(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		case 'H': /* task related */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 			gdb_cmd_task(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		case 'T': /* Query thread status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 			gdb_cmd_thread(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		case 'z': /* Break point remove */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		case 'Z': /* Break point set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 			gdb_cmd_break(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) #ifdef CONFIG_KGDB_KDB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		case '3': /* Escape into back into kdb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 			if (remcom_in_buffer[1] == '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 				gdb_cmd_detachkill(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 				return DBG_PASS_EVENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		case 'C': /* Exception passing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 			tmp = gdb_cmd_exception_pass(ks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 			if (tmp > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 				goto default_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 			if (tmp == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 			fallthrough;	/* on tmp < 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		case 'c': /* Continue packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		case 's': /* Single step packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 			if (kgdb_contthread && kgdb_contthread != current) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 				/* Can't switch threads in kgdb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 				error_packet(remcom_out_buffer, -EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 			fallthrough;	/* to default processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) default_handle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 			error = kgdb_arch_handle_exception(ks->ex_vector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 						ks->signo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 						ks->err_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 						remcom_in_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 						remcom_out_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 						ks->linux_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 			 * Leave cmd processing on error, detach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 			 * kill, continue, or single step.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 			if (error >= 0 || remcom_in_buffer[0] == 'D' ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 			    remcom_in_buffer[0] == 'k') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 				error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 				goto kgdb_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		/* reply to the request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		put_packet(remcom_out_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) kgdb_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	if (ks->pass_exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		error = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) int gdbstub_state(struct kgdb_state *ks, char *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	switch (cmd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	case 'e':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 		error = kgdb_arch_handle_exception(ks->ex_vector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 						   ks->signo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 						   ks->err_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 						   remcom_in_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 						   remcom_out_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 						   ks->linux_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	case 'c':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		strscpy(remcom_in_buffer, cmd, sizeof(remcom_in_buffer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	case '$':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		strscpy(remcom_in_buffer, cmd, sizeof(remcom_in_buffer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 		gdbstub_use_prev_in_buf = strlen(remcom_in_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		gdbstub_prev_in_buf_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	dbg_io_ops->write_char('+');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	put_packet(remcom_out_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)  * gdbstub_exit - Send an exit message to GDB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)  * @status: The exit code to report.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) void gdbstub_exit(int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	unsigned char checksum, ch, buffer[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	int loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	if (!kgdb_connected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	kgdb_connected = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	if (!dbg_io_ops || dbg_kdb_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	buffer[0] = 'W';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	buffer[1] = hex_asc_hi(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	buffer[2] = hex_asc_lo(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	dbg_io_ops->write_char('$');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	checksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	for (loop = 0; loop < 3; loop++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 		ch = buffer[loop];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		checksum += ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 		dbg_io_ops->write_char(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	dbg_io_ops->write_char('#');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	dbg_io_ops->write_char(hex_asc_hi(checksum));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	dbg_io_ops->write_char(hex_asc_lo(checksum));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	/* make sure the output is flushed, lest the bootloader clobber it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	if (dbg_io_ops->flush)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		dbg_io_ops->flush();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }