/*
  TMHal.h, Copyright  (c) by Christian Conrad,
  Swiss Federal Institute of Technology,
  Computer Engineering and Networks Laboratory.
 
  TOPSY -- A Teachable Operating System.
           Implementation of a tiny and simple
           micro kernel for teaching purposes.
 
  For further information, please visit http://www.tik.ee.ethz.ch/~topsy
 
  This software is provided under the terms of the GNU General Public Licence.
 
  A full copy of the GNU GPL is provided in the file COPYING found in the 
  development root of Topsy.
*/
/*
	File:                  $Source: /home/ruf/cvs_Topsy/cvs/Topsy/Threads/mips/TMHal.h,v $
 	Author(s):             Christian Conrad
 	Affiliation:           ETH Zuerich, TIK
 	Version:               $Revision: 2935 $
 	Last Date of Change:   $Date: 2007-03-21 11:58:17 +0100 (Mit, 21 Mär 2007) $
 */

#ifndef __TMHAL_H
#define __TMHAL_H

#include "tm-include.h"
#include "cpu.h"
#include "Exception.h"
#include "SupportMIPS.h"

#define MAXNBOFEXCEPTIONS    32 /* 32 mips exceptions */
#define MAXNBOFINTERRUPTS     8

/* THREADRETURNADDR is defined inside TMHal.h to allow portability.... :-) */
#define THREADRETURNADDR      4

#define STATUS_INT_ENABLE_KERNEL_PREV (getPRID() == PRID_R3K)?\
					(SR_IE_P | (SR_KU_P & 0)):(SR_IE | SR_KSU_KERNEL | SR_EXL)
#define STATUS_INT_ENABLE_USER_PREV (getPRID() == PRID_R3K)?\
					(SR_IE_P | SR_KU_P):(SR_IE | SR_KSU_USER | SR_EXL)

/* Processor dependent thread information */
typedef struct ProcContext_t
{
  Register returnValue[2];       /* v0 - v1 */
  Register argument[4];          /* a0 - a3 */
  Register callerSaved[10];      /* t0 - t9 */
  Register calleeSaved[8];       /* s0 - s7 */
  Register globalPointer;        /* gp */
  Register stackPointer;         /* sp */
  Register framePointer;         /* fp */
  Register returnAddress;        /* ra */
  Register programCounter;       /* pc */
  Register hilo[2];              /* hi, lo multiplier registers */
  Register statusRegister;       /* sr after trapping */
  Register assemblerTemp;        /* assembler temp, used also by gcc */
  Register TLBhi;								 /* tlb hi needed for the pid */
}
ProcContext;

/* Saving and restoring current thread context (assembler procedures) */
void saveContext(ProcContextPtr contextPtr);
/* global function */
void (*restoreContext)(ProcContextPtr contextPtr);
/* processor specific functions */
void restoreContext_R3k(ProcContextPtr contextPtr);
void restoreContext_R4k(ProcContextPtr contextPtr);

/* operations on the thread context are machine dependent and
 * encapsulated in the following functions. On CISC machines
 * most of these ops must be implemented using the current SP of
 * the context.
 */
void tmSetReturnValue(ProcContextPtr contextPtr, Register value);
void tmSetStackPointer(ProcContextPtr contextPtr, Register value);
void tmSetReturnAddress(ProcContextPtr contextPtr, Register value);
void tmSetProgramCounter(ProcContextPtr contextPtr, Register value);
void tmSetStatusRegister(ProcContextPtr contextPtr, Register value);
void tmSetFramePointer(ProcContextPtr contextPtr, Register value);
void tmSetArgument0(ProcContextPtr contextPtr, Register value);
void tmSetArgument1(ProcContextPtr contextPtr, Register value);
void tmSetMachineDependentRegisters(ThreadPtr thread, AddressSpace space);

void enableInterruptInContext( InterruptId intId, ProcContextPtr contextPtr);
void disableInterruptInContext( InterruptId intId, ProcContextPtr contextPtr);
void enableAllInterruptsInContext( ProcContextPtr contextPtr);

/* installs code by copying generalExceptionHandler()'s and
 * UTLBMissHandler()'s code at certain mips specific addresses
 */
void tmInstallExceptionCode(void);

/* Syscall exception handler (set per default as exception handler) */
void syscallExceptionHandler(ThreadId threadId);

/* Hardware exception handler (set per default as exception handler) */
void hwExceptionHandler(void);

/* branchDelayBit handler called directly in syscallExceptionHandler */
int branchDelayHandler( ThreadId fromId,       /* thread that caused exception */
                        Message* msgPtr,       /* message reference */
                        unsigned long int timeout,/* timeout for receiving */
                        MsgOpCode code);        /* SYSCALL_SEND_OP/SYSCALL_RECV_OP */

/* Automatic exit of a thread when stack underflow occurs */
void automaticThreadExit(void);
void endAutomaticThreadExit(void);

/* Symbols for the exception handlers (they are implemented in assembly) */
void UTLBMissHandler(void);
void endUTLBMissHandler(void);

void generalExceptionHandler(void);
void endGeneralExceptionHandler(void);

void moveMessageToPD(Thread* threadPtr, Message* msgPtr, Message* destPtr);
void msgAdjust(ThreadPtr pFromOrToThread, Message *msg, Boolean ToKernel);

void powerSaver(void);

/* LR 20010213: adjust Machine Dependencies at the end  */
void tmAdjustMachineDependentRegisters(ProcContextPtr contextPtr, AddressSpace space);

#endif
