/*
 * Copyright 2014 Google Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but without any warranty; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <gdb.h>
#include <libpayload.h>

struct gdb_state gdb_state;

static u8 reply_buf[2048];
static u8 command_buf[2048];

static struct gdb_message command = {
	.buf = command_buf,
	.used = 0,
	.size = sizeof(command_buf),
};
static struct gdb_message reply = {
	.buf = reply_buf,
	.used = 0,
	.size = sizeof(reply_buf),
};

void gdb_command_loop(u8 signal)
{
	if (gdb_state.resumed) {
		/* We were just running. Send a stop reply. */
		reply.used = 0;
		gdb_message_add_string(&reply, "S");
		gdb_message_encode_bytes(&reply, &signal, 1);
		gdb_send_reply(&reply);

	}
	gdb_state.signal = signal;
	gdb_state.resumed = 0;
	gdb_state.connected = 1;

	while (1) {
		int i;

		gdb_get_command(&command);

		reply.used = 0;
		for (i = 0; i < gdb_command_count; i++) {
			int clen = strlen(gdb_commands[i].str);
			if (!strncmp(gdb_commands[i].str, (char *)command.buf,
				     MIN(clen, command.used))) {
				gdb_commands[i].handler(&command, clen, &reply);
				break;
			}
		}

		/* If we're resuming, we won't send a reply until we stop. */
		if (gdb_state.resumed)
			return;

		gdb_send_reply(&reply);
	}
}

static void gdb_output_write(const void *buffer, size_t count)
{
	if (!gdb_state.resumed) {
		/* Must be a die_if() in GDB (or a bug), so bail out and die. */
		gdb_exit(-1);
		video_console_init();
		puts("GDB died, redirecting its last words to the screen:\n");
		console_write(buffer, count);
	} else {
		reply.used = 0;
		reply.buf[reply.used++] = 'O';
		gdb_message_encode_bytes(&reply, buffer, count);
		gdb_send_reply(&reply);
	}
}

static struct console_output_driver gdb_output_driver = {
	.write = &gdb_output_write
};

static void gdb_init(void)
{
	printf("Ready for GDB connection.\n");
	gdb_transport_init();
	gdb_arch_init();
	console_add_output_driver(&gdb_output_driver);
}

void gdb_enter(void)
{
	if (!gdb_state.connected)
		gdb_init();
	gdb_arch_enter();
}

void gdb_exit(s8 exit_status)
{
	if (!gdb_state.connected)
		return;

	reply.used = 0;
	gdb_message_add_string(&reply, "W");
	gdb_message_encode_bytes(&reply, &exit_status, 1);
	gdb_send_reply(&reply);

	console_remove_output_driver(&gdb_output_write);
	gdb_transport_teardown();
	gdb_state.connected = 0;
	printf("Detached from GDB connection.\n");
}
