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
RevLine 
[258]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>
[294]15#include <nic_driver.h>
16#include <cma_driver.h>
[297]17#include <mmc_driver.h>
[294]18#include <bdv_driver.h>
[258]19#include <dma_driver.h>
[322]20#include <spi_driver.h>
[281]21#include <mapping_info.h>
[258]22#include <utils.h>
[459]23#include <tty0.h>
[258]24
25#if NB_TIM_CHANNELS
[440]26extern volatile unsigned char _user_timer_event[NB_TIM_CHANNELS] ;
[258]27#endif
28
[519]29/////////////////////////////////////////////////////////////////////////
30// These ISR_TYPE names for display must be consistent with values in
31// irq_handler.h / mapping.py / xml_driver.c
32/////////////////////////////////////////////////////////////////////////
[494]33__attribute__((section(".kdata")))
[440]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"    ,
[519]46                           "SPI"    ,
47                           "MWR"    };
[440]48/////////////////
[258]49void _irq_demux() 
50{
[294]51    unsigned int gpid           = _get_procid();
[428]52    unsigned int cluster_xy     = gpid >> P_WIDTH;
[294]53    unsigned int x              = cluster_xy >> Y_WIDTH;
54    unsigned int y              = cluster_xy & ((1<<Y_WIDTH)-1);
[428]55    unsigned int lpid           = gpid & ((1<<P_WIDTH)-1);
[258]56    unsigned int irq_id;
[294]57    unsigned int irq_type;
[258]58
59    // get the highest priority active IRQ index
[294]60    unsigned int icu_out_index = lpid * IRQ_PER_PROCESSOR;
[258]61
[294]62    _xcu_get_index( cluster_xy, icu_out_index, &irq_id, &irq_type );
[258]63
64    if (irq_id < 32) 
65    {
[294]66        static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
[346]67        unsigned int        entry = 0;
[294]68        unsigned int        isr_type;
69        unsigned int        channel;
[258]70
[294]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
[258]75        {
[294]76            _printf("\n[GIET ERROR] illegal irq_type in irq_demux()\n");
77            _exit();
[258]78        }
[294]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
[310]84char* irq_type_str[] = { "HWI", "WTI", "PTI" }; 
[294]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 );
[297]114        else if ( isr_type == ISR_MMC    ) _mmc_isr    ( irq_type, irq_id, channel );
[322]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 );
[519]117        else if ( isr_type == ISR_MWR    ) _mwr_isr    ( irq_type, irq_id, channel );
[294]118        else
[258]119        {
[310]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 );
[258]126        }
127    }
[294]128    else   // no interrupt active
129    {
130        _isr_default();
131    } 
[258]132}
133
[440]134///////////////////
[294]135void _isr_default()
[258]136{
[294]137    unsigned int gpid       = _get_procid();
[428]138    unsigned int cluster_xy = gpid >> P_WIDTH;
[294]139    unsigned int x          = cluster_xy >> Y_WIDTH;
140    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
[428]141    unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
[258]142
[322]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() );
[258]146}
147
148
[440]149////////////////////////////////////////////////////////////
[294]150void _isr_wakup( unsigned int irq_type,   // HWI / WTI / PTI
151                 unsigned int irq_id,     // index returned by ICU
152                 unsigned int channel )   // unused
[258]153{
[428]154    unsigned int gpid       = _get_procid();
155    unsigned int cluster_xy = gpid >> P_WIDTH;
[294]156    unsigned int x          = cluster_xy >> Y_WIDTH;
157    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
[428]158    unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
159
[294]160    unsigned int task       = _get_current_task_id();
161    unsigned int value;
[258]162
[294]163    if ( irq_type != IRQ_TYPE_WTI )
[258]164    {
[294]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();
[258]175    }
176
[294]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  ");
[258]194#endif
195
[294]196    // context swich if required
197    if ( (task == IDLE_TASK_INDEX) || (value != 0) ) _ctx_switch();
[440]198} // end _isr_wakup
[258]199
[440]200///////////////////////////////////////////////////////////
[294]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
[258]204{
[428]205    unsigned int gpid       = _get_procid();
206    unsigned int cluster_xy = gpid >> P_WIDTH;
[440]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);
[258]210
[440]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    }
[258]224
[440]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
[294]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  ");
[258]238#endif
239
[294]240    // context switch
[258]241    _ctx_switch();
[440]242}  // end _isr_tick
[258]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.