source: rtems/c/src/lib/libcpu/mips/au1x00/vectorisrs/vectorisrs.c @ bd6515be

4.104.115
Last change on this file since bd6515be was 3b8ab757, checked in by Ralf Corsepius <ralf.corsepius@…>, on 05/28/10 at 06:09:35

2010-05-28 Ralf Corsépius <ralf.corsepius@…>

  • au1x00/include/au1x00.h: Add prototypes for mips_default_isr, assert_sw_irq, negate_sw_irq.
  • au1x00/vectorisrs/vectorisrs.c: Remove prototype of mips_default_isr.
  • Property mode set to 100644
File size: 3.8 KB
Line 
1/*
2 *  Au1x00 Interrupt Vectoring
3 *
4 * Copyright (c) 2005 by Cogent Computer Systems
5 * Written by Jay Monkman <jtm@lopingdog.com>
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *
10 *  http://www.rtems.com/license/LICENSE.
11 *
12 *  $Id$
13 */
14
15#include <rtems.h>
16#include <stdlib.h>
17#include <libcpu/au1x00.h>
18
19static void call_vectored_isr(CPU_Interrupt_frame *, uint32_t , void *);
20
21#define CALL_ISR(_vector,_frame) \
22  do { \
23    if ( _ISR_Vector_table[_vector] ) \
24      (_ISR_Vector_table[_vector])(_vector,_frame); \
25    else \
26      mips_default_isr(_vector); \
27  } while (0)
28
29#include <rtems/bspIo.h>  /* for printk */
30
31void mips_vector_isr_handlers( CPU_Interrupt_frame *frame )
32{
33  unsigned int sr;
34  unsigned int cause;
35
36  mips_get_sr( sr );
37  mips_get_cause( cause );
38
39  cause &= (sr & SR_IMASK);
40  cause >>= CAUSE_IPSHIFT;
41
42  /* count/compare interrupt */
43  if ( cause & 0x80 ) {
44      unsigned long zero = 0;
45      /*
46       * I don't see a good way to disable the compare
47       * interrupt, so let's just ignore it.
48       */
49      asm volatile ("mtc0 %0, $11\n" :: "r" (zero));
50
51/*      CALL_ISR( AU1X00_IRQ_CNT, frame );  */
52  }
53
54  /* Performance counter */
55  if ( cause & 0x40 ) {
56      CALL_ISR( AU1X00_IRQ_PERF, frame );
57  }
58
59  /* Interrupt controller 0 */
60  if ( cause & 0x0c ) {
61      call_vectored_isr(frame, cause, (void *)AU1X00_IC0_ADDR);
62  }
63
64  /* Interrupt controller 1 */
65  if ( cause & 0x30 ) {
66      call_vectored_isr(frame, cause, (void *)AU1X00_IC1_ADDR);
67  }
68
69  /* SW[0] */
70  if ( cause & 0x01 )
71      CALL_ISR( AU1X00_IRQ_SW0, frame );
72
73  /* SW[1] */
74  if ( cause & 0x02 )
75      CALL_ISR( AU1X00_IRQ_SW1, frame );
76}
77
78void mips_default_isr( int vector )
79{
80  unsigned int sr;
81  unsigned int cause;
82
83  mips_get_sr( sr );
84  mips_get_cause( cause );
85
86  printk( "Unhandled isr exception: vector 0x%02x, cause 0x%08X, sr 0x%08X\n",
87      vector, cause, sr );
88  rtems_fatal_error_occurred(1);
89}
90
91static void call_vectored_isr(
92    CPU_Interrupt_frame *frame,
93    uint32_t cause,
94    void *ctrlr
95    )
96{
97    uint32_t src;
98    uint32_t mask;
99    int index;
100
101    /* get mask register */
102    mask = AU1X00_IC_MASKRD(ctrlr);
103
104    /* check request 0 */
105    src = AU1X00_IC_REQ0INT(ctrlr);
106    src = src & mask;
107    index = 0;
108    while (src) {
109        /* check LSB */
110        if (src & 1) {
111            /* clear rising/falling edge detects */
112            AU1X00_IC_RISINGCLR(ctrlr) = (1 << index);
113            AU1X00_IC_FALLINGCLR(ctrlr) = (1 << index);
114            au_sync();
115            CALL_ISR(AU1X00_IRQ_IC0_BASE + index, frame);
116        }
117        index ++;
118
119        /* shift, and make sure MSB is clear */
120        src = (src >> 1) & 0x7fffffff;
121    }
122
123    /* check request 1 */
124    src = AU1X00_IC_REQ1INT(ctrlr);
125    src = src & mask;
126    index = 0;
127    while (src) {
128        /* check LSB */
129        if (src & 1) {
130            /* clear rising/falling edge detects */
131            AU1X00_IC_RISINGCLR(ctrlr) = (1 << index);
132            AU1X00_IC_FALLINGCLR(ctrlr) = (1 << index);
133            au_sync();
134            CALL_ISR(AU1X00_IRQ_IC0_BASE + index, frame);
135        }
136        index ++;
137
138        /* shift, and make sure MSB is clear */
139        src = (src >> 1) & 0x7fffffff;
140    }
141}
142
143/* Generate a software interrupt */
144int assert_sw_irq(uint32_t irqnum)
145{
146    uint32_t cause;
147
148    if (irqnum <= 1) {
149        mips_get_cause(cause);
150        cause = cause | ((irqnum + 1) << CAUSE_IPSHIFT);
151        mips_set_cause(cause);
152
153        return irqnum;
154    } else {
155        return -1;
156    }
157}
158
159/* Clear a software interrupt */
160int negate_sw_irq(uint32_t irqnum)
161{
162    uint32_t cause;
163
164    if (irqnum <= 1) {
165        mips_get_cause(cause);
166        cause = cause & ~((irqnum + 1) << CAUSE_IPSHIFT);
167        mips_set_cause(cause);
168
169        return irqnum;
170    } else {
171        return -1;
172    }
173}
Note: See TracBrowser for help on using the repository browser.