source: rtems/bsps/arm/tms570/irq/irq.c @ 8f8ccee

5
Last change on this file since 8f8ccee was 8f8ccee, checked in by Sebastian Huber <sebastian.huber@…>, on 04/23/18 at 07:50:39

bsps: Move interrupt controller support to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/**
2 * @file irq.c
3 *
4 * @ingroup tms570
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_MAX+1];
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 */
99void bsp_interrupt_vector_enable(
100  rtems_vector_number vector
101)
102{
103  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
104  TMS570_VIM.REQENASET[vector >> 5] = 1 << (vector & 0x1f);
105}
106
107/**
108 * @brief disables interrupt vector in the HW
109 *
110 * Disables HW interrupt for specified vector
111 *
112 * @param[in] vector vector of the isr which needs to be disabled.
113 * @retval RTEMS_INVALID_ID vector is invalid.
114 * @retval RTEMS_SUCCESSFUL interrupt source disabled.
115 */
116void bsp_interrupt_vector_disable(
117  rtems_vector_number vector
118)
119{
120  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
121  TMS570_VIM.REQENACLR[vector >> 5] = 1 << (vector & 0x1f);
122}
123
124/**
125 * @brief Init function of interrupt module
126 *
127 * Resets vectored interrupt interface to default state.
128 * Disables all interrupts.
129 * Set all sources as IRQ (not FIR).
130 *
131 * @retval RTEMS_SUCCESSFUL All is set
132 */
133rtems_status_code bsp_interrupt_facility_initialize(void)
134{
135  void (**vim_vec)(void) = (void (**)(void)) 0xFFF82000;
136  unsigned int value = 0x00010203;
137  unsigned int i = 0;
138  uint32_t sctlr;
139
140  /* Disable interrupts */
141  for ( i = 0; i < 3; i++ ) {
142    TMS570_VIM.REQENACLR[i] = 0xffffffff;
143  }
144  /* Map default events on interrupt vectors */
145  for ( i = 0; i < 24; i += 1, value += 0x04040404) {
146    TMS570_VIM.CHANCTRL[i] = value;
147  }
148  /* Set all vectors as IRQ (not FIR) */
149  TMS570_VIM.FIRQPR[0] = 3;
150  TMS570_VIM.FIRQPR[1] = 0;
151  TMS570_VIM.FIRQPR[2] = 0;
152
153  /*
154    _CPU_ISR_install_vector(
155        ARM_EXCEPTION_IRQ,
156        _ARMV4_Exception_interrupt,
157        NULL
158    );
159
160    Call to setup of interrupt entry in CPU level exception vectors table
161    is not used (necessary/possible) because the table is provided
162    by c/src/lib/libbsp/arm/shared/start/start.S and POM overlay
163    solution remaps that to address zero.
164  */
165
166  for ( i = 0; i <= 94; ++i ) {
167    vim_vec[i] = _ARMV4_Exception_interrupt;
168  }
169  /* Clear bit VE in SCTLR register to not use VIM IRQ exception bypass*/
170  asm volatile ("mrc p15, 0, %0, c1, c0, 0\n": "=r" (sctlr));
171  /*
172   * Disable bypass of CPU level exception table for interrupt entry which
173   * can be provided by VIM hardware
174   */
175  sctlr &= ~(1 << 24);
176  #if 0
177    /*
178     * Option to enable exception table bypass for interrupts
179     *
180     * Because RTEMS requires all interrupts to be serviced through
181     * common _ARMV4_Exception_interrupt handler to allow task switching
182     * on exit from interrupt working correctly, vim_vec cannot point
183     * directly to individual vector handlers and need to point
184     * to single entry path. But if TMS570_VIM.IRQINDEX is then used
185     * to target execution to corresponding service then for some
186     * peripherals (i.e. EMAC) interrupt is already acknowledged
187     * by VIM and IRQINDEX is read as zero which leads to spurious
188     * interrupt and peripheral not serviced/blocked.
189     *
190     * To analyze this behavior we used trampolines which setup
191     * bsp_interrupt_vector_inject and pass execution to
192     * _ARMV4_Exception_interrupt. It works but is more ugly than
193     * use of POM remap for these cases where application does not
194     * start at address 0x00000000. If RTEMS image is placed at
195     * memory space beginning then no of these constructs is necessary.
196     */
197    sctlr |= 1 << 24;
198  #endif
199  asm volatile ("mcr p15, 0, %0, c1, c0, 0\n": : "r" (sctlr));
200
201  return RTEMS_SUCCESSFUL;
202}
Note: See TracBrowser for help on using the repository browser.