Ignore:
Timestamp:
Nov 4, 2005, 1:39:45 AM (14 years ago)
Author:
Till Straumann <strauman@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
dc0f6585
Parents:
be45f8e
Message:

2005-11-03 <strauman@…>

  • shared/irq/openpic_i8259_irq.c: New file.
  • ChangeLog?, Makefile.am, motorola_powerpc/ChangeLog, motorola_powerpc/Makefile.am, shared/irq/irq.c, shared/irq/irq.h, shared/irq/irq_asm.S, shared/irq/irq_init.c: Separated openpic/i8259 specifica from generic irq handling into openpic_i8259_irq.c; added some compilation conditionals to help BSPs without ISA to omit ISA interrupts and calling i8259 code.
Location:
c/src/lib/libbsp/powerpc/shared/irq
Files:
1 added
4 edited

Legend:

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

    rbe45f8e r8c9fffd  
    11/*
    22 *
    3  *  This file contains the implementation of the function described in irq.h
     3 *  This file contains the PIC-independent implementation of the functions described in irq.h
    44 *
    55 *  Copyright (C) 1998, 1999 valette@crf.canon.fr
     
    1616#include <bsp.h>
    1717#include <bsp/irq.h>
    18 #include <bsp/VME.h>
    19 #include <bsp/openpic.h>
    2018#include <rtems/score/apiext.h>  /* for post ISR signal processing */
    2119#include <libcpu/raw_exception.h>
    22 #include <libcpu/io.h>
    2320#include <bsp/vectors.h>
    2421#include <stdlib.h>
    2522
    2623#include <rtems/bspIo.h> /* for printk */
    27 #define RAVEN_INTR_ACK_REG 0xfeff0030
    28 
    29 /*
    30  * pointer to the mask representing the additionnal irq vectors
    31  * that must be disabled when a particular entry is activated.
    32  * They will be dynamically computed from the priority table given
    33  * in BSP_rtems_irq_mngt_set();
    34  * CAUTION : this table is accessed directly by interrupt routine
    35  *           prologue.
    36  */
    37 rtems_i8259_masks       irq_mask_or_tbl[BSP_IRQ_NUMBER];
     24
     25extern unsigned int external_exception_vector_prolog_code_size[];
     26extern void external_exception_vector_prolog_code();
     27extern unsigned int decrementer_exception_vector_prolog_code_size[];
     28extern void decrementer_exception_vector_prolog_code();
     29
    3830/*
    3931 * default handler connected on each irq after bsp initialization
     
    4739static rtems_irq_global_settings*       internal_config;
    4840static rtems_irq_connect_data*          rtems_hdl_tbl;
    49 
    50 /*
    51  * Check if IRQ is an ISA IRQ
    52  */
    53 static inline int is_isa_irq(const rtems_irq_number irqLine)
    54 {
    55   return (((int) irqLine <= BSP_ISA_IRQ_MAX_OFFSET) &
    56           ((int) irqLine >= BSP_ISA_IRQ_LOWEST_OFFSET)
    57          );
    58 }
    59 
    60 /*
    61  * Check if IRQ is an OPENPIC IRQ
    62  */
    63 static inline int is_pci_irq(const rtems_irq_number irqLine)
    64 {
    65   return (((int) irqLine <= BSP_PCI_IRQ_MAX_OFFSET) &
    66           ((int) irqLine >= BSP_PCI_IRQ_LOWEST_OFFSET)
    67          );
    68 }
    6941
    7042/*
     
    7951
    8052/*
     53 * default on/off function
     54 */
     55static void nop_func(){}
     56/*
     57 * default isOn function
     58static int not_connected() {return 0;}
     59 */
     60/*
     61 * default possible isOn function
     62 */
     63static int connected() {return 1;}
     64
     65
     66/*
    8167 * ------------------------ RTEMS Irq helper functions ----------------
    8268 */
    83 
    84 /*
    85  * Caution : this function assumes the variable "internal_config"
    86  * is already set and that the tables it contains are still valid
    87  * and accessible.
    88  */
    89 static void compute_i8259_masks_from_prio ()
    90 {
    91   int i;
    92   int j;
    93   /*
    94    * Always mask at least current interrupt to prevent re-entrance
    95    */
    96   for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) {
    97     * ((unsigned short*) &irq_mask_or_tbl[i]) = (1 << i);
    98     for (j = BSP_ISA_IRQ_LOWEST_OFFSET; j < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; j++) {
    99       /*
    100        * Mask interrupts at i8259 level that have a lower priority
    101        */
    102       if (internal_config->irqPrioTbl [i] > internal_config->irqPrioTbl [j]) {
    103         * ((unsigned short*) &irq_mask_or_tbl[i]) |= (1 << j);
    104       }
    105     }
    106   }
    107 }
    10869
    10970/*
     
    152113    /* link chain to new topmost handler */
    153114    rtems_hdl_tbl[irq->name].next_handler = (void *)vchain;
    154 
    155     if (is_isa_irq(irq->name)) {
    156       /*
    157        * Enable interrupt at PIC level
    158        */
    159       BSP_irq_enable_at_i8259s (irq->name);
    160     }
    161 
    162     if (is_pci_irq(irq->name)) {
    163       /*
    164        * Enable interrupt at OPENPIC level
    165        */
    166       openpic_enable_irq ((int) irq->name - BSP_PCI_IRQ_LOWEST_OFFSET);
    167     }
    168115
    169116    if (is_processor_irq(irq->name)) {
     
    171118       * Enable exception at processor level
    172119       */
    173     }
     120    } else {
     121                BSP_enable_irq_at_pic(irq->name);
     122        }
    174123    /*
    175124     * Enable interrupt on device
     
    214163    rtems_hdl_tbl[irq->name].next_handler = (void *)-1;
    215164
    216     if (is_isa_irq(irq->name)) {
    217       /*
    218        * Enable interrupt at PIC level
    219        */
    220       BSP_irq_enable_at_i8259s (irq->name);
    221     }
    222 
    223     if (is_pci_irq(irq->name)) {
    224       /*
    225        * Enable interrupt at OPENPIC level
    226        */
    227       openpic_enable_irq ((int) irq->name - BSP_PCI_IRQ_LOWEST_OFFSET);
    228     }
    229 
    230165    if (is_processor_irq(irq->name)) {
    231166      /*
    232167       * Enable exception at processor level
    233168       */
    234     }
     169    } else {
     170          BSP_enable_irq_at_pic(irq->name);
     171        }
    235172    /*
    236173     * Enable interrupt on device
     
    306243    }
    307244
    308     if (is_isa_irq(irq->name)) {
    309       /*
    310        * disable interrupt at PIC level
    311        */
    312       BSP_irq_disable_at_i8259s (irq->name);
    313     }
    314     if (is_pci_irq(irq->name)) {
    315       /*
    316        * disable interrupt at OPENPIC level
    317        */
    318       openpic_disable_irq ((int) irq->name - BSP_PCI_IRQ_LOWEST_OFFSET);
    319     }
    320245    if (is_processor_irq(irq->name)) {
    321246      /*
    322247       * disable exception at processor level
    323248       */
    324     }
     249    } else {
     250          BSP_disable_irq_at_pic(irq->name);
     251        }
    325252
    326253    /*
     
    367294    int i;
    368295    unsigned int level;
    369    /*
    370     * Store various code accelerators
    371     */
     296        rtems_irq_connect_data* vchain;
     297        rtems_raw_except_connect_data vectorDesc;
     298
     299        /*
     300         * Store various code accelerators
     301         */
    372302    internal_config             = config;
    373303    default_rtems_entry         = config->defaultEntry;
    374     rtems_hdl_tbl               = config->irqHdlTbl;
     304    rtems_hdl_tbl                   = config->irqHdlTbl;
    375305
    376306    _CPU_ISR_Disable(level);
    377     /*
    378      * set up internal tables used by rtems interrupt prologue
    379      */
    380     /*
    381      * start with ISA IRQ
    382      */
    383     compute_i8259_masks_from_prio ();
    384 
    385     for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) {
    386       if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
    387          BSP_irq_enable_at_i8259s (i);
    388 
    389          /* rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); */
    390          {
    391             rtems_irq_connect_data* vchain;
    392             for( vchain = &rtems_hdl_tbl[i];
    393                  ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
    394                  vchain = (rtems_irq_connect_data*)vchain->next_handler )
    395             {
    396                vchain->on(vchain);
    397             }
    398          }
    399       }
    400       else {
    401          /* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
    402          {
    403             rtems_irq_connect_data* vchain;
    404             for( vchain = &rtems_hdl_tbl[i];
    405                  ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
    406                  vchain = (rtems_irq_connect_data*)vchain->next_handler )
    407             {
    408                vchain->off(vchain);
    409             }
    410          }
    411          BSP_irq_disable_at_i8259s (i);
    412       }
    413     }
    414     /*
    415      * must enable slave pic anyway
    416      */
    417     BSP_irq_enable_at_i8259s (2);
    418     /*
    419      * continue with PCI IRQ
    420      */
    421     for (i=BSP_PCI_IRQ_LOWEST_OFFSET; i < BSP_PCI_IRQ_LOWEST_OFFSET + BSP_PCI_IRQ_NUMBER ; i++) {
    422       /*
    423        * Note that openpic_set_priority() sets the TASK priority of the PIC
    424        */
    425       openpic_set_source_priority(i - BSP_PCI_IRQ_LOWEST_OFFSET,
    426                                   internal_config->irqPrioTbl[i]);
    427       if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
    428          openpic_enable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
    429          /* rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); */
    430          {
    431             rtems_irq_connect_data* vchain;
    432             for( vchain = &rtems_hdl_tbl[i];
    433                  ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
    434                  vchain = (rtems_irq_connect_data*)vchain->next_handler )
    435             {
    436                vchain->on(vchain);
    437             }
    438          }
    439 
    440       }
    441       else {
    442          /* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
    443          {
    444             rtems_irq_connect_data* vchain;
    445             for( vchain = &rtems_hdl_tbl[i];
    446                  ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
    447                  vchain = (rtems_irq_connect_data*)vchain->next_handler )
    448             {
    449                vchain->off(vchain);
    450             }
    451          }
    452 
    453          openpic_disable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
    454       }
    455     }
    456     /*
    457      * Must enable PCI/ISA bridge IRQ
    458      */
    459     openpic_enable_irq (0);
    460     /*
    461      * finish with Processor exceptions handled like IRQ
    462      */
    463     for (i=BSP_PROCESSOR_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER; i++) {
    464       if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
    465          /* rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); */
    466          {
    467             rtems_irq_connect_data* vchain;
    468             for( vchain = &rtems_hdl_tbl[i];
    469                  ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
    470                  vchain = (rtems_irq_connect_data*)vchain->next_handler )
    471             {
    472                vchain->on(vchain);
    473             }
    474          }
    475 
    476       }
    477       else {
    478          /* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
    479          {
    480             rtems_irq_connect_data* vchain;
    481             for( vchain = &rtems_hdl_tbl[i];
    482                  ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
    483                  vchain = (rtems_irq_connect_data*)vchain->next_handler )
    484             {
    485                vchain->off(vchain);
    486             }
    487          }
    488 
    489       }
    490     }
     307
     308        if ( !BSP_setup_the_pic(config) ) {
     309                printk("PIC setup failed; leaving IRQs OFF\n");
     310                return 0;
     311        }
     312
     313        for ( i = BSP_LOWEST_OFFSET; i <= BSP_MAX_OFFSET; i++ ) {
     314                for( vchain = &rtems_hdl_tbl[i];
     315                     ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
     316                     vchain = (rtems_irq_connect_data*)vchain->next_handler )
     317                {
     318              vchain->on(vchain);
     319                }
     320        }
     321
    491322    _CPU_ISR_Enable(level);
     323
     324        /*
     325         * We must connect the raw irq handler for the two
     326         * expected interrupt sources : decrementer and external interrupts.
     327         */
     328    vectorDesc.exceptIndex      =       ASM_DEC_VECTOR;
     329    vectorDesc.hdl.vector       =       ASM_DEC_VECTOR;
     330    vectorDesc.hdl.raw_hdl      =       decrementer_exception_vector_prolog_code;
     331    vectorDesc.hdl.raw_hdl_size =       (unsigned) decrementer_exception_vector_prolog_code_size;
     332    vectorDesc.on               =       nop_func;
     333    vectorDesc.off              =       nop_func;
     334    vectorDesc.isOn             =       connected;
     335    if (!mpc60x_set_exception (&vectorDesc)) {
     336      BSP_panic("Unable to initialize RTEMS decrementer raw exception\n");
     337    }
     338    vectorDesc.exceptIndex      =       ASM_EXT_VECTOR;
     339    vectorDesc.hdl.vector       =       ASM_EXT_VECTOR;
     340    vectorDesc.hdl.raw_hdl      =       external_exception_vector_prolog_code;
     341    vectorDesc.hdl.raw_hdl_size =       (unsigned) external_exception_vector_prolog_code_size;
     342    if (!mpc60x_set_exception (&vectorDesc)) {
     343      BSP_panic("Unable to initialize RTEMS external raw exception\n");
     344    }
    492345    return 1;
    493346}
     
    497350    *config = internal_config;
    498351    return 0;
    499 }
    500 
    501 int _BSP_vme_bridge_irq = -1;
    502 
    503 unsigned BSP_spuriousIntr = 0;
    504 /*
    505  * High level IRQ handler called from shared_raw_irq_code_entry
    506  */
    507 void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
    508 {
    509   register unsigned int irq;
    510   register unsigned isaIntr;                  /* boolean */
    511   register unsigned oldMask = 0;              /* old isa pic masks */
    512   register unsigned newMask;                  /* new isa pic masks */
    513   register unsigned msr;
    514   register unsigned new_msr;
    515 
    516   if (excNum == ASM_DEC_VECTOR) {
    517     _CPU_MSR_GET(msr);
    518     new_msr = msr | MSR_EE;
    519     _CPU_MSR_SET(new_msr);
    520 
    521     rtems_hdl_tbl[BSP_DECREMENTER].hdl(rtems_hdl_tbl[BSP_DECREMENTER].handle);
    522 
    523     _CPU_MSR_SET(msr);
    524     return;
    525 
    526   }
    527   irq = openpic_irq(0);
    528   if (irq == OPENPIC_VEC_SPURIOUS) {
    529     ++BSP_spuriousIntr;
    530     return;
    531   }
    532   isaIntr = (irq == BSP_PCI_ISA_BRIDGE_IRQ);
    533   if (isaIntr)  {
    534     /*
    535      * Acknowledge and read 8259 vector
    536      */
    537     irq = (unsigned int) (*(unsigned char *) RAVEN_INTR_ACK_REG);
    538     /*
    539      * store current PIC mask
    540      */
    541     oldMask = i8259s_cache;
    542     newMask = oldMask | irq_mask_or_tbl [irq];
    543     i8259s_cache = newMask;
    544     outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
    545     outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
    546     BSP_irq_ack_at_i8259s (irq);
    547     openpic_eoi(0);
    548   }
    549   _CPU_MSR_GET(msr);
    550   new_msr = msr | MSR_EE;
    551   _CPU_MSR_SET(new_msr);
    552 
    553   /* rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle); */
    554   {
    555      rtems_irq_connect_data* vchain;
    556      for( vchain = &rtems_hdl_tbl[irq];
    557           ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
    558           vchain = (rtems_irq_connect_data*)vchain->next_handler )
    559      {
    560         vchain->hdl(vchain->handle);
    561      }
    562   }
    563 
    564   _CPU_MSR_SET(msr);
    565 
    566   if (isaIntr)  {
    567     i8259s_cache = oldMask;
    568     outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
    569     outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
    570   }
    571   else {
    572 #ifdef BSP_PCI_VME_DRIVER_DOES_EOI
    573         /* leave it to the VME bridge driver to do EOI, so
    574      * it can re-enable the openpic while handling
    575      * VME interrupts (-> VME priorities in software)
    576          */
    577         if (_BSP_vme_bridge_irq != irq)
    578 #endif
    579                 openpic_eoi(0);
    580   }
    581352}
    582353
  • c/src/lib/libbsp/powerpc/shared/irq/irq.h

    rbe45f8e r8c9fffd  
    155155 * ------------------------ Intel 8259 (or emulation) Mngt Routines -------
    156156 */
     157void BSP_i8259s_init(void);
    157158
    158159/*
     
    184185extern void BSP_i8259s_init(void);
    185186
     187/*
     188 * PIC-independent function to enable/disable interrupt lines at
     189 * the pic.
     190 */
     191extern void BSP_enable_irq_at_pic               (const rtems_irq_number irqLine);
     192extern void BSP_disable_irq_at_pic              (const rtems_irq_number irqLine);
     193
     194extern int BSP_setup_the_pic                    (rtems_irq_global_settings* config);
    186195#ifdef __cplusplus
    187 }
    188 #endif
    189 
    190 #endif
    191 #endif
     196};
     197#endif
     198
     199#endif
     200#endif
  • c/src/lib/libbsp/powerpc/shared/irq/irq_asm.S

    rbe45f8e r8c9fffd  
    9494        /*
    9595         * Enable data and instruction address translation, exception recovery
    96      *
    97      * also, on CPUs with FP, enable FP so that FP context can be
    98      * saved and restored (using FP instructions)
    9996         */
    10097        ori     r3, r3, MSR_RI | MSR_IR | MSR_DR
  • c/src/lib/libbsp/powerpc/shared/irq/irq_init.c

    rbe45f8e r8c9fffd  
    3939static pci_isa_bridge_device bridge;
    4040
    41 extern unsigned int external_exception_vector_prolog_code_size[];
    42 extern void external_exception_vector_prolog_code();
    43 extern unsigned int decrementer_exception_vector_prolog_code_size[];
    44 extern void decrementer_exception_vector_prolog_code();
    45 
    4641/*
    4742 * default on/off function
     
    5449/*
    5550 * default possible isOn function
     51static int connected() {return 1;}
    5652 */
    57 static int connected() {return 1;}
    5853
    5954static rtems_irq_connect_data           rtemsIrq[BSP_IRQ_NUMBER];
     
    266261  int known_cpi_isa_bridge = 0;
    267262#endif
    268   rtems_raw_except_connect_data vectorDesc;
    269263  int i;
    270264
     
    273267   */
    274268#if defined(mvme2100)
    275 #ifdef TRACE_IRQ_INIT 
     269#ifdef TRACE_IRQ_INIT
    276270  printk("Going to initialize EPIC interrupt controller (openpic compliant)\n");
    277271#endif
    278272  openpic_init(1, mvme2100_openpic_initpolarities, mvme2100_openpic_initsenses);
    279273#else
    280 #ifdef TRACE_IRQ_INIT
     274#ifdef TRACE_IRQ_INIT  
    281275  printk("Going to initialize raven interrupt controller (openpic compliant)\n");
    282276#endif
    283277  openpic_init(1, mcp750_openpic_initpolarities, mcp750_openpic_initsenses);
    284 #endif       
    285 
    286 #if !defined(mvme2100)
    287278#ifdef TRACE_IRQ_INIT 
    288279  printk("Going to initialize the PCI/ISA bridge IRQ related setting (VIA 82C586)\n");
     
    337328      BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
    338329    }
    339 
    340   /*
    341    * We must connect the raw irq handler for the two
    342    * expected interrupt sources : decrementer and external interrupts.
    343    */
    344     vectorDesc.exceptIndex      =       ASM_DEC_VECTOR;
    345     vectorDesc.hdl.vector       =       ASM_DEC_VECTOR;
    346     vectorDesc.hdl.raw_hdl      =       decrementer_exception_vector_prolog_code;
    347     vectorDesc.hdl.raw_hdl_size =       (unsigned) decrementer_exception_vector_prolog_code_size;
    348     vectorDesc.on               =       nop_func;
    349     vectorDesc.off              =       nop_func;
    350     vectorDesc.isOn             =       connected;
    351     if (!mpc60x_set_exception (&vectorDesc)) {
    352       BSP_panic("Unable to initialize RTEMS decrementer raw exception\n");
    353     }
    354     vectorDesc.exceptIndex      =       ASM_EXT_VECTOR;
    355     vectorDesc.hdl.vector       =       ASM_EXT_VECTOR;
    356     vectorDesc.hdl.raw_hdl      =       external_exception_vector_prolog_code;
    357     vectorDesc.hdl.raw_hdl_size =       (unsigned) external_exception_vector_prolog_code_size;
    358     if (!mpc60x_set_exception (&vectorDesc)) {
    359       BSP_panic("Unable to initialize RTEMS external raw exception\n");
    360     }
    361 #ifdef TRACE_IRQ_INIT
     330 
     331#ifdef TRACE_IRQ_INIT 
    362332    printk("RTEMS IRQ management is now operational\n");
    363333#endif
Note: See TracChangeset for help on using the changeset viewer.