/**
 * @file main.c
 * @brief Starting poin of the kernell. 
 *
 * This file contains functions start, which is the entry point to all the kernel.
 * Processor at first jump to the routine on a fix adress (loader), loader starts
 * some routines from sys.S and then execute code of function start 
 * Function start do basic initilaization of internal
 * structures, than create system thread and switch context to system thread.
 * System thread must be living all the time in the kernell, so we must be sure that
 * will never call thread_kill(), so spawn one more thread and there run tests
 * 
 * This file is based on Kalisto, Development Kernel copyrighted (c) to 
 * Distributed Systems Research Group MFF UK, Czech republic.
 */
 
 
/**
 *
 * \mainpage [KalistoX, MIPS Kernel - Programmers Documentation]
 *
 * This kernel is based on Kalisto, Development Kernel copyrighted (c) to 
 * Distributed Systems Research Group MFF UK, Czech republic.
 * This kernel was written by seminar grup <b>Ficek, Podzimek, Pop</b> as a semir work
 * to subject Operating systems on MFF UK, Czech republic.
 * 
 * This kernel implements (kernel) threads, is implemented simple scheduler,
 * conditional variables, mutexes, semaphores, RWlocks, (kernel) timers. 
 * 
 * <b>Most inportant files:</b>
 *	@see thread.c 		.. Implementation of threads
 *	@see sched.c 		.. Implementation of simple round robin scheduler (no priorities)
 *  @see semaphore.c 	.. Implementation Semaphores, mutexes are based on it.
 *  @see timers.c		.. Implementation of timers
 *  @see tqueue.c		.. Implementation of cyclic queue, functions for sorted and unsorted manipulation \
 * 							this structure is used widely in kernel.
 * 
 * 
 * <h3>Some Implementation Notes</h3>
 * All parts are desctibed on the begining of corresponfing .c file
 * 
 * <h4>Scheduler implemetation</h4>
 * Scheduler is imlemented as a round robin. In the system is all the time queue of runnable threads.
 * Scheduler check sleeping threads (via timers), kill zombies (if they could not be killed 
 * in time, they stop executing),
 * and choose new tread to run. In system lives all the time system thread (id 0). Currently running
 * thread is stored in global variable. Runnable threads are in queue.
 * In system exists queue of zombies to kill (were detached or joined).
 * 
 * <h4>Thread implementation</h4> 
 * Thread is all the time living in the system in valid thread queue. Can be (bud it's not necessary)
 * enqueued in some othrer thread, like runnable threads or queue of synchronization primitiv.
 * Implementation allows to simply change number of quqeus where can be thread enqueud (for next grups)
 * Thread contains also pointer to pointer to queue where is enqued, this allows us to pull it
 * from queue where is enqueued. 
 */ 

 
#include "malloc.h"
#include "thread.h"
#include "sched.h"
#include "tlb.h"
#include "sys.h"
#include "io.h"
#include "timers.h"
#include "debug.h"
#include "thread.h"
#include "assignment-1.h"



/** System thread must be still living in the system... Can not be never killed, so we create
 * one more thread for tests. 
 */
static void test_thread (void* data){
				dprintk("running assignment_test\n");
	assignment_test();	
	___halt();
}

/**
 * System thread is first thread created in the system. It is created litle bit another way than
 * the others for example scheduling is not runnig, so we dont have to care about interrupts and 
 * such problems.
 */

void system_thread(void){
				dprintk ("BEZI SYSTEM THREAD\n");
	thread_t thr1;
	thread_create(&thr1, test_thread, NULL);
	for (;;)
		thread_yield();
}

/**
 * This is the entry point to C code. The "start" function is called from
 * the basic initialization routine in "sys.S". We have to create and
 * initialize the main data structures.
 *
 * The interrupts are (still) disabled. This will be changed when context is switched
 */
void
start (void)
{
	// BAsic initialization of the kernel
	 
	thread_t t; 	
	 	
	 	
						dprintk ("Initializing Kalisto environment... \n");
						dprintk ("Initializing tlb... \n");
	init_tlb ();
						dprintk ("Tlb initialized... \n");
						dprintk ("Initializing memory... \n");
	init_memory ();
						dprintk ("Memory initialized... \n");
						dprintk ("Initializing keyboard... \n");
	init_keyboard ();
						dprintk ("Keyboard initialized... \n");
 						dprintk ("Initializing timers... \n");
	init_timers();
						dprintk ("Timers initialized... \n");
	//create and initialize system thread.			
	t = thread_create_system(system_thread, KERNEL_THREAD_STATUS);
	
						dprintk ("Initializing scheduler...\n");
	init_scheduler (t);
						dprintk ("Scheduler initialized... \n");
						dprintk ("Kalisto environment initialized, switching context... \n");
						
	context_switch (t);
	//unreachable.
	___halt();
}
