Changeset 93fb8797 in rtems for c/src/lib/libbsp/i386


Ignore:
Timestamp:
May 6, 2016, 7:55:29 AM (4 years ago)
Author:
Chris Johns <chrisj@…>
Branches:
master
Children:
02ef5d9
Parents:
292dbff
git-author:
Chris Johns <chrisj@…> (05/06/16 07:55:29)
git-committer:
Chris Johns <chrisj@…> (05/11/16 01:45:01)
Message:

i386/pc386: Fix interrupt support.

Fix the interrupt and stop the spurious interrupt from happening.

The fix moves the EOI to C code and cleans that functionality out
of the asm part of the ISR handler.

The code checks the ISR and IRR registers on the enable.

Only ack the master for a slave IRQ if the slave has no other pending
requests.

Location:
c/src/lib/libbsp/i386
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/i386/Makefile.am

    r292dbff r93fb8797  
    2020EXTRA_DIST += shared/irq/idt.c
    2121EXTRA_DIST += shared/irq/irq_init.c
     22EXTRA_DIST += shared/irq/elcr.c
    2223
    2324# shared/pci
  • c/src/lib/libbsp/i386/pc386/Makefile.am

    r292dbff r93fb8797  
    162162libbsp_a_SOURCES += ../../i386/shared/irq/irq.c
    163163libbsp_a_SOURCES += ../../i386/shared/irq/irq_init.c
     164libbsp_a_SOURCES += ../../i386/shared/irq/elcr.c
    164165libbsp_a_SOURCES += ../../shared/bootcard.c
    165166libbsp_a_SOURCES += ../../shared/sbrk.c
  • c/src/lib/libbsp/i386/shared/irq/irq.c

    r292dbff r93fb8797  
    2020#include <inttypes.h>
    2121
     22
     23#include "elcr.h"
     24
    2225/*
    2326 * pointer to the mask representing the additionnal irq vectors
     
    2831 *           prologue.
    2932 */
    30 rtems_i8259_masks       irq_mask_or_tbl[BSP_IRQ_LINES_NUMBER];
    31 
    32 uint32_t            irq_count[BSP_IRQ_LINES_NUMBER] = {0};
    33 
    34 uint32_t
    35 BSP_irq_count_dump(FILE *f)
    36 {
    37 uint32_t tot = 0;
    38 int      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 }
     33static rtems_i8259_masks irq_mask_or_tbl[BSP_IRQ_LINES_NUMBER];
     34
     35/*
     36 * Stats of interrupts dispatched.
     37 */
     38static uint32_t irq_count[BSP_IRQ_VECTOR_NUMBER] = {0};
     39static uint32_t spurious_count;
     40
     41/*
     42 * Edge or level trigger interrupts.
     43 */
     44static enum intr_trigger irq_trigger[BSP_IRQ_LINES_NUMBER];
    4745
    4846/*-------------------------------------------------------------------------+
    49 | Cache for 1st and 2nd PIC IRQ line's status (enabled or disabled) register.
     47| Cache for 1st and 2nd PIC IRQ line's mssk (enabled or disabled) register.
    5048+--------------------------------------------------------------------------*/
    5149/*
     
    5452 * This cache is initialized in ldseg.s
    5553 */
    56 rtems_i8259_masks i8259s_cache = 0xFFFB;
    57 rtems_i8259_masks i8259s_super_imr = 0xFFFB;
     54static rtems_i8259_masks i8259a_cache = 0xFFFB;
     55
     56/*
     57 * Print the stats.
     58 */
     59uint32_t BSP_irq_count_dump(FILE *f)
     60{
     61  uint32_t tot = 0;
     62  int      i;
     63 if ( !f )
     64   f = stdout;
     65 fprintf(f,"SPURIOUS: %9"PRIu32"\n", spurious_count);
     66 for ( i = 0; i < BSP_IRQ_VECTOR_NUMBER; i++ ) {
     67   char type = '-';
     68   if (i < BSP_IRQ_LINES_NUMBER)
     69     type = irq_trigger[i] == INTR_TRIGGER_EDGE ? 'E' : 'L';
     70   tot += irq_count[i];
     71   fprintf(f,"IRQ %2u: %c %9"PRIu32"\n", i, type, irq_count[i]);
     72 }
     73 return tot;
     74}
     75
     76/*
     77 * Is the IRQ valid?
     78 */
     79static inline bool BSP_i8259a_irq_valid(const rtems_irq_number irqLine)
     80{
     81  return ((int)irqLine >= BSP_IRQ_VECTOR_LOWEST_OFFSET) &&
     82    ((int)irqLine <= BSP_IRQ_MAX_ON_i8259A);
     83}
     84
     85/*
     86 * Read the IRR register. The default.
     87 */
     88static inline uint8_t BSP_i8259a_irq_int_request_reg(uint32_t ioport)
     89{
     90  uint8_t isr;
     91  inport_byte(ioport, isr);
     92  return isr;
     93}
     94
     95/*
     96 * Read the ISR register. Keep the default of the IRR.
     97 */
     98static inline uint8_t BSP_i8259a_irq_in_service_reg(uint32_t ioport)
     99{
     100  uint8_t isr;
     101  outport_byte(ioport, PIC_OCW3_SEL | PIC_OCW3_RR | PIC_OCW3_RIS);
     102  inport_byte(ioport, isr);
     103  outport_byte(ioport, PIC_OCW3_SEL | PIC_OCW3_RR);
     104  return isr;
     105}
    58106
    59107/*-------------------------------------------------------------------------+
    60 |         Function:  BSP_irq_disable_at_i8259s
     108|         Function:  BSP_irq_disable_at_i8259a
    61109|      Description: Mask IRQ line in appropriate PIC chip.
    62 | Global Variables: i8259s_cache
     110| Global Variables: i8259a_cache
    63111|        Arguments: vector_offset - number of IRQ line to mask.
    64 |          Returns: Nothing.
     112|          Returns: 0 is OK.
    65113+--------------------------------------------------------------------------*/
    66 int BSP_irq_disable_at_i8259s    (const rtems_irq_number irqLine)
     114static int BSP_irq_disable_at_i8259a(const rtems_irq_number irqLine)
    67115{
    68116  unsigned short        mask;
    69117  rtems_interrupt_level level;
    70118
    71   if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
    72        ((int)irqLine > BSP_MAX_ON_i8259S )
    73        )
    74     return 1;
    75 
    76119  rtems_interrupt_disable(level);
    77120
    78121  mask = 1 << irqLine;
    79   i8259s_cache |= mask;
    80   i8259s_super_imr |= mask;
     122  i8259a_cache |= mask;
    81123
    82124  if (irqLine < 8)
    83125  {
    84     outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
     126    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259a_cache & 0xff);
    85127  }
    86128  else
    87129  {
    88     outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
    89   }
     130    outport_byte(PIC_SLAVE_IMR_IO_PORT, (i8259a_cache >> 8) & 0xff);
     131  }
     132
    90133  rtems_interrupt_enable(level);
    91134
     
    94137
    95138/*-------------------------------------------------------------------------+
    96 |         Function:  BSP_irq_enable_at_i8259s
     139|         Function:  BSP_irq_enable_at_i8259a
    97140|      Description: Unmask IRQ line in appropriate PIC chip.
    98 | Global Variables: i8259s_cache
     141| Global Variables: i8259a_cache
    99142|        Arguments: irqLine - number of IRQ line to mask.
    100143|          Returns: Nothing.
    101144+--------------------------------------------------------------------------*/
    102 int BSP_irq_enable_at_i8259s    (const rtems_irq_number irqLine)
     145static int BSP_irq_enable_at_i8259a(const rtems_irq_number irqLine)
    103146{
    104147  unsigned short        mask;
    105148  rtems_interrupt_level level;
    106 
    107   if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
    108        ((int)irqLine > BSP_MAX_ON_i8259S )
    109        )
    110     return 1;
     149  uint8_t               isr;
     150  uint8_t               irr;
    111151
    112152  rtems_interrupt_disable(level);
    113153
    114   mask = ~(1 << irqLine);
    115   i8259s_cache &= mask;
    116   i8259s_super_imr &= mask;
     154  mask = 1 << irqLine;
     155  i8259a_cache &= ~mask;
    117156
    118157  if (irqLine < 8)
    119158  {
    120     outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
     159    isr = BSP_i8259a_irq_in_service_reg(PIC_MASTER_COMMAND_IO_PORT);
     160    irr = BSP_i8259a_irq_int_request_reg(PIC_MASTER_COMMAND_IO_PORT);
     161    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259a_cache & 0xff);
    121162  }
    122163  else
    123164  {
    124     outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
    125   }
     165    isr = BSP_i8259a_irq_in_service_reg(PIC_SLAVE_COMMAND_IO_PORT);
     166    irr = BSP_i8259a_irq_int_request_reg(PIC_SLAVE_COMMAND_IO_PORT);
     167    outport_byte(PIC_SLAVE_IMR_IO_PORT, (i8259a_cache >> 8) & 0xff);
     168  }
     169
     170  if (((isr ^ irr) & mask) != 0)
     171    printk("i386: isr=%x irr=%x\n", isr, irr);
     172
    126173  rtems_interrupt_enable(level);
    127174
     
    129176} /* mask_irq */
    130177
    131 int BSP_irq_enabled_at_i8259s           (const rtems_irq_number irqLine)
    132 {
    133   unsigned short mask;
    134 
    135   if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
    136        ((int)irqLine > BSP_MAX_ON_i8259S )
    137      )
    138     return 1;
    139 
    140   mask = (1 << irqLine);
    141   return  (~(i8259s_cache & mask));
    142 }
    143 
    144178/*-------------------------------------------------------------------------+
    145 |         Function: BSP_irq_ack_at_i8259s
     179|         Function: BSP_irq_ack_at_i8259a
    146180|      Description: Signal generic End Of Interrupt (EOI) to appropriate PIC.
    147181| Global Variables: None.
     
    149183|          Returns: Nothing.
    150184+--------------------------------------------------------------------------*/
    151 int BSP_irq_ack_at_i8259s       (const rtems_irq_number irqLine)
    152 {
    153   if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
    154        ((int)irqLine > BSP_MAX_ON_i8259S )
    155        )
    156     return 1;
     185static int BSP_irq_ack_at_i8259a(const rtems_irq_number irqLine)
     186{
     187  uint8_t slave_isr = 0;
    157188
    158189  if (irqLine >= 8) {
    159190   outport_byte(PIC_SLAVE_COMMAND_IO_PORT, PIC_EOI);
    160   }
    161   outport_byte(PIC_MASTER_COMMAND_IO_PORT, PIC_EOI);
     191   slave_isr = BSP_i8259a_irq_in_service_reg(PIC_SLAVE_COMMAND_IO_PORT);
     192  }
     193
     194  /*
     195   * Only issue the EOI to the master if there are no more interrupts in
     196   * service for the slave. i8259a data sheet page 18, The Special Fully Nested
     197   * Mode, b.
     198   */
     199  if (slave_isr == 0)
     200    outport_byte(PIC_MASTER_COMMAND_IO_PORT, PIC_EOI);
    162201
    163202  return 0;
     
    180219  0,0,
    181220  255,
    182   0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0
     221  0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0
    183222};
    184223
     
    209248}
    210249
     250static inline bool bsp_interrupt_vector_is_valid(rtems_vector_number vector)
     251{
     252  return BSP_i8259a_irq_valid((const rtems_irq_number) vector);
     253}
     254
    211255rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
    212256{
    213   BSP_irq_enable_at_i8259s(vector);
    214 
     257  if (bsp_interrupt_vector_is_valid(vector))
     258    BSP_irq_enable_at_i8259a(vector);
    215259  return RTEMS_SUCCESSFUL;
    216260}
     
    218262rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
    219263{
    220   BSP_irq_disable_at_i8259s(vector);
    221 
     264  if (bsp_interrupt_vector_is_valid(vector))
     265    BSP_irq_disable_at_i8259a(vector);
    222266  return RTEMS_SUCCESSFUL;
    223267}
     
    225269rtems_status_code bsp_interrupt_facility_initialize(void)
    226270{
     271  int i;
     272
    227273  /*
    228274   * set up internal tables used by rtems interrupt prologue
     
    233279   * must enable slave pic anyway
    234280   */
    235   BSP_irq_enable_at_i8259s(2);
     281  BSP_irq_enable_at_i8259a(2);
     282
     283  /*
     284   * Probe the ELCR.
     285   */
     286  elcr_probe();
     287
     288  for (i = 0; i < BSP_IRQ_LINES_NUMBER; i++)
     289    irq_trigger[i] = elcr_read_trigger(i);
    236290
    237291  return RTEMS_SUCCESSFUL;
    238292}
    239293
    240 void C_dispatch_isr(int vector)
    241 {
    242   irq_count[vector]++;
    243   bsp_interrupt_handler_dispatch(vector);
    244 }
     294/*
     295 * Global so the asm handler can call it.
     296 */
     297void BSP_dispatch_isr(int vector);
     298
     299void BSP_dispatch_isr(int vector)
     300{
     301  uint16_t old_imr = 0;
     302
     303  if (vector < BSP_IRQ_VECTOR_NUMBER) {
     304    /*
     305     * Hardware?
     306     */
     307    if (vector <= BSP_IRQ_MAX_ON_i8259A) {
     308      /*
     309       * See if this is a spurious interrupt.
     310       */
     311      if ((vector == 7 || vector == 15)) {
     312        /*
     313         * Only check it there no handler for 7 or 15.
     314         */
     315        if (bsp_interrupt_handler_is_empty(vector)) {
     316          /*
     317           * Read the ISR register to see if IRQ 7/15 is really pending.
     318           */
     319          uint8_t isr = BSP_i8259a_irq_in_service_reg(PIC_MASTER_COMMAND_IO_PORT);
     320          if ((isr & (1 << 7)) == 0) {
     321            ++spurious_count;
     322            return;
     323          }
     324        }
     325      }
     326
     327      /*
     328       * Save the current cached value for the IMR. It will have the bit for this
     329       * vector clear.
     330       */
     331      if (vector <= BSP_IRQ_MAX_ON_i8259A) {
     332        old_imr = i8259a_cache;
     333        i8259a_cache |= irq_mask_or_tbl[vector];
     334        outport_byte(PIC_MASTER_IMR_IO_PORT, i8259a_cache & 0xff);
     335        outport_byte(PIC_SLAVE_IMR_IO_PORT, (i8259a_cache >> 8) & 0xff);
     336      }
     337
     338      /*
     339       * Do not use auto-EOI as some slave PIC do not work correctly.
     340       */
     341      BSP_irq_ack_at_i8259a(vector);
     342    }
     343
     344    /*
     345     * Count the interrupt.
     346     */
     347    irq_count[vector]++;
     348
     349    /*
     350     * Allow nesting.
     351     */
     352    __asm__ __volatile__("sti");
     353
     354    bsp_interrupt_handler_dispatch(vector);
     355
     356    /*
     357     * Disallow nesting.
     358     */
     359    __asm__ __volatile__("cli");
     360
     361    if (vector <= BSP_IRQ_MAX_ON_i8259A) {
     362      /*
     363       * Put the mask back but keep this vector masked if the trigger type is
     364       * level. The driver or a thread level interrupt server needs to enable it
     365       * again.
     366       */
     367      if (vector <= BSP_IRQ_MAX_ON_i8259A) {
     368        if (irq_trigger[vector] == INTR_TRIGGER_LEVEL)
     369          old_imr |= 1 << vector;
     370        i8259a_cache = old_imr;
     371        outport_byte(PIC_MASTER_IMR_IO_PORT, i8259a_cache & 0xff);
     372        outport_byte(PIC_SLAVE_IMR_IO_PORT, (i8259a_cache >> 8) & 0xff);
     373      }
     374    }
     375  }
     376}
  • c/src/lib/libbsp/i386/shared/irq/irq.h

    r292dbff r93fb8797  
    5151+--------------------------------------------------------------------------*/
    5252
    53     /** @brief Base vector for our IRQ handlers. */
     53/** @brief Base vector for our IRQ handlers. */
    5454#define BSP_IRQ_VECTOR_BASE             BSP_ASM_IRQ_VECTOR_BASE
    55 #define BSP_IRQ_LINES_NUMBER            17
    56 #define BSP_LOWEST_OFFSET               0
    57 #define BSP_MAX_ON_i8259S               (BSP_IRQ_LINES_NUMBER - 2)
    58 #define BSP_MAX_OFFSET                  (BSP_IRQ_LINES_NUMBER - 1)
    59     /** @brief
    60      * Interrupt offset in comparison to BSP_ASM_IRQ_VECTOR_BASE
    61      * NB : 1) Interrupt vector number in IDT = offset + BSP_ASM_IRQ_VECTOR_BASE
    62      *      2) The same name should be defined on all architecture
    63      *         so that handler connection can be unchanged.
    64      */
    65 #define BSP_PERIODIC_TIMER      0
    66 #define BSP_KEYBOARD            1
    67 #define BSP_UART_COM2_IRQ       3
    68 #define BSP_UART_COM1_IRQ       4
     55#define BSP_IRQ_LINES_NUMBER            16
     56#define BSP_IRQ_MAX_ON_i8259A           (BSP_IRQ_LINES_NUMBER - 1)
     57
     58/*
     59 * Define the number of valid vectors. This is different to the number of IRQ
     60 * signals supported. Use this value to allocation vector data or range check.
     61 */
     62#define BSP_IRQ_VECTOR_NUMBER        17
     63#define BSP_IRQ_VECTOR_LOWEST_OFFSET 0
     64#define BSP_IRQ_VECTOR_MAX_OFFSET    (BSP_IRQ_VECTOR_NUMBER - 1)
     65
     66/** @brief
     67 * Interrupt offset in comparison to BSP_ASM_IRQ_VECTOR_BASE
     68 * NB : 1) Interrupt vector number in IDT = offset + BSP_ASM_IRQ_VECTOR_BASE
     69 *          2) The same name should be defined on all architecture
     70 *             so that handler connection can be unchanged.
     71 */
     72#define BSP_PERIODIC_TIMER      0 /* fixed on all builds of PC */
     73#define BSP_KEYBOARD            1 /* fixed on all builds of PC */
     74#define BSP_UART_COM2_IRQ       3 /* fixed for ISA bus */
     75#define BSP_UART_COM1_IRQ       4 /* fixed for ISA bus */
    6976#define BSP_UART_COM3_IRQ       5
    7077#define BSP_UART_COM4_IRQ       6
    7178#define BSP_RT_TIMER1           8
    7279#define BSP_RT_TIMER3           10
    73 #define BSP_SMP_IPI             16
     80#define BSP_SMP_IPI             16 /* not part of the ATPIC */
    7481
    75 #define BSP_INTERRUPT_VECTOR_MIN BSP_LOWEST_OFFSET
    76 #define BSP_INTERRUPT_VECTOR_MAX BSP_MAX_OFFSET
     82#define BSP_INTERRUPT_VECTOR_MIN BSP_IRQ_VECTOR_LOWEST_OFFSET
     83#define BSP_INTERRUPT_VECTOR_MAX BSP_IRQ_VECTOR_MAX_OFFSET
    7784
    7885/** @brief
     
    8491 * @brief Contains the current IMR of both i8259s.
    8592 */
    86 extern rtems_i8259_masks i8259s_cache;
     93//extern rtems_i8259_masks i8259s_cache;
    8794
    8895/**
     
    93100 * is required for the interrupt server support used by the new network stack.
    94101 */
    95 extern rtems_i8259_masks i8259s_super_imr;
     102//extern rtems_i8259_masks i8259s_super_imr;
    96103
    97104/*-------------------------------------------------------------------------+
     
    107114 * not be propagated further to the processor
    108115 */
    109 int BSP_irq_disable_at_i8259s        (const rtems_irq_number irqLine);
     116//int BSP_irq_disable_at_i8259s        (const rtems_irq_number irqLine);
    110117/** @brief
    111118 * function to enable a particular irq at 8259 level. After calling
     
    113120 * be propagated further to the processor
    114121 */
    115 int BSP_irq_enable_at_i8259s            (const rtems_irq_number irqLine);
     122//int BSP_irq_enable_at_i8259s          (const rtems_irq_number irqLine);
    116123/** @brief
    117124 * function to acknoledge a particular irq at 8259 level. After calling
     
    121128 * handlers.
    122129 */
    123 int BSP_irq_ack_at_i8259s               (const rtems_irq_number irqLine);
     130//int BSP_irq_ack_at_i8259s             (const rtems_irq_number irqLine);
    124131/** @brief
    125132 * function to check if a particular irq is enabled at 8259 level. After calling
    126133 */
    127 int BSP_irq_enabled_at_i8259s           (const rtems_irq_number irqLine);
     134//int BSP_irq_enabled_at_i8259s         (const rtems_irq_number irqLine);
    128135
    129136/** @} */
  • c/src/lib/libbsp/i386/shared/irq/irq_asm.S

    r292dbff r93fb8797  
    1717#include <rtems/system.h>
    1818#include <bspopts.h>
    19 #include <bsp/irq_asm.h>
    2019#include <rtems/score/cpu.h>
    2120#include <rtems/score/percpu.h>
     
    2928/* Stack frame we use for intermediate storage               */
    3029#define ARG_OFF 0
    31 #define MSK_OFF 4
     30#define MSK_OFF 4        /* not used any more                */
    3231#define EBX_OFF 8        /* ebx                              */
    3332#define EBP_OFF 12       /* code restoring ebp/esp relies on */
     
    7877         *   saved ebp
    7978         *   saved irq mask
    80          *   vector arg to C_dispatch_isr   <- aligned SP
     79         *   vector arg to BSP_dispatch_isr   <- aligned SP
    8180         */
    8281        movl      esp, eax
     
    8685        movl      eax, ESP_OFF(esp)
    8786        movl      ebp, EBP_OFF(esp)
     87
     88        /*
     89         * GCC versions starting with 4.3 no longer place the cld
     90         * instruction before string operations.  We  need to ensure
     91         * it is set correctly for ISR handlers.
     92         */
     93        cld
    8894
    8995#ifdef __SSE__
     
    106112#endif
    107113
    108         /* Do not disable any 8259 interrupts if this isn't from one */
    109         cmp       ecx, 16               /* is this a PIC IRQ? */
    110         jge       .check_stack_switch
    111 
    112         /*
    113          * acknowledge the interrupt
    114          */
    115         movw      SYM (i8259s_cache), ax /* save current i8259 interrupt mask */
    116         movl      eax, MSK_OFF(esp)      /* save in stack frame */
    117 
    118         /*
    119          * compute the new PIC mask:
    120          *
    121          * <new mask> = <old mask> | irq_mask_or_tbl[<intr number aka ecx>]
    122          */
    123         movw      SYM (irq_mask_or_tbl) (,ecx,2), dx
    124         orw       dx, ax
    125         /*
    126          * Install new computed value on the i8259 and update cache
    127          * accordingly
    128          */
    129         movw      ax, SYM (i8259s_cache)
    130         outb      $PIC_MASTER_IMR_IO_PORT
    131         movb      ah, al
    132         outb      $PIC_SLAVE_IMR_IO_PORT
    133 
    134         movb      $PIC_EOI, al
    135         cmpl      $7, ecx
    136         jbe      .master
    137         outb      $PIC_SLAVE_COMMAND_IO_PORT
    138 .master:
    139         outb      $PIC_MASTER_COMMAND_IO_PORT
    140 
    141114        /*
    142115         *  Now switch stacks if necessary
     
    173146                                                                multitasking */
    174147        /*
    175          * GCC versions starting with 4.3 no longer place the cld
    176          * instruction before string operations.  We  need to ensure
    177          * it is set correctly for ISR handlers.
    178          */
    179         cld
    180 
    181         /*
    182          * re-enable interrupts at processor level as the current
    183          * interrupt source is now masked via i8259
    184          */
    185         sti
    186 
    187         /*
    188148         *  ECX is preloaded with the vector number; store as arg
    189149         *  on top of stack. Note that _CPU_Interrupt_stack_high
     
    193153
    194154        movl      ecx, ARG_OFF(esp)  /* store vector arg in stack */
    195         call      C_dispatch_isr
    196 
    197         /*
    198          * disable interrupts_again
    199          */
    200         cli
     155        call      BSP_dispatch_isr
    201156
    202157        movl      ARG_OFF(esp), ecx     /* grab vector arg from stack */
     
    208163        movl      ebp, esp
    209164
    210         /*
    211          * restore the original i8259 masks
    212          */
    213         /* Do not touch 8259 interrupts if this isn't from one */
    214         cmp       ecx, 16               /* is this a PIC IRQ? */
    215         jge       .dont_restore_i8259
    216 
    217         movw      SYM (i8259s_super_imr), dx
    218         movl      MSK_OFF(esp), eax
    219         orw       dx, ax
    220         movw      ax, SYM (i8259s_cache)
    221         outb      $PIC_MASTER_IMR_IO_PORT
    222         movb      ah, al
    223         outb      $PIC_SLAVE_IMR_IO_PORT
    224 
    225 .dont_restore_i8259:
    226165        decl      PER_CPU_ISR_NEST_LEVEL(ebx)  /* one less ISR nest level */
    227166                                            /* If interrupts are nested, */
  • c/src/lib/libbsp/i386/shared/irq/irq_asm.h

    r292dbff r93fb8797  
    1313 *  COPYRIGHT (c) 1998 valette@crf.canon.fr
    1414 *
     15 *  Copyright (c) 2016 Chris Johns <chrisj@rtems.org>
     16 *
    1517 *  The license and distribution terms for this file may be
    1618 *  found in the file LICENSE in this distribution or at
    1719 *  http://www.rtems.org/license/LICENSE.
    1820 */
    19 #ifndef __IRQ_ASM_H__
    20 #define __IRQ_ASM_H__
     21#ifndef __I8259S_H__
     22#define __I8259S_H__
    2123
    2224#define BSP_ASM_IRQ_VECTOR_BASE 0x20
     
    3133#define PIC_EOI         0x20    ///< Generic End of Interrupt (EOI)
    3234
     35/* Operation control word type 3.  Bit 3 (0x08) must be set. Even address. */
     36#define PIC_OCW3_RIS        0x01            /* 1 = read IS, 0 = read IR */
     37#define PIC_OCW3_RR         0x02            /* register read */
     38#define PIC_OCW3_P          0x04            /* poll mode command */
     39/* 0x08 must be 1 to select OCW3 vs OCW2 */
     40#define PIC_OCW3_SEL        0x08            /* must be 1 */
     41/* 0x10 must be 0 to select OCW3 vs ICW1 */
     42#define PIC_OCW3_SMM        0x20            /* special mode mask */
     43#define PIC_OCW3_ESMM       0x40            /* enable SMM */
     44
    3345#endif
  • c/src/lib/libbsp/i386/shared/irq/irq_init.c

    r292dbff r93fb8797  
    6767static rtems_raw_irq_connect_data       idtHdl[IDT_SIZE];
    6868
    69 static rtems_raw_irq_hdl rtemsIrq[BSP_IRQ_LINES_NUMBER] = {
     69static rtems_raw_irq_hdl rtemsIrq[BSP_IRQ_VECTOR_NUMBER] = {
    7070  rtems_irq_prologue_0,
    7171  rtems_irq_prologue_1,
     
    150150     * with RTEMS prologue.
    151151     */
    152     for (i = 0; i < BSP_IRQ_LINES_NUMBER; i++) {
     152    for (i = 0; i < BSP_IRQ_VECTOR_NUMBER; i++) {
    153153      create_interrupt_gate_descriptor(&idtEntry, rtemsIrq[i]);
    154154      idt_entry_tbl[i + BSP_ASM_IRQ_VECTOR_BASE] = idtEntry;
Note: See TracChangeset for help on using the changeset viewer.