/*
 * Kernel Debugger Architecture Independent Breakpoint Handler
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (c) 1999-2004 Silicon Graphics, Inc.  All Rights Reserved.
 * Copyright (c) 2009 Wind River Systems, Inc.  All Rights Reserved.
 */

#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/kdb.h>
#include <linux/kgdb.h>
#include <linux/smp.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include "kdb_private.h"

/*
 * Table of kdb_breakpoints
 */
kdb_bp_t kdb_breakpoints[KDB_MAXBPT];

static void kdb_setsinglestep(struct pt_regs *regs)
{
	KDB_STATE_SET(DOING_SS);
}

static char *kdb_rwtypes[] = {
	"Instruction(i)",
	"Instruction(Register)",
	"Data Write",
	"I/O",
	"Data Access"
};

static char *kdb_bptype(kdb_bp_t *bp)
{
	if (bp->bp_type < 0 || bp->bp_type > 4)
		return "";

	return kdb_rwtypes[bp->bp_type];
}

static int kdb_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp)
{
	int nextarg = *nextargp;
	int diag;

	bp->bph_length = 1;
	if ((argc + 1) != nextarg) {
		if (strncasecmp(argv[nextarg], "datar", sizeof("datar")) == 0)
			bp->bp_type = BP_ACCESS_WATCHPOINT;
		else if (strncasecmp(argv[nextarg], "dataw", sizeof("dataw")) == 0)
			bp->bp_type = BP_WRITE_WATCHPOINT;
		else if (strncasecmp(argv[nextarg], "inst", sizeof("inst")) == 0)
			bp->bp_type = BP_HARDWARE_BREAKPOINT;
		else
			return KDB_ARGCOUNT;

		bp->bph_length = 1;

		nextarg++;

		if ((argc + 1) != nextarg) {
			unsigned long len;

			diag = kdbgetularg((char *)argv[nextarg],
					   &len);
			if (diag)
				return diag;


			if (len > 8)
				return KDB_BADLENGTH;

			bp->bph_length = len;
			nextarg++;
		}

		if ((argc + 1) != nextarg)
			return KDB_ARGCOUNT;
	}

	*nextargp = nextarg;
	return 0;
}

static int _kdb_bp_remove(kdb_bp_t *bp)
{
	int ret = 1;
	if (!bp->bp_installed)
		return ret;
	if (!bp->bp_type)
		ret = dbg_remove_sw_break(bp->bp_addr);
	else
		ret = arch_kgdb_ops.remove_hw_breakpoint(bp->bp_addr,
			 bp->bph_length,
			 bp->bp_type);
	if (ret == 0)
		bp->bp_installed = 0;
	return ret;
}

static void kdb_handle_bp(struct pt_regs *regs, kdb_bp_t *bp)
{
	if (KDB_DEBUG(BP))
		kdb_printf("regs->ip = 0x%lx\n", instruction_pointer(regs));

	/*
	 * Setup single step
	 */
	kdb_setsinglestep(regs);

	/*
	 * Reset delay attribute
	 */
	bp->bp_delay = 0;
	bp->bp_delayed = 1;
}

static int _kdb_bp_install(struct pt_regs *regs, kdb_bp_t *bp)
{
	int ret;
	/*
	 * Install the breakpoint, if it is not already installed.
	 */

	if (KDB_DEBUG(BP))
		kdb_printf("%s: bp_installed %d\n",
			   __func__, bp->bp_installed);
	if (!KDB_STATE(SSBPT))
		bp->bp_delay = 0;
	if (bp->bp_installed)
		return 1;
	if (bp->bp_delay || (bp->bp_delayed && KDB_STATE(DOING_SS))) {
		if (KDB_DEBUG(BP))
			kdb_printf("%s: delayed bp\n", __func__);
		kdb_handle_bp(regs, bp);
		return 0;
	}
	if (!bp->bp_type)
		ret = dbg_set_sw_break(bp->bp_addr);
	else
		ret = arch_kgdb_ops.set_hw_breakpoint(bp->bp_addr,
			 bp->bph_length,
			 bp->bp_type);
	if (ret == 0) {
		bp->bp_installed = 1;
	} else {
		kdb_printf("%s: failed to set breakpoint at 0x%lx\n",
			   __func__, bp->bp_addr);
#ifdef CONFIG_DEBUG_RODATA
		if (!bp->bp_type) {
			kdb_printf("Software breakpoints are unavailable.\n"
				   "  Change the kernel CONFIG_DEBUG_RODATA=n\n"
				   "  OR use hw breaks: help bph\n");
		}
#endif
		return 1;
	}
	return 0;
}

/*
 * kdb_bp_install
 *
 *	Install kdb_breakpoints prior to returning from the
 *	kernel debugger.  This allows the kdb_breakpoints to be set
 *	upon functions that are used internally by kdb, such as
 *	printk().  This function is only called once per kdb session.
 */
void kdb_bp_install(struct pt_regs *regs)
{
	int i;

	for (i = 0; i < KDB_MAXBPT; i++) {
		kdb_bp_t *bp = &kdb_breakpoints[i];

		if (KDB_DEBUG(BP)) {
			kdb_printf("%s: bp %d bp_enabled %d\n",
				   __func__, i, bp->bp_enabled);
		}
		if (bp->bp_enabled)
			_kdb_bp_install(regs, bp);
	}
}

/*
 * kdb_bp_remove
 *
 *	Remove kdb_breakpoints upon entry to the kernel debugger.
 *
 * Parameters:
 *	None.
 * Outputs:
 *	None.
 * Returns:
 *	None.
 * Locking:
 *	None.
 * Remarks:
 */
void kdb_bp_remove(void)
{
	int i;

	for (i = KDB_MAXBPT - 1; i >= 0; i--) {
		kdb_bp_t *bp = &kdb_breakpoints[i];

		if (KDB_DEBUG(BP)) {
			kdb_printf("%s: bp %d bp_enabled %d\n",
				   __func__, i, bp->bp_enabled);
		}
		if (bp->bp_enabled)
			_kdb_bp_remove(bp);
	}
}


/*
 * kdb_printbp
 *
 *	Internal function to format and print a breakpoint entry.
 *
 * Parameters:
 *	None.
 * Outputs:
 *	None.
 * Returns:
 *	None.
 * Locking:
 *	None.
 * Remarks:
 */

static void kdb_printbp(kdb_bp_t *bp, int i)
{
	kdb_printf("%s ", kdb_bptype(bp));
	kdb_printf("BP #%d at ", i);
	kdb_symbol_print(bp->bp_addr, NULL, KDB_SP_DEFAULT);

	if (bp->bp_enabled)
		kdb_printf("\n    is enabled");
	else
		kdb_printf("\n    is disabled");

	kdb_printf("\taddr at %016lx, hardtype=%d installed=%d\n",
		   bp->bp_addr, bp->bp_type, bp->bp_installed);

	kdb_printf("\n");
}

/*
 * kdb_bp
 *
 *	Handle the bp commands.
 *
 *	[bp|bph] <addr-expression> [DATAR|DATAW]
 *
 * Parameters:
 *	argc	Count of arguments in argv
 *	argv	Space delimited command line arguments
 * Outputs:
 *	None.
 * Returns:
 *	Zero for success, a kdb diagnostic if failure.
 * Locking:
 *	None.
 * Remarks:
 *
 *	bp	Set breakpoint on all cpus.  Only use hardware assist if need.
 *	bph	Set breakpoint on all cpus.  Force hardware register
 */

static int kdb_bp(int argc, const char **argv)
{
	int i, bpno;
	kdb_bp_t *bp, *bp_check;
	int diag;
	char *symname = NULL;
	long offset = 0ul;
	int nextarg;
	kdb_bp_t template = {0};

	if (argc == 0) {
		/*
		 * Display breakpoint table
		 */
		for (bpno = 0, bp = kdb_breakpoints; bpno < KDB_MAXBPT;
		     bpno++, bp++) {
			if (bp->bp_free)
				continue;
			kdb_printbp(bp, bpno);
		}

		return 0;
	}

	nextarg = 1;
	diag = kdbgetaddrarg(argc, argv, &nextarg, &template.bp_addr,
			     &offset, &symname);
	if (diag)
		return diag;
	if (!template.bp_addr)
		return KDB_BADINT;

	/*
	 * Find an empty bp structure to allocate
	 */
	for (bpno = 0, bp = kdb_breakpoints; bpno < KDB_MAXBPT; bpno++, bp++) {
		if (bp->bp_free)
			break;
	}

	if (bpno == KDB_MAXBPT)
		return KDB_TOOMANYBPT;

	if (strcmp(argv[0], "bph") == 0) {
		template.bp_type = BP_HARDWARE_BREAKPOINT;
		diag = kdb_parsebp(argc, argv, &nextarg, &template);
		if (diag)
			return diag;
	} else {
		template.bp_type = BP_BREAKPOINT;
	}

	/*
	 * Check for clashing breakpoints.
	 *
	 * Note, in this design we can't have hardware breakpoints
	 * enabled for both read and write on the same address.
	 */
	for (i = 0, bp_check = kdb_breakpoints; i < KDB_MAXBPT;
	     i++, bp_check++) {
		if (!bp_check->bp_free &&
		    bp_check->bp_addr == template.bp_addr) {
			kdb_printf("You already have a breakpoint at "
				   kdb_bfd_vma_fmt0 "\n", template.bp_addr);
			return KDB_DUPBPT;
		}
	}

	template.bp_enabled = 1;

	/*
	 * Actually allocate the breakpoint found earlier
	 */
	*bp = template;
	bp->bp_free = 0;

	kdb_printbp(bp, bpno);

	return 0;
}

/*
 * kdb_bc
 *
 *	Handles the 'bc', 'be', and 'bd' commands
 *
 *	[bd|bc|be] <breakpoint-number>
 *	[bd|bc|be] *
 *
 * Parameters:
 *	argc	Count of arguments in argv
 *	argv	Space delimited command line arguments
 * Outputs:
 *	None.
 * Returns:
 *	Zero for success, a kdb diagnostic for failure
 * Locking:
 *	None.
 * Remarks:
 */
static int kdb_bc(int argc, const char **argv)
{
	unsigned long addr;
	kdb_bp_t *bp = NULL;
	int lowbp = KDB_MAXBPT;
	int highbp = 0;
	int done = 0;
	int i;
	int diag = 0;

	int cmd;			/* KDBCMD_B? */
#define KDBCMD_BC	0
#define KDBCMD_BE	1
#define KDBCMD_BD	2

	if (strcmp(argv[0], "be") == 0)
		cmd = KDBCMD_BE;
	else if (strcmp(argv[0], "bd") == 0)
		cmd = KDBCMD_BD;
	else
		cmd = KDBCMD_BC;

	if (argc != 1)
		return KDB_ARGCOUNT;

	if (strcmp(argv[1], "*") == 0) {
		lowbp = 0;
		highbp = KDB_MAXBPT;
	} else {
		diag = kdbgetularg(argv[1], &addr);
		if (diag)
			return diag;

		/*
		 * For addresses less than the maximum breakpoint number,
		 * assume that the breakpoint number is desired.
		 */
		if (addr < KDB_MAXBPT) {
			bp = &kdb_breakpoints[addr];
			lowbp = highbp = addr;
			highbp++;
		} else {
			for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT;
			    i++, bp++) {
				if (bp->bp_addr == addr) {
					lowbp = highbp = i;
					highbp++;
					break;
				}
			}
		}
	}

	/*
	 * Now operate on the set of breakpoints matching the input
	 * criteria (either '*' for all, or an individual breakpoint).
	 */
	for (bp = &kdb_breakpoints[lowbp], i = lowbp;
	    i < highbp;
	    i++, bp++) {
		if (bp->bp_free)
			continue;

		done++;

		switch (cmd) {
		case KDBCMD_BC:
			bp->bp_enabled = 0;

			kdb_printf("Breakpoint %d at "
				   kdb_bfd_vma_fmt " cleared\n",
				   i, bp->bp_addr);

			bp->bp_addr = 0;
			bp->bp_free = 1;

			break;
		case KDBCMD_BE:
			bp->bp_enabled = 1;

			kdb_printf("Breakpoint %d at "
				   kdb_bfd_vma_fmt " enabled",
				   i, bp->bp_addr);

			kdb_printf("\n");
			break;
		case KDBCMD_BD:
			if (!bp->bp_enabled)
				break;

			bp->bp_enabled = 0;

			kdb_printf("Breakpoint %d at "
				   kdb_bfd_vma_fmt " disabled\n",
				   i, bp->bp_addr);

			break;
		}
		if (bp->bp_delay && (cmd == KDBCMD_BC || cmd == KDBCMD_BD)) {
			bp->bp_delay = 0;
			KDB_STATE_CLEAR(SSBPT);
		}
	}

	return (!done) ? KDB_BPTNOTFOUND : 0;
}

/*
 * kdb_ss
 *
 *	Process the 'ss' (Single Step) command.
 *
 *	ss
 *
 * Parameters:
 *	argc	Argument count
 *	argv	Argument vector
 * Outputs:
 *	None.
 * Returns:
 *	KDB_CMD_SS for success, a kdb error if failure.
 * Locking:
 *	None.
 * Remarks:
 *
 *	Set the arch specific option to trigger a debug trap after the next
 *	instruction.
 */

static int kdb_ss(int argc, const char **argv)
{
	if (argc != 0)
		return KDB_ARGCOUNT;
	/*
	 * Set trace flag and go.
	 */
	KDB_STATE_SET(DOING_SS);
	return KDB_CMD_SS;
}

/* Initialize the breakpoint table and register	breakpoint commands. */

void __init kdb_initbptab(void)
{
	int i;
	kdb_bp_t *bp;

	/*
	 * First time initialization.
	 */
	memset(&kdb_breakpoints, '\0', sizeof(kdb_breakpoints));

	for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++)
		bp->bp_free = 1;

	kdb_register_flags("bp", kdb_bp, "[<vaddr>]",
		"Set/Display breakpoints", 0,
		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
	kdb_register_flags("bl", kdb_bp, "[<vaddr>]",
		"Display breakpoints", 0,
		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
	if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT)
		kdb_register_flags("bph", kdb_bp, "[<vaddr>]",
		"[datar [length]|dataw [length]]   Set hw brk", 0,
		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
	kdb_register_flags("bc", kdb_bc, "<bpnum>",
		"Clear Breakpoint", 0,
		KDB_ENABLE_FLOW_CTRL);
	kdb_register_flags("be", kdb_bc, "<bpnum>",
		"Enable Breakpoint", 0,
		KDB_ENABLE_FLOW_CTRL);
	kdb_register_flags("bd", kdb_bc, "<bpnum>",
		"Disable Breakpoint", 0,
		KDB_ENABLE_FLOW_CTRL);

	kdb_register_flags("ss", kdb_ss, "",
		"Single Step", 1,
		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
	/*
	 * Architecture dependent initialization.
	 */
}
