source: rtems/bsps/powerpc/gen83xx/irq/irq.c

Last change on this file was bcef89f2, checked in by Sebastian Huber <sebastian.huber@…>, on 05/19/23 at 06:18:25

Update company name

The embedded brains GmbH & Co. KG is the legal successor of embedded
brains GmbH.

  • Property mode set to 100644
File size: 19.7 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/*
4 * RTEMS generic MPC83xx BSP
5 *
6 * This file integrates the IPIC irq controller.
7 */
8
9/*
10 * Copyright (c) 2007 embedded brains GmbH & Co. KG
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <mpc83xx/mpc83xx.h>
35
36#include <rtems.h>
37
38#include <libcpu/powerpc-utility.h>
39#include <bsp/vectors.h>
40
41#include <bsp.h>
42#include <bsp/irq.h>
43#include <bsp/irq-generic.h>
44
45#define MPC83XX_IPIC_VECTOR_NUMBER 92
46
47#define MPC83XX_IPIC_IS_VALID_VECTOR( vector) ((vector) >= 0 && (vector) < MPC83XX_IPIC_VECTOR_NUMBER)
48
49#define MPC83XX_IPIC_INVALID_MASK_POSITION 255
50
51typedef struct {
52  volatile uint32_t *pend_reg;
53  volatile uint32_t *mask_reg;
54  const uint32_t bit_num;
55} BSP_isrc_rsc_t;
56
57/*
58 * data structure to handle all mask registers in the IPIC
59 *
60 * Mask positions:
61 *   simsr [0] :  0 .. 31
62 *   simsr [1] : 32 .. 63
63 *   semsr     : 64 .. 95
64 *   sermr     : 96 .. 127
65 */
66typedef struct {
67  uint32_t simsr_mask [2];
68  uint32_t semsr_mask;
69  uint32_t sermr_mask;
70} mpc83xx_ipic_mask_t;
71
72static const BSP_isrc_rsc_t mpc83xx_ipic_isrc_rsc [MPC83XX_IPIC_VECTOR_NUMBER] = {
73  /* vector 0 */
74  {&mpc83xx.ipic.sersr, &mpc83xx.ipic.sermr, 31},
75  {NULL, NULL, 0},
76  {NULL, NULL, 0},
77  {NULL, NULL, 0},
78  {NULL, NULL, 0},
79  {NULL, NULL, 0},
80  {NULL, NULL, 0},
81  {NULL, NULL, 0},
82  /* vector  8 */
83  {NULL, NULL, 0},  /* reserved vector  8 */
84  /* vector  9: UART1 SIxxR_H, Bit 24 */
85  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 24},
86  /* vector 10: UART2 SIxxR_H, Bit 25 */
87  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 25},
88  /* vector 11: SEC   SIxxR_H, Bit 26 */
89  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 26},
90  {NULL, NULL, 0},  /* reserved vector 12 */
91  {NULL, NULL, 0},  /* reserved vector 13 */
92  /* vector 14: I2C1 SIxxR_H, Bit 29 */
93  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 29},
94  /* vector 15: I2C2 SIxxR_H, Bit 30 */
95  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 30},
96  /* vector 16: SPI  SIxxR_H, Bit 31 */
97  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 31},
98  /* vector 17: IRQ1 SExxR  , Bit  1 */
99  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 1},
100  /* vector 18: IRQ2 SExxR  , Bit  2 */
101  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 2},
102  /* vector 19: IRQ3 SExxR  , Bit  3 */
103  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 3},
104  /* vector 20: IRQ4 SExxR  , Bit  4 */
105  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 4},
106  /* vector 21: IRQ5 SExxR  , Bit  5 */
107  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 5},
108  /* vector 22: IRQ6 SExxR  , Bit  6 */
109  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 6},
110  /* vector 23: IRQ7 SExxR  , Bit  7 */
111  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 7},
112  {NULL, NULL, 0},  /* reserved vector 24 */
113  {NULL, NULL, 0},  /* reserved vector 25 */
114  {NULL, NULL, 0},  /* reserved vector 26 */
115  {NULL, NULL, 0},  /* reserved vector 27 */
116  {NULL, NULL, 0},  /* reserved vector 28 */
117  {NULL, NULL, 0},  /* reserved vector 29 */
118  {NULL, NULL, 0},  /* reserved vector 30 */
119  {NULL, NULL, 0},  /* reserved vector 31 */
120  /* vector 32: TSEC1 Tx  SIxxR_H  , Bit  0 */
121  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 0},
122  /* vector 33: TSEC1 Rx  SIxxR_H  , Bit  1 */
123  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 1},
124  /* vector 34: TSEC1 Err SIxxR_H  , Bit  2 */
125  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 2},
126  /* vector 35: TSEC2 Tx  SIxxR_H  , Bit  3 */
127  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 3},
128  /* vector 36: TSEC2 Rx  SIxxR_H  , Bit  4 */
129  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 4},
130  /* vector 37: TSEC2 Err SIxxR_H  , Bit  5 */
131  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 5},
132  /* vector 38: USB DR    SIxxR_H  , Bit  6 */
133  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 6},
134  /* vector 39: USB MPH   SIxxR_H  , Bit  7 */
135  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 7},
136  {NULL, NULL, 0},  /* reserved vector 40 */
137  {NULL, NULL, 0},  /* reserved vector 41 */
138  {NULL, NULL, 0},  /* reserved vector 42 */
139  {NULL, NULL, 0},  /* reserved vector 43 */
140  {NULL, NULL, 0},  /* reserved vector 44 */
141  {NULL, NULL, 0},  /* reserved vector 45 */
142  {NULL, NULL, 0},  /* reserved vector 46 */
143  {NULL, NULL, 0},  /* reserved vector 47 */
144  /* vector 48: IRQ0 SExxR  , Bit  0 */
145  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 0},
146  {NULL, NULL, 0},  /* reserved vector 49 */
147  {NULL, NULL, 0},  /* reserved vector 50 */
148  {NULL, NULL, 0},  /* reserved vector 51 */
149  {NULL, NULL, 0},  /* reserved vector 52 */
150  {NULL, NULL, 0},  /* reserved vector 53 */
151  {NULL, NULL, 0},  /* reserved vector 54 */
152  {NULL, NULL, 0},  /* reserved vector 55 */
153  {NULL, NULL, 0},  /* reserved vector 56 */
154  {NULL, NULL, 0},  /* reserved vector 57 */
155  {NULL, NULL, 0},  /* reserved vector 58 */
156  {NULL, NULL, 0},  /* reserved vector 59 */
157  {NULL, NULL, 0},  /* reserved vector 60 */
158  {NULL, NULL, 0},  /* reserved vector 61 */
159  {NULL, NULL, 0},  /* reserved vector 62 */
160  {NULL, NULL, 0},  /* reserved vector 63 */
161  /* vector 64: RTC SEC   SIxxR_L  , Bit  0 */
162  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 0},
163  /* vector 65: PIT       SIxxR_L  , Bit  1 */
164  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 1},
165  /* vector 66: PCI1      SIxxR_L  , Bit  2 */
166  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 2},
167  /* vector 67: PCI2      SIxxR_L  , Bit  3 */
168  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 3},
169  /* vector 68: RTC ALR   SIxxR_L  , Bit  4 */
170  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 4},
171  /* vector 69: MU        SIxxR_L  , Bit  5 */
172  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 5},
173  /* vector 70: SBA       SIxxR_L  , Bit  6 */
174  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 6},
175  /* vector 71: DMA       SIxxR_L  , Bit  7 */
176  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 7},
177  /* vector 72: GTM4      SIxxR_L  , Bit  8 */
178  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 8},
179  /* vector 73: GTM8      SIxxR_L  , Bit  9 */
180  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 9},
181  /* vector 74: GPIO1     SIxxR_L  , Bit 10 */
182  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 10},
183  /* vector 75: GPIO2     SIxxR_L  , Bit 11 */
184  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 11},
185  /* vector 76: DDR       SIxxR_L  , Bit 12 */
186  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 12},
187  /* vector 77: LBC       SIxxR_L  , Bit 13 */
188  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 13},
189  /* vector 78: GTM2      SIxxR_L  , Bit 14 */
190  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 14},
191  /* vector 79: GTM6      SIxxR_L  , Bit 15 */
192  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 15},
193  /* vector 80: PMC       SIxxR_L  , Bit 16 */
194  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 16},
195  {NULL, NULL, 0},  /* reserved vector 81 */
196  {NULL, NULL, 0},  /* reserved vector 82 */
197  {NULL, NULL, 0},  /* reserved vector 63 */
198  /* vector 84: GTM3      SIxxR_L  , Bit 20 */
199  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 20},
200  /* vector 85: GTM7      SIxxR_L  , Bit 21 */
201  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 21},
202  {NULL, NULL, 0},  /* reserved vector 81 */
203  {NULL, NULL, 0},  /* reserved vector 82 */
204  {NULL, NULL, 0},  /* reserved vector 63 */
205  {NULL, NULL, 0},  /* reserved vector 63 */
206  /* vector 90: GTM1      SIxxR_L  , Bit 26 */
207  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 26},
208  /* vector 91: GTM5      SIxxR_L  , Bit 27 */
209  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 27}
210};
211
212static const uint8_t
213    mpc83xx_ipic_mask_position_table [MPC83XX_IPIC_VECTOR_NUMBER] = {
214  MPC83XX_IPIC_INVALID_MASK_POSITION,
215  MPC83XX_IPIC_INVALID_MASK_POSITION,
216  MPC83XX_IPIC_INVALID_MASK_POSITION,
217  MPC83XX_IPIC_INVALID_MASK_POSITION,
218  MPC83XX_IPIC_INVALID_MASK_POSITION,
219  MPC83XX_IPIC_INVALID_MASK_POSITION,
220  MPC83XX_IPIC_INVALID_MASK_POSITION,
221  MPC83XX_IPIC_INVALID_MASK_POSITION,
222  MPC83XX_IPIC_INVALID_MASK_POSITION,
223  7,
224  6,
225  5,
226  MPC83XX_IPIC_INVALID_MASK_POSITION,
227  MPC83XX_IPIC_INVALID_MASK_POSITION,
228  2,
229  1,
230  0,
231  94,
232  93,
233  92,
234  91,
235  90,
236  89,
237  88,
238  MPC83XX_IPIC_INVALID_MASK_POSITION,
239  MPC83XX_IPIC_INVALID_MASK_POSITION,
240  MPC83XX_IPIC_INVALID_MASK_POSITION,
241  MPC83XX_IPIC_INVALID_MASK_POSITION,
242  MPC83XX_IPIC_INVALID_MASK_POSITION,
243  MPC83XX_IPIC_INVALID_MASK_POSITION,
244  MPC83XX_IPIC_INVALID_MASK_POSITION,
245  MPC83XX_IPIC_INVALID_MASK_POSITION,
246  31,
247  30,
248  29,
249  28,
250  27,
251  26,
252  25,
253  24,
254  MPC83XX_IPIC_INVALID_MASK_POSITION,
255  MPC83XX_IPIC_INVALID_MASK_POSITION,
256  MPC83XX_IPIC_INVALID_MASK_POSITION,
257  MPC83XX_IPIC_INVALID_MASK_POSITION,
258  MPC83XX_IPIC_INVALID_MASK_POSITION,
259  MPC83XX_IPIC_INVALID_MASK_POSITION,
260  MPC83XX_IPIC_INVALID_MASK_POSITION,
261  MPC83XX_IPIC_INVALID_MASK_POSITION,
262  95,
263  MPC83XX_IPIC_INVALID_MASK_POSITION,
264  MPC83XX_IPIC_INVALID_MASK_POSITION,
265  MPC83XX_IPIC_INVALID_MASK_POSITION,
266  MPC83XX_IPIC_INVALID_MASK_POSITION,
267  MPC83XX_IPIC_INVALID_MASK_POSITION,
268  MPC83XX_IPIC_INVALID_MASK_POSITION,
269  MPC83XX_IPIC_INVALID_MASK_POSITION,
270  MPC83XX_IPIC_INVALID_MASK_POSITION,
271  MPC83XX_IPIC_INVALID_MASK_POSITION,
272  MPC83XX_IPIC_INVALID_MASK_POSITION,
273  MPC83XX_IPIC_INVALID_MASK_POSITION,
274  MPC83XX_IPIC_INVALID_MASK_POSITION,
275  MPC83XX_IPIC_INVALID_MASK_POSITION,
276  MPC83XX_IPIC_INVALID_MASK_POSITION,
277  MPC83XX_IPIC_INVALID_MASK_POSITION,
278  63,
279  62,
280  61,
281  60,
282  59,
283  58,
284  57,
285  56,
286  55,
287  54,
288  53,
289  52,
290  51,
291  50,
292  49,
293  48,
294  47,
295  MPC83XX_IPIC_INVALID_MASK_POSITION,
296  MPC83XX_IPIC_INVALID_MASK_POSITION,
297  MPC83XX_IPIC_INVALID_MASK_POSITION,
298  43,
299  42,
300  MPC83XX_IPIC_INVALID_MASK_POSITION,
301  MPC83XX_IPIC_INVALID_MASK_POSITION,
302  MPC83XX_IPIC_INVALID_MASK_POSITION,
303  MPC83XX_IPIC_INVALID_MASK_POSITION,
304  37,
305  36
306};
307
308/*
309 * this array will be filled with mask values needed
310 * to temporarily disable all IRQ soures with lower or same
311 * priority of the current source (whose vector is the array index)
312 */
313static mpc83xx_ipic_mask_t mpc83xx_ipic_prio2mask [MPC83XX_IPIC_VECTOR_NUMBER];
314
315rtems_status_code mpc83xx_ipic_set_mask(
316  rtems_vector_number vector,
317  rtems_vector_number mask_vector,
318  bool mask
319)
320{
321  uint8_t pos = 0;
322  mpc83xx_ipic_mask_t *mask_entry;
323  uint32_t *mask_reg;
324  rtems_interrupt_level level;
325
326  /* Parameter check */
327  if (!MPC83XX_IPIC_IS_VALID_VECTOR( vector) ||
328      !MPC83XX_IPIC_IS_VALID_VECTOR( mask_vector)) {
329    return RTEMS_INVALID_NUMBER;
330  } else if (vector == mask_vector) {
331    return RTEMS_RESOURCE_IN_USE;
332  }
333
334  /* Position and mask entry */
335  pos = mpc83xx_ipic_mask_position_table [mask_vector];
336  mask_entry = &mpc83xx_ipic_prio2mask [vector];
337
338  /* Mask register and position */
339  if (pos < 32) {
340    mask_reg = &mask_entry->simsr_mask [0];
341  } else if (pos < 64) {
342    pos -= 32;
343    mask_reg = &mask_entry->simsr_mask [1];
344  } else if (pos < 96) {
345    pos -= 64;
346    mask_reg = &mask_entry->semsr_mask;
347  } else if (pos < 128) {
348    pos -= 96;
349    mask_reg = &mask_entry->sermr_mask;
350  } else {
351    return RTEMS_NOT_IMPLEMENTED;
352  }
353
354  /* Mask or unmask */
355  if (mask) {
356    rtems_interrupt_disable( level);
357    *mask_reg &= ~(1 << pos);
358    rtems_interrupt_enable( level);
359  } else {
360    rtems_interrupt_disable( level);
361    *mask_reg |= 1 << pos;
362    rtems_interrupt_enable( level);
363  }
364
365  return RTEMS_SUCCESSFUL;
366}
367
368rtems_status_code mpc83xx_ipic_set_highest_priority_interrupt(
369  rtems_vector_number vector,
370  int type
371)
372{
373  rtems_interrupt_level level;
374  uint32_t reg = 0;
375
376  if (!MPC83XX_IPIC_IS_VALID_VECTOR( vector)) {
377    return RTEMS_INVALID_NUMBER;
378  } else if (type < 0 || type > MPC83XX_IPIC_INTERRUPT_CRITICAL) {
379    return RTEMS_INVALID_NUMBER;
380  }
381
382  rtems_interrupt_disable( level);
383  reg = mpc83xx.ipic.sicfr;
384  mpc83xx.ipic.sicfr = (reg & ~0x7f000300) | (vector << 24) | (type << 8);
385  rtems_interrupt_enable( level);
386
387  return RTEMS_SUCCESSFUL;
388}
389
390/*
391 * functions to enable/disable a source at the ipic
392 */
393rtems_status_code bsp_interrupt_get_attributes(
394  rtems_vector_number         vector,
395  rtems_interrupt_attributes *attributes
396)
397{
398  return RTEMS_SUCCESSFUL;
399}
400
401rtems_status_code bsp_interrupt_is_pending(
402  rtems_vector_number vector,
403  bool               *pending
404)
405{
406  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
407  bsp_interrupt_assert(pending != NULL);
408  *pending = false;
409  return RTEMS_UNSATISFIED;
410}
411
412rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
413{
414  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
415  return RTEMS_UNSATISFIED;
416}
417
418rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
419{
420  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
421  return RTEMS_UNSATISFIED;
422}
423
424rtems_status_code bsp_interrupt_vector_is_enabled(
425  rtems_vector_number vector,
426  bool               *enabled
427)
428{
429  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
430  bsp_interrupt_assert(enabled != NULL);
431  *enabled = false;
432  return RTEMS_UNSATISFIED;
433}
434
435rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number vector)
436{
437  rtems_vector_number vecnum = vector - BSP_IPIC_IRQ_LOWEST_OFFSET;
438  const BSP_isrc_rsc_t *rsc_ptr;
439
440  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
441
442  if (MPC83XX_IPIC_IS_VALID_VECTOR( vecnum)) {
443    rsc_ptr = &mpc83xx_ipic_isrc_rsc [vecnum];
444    if (rsc_ptr->mask_reg != NULL) {
445      uint32_t bit = 1U << (31 - rsc_ptr->bit_num);
446      rtems_interrupt_level level;
447
448      rtems_interrupt_disable(level);
449      *(rsc_ptr->mask_reg) |= bit;
450      rtems_interrupt_enable(level);
451    }
452  }
453
454  return RTEMS_SUCCESSFUL;
455}
456
457rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number vector)
458{
459  rtems_vector_number vecnum = vector - BSP_IPIC_IRQ_LOWEST_OFFSET;
460  const BSP_isrc_rsc_t *rsc_ptr;
461
462  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
463
464  if (MPC83XX_IPIC_IS_VALID_VECTOR( vecnum)) {
465    rsc_ptr = &mpc83xx_ipic_isrc_rsc [vecnum];
466    if (rsc_ptr->mask_reg != NULL) {
467      uint32_t bit = 1U << (31 - rsc_ptr->bit_num);
468      rtems_interrupt_level level;
469
470      rtems_interrupt_disable(level);
471      *(rsc_ptr->mask_reg) &= ~bit;
472      rtems_interrupt_enable(level);
473    }
474  }
475
476  return RTEMS_SUCCESSFUL;
477}
478
479/*
480 *  IRQ Handler: this is called from the primary exception dispatcher
481 */
482static int BSP_irq_handle_at_ipic( unsigned excNum)
483{
484  int32_t vecnum;
485#ifdef GEN83XX_ENABLE_INTERRUPT_NESTING
486  mpc83xx_ipic_mask_t mask_save;
487  const mpc83xx_ipic_mask_t *mask_ptr;
488  uint32_t msr = 0;
489  rtems_interrupt_level level;
490#endif
491
492  /* Get vector number */
493  switch (excNum) {
494    case ASM_EXT_VECTOR:
495      vecnum = MPC83xx_VCR_TO_VEC( mpc83xx.ipic.sivcr);
496      break;
497    case ASM_E300_SYSMGMT_VECTOR:
498      vecnum = MPC83xx_VCR_TO_VEC( mpc83xx.ipic.smvcr);
499      break;
500    case ASM_E300_CRIT_VECTOR:
501      vecnum = MPC83xx_VCR_TO_VEC( mpc83xx.ipic.scvcr);
502      break;
503    default:
504      return 1;
505  }
506
507  /*
508   * Check the vector number, mask lower priority interrupts, enable
509   * exceptions and dispatch the handler.
510   */
511  if (MPC83XX_IPIC_IS_VALID_VECTOR( vecnum)) {
512#ifdef GEN83XX_ENABLE_INTERRUPT_NESTING
513    mask_ptr = &mpc83xx_ipic_prio2mask [vecnum];
514
515    rtems_interrupt_disable( level);
516
517    /* Save current mask registers */
518    mask_save.simsr_mask [0] = mpc83xx.ipic.simsr [0];
519    mask_save.simsr_mask [1] = mpc83xx.ipic.simsr [1];
520    mask_save.semsr_mask = mpc83xx.ipic.semsr;
521    mask_save.sermr_mask = mpc83xx.ipic.sermr;
522
523    /* Mask all lower priority interrupts */
524    mpc83xx.ipic.simsr [0] &= mask_ptr->simsr_mask [0];
525    mpc83xx.ipic.simsr [1] &= mask_ptr->simsr_mask [1];
526    mpc83xx.ipic.semsr &= mask_ptr->semsr_mask;
527    mpc83xx.ipic.sermr &= mask_ptr->sermr_mask;
528
529    rtems_interrupt_enable( level);
530
531    /* Enable all interrupts */
532    if (excNum != ASM_E300_CRIT_VECTOR) {
533      msr = ppc_external_exceptions_enable();
534    }
535#endif /* GEN83XX_ENABLE_INTERRUPT_NESTING */
536
537    /* Dispatch interrupt handlers */
538    bsp_interrupt_handler_dispatch( vecnum + BSP_IPIC_IRQ_LOWEST_OFFSET);
539
540#ifdef GEN83XX_ENABLE_INTERRUPT_NESTING
541    /* Restore machine state */
542    if (excNum != ASM_E300_CRIT_VECTOR) {
543      ppc_external_exceptions_disable( msr);
544    }
545
546    /* Restore initial masks */
547    rtems_interrupt_disable( level);
548    mpc83xx.ipic.simsr [0] = mask_save.simsr_mask [0];
549    mpc83xx.ipic.simsr [1] = mask_save.simsr_mask [1];
550    mpc83xx.ipic.semsr = mask_save.semsr_mask;
551    mpc83xx.ipic.sermr = mask_save.sermr_mask;
552    rtems_interrupt_enable( level);
553#endif /* GEN83XX_ENABLE_INTERRUPT_NESTING */
554  } else {
555    bsp_interrupt_handler_default( vecnum);
556  }
557
558  return 0;
559}
560
561/*
562 * Fill the array mpc83xx_ipic_prio2mask to allow masking of lower prio sources
563 * to implement nested interrupts.
564 */
565static void mpc83xx_ipic_calc_prio2mask(void)
566{
567  /*
568   * FIXME: fill the array
569   */
570}
571
572/*
573 * Activate the interrupt controller
574 */
575static void mpc83xx_ipic_initialize(void)
576{
577  /*
578   * mask off all interrupts
579   */
580  mpc83xx.ipic.simsr [0] = 0;
581  mpc83xx.ipic.simsr [1] = 0;
582  mpc83xx.ipic.semsr = 0;
583  mpc83xx.ipic.sermr = 0;
584  /*
585   * set desired configuration as defined in bspopts.h
586   * normally, the default values should be fine
587   */
588#if defined( BSP_SICFR_VAL)  /* defined in bspopts.h ? */
589  mpc83xx.ipic.sicfr = BSP_SICFR_VAL;
590#endif
591
592  /*
593   * set desired priorities as defined in bspopts.h
594   * normally, the default values should be fine
595   */
596#if defined( BSP_SIPRR0_VAL)  /* defined in bspopts.h ? */
597  mpc83xx.ipic.siprr [0] = BSP_SIPRR0_VAL;
598#endif
599
600#if defined( BSP_SIPRR1_VAL)  /* defined in bspopts.h ? */
601  mpc83xx.ipic.siprr [1] = BSP_SIPRR1_VAL;
602#endif
603
604#if defined( BSP_SIPRR2_VAL)  /* defined in bspopts.h ? */
605  mpc83xx.ipic.siprr [2] = BSP_SIPRR2_VAL;
606#endif
607
608#if defined( BSP_SIPRR3_VAL)  /* defined in bspopts.h ? */
609  mpc83xx.ipic.siprr [3] = BSP_SIPRR3_VAL;
610#endif
611
612#if defined( BSP_SMPRR0_VAL)  /* defined in bspopts.h ? */
613  mpc83xx.ipic.smprr [0] = BSP_SMPRR0_VAL;
614#endif
615
616#if defined( BSP_SMPRR1_VAL)  /* defined in bspopts.h ? */
617  mpc83xx.ipic.smprr [1] = BSP_SMPRR1_VAL;
618#endif
619
620#if defined( BSP_SECNR_VAL)  /* defined in bspopts.h ? */
621  mpc83xx.ipic.secnr = BSP_SECNR_VAL;
622#endif
623
624  /*
625   * calculate priority masks
626   */
627  mpc83xx_ipic_calc_prio2mask();
628}
629
630static int mpc83xx_exception_handler(
631  BSP_Exception_frame *frame,
632  unsigned exception_number
633)
634{
635  return BSP_irq_handle_at_ipic( exception_number);
636}
637
638void bsp_interrupt_facility_initialize()
639{
640  rtems_status_code sc;
641
642  /* Install exception handler */
643  sc = ppc_exc_set_handler( ASM_EXT_VECTOR, mpc83xx_exception_handler);
644  _Assert_Unused_variable_equals( sc, RTEMS_SUCCESSFUL);
645  sc = ppc_exc_set_handler( ASM_E300_SYSMGMT_VECTOR, mpc83xx_exception_handler);
646  _Assert_Unused_variable_equals( sc, RTEMS_SUCCESSFUL);
647  sc = ppc_exc_set_handler( ASM_E300_CRIT_VECTOR, mpc83xx_exception_handler);
648  _Assert_Unused_variable_equals( sc, RTEMS_SUCCESSFUL);
649
650  /* Initialize the interrupt controller */
651  mpc83xx_ipic_initialize();
652}
Note: See TracBrowser for help on using the repository browser.