OpenCores
URL https://opencores.org/ocsvn/ao486/ao486/trunk

Subversion Repositories ao486

[/] [ao486/] [trunk/] [syn/] [soc/] [firmware/] [exe_bsp/] [HAL/] [src/] [alt_irq_handler.c] - Blame information for rev 7

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/******************************************************************************
2
*                                                                             *
3
* License Agreement                                                           *
4
*                                                                             *
5
* Copyright (c) 2009      Altera Corporation, San Jose, California, USA.      *
6
* All rights reserved.                                                        *
7
*                                                                             *
8
* Permission is hereby granted, free of charge, to any person obtaining a     *
9
* copy of this software and associated documentation files (the "Software"),  *
10
* to deal in the Software without restriction, including without limitation   *
11
* the rights to use, copy, modify, merge, publish, distribute, sublicense,    *
12
* and/or sell copies of the Software, and to permit persons to whom the       *
13
* Software is furnished to do so, subject to the following conditions:        *
14
*                                                                             *
15
* The above copyright notice and this permission notice shall be included in  *
16
* all copies or substantial portions of the Software.                         *
17
*                                                                             *
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  *
19
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,    *
20
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
21
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      *
22
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING     *
23
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER         *
24
* DEALINGS IN THE SOFTWARE.                                                   *
25
*                                                                             *
26
* This agreement shall be governed in all respects by the laws of the State   *
27
* of California and by the laws of the United States of America.              *
28
*                                                                             *
29
* Altera does not recommend, suggest or require that this reference design    *
30
* file be used in conjunction or combination with any other product.          *
31
******************************************************************************/
32
 
33
#include <errno.h>
34
#include "system.h"
35
 
36
/*
37
 * This interrupt handler only works with an internal interrupt controller
38
 * (IIC). Processors with an external interrupt controller (EIC) use an
39
 * implementation provided by an EIC driver.
40
 */
41
#ifndef ALT_CPU_EIC_PRESENT
42
 
43
#include "sys/alt_irq.h"
44
#include "os/alt_hooks.h"
45
 
46
#include "alt_types.h"
47
 
48
/*
49
 * A table describing each interrupt handler. The index into the array is the
50
 * interrupt id associated with the handler.
51
 *
52
 * When an interrupt occurs, the associated handler is called with
53
 * the argument stored in the context member.
54
 */
55
struct ALT_IRQ_HANDLER
56
{
57
#ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT
58
  void (*handler)(void*);
59
#else
60
  void (*handler)(void*, alt_u32);
61
#endif
62
  void *context;
63
} alt_irq[ALT_NIRQ];
64
 
65
/*
66
 * alt_irq_handler() is called by the interrupt exception handler in order to
67
 * process any outstanding interrupts.
68
 *
69
 * It is defined here since it is linked in using weak linkage.
70
 * This means that if there is never a call to alt_irq_register() (above) then
71
 * this function will not get linked in to the executable. This is acceptable
72
 * since if no handler is ever registered, then an interrupt can never occur.
73
 *
74
 * If Nios II interrupt vector custom instruction exists, use it to accelerate
75
 * the dispatch of interrupt handlers.  The Nios II interrupt vector custom
76
 * instruction is present if the macro ALT_CI_INTERRUPT_VECTOR defined.
77
 */
78
 
79
void alt_irq_handler (void) __attribute__ ((section (".exceptions")));
80
void alt_irq_handler (void)
81
{
82
#ifdef ALT_CI_INTERRUPT_VECTOR
83
  alt_32 offset;
84
  char*  alt_irq_base = (char*)alt_irq;
85
#else
86
  alt_u32 active;
87
  alt_u32 mask;
88
  alt_u32 i;
89
#endif /* ALT_CI_INTERRUPT_VECTOR */
90
 
91
  /*
92
   * Notify the operating system that we are at interrupt level.
93
   */
94
 
95
  ALT_OS_INT_ENTER();
96
 
97
#ifdef ALT_CI_INTERRUPT_VECTOR
98
  /*
99
   * Call the interrupt vector custom instruction using the
100
   * ALT_CI_INTERRUPT_VECTOR macro.
101
   * It returns the offset into the vector table of the lowest-valued pending
102
   * interrupt (corresponds to highest priority) or a negative value if none.
103
   * The custom instruction assumes that each table entry is eight bytes.
104
   */
105
  while ((offset = ALT_CI_INTERRUPT_VECTOR) >= 0) {
106
    struct ALT_IRQ_HANDLER* handler_entry =
107
      (struct ALT_IRQ_HANDLER*)(alt_irq_base + offset);
108
#ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT
109
    handler_entry->handler(handler_entry->context);
110
#else
111
    handler_entry->handler(handler_entry->context, offset >> 3);
112
#endif
113
  }
114
#else /* ALT_CI_INTERRUPT_VECTOR */
115
  /*
116
   * Obtain from the interrupt controller a bit list of pending interrupts,
117
   * and then process the highest priority interrupt. This process loops,
118
   * loading the active interrupt list on each pass until alt_irq_pending()
119
   * return zero.
120
   *
121
   * The maximum interrupt latency for the highest priority interrupt is
122
   * reduced by finding out which interrupts are pending as late as possible.
123
   * Consider the case where the high priority interupt is asserted during
124
   * the interrupt entry sequence for a lower priority interrupt to see why
125
   * this is the case.
126
   */
127
 
128
  active = alt_irq_pending ();
129
 
130
  do
131
  {
132
    i = 0;
133
    mask = 1;
134
 
135
    /*
136
     * Test each bit in turn looking for an active interrupt. Once one is
137
     * found, the interrupt handler asigned by a call to alt_irq_register() is
138
     * called to clear the interrupt condition.
139
     */
140
 
141
    do
142
    {
143
      if (active & mask)
144
      {
145
#ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT
146
        alt_irq[i].handler(alt_irq[i].context);
147
#else
148
        alt_irq[i].handler(alt_irq[i].context, i);
149
#endif
150
        break;
151
      }
152
      mask <<= 1;
153
      i++;
154
 
155
    } while (1);
156
 
157
    active = alt_irq_pending ();
158
 
159
  } while (active);
160
#endif /* ALT_CI_INTERRUPT_VECTOR */
161
 
162
  /*
163
   * Notify the operating system that interrupt processing is complete.
164
   */
165
 
166
  ALT_OS_INT_EXIT();
167
}
168
 
169
#endif /* ALT_CPU_EIC_PRESENT */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.