Changeset 2f56b737 in rtems


Ignore:
Timestamp:
Feb 12, 2021, 7:35:40 PM (2 months ago)
Author:
Chris Johns <chrisj@…>
Branches:
5
Children:
3824960
Parents:
388bd805
git-author:
Chris Johns <chrisj@…> (02/12/21 19:35:40)
git-committer:
Chris Johns <chrisj@…> (02/16/21 04:24:33)
Message:

Update motorola_power to irq-generic interrupt management

  • Add support to the BSP to enable irq-generic management
  • Update the powerpc shared irq code to support irq-generic. This is an opt in option for existing powerpc bsps. This change should be simpler now
  • Fix a number of issues in ISA IRQ controller handling by porting fixes from the i386 (PC) BSP

Closes #4247
Closes #4248

Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • bsps/powerpc/include/bsp/irq_supp.h

    r388bd805 r2f56b737  
    5050 */
    5151extern int  BSP_setup_the_pic(rtems_irq_global_settings* config);
     52
     53/*
     54 * Set up for the irq-generic.h interface.
     55 */
     56int BSP_rtems_irq_generic_set(rtems_irq_global_settings* config);
    5257
    5358/* IRQ dispatcher to be defined by the PIC driver; note that it MUST
  • bsps/powerpc/motorola_powerpc/include/bsp/irq.h

    r388bd805 r2f56b737  
    2020#define BSP_POWERPC_IRQ_H
    2121
     22#ifndef BSP_SHARED_HANDLER_SUPPORT
    2223#define BSP_SHARED_HANDLER_SUPPORT      1
     24#endif
     25
    2326#include <rtems/irq.h>
    24 #include <bsp/irq-default.h>
     27
     28/*
     29 * Switch to using the generic support. Remove this when all BSPs have
     30 * been converted.
     31 */
     32#define BSP_POWERPC_IRQ_GENERIC_SUPPORT 1
    2533
    2634/*
     
    108116#define BSP_LOWEST_OFFSET               (BSP_ISA_IRQ_LOWEST_OFFSET)
    109117#define BSP_MAX_OFFSET                  (BSP_MISC_IRQ_MAX_OFFSET)
     118#define BSP_INTERRUPT_VECTOR_MIN        (BSP_LOWEST_OFFSET)
     119#define BSP_INTERRUPT_VECTOR_MAX        (BSP_MAX_OFFSET)
    110120/*
    111121 * Some ISA IRQ symbolic name definition
     
    192202int BSP_irq_enabled_at_i8259s           (const rtems_irq_number irqLine);
    193203
     204unsigned short BSP_irq_suspend_i8259s(unsigned short mask);
     205void BSP_irq_resume_i8259s(unsigned short in_progress_save);
     206
    194207extern void BSP_rtems_irq_mng_init(unsigned cpuId);
    195208extern void BSP_i8259s_init(void);
  • bsps/powerpc/motorola_powerpc/start/bspstart.c

    r388bd805 r2f56b737  
    2828#include <bsp/openpic.h>
    2929#include <bsp/irq.h>
     30#include <bsp/irq-generic.h>
    3031#include <libcpu/bat.h>
    3132#include <libcpu/pte121.h>
     
    335336  bsp_clicks_per_usec    = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
    336337
    337   /*
    338    * Initalize RTEMS IRQ system
    339    */
    340   BSP_rtems_irq_mng_init(0);
     338  /* Initialize interrupt support */
     339  bsp_interrupt_initialize();
    341340
    342341  /* Activate the page table mappings only after
  • bsps/powerpc/shared/irq/i8259.c

    r388bd805 r2f56b737  
    1313#include <bsp/irq.h>
    1414
     15#define PIC_EOSI        0x60    ///< End of Specific Interrupt (EOSI)
     16#define PIC_EOI         0x20    ///< Generic End of Interrupt (EOI)
     17
     18/* Operation control word type 3.  Bit 3 (0x08) must be set. Even address. */
     19#define PIC_OCW3_RIS        0x01            /* 1 = read IS, 0 = read IR */
     20#define PIC_OCW3_RR         0x02            /* register read */
     21#define PIC_OCW3_P          0x04            /* poll mode command */
     22/* 0x08 must be 1 to select OCW3 vs OCW2 */
     23#define PIC_OCW3_SEL        0x08            /* must be 1 */
     24/* 0x10 must be 0 to select OCW3 vs ICW1 */
     25#define PIC_OCW3_SMM        0x20            /* special mode mask */
     26#define PIC_OCW3_ESMM       0x40            /* enable SMM */
     27
    1528/*-------------------------------------------------------------------------+
    1629| Cache for 1st and 2nd PIC IRQ line's status (enabled or disabled) register.
     
    2033 * while upper bits are interrupt on the slave PIC.
    2134 */
    22 volatile rtems_i8259_masks i8259s_cache = 0xfffb;
     35static rtems_i8259_masks i8259s_imr_cache = 0xFFFB;
     36static rtems_i8259_masks i8259s_in_progress = 0;
     37
     38static inline
     39void BSP_i8259s_irq_update_master_imr( void )
     40{
     41  rtems_i8259_masks mask = i8259s_in_progress | i8259s_imr_cache;
     42  outport_byte( PIC_MASTER_IMR_IO_PORT, mask & 0xff );
     43}
     44
     45static inline
     46void BSP_i8259s_irq_update_slave_imr( void )
     47{
     48  rtems_i8259_masks mask = i8259s_in_progress | i8259s_imr_cache;
     49  outport_byte( PIC_SLAVE_IMR_IO_PORT, ( mask >> 8 ) & 0xff );
     50}
     51
     52/*
     53 * Is the IRQ valid?
     54 */
     55static inline bool BSP_i8259s_irq_valid(const rtems_irq_number irqLine)
     56{
     57  return ((int)irqLine >= BSP_ISA_IRQ_LOWEST_OFFSET) &&
     58    ((int)irqLine <= BSP_ISA_IRQ_MAX_OFFSET);
     59}
     60
     61/*
     62 * Read the IRR register. The default.
     63 */
     64static inline uint8_t BSP_i8259s_irq_int_request_reg(uint32_t ioport)
     65{
     66  uint8_t isr;
     67  inport_byte(ioport, isr);
     68  return isr;
     69}
     70
     71/*
     72 * Read the ISR register. Keep the default of the IRR.
     73 */
     74static inline uint8_t BSP_i8259s_irq_in_service_reg(uint32_t ioport)
     75{
     76  uint8_t isr;
     77  outport_byte(ioport, PIC_OCW3_SEL | PIC_OCW3_RR | PIC_OCW3_RIS);
     78  inport_byte(ioport, isr);
     79  outport_byte(ioport, PIC_OCW3_SEL | PIC_OCW3_RR);
     80  return isr;
     81}
    2382
    2483/*-------------------------------------------------------------------------+
    2584|         Function:  BSP_irq_disable_at_i8259s
    2685|      Description: Mask IRQ line in appropriate PIC chip.
    27 | Global Variables: i8259s_cache
     86| Global Variables: i8259s_imr_cache, i8259s_in_progress
    2887|        Arguments: vector_offset - number of IRQ line to mask.
    29 |          Returns: original state or -1 on error.
    30 +--------------------------------------------------------------------------*/
    31 int BSP_irq_disable_at_i8259s    (const rtems_irq_number irqLine)
     88|          Returns: 0 is OK.
     89+--------------------------------------------------------------------------*/
     90int BSP_irq_disable_at_i8259s(const rtems_irq_number irqLine)
    3291{
    3392  unsigned short        mask;
    3493  rtems_interrupt_level level;
    35   int                   rval;
    36 
    37   if ( ((int)irqLine < BSP_ISA_IRQ_LOWEST_OFFSET) ||
    38        ((int)irqLine > BSP_ISA_IRQ_MAX_OFFSET)
    39        )
     94
     95  if (!BSP_i8259s_irq_valid(irqLine))
    4096    return -1;
    4197
     
    4399
    44100  mask = 1 << irqLine;
    45   rval = i8259s_cache & mask ? 0 : 1;
    46   i8259s_cache |= mask;
     101  i8259s_imr_cache |= mask;
    47102
    48103  if (irqLine < 8)
    49104  {
    50     outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
     105    BSP_i8259s_irq_update_master_imr();
    51106  }
    52107  else
    53108  {
    54     outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
    55   }
     109    BSP_i8259s_irq_update_slave_imr();
     110  }
     111
    56112  rtems_interrupt_enable(level);
    57113
    58   return rval;
     114  return 0;
    59115}
    60116
     
    62118|         Function:  BSP_irq_enable_at_i8259s
    63119|      Description: Unmask IRQ line in appropriate PIC chip.
    64 | Global Variables: i8259s_cache
     120| Global Variables: i8259s_imr_cache, i8259s_in_progress
    65121|        Arguments: irqLine - number of IRQ line to mask.
    66122|          Returns: Nothing.
    67123+--------------------------------------------------------------------------*/
    68 int BSP_irq_enable_at_i8259s    (const rtems_irq_number irqLine)
    69 {
     124int BSP_irq_enable_at_i8259s(const rtems_irq_number irqLine)
     125{
     126  rtems_interrupt_level level;
    70127  unsigned short        mask;
    71   rtems_interrupt_level level;
    72 
    73   if ( ((int)irqLine < BSP_ISA_IRQ_LOWEST_OFFSET) ||
    74        ((int)irqLine > BSP_ISA_IRQ_MAX_OFFSET )
    75        )
     128  uint8_t               isr;
     129  uint8_t               irr;
     130
     131  if (!BSP_i8259s_irq_valid(irqLine))
    76132    return 1;
    77133
    78134  rtems_interrupt_disable(level);
    79135
    80   mask = ~(1 << irqLine);
    81   i8259s_cache &= mask;
     136  mask = 1 << irqLine;
     137  i8259s_imr_cache &= ~mask;
    82138
    83139  if (irqLine < 8)
    84140  {
    85     outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
     141    isr = BSP_i8259s_irq_in_service_reg(PIC_MASTER_COMMAND_IO_PORT);
     142    irr = BSP_i8259s_irq_int_request_reg(PIC_MASTER_COMMAND_IO_PORT);
     143    BSP_i8259s_irq_update_master_imr();
    86144  }
    87145  else
    88146  {
    89     outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
    90   }
     147    isr = BSP_i8259s_irq_in_service_reg(PIC_SLAVE_COMMAND_IO_PORT);
     148    irr = BSP_i8259s_irq_int_request_reg(PIC_SLAVE_COMMAND_IO_PORT);
     149    BSP_i8259s_irq_update_slave_imr();
     150  }
     151
    91152  rtems_interrupt_enable(level);
    92153
     
    94155} /* mask_irq */
    95156
    96 int BSP_irq_enabled_at_i8259s           (const rtems_irq_number irqLine)
     157int BSP_irq_enabled_at_i8259s(const rtems_irq_number irqLine)
    97158{
    98159  unsigned short mask;
    99160
    100   if ( ((int)irqLine < BSP_ISA_IRQ_LOWEST_OFFSET) ||
    101        ((int)irqLine > BSP_ISA_IRQ_MAX_OFFSET)
    102      )
     161  if (!BSP_i8259s_irq_valid(irqLine))
    103162    return 1;
    104163
    105164  mask = (1 << irqLine);
    106   return  (~(i8259s_cache & mask));
     165  return  (~(i8259s_imr_cache & mask));
    107166}
    108167
     
    114173|          Returns: Nothing.
    115174+--------------------------------------------------------------------------*/
    116 int BSP_irq_ack_at_i8259s       (const rtems_irq_number irqLine)
    117 {
     175int BSP_irq_ack_at_i8259s(const rtems_irq_number irqLine)
     176{
     177  uint8_t slave_isr = 0;
     178
    118179  if (irqLine >= 8) {
    119     outport_byte(PIC_MASTER_COMMAND_IO_PORT, SLAVE_PIC_EOSI);
    120     outport_byte(PIC_SLAVE_COMMAND_IO_PORT, (PIC_EOSI | (irqLine - 8)));
    121   }
    122   else {
    123     outport_byte(PIC_MASTER_COMMAND_IO_PORT, (PIC_EOSI | irqLine));
    124   }
     180   outport_byte(PIC_SLAVE_COMMAND_IO_PORT, PIC_EOI);
     181   slave_isr = BSP_i8259s_irq_in_service_reg(PIC_SLAVE_COMMAND_IO_PORT);
     182  }
     183
     184  /*
     185   * Only issue the EOI to the master if there are no more interrupts in
     186   * service for the slave. i8259a data sheet page 18, The Special Fully Nested
     187   * Mode, b.
     188   */
     189  if (slave_isr == 0)
     190    outport_byte(PIC_MASTER_COMMAND_IO_PORT, PIC_EOI);
    125191
    126192  return 0;
     
    128194} /* ackIRQ */
    129195
     196unsigned short BSP_irq_suspend_i8259s(unsigned short mask)
     197{
     198  unsigned short in_progress_save = i8259s_in_progress;
     199  i8259s_in_progress |= mask;
     200  BSP_i8259s_irq_update_master_imr();
     201  BSP_i8259s_irq_update_slave_imr();
     202  return in_progress_save;
     203}
     204
     205void BSP_irq_resume_i8259s(unsigned short in_progress_save)
     206{
     207  i8259s_in_progress = in_progress_save;
     208  BSP_i8259s_irq_update_master_imr();
     209  BSP_i8259s_irq_update_slave_imr();
     210}
     211
    130212void BSP_i8259s_init(void)
    131213{
    132214  /*
    133    * init master 8259 interrupt controller
     215   * Always mask at least current interrupt to prevent re-entrance
    134216   */
    135217  outport_byte(PIC_MASTER_COMMAND_IO_PORT, 0x11); /* Start init sequence */
  • bsps/powerpc/shared/irq/irq_init.c

    r388bd805 r2f56b737  
    281281#endif
    282282  int i;
     283  int r;
    283284
    284285  /*
     
    352353    initial_config.irqPrioTbl   = irqPrioTable;
    353354
    354     if (!BSP_rtems_irq_mngt_set(&initial_config)) {
     355#ifdef BSP_POWERPC_IRQ_GENERIC_SUPPORT
     356#ifdef TRACE_IRQ_INIT
     357    printk("RTEMS IRQ management: irq-generic\n");
     358#endif
     359    r = BSP_rtems_irq_generic_set(&initial_config);
     360#else
     361#ifdef TRACE_IRQ_INIT
     362    printk("RTEMS IRQ management: legacy\n");
     363#endif
     364    r = BSP_rtems_irq_mngt_set(&initial_config);
     365#endif
     366
     367    if (!r) {
    355368      /*
    356369       * put something here that will show the failure...
  • bsps/powerpc/shared/irq/openpic_i8259_irq.c

    r388bd805 r2f56b737  
    1616#include <bsp/irq.h>
    1717#include <bsp/irq_supp.h>
     18#include <bsp/irq-generic.h>
    1819#ifndef BSP_HAS_NO_VME
    1920#include <bsp/VMEConfig.h>
     
    235236  register unsigned isaIntr;                  /* boolean */
    236237  register unsigned oldMask = 0;              /* old isa pic masks */
    237   register unsigned newMask;                  /* new isa pic masks */
    238238#endif
    239239
    240240  if (excNum == ASM_DEC_VECTOR) {
    241 
    242         bsp_irq_dispatch_list(rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_entry.hdl);
    243 
     241#ifdef BSP_POWERPC_IRQ_GENERIC_SUPPORT
     242    bsp_interrupt_handler_dispatch(BSP_DECREMENTER);
     243#else
     244    bsp_irq_dispatch_list(rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_entry.hdl);
     245#endif
    244246    return 0;
    245 
    246247  }
    247248
     
    275276#if BSP_ISA_IRQ_NUMBER > 0
    276277#ifdef BSP_PCI_ISA_BRIDGE_IRQ
    277 #if 0 == BSP_PCI_IRQ_NUMBER 
     278#if 0 == BSP_PCI_IRQ_NUMBER
    278279#error "Configuration Error -- BSP w/o PCI IRQs MUST NOT define BSP_PCI_ISA_BRIDGE_IRQ"
    279280#endif
     
    290291     * store current PIC mask
    291292     */
    292     oldMask = i8259s_cache;
    293     newMask = oldMask | irq_mask_or_tbl [irq];
    294     i8259s_cache = newMask;
    295     outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
    296     outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
     293    oldMask = BSP_irq_suspend_i8259s(irq_mask_or_tbl [irq]);
    297294    BSP_irq_ack_at_i8259s (irq);
    298295#if BSP_PCI_IRQ_NUMBER > 0
     
    304301
    305302  /* dispatch handlers */
     303#ifdef BSP_POWERPC_IRQ_GENERIC_SUPPORT
     304  bsp_interrupt_handler_dispatch(irq);
     305#else
    306306  bsp_irq_dispatch_list(rtems_hdl_tbl, irq, default_rtems_entry.hdl);
     307#endif
    307308
    308309#if BSP_ISA_IRQ_NUMBER > 0
    309310  if (isaIntr)  {
    310     i8259s_cache = oldMask;
    311     outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
    312     outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
     311    BSP_irq_resume_i8259s(oldMask);
    313312  }
    314313  else
  • c/src/lib/libbsp/powerpc/motorola_powerpc/Makefile.am

    r388bd805 r2f56b737  
    9393librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/mmu/mmuAsm.S
    9494librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/mmu/pte121.c
    95 librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/irq/ppc-irq-legacy.c
     95librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/irq/ppc-irq-generic.c
     96librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
    9697
    97 include $(srcdir)/../../../../../../bsps/shared/irq-default-sources.am
     98include $(srcdir)/../../../../../../bsps/shared/irq-sources.am
    9899include $(srcdir)/../../../../../../bsps/shared/shared-sources.am
    99100include $(top_srcdir)/../../../../automake/subdirs.am
Note: See TracChangeset for help on using the changeset viewer.