/*
 * Copyright (c) 2008 Travis Geiselbrecht
 *
 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 *
 * 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>
#include <kernel/timer.h>
#include <rand.h>

void __attribute__ ((noreturn))
__stack_chk_fail (void)
{
	panic("stack smashing detected.");
}

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];
	char ts_buf[13];
	int err;

	snprintf(ts_buf, sizeof(ts_buf), "[%u] ", current_time());
	dputs(ALWAYS, ts_buf);

	va_list ap;
	va_start(ap, fmt);
	err = vsnprintf(buf, sizeof(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 = vsnprintf(buf, sizeof(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_LIB_CONSOLE
#include <lib/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
 
