/*
    MMError.c, Copyright  (c) by Lukas Ruf, lr@lpr.ch,
    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/ia32/MMError.c,v $
 	Author(s):             Lukas Ruf, lr@lpr.ch
 	Affiliation:           ETH Zuerich, TIK
 	Version:               $Revision: 3042 $
 	Creation Date:         
 	Last Date of Change:   $Date: 2007-06-28 01:28:34 +0200 (Don, 28 Jun 2007) $      by: $Author: sryffel $
*/
#include "MMError.h"
#include "Threads.h"
#include "Messages.h"
#include "TMHal.h"
#include "TMIPC.h"

static void mmBOUNDS(ThreadId currentThread);
static void mmCoProSeg(ThreadId currentThread);
static void mmInvTSS(ThreadId currentThread);
static void mmSegNotPres(ThreadId currentThread);
static void mmStackEx(ThreadId currentThread);
static void mmPageFault(ThreadId currentThread);
static void mmAlignment(ThreadId currentThread);

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


void mmInstallErrorHandlers(void)
{
  tmSetExceptionHandler(T_EX_05, mmBOUNDS);
  tmSetExceptionHandler(T_EX_09, mmCoProSeg);
  tmSetExceptionHandler(T_EX_0A, mmInvTSS);
  tmSetExceptionHandler(T_EX_0B, mmSegNotPres);
  tmSetExceptionHandler(T_EX_0C, mmStackEx);
  tmSetExceptionHandler(T_EX_0E, mmPageFault);
  tmSetExceptionHandler(T_EX_11, mmAlignment);
}


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

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

  ERROR(errorString);
  ERROR("Hi");
  /* LR 000604 */
  asm("hlt");
  /* immediate in-kernel delivery without syscall
   * kSend does a schedule after the message arrived
   */
  kSend(TMTHREADID, &msg);
}

static void mmBOUNDS(ThreadId currentThread)
{
  mmError(currentThread,"Boundary Check Violation");
}
static void mmCoProSeg(ThreadId currentThread)
{
  mmError(currentThread,"Co-Processor Segment Overrun");
}
static void mmInvTSS(ThreadId currentThread)
{
  mmError(currentThread,"Invalid Task State Segment");
}
static void mmSegNotPres(ThreadId currentThread)
{
  mmError(currentThread,"Segment not Present");
}
static void mmStackEx(ThreadId currentThread)
{
  mmError(currentThread,"Stack Exception");
}
static void mmPageFault(ThreadId currentThread)
{
  mmError(currentThread,"Page Fault");
}
static void mmAlignment(ThreadId currentThread)
{
  mmError(currentThread,"Alignment Check Error");
}
