source: soft/giet_vm/giet_kernel/irq_handler.c @ 520

Last change on this file since 520 was 519, checked in by alain, 10 years ago

Introducing support for hardware coprocessors
using the vci_mwmr_dma components.

  • Property svn:executable set to *
File size: 8.1 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////
2// File     : irq_handler.c
3// Date     : 01/04/2012
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7
8#include <giet_config.h>
9#include <irq_handler.h>
10#include <sys_handler.h>
11#include <ctx_handler.h>
12#include <tim_driver.h>
13#include <xcu_driver.h>
14#include <tty_driver.h>
15#include <nic_driver.h>
16#include <cma_driver.h>
17#include <mmc_driver.h>
18#include <bdv_driver.h>
19#include <dma_driver.h>
20#include <spi_driver.h>
21#include <mapping_info.h>
22#include <utils.h>
23#include <tty0.h>
24
25#if NB_TIM_CHANNELS
26extern volatile unsigned char _user_timer_event[NB_TIM_CHANNELS] ;
27#endif
28
29/////////////////////////////////////////////////////////////////////////
30// These ISR_TYPE names for display must be consistent with values in
31// irq_handler.h / mapping.py / xml_driver.c
32/////////////////////////////////////////////////////////////////////////
33__attribute__((section(".kdata")))
34char* _isr_type_name[] = { "DEFAULT",
35                           "TICK"   ,
36                           "TTY_RX" ,
37                           "TTY_TX" ,
38                           "BDV"    ,
39                           "TIMER"  ,
40                           "WAKUP"  ,
41                           "NIC_RX" ,
42                           "NIC_TX" ,
43                           "CMA"    ,
44                           "MMC"    ,
45                           "DMA"    ,
46                           "SPI"    ,
47                           "MWR"    };
48/////////////////
49void _irq_demux() 
50{
51    unsigned int gpid           = _get_procid();
52    unsigned int cluster_xy     = gpid >> P_WIDTH;
53    unsigned int x              = cluster_xy >> Y_WIDTH;
54    unsigned int y              = cluster_xy & ((1<<Y_WIDTH)-1);
55    unsigned int lpid           = gpid & ((1<<P_WIDTH)-1);
56    unsigned int irq_id;
57    unsigned int irq_type;
58
59    // get the highest priority active IRQ index
60    unsigned int icu_out_index = lpid * IRQ_PER_PROCESSOR;
61
62    _xcu_get_index( cluster_xy, icu_out_index, &irq_id, &irq_type );
63
64    if (irq_id < 32) 
65    {
66        static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
67        unsigned int        entry = 0;
68        unsigned int        isr_type;
69        unsigned int        channel;
70
71        if      (irq_type == IRQ_TYPE_HWI) entry = psched->hwi_vector[irq_id];
72        else if (irq_type == IRQ_TYPE_PTI) entry = psched->pti_vector[irq_id];
73        else if (irq_type == IRQ_TYPE_WTI) entry = psched->wti_vector[irq_id];
74        else
75        {
76            _printf("\n[GIET ERROR] illegal irq_type in irq_demux()\n");
77            _exit();
78        }
79
80        isr_type   = (entry    ) & 0x0000FFFF;
81        channel    = (entry>>16) & 0x00007FFF;
82
83#if GIET_DEBUG_IRQS // we don't take the TTY lock to avoid deadlocks
84char* irq_type_str[] = { "HWI", "WTI", "PTI" }; 
85_puts("\n[IRQS DEBUG] Processor[");
86_putd(x);
87_puts(",");
88_putd(y);
89_puts(",");
90_putd(lpid);
91_puts("] enters _irq_demux() at cycle ");
92_putd(_get_proctime() );
93_puts("\n  ");
94_puts(irq_type_str[irq_type] );
95_puts(" : irq_id = ");
96_putd(irq_id);
97_puts(" / isr_type = ");
98_putd(isr_type);
99_puts(" / channel = ");
100_putd(channel);
101_puts("\n");
102#endif
103
104        // ISR call
105        if      ( isr_type == ISR_TICK   ) _isr_tick   ( irq_type, irq_id, channel );
106        else if ( isr_type == ISR_WAKUP  ) _isr_wakup  ( irq_type, irq_id, channel );
107        else if ( isr_type == ISR_BDV    ) _bdv_isr    ( irq_type, irq_id, channel );
108        else if ( isr_type == ISR_CMA    ) _cma_isr    ( irq_type, irq_id, channel );
109        else if ( isr_type == ISR_TTY_RX ) _tty_rx_isr ( irq_type, irq_id, channel );
110        else if ( isr_type == ISR_TTY_TX ) _tty_tx_isr ( irq_type, irq_id, channel );
111        else if ( isr_type == ISR_NIC_RX ) _nic_rx_isr ( irq_type, irq_id, channel );
112        else if ( isr_type == ISR_NIC_TX ) _nic_tx_isr ( irq_type, irq_id, channel );
113        else if ( isr_type == ISR_TIMER  ) _timer_isr  ( irq_type, irq_id, channel );
114        else if ( isr_type == ISR_MMC    ) _mmc_isr    ( irq_type, irq_id, channel );
115        else if ( isr_type == ISR_DMA    ) _dma_isr    ( irq_type, irq_id, channel );
116        else if ( isr_type == ISR_SPI    ) _spi_isr    ( irq_type, irq_id, channel );
117        else if ( isr_type == ISR_MWR    ) _mwr_isr    ( irq_type, irq_id, channel );
118        else
119        {
120            _printf("\n[GIET ERROR] in _irq_demux() :"
121                    " illegal ISR type on processor[%d,%d,%d] at cycle %d\n"
122                    " - irq_type = %d\n"
123                    " - irq_id   = %d\n"
124                    " - isr_type = %x\n",
125                    x, y, lpid, _get_proctime(), irq_type, irq_id, isr_type );
126        }
127    }
128    else   // no interrupt active
129    {
130        _isr_default();
131    } 
132}
133
134///////////////////
135void _isr_default()
136{
137    unsigned int gpid       = _get_procid();
138    unsigned int cluster_xy = gpid >> P_WIDTH;
139    unsigned int x          = cluster_xy >> Y_WIDTH;
140    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
141    unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
142
143    _printf("\n[GIET WARNING] IRQ handler called but no active IRQ "
144            "on processor[%d,%d,%d] at cycle %d\n",
145            x, y, lpid, _get_proctime() );
146}
147
148
149////////////////////////////////////////////////////////////
150void _isr_wakup( unsigned int irq_type,   // HWI / WTI / PTI
151                 unsigned int irq_id,     // index returned by ICU
152                 unsigned int channel )   // unused
153{
154    unsigned int gpid       = _get_procid();
155    unsigned int cluster_xy = gpid >> P_WIDTH;
156    unsigned int x          = cluster_xy >> Y_WIDTH;
157    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
158    unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
159
160    unsigned int task       = _get_current_task_id();
161    unsigned int value;
162
163    if ( irq_type != IRQ_TYPE_WTI )
164    {
165        _puts("[GIET ERROR] _isr_wakup() not called by a WTI on processor[");
166        _putd( x );
167        _puts(",");
168        _putd( y );
169        _puts(",");
170        _putd( lpid );
171        _puts("] at cycle ");
172        _putd( _get_proctime() );
173        _puts("\n");
174        _exit();
175    }
176
177    // get mailbox value and acknowledge WTI
178    _xcu_get_wti_value( cluster_xy, irq_id, &value );
179
180#if GIET_DEBUG_IRQS // we don't take the TTY lock to avoid deadlocks
181_puts("\n[IRQS DEBUG] Processor[");
182_putd( x );
183_puts(",");
184_putd( y );
185_puts(",");
186_putd( lpid );
187_puts("] enters _isr_wakup() at cycle ");
188_putd( _get_proctime() );
189_puts("\n  WTI / mailbox data = ");
190_putx( value );
191_puts(" / current task index = ");
192_putd( task );
193_puts("\n  ");
194#endif
195
196    // context swich if required
197    if ( (task == IDLE_TASK_INDEX) || (value != 0) ) _ctx_switch();
198} // end _isr_wakup
199
200///////////////////////////////////////////////////////////
201void _isr_tick( unsigned int irq_type,   // HWI / WTI / PTI
202                unsigned int irq_id,     // index returned by ICU
203                unsigned int channel )   // channel index if HWI
204{
205    unsigned int gpid       = _get_procid();
206    unsigned int cluster_xy = gpid >> P_WIDTH;
207    unsigned int x          = cluster_xy >> Y_WIDTH;
208    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
209    unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
210
211    if ( irq_type != IRQ_TYPE_PTI )
212    {
213        _puts("[GIET ERROR] _isr_tick() not called by a PTI on processor[");
214        _putd( x );
215        _puts(",");
216        _putd( y );
217        _puts(",");
218        _putd( lpid );
219        _puts("] at cycle ");
220        _putd( _get_proctime() );
221        _puts("\n");
222        _exit();
223    }
224
225    // acknowledge PTI
226    _xcu_timer_reset_irq( cluster_xy, irq_id );
227
228#if GIET_DEBUG_IRQS  // we don't take the TTY lock to avoid deadlock
229_puts("\n[IRQS DEBUG] Processor[");
230_putd( x );
231_puts(",");
232_putd( y );
233_puts(",");
234_putd( lpid );
235_puts("] enters _isr_tick() at cycle ");
236_putd( _get_proctime() );
237_puts("\n  ");
238#endif
239
240    // context switch
241    _ctx_switch();
242}  // end _isr_tick
243
244
245// Local Variables:
246// tab-width: 4
247// c-basic-offset: 4
248// c-file-offsets:((innamespace . 0)(inline-open . 0))
249// indent-tabs-mode: nil
250// End:
251// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
252
Note: See TracBrowser for help on using the repository browser.