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

4.115
Last change on this file since 41572c4 was 41572c4, checked in by Joel Sherrill <joel.sherrill@…>, on 01/31/12 at 21:15:20

Fix spelling error and improve comment.

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