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

4.11
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on Mar 20, 2014 at 9:10:47 PM

Change all references of rtems.com to rtems.org.

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