/*
    MMError.c, 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.
*/
/*
	
	File:                  $Source: /home/ruf/cvs_Topsy/cvs/Topsy/Memory/mips/MMError.c,v $
 	Author(s):             George Fankhauser
 	Affiliation:           ETH Zuerich, TIK
 	Version:               $Revision: 2922 $
 	Creation Date:         
 	Last Date of Change:   $Date: 2007-03-19 17:48:52 +0100 (Mon, 19 Mär 2007) $      by: $Author: baderma $
	
	
	$Log: MMError.c,v $
	Revision 1.11  2000/11/15 10:08:33  ruf
	Repository Reorganisation
	
	Revision 1.10  1999/12/13 21:48:31  ruf
	GNU General Public Licence Update
	
	Revision 1.9  1998/04/07 15:30:50  gfa
	added printreg
	
	Revision 1.8  1997/04/23 11:48:53  gfa
	replaced 8 by appropriate constant
 
 * Revision 1.7  1997/03/31  20:35:34  gfa
 * adapted for global name changes (syscalls)
 *
 * Revision 1.6  1997/03/18  19:04:29  gfa
 * kills faulting thread now...
 *
 * Revision 1.5  1997/03/13  23:59:52  gfa
 * added utlb miss handler
 *
 * Revision 1.4  1997/03/13  10:38:33  gfa
 * added UTLB miss handler
 *
 * Revision 1.3  1997/03/09  20:48:44  gfa
 * init / panic as a default reaction
 *
 * Revision 1.2  1997/02/13  15:43:44  conrad
 * First compilation/linking of complete environment (all modules)
 *
 * Revision 1.1  1997/02/12  16:18:39  zitzler
 * Initial revision
 *
*/

#include "MMError.h"
#include "Threads.h"
#include "Messages.h"
#include "TMHal.h"


static void mmBusError(ThreadId currentThread);
static void mmAddressError(ThreadId currentThread);
static void mmTLBError(ThreadId currentThread);
static void mmUTLBError(ThreadId currentThread);
static void mmError(ThreadId currentThread, char* errorString);


void mmInstallErrorHandlers(void)
{
  tmSetExceptionHandler(TLB_MOD, mmTLBError);
  tmSetExceptionHandler(TLB_LOAD, mmTLBError);
  tmSetExceptionHandler(TLB_STORE, mmTLBError);
  tmSetExceptionHandler(UTLB_MISS, mmUTLBError);
  tmSetExceptionHandler(ADDR_ERR_LOAD, mmAddressError);
  tmSetExceptionHandler(ADDR_ERR_STORE, mmAddressError);
  tmSetExceptionHandler(BUSERR_INSTR, mmBusError);
  tmSetExceptionHandler(BUSERR_DATA, mmBusError);
}


static void mmError(ThreadId currentThread, char* errorString)
{
  Message msg;

  msg.id = TM_KILL;
  msg.from = MMTHREADID;
  msg.msg.tmKill.id = currentThread;

  ERROR(errorString);
  printRegisters();

  /* immediate in-kernel delivery without syscall
   * kSend does a schedule after the message arrived
   */
  kSend(TMTHREADID, &msg);
}

static void mmBusError(ThreadId currentThread)
{
  mmError(currentThread, "bus error");
}


static void mmAddressError(ThreadId currentThread)
{
  mmError(currentThread, "address error");
}

static void mmTLBError(ThreadId currentThread)
{
  mmError(currentThread, "tlb error");
}

static void mmUTLBError(ThreadId currentThread)
{
  mmError(currentThread, "user tlb error");
}
