/*
  TMHal.h, Copyright  (c) by George Fankhauser,
  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.
*/

#ifndef _TMHAL_H_
#define _TMHAL_H_

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

#include "Unix.h"

#define MAXNBOFEXCEPTIONS     NOFSIGNALS
#define MAXNBOFINTERRUPTS              0

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

// status register bits
#define STATUS_INT_ENABLE_KERNEL_PREV 0
#define STATUS_INT_ENABLE_USER_PREV 0

/* Processor dependent thread information */
typedef struct ProcContext_t
{
  struct ucontext uc;
#ifdef sparc

  struct gwindows gwins;
#endif
}
ProcContext;

/* Saving and restoring current thread context (assembler procedures) */
void saveContext(ProcContextPtr contextPtr);
void restoreContext(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(ProcContextPtr contextPtr, AddressSpace space);

Register tmGetProgramCounter(ProcContextPtr contextPtr);
Register tmGetFaultingAddress(ProcContextPtr contextPtr);

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();

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

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

/* Automatic exit of a thread when stack underflow occurs */
void automaticThreadExit();
void endAutomaticThreadExit();  // label to derive the length of the exit code

void generalExceptionHandler();

void msgAdjust(ThreadPtr pFromOrToThread, Message *msg, Boolean ToKernel);

void powerSaver();

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

#endif
