home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / monitors / rsys / source.lha / src / rsyssignaltrap.c < prev    next >
C/C++ Source or Header  |  1995-01-09  |  8KB  |  309 lines

  1. /*
  2. ***************************************************************************
  3. *
  4. * Datei:
  5. *    RSysSignalTrap.c
  6. *
  7. * Inhalt:
  8. *    void HandleTrap(int signal);
  9. *    void InstallTrapHandlers(void);
  10. *    void RemoveTrapHandlers(void);
  11. *    void _traphandler(long sig);
  12. *
  13. * Bemerkungen:
  14. *    Verwaltung eines Traphandlers, um RSys wirklich (?) absturzsicher
  15. *    zu machen.
  16. *
  17. * Erstellungsdatum:
  18. *    07-Jul-93    Rolf Böhme
  19. *
  20. * Änderungen:
  21. *    07-Jul-93    Rolf Böhme    Erstellung
  22. *
  23. ***************************************************************************
  24. */
  25.  
  26. #include "RSysDebug.h"
  27. #include "RSysFunc.h"
  28.  
  29. /*
  30. #define SIG_BEGINSSP       0
  31. #define SIG_BEGINPC        1
  32. #define SIG_BUSERROR       2
  33. #define SIG_ADDRERROR      3
  34. #define SIG_ILLCOMM        4
  35. #define SIG_DIVZERO        5
  36. #define SIG_CHKERROR       6
  37. #define SIG_TRAPV          7
  38. #define SIG_VIOLPRIV       8
  39. #define SIG_TRACE          9
  40. #define SIG_LINEAEMUL      10
  41. #define SIG_LINEFEMUL      11
  42. #define SIG_NOTDEF         12
  43. #define SIG_COPROPROT      13
  44. #define SIG_FORMATERR      14
  45. #define SIG_INTRFAIL       15
  46.  
  47. #define SIG_MC_ILLCOND     48
  48. #define SIG_MC_ILLRESULT   49
  49. #define SIG_MC_DIVZERO     50
  50. #define SIG_MC_UNDERFLOW   51
  51. #define SIG_MC_OPERROR     52
  52. #define SIG_MC_OVERFLOW    53
  53. #define SIG_MC_NANSIG      54
  54. #define SIG_MC_NOTDEF      55
  55. */
  56.  
  57. #define _NUMSIG            15
  58. #define _FSTSIG            0
  59.  
  60. void (*mysignal(register int sig, void (*func)(int)))(int);
  61. void my_sig_setup(void);
  62.  
  63. void (*_sigfuncs[_NUMSIG])(int);
  64. int _trapexception(void);
  65. void *_oldtrap, **_trapaddr;
  66.  
  67. static struct Task *tp;
  68.  
  69. char *TrapCPUMsg[] = {
  70.    "Begin of SSP (ISP by 680x0)",
  71.    "Begin of PC",
  72.    "Bus error",
  73.    "Address error",
  74.    "Illegal or unknown instruction",
  75.    "Division by zero or arithmetic fault",
  76.    "CHK and CHK2 affected",
  77.    "TRAP or TRAPV reached",
  78.    "Priviledge violation",
  79.    "Trace error",
  80.    "Line A Emulator, illegal Opcode by MC68000",
  81.    "Line F Emulator, illegal Opcode by MC68000",
  82.    "Error is reserved",
  83.    "Coprocessor protocol error",
  84.    "Format error by MC680x0",
  85.    "Uninitialized Interrupt"
  86. };
  87.  
  88.    /*
  89.     * convert() konvertiert eine 32Bit-Zahl in einen
  90.     * "Binärstring", also in einen String, der nur aus '0'
  91.     * und '1' besteht
  92.     */
  93. static void
  94. convert(ULONG state,char *str)
  95. {
  96.    register int bit;
  97.  
  98.    for( bit = 0; bit < 32; bit++ )
  99.       str[31-bit] = ((state & (1L<<bit)) ? '1' : '0');
  100.  
  101.    str[32] = STRINGEND;
  102. }
  103.  
  104.    /*
  105.     * HandleTrap() ist die Funktion, die im Falle eines
  106.     * System traps aktiviert wird. Diese Routine ruft
  107.     * entweder den System debugger ROMWack auf, oder
  108.     * verursacht einen Kaltstart des Rechners, falls dies
  109.     * gewünscht wird. Installiert wird diese Routine
  110.     * mit der ANSI-Routine signal() des
  111.     * Aztec-C-Compilers
  112.     */
  113. void
  114. HandleTrap(int signal)
  115. {
  116.    int action;
  117.    char exceptstr[33],signalstr[33],statestr[33];
  118.    UBYTE *fmt = (UBYTE *)"Error signal: %s (%ld)\n"
  119.                           "Exception   : %s (0x%08lX)\n"
  120.                           "Task signal : %s (0x%08lX)\n"
  121.                           "CPU Status  : %s (0x%08lX)\n"
  122.                          "Trap data   : %08lX\n"
  123.                          "Except data : %08lX\n";
  124.    ULONG exc,sig,sta;
  125.    APTR UserStack;
  126.  
  127.    UserStack = SuperState();
  128.  
  129.    exc = SetExcept(0L,0L);
  130.    sig = SetSignal(0L,0L);
  131.    sta = SetSR(0L,0L);
  132.  
  133.    UserState(UserStack);
  134.  
  135.    convert(exc,exceptstr);
  136.    convert(sig,signalstr);
  137.    convert(sta,statestr);
  138.  
  139.    if(IntuitionBase != NULL)
  140.        action = MyEasyRequest(NULL,
  141.                      (UBYTE *)NAME " *** Emergency trap failure message ***",
  142.                      (UBYTE *)"Continue|Terminate RSys|Call system debugger|Reboot system",
  143.                      fmt, TrapCPUMsg[signal], signal,
  144.                      exceptstr,exc,signalstr,sig,statestr,sta,
  145.                     tp->tc_TrapData, tp->tc_ExceptData);
  146.    else
  147.    {
  148.       action = 2;
  149.        Printf(fmt,(ULONG)TrapCPUMsg[signal],signal,
  150.                   exceptstr,exc,signalstr,sig,statestr,sta,
  151.                  tp->tc_TrapData, tp->tc_ExceptData);
  152.    }
  153.  
  154.    switch(action)
  155.    {
  156.       case 0:
  157.          ColdReboot();
  158.          break;
  159.  
  160.       case 1:
  161.          break;
  162.  
  163.       case 2:
  164.          CloseAll();
  165.          break;
  166.  
  167.       case 3:
  168.          Debug(0L);
  169.          CloseAll();
  170.          break;
  171.    }
  172.  
  173.    return;
  174. }
  175.  
  176.    /*
  177.     * InstallTrapHandlers() installiert einen Traphandler,
  178.     * der auf verschiedene Traps reagieren kann
  179.     */
  180. void
  181. InstallTrapHandlers(void)
  182. {
  183.    register int i;
  184.    extern struct ExecBase *SysBase;
  185.  
  186.    tp = FindTask(NULL);
  187.  
  188.    _trapaddr = (void *)&tp->tc_TrapCode;
  189.    _oldtrap= tp->tc_TrapCode;
  190.  
  191.    tp->tc_TrapCode = (APTR)&_trapexception;
  192.  
  193.    if (SysBase->AttnFlags & AFF_68881)
  194.    {
  195. #asm
  196.         mc68881
  197.  
  198.         fmove.l  FPCR,d0
  199.         or.w     #$1400,d0
  200.         fmove.l  d0,FPCR
  201. #endasm
  202.     }
  203.  
  204.    for(i = _FSTSIG; i <= _NUMSIG; i++)
  205.       _sigfuncs[i] = HandleTrap;
  206.  
  207.    return;
  208. }
  209.  
  210. void
  211. RemoveTrapHandlers(void)
  212. {
  213.    register int i;
  214.  
  215.    Forbid();
  216.  
  217.    if (_trapaddr)
  218.       *_trapaddr = _oldtrap;
  219.  
  220.    for(i = _FSTSIG; i <= _NUMSIG; i++)
  221.       _sigfuncs[i] = NULL;
  222.  
  223.    Permit();
  224.  
  225.    return;
  226. }
  227.  
  228. void
  229. _traphandler(long sig)
  230. {
  231.    register void (*handler)(int);
  232.  
  233.    if ((handler = _sigfuncs[sig]) != NULL)
  234.       (*handler)(sig);
  235.  
  236.    return;
  237. }
  238.  
  239. #asm
  240.         far      code
  241.  
  242.         public   _geta4
  243.         public   __trapexception
  244.  
  245. DEFTRAP MACRO                       ;&signalnumber
  246.         cmp.w    \1,d0             ;compare trap number
  247.         beq      _deftrap           ;branch to default traphandler
  248.         ENDM
  249.  
  250. MYTRAP  MACRO                       ;&signalnumber
  251.         cmp.w    \1,d0             ;compare trap number
  252.         beq      _mytrap            ;branch to own traphandler
  253.         ENDM
  254.  
  255. __trapexception:
  256.         movem.l  d0/a4,-(sp)        ;need some registers
  257.         jsr      _geta4             ;set up a4
  258.         move.l   8(sp),d0           ;get trap number
  259.         DEFTRAP  #1                 ;define the traphandler
  260.         DEFTRAP  #2
  261.         DEFTRAP  #3
  262.         MYTRAP   #4
  263.         MYTRAP   #5
  264.         MYTRAP   #6
  265.         DEFTRAP  #7
  266.         MYTRAP   #8
  267.         MYTRAP   #9
  268.         DEFTRAP  #10
  269.         DEFTRAP  #11
  270.         MYTRAP   #12
  271.         DEFTRAP  #13
  272.         DEFTRAP  #14
  273.         DEFTRAP  #15
  274.         MYTRAP   #16
  275.  
  276. _deftrap:
  277.         move.l   4(sp),d0           ;get a4 for later
  278.         move.l   __oldtrap,4(sp)    ;get regular handler
  279.         move.l   d0,a4              ;set real a4 value
  280.         move.l   (sp)+,d0           ;restore d0 contents
  281.         rte                         ;jump to it
  282.  
  283. _mytrap:
  284.         move.l   a0,-(sp)           ;save a0
  285.         move.l   usp,a0             ;get user stack pointer
  286.         move.l   18(sp),-(a0)       ;save old pc
  287.         move.w   14(sp),-(a0)       ;save old sr
  288.         movem.l  d0-d7/a0-a6,-(a0)  ;save old registers
  289.         movem.l  (sp)+,d1/d2/d3     ;restore d0/a0/a4
  290.         move.l   d1,(a0)            ;set d0
  291.         move.l   d2,32(a0)          ;set a0
  292.         move.l   d3,48(a0)          ;set a4
  293.         move.l   d0,-(a0)           ;pass trap number on stack
  294.         lea      _conttrap,a1       ;get return in case they want to continue
  295.         move.l   a1,-(a0)           ;set return address
  296.         move.l   a0,usp             ;set new user stack pointer
  297.         lea      __traphandler,a0   ;get trap handler
  298.         move.l   a0,6(sp)           ;modify rte address
  299.         addq     #4,sp              ;remove trap #
  300.         rte                         ;go and do the handler
  301.  
  302. _conttrap:
  303.         add.w    #4,sp              ;pop arg
  304.         movem.l  (sp)+,d0-d7/a0-a6  ;restore old registers
  305.         move.w   (sp)+,ccr          ;restore old condition codes
  306.         rts                         ;and continue where we left off
  307. #endasm
  308.  
  309.