/* TMError.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. */ #include "TMError.h" static void tmReservedInstructionError(ThreadId currentThread); static void tmSignalInterruptError(ThreadId currentThread); static void tmSignalEMT(ThreadId currentThread); void tmInstallErrorHandlers(void) { /* Vital for correct operations */ tmSetExceptionHandler(SEND, syscallExceptionHandler); tmSetExceptionHandler(RECV, syscallExceptionHandler); tmSetExceptionHandler(ALARM, tmClockHandler); /* Error handling for faulting threads */ tmSetExceptionHandler(RESERVEDINSTRUCTION, tmReservedInstructionError); tmSetExceptionHandler(INTERRUPTSIGNAL, tmSignalInterruptError); #ifdef linux tmSetExceptionHandler(SIGUNUSED, tmSignalEMT); #else tmSetExceptionHandler(SIGEMT, tmSignalEMT); #endif } void tmError(ThreadId currentThread, char* errorString) { Message msg; msg.id = TM_KILL; msg.from = TMTHREADID; 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 tmReservedInstructionError(ThreadId currentThread) { tmError(currentThread, "reserved instruction"); } static void tmSignalInterruptError(ThreadId currentThread) { tmError(currentThread, "sig int, exiting..."); exit(0); } // used in unix for a simple exit on stack underflow // on native systems this is usually a little more complex using // exit code and an exit message on the stack... static void tmSignalEMT(ThreadId currentThread) { Message msg; msg.id = TM_KILL; msg.from = TMTHREADID; msg.msg.tmKill.id = currentThread; kSend(TMTHREADID, &msg); }