summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc/erc32/gnatsupp/gnatsupp.c
blob: 79f1f037db41d581e525634c854f00c98d56e5c4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
 *
 * Support for gnat/rtems machine error exception handling.
 * Jiri Gaisler, ESA/ESTEC, 17-02-1999.
 *
 */

#include <bsp.h>
#include <signal.h>

/*
 * Synchronous trap handler. Map the trap number of SIGFPE, SIGSEGV
 * or SIGILL to generate the corresponding Ada exception.
 */

rtems_isr __gnat_exception_handler
    ( rtems_vector_number trap)
{
    rtems_unsigned32 real_trap;
    rtems_unsigned32 signal;

    real_trap = SPARC_REAL_TRAP_NUMBER(trap);
    switch (real_trap) {
        case 0x08: 		/* FPU exception */
        case 0x0A: 		/* TAG overflow */
        case 0x82: 		/* divide by zero */
	    signal = SIGFPE;	/* Will cause Constraint_Error */
	    break;
        case 0x01: 		/* Instruction access exception */
        case 0x09: 		/* Data access exception */
	    signal = SIGSEGV;	/* Will cause Storage_Error */
	    break;
        default:		/* Anything else ... */
	    signal = SIGILL;	/* Will cause Program_Error */
	    break;
    }
    kill(getpid(),signal);
}

/*
 * Asynchronous trap handler. As it happens, the interrupt trap numbers for
 * SPARC is 17 - 31, so we just map then directly on the same signal.
 */

rtems_isr __gnat_interrupt_handler
    ( rtems_vector_number trap)
{
    rtems_unsigned32 real_trap;

    real_trap = SPARC_REAL_TRAP_NUMBER(trap);

    kill(getpid(),real_trap);

}

/*
 * Default signal handler with error reporting 
 */

void __gnat_signals_Abormal_termination_handler( int signo )
{
  switch ( signo ) {
  case SIGFPE: 
    DEBUG_puts("\nConstraint_Error\n");
    break;
  case SIGSEGV: 
    DEBUG_puts("\nStorage_Error\n");
    break;
  default:
    DEBUG_puts("\nProgram_Error\n");
    break;
  }
  exit( 1 );
}

const struct sigaction __gnat_error_vector = {
  0, -1, {__gnat_signals_Abormal_termination_handler}};

void __gnat_install_handler()
{
    rtems_unsigned32 trap;
    rtems_isr_entry previous_isr;

    sigaction(SIGSEGV, &__gnat_error_vector, NULL);
    sigaction(SIGFPE , &__gnat_error_vector, NULL);
    sigaction(SIGILL , &__gnat_error_vector, NULL);

    for ( trap=0 ; trap<256 ; trap++ ) {

	/*
	*  Skip window overflow, underflow, and flush as well as software
	*  trap 0 which we will use as a shutdown. Also avoid trap 0x70 - 0x7f
	*  which cannot happen and where some of the space is used to pass
	*  paramaters to the program. Trap 0x1d is used by the clock tick
	*  and 0x83 by the remote debugging stub.
	*/

	if (( trap >= 0x11 ) && ( trap <= 0x1f )) {
	   if ( trap != 0x1d )
	    	rtems_interrupt_catch( __gnat_interrupt_handler, 
		    trap, &previous_isr );
	} else if (( trap != 5 && trap != 6 && trap != 0x83 ) &&
		  (( trap < 0x70 ) || ( trap > 0x80 )))
	    set_vector( __gnat_exception_handler, 
	    		SPARC_SYNCHRONOUS_TRAP( trap ), 1 );
    }
}