/*
 * Copyright (c) 2008 Travis Geiselbrecht
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <ctype.h>
#include <debug.h>
#include <stdlib.h>
#include <printf.h>
#include <list.h>
#include <string.h>
#include <arch/ops.h>
#include <platform.h>
#include <platform/debug.h>
#include <kernel/thread.h>

void spin(uint32_t usecs)
{
	bigtime_t start = current_time_hires();

	while ((current_time_hires() - start) < usecs)
		;	
}

void halt(void)
{
	enter_critical_section(); // disable ints
	platform_halt();
}

void _panic(void *caller, const char *fmt, ...)
{
	dprintf(ALWAYS, "panic (caller %p): ", caller);

	va_list ap;
	va_start(ap, fmt);
	_dvprintf(fmt, ap);
	va_end(ap);

	halt();
}

int _dputs(const char *str)
{
	while(*str != 0) {
		_dputc(*str++);
	}

	return 0;
}

int _dprintf(const char *fmt, ...)
{
	char buf[256];
	int err;

	va_list ap;
	va_start(ap, fmt);
	err = vsprintf(buf, fmt, ap);
	va_end(ap);

	dputs(ALWAYS, buf);

	return err;
}

int _dvprintf(const char *fmt, va_list ap)
{
	char buf[256];
	int err;

	err = vsprintf(buf, fmt, ap);

	dputs(ALWAYS, buf);

	return err;
}

void hexdump(const void *ptr, size_t len)
{
	addr_t address = (addr_t)ptr;
	size_t count;
	int i;

	for (count = 0 ; count < len; count += 16) {
		printf("0x%08lx: ", address);
		printf("%08x %08x %08x %08x |", *(const uint32_t *)address, *(const uint32_t *)(address + 4), *(const uint32_t *)(address + 8), *(const uint32_t *)(address + 12));
		for (i=0; i < 16; i++) {
			char c = *(const char *)(address + i);
			if (isalpha(c)) {
				printf("%c", c);
			} else {
				printf(".");
			}
		}
		printf("|\n");
		address += 16;
	}	
}

void hexdump8(const void *ptr, size_t len)
{
	addr_t address = (addr_t)ptr;
	size_t count;
	int i;

	for (count = 0 ; count < len; count += 16) {
		printf("0x%08lx: ", address);
		for (i=0; i < 16; i++) {
			printf("0x%02hhx ", *(const uint8_t *)(address + i));
		}
		printf("\n");
		address += 16;
	}	
}

#ifdef WITH_APP_CONSOLE
#include <app/console.h>

static int cmd_display_mem(int argc, const cmd_args *argv);
static int cmd_modify_mem(int argc, const cmd_args *argv);
static int cmd_fill_mem(int argc, const cmd_args *argv);
static int cmd_reset(int argc, const cmd_args *argv);
static int cmd_memtest(int argc, const cmd_args *argv);
static int cmd_copy_mem(int argc, const cmd_args *argv);

STATIC_COMMAND_START
#if DEBUGLEVEL > 0
	{ "dw", "display memory in words", &cmd_display_mem },
	{ "dh", "display memory in halfwords", &cmd_display_mem },
	{ "db", "display memory in bytes", &cmd_display_mem },
	{ "mw", "modify word of memory", &cmd_modify_mem },
	{ "mh", "modify halfword of memory", &cmd_modify_mem },
	{ "mb", "modify byte of memory", &cmd_modify_mem },
	{ "fw", "fill range of memory by word", &cmd_fill_mem },
	{ "fh", "fill range of memory by halfword", &cmd_fill_mem },
	{ "fb", "fill range of memory by byte", &cmd_fill_mem },
	{ "mc", "copy a range of memory", &cmd_copy_mem },
#endif
#if DEBUGLEVEL > 1
	{ "mtest", "simple memory test", &cmd_memtest },
#endif
STATIC_COMMAND_END(mem);

static int cmd_display_mem(int argc, const cmd_args *argv)
{
	int size;

	if (argc < 3) {
		printf("not enough arguments\n");
		printf("%s <address> <length>\n", argv[0].str);
		return -1;
	}

	if (strcmp(argv[0].str, "dw") == 0) {
		size = 4;
	} else if (strcmp(argv[0].str, "dh") == 0) {
		size = 2;
	} else {
		size = 1;
	}

	unsigned long address = argv[1].u;
	size_t len = argv[2].u;
	unsigned long stop = address + len;
	int count = 0;

	if ((address & (size - 1)) != 0) {
		printf("unaligned address, cannot display\n");
		return -1;
	}

	for ( ; address < stop; address += size) {
		if (count == 0)
			printf("0x%08lx: ", address);
		switch (size) {
			case 4:
				printf("%08x ", *(uint32_t *)address);
				break;
			case 2:
				printf("%04hx ", *(uint16_t *)address);
				break;
			case 1:
				printf("%02hhx ", *(uint8_t *)address);
				break;
		}
		count += size;
		if (count == 16) {
			printf("\n");
			count = 0;
		}
	}	

	if (count != 0)
		printf("\n");

	return 0;
}

static int cmd_modify_mem(int argc, const cmd_args *argv)
{
	int size;

	if (argc < 3) {
		printf("not enough arguments\n");
		printf("%s <address> <val>\n", argv[0].str);
		return -1;
	}

	if (strcmp(argv[0].str, "mw") == 0) {
		size = 4;
	} else if (strcmp(argv[0].str, "mh") == 0) {
		size = 2;
	} else {
		size = 1;
	}

	unsigned long address = argv[1].u;
	unsigned int val = argv[2].u;

	if ((address & (size - 1)) != 0) {
		printf("unaligned address, cannot modify\n");
		return -1;
	}

	switch (size) {
		case 4:
			*(uint32_t *)address = (uint32_t)val;
			break;
		case 2:
			*(uint16_t *)address = (uint16_t)val;
			break;
		case 1:
			*(uint8_t *)address = (uint8_t)val;
			break;
	}

	return 0;
}

static int cmd_fill_mem(int argc, const cmd_args *argv)
{
	int size;

	if (argc < 4) {
		printf("not enough arguments\n");
		printf("%s <address> <len> <val>\n", argv[0].str);
		return -1;
	}

	if (strcmp(argv[0].str, "fw") == 0) {
		size = 4;
	} else if (strcmp(argv[0].str, "fh") == 0) {
		size = 2;
	} else {
		size = 1;
	}

	unsigned long address = argv[1].u;
	unsigned long len = argv[2].u;
	unsigned long stop = address + len;
	unsigned int val = argv[3].u;

	if ((address & (size - 1)) != 0) {
		printf("unaligned address, cannot modify\n");
		return -1;
	}

	for ( ; address < stop; address += size) {
		switch (size) {
		case 4:
			*(uint32_t *)address = (uint32_t)val;
			break;
		case 2:
			*(uint16_t *)address = (uint16_t)val;
			break;
		case 1:
			*(uint8_t *)address = (uint8_t)val;
			break;
		}
	}

	return 0;
}

static int cmd_copy_mem(int argc, const cmd_args *argv)
{
	if (argc < 4) {
		printf("not enough arguments\n");
		printf("%s <source address> <target address> <len>\n", argv[0].str);
		return -1;
	}
	
	addr_t source = argv[1].u;
	addr_t target = argv[2].u;
	size_t len = argv[3].u;

	memcpy((void *)target, (const void *)source, len);

	return 0;
}

static int cmd_memtest(int argc, const cmd_args *argv)
{
	if (argc < 3) {
		printf("not enough arguments\n");
		printf("%s <base> <len>\n", argv[0].str);
		return -1;
	}

	uint32_t *ptr;
	size_t len;

	ptr = (uint32_t *)argv[1].u;
	len = (size_t)argv[2].u;

	size_t i;
	// write out
	printf("writing first pass...");
	for (i = 0; i < len / 4; i++) {
		ptr[i] = i;
	}
	printf("done\n");

	// verify
	printf("verifying...");
	for (i = 0; i < len / 4; i++) {
		if (ptr[i] != i)
			printf("error at %p\n", &ptr[i]);
	}
	printf("done\n");

	return 0;
}

#endif
 
