source: soft/giet_vm/giet_drivers/mwr_driver.c @ 616

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

1) Introduce a new driver "sdc_driver" for SD Card uding directly the 4 bits SD bus.
2) Improve the debug for all IOC drivers (debug activated only if _get_time() > GIET_DEBUG_IOC_DRIVER).

File size: 8.6 KB
RevLine 
[258]1///////////////////////////////////////////////////////////////////////////////////
2// File     : mwr_driver.c
[518]3// Date     : 27/02/2015
[258]4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7
8#include <giet_config.h>
[320]9#include <hard_config.h>
[518]10#include <mapping_info.h>
[258]11#include <mwr_driver.h>
[563]12#include <xcu_driver.h>
[554]13#include <ctx_handler.h>
[258]14#include <utils.h>
[529]15#include <kernel_locks.h>
[456]16#include <tty0.h>
[518]17#include <io.h>
[258]18
[263]19#if !defined(X_SIZE)
20# error: You must define X_SIZE in the hard_config.h file
[258]21#endif
22
[263]23#if !defined(Y_SIZE)
24# error: You must define X_SIZE in the hard_config.h file
[258]25#endif
26
[263]27#if !defined(X_WIDTH)
28# error: You must define X_WIDTH in the hard_config.h file
29#endif
30
31#if !defined(Y_WIDTH)
32# error: You must define X_WIDTH in the hard_config.h file
33#endif
34
[320]35#if !defined(SEG_MWR_BASE)
36# error: You must define SEG_MWR_BASE in the hard_config.h file
37#endif
38
[333]39#if !defined(PERI_CLUSTER_INCREMENT)
40# error: You must define PERI_CLUSTER_INCREMENT in the hard_config.h file
[320]41#endif
42
[518]43
44/////////////////////////////////////////////////////////////////////////////
[554]45//      Global variables (all arrays are indexed by the cluster index)
[529]46/////////////////////////////////////////////////////////////////////////////
47
[554]48// Lock protecting exclusive access
[529]49__attribute__((section(".kdata")))
50simple_lock_t  _coproc_lock[X_SIZE*Y_SIZE];
51
[554]52// Coprocessor type
[529]53__attribute__((section(".kdata")))
[554]54unsigned int  _coproc_type[X_SIZE*Y_SIZE];
[529]55
[554]56// coprocessor characteristics
57__attribute__((section(".kdata")))
58unsigned int   _coproc_info[X_SIZE*Y_SIZE];
59
60// Coprocessor running mode
61__attribute__((section(".kdata")))
62unsigned int  _coproc_mode[X_SIZE*Y_SIZE];
63
64// coprocessor status (for MODE_DMA_IRQ)
65__attribute__((section(".kdata")))
66unsigned int   _coproc_error[X_SIZE*Y_SIZE];
67
68// descheduled task gtid (for MODE_DMA_IRQ)
69__attribute__((section(".kdata")))
70unsigned int   _coproc_gtid[X_SIZE*Y_SIZE];
71
[529]72/////////////////////////////////////////////////////////////////////////////
[518]73// This function returns the value contained in a private register
74// of the coprocessor contained in cluster "cluster_xy".
75/////////////////////////////////////////////////////////////////////////////
76unsigned int _mwr_get_coproc_register( unsigned int cluster_xy, // cluster
77                                       unsigned int index )     // register
[258]78{
[518]79    unsigned int vaddr =
80        SEG_MWR_BASE + 
81        (cluster_xy * PERI_CLUSTER_INCREMENT) + 
82        (index << 2);
[258]83
[518]84    return ioread32( (void*)vaddr );
85}
[258]86
[518]87/////////////////////////////////////////////////////////////////////////////
88// This function sets a new value in a private register
89// of the coprocessor contained in cluster "clustenr_xy".
90/////////////////////////////////////////////////////////////////////////////
91void _mwr_set_coproc_register( unsigned int cluster_xy,   // cluster index
92                               unsigned int index,        // register index
93                               unsigned int value )       // writte value
94{
95    unsigned int vaddr =
96        SEG_MWR_BASE + 
97        (cluster_xy * PERI_CLUSTER_INCREMENT) +
98        (index << 2);
99       
100    iowrite32( (void*)vaddr, value );
101}
[258]102
[518]103/////////////////////////////////////////////////////////////////////////////
104// This function returns the value contained in a channel register
105// defined by the "index" and "channel" arguments, in the MWMR_DMA component
106// contained in cluster "cluster_xy".
107/////////////////////////////////////////////////////////////////////////////
108unsigned int _mwr_get_channel_register( unsigned int cluster_xy, // cluster
109                                        unsigned int channel,    // channel
110                                        unsigned int index )     // register
111{
112    unsigned int vaddr =
113        SEG_MWR_BASE + 
114        (cluster_xy * PERI_CLUSTER_INCREMENT) + 
[554]115        ((channel + 1) * (MWR_CHANNEL_SPAN << 2)) +
[518]116        (index << 2);
[258]117
[518]118    return ioread32( (void*)vaddr );
119}
[258]120
[518]121/////////////////////////////////////////////////////////////////////////////
122// This function sets a new value in a channel register
123// defined by the "index" and "channel") arguments, in the MWMR_DMA component
124// contained in cluster "cluster_xy".
[554]125////////////////////////////////////////////////////////////////////////////yy
[518]126void _mwr_set_channel_register( unsigned int cluster_xy,  // cluster index
127                                unsigned int channel,     // channel index
128                                unsigned int index,       // register index
129                                unsigned int value )      // written value
130{
131    unsigned int vaddr =
132        SEG_MWR_BASE + 
133        (cluster_xy * PERI_CLUSTER_INCREMENT) +
[554]134        ((channel + 1) * (MWR_CHANNEL_SPAN << 2)) +
[518]135        (index << 2);
136       
137    iowrite32( (void*)vaddr, value );
[258]138}
139
[554]140////////////////////////////////////////////////////////////////////////////yy
141// This Interrupt service routine is called in two situations:
142// - The MWR_DMA component is running in MODE_DMA_IRQ, and all the
143//   communication channels have successfully completed.
144// - The MWR_DMA component is running in any mode, and at least one
145//   communication channel is reporting a VCI error.
146////////////////////////////////////////////////////////////////////////////yy
147void _mwr_isr( unsigned int irq_type,  // unused : should be HWI
[518]148               unsigned int irq_id,    // index returned by XCU
[554]149               unsigned int bloup )    // unused : should be 0         
[518]150{
[554]151    // get coprocessor coordinates and characteristics
152    // the processor executing the ISR an the coprocessor
153    // are in the same cluster
[518]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);
[554]158    unsigned int cluster_id = x * Y_SIZE + y;
159    unsigned int info       = _coproc_info[cluster_id];
160    unsigned int nb_to      = info & 0xFF;
161    unsigned int nb_from    = (info>>8) & 0xFF;
162    unsigned int channel;
163    unsigned int status;
164    unsigned int error = 0;
[258]165
[554]166    // check status, report errors and reset all channels
167    for ( channel = 0 ; channel < (nb_to + nb_from) ; channel++ )
168    {
169        status = _mwr_get_channel_register( cluster_xy , channel , MWR_CHANNEL_STATUS );
[518]170
[554]171        if ( status == MWR_CHANNEL_BUSY )          // strange => report error
172        {
173            _printf("\n[GIET_ERROR] in _mwr_isr() : channel %d is busy\n", channel );
174            error = 1;
175        }
176        else if ( status == MWR_CHANNEL_ERROR_DATA ) 
177        {
178            _printf("\n[GIET_ERROR] in _mwr_isr() : DATA_ERROR / channel %d\n", channel );
179            error = 1;
180        }
181        else if ( status == MWR_CHANNEL_ERROR_LOCK )
182        {
183            _printf("\n[GIET_ERROR] in _mwr_isr() : LOCK_ERROR / channel %d\n", channel );
184            error = 1;
185        }
186        else if ( status == MWR_CHANNEL_ERROR_DESC )
187        {
188            _printf("\n[GIET_ERROR] in _mwr_isr() : DESC_ERROR / channel %d\n", channel );
189            error = 1;
190        }
[518]191
[554]192        // reset channel
193        _mwr_set_channel_register( cluster_xy , channel , MWR_CHANNEL_RUNNING , 0 ); 
194    }
195
196    // register error
197    _coproc_error[cluster_id]  = error;
198
199    // identify task waiting on coprocessor completion
200    // this task can run in a remote cluster
201    unsigned int gtid           = _coproc_gtid[cluster_id];
202    unsigned int remote_procid  = gtid>>16;
203    unsigned int ltid           = gtid & 0xFFFF;
204    unsigned int remote_cluster = remote_procid >> P_WIDTH;
205    unsigned int remote_x       = remote_cluster >> Y_WIDTH;
206    unsigned int remote_y       = remote_cluster & ((1<<Y_WIDTH)-1);
207    unsigned int remote_p       = remote_procid & ((1<<P_WIDTH)-1);
208
209    // re-activates sleeping task
210    _set_task_slot( remote_x,
211                    remote_y,
212                    remote_p,
213                    ltid,       
214                    CTX_RUN_ID,  // CTX_RUN slot
215                    1 );         // running value
216
217    // send a WAKUP WTI to processor running the sleeping task
218    _xcu_send_wti( remote_cluster,   
219                   remote_p, 
220                   0 );          // don't force context switch
221
222#if GIET_DEBUG_COPROC 
[563]223unsigned int p          = gpid & ((1<<P_WIDTH)-1);
[554]224_printf("\n[GIET DEBUG COPROC] P[%d,%d,%d] executes _mwr_isr() at cycle %d\n"
225        "  for task %d running on P[%d,%d,%d] / error = %d\n",
226        x , y , p , _get_proctime() , ltid , remote_x , remote_y , remote_p , error );
227#endif
[518]228}
229
230
231
[258]232// Local Variables:
233// tab-width: 4
234// c-basic-offset: 4
235// c-file-offsets:((innamespace . 0)(inline-open . 0))
236// indent-tabs-mode: nil
237// End:
238// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
239
Note: See TracBrowser for help on using the repository browser.