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

4.115
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

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