/*
 * BedBug Functions
 */

#include <common.h>
#include <command.h>
#include <linux/ctype.h>
#include <net.h>
#include <bedbug/type.h>
#include <bedbug/bedbug.h>
#include <bedbug/regs.h>
#include <bedbug/ppc.h>

DECLARE_GLOBAL_DATA_PTR;

extern void show_regs __P ((struct pt_regs *));
extern int run_command __P ((const char *, int));
extern char console_buffer[];

ulong dis_last_addr = 0;	/* Last address disassembled   */
ulong dis_last_len = 20;	/* Default disassembler length */
CPU_DEBUG_CTX bug_ctx;		/* Bedbug context structure    */


/* ======================================================================
 * U-Boot's puts function does not append a newline, so the bedbug stuff
 * will use this for the output of the dis/assembler.
 * ====================================================================== */

int bedbug_puts (const char *str)
{
	/* -------------------------------------------------- */

	printf ("%s\r\n", str);
	return 0;
}				/* bedbug_puts */



/* ======================================================================
 * Initialize the bug_ctx structure used by the bedbug debugger.  This is
 * specific to the CPU since each has different debug registers and
 * settings.
 * ====================================================================== */

void bedbug_init (void)
{
	/* -------------------------------------------------- */

#if defined(CONFIG_4xx)
	void bedbug405_init (void);

	bedbug405_init ();
#elif defined(CONFIG_8xx)
	void bedbug860_init (void);

	bedbug860_init ();
#endif

#if defined(CONFIG_MPC824X) || defined(CONFIG_MPC8260)
	/* Processors that are 603e core based */
	void bedbug603e_init (void);

	bedbug603e_init ();
#endif

	return;
}				/* bedbug_init */



/* ======================================================================
 * Entry point from the interpreter to the disassembler.  Repeated calls
 * will resume from the last disassembled address.
 * ====================================================================== */
int do_bedbug_dis (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	ulong addr;		/* Address to start disassembly from    */
	ulong len;		/* # of instructions to disassemble     */

	/* -------------------------------------------------- */

	/* Setup to go from the last address if none is given */
	addr = dis_last_addr;
	len = dis_last_len;

	if (argc < 2)
		return cmd_usage(cmdtp);

	if ((flag & CMD_FLAG_REPEAT) == 0) {
		/* New command */
		addr = simple_strtoul (argv[1], NULL, 16);

		/* If an extra param is given then it is the length */
		if (argc > 2)
			len = simple_strtoul (argv[2], NULL, 16);
	}

	/* Run the disassembler */
	disppc ((unsigned char *) addr, 0, len, bedbug_puts, F_RADHEX);

	dis_last_addr = addr + (len * 4);
	dis_last_len = len;
	return 0;
}				/* do_bedbug_dis */

U_BOOT_CMD (ds, 3, 1, do_bedbug_dis,
	    "disassemble memory",
	    "ds <address> [# instructions]");

/* ======================================================================
 * Entry point from the interpreter to the assembler.  Assembles
 * instructions in consecutive memory locations until a '.' (period) is
 * entered on a line by itself.
 * ====================================================================== */
int do_bedbug_asm (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	long mem_addr;		/* Address to assemble into     */
	unsigned long instr;	/* Machine code for text        */
	char prompt[15];	/* Prompt string for user input */
	int asm_err;		/* Error code from the assembler */

	/* -------------------------------------------------- */
	int rcode = 0;

	if (argc < 2)
		return cmd_usage(cmdtp);

	printf ("\nEnter '.' when done\n");
	mem_addr = simple_strtoul (argv[1], NULL, 16);

	while (1) {
		putc ('\n');
		disppc ((unsigned char *) mem_addr, 0, 1, bedbug_puts,
			F_RADHEX);

		sprintf (prompt, "%08lx:    ", mem_addr);
		readline (prompt);

		if (console_buffer[0] && strcmp (console_buffer, ".")) {
			if ((instr =
			     asmppc (mem_addr, console_buffer,
				     &asm_err)) != 0) {
				*(unsigned long *) mem_addr = instr;
				mem_addr += 4;
			} else {
				printf ("*** Error: %s ***\n",
					asm_error_str (asm_err));
				rcode = 1;
			}
		} else {
			break;
		}
	}
	return rcode;
}				/* do_bedbug_asm */

U_BOOT_CMD (as, 2, 0, do_bedbug_asm,
	    "assemble memory", "as <address>");

/* ======================================================================
 * Used to set a break point from the interpreter.  Simply calls into the
 * CPU-specific break point set routine.
 * ====================================================================== */

int do_bedbug_break (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	/* -------------------------------------------------- */
	if (bug_ctx.do_break)
		(*bug_ctx.do_break) (cmdtp, flag, argc, argv);
	return 0;

}				/* do_bedbug_break */

U_BOOT_CMD (break, 3, 0, do_bedbug_break,
	    "set or clear a breakpoint",
	    " - Set or clear a breakpoint\n"
	    "break <address> - Break at an address\n"
	    "break off <bp#> - Disable breakpoint.\n"
	    "break show      - List breakpoints.");

/* ======================================================================
 * Called from the debug interrupt routine.  Simply calls the CPU-specific
 * breakpoint handling routine.
 * ====================================================================== */

void do_bedbug_breakpoint (struct pt_regs *regs)
{
	/* -------------------------------------------------- */

	if (bug_ctx.break_isr)
		(*bug_ctx.break_isr) (regs);

	return;
}				/* do_bedbug_breakpoint */



/* ======================================================================
 * Called from the CPU-specific breakpoint handling routine.  Enter a
 * mini main loop until the stopped flag is cleared from the breakpoint
 * context.
 *
 * This handles the parts of the debugger that are common to all CPU's.
 * ====================================================================== */

void bedbug_main_loop (unsigned long addr, struct pt_regs *regs)
{
	int len;		/* Length of command line */
	int flag;		/* Command flags          */
	int rc = 0;		/* Result from run_command */
	char prompt_str[20];	/* Prompt string          */
	static char lastcommand[CONFIG_SYS_CBSIZE] = { 0 };	/* previous command */
	/* -------------------------------------------------- */

	if (bug_ctx.clear)
		(*bug_ctx.clear) (bug_ctx.current_bp);

	printf ("Breakpoint %d: ", bug_ctx.current_bp);
	disppc ((unsigned char *) addr, 0, 1, bedbug_puts, F_RADHEX);

	bug_ctx.stopped = 1;
	bug_ctx.regs = regs;

	sprintf (prompt_str, "BEDBUG.%d =>", bug_ctx.current_bp);

	/* A miniature main loop */
	while (bug_ctx.stopped) {
		len = readline (prompt_str);

		flag = 0;	/* assume no special flags for now */

		if (len > 0)
			strcpy (lastcommand, console_buffer);
		else if (len == 0)
			flag |= CMD_FLAG_REPEAT;

		if (len == -1)
			printf ("<INTERRUPT>\n");
		else
			rc = run_command (lastcommand, flag);

		if (rc <= 0) {
			/* invalid command or not repeatable, forget it */
			lastcommand[0] = 0;
		}
	}

	bug_ctx.regs = NULL;
	bug_ctx.current_bp = 0;

	return;
}				/* bedbug_main_loop */



/* ======================================================================
 * Interpreter command to continue from a breakpoint.  Just clears the
 * stopped flag in the context so that the breakpoint routine will
 * return.
 * ====================================================================== */
int do_bedbug_continue (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	/* -------------------------------------------------- */

	if (!bug_ctx.stopped) {
		printf ("Not at a breakpoint\n");
		return 1;
	}

	bug_ctx.stopped = 0;
	return 0;
}				/* do_bedbug_continue */

U_BOOT_CMD (continue, 1, 0, do_bedbug_continue,
	    "continue from a breakpoint",
	    "");

/* ======================================================================
 * Interpreter command to continue to the next instruction, stepping into
 * subroutines.  Works by calling the find_next_addr() routine to compute
 * the address passes control to the CPU-specific set breakpoint routine
 * for the current breakpoint number.
 * ====================================================================== */
int do_bedbug_step (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	unsigned long addr;	/* Address to stop at */

	/* -------------------------------------------------- */

	if (!bug_ctx.stopped) {
		printf ("Not at a breakpoint\n");
		return 1;
	}

	if (!find_next_address ((unsigned char *) &addr, FALSE, bug_ctx.regs))
		return 1;

	if (bug_ctx.set)
		(*bug_ctx.set) (bug_ctx.current_bp, addr);

	bug_ctx.stopped = 0;
	return 0;
}				/* do_bedbug_step */

U_BOOT_CMD (step, 1, 1, do_bedbug_step,
	    "single step execution.",
	    "");

/* ======================================================================
 * Interpreter command to continue to the next instruction, stepping over
 * subroutines.  Works by calling the find_next_addr() routine to compute
 * the address passes control to the CPU-specific set breakpoint routine
 * for the current breakpoint number.
 * ====================================================================== */
int do_bedbug_next (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	unsigned long addr;	/* Address to stop at */

	/* -------------------------------------------------- */

	if (!bug_ctx.stopped) {
		printf ("Not at a breakpoint\n");
		return 1;
	}

	if (!find_next_address ((unsigned char *) &addr, TRUE, bug_ctx.regs))
		return 1;

	if (bug_ctx.set)
		(*bug_ctx.set) (bug_ctx.current_bp, addr);

	bug_ctx.stopped = 0;
	return 0;
}				/* do_bedbug_next */

U_BOOT_CMD (next, 1, 1, do_bedbug_next,
	    "single step execution, stepping over subroutines.",
	    "");

/* ======================================================================
 * Interpreter command to print the current stack.  This assumes an EABI
 * architecture, so it starts with GPR R1 and works back up the stack.
 * ====================================================================== */
int do_bedbug_stack (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	unsigned long sp;	/* Stack pointer                */
	unsigned long func;	/* LR from stack                */
	int depth;		/* Stack iteration level        */
	int skip = 1;		/* Flag to skip the first entry */
	unsigned long top;	/* Top of memory address        */

	/* -------------------------------------------------- */

	if (!bug_ctx.stopped) {
		printf ("Not at a breakpoint\n");
		return 1;
	}

	top = gd->bd->bi_memstart + gd->bd->bi_memsize;
	depth = 0;

	printf ("Depth     PC\n");
	printf ("-----  --------\n");
	printf ("%5d  %08lx\n", depth++, bug_ctx.regs->nip);

	sp = bug_ctx.regs->gpr[1];
	func = *(unsigned long *) (sp + 4);

	while ((func < top) && (sp < top)) {
		if (!skip)
			printf ("%5d  %08lx\n", depth++, func);
		else
			--skip;

		sp = *(unsigned long *) sp;
		func = *(unsigned long *) (sp + 4);
	}
	return 0;
}				/* do_bedbug_stack */

U_BOOT_CMD (where, 1, 1, do_bedbug_stack,
	    "Print the running stack.",
	    "");

/* ======================================================================
 * Interpreter command to dump the registers.  Calls the CPU-specific
 * show registers routine.
 * ====================================================================== */
int do_bedbug_rdump (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	/* -------------------------------------------------- */

	if (!bug_ctx.stopped) {
		printf ("Not at a breakpoint\n");
		return 1;
	}

	show_regs (bug_ctx.regs);
	return 0;
}				/* do_bedbug_rdump */

U_BOOT_CMD (rdump, 1, 1, do_bedbug_rdump,
	    "Show registers.", "");
/* ====================================================================== */


/*
 * Copyright (c) 2001 William L. Pitts
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are freely
 * permitted provided that the above copyright notice and this
 * paragraph and the following disclaimer are duplicated in all
 * such forms.
 *
 * This software is provided "AS IS" and without any express or
 * implied warranties, including, without limitation, the implied
 * warranties of merchantability and fitness for a particular
 * purpose.
 */
