Changeset fc5490f in rtems


Ignore:
Timestamp:
Jul 3, 2009, 3:08:54 PM (10 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, master
Children:
562eab5c
Parents:
2c8a980
Message:

2009-07-01 Sebastian Huber <sebastian.huber@…>

  • shared/irq/irq.h, shared/irq/irq.c, shared/irq/irq_init.c: Converted to use generic interrupt support.
  • shared/irq/irq-config.h: New file.
Location:
c/src/lib/libbsp/i386
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/i386/ChangeLog

    r2c8a980 rfc5490f  
     12009-07-01      Sebastian Huber <sebastian.huber@embedded-brains.de>
     2
     3        * shared/irq/irq.h, shared/irq/irq.c, shared/irq/irq_init.c: Converted
     4        to use generic interrupt support.
     5        * shared/irq/irq-config.h: New file.
     6
    172009-05-06      Joel Sherrill <joel.sherrill@oarcorp.com>
    28
  • c/src/lib/libbsp/i386/shared/irq/irq.c

    r2c8a980 rfc5490f  
    33 *  This file contains the implementation of the function described in irq.h
    44 *
     5 *  Copyright (c) 2009 embedded brains GmbH
    56 *  Copyright (C) 1998 valette@crf.canon.fr
    67 *
     
    1718#include <bsp.h>
    1819#include <bsp/irq.h>
     20#include <bsp/irq-generic.h>
     21
    1922#include <stdlib.h>
    2023#include <rtems/score/apiext.h>
     
    3033rtems_i8259_masks       irq_mask_or_tbl[BSP_IRQ_LINES_NUMBER];
    3134
    32 /*
    33  * default handler connected on each irq after bsp initialization
    34  */
    35 static rtems_irq_connect_data   default_rtems_entry;
    36 
    37 /*
    38  * location used to store initial tables used for interrupt
    39  * management.
    40  */
    41 static rtems_irq_global_settings*       internal_config;
    42 rtems_irq_connect_data*                 rtems_hdl_tbl;
    4335/*-------------------------------------------------------------------------+
    4436| Cache for 1st and 2nd PIC IRQ line's status (enabled or disabled) register.
     
    161153 */
    162154
    163 /*
    164  * Caution : this function assumes the variable "internal_config"
    165  * is already set and that the tables it contains are still valid
    166  * and accessible.
    167  */
     155static rtems_irq_prio irqPrioTable[BSP_IRQ_LINES_NUMBER]={
     156  /*
     157   * actual rpiorities for interrupt :
     158   *    0   means that only current interrupt is masked
     159   *    255 means all other interrupts are masked
     160   * The second entry has a priority of 255 because
     161   * it is the slave pic entry and is should always remain
     162   * unmasked.
     163   */
     164  0,0,
     165  255,
     166  0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0
     167};
     168
    168169static void compute_i8259_masks_from_prio (void)
    169170{
     171  rtems_interrupt_level level;
    170172  unsigned int i;
    171173  unsigned int j;
     174
     175  rtems_interrupt_disable(level); /* XXX */
     176
    172177  /*
    173178   * Always mask at least current interrupt to prevent re-entrance
    174179   */
    175   for (i=0; i < internal_config->irqNb; i++) {
     180  for (i=0; i < BSP_IRQ_LINES_NUMBER; i++) {
    176181    * ((unsigned short*) &irq_mask_or_tbl[i]) = (1 << i);
    177     for (j = 0; j < internal_config->irqNb; j++) {
     182    for (j = 0; j < BSP_IRQ_LINES_NUMBER; j++) {
    178183      /*
    179184       * Mask interrupts at i8259 level that have a lower priority
    180185       */
    181       if (internal_config->irqPrioTbl [i] > internal_config->irqPrioTbl [j]) {
     186      if (irqPrioTable [i] > irqPrioTable [j]) {
    182187        * ((unsigned short*) &irq_mask_or_tbl[i]) |= (1 << j);
    183188      }
    184189    }
    185190  }
    186 }
    187 
    188 /*
    189  * This function check that the value given for the irq line
    190  * is valid.
    191  */
    192 
    193 static int isValidInterrupt(int irq)
    194 {
    195   if ( (irq < BSP_LOWEST_OFFSET) || (irq > BSP_MAX_OFFSET))
    196     return 0;
    197   return 1;
    198 }
    199 
    200 /*
    201  * ------------------- RTEMS Shared Irq Handler Mngt Routines ------------
    202  */
    203 int BSP_install_rtems_shared_irq_handler  (const rtems_irq_connect_data* irq)
    204 {
    205   rtems_interrupt_level   level;
    206   rtems_irq_connect_data* vchain;
    207 
    208   if (!isValidInterrupt(irq->name)) {
    209     printk("Invalid interrupt vector %d\n",irq->name);
    210     return 0;
    211   }
    212 
    213   rtems_interrupt_disable(level);
    214 
    215   if ( (int)rtems_hdl_tbl[irq->name].next_handler  == -1 ) {
    216     rtems_interrupt_enable(level);
    217     printk(
    218       "IRQ vector %d already connected to an unshared handler\n",
    219       irq->name
    220     );
    221     return 0;
    222   }
    223 
    224    vchain = (rtems_irq_connect_data*)malloc(sizeof(rtems_irq_connect_data));
    225 
    226   /* save off topmost handler */
    227   vchain[0]= rtems_hdl_tbl[irq->name];
    228 
    229   /*
    230    * store the data provided by user
    231    */
    232   rtems_hdl_tbl[irq->name] = *irq;
    233 
    234   /* link chain to new topmost handler */
    235   rtems_hdl_tbl[irq->name].next_handler = (void *)vchain;
    236 
    237   /*
    238    * enable_irq_at_pic is supposed to ignore
    239    * requests to disable interrupts outside
    240    * of the range handled by the PIC
    241    */
    242   BSP_irq_enable_at_i8259s (irq->name);
    243 
    244   /*
    245    * Enable interrupt on device
    246    */
    247   if (irq->on)
    248     irq->on(irq);
    249191
    250192  rtems_interrupt_enable(level);
    251 
    252   return 1;
    253 }
    254 
    255 
    256 /*
    257  * --------------- RTEMS Single Irq Handler Mngt Routines ---------------
    258  */
    259 
    260 int BSP_install_rtems_irq_handler  (const rtems_irq_connect_data* irq)
    261 {
    262     rtems_interrupt_level       level;
    263 
    264     if (!isValidInterrupt(irq->name)) {
    265       return 0;
    266     }
    267     /*
    268      * Check if default handler is actually connected. If not issue an error.
    269      * You must first get the current handler via i386_get_current_idt_entry
    270      * and then disconnect it using i386_delete_idt_entry.
    271      * RATIONALE : to always have the same transition by forcing the user
    272      * to get the previous handler before accepting to disconnect.
    273      */
    274     rtems_interrupt_disable(level);
    275     if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) {
    276           rtems_interrupt_enable(level);
    277       return 0;
    278     }
    279 
    280     /*
    281      * store the data provided by user
    282      */
    283     rtems_hdl_tbl[irq->name] = *irq;
    284     rtems_hdl_tbl[irq->name].next_handler = (void *)-1;
    285 
    286     /*
    287      * Enable interrupt at PIC level
    288      */
    289     BSP_irq_enable_at_i8259s (irq->name);
    290     /*
    291      * Enable interrupt on device
    292      */
    293     if (irq->on)
    294         irq->on(irq);
    295 
    296     rtems_interrupt_enable(level);
    297 
    298     return 1;
    299 }
    300 
    301 int BSP_get_current_rtems_irq_handler   (rtems_irq_connect_data* irq)
    302 {
    303     rtems_interrupt_level       level;
    304 
    305     if (!isValidInterrupt(irq->name)) {
    306       return 0;
    307     }
    308     rtems_interrupt_disable(level);
    309       *irq = rtems_hdl_tbl[irq->name];
    310     rtems_interrupt_enable(level);
    311     return 1;
    312 }
    313 
    314 int BSP_remove_rtems_irq_handler  (const rtems_irq_connect_data* irq)
    315 {
    316   rtems_interrupt_level       level;
    317   rtems_irq_connect_data *pchain= NULL, *vchain = NULL;
    318 
    319   if (!isValidInterrupt(irq->name)) {
    320     return 0;
    321   }
    322 
    323   /*
    324    * Check if default handler is actually connected. If not issue an error.
    325    * You must first get the current handler via i386_get_current_idt_entry
    326    * and then disconnect it using i386_delete_idt_entry.
    327    * RATIONALE : to always have the same transition by forcing the user
    328    * to get the previous handler before accepting to disconnect.
    329    */
    330   rtems_interrupt_disable(level);
    331   if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) {
    332     rtems_interrupt_enable(level);
    333     return 0;
    334   }
    335 
    336   if ( (int)rtems_hdl_tbl[irq->name].next_handler != -1 ) {
    337     int found = 0;
    338 
    339     for( (pchain= NULL, vchain = &rtems_hdl_tbl[irq->name]);
    340          (vchain->hdl != default_rtems_entry.hdl);
    341          (pchain= vchain,
    342           vchain = (rtems_irq_connect_data*)vchain->next_handler) ) {
    343       if ( vchain->hdl == irq->hdl ) {
    344         found =  -1;
    345         break;
    346       }
    347     }
    348 
    349     if ( !found ) {
    350       rtems_interrupt_enable(level);
    351       return 0;
    352     }
    353   } else {
    354     if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) {
    355       rtems_interrupt_enable(level);
    356       return 0;
    357     }
    358   }
    359 
    360   /*
    361    * disable interrupt at PIC level
    362    */
    363   BSP_irq_disable_at_i8259s (irq->name);
    364 
    365   /*
    366    * Disable interrupt on device
    367    */
    368   if (irq->off)
    369     irq->off(irq);
    370 
    371   /*
    372    * restore the default irq value
    373    */
    374   if( !vchain ) {
    375      /* single handler vector... */
    376      rtems_hdl_tbl[irq->name] = default_rtems_entry;
    377   } else {
    378     if ( pchain ) {
    379        /* non-first handler being removed */
    380        pchain->next_handler = vchain->next_handler;
    381     } else {
    382        /* first handler isn't malloc'ed, so just overwrite it.  Since
    383         * the contents of vchain are being struct copied, vchain itself
    384         * goes away
    385         */
    386        vchain = vchain->next_handler;
    387        rtems_hdl_tbl[irq->name]= *vchain;
    388     }
    389     free(vchain);
    390   }
    391 
    392 
    393   rtems_interrupt_enable(level);
    394 
    395   return 1;
    396 }
    397 
    398 /*
    399  * ------------------------ RTEMS Global Irq Handler Mngt Routines ----------------
    400  */
    401 
    402 int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
    403 {
    404     int                    i;
    405     rtems_irq_connect_data*       vchain;
    406     rtems_interrupt_level  level;
    407 
    408     /*
    409      * Store various code accelerators
    410      */
    411     internal_config             = config;
    412     default_rtems_entry         = config->defaultEntry;
    413     rtems_hdl_tbl               = config->irqHdlTbl;
    414 
    415     rtems_interrupt_disable(level);
    416     /*
    417      * set up internal tables used by rtems interrupt prologue
    418      */
    419     compute_i8259_masks_from_prio ();
    420 
    421     for (i=0; i < internal_config->irqNb; i++) {
    422       BSP_irq_disable_at_i8259s (i);
    423       for( vchain = &rtems_hdl_tbl[i];
    424            ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
    425            vchain = (rtems_irq_connect_data*)vchain->next_handler ) {
    426         BSP_irq_enable_at_i8259s (i);
    427         if (vchain->on)
    428           vchain->on(vchain);
    429       }
    430     }
    431 
    432     /*
    433      * must enable slave pic anyway
    434      */
    435     BSP_irq_enable_at_i8259s (2);
    436     rtems_interrupt_enable(level);
    437     return 1;
    438 }
    439 
    440 int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config)
    441 {
    442     *config = internal_config;
    443     return 0;
     193}
     194
     195rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
     196{
     197  BSP_irq_enable_at_i8259s(vector);
     198
     199  return RTEMS_SUCCESSFUL;
     200}
     201
     202rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
     203{
     204  BSP_irq_disable_at_i8259s(vector);
     205
     206  return RTEMS_SUCCESSFUL;
     207}
     208
     209rtems_status_code bsp_interrupt_facility_initialize(void)
     210{
     211  /*
     212   * set up internal tables used by rtems interrupt prologue
     213   */
     214  compute_i8259_masks_from_prio();
     215
     216  /*
     217   * must enable slave pic anyway
     218   */
     219  BSP_irq_enable_at_i8259s(2);
     220
     221  return RTEMS_SUCCESSFUL;
     222}
     223
     224void bsp_interrupt_handler_default(rtems_vector_number vector)
     225{
     226  printk("spurious interrupt: %u\n", vector);
     227}
     228
     229void C_dispatch_isr(int vector)
     230{
     231  bsp_interrupt_handler_dispatch(vector);
    444232}
    445233
     
    462250   */
    463251}
    464 
    465 void processIrq(unsigned index)
    466 {
    467   rtems_hdl_tbl[index].hdl(rtems_hdl_tbl[index].handle);
    468 }
    469 
    470 static inline void
    471 bsp_irq_dispatch_list(
    472   rtems_irq_connect_data *tbl,
    473   unsigned                irq,
    474   rtems_irq_hdl                sentinel
    475 )
    476 {
    477   rtems_irq_connect_data* vchain;
    478   for( vchain = &tbl[irq];
    479        ((int)vchain != -1 && vchain->hdl != sentinel);
    480        vchain = (rtems_irq_connect_data*)vchain->next_handler ) {
    481           vchain->hdl(vchain->handle);
    482   }
    483 }
    484 
    485 
    486 void C_dispatch_isr(int irq)
    487 {
    488   bsp_irq_dispatch_list(rtems_hdl_tbl, irq, default_rtems_entry.hdl);
    489 }
  • c/src/lib/libbsp/i386/shared/irq/irq.h

    r2c8a980 rfc5490f  
    3434#define BSP_SHARED_HANDLER_SUPPORT      1
    3535#include <rtems/irq.h>
     36#include <rtems/irq-extension.h>
    3637
    3738/*-------------------------------------------------------------------------+
  • c/src/lib/libbsp/i386/shared/irq/irq_init.c

    r2c8a980 rfc5490f  
    44 *  related to interrupt handling.
    55 *
     6 *  Copyright (c) 2009 embedded brains GmbH
    67 *  CopyRight (C) 1998 valette@crf.canon.fr
    78 *
     
    1314 */
    1415
     16#include <rtems/bspIo.h>
     17
    1518#include <libcpu/cpu.h>
     19
     20#include <bsp.h>
    1621#include <bsp/irq.h>
    17 #include <bsp.h>
    18 #include <rtems/bspIo.h>
     22#include <bsp/irq-generic.h>
    1923
    2024/*
     
    6165static rtems_raw_irq_connect_data       idtHdl[IDT_SIZE];
    6266
    63 /*
    64  * default IRQ handler
    65  */
    66 static void irq_default_handler(rtems_irq_hdl_param unused)
    67 {
    68 }
    69 
    70 /*
    71  * default IRQ on/off function
    72  */
    73 static void irq_nop_func(const struct __rtems_irq_connect_data__ *unused)
    74 {
    75 }
    76 
    77 /*
    78  * default irq isOn function
    79  */
    80 static int irq_not_connected( const struct __rtems_irq_connect_data__ *unused)
    81 {
    82   return 0;
    83 }
    84 
    85 
    86 /*
    87  * Table used to store rtems managed interrupt handlers.
    88  * Borrow the table to store raw handler entries at the beginning.
    89  * The table will be reinitialized before the call to BSP_rtems_irq_mngt_set().
    90  */
    91 static rtems_irq_connect_data           rtemsIrq[BSP_IRQ_LINES_NUMBER] = {
    92   {0,(rtems_irq_hdl)rtems_irq_prologue_0},
    93   {0,(rtems_irq_hdl)rtems_irq_prologue_1},
    94   {0,(rtems_irq_hdl)rtems_irq_prologue_2},
    95   {0,(rtems_irq_hdl)rtems_irq_prologue_3},
    96   {0,(rtems_irq_hdl)rtems_irq_prologue_4},
    97   {0,(rtems_irq_hdl)rtems_irq_prologue_5},
    98   {0,(rtems_irq_hdl)rtems_irq_prologue_6},
    99   {0,(rtems_irq_hdl)rtems_irq_prologue_7},
    100   {0,(rtems_irq_hdl)rtems_irq_prologue_8},
    101   {0,(rtems_irq_hdl)rtems_irq_prologue_9},
    102   {0,(rtems_irq_hdl)rtems_irq_prologue_10},
    103   {0,(rtems_irq_hdl)rtems_irq_prologue_11},
    104   {0,(rtems_irq_hdl)rtems_irq_prologue_12},
    105   {0,(rtems_irq_hdl)rtems_irq_prologue_13},
    106   {0,(rtems_irq_hdl)rtems_irq_prologue_14},
    107   {0,(rtems_irq_hdl)rtems_irq_prologue_15}
     67static rtems_raw_irq_hdl rtemsIrq[BSP_IRQ_LINES_NUMBER] = {
     68  rtems_irq_prologue_0,
     69  rtems_irq_prologue_1,
     70  rtems_irq_prologue_2,
     71  rtems_irq_prologue_3,
     72  rtems_irq_prologue_4,
     73  rtems_irq_prologue_5,
     74  rtems_irq_prologue_6,
     75  rtems_irq_prologue_7,
     76  rtems_irq_prologue_8,
     77  rtems_irq_prologue_9,
     78  rtems_irq_prologue_10,
     79  rtems_irq_prologue_11,
     80  rtems_irq_prologue_12,
     81  rtems_irq_prologue_13,
     82  rtems_irq_prologue_14,
     83  rtems_irq_prologue_15
    10884};
    10985
     
    11692};
    11793
    118 static rtems_irq_connect_data           defaultIrq = {
    119   0,                     /* vectorIdex */
    120   irq_default_handler,   /* hdl */
    121   0,                     /* handle */
    122   irq_nop_func,          /* on */
    123   irq_nop_func,          /* off */
    124   irq_not_connected      /* isOn */
    125 };
    126 
    127 static rtems_irq_prio irqPrioTable[BSP_IRQ_LINES_NUMBER]={
    128   /*
    129    * actual rpiorities for interrupt :
    130    *    0   means that only current interrupt is masked
    131    *    255 means all other interrupts are masked
    132    * The second entry has a priority of 255 because
    133    * it is the slave pic entry and is should always remain
    134    * unmasked.
    135    */
    136   0,0,
    137   255,
    138   0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0
    139 };
    140 
    14194static interrupt_gate_descriptor        idtEntry;
    14295
    143 static rtems_irq_global_settings     initial_config;
    14496static rtems_raw_irq_global_settings raw_initial_config;
    14597
     
    192144     */
    193145    for (i = 0; i < BSP_IRQ_LINES_NUMBER; i++) {
    194       create_interrupt_gate_descriptor(&idtEntry,(rtems_raw_irq_hdl) rtemsIrq[i].hdl);
     146      create_interrupt_gate_descriptor(&idtEntry, rtemsIrq[i]);
    195147      idt_entry_tbl[i + BSP_ASM_IRQ_VECTOR_BASE] = idtEntry;
    196148    }
     
    200152     * interrupt management.
    201153     */
    202     /*
    203      * re-init the rtemsIrq table
    204      */
    205     for (i = 0; i < BSP_IRQ_LINES_NUMBER; i++) {
    206       rtemsIrq[i]      = defaultIrq;
    207       rtemsIrq[i].name = i;
    208     }
     154
    209155    /*
    210156     * Init initial Interrupt management config
    211157     */
    212     initial_config.irqNb        = BSP_IRQ_LINES_NUMBER;
    213     initial_config.defaultEntry = defaultIrq;
    214     initial_config.irqHdlTbl    = rtemsIrq;
    215     initial_config.irqBase      = BSP_ASM_IRQ_VECTOR_BASE;
    216     initial_config.irqPrioTbl   = irqPrioTable;
    217 
    218     if (!BSP_rtems_irq_mngt_set(&initial_config)) {
     158    if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) {
    219159      /*
    220160       * put something here that will show the failure...
Note: See TracChangeset for help on using the changeset viewer.