home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
monitors
/
rsys
/
source.lha
/
src
/
rsyssignaltrap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-09
|
8KB
|
309 lines
/*
***************************************************************************
*
* Datei:
* RSysSignalTrap.c
*
* Inhalt:
* void HandleTrap(int signal);
* void InstallTrapHandlers(void);
* void RemoveTrapHandlers(void);
* void _traphandler(long sig);
*
* Bemerkungen:
* Verwaltung eines Traphandlers, um RSys wirklich (?) absturzsicher
* zu machen.
*
* Erstellungsdatum:
* 07-Jul-93 Rolf Böhme
*
* Änderungen:
* 07-Jul-93 Rolf Böhme Erstellung
*
***************************************************************************
*/
#include "RSysDebug.h"
#include "RSysFunc.h"
/*
#define SIG_BEGINSSP 0
#define SIG_BEGINPC 1
#define SIG_BUSERROR 2
#define SIG_ADDRERROR 3
#define SIG_ILLCOMM 4
#define SIG_DIVZERO 5
#define SIG_CHKERROR 6
#define SIG_TRAPV 7
#define SIG_VIOLPRIV 8
#define SIG_TRACE 9
#define SIG_LINEAEMUL 10
#define SIG_LINEFEMUL 11
#define SIG_NOTDEF 12
#define SIG_COPROPROT 13
#define SIG_FORMATERR 14
#define SIG_INTRFAIL 15
#define SIG_MC_ILLCOND 48
#define SIG_MC_ILLRESULT 49
#define SIG_MC_DIVZERO 50
#define SIG_MC_UNDERFLOW 51
#define SIG_MC_OPERROR 52
#define SIG_MC_OVERFLOW 53
#define SIG_MC_NANSIG 54
#define SIG_MC_NOTDEF 55
*/
#define _NUMSIG 15
#define _FSTSIG 0
void (*mysignal(register int sig, void (*func)(int)))(int);
void my_sig_setup(void);
void (*_sigfuncs[_NUMSIG])(int);
int _trapexception(void);
void *_oldtrap, **_trapaddr;
static struct Task *tp;
char *TrapCPUMsg[] = {
"Begin of SSP (ISP by 680x0)",
"Begin of PC",
"Bus error",
"Address error",
"Illegal or unknown instruction",
"Division by zero or arithmetic fault",
"CHK and CHK2 affected",
"TRAP or TRAPV reached",
"Priviledge violation",
"Trace error",
"Line A Emulator, illegal Opcode by MC68000",
"Line F Emulator, illegal Opcode by MC68000",
"Error is reserved",
"Coprocessor protocol error",
"Format error by MC680x0",
"Uninitialized Interrupt"
};
/*
* convert() konvertiert eine 32Bit-Zahl in einen
* "Binärstring", also in einen String, der nur aus '0'
* und '1' besteht
*/
static void
convert(ULONG state,char *str)
{
register int bit;
for( bit = 0; bit < 32; bit++ )
str[31-bit] = ((state & (1L<<bit)) ? '1' : '0');
str[32] = STRINGEND;
}
/*
* HandleTrap() ist die Funktion, die im Falle eines
* System traps aktiviert wird. Diese Routine ruft
* entweder den System debugger ROMWack auf, oder
* verursacht einen Kaltstart des Rechners, falls dies
* gewünscht wird. Installiert wird diese Routine
* mit der ANSI-Routine signal() des
* Aztec-C-Compilers
*/
void
HandleTrap(int signal)
{
int action;
char exceptstr[33],signalstr[33],statestr[33];
UBYTE *fmt = (UBYTE *)"Error signal: %s (%ld)\n"
"Exception : %s (0x%08lX)\n"
"Task signal : %s (0x%08lX)\n"
"CPU Status : %s (0x%08lX)\n"
"Trap data : %08lX\n"
"Except data : %08lX\n";
ULONG exc,sig,sta;
APTR UserStack;
UserStack = SuperState();
exc = SetExcept(0L,0L);
sig = SetSignal(0L,0L);
sta = SetSR(0L,0L);
UserState(UserStack);
convert(exc,exceptstr);
convert(sig,signalstr);
convert(sta,statestr);
if(IntuitionBase != NULL)
action = MyEasyRequest(NULL,
(UBYTE *)NAME " *** Emergency trap failure message ***",
(UBYTE *)"Continue|Terminate RSys|Call system debugger|Reboot system",
fmt, TrapCPUMsg[signal], signal,
exceptstr,exc,signalstr,sig,statestr,sta,
tp->tc_TrapData, tp->tc_ExceptData);
else
{
action = 2;
Printf(fmt,(ULONG)TrapCPUMsg[signal],signal,
exceptstr,exc,signalstr,sig,statestr,sta,
tp->tc_TrapData, tp->tc_ExceptData);
}
switch(action)
{
case 0:
ColdReboot();
break;
case 1:
break;
case 2:
CloseAll();
break;
case 3:
Debug(0L);
CloseAll();
break;
}
return;
}
/*
* InstallTrapHandlers() installiert einen Traphandler,
* der auf verschiedene Traps reagieren kann
*/
void
InstallTrapHandlers(void)
{
register int i;
extern struct ExecBase *SysBase;
tp = FindTask(NULL);
_trapaddr = (void *)&tp->tc_TrapCode;
_oldtrap= tp->tc_TrapCode;
tp->tc_TrapCode = (APTR)&_trapexception;
if (SysBase->AttnFlags & AFF_68881)
{
#asm
mc68881
fmove.l FPCR,d0
or.w #$1400,d0
fmove.l d0,FPCR
#endasm
}
for(i = _FSTSIG; i <= _NUMSIG; i++)
_sigfuncs[i] = HandleTrap;
return;
}
void
RemoveTrapHandlers(void)
{
register int i;
Forbid();
if (_trapaddr)
*_trapaddr = _oldtrap;
for(i = _FSTSIG; i <= _NUMSIG; i++)
_sigfuncs[i] = NULL;
Permit();
return;
}
void
_traphandler(long sig)
{
register void (*handler)(int);
if ((handler = _sigfuncs[sig]) != NULL)
(*handler)(sig);
return;
}
#asm
far code
public _geta4
public __trapexception
DEFTRAP MACRO ;&signalnumber
cmp.w \1,d0 ;compare trap number
beq _deftrap ;branch to default traphandler
ENDM
MYTRAP MACRO ;&signalnumber
cmp.w \1,d0 ;compare trap number
beq _mytrap ;branch to own traphandler
ENDM
__trapexception:
movem.l d0/a4,-(sp) ;need some registers
jsr _geta4 ;set up a4
move.l 8(sp),d0 ;get trap number
DEFTRAP #1 ;define the traphandler
DEFTRAP #2
DEFTRAP #3
MYTRAP #4
MYTRAP #5
MYTRAP #6
DEFTRAP #7
MYTRAP #8
MYTRAP #9
DEFTRAP #10
DEFTRAP #11
MYTRAP #12
DEFTRAP #13
DEFTRAP #14
DEFTRAP #15
MYTRAP #16
_deftrap:
move.l 4(sp),d0 ;get a4 for later
move.l __oldtrap,4(sp) ;get regular handler
move.l d0,a4 ;set real a4 value
move.l (sp)+,d0 ;restore d0 contents
rte ;jump to it
_mytrap:
move.l a0,-(sp) ;save a0
move.l usp,a0 ;get user stack pointer
move.l 18(sp),-(a0) ;save old pc
move.w 14(sp),-(a0) ;save old sr
movem.l d0-d7/a0-a6,-(a0) ;save old registers
movem.l (sp)+,d1/d2/d3 ;restore d0/a0/a4
move.l d1,(a0) ;set d0
move.l d2,32(a0) ;set a0
move.l d3,48(a0) ;set a4
move.l d0,-(a0) ;pass trap number on stack
lea _conttrap,a1 ;get return in case they want to continue
move.l a1,-(a0) ;set return address
move.l a0,usp ;set new user stack pointer
lea __traphandler,a0 ;get trap handler
move.l a0,6(sp) ;modify rte address
addq #4,sp ;remove trap #
rte ;go and do the handler
_conttrap:
add.w #4,sp ;pop arg
movem.l (sp)+,d0-d7/a0-a6 ;restore old registers
move.w (sp)+,ccr ;restore old condition codes
rts ;and continue where we left off
#endasm