/*
 * Copyright (c) 2009 Corey Tabaka
 *
 * 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 <stdarg.h>
#include <reg.h>
#include <printf.h>
#include <kernel/thread.h>
#include <arch/x86.h>
#include <platform/x86/memmap.h>
#include <platform/console.h>
#include <platform/keyboard.h>
#include <platform/debug.h>

void _dputc(char c)
{
	cputc(c);
}

int dgetc(char *c)
{
	return platform_read_key(c);
}

void debug_dump_regs(void)
{
}

void platform_halt(void)
{
	for(;;) {
		x86_cli();
		x86_hlt();
	}
}

void debug_dump_memory_bytes(void *mem, int len)
{
}

void debug_dump_memory_halfwords(void *mem, int len)
{
}

void debug_dump_memory_words(void *mem, int len)
{
}

void debug_set_trace_level(int trace_type, int level)
{
}

uint32_t debug_cycle_count()
{
	uint32_t timestamp;
	rdtscl(timestamp);
	
	return timestamp;
}
