Changeset d216c5d6 in rtems


Ignore:
Timestamp:
Jul 23, 2016, 10:10:34 AM (4 years ago)
Author:
Pavel Pisa <pisa@…>
Branches:
master
Children:
ba0471d
Parents:
d548318
Message:

arm/raspberrypi: change interrupt dispatch and enable to generic vector id based approach.

Using conditional branches to find bits is extremely inefficient
and for asynchronous delivery of different interrupt sources
lead to total confusion of branch prediction unit.

Location:
c/src/lib/libbsp/arm/raspberrypi
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/arm/raspberrypi/include/irq.h

    rd548318 rd216c5d6  
    5353
    5454
     55#define BCM2835_IRQ_ID_BASIC_BASE_ID 64
    5556#define BCM2835_IRQ_ID_TIMER_0       64
    5657#define BCM2835_IRQ_ID_MAILBOX_0     65
     
    5859#define BCM2835_IRQ_ID_DOORBELL_1    67
    5960#define BCM2835_IRQ_ID_GPU0_HALTED   68
     61#define BCM2835_IRQ_ID_GPU1_HALTED   69
     62#define BCM2835_IRQ_ID_ILL_ACCESS_1  70
     63#define BCM2835_IRQ_ID_ILL_ACCESS_0  71
    6064
    6165#define BSP_INTERRUPT_VECTOR_MIN    (0)
  • c/src/lib/libbsp/arm/raspberrypi/irq/irq.c

    rd548318 rd216c5d6  
    3131#include <bsp/mmu.h>
    3232#include <rtems/bspIo.h>
     33#include <strings.h>
     34
     35typedef struct {
     36  unsigned long enable_reg_addr;
     37  unsigned long disable_reg_addr;
     38} bcm2835_irq_ctrl_reg_t;
     39
     40static const bcm2835_irq_ctrl_reg_t bcm2835_irq_ctrl_reg_table[] = {
     41  { BCM2835_IRQ_ENABLE1, BCM2835_IRQ_DISABLE1 },
     42  { BCM2835_IRQ_ENABLE2, BCM2835_IRQ_DISABLE2 },
     43  { BCM2835_IRQ_ENABLE_BASIC, BCM2835_IRQ_DISABLE_BASIC }
     44};
     45
     46static inline const bcm2835_irq_ctrl_reg_t *
     47bsp_vector_to_reg(rtems_vector_number vector)
     48{
     49  return bcm2835_irq_ctrl_reg_table + (vector >> 5);
     50}
     51
     52static inline uint32_t
     53bsp_vector_to_mask(rtems_vector_number vector)
     54{
     55  return 1 << (vector & 0x1f);
     56}
     57
     58static const int bcm2835_irq_speedup_table[] =
     59{
     60  /*  0 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  0,
     61  /*  1 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  1,
     62  /*  2 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  2,
     63  /*  3 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  3,
     64  /*  4 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  4,
     65  /*  5 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  5,
     66  /*  6 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  6,
     67  /*  7 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  7,
     68  /*  8 */ -1, /* One or more bits set in pending register 1 */
     69  /*  9 */ -2, /* One or more bits set in pending register 2 */
     70  /* 10 */  7, /* GPU IRQ 7 */
     71  /* 11 */  9, /* GPU IRQ 9 */
     72  /* 12 */ 10, /* GPU IRQ 10 */
     73  /* 13 */ 18, /* GPU IRQ 18 */
     74  /* 14 */ 19, /* GPU IRQ 19 */
     75  /* 15 */ 53, /* GPU IRQ 53 */
     76  /* 16 */ 54, /* GPU IRQ 54 */
     77  /* 17 */ 55, /* GPU IRQ 55 */
     78  /* 18 */ 56, /* GPU IRQ 56 */
     79  /* 19 */ 57, /* GPU IRQ 57 */
     80  /* 20 */ 62, /* GPU IRQ 62 */
     81};
    3382
    3483/*
    35 ** Determine the source of the interrupt and dispatch the correct handler.
    36 */
     84 * Define which basic peding register (BCM2835_IRQ_BASIC) bits
     85 * should be processed through bcm2835_irq_speedup_table
     86 */
     87
     88#define BCM2835_IRQ_BASIC_SPEEDUP_USED_BITS 0x1ffcff
     89
     90/*
     91 * Determine the source of the interrupt and dispatch the correct handler.
     92 */
    3793void bsp_interrupt_dispatch(void)
    3894{
     95  unsigned int pend;
     96  unsigned int pend_bit;
     97
    3998  rtems_vector_number vector = 255;
    4099
    41   /* ARM timer */
    42   if ( BCM2835_REG(BCM2835_IRQ_BASIC) & 0x1 )
    43   {
    44       vector = BCM2835_IRQ_ID_TIMER_0;
    45   }
    46   /* UART 0 */
    47   else if ( BCM2835_REG(BCM2835_IRQ_BASIC) & BCM2835_BIT(19) )
    48   {
    49       vector = BCM2835_IRQ_ID_UART;
    50   }
    51   /* GPIO 0*/
    52   else if ( BCM2835_REG(BCM2835_IRQ_PENDING2) & BCM2835_BIT(17) )
    53   {
    54       vector = BCM2835_IRQ_ID_GPIO_0;
    55   }
    56   else if ( BCM2835_REG(BCM2835_IRQ_PENDING2) & BCM2835_BIT(18) )
    57   {
    58       vector = BCM2835_IRQ_ID_GPIO_1;
    59   }
    60   else if ( BCM2835_REG(BCM2835_IRQ_PENDING2) & BCM2835_BIT(19) )
    61   {
    62       vector = BCM2835_IRQ_ID_GPIO_2;
    63   }
    64   else if ( BCM2835_REG(BCM2835_IRQ_PENDING2) & BCM2835_BIT(20) )
    65   {
    66       vector = BCM2835_IRQ_ID_GPIO_3;
    67   }
    68   /* I2C */
    69   else if ( BCM2835_REG(BCM2835_IRQ_PENDING2) & BCM2835_BIT(21) )
    70   {
    71       vector = BCM2835_IRQ_ID_I2C;
    72   }
    73   /* SPI */
    74   else if ( BCM2835_REG(BCM2835_IRQ_PENDING2) & BCM2835_BIT(22) )
    75   {
    76       vector = BCM2835_IRQ_ID_SPI;
    77   }
    78   /* USB */
    79   else if ( BCM2835_REG(BCM2835_IRQ_PENDING1) & BCM2835_BIT(9) )
    80   {
    81       vector = BCM2835_IRQ_ID_USB;
     100  pend = BCM2835_REG(BCM2835_IRQ_BASIC);
     101  if ( pend & BCM2835_IRQ_BASIC_SPEEDUP_USED_BITS ) {
     102    pend_bit = ffs(pend) - 1;
     103    vector = bcm2835_irq_speedup_table[pend_bit];
     104  } else {
     105    pend = BCM2835_REG(BCM2835_IRQ_PENDING1);
     106    if ( pend != 0 ) {
     107      pend_bit = ffs(pend) - 1;
     108      vector = pend_bit;
     109    } else {
     110      pend = BCM2835_REG(BCM2835_IRQ_PENDING2);
     111      if ( pend != 0 ) {
     112        pend_bit = ffs(pend) - 1;
     113        vector = pend_bit + 32;
     114      }
     115    }
    82116  }
    83117
     
    90124rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
    91125{
    92   rtems_interrupt_level  level;
     126  if ( vector > BSP_INTERRUPT_VECTOR_MAX )
     127    return RTEMS_INVALID_ID;
    93128
    94   rtems_interrupt_disable(level);
    95  
    96   /* ARM Timer */
    97   if ( vector == BCM2835_IRQ_ID_TIMER_0 )
    98   {
    99       BCM2835_REG(BCM2835_IRQ_ENABLE_BASIC) = 0x1;
    100   }
    101   /* UART 0 */
    102   else if ( vector == BCM2835_IRQ_ID_UART )
    103   {
    104       BCM2835_REG(BCM2835_IRQ_ENABLE2) =  BCM2835_BIT(25);
    105   }
    106   /* GPIO 0 */
    107   else if ( vector == BCM2835_IRQ_ID_GPIO_0 )
    108   {
    109       BCM2835_REG(BCM2835_IRQ_ENABLE2) = BCM2835_BIT(17);
    110   }
    111   /* GPIO 1 */
    112   else if ( vector == BCM2835_IRQ_ID_GPIO_1 )
    113   {
    114       BCM2835_REG(BCM2835_IRQ_ENABLE2) = BCM2835_BIT(18);
    115   }
    116   /* GPIO 2 */
    117   else if ( vector == BCM2835_IRQ_ID_GPIO_2 )
    118   {
    119       BCM2835_REG(BCM2835_IRQ_ENABLE2) = BCM2835_BIT(19);
    120   }
    121   /* GPIO 3 */
    122   else if ( vector == BCM2835_IRQ_ID_GPIO_3 )
    123   {
    124       BCM2835_REG(BCM2835_IRQ_ENABLE2) = BCM2835_BIT(20);
    125   }
    126   /* I2C */
    127   else if ( vector == BCM2835_IRQ_ID_I2C )
    128   {
    129       BCM2835_REG(BCM2835_IRQ_ENABLE2) = BCM2835_BIT(21);
    130   }
    131   /* SPI */
    132   else if ( vector == BCM2835_IRQ_ID_SPI )
    133   {
    134       BCM2835_REG(BCM2835_IRQ_ENABLE2) = BCM2835_BIT(22);
    135   }
    136   /* USB */
    137   else if ( vector == BCM2835_IRQ_ID_USB )
    138   {
    139       BCM2835_REG(BCM2835_IRQ_ENABLE1) = BCM2835_BIT(9);
    140   }
    141  
    142   rtems_interrupt_enable(level);
     129  BCM2835_REG(bsp_vector_to_reg(vector)->enable_reg_addr) =
     130              bsp_vector_to_mask(vector);
    143131
    144132  return RTEMS_SUCCESSFUL;
     
    147135rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
    148136{
    149   rtems_interrupt_level level;
     137  if ( vector > BSP_INTERRUPT_VECTOR_MAX )
     138    return RTEMS_INVALID_ID;
    150139
    151   rtems_interrupt_disable(level);
    152 
    153   if ( vector == BCM2835_IRQ_ID_TIMER_0 )
    154   {
    155       BCM2835_REG(BCM2835_IRQ_DISABLE_BASIC) = 0x1;
    156   }
    157   else if ( vector == BCM2835_IRQ_ID_UART )
    158   {
    159       BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(25);
    160   }
    161   /* GPIO 0 */
    162   else if ( vector == BCM2835_IRQ_ID_GPIO_0 )
    163   {
    164       BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(17);
    165   }
    166   /* GPIO 1 */
    167   else if ( vector == BCM2835_IRQ_ID_GPIO_1 )
    168   {
    169       BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(18);
    170   }
    171   /* GPIO 2 */
    172   else if ( vector == BCM2835_IRQ_ID_GPIO_2 )
    173   {
    174       BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(19);
    175   }
    176   /* GPIO 3 */
    177   else if ( vector == BCM2835_IRQ_ID_GPIO_3 )
    178   {
    179       BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(20);
    180   }
    181   /* I2C */
    182   else if ( vector == BCM2835_IRQ_ID_I2C )
    183   {
    184       BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(21);
    185   }
    186   /* SPI */
    187   else if ( vector == BCM2835_IRQ_ID_SPI )
    188   {
    189       BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(22);
    190   }
    191   /* USB */
    192   else if ( vector == BCM2835_IRQ_ID_USB )
    193   {
    194       BCM2835_REG(BCM2835_IRQ_DISABLE1) = BCM2835_BIT(9);
    195   }
    196 
    197   rtems_interrupt_enable(level);
     140  BCM2835_REG(bsp_vector_to_reg(vector)->disable_reg_addr) =
     141              bsp_vector_to_mask(vector);
    198142
    199143  return RTEMS_SUCCESSFUL;
Note: See TracChangeset for help on using the changeset viewer.