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

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

Introducing dynamic allocation of peripheral channels (NIC, TTY, CMA, TIM)
Intoducing a kernel function for all system calls: No more direct call
to the peripheral drivers.

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