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

Last change on this file since 512 was 494, checked in by alain, 10 years ago

Introduce a fully parallel procedure for the kernel initialisation.

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