source: rtems/bsps/arm/tms570/irq/irq.c @ c7b4eca7

Last change on this file since c7b4eca7 was c7b4eca7, checked in by Sebastian Huber <sebastian.huber@…>, on 07/27/21 at 07:58:43

bsps/irq: bsp_interrupt_facility_initialize()

Do not return a status code in bsp_interrupt_facility_initialize() since this
leads to unreachable code in bsp_interrupt_initialize(). Use RTEMS_DEBUG
assertions in bsp_interrupt_facility_initialize() if necessary.

  • Property mode set to 100644
File size: 6.7 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSBSPsARMTMS570
5 *
6 * @brief TMS570 interrupt support functions definitions.
7 */
8
9/*
10 * Copyright (c) 2014 Premysl Houdek <kom541000@gmail.com>
11 *
12 * Google Summer of Code 2014 at
13 * Czech Technical University in Prague
14 * Zikova 1903/4
15 * 166 36 Praha 6
16 * Czech Republic
17 *
18 * Based on LPC24xx and LPC1768 BSP
19 *
20 * The license and distribution terms for this file may be
21 * found in the file LICENSE in this distribution or at
22 * http://www.rtems.org/license/LICENSE.
23 */
24
25#include <bsp.h>
26#include <bsp/irq-generic.h>
27#include <bsp/tms570-vim.h>
28#include <bsp/irq.h>
29#include <rtems/score/armv4.h>
30
31unsigned int priorityTable[BSP_INTERRUPT_VECTOR_COUNT];
32
33/**
34 * @brief Set priority of the interrupt vector.
35 *
36 * This function is here because of compability. It should set
37 * priority of the interrupt vector.
38 * @warning It does not set any priority at HW layer. It is nearly imposible to
39 * @warning set priority of the interrupt on TMS570 in a nice way.
40 * @param[in] vector vector of isr
41 * @param[in] priority new priority assigned to the vector
42 * @return Void
43 */
44void tms570_irq_set_priority(
45  rtems_vector_number vector,
46  unsigned priority
47)
48{
49  if ( bsp_interrupt_is_valid_vector(vector) ) {
50    priorityTable[vector] = priority;
51  }
52}
53
54/**
55 * @brief Gets priority of the interrupt vector.
56 *
57 * This function is here because of compability. It returns priority
58 * of the isr vector last set by tms570_irq_set_priority function.
59 *
60 * @warning It does not return any real priority of the HW layer.
61 * @param[in] vector vector of isr
62 * @retval 0 vector is invalid.
63 * @retval priority priority of the interrupt
64 */
65unsigned tms570_irq_get_priority(
66  rtems_vector_number vector
67)
68{
69  if ( bsp_interrupt_is_valid_vector(vector) ) {
70   return priorityTable[vector];
71 }
72 return 0;
73}
74
75/**
76 * @brief Interrupt dispatch
77 *
78 * Called by OS to determine which interrupt occured.
79 * Function passes control to interrupt handler.
80 *
81 * @return Void
82 */
83void bsp_interrupt_dispatch(void)
84{
85  rtems_vector_number vector = TMS570_VIM.IRQINDEX-1;
86
87  bsp_interrupt_handler_dispatch(vector);
88}
89
90/**
91 * @brief enables interrupt vector in the HW
92 *
93 * Enables HW interrupt for specified vector
94 *
95 * @param[in] vector vector of the isr which needs to be enabled.
96 * @retval RTEMS_INVALID_ID vector is invalid.
97 * @retval RTEMS_SUCCESSFUL interrupt source enabled.
98 */
99rtems_status_code bsp_interrupt_get_attributes(
100  rtems_vector_number         vector,
101  rtems_interrupt_attributes *attributes
102)
103{
104  return RTEMS_SUCCESSFUL;
105}
106
107rtems_status_code bsp_interrupt_is_pending(
108  rtems_vector_number vector,
109  bool               *pending
110)
111{
112  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
113  bsp_interrupt_assert(pending != NULL);
114  *pending = false;
115  return RTEMS_UNSATISFIED;
116}
117
118rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
119{
120  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
121  return RTEMS_UNSATISFIED;
122}
123
124rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
125{
126  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
127  return RTEMS_UNSATISFIED;
128}
129
130rtems_status_code bsp_interrupt_vector_is_enabled(
131  rtems_vector_number vector,
132  bool               *enabled
133)
134{
135  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
136  bsp_interrupt_assert(enabled != NULL);
137  *enabled = false;
138  return RTEMS_UNSATISFIED;
139}
140
141rtems_status_code bsp_interrupt_vector_enable(
142  rtems_vector_number vector
143)
144{
145  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
146  TMS570_VIM.REQENASET[vector >> 5] = 1 << (vector & 0x1f);
147  return RTEMS_SUCCESSFUL;
148}
149
150/**
151 * @brief disables interrupt vector in the HW
152 *
153 * Disables HW interrupt for specified vector
154 *
155 * @param[in] vector vector of the isr which needs to be disabled.
156 * @retval RTEMS_INVALID_ID vector is invalid.
157 * @retval RTEMS_SUCCESSFUL interrupt source disabled.
158 */
159rtems_status_code bsp_interrupt_vector_disable(
160  rtems_vector_number vector
161)
162{
163  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
164  TMS570_VIM.REQENACLR[vector >> 5] = 1 << (vector & 0x1f);
165  return RTEMS_SUCCESSFUL;
166}
167
168/**
169 * @brief Init function of interrupt module
170 *
171 * Resets vectored interrupt interface to default state.
172 * Disables all interrupts.
173 * Set all sources as IRQ (not FIR).
174 *
175 * @retval RTEMS_SUCCESSFUL All is set
176 */
177void bsp_interrupt_facility_initialize(void)
178{
179  void (**vim_vec)(void) = (void (**)(void)) 0xFFF82000;
180  unsigned int value = 0x00010203;
181  unsigned int i = 0;
182  uint32_t sctlr;
183
184  /* Disable interrupts */
185  for ( i = 0; i < 3; i++ ) {
186    TMS570_VIM.REQENACLR[i] = 0xffffffff;
187  }
188  /* Map default events on interrupt vectors */
189  for ( i = 0; i < 24; i += 1, value += 0x04040404) {
190    TMS570_VIM.CHANCTRL[i] = value;
191  }
192  /* Set all vectors as IRQ (not FIR) */
193  TMS570_VIM.FIRQPR[0] = 3;
194  TMS570_VIM.FIRQPR[1] = 0;
195  TMS570_VIM.FIRQPR[2] = 0;
196
197  /*
198    _CPU_ISR_install_vector(
199        ARM_EXCEPTION_IRQ,
200        _ARMV4_Exception_interrupt,
201        NULL
202    );
203
204    Call to setup of interrupt entry in CPU level exception vectors table
205    is not used (necessary/possible) because the table is provided
206    by c/src/lib/libbsp/arm/shared/start/start.S and POM overlay
207    solution remaps that to address zero.
208  */
209
210  for ( i = 0; i <= 94; ++i ) {
211    vim_vec[i] = _ARMV4_Exception_interrupt;
212  }
213  /* Clear bit VE in SCTLR register to not use VIM IRQ exception bypass*/
214  asm volatile ("mrc p15, 0, %0, c1, c0, 0\n": "=r" (sctlr));
215  /*
216   * Disable bypass of CPU level exception table for interrupt entry which
217   * can be provided by VIM hardware
218   */
219  sctlr &= ~(1 << 24);
220  #if 0
221    /*
222     * Option to enable exception table bypass for interrupts
223     *
224     * Because RTEMS requires all interrupts to be serviced through
225     * common _ARMV4_Exception_interrupt handler to allow task switching
226     * on exit from interrupt working correctly, vim_vec cannot point
227     * directly to individual vector handlers and need to point
228     * to single entry path. But if TMS570_VIM.IRQINDEX is then used
229     * to target execution to corresponding service then for some
230     * peripherals (i.e. EMAC) interrupt is already acknowledged
231     * by VIM and IRQINDEX is read as zero which leads to spurious
232     * interrupt and peripheral not serviced/blocked.
233     *
234     * To analyze this behavior we used trampolines which setup
235     * bsp_interrupt_vector_inject and pass execution to
236     * _ARMV4_Exception_interrupt. It works but is more ugly than
237     * use of POM remap for these cases where application does not
238     * start at address 0x00000000. If RTEMS image is placed at
239     * memory space beginning then no of these constructs is necessary.
240     */
241    sctlr |= 1 << 24;
242  #endif
243  asm volatile ("mcr p15, 0, %0, c1, c0, 0\n": : "r" (sctlr));
244}
Note: See TracBrowser for help on using the repository browser.