/*
 * arch/i386/task.c
 *
 * This file handles the task related architecture-dependent parts 
 * KLIB for i386 based systems.
 *
 * Copyright 1999 Silicon Graphics, Inc. All rights reserved.
 */
#include <klib.h>

/*
 * get_dump_header()
 */
static int
get_dump_header(dump_header_t *dump_header)
{
	/* first, make sure this isn't a live system
	 */
	if (MIP->core_type != reg_core) {
		KL_ERROR = KLE_ACTIVE;
		return(1);
	}

	/* get the dump header
	 */
	if (lseek(MIP->core_fd, 0, SEEK_SET) < 0) {
		KL_ERROR = KLE_INVALID_LSEEK;
		return(1);
	}

	if (read(MIP->core_fd, (char *)dump_header, sizeof(dump_header_t)) != 
					sizeof(dump_header_t)) {
		KL_ERROR = KLE_INVALID_READ;
		return(1);
	}

	if (dump_header->dh_magic_number != DUMP_MAGIC_NUMBER) {
		KL_ERROR = KLE_INVALID_DUMP_MAGIC;
		return(1);
	}
	return(0);
}

/*
 * get_dump_header_asm()
 */
static int
get_dump_header_asm(dump_header_asm_t *dump_header_asm)
{
	dump_header_t dump_header;

	/* first, make sure this isn't a live system
	 */
	if (MIP->core_type != reg_core) {
		KL_ERROR = KLE_ACTIVE;
		return(1);
	}

	/* get the dump header
	 */
	if (lseek(MIP->core_fd, 0, SEEK_SET) < 0) {
		KL_ERROR = KLE_INVALID_LSEEK;
		return(1);
	}

	if (read(MIP->core_fd, (char *)&dump_header, sizeof(dump_header_t)) != 
					sizeof(dump_header_t)) {
		KL_ERROR = KLE_INVALID_READ;
		return(1);
	}

	if (dump_header.dh_magic_number != DUMP_MAGIC_NUMBER) {
		KL_ERROR = KLE_INVALID_DUMP_MAGIC;
		return(1);
	}

	if (read(MIP->core_fd, (char *)dump_header_asm,
		sizeof(dump_header_asm_t)) != sizeof(dump_header_asm_t)) {
			KL_ERROR = KLE_INVALID_READ;
			return(1);
	}

	if (dump_header_asm->dha_magic_number != DUMP_ASM_MAGIC_NUMBER) {
		KL_ERROR = KLE_INVALID_DUMP_MAGIC;
		return(1);
	}

	return(0);
}

/*
 * kl_dumpesp()
 */
kaddr_t
kl_dumpesp(void)
{
	dump_header_asm_t dump_header_asm;

	if (get_dump_header_asm(&dump_header_asm)) {
		return((kaddr_t)NULL);
	}
#ifdef ARCH_SPECIFIC
	if (dump_header_asm.dha_regs.esp) {
		return((kaddr_t)dump_header_asm.dha_regs.esp);
	} else { 
		return((kaddr_t)dump_header_asm.dha_esp);
	}
#endif
}

/*
 * kl_dumpeip()
 */
kaddr_t
kl_dumpeip(void)
{
	dump_header_asm_t dump_header_asm;

	if (get_dump_header_asm(&dump_header_asm)) {
		return((kaddr_t)NULL);
	}
#ifdef ARCH_SPECIFIC
	if (dump_header_asm.dha_regs.eip) {
		return((kaddr_t)dump_header_asm.dha_regs.eip);
	} else { 
		return((kaddr_t)dump_header_asm.dha_eip);
	}
#endif
}

/*
 * kl_dumptask()
 */
kaddr_t
kl_dumptask(void)
{
	dump_header_t dump_header;

	if (get_dump_header(&dump_header)) {
		return((kaddr_t)NULL);
	}
	return((kaddr_t)dump_header.dh_current_task);
}

