source: rtems/bsps/arm/raspberrypi/irq/irq.c @ 0d362ff3

5
Last change on this file since 0d362ff3 was 0d362ff3, checked in by Sebastian Huber <sebastian.huber@…>, on 07/23/18 at 12:54:51

score: _SMP_Inter_processor_interrupt_handler()

Pass current processor control via parameter since it may be already
available at the caller side.

  • Property mode set to 100644
File size: 4.5 KB
Line 
1/**
2 * @file irq.c
3 *
4 * @ingroup raspberrypi_interrupt
5 *
6 * @brief Interrupt support.
7 */
8
9/*
10 * Copyright (c) 2014 Andre Marques <andre.lousa.marques at gmail.com>
11 *
12 * Copyright (c) 2009
13 * embedded brains GmbH
14 * Obere Lagerstr. 30
15 * D-82178 Puchheim
16 * Germany
17 * <rtems@embedded-brains.de>
18 *
19 * The license and distribution terms for this file may be
20 * found in the file LICENSE in this distribution or at
21 * http://www.rtems.org/license/LICENSE.
22 */
23
24#include <rtems/score/armv4.h>
25
26#include <bsp.h>
27#include <bsp/irq.h>
28#include <bsp/irq-generic.h>
29#include <bsp/raspberrypi.h>
30#include <bsp/linker-symbols.h>
31#include <bsp/mmu.h>
32#include <rtems/bspIo.h>
33#include <strings.h>
34
35#ifdef RTEMS_SMP
36#include <rtems/score/smp.h>
37#include <rtems/score/smpimpl.h>
38#endif
39
40typedef struct {
41  unsigned long enable_reg_addr;
42  unsigned long disable_reg_addr;
43} bcm2835_irq_ctrl_reg_t;
44
45static const bcm2835_irq_ctrl_reg_t bcm2835_irq_ctrl_reg_table[] = {
46  { BCM2835_IRQ_ENABLE1, BCM2835_IRQ_DISABLE1 },
47  { BCM2835_IRQ_ENABLE2, BCM2835_IRQ_DISABLE2 },
48  { BCM2835_IRQ_ENABLE_BASIC, BCM2835_IRQ_DISABLE_BASIC }
49};
50
51static inline const bcm2835_irq_ctrl_reg_t *
52bsp_vector_to_reg(rtems_vector_number vector)
53{
54  return bcm2835_irq_ctrl_reg_table + (vector >> 5);
55}
56
57static inline uint32_t
58bsp_vector_to_mask(rtems_vector_number vector)
59{
60  return 1 << (vector & 0x1f);
61}
62
63static const int bcm2835_irq_speedup_table[] =
64{
65  /*  0 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  0,
66  /*  1 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  1,
67  /*  2 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  2,
68  /*  3 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  3,
69  /*  4 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  4,
70  /*  5 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  5,
71  /*  6 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  6,
72  /*  7 */ BCM2835_IRQ_ID_BASIC_BASE_ID +  7,
73  /*  8 */ -1, /* One or more bits set in pending register 1 */
74  /*  9 */ -2, /* One or more bits set in pending register 2 */
75  /* 10 */  7, /* GPU IRQ 7 */
76  /* 11 */  9, /* GPU IRQ 9 */
77  /* 12 */ 10, /* GPU IRQ 10 */
78  /* 13 */ 18, /* GPU IRQ 18 */
79  /* 14 */ 19, /* GPU IRQ 19 */
80  /* 15 */ 53, /* GPU IRQ 53 */
81  /* 16 */ 54, /* GPU IRQ 54 */
82  /* 17 */ 55, /* GPU IRQ 55 */
83  /* 18 */ 56, /* GPU IRQ 56 */
84  /* 19 */ 57, /* GPU IRQ 57 */
85  /* 20 */ 62, /* GPU IRQ 62 */
86};
87
88/*
89 * Define which basic peding register (BCM2835_IRQ_BASIC) bits
90 * should be processed through bcm2835_irq_speedup_table
91 */
92
93#define BCM2835_IRQ_BASIC_SPEEDUP_USED_BITS 0x1ffcff
94
95/*
96 * Determine the source of the interrupt and dispatch the correct handler.
97 */
98void bsp_interrupt_dispatch(void)
99{
100  unsigned int pend;
101  unsigned int pend_bit;
102
103  rtems_vector_number vector = 255;
104
105#ifdef RTEMS_SMP
106  uint32_t cpu_index_self = _SMP_Get_current_processor();
107  uint32_t local_source = BCM2835_REG(BCM2836_IRQ_SOURCE_REG(cpu_index_self));
108
109  if ( local_source & BCM2836_IRQ_SOURCE_MBOX3 ) {
110    /* reset mailbox 3 contents to zero */
111    BCM2835_REG(BCM2836_MAILBOX_3_READ_CLEAR_BASE + 0x10 * cpu_index_self) = 0xffffffff;
112    _SMP_Inter_processor_interrupt_handler(
113      _Per_CPU_Get_by_index(cpu_index_self)
114    );
115  }
116  if ( cpu_index_self != 0 )
117    return;
118#endif /* RTEMS_SMP */
119
120  pend = BCM2835_REG(BCM2835_IRQ_BASIC);
121  if ( pend & BCM2835_IRQ_BASIC_SPEEDUP_USED_BITS ) {
122    pend_bit = ffs(pend) - 1;
123    vector = bcm2835_irq_speedup_table[pend_bit];
124  } else {
125    pend = BCM2835_REG(BCM2835_IRQ_PENDING1);
126    if ( pend != 0 ) {
127      pend_bit = ffs(pend) - 1;
128      vector = pend_bit;
129    } else {
130      pend = BCM2835_REG(BCM2835_IRQ_PENDING2);
131      if ( pend != 0 ) {
132        pend_bit = ffs(pend) - 1;
133        vector = pend_bit + 32;
134      }
135    }
136  }
137
138  if ( vector < 255 )
139  {
140      bsp_interrupt_handler_dispatch(vector);
141  }
142}
143
144void bsp_interrupt_vector_enable(rtems_vector_number vector)
145{
146  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
147  BCM2835_REG(bsp_vector_to_reg(vector)->enable_reg_addr) =
148              bsp_vector_to_mask(vector);
149}
150
151void bsp_interrupt_vector_disable(rtems_vector_number vector)
152{
153  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
154  BCM2835_REG(bsp_vector_to_reg(vector)->disable_reg_addr) =
155              bsp_vector_to_mask(vector);
156}
157
158void bsp_interrupt_handler_default(rtems_vector_number vector)
159{
160    printk("spurious interrupt: %lu\n", vector);
161}
162
163rtems_status_code bsp_interrupt_facility_initialize(void)
164{
165   BCM2835_REG(BCM2835_IRQ_DISABLE1) = 0xffffffff;
166   BCM2835_REG(BCM2835_IRQ_DISABLE2) = 0xffffffff;
167   BCM2835_REG(BCM2835_IRQ_DISABLE_BASIC) = 0xffffffff;
168   BCM2835_REG(BCM2835_IRQ_FIQ_CTRL) = 0;
169   return RTEMS_SUCCESSFUL;
170}
Note: See TracBrowser for help on using the repository browser.