Changeset 78627fe2 in rtems


Ignore:
Timestamp:
Jul 23, 2016, 10:10:34 AM (4 years ago)
Author:
Pavel Pisa <pisa@…>
Branches:
4.11
Children:
fab0dd1
Parents:
acb488ff
git-author:
Pavel Pisa <pisa@…> (07/23/16 10:10:34)
git-committer:
Pavel Pisa <pisa@…> (10/02/16 08:40:35)
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.

Updates #2783

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

Legend:

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

    racb488ff r78627fe2  
    5252
    5353
     54#define BCM2835_IRQ_ID_BASIC_BASE_ID 64
    5455#define BCM2835_IRQ_ID_TIMER_0       64
    5556#define BCM2835_IRQ_ID_MAILBOX_0     65
     
    5758#define BCM2835_IRQ_ID_DOORBELL_1    67
    5859#define BCM2835_IRQ_ID_GPU0_HALTED   68
     60#define BCM2835_IRQ_ID_GPU1_HALTED   69
     61#define BCM2835_IRQ_ID_ILL_ACCESS_1  70
     62#define BCM2835_IRQ_ID_ILL_ACCESS_0  71
    5963
    6064#define BSP_INTERRUPT_VECTOR_MIN    (0)
  • c/src/lib/libbsp/arm/raspberrypi/irq/irq.c

    racb488ff r78627fe2  
    11/**
    2  * @file
     2 * @file irq.c
    33 *
    44 * @ingroup raspberrypi_interrupt
     
    88
    99/*
     10 * Copyright (c) 2014 Andre Marques <andre.lousa.marques at gmail.com>
     11 *
    1012 * Copyright (c) 2009
    1113 * embedded brains GmbH
     
    2830#include <bsp/linker-symbols.h>
    2931#include <bsp/mmu.h>
     32#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};
    3082
    3183/*
    32 ** Determine the source of the interrupt and dispatch the correct handler.
    33 */
     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 */
    3493void bsp_interrupt_dispatch(void)
    3594{
     95  unsigned int pend;
     96  unsigned int pend_bit;
     97
    3698  rtems_vector_number vector = 255;
    3799
    38   /* ARM timer */
    39   if (BCM2835_REG(BCM2835_IRQ_BASIC) && 0x1)
    40   {
    41       vector = BCM2835_IRQ_ID_TIMER_0;
    42 
    43   }
    44   /* UART 0 */
    45   else if ( BCM2835_REG(BCM2835_IRQ_BASIC) && BCM2835_BIT(19))
    46   {
    47       vector = BCM2835_IRQ_ID_UART;
     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    }
    48116  }
    49117
     
    52120      bsp_interrupt_handler_dispatch(vector);
    53121  }
    54 
    55122}
    56123
    57124rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
    58125{
    59   rtems_interrupt_level  level;
     126  if ( vector > BSP_INTERRUPT_VECTOR_MAX )
     127    return RTEMS_INVALID_ID;
    60128
    61   rtems_interrupt_disable(level);
    62 
    63    /* ARM Timer */
    64   if ( vector == BCM2835_IRQ_ID_TIMER_0 )
    65   {
    66       BCM2835_REG(BCM2835_IRQ_ENABLE_BASIC) = 0x1;
    67   }
    68   /* UART 0 */
    69   else if ( vector == BCM2835_IRQ_ID_UART )
    70   {
    71       BCM2835_REG(BCM2835_IRQ_ENABLE2) =  BCM2835_BIT(25);
    72 
    73   }
    74   rtems_interrupt_enable(level);
     129  BCM2835_REG(bsp_vector_to_reg(vector)->enable_reg_addr) =
     130              bsp_vector_to_mask(vector);
    75131
    76132  return RTEMS_SUCCESSFUL;
     
    79135rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
    80136{
    81   rtems_interrupt_level level;
     137  if ( vector > BSP_INTERRUPT_VECTOR_MAX )
     138    return RTEMS_INVALID_ID;
    82139
    83   rtems_interrupt_disable(level);
    84 
    85   if ( vector == BCM2835_IRQ_ID_TIMER_0 )
    86   {
    87       BCM2835_REG(BCM2835_IRQ_DISABLE_BASIC) = 0x1;
    88   }
    89   else if ( vector == BCM2835_IRQ_ID_UART )
    90   {
    91       BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(25);
    92   }
    93   rtems_interrupt_enable(level);
     140  BCM2835_REG(bsp_vector_to_reg(vector)->disable_reg_addr) =
     141              bsp_vector_to_mask(vector);
    94142
    95143  return RTEMS_SUCCESSFUL;
    96144}
    97145
    98 
    99146void bsp_interrupt_handler_default(rtems_vector_number vector)
    100147{
    101     printk("spurious interrupt: %u\n", vector);
     148    printk("spurious interrupt: %lu\n", vector);
    102149}
    103150
Note: See TracChangeset for help on using the changeset viewer.