source: rtems/c/src/lib/libbsp/powerpc/score603e/startup/genpvec.c @ f05b2ac

4.104.114.84.9
Last change on this file since f05b2ac was f05b2ac, checked in by Ralf Corsepius <ralf.corsepius@…>, on Apr 21, 2004 at 4:01:48 PM

Remove duplicate white lines.

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*  genpvec.c
2 *
3 *  These routines handle the external exception.  Multiple ISRs occur off
4 *  of this one interrupt.
5 *
6 *  COPYRIGHT (c) 1989-1997.
7 *  On-Line Applications Research Corporation (OAR).
8 *
9 *  The license and distribution terms for this file may in
10 *  the file LICENSE in this distribution or at
11 *  http://www.rtems.com/license/LICENSE.
12 *
13 *  $Id$
14 */
15
16#include <bsp.h>
17#include <rtems/chain.h>
18#include <assert.h>
19
20#include <stdio.h> /* for sprintf */
21
22/*
23 * Proto types for this file
24 */
25
26rtems_isr external_exception_ISR (
27  rtems_vector_number   vector                                  /* IN  */
28);
29
30#define   NUM_LIRQ_HANDLERS   20
31#define   NUM_LIRQ            ( MAX_BOARD_IRQS - PPC_IRQ_LAST )
32
33/*
34 * Structure to for one of possible multiple interrupt handlers for
35 * a given interrupt.
36 */
37typedef struct
38{
39  Chain_Node          Node;
40  rtems_isr_entry     handler;                  /* isr routine        */
41  rtems_vector_number vector;                   /* vector number      */
42} EE_ISR_Type;
43
44/* Note:  The following will not work if we add a method to remove
45 *        handlers at a later time.
46 */
47  EE_ISR_Type       ISR_Nodes [NUM_LIRQ_HANDLERS];
48  uint16_t          Nodes_Used;
49  Chain_Control     ISR_Array  [NUM_LIRQ];
50
51/* XXX */
52void init_irq_data_register();
53
54void initialize_external_exception_vector ()
55{
56  int i;
57  rtems_isr_entry previous_isr;
58  rtems_status_code status;
59
60  Nodes_Used = 0;
61
62  /*
63   * Mask out all interupts until they have a handler installed.
64   */
65
66  for (i=0; i <NUM_LIRQ; i++)
67    Chain_Initialize_empty( &ISR_Array[i] );
68
69  init_irq_data_register();
70
71  /*
72   * Install external_exception_ISR () as the handler for
73   *  the General Purpose Interrupt.
74   */
75  status = rtems_interrupt_catch( external_exception_ISR,
76           PPC_IRQ_EXTERNAL, (rtems_isr_entry *) &previous_isr );
77}
78
79void Init_EE_mask_init() {
80;
81}
82
83/*
84 *  This routine installs one of multiple ISRs for the general purpose
85 *  inerrupt.
86 */
87rtems_isr_entry  set_EE_vector(
88  rtems_isr_entry     handler,      /* isr routine        */
89  rtems_vector_number vector        /* vector number      */
90)
91{
92  uint16_t         vec_idx  = vector - Score_IRQ_First;
93  uint32_t         index;
94
95  assert  (Nodes_Used < NUM_LIRQ_HANDLERS);
96
97  /*
98   *  If we have already installed this handler for this vector, then
99   *  just reset it.
100   */
101
102  for ( index=0 ; index <= Nodes_Used ; index++ ) {
103    if ( ISR_Nodes[index].vector == vector &&
104         ISR_Nodes[index].handler == handler )
105      return NULL;
106  }
107
108  /*
109   *  Doing things in this order makes them more atomic
110   */
111
112  Nodes_Used++;
113
114  index = Nodes_Used - 1;
115
116  ISR_Nodes[index].handler = handler;
117  ISR_Nodes[index].vector  = vector;
118
119  /* printf( "Vector Index: %04x, Vector: %d (%x)\n",
120          vec_idx, vector, vector); */
121
122  Chain_Append( &ISR_Array[vec_idx], &ISR_Nodes[index].Node );
123
124  /*
125   * Unmask the interrupt.
126   */
127  unmask_irq( vec_idx );
128
129  return NULL;
130}
131
132/*
133 * This interrupt service routine is called for an External Exception.
134 */
135rtems_isr external_exception_ISR (
136  rtems_vector_number   vector             /* IN  */
137)
138{
139 uint16_t            index;
140 EE_ISR_Type         *node;
141 uint16_t            value;
142 char                err_msg[100];
143#if (HAS_PMC_PSC8)
144 uint16_t            PMC_irq;
145 uint16_t            check_irq;
146 uint16_t            status_word;
147#endif
148
149 index = read_and_clear_irq();
150 if ( index >= NUM_LIRQ ) {
151   sprintf( err_msg, "ERROR:: Invalid interrupt number (%02x)\n", index );
152   DEBUG_puts( err_msg );
153   return;
154 }
155
156#if (HAS_PMC_PSC8)
157  PMC_irq = SCORE603E_PCI_IRQ_0 - SCORE603E_IRQ00;
158
159  if (index ==  PMC_irq) {
160    status_word = read_and_clear_PMC_irq( index );
161
162    for (check_irq=SCORE603E_IRQ16; check_irq<=SCORE603E_IRQ19; check_irq++) {
163      if ( Is_PMC_IRQ( check_irq, status_word )) {
164        index = check_irq - SCORE603E_IRQ00;
165        node = (EE_ISR_Type *)(ISR_Array[ index ].first);
166
167        if ( _Chain_Is_tail( &ISR_Array[ index ], (void *)node ) ) {
168          sprintf(err_msg,"ERROR:: check %d interrupt %02d has no isr\n",
169                  check_irq, index);
170          DEBUG_puts( err_msg);
171          value = get_irq_mask();
172          sprintf(err_msg,"        Mask = %02x\n", value);
173          DEBUG_puts( err_msg);
174        }
175        while ( !_Chain_Is_tail( &ISR_Array[ index ], (void *)node ) ) {
176          (*node->handler)( node->vector );
177          node = (EE_ISR_Type *) node->Node.next;
178        }
179      }
180    }
181  }
182  else
183#endif
184  {
185    node = (EE_ISR_Type *)(ISR_Array[ index ].first);
186    if ( _Chain_Is_tail( &ISR_Array[ index ], (void *)node ) ) {
187      sprintf(err_msg,"ERROR:: interrupt %02x has no isr\n", index);
188      DEBUG_puts( err_msg);
189      value = get_irq_mask();
190      sprintf(err_msg,"        Mask = %02x\n", value);
191      DEBUG_puts( err_msg);
192      return;
193    }
194    while ( !_Chain_Is_tail( &ISR_Array[ index ], (void *)node ) ) {
195     (*node->handler)( node->vector );
196     node = (EE_ISR_Type *) node->Node.next;
197    }
198  }
199
200}
Note: See TracBrowser for help on using the repository browser.