Changeset facebbb in rtems for c/src/lib/libbsp/i386


Ignore:
Timestamp:
Oct 2, 2016, 10:19:12 AM (3 years ago)
Author:
Pavel Pisa <pisa@…>
Branches:
master
Children:
ed19002
Parents:
4745650
git-author:
Pavel Pisa <pisa@…> (10/02/16 10:19:12)
git-committer:
Pavel Pisa <pisa@…> (10/11/16 20:17:04)
Message:

bsps/i386: Separate variable for i8259 IRQs disable due to in progress state.

The global state of enabled and disabled interrupts has to hold
interrupts really disabled by drivers and system. If the state is
combined with interrupts temporarily disabled because they are
processed at given time then it is impossible to maintain state
by interrupt handlers in drivers.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/i386/shared/irq/irq.c

    r4745650 rfacebbb  
    1515#include <bsp/irq.h>
    1616#include <bsp/irq-generic.h>
     17#include <rtems/score/cpu.h>
    1718
    1819#include <stdlib.h>
     
    5253 * This cache is initialized in ldseg.s
    5354 */
    54 static rtems_i8259_masks i8259a_cache = 0xFFFB;
     55static rtems_i8259_masks i8259a_imr_cache = 0xFFFB;
     56static rtems_i8259_masks i8259a_in_progress = 0;
     57
     58static inline
     59void BSP_i8259a_irq_update_master_imr( void )
     60{
     61  rtems_i8259_masks mask = i8259a_in_progress | i8259a_imr_cache;
     62  outport_byte( PIC_MASTER_IMR_IO_PORT, mask & 0xff );
     63}
     64
     65static inline
     66void BSP_i8259a_irq_update_slave_imr( void )
     67{
     68  rtems_i8259_masks mask = i8259a_in_progress | i8259a_imr_cache;
     69  outport_byte( PIC_SLAVE_IMR_IO_PORT, ( mask >> 8 ) & 0xff );
     70}
    5571
    5672/*
     
    108124|         Function:  BSP_irq_disable_at_i8259a
    109125|      Description: Mask IRQ line in appropriate PIC chip.
    110 | Global Variables: i8259a_cache
     126| Global Variables: i8259a_imr_cache, i8259a_in_progress
    111127|        Arguments: vector_offset - number of IRQ line to mask.
    112128|          Returns: 0 is OK.
     
    120136
    121137  mask = 1 << irqLine;
    122   i8259a_cache |= mask;
     138  i8259a_imr_cache |= mask;
    123139
    124140  if (irqLine < 8)
    125141  {
    126     outport_byte(PIC_MASTER_IMR_IO_PORT, i8259a_cache & 0xff);
     142    BSP_i8259a_irq_update_master_imr();
    127143  }
    128144  else
    129145  {
    130     outport_byte(PIC_SLAVE_IMR_IO_PORT, (i8259a_cache >> 8) & 0xff);
     146    BSP_i8259a_irq_update_slave_imr();
    131147  }
    132148
     
    139155|         Function:  BSP_irq_enable_at_i8259a
    140156|      Description: Unmask IRQ line in appropriate PIC chip.
    141 | Global Variables: i8259a_cache
     157| Global Variables: i8259a_imr_cache, i8259a_in_progress
    142158|        Arguments: irqLine - number of IRQ line to mask.
    143159|          Returns: Nothing.
     
    153169
    154170  mask = 1 << irqLine;
    155   i8259a_cache &= ~mask;
     171  i8259a_imr_cache &= ~mask;
    156172
    157173  if (irqLine < 8)
     
    159175    isr = BSP_i8259a_irq_in_service_reg(PIC_MASTER_COMMAND_IO_PORT);
    160176    irr = BSP_i8259a_irq_int_request_reg(PIC_MASTER_COMMAND_IO_PORT);
    161     outport_byte(PIC_MASTER_IMR_IO_PORT, i8259a_cache & 0xff);
     177    BSP_i8259a_irq_update_master_imr();
    162178  }
    163179  else
     
    165181    isr = BSP_i8259a_irq_in_service_reg(PIC_SLAVE_COMMAND_IO_PORT);
    166182    irr = BSP_i8259a_irq_int_request_reg(PIC_SLAVE_COMMAND_IO_PORT);
    167     outport_byte(PIC_SLAVE_IMR_IO_PORT, (i8259a_cache >> 8) & 0xff);
     183    BSP_i8259a_irq_update_slave_imr();
    168184  }
    169185
     
    299315void BSP_dispatch_isr(int vector)
    300316{
    301   uint16_t old_imr = 0;
     317  rtems_i8259_masks in_progress_save = 0;
    302318
    303319  if (vector < BSP_IRQ_VECTOR_NUMBER) {
     
    330346       */
    331347      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);
     348        in_progress_save = i8259a_in_progress;
     349        i8259a_in_progress |= irq_mask_or_tbl[vector];
     350        BSP_i8259a_irq_update_master_imr();
     351        BSP_i8259a_irq_update_slave_imr();
    336352      }
    337353
     
    347363    irq_count[vector]++;
    348364
     365    RTEMS_COMPILER_MEMORY_BARRIER();
    349366    /*
    350367     * Allow nesting.
     
    359376    __asm__ __volatile__("cli");
    360377
     378    RTEMS_COMPILER_MEMORY_BARRIER();
     379
    361380    if (vector <= BSP_IRQ_MAX_ON_i8259A) {
    362381      /*
     
    366385       */
    367386      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);
     387        i8259a_in_progress = in_progress_save;
     388        BSP_i8259a_irq_update_master_imr();
     389        BSP_i8259a_irq_update_slave_imr();
    373390      }
    374391    }
Note: See TracChangeset for help on using the changeset viewer.