////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002 Xilinx, Inc.  All rights reserved.
//
// Xilinx, Inc.
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A 
// COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR 
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE 
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.  
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO 
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO 
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE 
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY 
// AND FITNESS FOR A PARTICULAR PURPOSE.
// 
// $Id: main.c,v 1.1.2.2 2003/04/01 00:55:48 mohan Exp $
//
//////////////////////////////////////////////////////////////////////////////

/**
 * @file main.c 
 *
 * The main rouine, that starts the kernel.
 * 
 * Enables the Interrupts and starts the timer Interrupt.
 * Initialises the system by calling sys_init() and loops. On first timer 
 * interrupt the first process gets scheduled.
 ***************************************************************************/
#ifdef MB_XILKERNEL
#include <sys/process.h>
#endif
#ifdef PPC_XILKERNEL
#include <xparameters.h>
#include <sys/process.h>
#include <xpseudo_asm.h>
#include <xexception_l.h>
#include <xtime_l.h>
#include <sys/syscall.h>
 #include "xcache_l.h"

struct t_syscall_data system_call_data;
struct t_syscall_data *system_call_data_ptr = &system_call_data; /* this pointer points to data shared between user and system */
extern void timer_int_handler(int) ;
extern void system_call_handler(void *baseaddr);
#endif
int main() {
#ifdef PPC_XILKERNEL
  	int timer_count;
  	int i;
        struct t_syscall_data **system_call_data_ptr_ptr = &system_call_data_ptr;
/*enable caches for workaround of Rev1 board bug*/
  /*    0x80000000  | [0, 0x07FF FFFF]
   *    0x00000001  | [0xF8000000, 0xFFFFFFFF]
   *    0x80000001  | [0, 0x7FFFFFF],[0xF8000000, 0xFFFFFFFF]
   */

         XCache_EnableICache(0x80000000);
         XCache_EnableDCache(0x80000000);

#endif
	sys_init() ;
#ifdef MB_XILKERNEL
	/* Enable microblaze interrupts */
	microblaze_enable_interrupts();
#endif
#ifdef PPC_XILKERNEL
	/* Initialize exception handling */
	XExc_Init();
XExc_mDisableExceptions(XEXC_NON_CRITICAL);
        /* Register System Call handler */
        XExc_RegisterHandler(XEXC_ID_SYSTEM_CALL, (XExceptionHandler)system_call_handler, (void *)system_call_data_ptr);
        /* set the value of SPRG4 to this address */
        asm volatile ("lwz 0, 0(%0)" : : "b" (system_call_data_ptr_ptr)) ; // move address of system_call_data into r0
        asm volatile ("mtspr 0x114, 0") ;	//store this in SPRG4 (0x114 in priv mode -- cannot store in user mode)
	/* Register PIT interrupt handler */
	XExc_RegisterHandler(XEXC_ID_PIT_INT, (XExceptionHandler)timer_int_handler, (void *)0);

	/* Initialise and enable the PIT timer */
	XTime_PITSetInterval( 0x00ffffff  ) ;	
	XTime_PITEnableAutoReload() ;
	XTime_PITEnableInterrupt() ;	
  
	/* Enable PPC non-critical interrupts */
	XExc_mEnableExceptions(XEXC_NON_CRITICAL);	

#endif
  	while(1) {	/* Keep looping....*/
	  //	print("Hi\r\n") ;
  	} 
  	return 0 ; 
}

