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

4.115
Last change on this file since ad2cefe was ad2cefe, checked in by Jennifer Averett <Jennifer.Averett@…>, on 07/14/11 at 17:30:28

2011-07-14 Jennifer Averett <Jennifer.Averett@…>

  • shared/irq/irq.c, shared/irq/irq.h, shared/irq/irq_init.c: Add initial support for APIC.
  • Property mode set to 100644
File size: 6.3 KB
RevLine 
[67a2288]1/* irq.c
2 *
3 *  This file contains the implementation of the function described in irq.h
4 *
[fc5490f]5 *  Copyright (c) 2009 embedded brains GmbH
[a62222fb]6 *  Copyright (C) 1998 valette@crf.canon.fr
[67a2288]7 *
8 *  The license and distribution terms for this file may be
[8c41855]9 *  found in the file LICENSE in this distribution or at
[a3c7123]10 *  http://www.rtems.com/license/LICENSE.
[67a2288]11 *
12 *  $Id$
13 */
14
[f9abe50]15/* so we can see _API_extensions_Run_postswitch */
16#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
17
[67a2288]18#include <bsp.h>
[529cebf0]19#include <bsp/irq.h>
[fc5490f]20#include <bsp/irq-generic.h>
21
[f9abe50]22#include <stdlib.h>
[eb562f2]23#include <rtems/score/apiext.h>
[385212f]24#include <stdio.h>
25#include <inttypes.h>
[eb562f2]26
[67a2288]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
[0ebbf66]31 * in BSP_rtems_irq_mngt_set();
[67a2288]32 * CAUTION : this table is accessed directly by interrupt routine
33 *           prologue.
34 */
[0ebbf66]35rtems_i8259_masks       irq_mask_or_tbl[BSP_IRQ_LINES_NUMBER];
[67a2288]36
[385212f]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
[67a2288]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 */
[a1c70a2]61rtems_i8259_masks i8259s_cache = 0xFFFB;
[67a2288]62
63/*-------------------------------------------------------------------------+
[0ebbf66]64|         Function:  BSP_irq_disable_at_i8259s
[67a2288]65|      Description: Mask IRQ line in appropriate PIC chip.
66| Global Variables: i8259s_cache
67|        Arguments: vector_offset - number of IRQ line to mask.
[6128a4a]68|          Returns: Nothing.
[67a2288]69+--------------------------------------------------------------------------*/
[838c82b]70int BSP_irq_disable_at_i8259s    (const rtems_irq_number irqLine)
[67a2288]71{
[c83c325]72  unsigned short        mask;
73  rtems_interrupt_level level;
[67a2288]74
[0ebbf66]75  if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
[ad2cefe]76       ((int)irqLine > BSP_MAX_ON_i8259S )
[67a2288]77       )
78    return 1;
[6128a4a]79
[c83c325]80  rtems_interrupt_disable(level);
[6128a4a]81
[67a2288]82  mask = 1 << irqLine;
83  i8259s_cache |= mask;
[6128a4a]84
[67a2288]85  if (irqLine < 8)
86  {
87    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
88  }
89  else
90  {
[783e8322]91    outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
[67a2288]92  }
[c83c325]93  rtems_interrupt_enable(level);
[67a2288]94
95  return 0;
[6128a4a]96}
[67a2288]97
98/*-------------------------------------------------------------------------+
[0ebbf66]99|         Function:  BSP_irq_enable_at_i8259s
[67a2288]100|      Description: Unmask IRQ line in appropriate PIC chip.
101| Global Variables: i8259s_cache
102|        Arguments: irqLine - number of IRQ line to mask.
[6128a4a]103|          Returns: Nothing.
[67a2288]104+--------------------------------------------------------------------------*/
[838c82b]105int BSP_irq_enable_at_i8259s    (const rtems_irq_number irqLine)
[67a2288]106{
[c83c325]107  unsigned short        mask;
108  rtems_interrupt_level level;
[67a2288]109
[0ebbf66]110  if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
[ad2cefe]111       ((int)irqLine > BSP_MAX_ON_i8259S )
[67a2288]112       )
113    return 1;
114
[c83c325]115  rtems_interrupt_disable(level);
[6128a4a]116
[67a2288]117  mask = ~(1 << irqLine);
118  i8259s_cache &= mask;
[6128a4a]119
[67a2288]120  if (irqLine < 8)
121  {
122    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
123  }
124  else
125  {
[783e8322]126    outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
[67a2288]127  }
[c83c325]128  rtems_interrupt_enable(level);
[67a2288]129
130  return 0;
131} /* mask_irq */
132
[838c82b]133int BSP_irq_enabled_at_i8259s           (const rtems_irq_number irqLine)
[67a2288]134{
135  unsigned short mask;
136
[0ebbf66]137  if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
[ad2cefe]138       ((int)irqLine > BSP_MAX_ON_i8259S )
[67a2288]139     )
140    return 1;
141
142  mask = (1 << irqLine);
143  return  (~(i8259s_cache & mask));
144}
[6128a4a]145
[67a2288]146/*-------------------------------------------------------------------------+
[0ebbf66]147|         Function: BSP_irq_ack_at_i8259s
[67a2288]148|      Description: Signal generic End Of Interrupt (EOI) to appropriate PIC.
149| Global Variables: None.
150|        Arguments: irqLine - number of IRQ line to acknowledge.
[6128a4a]151|          Returns: Nothing.
[67a2288]152+--------------------------------------------------------------------------*/
[838c82b]153int BSP_irq_ack_at_i8259s       (const rtems_irq_number irqLine)
[67a2288]154{
[0ebbf66]155  if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
[ad2cefe]156       ((int)irqLine > BSP_MAX_ON_i8259S )
[67a2288]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 */
[6128a4a]172
[fc5490f]173static rtems_irq_prio irqPrioTable[BSP_IRQ_LINES_NUMBER]={
174  /*
175   * actual rpiorities for interrupt :
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
[f9abe50]187static void compute_i8259_masks_from_prio (void)
[67a2288]188{
[fc5490f]189  rtems_interrupt_level level;
[67a2288]190  unsigned int i;
191  unsigned int j;
[fc5490f]192
[ad2cefe]193  rtems_interrupt_disable(level);
[fc5490f]194
[67a2288]195  /*
196   * Always mask at least current interrupt to prevent re-entrance
197   */
[fc5490f]198  for (i=0; i < BSP_IRQ_LINES_NUMBER; i++) {
[67a2288]199    * ((unsigned short*) &irq_mask_or_tbl[i]) = (1 << i);
[fc5490f]200    for (j = 0; j < BSP_IRQ_LINES_NUMBER; j++) {
[67a2288]201      /*
202       * Mask interrupts at i8259 level that have a lower priority
203       */
[fc5490f]204      if (irqPrioTable [i] > irqPrioTable [j]) {
[67a2288]205        * ((unsigned short*) &irq_mask_or_tbl[i]) |= (1 << j);
206      }
207    }
208  }
[a62222fb]209
210  rtems_interrupt_enable(level);
211}
212
[fc5490f]213rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
[67a2288]214{
[fc5490f]215  BSP_irq_enable_at_i8259s(vector);
[6128a4a]216
[fc5490f]217  return RTEMS_SUCCESSFUL;
[67a2288]218}
219
[fc5490f]220rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
[67a2288]221{
[fc5490f]222  BSP_irq_disable_at_i8259s(vector);
[fe235a1e]223
[fc5490f]224  return RTEMS_SUCCESSFUL;
[67a2288]225}
226
[fc5490f]227rtems_status_code bsp_interrupt_facility_initialize(void)
[67a2288]228{
[a62222fb]229  /*
[fc5490f]230   * set up internal tables used by rtems interrupt prologue
[a62222fb]231   */
[fc5490f]232  compute_i8259_masks_from_prio();
[67a2288]233
[a62222fb]234  /*
[fc5490f]235   * must enable slave pic anyway
[a62222fb]236   */
[fc5490f]237  BSP_irq_enable_at_i8259s(2);
[67a2288]238
[fc5490f]239  return RTEMS_SUCCESSFUL;
[67a2288]240}
241
[fc5490f]242void bsp_interrupt_handler_default(rtems_vector_number vector)
[67a2288]243{
[fc5490f]244  printk("spurious interrupt: %u\n", vector);
[67a2288]245}
246
[fc5490f]247void C_dispatch_isr(int vector)
[67a2288]248{
[385212f]249  irq_count[vector]++;
[fc5490f]250  bsp_interrupt_handler_dispatch(vector);
[6128a4a]251}
Note: See TracBrowser for help on using the repository browser.