source: rtems/c/src/lib/libbsp/i386/shared/irq/irq.c @ ae75429

4.115
Last change on this file since ae75429 was ae75429, checked in by Sebastian Huber <sebastian.huber@…>, on Aug 6, 2013 at 2:10:26 PM

PR766: Delete RTEMS_VIOLATE_KERNEL_VISIBILITY

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/* irq.c
2 *
3 *  This file contains the implementation of the function described in irq.h
4 *
5 *  Copyright (c) 2009 embedded brains GmbH
6 *  Copyright (C) 1998 valette@crf.canon.fr
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.rtems.com/license/LICENSE.
11 */
12
13#include <bsp.h>
14#include <bsp/irq.h>
15#include <bsp/irq-generic.h>
16
17#include <stdlib.h>
18#include <rtems/score/apiext.h>
19#include <stdio.h>
20#include <inttypes.h>
21
22/*
23 * pointer to the mask representing the additionnal irq vectors
24 * that must be disabled when a particular entry is activated.
25 * They will be dynamically computed from teh prioruty table given
26 * in BSP_rtems_irq_mngt_set();
27 * CAUTION : this table is accessed directly by interrupt routine
28 *           prologue.
29 */
30rtems_i8259_masks       irq_mask_or_tbl[BSP_IRQ_LINES_NUMBER];
31
32uint32_t            irq_count[BSP_IRQ_LINES_NUMBER] = {0};
33
34uint32_t
35BSP_irq_count_dump(FILE *f)
36{
37uint32_t tot = 0;
38int      i;
39        if ( !f )
40                f = stdout;
41        for ( i=0; i<BSP_IRQ_LINES_NUMBER; i++ ) {
42                tot += irq_count[i];
43                fprintf(f,"IRQ %2u: %9"PRIu32"\n", i, irq_count[i]);
44        }
45        return tot;
46}
47
48/*-------------------------------------------------------------------------+
49| Cache for 1st and 2nd PIC IRQ line's status (enabled or disabled) register.
50+--------------------------------------------------------------------------*/
51/*
52 * lower byte is interrupt mask on the master PIC.
53 * while upper bits are interrupt on the slave PIC.
54 * This cache is initialized in ldseg.s
55 */
56rtems_i8259_masks i8259s_cache = 0xFFFB;
57
58/*-------------------------------------------------------------------------+
59|         Function:  BSP_irq_disable_at_i8259s
60|      Description: Mask IRQ line in appropriate PIC chip.
61| Global Variables: i8259s_cache
62|        Arguments: vector_offset - number of IRQ line to mask.
63|          Returns: Nothing.
64+--------------------------------------------------------------------------*/
65int BSP_irq_disable_at_i8259s    (const rtems_irq_number irqLine)
66{
67  unsigned short        mask;
68  rtems_interrupt_level level;
69
70  if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
71       ((int)irqLine > BSP_MAX_ON_i8259S )
72       )
73    return 1;
74
75  rtems_interrupt_disable(level);
76
77  mask = 1 << irqLine;
78  i8259s_cache |= mask;
79
80  if (irqLine < 8)
81  {
82    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
83  }
84  else
85  {
86    outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
87  }
88  rtems_interrupt_enable(level);
89
90  return 0;
91}
92
93/*-------------------------------------------------------------------------+
94|         Function:  BSP_irq_enable_at_i8259s
95|      Description: Unmask IRQ line in appropriate PIC chip.
96| Global Variables: i8259s_cache
97|        Arguments: irqLine - number of IRQ line to mask.
98|          Returns: Nothing.
99+--------------------------------------------------------------------------*/
100int BSP_irq_enable_at_i8259s    (const rtems_irq_number irqLine)
101{
102  unsigned short        mask;
103  rtems_interrupt_level level;
104
105  if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
106       ((int)irqLine > BSP_MAX_ON_i8259S )
107       )
108    return 1;
109
110  rtems_interrupt_disable(level);
111
112  mask = ~(1 << irqLine);
113  i8259s_cache &= mask;
114
115  if (irqLine < 8)
116  {
117    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
118  }
119  else
120  {
121    outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
122  }
123  rtems_interrupt_enable(level);
124
125  return 0;
126} /* mask_irq */
127
128int BSP_irq_enabled_at_i8259s           (const rtems_irq_number irqLine)
129{
130  unsigned short mask;
131
132  if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
133       ((int)irqLine > BSP_MAX_ON_i8259S )
134     )
135    return 1;
136
137  mask = (1 << irqLine);
138  return  (~(i8259s_cache & mask));
139}
140
141/*-------------------------------------------------------------------------+
142|         Function: BSP_irq_ack_at_i8259s
143|      Description: Signal generic End Of Interrupt (EOI) to appropriate PIC.
144| Global Variables: None.
145|        Arguments: irqLine - number of IRQ line to acknowledge.
146|          Returns: Nothing.
147+--------------------------------------------------------------------------*/
148int BSP_irq_ack_at_i8259s       (const rtems_irq_number irqLine)
149{
150  if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
151       ((int)irqLine > BSP_MAX_ON_i8259S )
152       )
153    return 1;
154
155  if (irqLine >= 8) {
156   outport_byte(PIC_SLAVE_COMMAND_IO_PORT, PIC_EOI);
157  }
158  outport_byte(PIC_MASTER_COMMAND_IO_PORT, PIC_EOI);
159
160  return 0;
161
162} /* ackIRQ */
163
164/*
165 * ------------------------ RTEMS Irq helper functions ----------------
166 */
167
168static rtems_irq_prio irqPrioTable[BSP_IRQ_LINES_NUMBER]={
169  /*
170   * actual priorities for each interrupt source:
171   *    0   means that only current interrupt is masked
172   *    255 means all other interrupts are masked
173   * The second entry has a priority of 255 because
174   * it is the slave pic entry and is should always remain
175   * unmasked.
176   */
177  0,0,
178  255,
179  0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0
180};
181
182static void compute_i8259_masks_from_prio (void)
183{
184  rtems_interrupt_level level;
185  unsigned int i;
186  unsigned int j;
187
188  rtems_interrupt_disable(level);
189
190  /*
191   * Always mask at least current interrupt to prevent re-entrance
192   */
193  for (i=0; i < BSP_IRQ_LINES_NUMBER; i++) {
194    * ((unsigned short*) &irq_mask_or_tbl[i]) = (1 << i);
195    for (j = 0; j < BSP_IRQ_LINES_NUMBER; j++) {
196      /*
197       * Mask interrupts at i8259 level that have a lower priority
198       */
199      if (irqPrioTable [i] > irqPrioTable [j]) {
200        * ((unsigned short*) &irq_mask_or_tbl[i]) |= (1 << j);
201      }
202    }
203  }
204
205  rtems_interrupt_enable(level);
206}
207
208rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
209{
210  BSP_irq_enable_at_i8259s(vector);
211
212  return RTEMS_SUCCESSFUL;
213}
214
215rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
216{
217  BSP_irq_disable_at_i8259s(vector);
218
219  return RTEMS_SUCCESSFUL;
220}
221
222rtems_status_code bsp_interrupt_facility_initialize(void)
223{
224  /*
225   * set up internal tables used by rtems interrupt prologue
226   */
227  compute_i8259_masks_from_prio();
228
229  /*
230   * must enable slave pic anyway
231   */
232  BSP_irq_enable_at_i8259s(2);
233
234  return RTEMS_SUCCESSFUL;
235}
236
237void C_dispatch_isr(int vector)
238{
239  irq_count[vector]++;
240  bsp_interrupt_handler_dispatch(vector);
241}
Note: See TracBrowser for help on using the repository browser.