home *** CD-ROM | disk | FTP | other *** search
- /*
- ***************************************************************************
- *
- * 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
-
-