RTEMS
spurious.c
1 /*
2  * LEON Spurious Trap Handler
3  *
4  * This is just enough of a trap handler to let us know what
5  * the likely source of the trap was.
6  *
7  * Developed as part of the port of RTEMS to the LEON implementation
8  * of the SPARC by On-Line Applications Research Corporation (OAR)
9  * under contract to the European Space Agency (ESA).
10  *
11  * COPYRIGHT (c) 1995. European Space Agency.
12  *
13  * Modified for LEON3 BSP.
14  * COPYRIGHT (c) 2004.
15  * Gaisler Research.
16  *
17  * This terms of the RTEMS license apply to this file.
18  */
19 
20 #include <bsp.h>
21 #include <rtems/score/cpu.h>
22 #include <rtems/bspIo.h>
23 #include <inttypes.h>
24 
25 void _CPU_Exception_frame_print( const CPU_Exception_frame *frame )
26 {
27  uint32_t trap;
28  uint32_t real_trap;
29  const CPU_Interrupt_frame *isf;
30 
31  trap = frame->trap;
32  real_trap = SPARC_REAL_TRAP_NUMBER(trap);
33  isf = frame->isf;
34 
35  printk(
36  "Unexpected trap (%2" PRId32 ") at address 0x%08" PRIx32 "\n",
37  real_trap,
38  isf->tpc
39  );
40 
41  switch (real_trap) {
42 
43  /*
44  * First the ones defined by the basic architecture
45  */
46 
47  case 0x00:
48  printk( "reset\n" );
49  break;
50  case 0x01:
51  printk( "instruction access exception\n" );
52  break;
53  case 0x02:
54  printk( "illegal instruction\n" );
55  break;
56  case 0x03:
57  printk( "privileged instruction\n" );
58  break;
59  case 0x04:
60  printk( "fp disabled\n" );
61  break;
62  case 0x07:
63  printk( "memory address not aligned\n" );
64  break;
65  case 0x08:
66  printk( "fp exception\n" );
67  break;
68  case 0x0A:
69  printk( "tag overflow\n" );
70  break;
71 
72  /*
73  * Then the ones defined by the LEON in particular
74  */
75  /* FIXME */
76 
77  /*
78  case LEON_TRAP_TYPE( LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR ):
79  printk( "LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR\n" );
80  break;
81  case LEON_TRAP_TYPE( LEON_INTERRUPT_UART_2_RX_TX ):
82  printk( "LEON_INTERRUPT_UART_2_RX_TX\n" );
83  break;
84  case LEON_TRAP_TYPE( LEON_INTERRUPT_UART_1_RX_TX ):
85  printk( "LEON_INTERRUPT_UART_1_RX_TX\n" );
86  break;
87  case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_0 ):
88  printk( "LEON_INTERRUPT_EXTERNAL_0\n" );
89  break;
90  case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_1 ):
91  printk( "LEON_INTERRUPT_EXTERNAL_1\n" );
92  break;
93  case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_2 ):
94  printk( "LEON_INTERRUPT_EXTERNAL_2\n" );
95  break;
96  case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_3 ):
97  printk( "LEON_INTERRUPT_EXTERNAL_3\n" );
98  break;
99  case LEON_TRAP_TYPE( LEON_INTERRUPT_TIMER1 ):
100  printk( "LEON_INTERRUPT_TIMER1\n" );
101  break;
102  case LEON_TRAP_TYPE( LEON_INTERRUPT_TIMER2 ):
103  printk( "LEON_INTERRUPT_TIMER2\n" );
104  break;
105  */
106 
107  default:
108  break;
109  }
110 }
111 
112 static rtems_isr bsp_spurious_handler(
113  rtems_vector_number trap,
115 )
116 {
117  CPU_Exception_frame frame = {
118  .trap = trap,
119  .isf = isf
120  };
121 
122 #if !defined(SPARC_USE_LAZY_FP_SWITCH)
123  if ( SPARC_REAL_TRAP_NUMBER( trap ) == 4 ) {
124  _Internal_error( INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT );
125  }
126 #endif
127 
128  rtems_fatal(
130  (rtems_fatal_code) &frame
131  );
132 }
133 
134 /*
135  * bsp_spurious_initialize
136  *
137  * Install the spurious handler for most traps. Note that set_vector()
138  * will unmask the corresponding asynchronous interrupt, so the initial
139  * interrupt mask is restored after the handlers are installed.
140  */
141 
142 void bsp_spurious_initialize()
143 {
144  uint32_t trap;
145  uint32_t level;
146  /* uint32_t mask; */
147 
148  level = sparc_disable_interrupts();
149  /* mask = LEON3_IrqCtrl_Regs->mask_p0; */
150 
151  for ( trap=0 ; trap<256 ; trap++ ) {
152 
153  /*
154  * Skip window overflow, underflow, and flush as well as software
155  * trap 0,9,10 which we will use as a shutdown, IRQ disable, IRQ enable.
156  * Also avoid trap 0x70 - 0x7f which cannot happen and where some of the
157  * space is used to pass parameters to the program.
158  */
159 
160  if (( trap == 5 ) || ( trap == 6 ) ||
161 #if defined(SPARC_USE_LAZY_FP_SWITCH)
162  ( trap == 4 ) ||
163 #endif
164  (( trap >= 0x11 ) && ( trap <= 0x1f )) ||
165  (( trap >= 0x70 ) && ( trap <= 0x83 )) ||
166  ( trap == 0x80 + SPARC_SWTRAP_IRQDIS ) ||
167 #if defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH)
168  ( trap == 0x80 + SPARC_SWTRAP_IRQDIS_FP ) ||
169 #endif
170  ( trap == 0x80 + SPARC_SWTRAP_IRQEN ))
171  continue;
172 
173  set_vector(
174  (rtems_isr_entry) bsp_spurious_handler,
175  SPARC_SYNCHRONOUS_TRAP( trap ),
176  1
177  );
178  }
179 
180  /* LEON3_IrqCtrl_Regs->mask_p0 = mask; */
182 
183 }
static uint32_t sparc_disable_interrupts(void)
SPARC disable processor interrupts.
Definition: sparc.h:319
static RTEMS_NO_RETURN void rtems_fatal(rtems_fatal_source fatal_source, rtems_fatal_code error_code)
%
Definition: fatal.h:162
static void sparc_enable_interrupts(uint32_t psr)
SPARC enable processor interrupts.
Definition: sparc.h:333
Fatal source of the exceptions.
Definition: interr.h:119
Interrupt stack frame (ISF).
Definition: cpu.h:571
#define SPARC_REAL_TRAP_NUMBER(_trap)
Definition: cpu.h:713
uint32_t tpc
Definition: cpu.h:613
SPARC CPU Department Source.
Interface to Kernel Print Methods.
Internal_errors_t rtems_fatal_code
%
Definition: extension.h:132
#define SPARC_SYNCHRONOUS_TRAP(_trap)
Definition: cpu.h:708
void _Internal_error(Internal_errors_Core_list core_error) RTEMS_NO_RETURN
Terminates the system with an INTERNAL_ERROR_CORE fatal source and the specified core error code...
Definition: interr.c:51
void(* rtems_isr_entry)(void *)
Interrupt service routines installed by rtems_interrupt_catch() shall have this function pointer type...
Definition: intr.h:103
ISR_Handler rtems_isr
%
Definition: intr.h:202
ISR_Vector_number rtems_vector_number
%
Definition: intr.h:90
int printk(const char *fmt,...) RTEMS_PRINTFLIKE(1
Kernel Print.