/*
 * Copyright (c) 2015 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file Generic part of the GDB server
 *
 * This module provides the embedded GDB Remote Serial Protocol for Zephyr.
 *
 * The following is a list of all currently defined GDB RSP commands.
 *
 * `?'
 *     Indicate the reason the target halted.
 *
 * `c [addr]'
 *     Continue. addr is address to resume. If addr is omitted, resume at
 *     current address.
 *
 * `C sig[;addr]'
 *     Continue with signal sig (hex signal number). If `;addr' is omitted,
 *     resume at same address.
 *
 *     _WRS_XXX - Current limitation: Even if this syntax is understood, the
 *     GDB server does not resume the context with the specified signal but
 *     resumes it with the exception vector that caused the context to stop.
 *
 * `D'
 *     Detach GDB from the remote system.
 *
 * `g'
 *     Read general registers.
 *
 * `G XX...'
 *     Write general registers.
 *
 * `k'
 *     Detach GDB from the remote system.
 *
 * `m addr,length'
 *     Read length bytes of memory starting at address addr. Note that addr
 *     may not be aligned to any particular boundary.  The stub need not use
 *     any particular size or alignment when gathering data from memory for
 *     the response; even if addr is word-aligned and length is a multiple of
 *     the word size, the stub is free to use byte accesses, or not. For this
 *     reason, this packet may not be suitable for accessing memory-mapped I/O
 *     devices.
 *
 * `M addr,length:XX...'
 *     Write length bytes of memory starting at address addr. XX... is the data.
 *     Each byte is transmitted as a two-digit hexadecimal number.
 *
 * `p n'
 *     Read the value of register n; n is in hex.
 *
 * `P n...=r...'
 *     Write register n... with value r.... The register number n is in
 *     hexadecimal, and r... contains two hex digits for each byte in the
 *     register (target byte order).
 *
 * `q name params...'
 *     General query. See General Query Packets description
 *
 * `s [addr]'
 *     Single step. addr is the address at which to resume. If addr is omitted,
 *     resume at same address.
 *
 * `S sig[;addr]'
 *     Step with signal. This is analogous to the `C' packet, but requests a
 *     single-step, rather than a normal resumption of execution.
 *
 *     NOTE: Current limitation: Even if this syntax is understood, the GDB
 *     server steps the context without the specified signal (i.e like the
 *     `s [addr]' command).
 *
 * `T thread-id'
 *     Find out if the thread thread-id is alive.
 *
 * `vCont[;action[:thread-id]]...'
 *     Resume the inferior, specifying different actions for each thread. If an
 *     action is specified with no thread-id, then it is applied to any threads
 *     that don't have a specific action specified; if no default action is
 *     specified then other threads should remain stopped. Specifying multiple
 *     default actions is an error; specifying no actions is also an error.
 *
 *     Currently supported actions are:
 *
 *     `c'
 *         Continue.
 *     `C sig'
 *         Continue with signal sig. The signal sig should be two hex digits.
 *     `s'
 *         Step.
 *     `S sig'
 *         Step with signal sig. The signal sig should be two hex digits.
 *
 *     The optional argument addr normally associated with the `c', `C', `s',
 *     and `S' packets is not supported in `vCont'.
 *
 * `X addr,length:XX...'
 *     Write length bytes of memory starting at address addr, where the data
 *     is transmitted in binary. The binary data representation uses 7d (ascii
 *     ‘}’) as an escape character.  Any escaped byte is transmitted as the
 *     escape character followed by the original character XORed with 0x20.
 *
 * `z type,addr,length'
 * `Z type,addr,length'
 *     Insert (`Z') or remove (`z') a type breakpoint starting at addr address
 *     of length length.
 *
 * General Query Packets:
 * `qC'
 *     Return the current thread ID.
 *
 * `qSupported'
 *     Query the GDB server for features it supports. This packet allows
 *     client to take advantage of GDB server's features.
 *
 *     These are the currently defined GDB server features, in more detail:
 *
 *     `PacketSize=bytes'
 *         The GDB server can accept packets up to at least bytes in length.
 *         client will send packets up to this size for bulk transfers, and
 *         will never send larger packets. This is a limit on the data
 *         characters in the packet, including the frame and checksum. There
 *         is no trailing NUL byte in a remote protocol packet;
 *
 *     `qXfer:features:read'
 *         Access the target description. Target description can identify the
 *         architecture of the remote target and (for some architectures)
 *         provide information about custom register sets. They can also
 *         identify the OS ABI of the remote target. Client can use this
 *         information to autoconfigure for your target, or to warn you if you
 *         connect to an unsupported target.
 *
 *         By default, the following simple target description is supported:
 *
 *         <target version="1.0">
 *             <architecture>i386</architecture>
 *         </target>
 *
 *         But architectures may also reports information on specific features
 *         such as extended registers definitions or hardware breakpoint
 *         definitions.
 *
 *         Each `<feature>' describes some logical portion of the target
 *         system.
 *         A `<feature>' element has this form:
 *
 *         <feature name="NAME">
 *             [TYPE...]
 *             REG...
 *         </feature>
 *
 *         Each feature's name should be unique within the description.  The
 *         name of a feature does not matter unless GDB has some special
 *         knowledge of the contents of that feature; if it does, the feature
 *         should have its standard name.
 *
 *         Extended registers definitions are reported following the standard
 *         register format defined by GDB Remote protocol:
 *
 *         Each register is represented as an element with this form:
 *
 *         <reg name="NAME"
 *            bitsize="SIZE"
 *            [regnum="NUM"]
 *            [save-restore="SAVE-RESTORE"]
 *            [type="TYPE"]
 *            [group="GROUP"]/>
 *
 *         The components are as follows:
 *
 *         NAME
 *             The register's name; it must be unique within the target
 *             description.
 *
 *         BITSIZE
 *             The register's size, in bits.
 *
 *         REGNUM
 *             The register's number.  If omitted, a register's number is one
 *             greater than that of the previous register (either in the
 *             current feature or in a preceding feature); the first register
 *             in the target description defaults to zero.  This register
 *             number is used to read or write the register; e.g. it is used
 *             in the remote `p' and `P' packets, and registers appear in the
 *             `g' and `G' packets in order of increasing register number.
 *
 *         SAVE-RESTORE
 *             Whether the register should be preserved across inferior
 *             function calls; this must be either `yes' or `no'.  The default
 *             is `yes', which is appropriate for most registers except for
 *             some system control registers; this is not related to the
 *             target's ABI.
 *
 *         TYPE
 *             The type of the register.  TYPE may be a predefined type, a
 *             type defined in the current feature, or one of the special
 *             types `int' and `float'.  `int' is an integer type of the
 *             correct size for BITSIZE, and `float' is a floating point type
 *             (in the architecture's normal floating point format) of the
 *             correct size for BITSIZE.  The default is `int'.
 *
 *         GROUP
 *             The register group to which this register belongs.  GROUP must
 *             be either `general', `float', or `vector'.  If no GROUP is
 *             specified, GDB will not display the register in `info
 *             registers'.
 *
 *
 *         Hardware breakpoint definitions are reported using the following
 *         format:
 *
 *         <feature name="HW_BP_FEATURE">
 *             <defaults
 *                     max_bp="MAX_BP"
 *                     max_inst_bp="MAX_INST_BP"
 *                 max_watch_bp="MAX_WATCH_BP"
 *                 length="LENGTH"
 *                 >
 *             HW_BP_DESC...
 *         </feature>
 *
 *         The defaults section allows to define some default values and avoid
 *         to list them in each HW_BP_DESC.
 *
 *         Each HW_BP_DESC entry has the form:
 *
 *         <hwbp type="ACCESS_TYPE"
 *               [length="LENGTH"]
 *               [max_bp="MAX_BP"]
 *               />
 *
 *         If HW_BP_DESC defines an item which has a default value defined,
 *         then it overwrite the default value for HW_BP_DESC entry.
 *
 *         Items in [brackets] are optional. The components are as follows:
 *
 *         MAX_BP
 *             Maximum number of hardware breakpoints that can be set.
 *
 *         MAX_INST_BP
 *             Maximum number of instruction hardware breakpoints that can be
 *             set.
 *
 *         MAX_WATCH_BP
 *             Maximum number of data hardware breakpoints that can be set.
 *
 *         LENGTH
 *             Supported access lengths (in hexadecimal without 0x prefix).
 *             Access lengths are encoded as powers of 2 which can be OR'ed.
 *             For example, if an hardware breakpoint type supports 1, 2, 4,
 *             8 bytes access, length will be f (0x1|0x2|0x4|0x8).
 *
 *         ACCESS_TYPE
 *             Hardware breakpoint type:
 *                 inst  : Instruction breakpoint
 *                 watch : Write access breakpoint
 *                 rwatch: Read access breakpoint
 *                 awatch: Read|Write access breakpoint
 *
 *         The GDB server can also reports additional information using the
 *         "WR_AGENT_FEATURE" feature. The purpose of this feature is to report
 *         information about the agent configuration.
 *         The GDB server feature is using the following format:
 *
 *         <feature name="WR_AGENT_FEATURE">
 *             <config max_sw_bp="MAX_SW_BP"
 *                     step_only_on_bp="STEP_ONLY_ON_BP"
 *                     />
 *         </feature>
 *
 *         The components are as follows:
 *
 *         MAX_SW_BP
 *             Maximum number of software breakpoint that can be set.
 *
 *         STEP_ONLY_ON_BP
 *             This parameter is set to 1 if the GDB server is only able to
 *             step the context which hit the breakpoint.
 *             This parameter is set to 0 if the GDB server is able to step
 *             any context.
 *
 *     `QStartNoAckMode'
 *         By default, when either the client or the server sends a packet,
 *         the first response expected is an acknowledgment: either `+' (to
 *         indicate the package was received correctly) or `-' (to request
 *         retransmission). This mechanism allows the GDB remote protocol to
 *         operate over unreliable transport mechanisms, such as a serial
 *         line.
 *
 *         In cases where the transport mechanism is itself reliable (such as
 *         a pipe or TCP connection), the `+'/`-' acknowledgments are
 *         redundant. It may be desirable to disable them in that case to
 *         reduce communication overhead, or for other reasons. This can be
 *         accomplished by means of the `QStartNoAckMode' packet.
 *
 *     `CONFIG_GDB_REMOTE_SERIAL_EXT_NOTIF_PREFIX_STR`
 *         This parameter indicates that the GDB server supports transfer of
 *         Zephyr console I/O to the client using GDB notification packets.
 *
 *         NOTE: Current limitation: For now, the GDB server only supports the
 *         console output.
 *
 * Notification Packets:
 *     Extension of the GDB Remote Serial Protocol uses notification packets
 *     (See `CONFIG_GDB_REMOTE_SERIAL_EXT_NOTIF_PREFIX_STR` support).
 *     Those packets are transferred using the following format:
 *         %<notificationName:<notificationData>#<checksum>
 *
 *     For example:
 *       %CONFIG_GDB_REMOTE_SERIAL_EXT_NOTIF_PREFIX_STR:<notificationData>#<checksum>
 */

#include <kernel.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <kernel_structs.h>
#include <board.h>
#include <device.h>
#include <uart.h>
#include <cache.h>
#include <init.h>
#include <debug/gdb_arch.h>
#include <debug/mem_safe.h>
#include <gdb_server.h>
#include <debug_info.h>
#ifdef CONFIG_GDB_SERVER_INTERRUPT_DRIVEN
#include <drivers/console/uart_console.h>
#endif
#ifdef CONFIG_REBOOT
#include <misc/reboot.h>
#endif

#define STUB_OK "OK"
#define STUB_ERROR "ENN"

/* Size of notification data buffers */
#ifndef GDB_NOTIF_DATA_SIZE
#define GDB_NOTIF_DATA_SIZE 100
#endif

/* Overhead size for notification packet encoding. */
#define NOTIF_PACKET_OVERHEAD 6

/* Maximum number of software breakpoints */
#define MAX_SW_BP CONFIG_GDB_SERVER_MAX_SW_BP

#define GDB_INVALID_REG_SET ((void *)-1)

#define fill_output_buffer(x) strncpy((char *)gdb_buffer, x, GDB_BUF_SIZE - 1)

#ifdef CONFIG_GDB_SERVER_BOOTLOADER
#define STR_TYPE ";type=zephyr_boot"
#else
#define STR_TYPE ";type=zephyr"
#endif

#ifdef GDB_ARCH_HAS_RUNCONTROL
#define RESUME_SYSTEM() resume_system()
#define REMOVE_ALL_INSTALLED_BREAKPOINTS() \
	remove_all_installed_breakpoints()
#define UNINSTALL_BREAKPOINTS() uninstall_breakpoints()
#else
#define RESUME_SYSTEM()
#define REMOVE_ALL_INSTALLED_BREAKPOINTS()
#define UNINSTALL_BREAKPOINTS()
#endif

#ifdef GDB_ARCH_HAS_RUNCONTROL
struct bp_array {
	gdb_instr_t *addr;      /* breakpoint address */
	gdb_instr_t instr;      /* saved instruction */
	char valid;             /* breakpoint is valid? */
	char enabled;           /* breakpoint is enabled? */
};
#endif

static const unsigned char hex_chars[] = {
	'0', '1', '2', '3', '4', '5', '6', '7',
	'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};

static int client_is_connected;
static int in_no_ack_mode;
static int valid_registers;
static volatile int event_is_pending;
static volatile int cpu_stop_signal = GDB_SIG_NULL;
static volatile int cpu_pending_signal;
static struct gdb_reg_set gdb_regs;

static const char *xml_target_header =
	"<?xml version=\"1.0\"?> "
	"<!DOCTYPE target SYSTEM "
	"\"gdb-target.dtd\"> <target version=\"1.0\">\n";

static const char *xml_target_footer = "</target>";
static unsigned char gdb_buffer[GDB_BUF_SIZE];

static unsigned char tmp_reg_buffer[GDB_NUM_REG_BYTES];

#ifdef GDB_ARCH_HAS_RUNCONTROL

#ifdef GDB_ARCH_HAS_HW_BP
static int hw_bp_cnt;
static struct gdb_debug_regs dbg_regs;
#endif
static int trace_lock_key;

/*
 * GDB breakpoint table. Note that all the valid entries in the breakpoint
 * table are kept contiguous. When parsing the table, the first invalid entry
 * in the table marks the end of the table.
 */
static struct bp_array bp_array[MAX_SW_BP];

#ifdef GDB_ARCH_NO_SINGLE_STEP
static gdb_instr_t *gdb_step_emu_next_pc;
static gdb_instr_t gdb_step_emu_instr;
#endif

#endif

#ifdef GDB_ARCH_HAS_REMOTE_SERIAL_EXT_USING_NOTIF_PACKETS
static volatile int notif_pkt_pending;
static volatile int notif_data_idx;
static unsigned char notif_data[GDB_NOTIF_DATA_SIZE];
#endif

#ifdef CONFIG_GDB_SERVER_INTERRUPT_DRIVEN
static struct k_fifo avail_queue;
static struct k_fifo cmds_queue;
#endif

static struct device *uart_console_dev;

/* global definitions */

volatile int gdb_debug_status = NOT_DEBUGGING;

#ifdef GDB_ARCH_HAS_RUNCONTROL
#ifdef GDB_ARCH_HAS_HW_BP
volatile int cpu_stop_bp_type = GDB_SOFT_BP;
long cpu_stop_hw_bp_addr;
#endif
#endif

static int put_packet(unsigned char *buffer);
static void put_debug_char(unsigned char ch);
static unsigned char get_debug_char(void);

static void post_event(void);
static void control_loop(void);
static void handle_system_stop(NANO_ISF *reg, int sig);

#ifdef GDB_ARCH_HAS_RUNCONTROL

#define ADD_DEL_BP_SIG(x) \
	int(x)(enum gdb_bp_type type, long addr, int len, \
	       enum gdb_error_code *err)

typedef ADD_DEL_BP_SIG (add_del_bp_t);
static ADD_DEL_BP_SIG(add_bp);
static ADD_DEL_BP_SIG(delete_bp);

static void resume_system(void);
static int set_instruction(void *addr, gdb_instr_t *instruction, size_t size);
static void remove_all_installed_breakpoints(void);
#endif

#ifdef GDB_ARCH_HAS_REMOTE_SERIAL_EXT_USING_NOTIF_PACKETS
static void handle_notification(void);
static void request_notification_packet_flush(void);
static uint32_t write_to_console(char *buf, uint32_t len);
#endif

#ifdef CONFIG_GDB_SERVER_INTERRUPT_DRIVEN
static int console_irq_input_hook(uint8_t ch);
#endif

static int get_hex_char_value(unsigned char ch)
{
	if ((ch >= 'a') && (ch <= 'f')) {
		return ch - 'a' + 10;
	}
	if ((ch >= '0') && (ch <= '9')) {
		return ch - '0';
	}
	if ((ch >= 'A') && (ch <= 'F')) {
		return ch - 'A' + 10;
	}
	return -1;
}

/**
 * @brief Consume a hex number from a string and convert to long long number
 *
 * Consume the string up to the end of the hex number, i.e. the pointer to the
 * string is advanced and output that number via the @a value parameter.
 *
 * Does not handle negative numbers.
 *
 * @return The number of characters consumed from the string.
 */
static int hex_str_to_longlong(unsigned char **hex_str, long long *value)
{
	int num_chars_consumed = 0;
	int hex_value;

	*value = 0;
	while (**hex_str) {
		hex_value = get_hex_char_value(**hex_str);
		if (hex_value < 0) {
			break;
		}
		*value = (*value << 4) | hex_value;
		num_chars_consumed++;
		(*hex_str)++;
	}
	return num_chars_consumed;
}

/*
 * Similar to hex_str_to_longlong, but outputs an int and handles negative
 * numbers.
 */
static int hex_str_to_int(unsigned char **ptr, int *value)
{
	int num_chars_consumed = 0;
	int hex_value;
	int neg = 0;

	*value = 0;

	if (**ptr == '-') {
		neg = 1;
		(*ptr)++;
		num_chars_consumed++;
	}

	while (**ptr) {
		hex_value = get_hex_char_value(**ptr);
		if (hex_value < 0) {
			break;
		}
		*value = (*value << 4) | hex_value;
		num_chars_consumed++;
		(*ptr)++;
	}

	if (neg) {
		if (num_chars_consumed == 1) {
			(*ptr)--;
			num_chars_consumed = 0;
		} else {
			*value = -(*value);
		}
	}
	return num_chars_consumed;
}

/*
 * Consume two hex characters from a string and return the corresponding
 * value.
 */
static int hex_str_to_byte(unsigned char **str)
{
	unsigned char *ptr = *str;
	int byte;

	byte = get_hex_char_value(*ptr++);
	byte = (byte << 4) + get_hex_char_value(*ptr++);
	if (byte >= 0) {
		*str = ptr;
	}
	return byte;
}

/*
 * Turn a one-byte value into two hex characters and write them to the buffer.
 * Return the next position in the buffer.
 */

static unsigned char *put_hex_byte(unsigned char *buf, int value)
{
	*buf++ = hex_chars[value >> 4];
	*buf++ = hex_chars[value & 0xf];
	return buf;
}

static inline int is_size_encoder(int num)
{
	/*
	 * It is not possible to use the '$', '#' and '%' characters to encode
	 * the size per GDB remote protocol specification.
	 */
	return (num + 29) != '$' && (num + 29) != '#' && (num + 29) != '%';
}

/*
 * Compress memory pointed to by buffer into its ascii hex value, the
 * character '*' and the number of times it is reapeated, placing result in
 * the same buffer. Return a pointer to the last char put in buf (null).
 */

static unsigned char *compress(unsigned char *buf)
{
	unsigned char *read_ptr = buf;
	unsigned char *write_ptr = buf;
	unsigned char ch;
	size_t count = strlen((char *)buf);
	int max_repeat = 126 - 29;
	size_t ix;

	for (ix = 0; ix < count; ix++) {
		int num = 0;
		int jx;

		ch = *read_ptr++;
		*write_ptr++ = ch;
		for (jx = 1; ((jx + ix) < count) && (jx < max_repeat); jx++) {
			if (read_ptr[jx - 1] == ch) {
				num++;
			} else {
				break;
			}
		}
		if (num >= 3) {
			/*
			 * Skip characters that cannot be used as size
			 * encoders.
			 */
			while (!is_size_encoder(num)) {
				num--;
			}

			*write_ptr++ = '*';
			*write_ptr++ = (unsigned char)(num + 29);
			read_ptr += num;
			ix += num;
		}
	}
	*write_ptr = 0;
	return write_ptr;
}

/**
 * @brief encode memory data using hexadecimal value of chars from '0' to 'f'
 *
 * For example, 0x3 (CTRL+C) will be encoded with hexadecimal values of
 * '0' (0x30) and '3' (0x33): 0x3033.
 *
 * Use mem2hex() to encode a buffer avoid to send control chars that could
 * perturbate communication protocol.
 *
 * @param data to encode
 * @param output buffer
 * @param size of data to encode
 * @param Compress output data ?
 *
 * @return Pointer to the last char put in buf (null).
 */

static unsigned char *mem2hex(unsigned char *mem, unsigned char *buf,
			      int count, int do_compress)
{
	int i;
	unsigned char ch;
	unsigned char *saved_buf = buf;

	for (i = 0; i < count; i++) {
		ch = *mem++;
		buf = put_hex_byte(buf, ch);
	}
	*buf = 0;

	if (do_compress) {
		return compress(saved_buf);
	}

	return buf;
}

static inline int do_mem_probe(char *addr, int mode, int width,
			       int preserve, long *dummy)
{
	char *p = (char *)dummy;

	if (preserve) {
		if (_mem_probe(addr, SYS_MEM_SAFE_READ, width, p) < 0) {
			return -1;
		}
	}
	if (_mem_probe(addr, mode, width, p) < 0) {
		return -1;
	}

	return 0;
}

/**
 * @brief Probe if memory location is valid
 *
 * @param addr Address to test
 * @param mode Mode of access (SYS_MEM_SAFE_READ/WRITE)
 * @param size Number of bytes to test
 * @param width Width of memory access (1, 2, or 4)
 * @param preserve Preserve memory on write test ?
 *
 * @return 0 if memory is accessible, -1 otherwise.
 */

static int mem_probe(char *addr, int mode, int size,
		     int width, int preserve)
{
	long dummy;

	/* if memory length is zero, test is done */
	if (size == 0) {
		return 0;
	}

	/* Validate parameters */

	preserve = mode == SYS_MEM_SAFE_READ ? 0 : preserve;

	if (width == 0) {
		width = 1;
	} else {
		if ((width != 1) && (width != 2) && (width != 4)) {
			return -1;
		}
	}

	/* Check addr, size & width parameters coherency */

	if (((unsigned long)addr % width) || (size % width)) {
		return -1;
	}

	/* Check first address */

	if (do_mem_probe(addr, mode, width, preserve, &dummy) < 0) {
		return -1;
	}

	/* Check if we have tested the whole memory */

	if (width == size) {
		return 0;
	}

	/* Check last address */

	addr = addr + size - width;
	if (do_mem_probe(addr, mode, width, preserve, &dummy) < 0) {
		return -1;
	}

	return 0;
}

static int put_packet(unsigned char *buffer)
{
	unsigned char checksum = 0;
	int count = 0;
	unsigned char ch;

	/*  $<packet info>#<checksum>. */
	do {
		put_debug_char('$');
		checksum = 0;
		count = 0;

		/* Buffer terminated with null character */

		while ((ch = buffer[count])) {
			put_debug_char(ch);
			checksum = (unsigned char)(checksum + ch);
			count += 1;
		}

		put_debug_char('#');
		put_debug_char(hex_chars[(checksum >> 4)]);
		put_debug_char(hex_chars[(checksum & 0xf)]);

		if (!in_no_ack_mode) {
			/* Wait for ack */

			ch = get_debug_char();
			if (ch == '+') {
				return 0;
			}
			if (ch == '$') {
				put_debug_char('-');
				return 0;
			}
			if (ch == GDB_STOP_CHAR) {
				cpu_stop_signal = GDB_SIG_INT;
				gdb_debug_status = DEBUGGING;
				post_event();
				return 0;
			}
		} else {
			return 0;
		}
	} while (1);
}

#ifdef GDB_ARCH_HAS_REMOTE_SERIAL_EXT_USING_NOTIF_PACKETS
/*
 * Request a flush of pending notification packets. This is done by setting
 * notif_pkt_pending to 1 before stopping the CPU. Once stopped, the
 * control loop will send pending packets before resuming the system.
 */

static void request_notification_packet_flush(void)
{
	/*
	 * Before stopping CPU we must indicate that we're stopping the system
	 * to handle a packet notification. During the packet notification, we
	 * should prevent CPU from reading protocol...
	 */

	if (gdb_debug_status != NOT_DEBUGGING) {
		return;
	}
	notif_pkt_pending = 1;
	gdb_debug_status = DEBUGGING;
	control_loop();
	gdb_debug_status = NOT_DEBUGGING;
	RESUME_SYSTEM();
}

/*
 * If the notification buffer for current CPU is full, or if we found a new
 * line or carriage return character, then we must flush received data to
 * remote client.
 */
static inline int must_flush_notification_buffer(unsigned char ch)
{
	return (notif_data_idx == GDB_NOTIF_DATA_SIZE) ||
	       (ch == '\n') || (ch == '\r');
}

/*
 * Write data to debug agent console. For performance reason, the data is
 * bufferized until we receive a carriage return character or until the buffer
 * gets full.
 *
 * The buffer is also automatically flushed when system is stopped.
 */
static uint32_t write_to_console(char *buf, uint32_t len)
{
	uint32_t ix;
	unsigned char ch;

	int key = irq_lock();

	/* Copy data to notification buffer for current CPU */
	for (ix = 0; ix < len; ix++) {
		ch = buf[ix];
		notif_data[notif_data_idx++] = ch;

		if (must_flush_notification_buffer(ch)) {
			notif_data[notif_data_idx] = '\0';
			request_notification_packet_flush();
		}
	}

	irq_unlock(key);

	return len;
}

/*
 * Handle pending notification packets for the CPU. It is invoked while
 * running in GDB CPU control loop (When system is stopped).
 */
static void handle_notification(void)
{
	const char *name = CONFIG_GDB_REMOTE_SERIAL_EXT_NOTIF_PREFIX_STR;
	unsigned char checksum = 0;
	int ix = 0;
	unsigned char ch;
	int more_data = 0;
	uint32_t max_packet_size;
	uint32_t data_size;
	unsigned char *ptr = notif_data;

	/* First, check if there is pending data */

	if (notif_data[0] == '\0') {
		return;
	}

again:
	/*
	 * Build notification packet.
	 *
	 * A notification packet has the form `%<data>#<checksum>', where data
	 * is the content of the notification, and checksum is a checksum of
	 * data, computed and formatted as for ordinary gdb packets. A
	 * notification's data never contains `$', `%' or `#' characters. Upon
	 * receiving a notification, the recipient sends no `+' or `-' to
	 * acknowledge the notification's receipt or to report its corruption.
	 *
	 * Every notification's data begins with a name, which contains no
	 * colon characters, followed by a colon character.
	 */
	put_debug_char('%');
	checksum = 0;

	/* Add name to notification packet */
	ix = 0;
	while ((ch = name[ix++])) {
		put_debug_char(ch);
		checksum += ch;
	}

	/* Name must be followed by a colon character. */
	put_debug_char(':');
	checksum += ':';

	/*
	 * Add data to notification packet.
	 * Warning: The value to hex encoding double the size of the data,
	 * so we must not encode more than the remaining GDB buffer size
	 * divided by 2.
	 */
	max_packet_size =
		GDB_BUF_SIZE - (strlen(name) + NOTIF_PACKET_OVERHEAD);

	data_size = strlen((char *)ptr);
	if (data_size <= (max_packet_size / 2)) {
		more_data = 0;
	} else {
		data_size = max_packet_size / 2;
		more_data = 1;  /* Not enough room in notif packet */
	}

	/* Encode data using hex values */
	for (ix = 0; ix < data_size; ix++) {
		ch = hex_chars[(*ptr >> 4)];
		put_debug_char(ch);
		checksum += ch;
		ch = hex_chars[(*ptr & 0xf)];
		put_debug_char(ch);
		checksum += ch;
		ptr++;
	}

	/* Terminate packet with #<checksum> */
	put_debug_char('#');
	put_debug_char(hex_chars[(checksum >> 4)]);
	put_debug_char(hex_chars[(checksum & 0xf)]);

	if (more_data) {
		goto again;
	}

	/* Clear buffer & index */
	notif_data[0] = '\0';
	notif_data_idx = 0;
}
#endif

#ifdef GDB_ARCH_HAS_HW_BP
static int has_hit_a_hw_bp(void)
{
	/* instruction hw breakpoints are reported as sw breakpoints */
	return (cpu_stop_signal == GDB_SIG_TRAP) &&
	       (cpu_stop_bp_type != GDB_SOFT_BP) &&
	       (cpu_stop_bp_type != GDB_HW_INST_BP);
}
#endif

static void do_post_event_hw_bp(unsigned char **buf, size_t *buf_size)
{
#ifdef GDB_ARCH_HAS_HW_BP
	/*
	 * If it's an hardware breakpoint, report the address and access
	 * type at the origin of the HW breakpoint. Supported syntaxes:
	 *        watch:<dataAddr> : Write access
	 *        rwatch:<dataAddr> : Read access
	 *        awatch:<dataAddr> : Read/Write Access
	 * Instruction hardware breakpoints are reported as software
	 * breakpoints
	 */

	if (!has_hit_a_hw_bp()) {
		return;
	}

	int count = 0;

	switch (cpu_stop_bp_type) {
	case GDB_HW_DATA_WRITE_BP:
		count = snprintf((char *)*buf, *buf_size, ";watch");
		break;

	case GDB_HW_DATA_READ_BP:
		count = snprintf((char *)*buf, *buf_size, ";rwatch");
		break;

	case GDB_HW_DATA_ACCESS_BP:
		count = snprintf((char *)*buf, *buf_size, ";awatch");
		break;
	}
	if (count != 0) {
		*buf += count;
		*buf_size -= count;
		count = snprintf((char *)*buf, *buf_size, ":%lx",
				 cpu_stop_hw_bp_addr);
		*buf += count;
		*buf_size -= count;
	}
	cpu_stop_hw_bp_addr = 0;
	cpu_stop_bp_type = GDB_SOFT_BP;
	cpu_stop_signal = GDB_SIG_NULL;
#endif
}

static void write_regs_to_buffer(unsigned char **buf, size_t *buf_size)
{
	unsigned char *saved_buf;
	int count;

#ifdef GDB_ARCH_HAS_ALL_REGS
	count = snprintf((char *)*buf, *buf_size, ";regs:");
	*buf += count;
	*buf_size -= count;
	saved_buf = *buf;
	*buf = mem2hex(tmp_reg_buffer, *buf, sizeof(gdb_regs), 1);
	*buf_size -= (*buf - saved_buf);
#else
	int offset = 0;
	int size = 4;

	count = snprintf((char *)*buf, *buf_size, ";%x:", GDB_PC_REG);
	*buf += count;
	*buf_size -= count;
	gdb_arch_reg_info_get(GDB_PC_REG, &size, &offset);
	saved_buf = *buf;
	*buf = mem2hex(tmp_reg_buffer + offset, *buf, size, 1);
	*buf_size -= (*buf - saved_buf);
#endif
}

static void do_post_event(void)
{
	unsigned char *buf = gdb_buffer;
	size_t buf_size = GDB_BUF_SIZE;
	int count;

	if (buf != gdb_buffer) {
		*buf++ = '|';
		buf_size--;
	}
	count = snprintf((char *)buf, buf_size, "T%02xthread:%02x",
			 cpu_stop_signal, 1);
	buf += count;
	buf_size -= count;

	do_post_event_hw_bp(&buf, &buf_size);

	if (valid_registers) {
		gdb_arch_regs_get(&gdb_regs, (char *)tmp_reg_buffer);
		write_regs_to_buffer(&buf, &buf_size);
	}

	/* clear stop reason */
	cpu_stop_signal = GDB_SIG_NULL;

	*buf = '\0';
}

static void post_event(void)
{
	event_is_pending = 0;

	if (cpu_stop_signal != GDB_SIG_NULL) {
		do_post_event();
	} else {
		(void)snprintf((char *)gdb_buffer, GDB_BUF_SIZE, "S%02x",
			       GDB_SIG_INT);
	}

	(void)put_packet(gdb_buffer);
}

/**
 * @brief Get a character from serial line
 *
 * It loops until it has received a character or until it has detected that a
 * GDB event is pending and should be handled.
 *
 * Note that this routine should only be called from the gdb control loop when
 * the system is stopped.
 *
 * @return -1 if no character has been received and there is a GDB event
 * pending or debug operation pending, number of received character otherwise.
 */

static int get_debug_char_raw(void)
{
	unsigned char ch;

	while (uart_poll_in(uart_console_dev, &ch) != 0) {
		if (event_is_pending) {
			return -1;
		}
	}
	return ch;
}

static unsigned char get_debug_char(void)
{
	return (unsigned char)get_debug_char_raw();
}

/**
 * @brief Get a GDB serial packet
 *
 * Poll the serial line to get a full GDB serial packet. Once
 * the packet is received, it computes its checksum and return acknowledgment.
 * It then returns the packet to the caller.
 *
 * This routine must only be called when all CPUs are stopped (from the GDB
 * CPU control loop).
 *
 * If a pending GDB event is detected or if a stop event is received from the
 * client, the corresponding GDB stop event is sent to the client. This
 * loop does also handle the GDB cpu loop hooks by the intermediate of
 * get_debug_char() API.
 *
 * If a debug operation is pending, this routine returns immediately.
 *
 * @return Pointer to received packet or NULL on pending debug operation
 */

static unsigned char *get_packet(unsigned char *buffer, size_t size)
{
	unsigned char checksum, c, *p;

	while (1) {
		while ((c = get_debug_char()) != '$') {
			if (!event_is_pending) {
				return NULL;
			}

			/* ignore other chars than GDB break character */
			if ((c == GDB_STOP_CHAR) || event_is_pending) {
				post_event();
			}
		}

		checksum = 0;
		p = buffer;

		/*
		 * Continue reading characters until a '#' is found or until
		 * the end of the buffer is reached.
		 */

		while (p < &buffer[size]) {
			c = get_debug_char();

			if (c == '#') {
				break;
			} else if (c == '$') {
				/* start over */
				checksum = 0;
				p = buffer;
				continue;
			} else {
				checksum += c;
				*p++ = c;
			}
		}

		*p = 0;

		if (c == '#') {
			if (in_no_ack_mode) {
				(void)get_debug_char();
				(void)get_debug_char();
				return buffer;
			}

			unsigned char cs[2];

			cs[0] = get_hex_char_value(get_debug_char()) << 4;
			cs[1] = get_hex_char_value(get_debug_char());

			if (checksum != (cs[0] | cs[1])) {
				/* checksum failed */
				put_debug_char('-');
			} else {
				/* checksum passed */
				put_debug_char('+');

				if (buffer[2] == ':') {
					put_debug_char(buffer[0]);
					put_debug_char(buffer[1]);
					return &buffer[3];
				}
				return buffer;
			}
		}
	}

	return NULL;
}

/**
 * @brief write a XML string into output buffer
 *
 * It takes care of offset, length and also deal with overflow (if the XML
 * string is bigger than the output buffer).
 */

static void write_xml_string(char *buf, const char *xml_str, int off, int len)
{
	size_t max_len = strlen(xml_str);

	if (off == max_len) {
		strncat((char *)buf, "l", len - 1);
	} else if (off > max_len) {
		fill_output_buffer("E00");
	} else {
		if ((off + max_len) <= len) {
			/* we can read the full data */
			buf[0] = 'l';
			int size_to_copy = len <= (GDB_BUF_SIZE - 2) ? len :
					   GDB_BUF_SIZE - 2;
			strncpy(&buf[1], xml_str + off, size_to_copy);
		} else {
			buf[0] = 'm';
			strncpy(&buf[1], xml_str + off, GDB_BUF_SIZE - 2);
			buf[len + 1] = '\0';
		}
	}
}

/**
 * @brief get XML target description
 *
 * This routine is used to build the string that will hold the XML target
 * description provided to the GDB client.
 *
 * NOTE: Non-re-entrant, since it uses a static buffer.
 *
 * @return a pointer on XML target description
 */

static char *get_xml_target_description(void)
{
	static char target_description[GDB_BUF_SIZE] = { 0 };
	char *ptr = target_description;
	size_t buf_size = sizeof(target_description);
	size_t size;

	if (target_description[0] != 0) {
		return target_description;
	}

	strncpy(ptr, xml_target_header, GDB_BUF_SIZE - 1);
	size = strlen(ptr);
	ptr += size;
	buf_size -= size;

	/* Add architecture definition */

	(void)snprintf(ptr, buf_size, "  <architecture>%s</architecture>\n",
		       GDB_TGT_ARCH);
	size = strlen(ptr);
	ptr += size;
	buf_size -= size;

	strncpy(ptr, xml_target_footer,
		GDB_BUF_SIZE - (ptr - target_description) - 1);

	return target_description;
}

/* utility functions for handling each case of protocal_parse() */

static void handle_new_connection(void)
{
	/*
	 * This is a new connection. Clear in_no_ack_mode field if it was set
	 * and send acknowledgment for this command that has not been sent as
	 * it should have.
	 */
	if (in_no_ack_mode) {
		put_debug_char('+');
		in_no_ack_mode = 0;
	}

	snprintf((char *)gdb_buffer, GDB_BUF_SIZE, "T02thread:%02x;", 1);

	/*
	 * This is an initial connection, should remove all
	 * the breakpoints and cleanup.
	 */
	REMOVE_ALL_INSTALLED_BREAKPOINTS();
	client_is_connected = 1;
}

static void reboot(void)
{
#ifdef CONFIG_REBOOT
	sys_reboot(SYS_REBOOT_COLD);
	fill_output_buffer(STUB_OK);
#endif
}

static void detach(void)
{
	fill_output_buffer(STUB_OK);
	REMOVE_ALL_INSTALLED_BREAKPOINTS();
	client_is_connected = 0;
	gdb_debug_status = NOT_DEBUGGING;
	RESUME_SYSTEM();
	in_no_ack_mode = 0;
}

static unsigned char *handle_thread_query(unsigned char *packet)
{
	int thread;

	if (!hex_str_to_int(&packet, &thread)) {
		gdb_buffer[0] = '\0';
		return packet;
	}
	if (thread != 1) {
		fill_output_buffer(STUB_ERROR);
	} else {
		fill_output_buffer(STUB_OK);
	}

	return packet;
}

#ifdef CONFIG_REBOOT
#define STR_REBOOT ";reboot+"
static size_t concat_reboot_feature_if_supported(size_t size)
{
	strncat((char *)gdb_buffer, STR_REBOOT, size);
	return sizeof(STR_REBOOT);
}
#else
#define concat_reboot_feature_if_supported(size) (0)
#endif

static ALWAYS_INLINE int is_valid_xml_query(unsigned char **packet,
					    int *off, int *len)
{
	unsigned char *p = *packet;
	int is_valid = hex_str_to_int(&p, off) && *p++ == ','
		       && hex_str_to_int(&p, len) && *p == '\0';

	*packet = p;
	return is_valid;
}

static unsigned char *handle_xml_query(unsigned char *packet)
{
	int off, len;

	packet += 11;
	if (is_valid_xml_query(&packet, &off, &len)) {
		char *xml = get_xml_target_description();

		write_xml_string((char *)gdb_buffer, xml, off, len);
	} else {
		fill_output_buffer(STUB_ERROR);
	}

	return packet;
}

static const char *supported_features_cmd =
	"PacketSize=%x;qXfer:features:read+;QStartNoAckMode+"
#ifdef GDB_ARCH_HAS_REMOTE_SERIAL_EXT_USING_NOTIF_PACKETS
	";" CONFIG_GDB_REMOTE_SERIAL_EXT_NOTIF_PREFIX_STR "+"
#endif
;

static unsigned char *handle_general_query(unsigned char *packet)
{
	if (packet[0] == 'C') {
		snprintf((char *)gdb_buffer, GDB_BUF_SIZE, "QC%x", 1);
	} else if (strncmp((char *)packet, "wr.", 3) == 0) {
		packet += 3;
		gdb_buffer[0] = '\0';
	} else if (strcmp((char *)packet, "Supported") == 0) {
		size_t size = GDB_BUF_SIZE;

		snprintf((char *)gdb_buffer, size, supported_features_cmd,
			 GDB_BUF_SIZE);
		size -= (strlen((char *)gdb_buffer) + 1);

		size -= concat_reboot_feature_if_supported(size);

		strncat((char *)gdb_buffer, STR_TYPE, size);
		size -= sizeof(STR_TYPE);
	} else if (strncmp((char *)packet, "Xfer:features:read:", 19) == 0) {
		packet += 19;
		if (strncmp((char *)packet, "target.xml:", 11) == 0) {
			packet = handle_xml_query(packet);
		} else {
			gdb_buffer[0] = '\0';
		}
	} else {
		gdb_buffer[0] = '\0';
	}

	return packet;
}

static ALWAYS_INLINE void handle_get_registers(void)
{
	if (!valid_registers) {
		fill_output_buffer("E02");
		return;
	}
	(void)gdb_arch_regs_get(&gdb_regs, (char *)tmp_reg_buffer);
	mem2hex(tmp_reg_buffer, gdb_buffer, GDB_NUM_REG_BYTES, 1);
}

static ALWAYS_INLINE
unsigned char *handle_write_registers(unsigned char *packet)
{
	if (!valid_registers) {
		fill_output_buffer("E02");
		return packet;
	}

	(void)gdb_arch_regs_get(&gdb_regs, (char *)tmp_reg_buffer);

	for (int i = 0; i < GDB_NUM_REG_BYTES; i++) {
		int value = hex_str_to_byte(&packet);

		if (value < 0) {
			break;
		}
		tmp_reg_buffer[i] = (unsigned char)value;
	}

	gdb_arch_regs_set(&gdb_regs, (char *)tmp_reg_buffer);

	fill_output_buffer(STUB_OK);
	return packet;
}

#ifdef GDB_HAS_SINGLE_REG_ACCESS
static ALWAYS_INLINE
unsigned char *handle_write_single_register(unsigned char *packet)
{
	int reg_num = 0;
	int offset = 0;
	int size = 4;
	int i, value;

	if (!valid_registers) {
		fill_output_buffer("E02");
		return packet;
	}
	if (!hex_str_to_int(&packet, &reg_num) || *(packet++) != '=') {
		fill_output_buffer("E02");
		return packet;
	}

	gdb_arch_regs_get(&gdb_regs, (char *)tmp_reg_buffer);
	gdb_arch_reg_info_get(reg_num, &size, &offset);

	for (i = 0; i < size; i++) {
		value = hex_str_to_byte(&packet);
		if (value < 0) {
			break;
		}
		tmp_reg_buffer[offset + i] = (unsigned char)value;
	}
	if (i != size) {
		fill_output_buffer(STUB_ERROR);
		return packet;
	}
	gdb_arch_regs_set(&gdb_regs, (char *)tmp_reg_buffer);
	fill_output_buffer(STUB_OK);
	return packet;
}

static ALWAYS_INLINE
unsigned char *handle_read_single_register(unsigned char *packet)
{
	int reg_num = 0;
	int offset = 0;
	int size = 4;

	if (!valid_registers) {
		fill_output_buffer("E02");
		return packet;
	}
	/* p<regno> */

	if (!hex_str_to_int(&packet, &reg_num)) {
		fill_output_buffer("E02");
		return packet;
	}

	gdb_arch_regs_get(&gdb_regs, (char *)tmp_reg_buffer);
	gdb_arch_reg_info_get(reg_num, &size, &offset);
	mem2hex(tmp_reg_buffer + offset, gdb_buffer, size, 1);
	return packet;
}
#endif

static ALWAYS_INLINE
unsigned char *handle_read_memory(unsigned char *packet)
{
	/* m<addr>,<length> */

	long long addr;
	int length;
	void *p;

	if (hex_str_to_longlong((unsigned char **)&packet, &addr) == 0) {
		fill_output_buffer("E01");
		return packet;
	}

	if (!(*packet++ == ',' && hex_str_to_int(&packet, &length))) {
		fill_output_buffer("E01");
		return packet;
	}

	p = (void *)((long)addr);
	if (mem_probe(p, SYS_MEM_SAFE_READ, length, 0, 1) == -1) {
		/* No read access */
		fill_output_buffer("E01");
		return packet;
	}

	/* Now read memory */
	mem2hex(p, gdb_buffer, length, 1);
	return packet;
}

#define WRITE_MEM_SIG(x) \
	unsigned char *(x)(unsigned char *packet, unsigned char *dest, int len)
typedef WRITE_MEM_SIG (write_mem_t);

static ALWAYS_INLINE unsigned char *handle_write_memory(unsigned char *packet,
							write_mem_t *write_mem)
{
	long long addr;
	int len;
	unsigned char *p;

	/* [X or P]<addr>,<length>:<val><val>...<val> */

	if (hex_str_to_longlong(&packet, &addr) == 0) {
		fill_output_buffer("E02");
		return packet;
	}

	p = packet; /* to allow the if expression to fit on one line */
	if (!(*p++ == ',' && hex_str_to_int(&p, &len) && *p++ == ':')) {
		fill_output_buffer("E02");
		return p;
	}
	packet = p;

	p = (void *)((long)addr);
	if (mem_probe((char *) p, SYS_MEM_SAFE_WRITE, len, 0, 1) == -1) {
		/* No write access */
		fill_output_buffer("E02");
		return packet;
	}

	packet = write_mem(packet, p, len);

	fill_output_buffer(STUB_OK);
	return packet;
}

static WRITE_MEM_SIG(write_memory)
{
	unsigned char value;
	int i;

	for (i = 0; i < len; i++) {
		value = hex_str_to_byte(&packet);
		if (value < 0) {
			break;
		}
		dest[i] = (unsigned char)value;
	}

	return packet;
}

static WRITE_MEM_SIG(write_memory_from_binary_format)
{
	unsigned char value;
	int i;

	for (i = 0; i < len; i++) {
		value = packet[0];
		packet++;
		if (value == '}') {
			value = packet[0] ^ 0x20;
			packet++;
		}
		dest[i] = (unsigned char)value;
	}

	return packet;
}

static ALWAYS_INLINE
unsigned char *handle_pass_signal_to_context(unsigned char *packet)
{
	int signal;

	/* read signal number */
	if (!hex_str_to_int(&packet, &signal)) {
		fill_output_buffer("E02");
		return packet;
	}

	cpu_pending_signal = signal;

	if (*packet == ';') {
		packet++;
	}

	return packet;
}

static ALWAYS_INLINE
unsigned char *handle_continue_execution(unsigned char *packet)
{
	long long addr;

	/* try to read optional parameter, PC unchanged if no param */
	hex_str_to_longlong(&packet, &addr);
	gdb_debug_status = NOT_DEBUGGING;

	return packet;
}

static ALWAYS_INLINE unsigned char *handle_step(unsigned char *packet)
{
	long long addr;

	/* try to read optional parameter, PC unchanged if no param */
	hex_str_to_longlong(&packet, &addr);

	gdb_debug_status = SINGLE_STEP;

	return packet;
}

static ALWAYS_INLINE
unsigned char *handle_vcont_action(unsigned char *packet, int *do_not_send_ack)
{
	char action;
	int signal = 0, thread;

	packet += 5;
	action = *packet++;
	if ((action != 'c') && (action != 'C') &&
	    (action != 's') && (action != 'S')) {
		gdb_buffer[0] = '\0';
		return packet;
	}

	if ((action == 'C') || (action == 'S')) {
		/* read signal number */
		if (!hex_str_to_int(&packet, &signal)) {
			fill_output_buffer("E02");
			return packet;
		}
	}

	if (*packet == ':') {
		packet++;
		hex_str_to_int(&packet, &thread);
	}

	if (signal != 0) {
		cpu_pending_signal = signal;
	}

	if ((action == 'c') || (action == 'C')) {
		gdb_debug_status = NOT_DEBUGGING;
	} else {
		gdb_debug_status = SINGLE_STEP;
	}

	*do_not_send_ack = 1;
	return packet;
}

#ifdef GDB_ARCH_HAS_RUNCONTROL
static ALWAYS_INLINE
unsigned char *handle_breakpoint_install(unsigned char *packet,
					 add_del_bp_t *bp_op)
{
	/* remove (ztype,addr,length) or insert (Ztype,addr,length) */

	int type, len;
	long long addr;
	enum gdb_error_code err;

	/* read <type> & <addr> */
	if (!(hex_str_to_int(&packet, &type) && *packet++ == ',' &&
	      hex_str_to_longlong(&packet, &addr))) {
		fill_output_buffer("E07");
		return packet;
	}

	/* read length */
	if (!(*packet++ == ',' && hex_str_to_int(&packet, &len))) {
		fill_output_buffer("E07");
		return packet;
	}

	if (bp_op(type, (long)addr, len, &err) == 0) {
		fill_output_buffer(STUB_OK);
	} else {
		snprintf((char *)gdb_buffer, GDB_BUF_SIZE, "E%02d", err);
	}

	return packet;
}
#endif

/**
 * @brief parse given GDB command string
 *
 * Parse and execute the given GDB command string, and send acknowledgment if
 * acknowledgment is enabled.
 *
 * @return 0 on success, -1 if failed to send acknowledgment.
 */

static int protocol_parse(unsigned char *packet)
{
	unsigned char ch;
	int do_not_send_ack = 0;

	ch = *packet++;

	switch (ch) {
	case '?':
		handle_new_connection();
		break;
	case 'k':
		/* Kill request: we use it to reboot */
		reboot();
		break;
	case 'D':
		detach();
		break;
	case 'T':
		packet = handle_thread_query(packet);
		break;
	case 'Q':
		/* the only 'Q' command we support is "start no-ack mode" */
		if (strcmp((const char *)packet, "StartNoAckMode") == 0) {
			in_no_ack_mode = 1;
			fill_output_buffer(STUB_OK);
		} else {
			gdb_buffer[0] = '\0';
		}
		break;
	case 'q':
		packet = handle_general_query(packet);
		break;
	case 'g':
		handle_get_registers();
		break;
	case 'G':
		packet = handle_write_registers(packet);
		break;

#ifdef GDB_HAS_SINGLE_REG_ACCESS
	case 'P':
		packet = handle_write_single_register(packet);
		break;
	case 'p':
		packet = handle_read_single_register(packet);
		break;
#endif

	case 'm':
		packet = handle_read_memory(packet);
		break;
	case 'M':
		packet = handle_write_memory(packet, write_memory);
		break;
	case 'X':
		packet = handle_write_memory(packet,
					     write_memory_from_binary_format);
		break;

	case 'C':
		packet = handle_pass_signal_to_context(packet);
	/* fall through */
	case 'c':
		packet = handle_continue_execution(packet);
		do_not_send_ack = 1;
		break;

	case 'S':
		packet = handle_pass_signal_to_context(packet);
	/* fall through */
	case 's':
		packet = handle_step(packet);
		do_not_send_ack = 1;
		break;
	case 'v':
		if (strcmp((const char *)packet, "Cont?") == 0) {
			fill_output_buffer("vCont;c;s;C;S");
			break;
		} else if (strncmp((const char *)packet, "Cont;", 5) != 0) {
			gdb_buffer[0] = '\0';
			break;
		}

		packet = handle_vcont_action(packet, &do_not_send_ack);
		break;

#ifdef GDB_ARCH_HAS_RUNCONTROL
	case 'z':
		packet = handle_breakpoint_install(packet, delete_bp);
		break;
	case 'Z':
		packet = handle_breakpoint_install(packet, add_bp);
		break;
#endif
	default:
		/* in case of an unsupported command, send empty response */
		gdb_buffer[0] = '\0';
		break;
	}

	/* Send the acknowledgment command when necessary */

	if (!do_not_send_ack) {
		if (put_packet(gdb_buffer) < 0) {
			return -1;
		}
	}

	return 0;
}

/*
 * function: put_debug_char
 * description:
 *      - "What you must do for the stub"
 *      - Write a single character from a port.
 */
static void put_debug_char(unsigned char ch)
{
	(void)uart_poll_out(uart_console_dev, ch);
}

#ifdef GDB_ARCH_HAS_RUNCONTROL

/**
 * @brief add an hardware breakpoint to debug registers set
 *
 * This routine adds an hardware breakpoint to debug registers structure.
 * It does not update the debug registers.
 *
 * @param addr Address where to set the breakpoint
 * @param type Type of breakpoint
 * @param len Length of data
 * @param err Container for returning error code
 *
 * @return 0 on success, -1 if failed (Error code returned via @a err).
 */

static int add_hw_bp(long addr, enum gdb_bp_type type, int len,
		     enum gdb_error_code *err)
{
#ifdef GDB_ARCH_HAS_HW_BP
	if (gdb_hw_bp_set(&dbg_regs, addr, type, len, err) == -1) {
		return -1;
	}

	hw_bp_cnt++;
	return 0;
#else
	*err = GDB_ERROR_HW_BP_NOT_SUP;
	return -1;
#endif
}

/**
 * @brief remove an hardware breakpoint from debug registers set
 *
 * This routine removes an hardware breakpoint from debug registers structure.
 * It does not update the debug registers.
 *
 * @param addr Address where to set the breakpoint
 * @param type Type of breakpoint
 * @param len Length of data
 * @param err Container for returning error code
 *
 * @return 0 on success, -1 if failed (Error code returned via @a err).
 */

static int remove_hw_bp(long addr, enum gdb_bp_type type, int len,
			enum gdb_error_code *err)
{
#ifdef GDB_ARCH_HAS_HW_BP
	if (gdb_hw_bp_clear(&dbg_regs, addr, type, len, err) == -1) {
		return -1;
	}

	hw_bp_cnt--;
	return 0;
#else
	*err = GDB_ERROR_HW_BP_NOT_SUP;
	return -1;
#endif
}

/**
 * @brief add a new breakpoint or watchpoint to breakpoint list
 *
 * This routine adds a new breakpoint or watchpoint to breakpoint list. For
 * watchpoints, this routine checks that the given type/length combination is
 * supported on current architecture, and that debug registers are not full.
 *
 * @param type GDB breakpoint type:
 *
 *        0 : software breakpoint    (GDB_SOFT_BP)
 *        1 : hardware breakpoint    (GDB_HW_INST_BP)
 *        2 : write watchpoint       (GDB_HW_DATA_WRITE_BP)
 *        3 : read watchpoint        (GDB_HW_DATA_READ_BP)
 *        4 : access watchpoint      (GDB_HW_DATA_ACCESS_BP)
 *
 * @param addr Breakpoint address
 * @param len For a software breakpoint, len specifies the size of the
 *            instruction to be patched. For hardware breakpoints and
 *            watchpoints length specifies the memory region to be monitored.
 * @param err Pointer to error code if failed to add breakpoint.
 *
 * @return 0 on success, -1 if failed to add breakpoint.
 */

static int add_bp(enum gdb_bp_type type, long addr, int len,
		  enum gdb_error_code *err)
{
	if (type != GDB_SOFT_BP) {
		return add_hw_bp(addr, type, len, err);
	}

	if (mem_probe((void *)addr, SYS_MEM_SAFE_READ, len, 0, 1) == -1) {
		*err = GDB_ERROR_INVALID_MEM;
		return -1;
	}

	/* Add software breakpoint to BP list */

	for (int ix = 0; ix < MAX_SW_BP; ix++) {
		if (bp_array[ix].valid == 0) {
			bp_array[ix].valid = 1;
			bp_array[ix].enabled = 0;
			bp_array[ix].addr = (gdb_instr_t *)addr;
			return 0;
		}
	}

	*err = GDB_ERROR_BP_LIST_FULL;
	return -1;
}

/**
 * @brief delete a breakpoint or watchpoint from breakpoint list
 *
 * @return 0 on success, -1 if failed to remove breakpoint.
 */

static int delete_bp(enum gdb_bp_type type, long addr, int len,
		     enum gdb_error_code *err)
{
	gdb_instr_t *bp_addr = (gdb_instr_t *)addr;

	if (type != GDB_SOFT_BP) {
		return remove_hw_bp(addr, type, len, err);
	}

	for (int ix = 0; ix < MAX_SW_BP; ix++) {
		if (bp_array[ix].valid && bp_array[ix].addr == bp_addr) {

			bp_array[ix].valid = 0;

			/*
			 * Make sure all valid entries are contiguous to speed
			 * up breakpoint table parsing.
			 */

			for (int jx = ix + 1; jx < MAX_SW_BP; jx++) {
				if (bp_array[jx].valid == 1) {
					bp_array[jx - 1] = bp_array[jx];
					bp_array[jx].valid = 0;
				} else {
					break;
				}
			}

			return 0;

		} else if (!bp_array[ix].valid) {
			break;
		}
	}

	*err = GDB_ERROR_INVALID_BP;
	return -1;
}

static void remove_all_installed_breakpoints(void)
{
	for (int ix = 0; ix < MAX_SW_BP; ix++) {
		if (!bp_array[ix].valid) {
			break;
		}
		bp_array[ix].valid = 0;
	}
}

#ifdef GDB_ARCH_HAS_HW_BP
static inline void set_debug_regs_for_hw_breakpoints(void)
{
	if (hw_bp_cnt > 0) {
		gdb_dbg_regs_set(&dbg_regs);
	}
}
#else
#define set_debug_regs_for_hw_breakpoints() do { } while ((0))
#endif

/*
 * Physically install breakpoints, and make sure that modified memory is
 * flushed on all CPUs.
 *
 * Must only be called when ready to exit the CPU control loop.
 */

static void install_breakpoints(void)
{
	gdb_instr_t instr = GDB_BREAK_INSTRUCTION;

	/* Software breakpoints installation */

	for (int ix = 0; ix < MAX_SW_BP; ix++) {
		if (bp_array[ix].valid && !bp_array[ix].enabled) {
			gdb_instr_t *addr = bp_array[ix].addr;

			bp_array[ix].instr = *addr;
			(void)set_instruction(addr, &instr, sizeof(instr));
			bp_array[ix].enabled = 1;
		} else if (!bp_array[ix].valid) {
			break;
		}
	}

	set_debug_regs_for_hw_breakpoints();
}


#ifdef GDB_ARCH_HAS_HW_BP
static inline void clear_debug_regs_for_hw_breakpoints(void)
{
	if (hw_bp_cnt > 0) {
		gdb_dbg_regs_clear();
	}
}
#else
#define clear_debug_regs_for_hw_breakpoints() do { } while ((0))
#endif

/*
 * Physically uninstall breakpoints, and make sure that modified memory is
 * flushed on all CPUs.
 *
 * Must only be called in the CPU control loop.
 */

static void uninstall_breakpoints(void)
{
	for (int ix = 0; ix < MAX_SW_BP; ix++) {
		if (bp_array[ix].valid == 1 && bp_array[ix].enabled) {
			gdb_instr_t *addr = bp_array[ix].addr;
			(void)set_instruction(addr, &bp_array[ix].instr,
					      sizeof(gdb_instr_t));
			bp_array[ix].enabled = 0;
		} else if (bp_array[ix].valid == 0) {
			break;
		}
	}

	clear_debug_regs_for_hw_breakpoints();
}

/* Re-install breakpoints and resume the system. */

static void resume_system(void)
{
	/*
	 * System must not be resumed if we're going to execute a single step.
	 */

	if (gdb_debug_status == SINGLE_STEP) {
		return;
	}

	install_breakpoints();
}

static inline void enter_trace_mode(void)
{
#ifdef GDB_ARCH_NO_SINGLE_STEP
	gdb_instr_t bp_instr = GDB_BREAK_INSTRUCTION;

	gdb_step_emu_next_pc = gdb_get_next_pc(&gdb_regs);
	gdb_step_emu_instr = *gdb_step_emu_next_pc;
	(void)set_instruction(gdb_step_emu_next_pc, &bp_instr,
			      sizeof(gdb_instr_t));
	trace_lock_key = gdb_int_regs_lock(&gdb_regs);
#else
	/* Handle single step request for runcontrol CPU */

	trace_lock_key = gdb_trace_mode_set(&gdb_regs);
#endif
}
static inline void disable_trace_mode(void)
{
#ifdef GDB_ARCH_NO_SINGLE_STEP
	/* remove temporary breakpoint */
	(void)set_instruction(gdb_step_emu_next_pc,
			      &gdb_step_emu_instr,
			      sizeof(gdb_instr_t));
	/* Disable trace mode */
	gdb_int_regs_unlock(&gdb_regs, trace_lock_key);
#else
	/* Disable trace mode */
	gdb_trace_mode_clear(&gdb_regs, trace_lock_key);
#endif
}

/**
 * @brief stop mode agent BP/trace handler
 *
 * Common handler of breakpoint and trace mode exceptions.
 * It is invoked with interrupts locked.
 *
 * @return n/a
 */

void gdb_handler(enum gdb_exc_mode mode, void *esf, int signal)
{
	/* Save BP/Trace handler registers */
	gdb_arch_regs_from_esf(&gdb_regs, (NANO_ESF *)esf);
	valid_registers = 1;

	if (mode == GDB_EXC_TRACE) {
		/* Check if GDB did request a step */
		if (gdb_debug_status != SINGLE_STEP) {
			return;
		}

		/* No longer pending trace mode exception */
		gdb_debug_status = DEBUGGING;

		disable_trace_mode();
	}

	event_is_pending = 1;
	cpu_stop_signal = signal;

	/* Enter stop mode agent control loop */
	control_loop();

	/* Restore BP handler registers */
	gdb_arch_regs_to_esf(&gdb_regs, (NANO_ESF *)esf);

	/* Resume system if not handling a single step */
	RESUME_SYSTEM();
}

static int set_instruction(void *addr, gdb_instr_t *instr, size_t size)
{

	if (_mem_safe_write_to_text_section(addr, (char *)instr, size) < 0) {
		return -EFAULT;
	}
	sys_cache_flush((vaddr_t) addr, size);
	return 0;
}

#endif /* GDB_ARCH_HAS_RUNCONTROL */

static inline void setup_singlestep_if_non_steppable_instruction(void)
{
#ifdef GDB_ARCH_CAN_STEP
	if (gdb_debug_status == SINGLE_STEP) {
		if (!GDB_ARCH_CAN_STEP(&gdb_regs)) {
			gdb_debug_status = DEBUGGING;
			event_is_pending = 1;
			cpu_stop_signal = GDB_SIG_TRAP;
		}
	}
#endif
}

static inline int handle_single_stepping(void)
{
#ifdef GDB_ARCH_HAS_RUNCONTROL
	setup_singlestep_if_non_steppable_instruction();

	if (gdb_debug_status == SINGLE_STEP) {
		enter_trace_mode();
		return 1;
	}
#endif
	return 0;
}

/**
 * @brief GDB control loop
 *
 * The CPU control loop is an active wait loop used to stop CPU activity.
 *
 * It must be called with interrupts locked.
 *
 * It loops while waiting for debug events which can be:
 *
 * - System resumed: gdb_debug_status != NOT_DEBUGGING
 *       The control loop must be exited.
 *
 * - Single step request: gdb_debug_status == SINGLE_STEP
 *       Notify client that CPU is already stopped.
 *       This is done by setting event_is_pending = 1.
 *       event_is_pending will be handled by next get_packet().
 *
 * @return n/a
 */

static void control_loop(void)
{
	unsigned char ch;

	UNINSTALL_BREAKPOINTS();

	/* Flush input buffer */
	while (uart_poll_in(uart_console_dev, &ch) == 0) {
		if (ch == GDB_STOP_CHAR) {
			gdb_debug_status = DEBUGGING;
			cpu_stop_signal = GDB_SIG_INT;
			event_is_pending = 1;
			break;
		}
	}

	while (gdb_debug_status != NOT_DEBUGGING) {
#ifdef GDB_ARCH_HAS_REMOTE_SERIAL_EXT_USING_NOTIF_PACKETS
		/*
		 * Check if system has been stopped to handle a notification
		 * packet: If a notification is pending (notif_pkt_pending),
		 * but no stop signal has been set.
		 */
		if ((cpu_stop_signal == GDB_SIG_NULL) && notif_pkt_pending) {
			handle_notification();
			/* Mark packet notification as done */
			notif_pkt_pending = 0;
			break;
		}
#endif

		unsigned char *packet = get_packet(gdb_buffer, GDB_BUF_SIZE);

		if (packet) {
			protocol_parse(packet);
		}

		if (handle_single_stepping()) {
			return;
		}
	}
}

/**
 * @brief handle a system stop request
 *
 * The purpose of this routine is to handle a stop request issued by remote
 * debug client. It is called when receiving a break char.
 *
 * It indicates that a GDB event is pending (the answer to stop request) and
 * transfer control from the runtime system to the stop mode agent. The event
 * will be posted by this control loop.
 *
 * @return n/a
 */

static void handle_system_stop(NANO_ISF *regs, int signal)
{
	int key = irq_lock();

	gdb_debug_status = DEBUGGING;
	if (signal != 0) {
		cpu_stop_signal = signal;
	} else {
		cpu_stop_signal = GDB_SIG_INT;  /* Stopped by a command */
	}

	/* Save registers */
	if (regs == GDB_INVALID_REG_SET) {
		valid_registers = 0;
	} else {
		if (!regs) {
			regs = sys_debug_current_isf_get();
		}
		gdb_arch_regs_from_isf(&gdb_regs, regs);
		valid_registers = 1;
	}

	/* A GDB event is pending */
	event_is_pending = 1;

	/* Transfer control to the control loop */
	control_loop();

	/* Load registers */
	if (valid_registers) {
		gdb_arch_regs_to_isf(&gdb_regs, regs);
	}

	/* Resume system if not a single step request */
	RESUME_SYSTEM();

	irq_unlock(key);
}

/**
 * @brief wrapper to send a character to console
 *
 * This routine is a specific wrapper to send a character to console.
 * If the GDB Server is started, this routine intercepts the data and transfer
 * it to the connected debug clients using a GDB notification packet.
 *
 * @return n/a
 */

static UART_CONSOLE_OUT_DEBUG_HOOK_SIG(gdb_console_out)
{
#ifdef GDB_ARCH_HAS_REMOTE_SERIAL_EXT_USING_NOTIF_PACKETS
	/*
	 * If remote debug client is connected, then transfer data to remote
	 * client. Otherwise, discard this character.
	 */
	if (client_is_connected) {
		write_to_console(&c, 1);
		return UART_CONSOLE_DEBUG_HOOK_HANDLED;
	}
#endif
	return !UART_CONSOLE_DEBUG_HOOK_HANDLED;
}

#ifdef CONFIG_GDB_SERVER_INTERRUPT_DRIVEN
static int console_irq_input_hook(uint8_t ch)
{
	if (ch == GDB_STOP_CHAR) {
		(void)irq_lock();

		handle_system_stop(NULL, 0);
		return 1;
	}
	return 0;
}
#endif

void system_stop_here(void *regs)
{
	int key = irq_lock();

	handle_system_stop((NANO_ISF *) regs, GDB_SIG_STOP);

	irq_unlock(key);
}

void _debug_fatal_hook(const NANO_ESF *esf)
{
	struct gdb_reg_set regs;

	gdb_arch_regs_from_esf(&regs, (NANO_ESF *) esf);
	system_stop_here((void *)&regs);
	gdb_arch_regs_to_esf(&regs, (NANO_ESF *) esf);
}

#ifdef CONFIG_GDB_SERVER_INTERRUPT_DRIVEN
static void init_interrupt_handling(void)
{
	k_fifo_init(&cmds_queue);
	k_fifo_init(&avail_queue);
	uart_console_in_debug_hook_install(console_irq_input_hook);
	uart_register_input(&avail_queue, &cmds_queue, NULL);
}
#else
#define init_interrupt_handling() do { } while ((0))
#endif

#ifdef CONFIG_MEM_SAFE_NUM_EXTRA_REGIONS
static void init_mem_safe_access(void)
{
	(void)_mem_safe_region_add((void *)CONFIG_GDB_RAM_ADDRESS,
				   CONFIG_GDB_RAM_SIZE, SYS_MEM_SAFE_READ);
	(void)_mem_safe_region_add((void *)CONFIG_GDB_RAM_ADDRESS,
				   CONFIG_GDB_RAM_SIZE, SYS_MEM_SAFE_WRITE);
}
#else
#define init_mem_safe_access() do { } while ((0))
#endif

static int init_gdb_server(struct device *unused)
{
	static int gdb_is_initialized;

	if (gdb_is_initialized) {
		return -1;
	}

	gdb_arch_init();

	uart_console_dev = device_get_binding(CONFIG_UART_CONSOLE_ON_DEV_NAME);

	uart_console_out_debug_hook_install(gdb_console_out);

	init_interrupt_handling();
	init_mem_safe_access();

	gdb_is_initialized = 1;
	system_stop_here(GDB_INVALID_REG_SET);

	return 0;
}

SYS_INIT(init_gdb_server, POST_KERNEL, 1);
