source: rtems/c/src/lib/libbsp/powerpc/virtex5/irq/irq_init.c @ 16a8616

4.115
Last change on this file since 16a8616 was 16a8616, checked in by Ric Claus <claus@…>, on 03/30/12 at 15:03:43

Add Virtex4 and Virtex5 BSPs

This commit covers at least PR2020, 2022, and 2023. This
patch adds all of the code for both BSPs, modifications
to libcpu/powerpc for the ppc440, and some updates to the
BSPs from follow up review and testing.

These BSPs should be good baselines for future development.
The configurations used by Ric are custom and have a non-standard
NIC. They also do not have a UART. Thus the current console
driver just prints to a RAM buffer.

The NIC and UART support are left for future work. When the UART
support is added, moving the existing "to RAM" console driver to
a shared location is likely desirable because boards with no debug
UART port are commonly deployed. This would let printk() go to RAM.

  • Property mode set to 100644
File size: 8.3 KB
Line 
1/*===============================================================*\
2| Project: RTEMS virtex BSP                                       |
3+-----------------------------------------------------------------+
4| Partially based on the code references which are named below.   |
5| Adaptions, modifications, enhancements and any recent parts of  |
6| the code are:                                                   |
7|                    Copyright (c) 2007                           |
8|                    Embedded Brains GmbH                         |
9|                    Obere Lagerstr. 30                           |
10|                    D-82178 Puchheim                             |
11|                    Germany                                      |
12|                    rtems@embedded-brains.de                     |
13+-----------------------------------------------------------------+
14| The license and distribution terms for this file may be         |
15| found in the file LICENSE in this distribution or at            |
16|                                                                 |
17| http://www.rtems.com/license/LICENSE.                           |
18|                                                                 |
19+-----------------------------------------------------------------+
20| this file contains the irq controller handler                   |
21\*===============================================================*/
22#include <libcpu/spr.h>
23#include <bsp/irq.h>
24#include <bsp.h>
25#include <rtems/bspIo.h>
26#include <rtems/powerpc/powerpc.h>
27#include <bsp/vectors.h>
28
29static rtems_irq_connect_data rtemsIrqTbl[BSP_IRQ_NUMBER];
30rtems_irq_connect_data *BSP_rtems_irq_tbl;
31rtems_irq_global_settings* BSP_rtems_irq_config;
32
33/***********************************************************
34 * dummy functions for on/off/isOn calls
35 * these functions just do nothing fulfill the semantic
36 * requirements to enable/disable a certain interrupt or exception
37 */
38void BSP_irq_nop_func(const rtems_irq_connect_data *unused)
39{
40  /*
41   * nothing to do
42   */
43}
44
45void BSP_irq_nop_hdl(void *hdl)
46{
47  /*
48   * nothing to do
49   */
50}
51
52int BSP_irq_isOn_func(const rtems_irq_connect_data *unused)
53{
54  /*
55   * nothing to do
56   */
57  return 0;
58}
59
60/***********************************************************
61 * interrupt handler and its enable/disable functions
62 ***********************************************************/
63
64/***********************************************************
65 * functions to enable/disable/query external/critical interrupts
66 */
67void BSP_irqexc_on_fnc(rtems_irq_connect_data *conn_data)
68{
69  uint32_t msr_value;
70  /*
71   * get current MSR value
72   */
73  _CPU_MSR_GET(msr_value);
74
75  msr_value |= PPC_MSR_EE;
76  _CPU_MSR_SET(msr_value);
77}
78
79void BSP_irqexc_off_fnc(rtems_irq_connect_data *unused)
80{
81  uint32_t msr_value;
82  /*
83   * get current MSR value
84   */
85  _CPU_MSR_GET(msr_value);
86
87  msr_value &= ~PPC_MSR_EE;
88  _CPU_MSR_SET(msr_value);
89}
90
91/***********************************************************
92 * High level IRQ handler called from shared_raw_irq_code_entry
93 */
94int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
95{
96  /*
97   * Handle interrupt
98   */
99  switch(excNum) {
100  case ASM_EXT_VECTOR:
101    BSP_rtems_irq_tbl[BSP_EXT].hdl(BSP_rtems_irq_tbl[BSP_EXT].handle);
102    break;
103  case ASM_BOOKE_DEC_VECTOR:
104    BSP_rtems_irq_tbl[BSP_PIT].hdl(BSP_rtems_irq_tbl[BSP_PIT].handle);
105    break;
106#if 0 /* Critical interrupts not yet supported */
107  case ASM_BOOKE_CRIT_VECTOR:
108    BSP_rtems_irq_tbl[BSP_CRIT].hdl(BSP_rtems_irq_tbl[BSP_CRIT].handle);
109    break;
110#endif
111  }
112
113  return 0;
114}
115
116/***********************************************************
117 * functions to set/get/remove interrupt handlers
118 ***********************************************************/
119int BSP_install_rtems_irq_handler  (const rtems_irq_connect_data* irq)
120{
121  rtems_interrupt_level level;
122
123  /*
124   * check for valid irq name
125   * if invalid, print error and return 0
126   */
127  if (!BSP_IS_VALID_IRQ(irq->name)) {
128    printk("Invalid interrupt vector %d\n",irq->name);
129    return 0;
130  }
131
132  /*
133   * disable interrupts
134   */
135  rtems_interrupt_disable(level);
136
137  /*
138   * check, that default handler is installed now
139   */
140  if (rtemsIrqTbl[irq->name].hdl != BSP_rtems_irq_config->defaultEntry.hdl) {
141    rtems_interrupt_enable(level);
142    printk("IRQ vector %d already connected\n",irq->name);
143    return 0;
144  }
145
146  /*
147   * store new handler data
148   */
149  rtemsIrqTbl[irq->name] = *irq;
150
151  /*
152   * call "on" function to enable interrupt at device
153   */
154  irq->on(irq);
155
156  /*
157   * reenable interrupts
158   */
159  rtems_interrupt_enable(level);
160
161  return 1;
162}
163
164int BSP_get_current_rtems_irq_handler   (rtems_irq_connect_data* irq)
165{
166  rtems_interrupt_level level;
167
168  /*
169   * check for valid IRQ name
170   */
171  if (!BSP_IS_VALID_IRQ(irq->name)) {
172    return 0;
173  }
174  rtems_interrupt_disable(level);
175
176  /*
177   * return current IRQ entry
178   */
179  *irq = rtemsIrqTbl[irq->name];
180  rtems_interrupt_enable(level);
181  return 1;
182}
183
184int BSP_remove_rtems_irq_handler  (const rtems_irq_connect_data* irq)
185{
186  rtems_interrupt_level level;
187
188  /*
189   * check for valid IRQ name
190   */
191  if (!BSP_IS_VALID_IRQ(irq->name)) {
192    return 0;
193  }
194  rtems_interrupt_disable(level);
195
196  /*
197   * check, that specified handler is really connected now
198   */
199  if (rtemsIrqTbl[irq->name].hdl != irq->hdl) {
200    rtems_interrupt_enable(level);
201    return 0;
202  }
203
204  /*
205   * disable interrupt at source
206   */
207  irq->off(irq);
208
209  /*
210   * restore default interrupt handler
211   */
212  rtemsIrqTbl[irq->name] = BSP_rtems_irq_config->defaultEntry;
213
214  /*
215   * reenable interrupts
216   */
217  rtems_interrupt_enable(level);
218
219  return 1;
220}
221
222/***********************************************************
223 * functions to set/get the basic interrupt management setup
224 ***********************************************************/
225/*
226 * (Re) get info on current RTEMS interrupt management.
227 */
228int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** ret_ptr)
229{
230  *ret_ptr = BSP_rtems_irq_config;
231  return 0;
232}
233
234
235/*
236 * set management stuff
237 */
238int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
239{
240  int                    i;
241  rtems_interrupt_level  level;
242
243  rtems_interrupt_disable(level);
244
245  /*
246   * store given configuration
247   */
248  BSP_rtems_irq_config = config;
249  BSP_rtems_irq_tbl    = BSP_rtems_irq_config->irqHdlTbl;
250
251  /*
252   * store any irq-like processor exceptions
253   */
254  for (i = BSP_PROCESSOR_IRQ_LOWEST_OFFSET;
255       i < BSP_PROCESSOR_IRQ_MAX_OFFSET;
256       i++) {
257    if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
258      if (BSP_rtems_irq_tbl[i].on != NULL) {
259        BSP_rtems_irq_tbl[i].on
260          (&(BSP_rtems_irq_tbl[i]));
261      }
262    }
263    else {
264      if (BSP_rtems_irq_tbl[i].off != NULL) {
265        BSP_rtems_irq_tbl[i].off
266          (&(BSP_rtems_irq_tbl[i]));
267      }
268    }
269  }
270  rtems_interrupt_enable(level);
271  return 1;
272}
273
274/*
275 * dummy for an empty IRQ handler entry
276 */
277static rtems_irq_connect_data emptyIrq = {
278  0,                     /* Irq Name                 */
279  BSP_irq_nop_hdl,       /* handler function         */
280  NULL,                  /* handle passed to handler */
281  BSP_irq_nop_func,      /* on function              */
282  BSP_irq_nop_func,      /* off function             */
283  BSP_irq_isOn_func      /* isOn function            */
284};
285
286static rtems_irq_global_settings initialConfig = {
287  BSP_IRQ_NUMBER,    /* irqNb */
288  {  0,                          /* Irq Name                 */
289     BSP_irq_nop_hdl,       /* handler function         */
290     NULL,                  /* handle passed to handler */
291     BSP_irq_nop_func,      /* on function              */
292     BSP_irq_nop_func,      /* off function             */
293     BSP_irq_isOn_func      /* isOn function            */
294  }, /* emptyIrq */
295  rtemsIrqTbl, /* irqHdlTbl  */
296  0,           /* irqBase    */
297  NULL         /* irqPrioTbl */
298};
299
300void BSP_rtems_irq_mngt_init(unsigned cpuId)
301{
302  int i;
303
304  /*
305   * connect all exception vectors needed
306   */
307  ppc_exc_set_handler(ASM_EXT_VECTOR,       C_dispatch_irq_handler);
308  ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_irq_handler);
309
310  /*
311   * setup interrupt handlers table
312   */
313  for (i = 0;
314       i < BSP_IRQ_NUMBER;
315       i++) {
316    rtemsIrqTbl[i]      = emptyIrq;
317    rtemsIrqTbl[i].name = i;
318  }
319
320  /*
321   * initialize interrupt management
322   */
323  if (!BSP_rtems_irq_mngt_set(&initialConfig)) {
324    BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
325  }
326}
Note: See TracBrowser for help on using the repository browser.