/* See COPYRIGHT for copyright information. */

#include <inc/asm.h>
#include <kern/trap.h>
#include <kern/pmap.h>
#include <kern/env.h>
#include <kern/console.h>
#include <kern/printf.h>
#include <kern/picirq.h>
#include <kern/kclock.h>
#include <kern/sched.h>

static int debug = 0;

void
i386_init(void)
{
	// can't call printf until after cons_init()
	cons_init();

	printf("Booting 6828 kernel\n");

	// Lab 2 initialization functions
	i386_detect_memory();
	i386_vm_init();
	page_init();
	if (debug) page_check();

	// Lab 3 initialization functions
	idt_init();
	pic_init();
	kclock_init();
	env_init();

	// Should always have an idle process as first one.
	ENV_CREATE(user_idle, "idle");

	// Start fs.
	ENV_CREATE(fs_fs, "FS");

	// Start init
  #if defined(TEST)
	// Don't touch -- used by grading script!
	ENV_CREATE2(TEST, TESTSIZE, "TEST")
  #else
  	// Touch all you want.
	 ENV_CREATE(user_icode, "icode");
  #endif

	// Should not be necessary - drain keyboard because interrupt has given up.
	kbd_intr();

	sched_yield();
	panic("init.c: end of i386_init() reached!");
}


// like bcopy(but doesn't handle overlapping src/dst)
void
bcopy(const void *src, void *dst, size_t len)
{
	void *max;

	max = dst + len;
	// copy machine words while possible
	while (dst + 3 < max)
		*(int *)dst++ = *(int *)src++;
	// finish remaining 0-3 bytes
	while (dst < max)
		*(char *)dst++ = *(char *)src++;
}

void
bzero(void *b, size_t len)
{
	void *max;

	max = b + len;
	// zero machine words while possible
	while (b + 3 < max)
		*(int *)b++ = 0;
	// finish remaining 0-3 bytes
	while (b < max)
		*(char *)b++ = 0;
}

// Ignore from here on down.  The functions below here are never
// called.  They are just here to get around a linking problem.

void
abort(void)
{
	panic("abort");
}

void *
malloc(size_t size)
{
	panic("malloc: size %d", size);
}

void
free(void *ptr)
{
	panic("free: ptr %p", ptr);
}

int
atexit(void(*function)(void))
{
	panic("atexit: function %p", function);
}

