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

Last change on this file since 609 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
Line 
1///////////////////////////////////////////////////////////////////////////////////
2// File     : mwr_driver.c
3// Date     : 27/02/2015
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7
8#include <giet_config.h>
9#include <hard_config.h>
10#include <mapping_info.h>
11#include <mwr_driver.h>
12#include <xcu_driver.h>
13#include <ctx_handler.h>
14#include <utils.h>
15#include <kernel_locks.h>
16#include <tty0.h>
17#include <io.h>
18
19#if !defined(X_SIZE)
20# error: You must define X_SIZE in the hard_config.h file
21#endif
22
23#if !defined(Y_SIZE)
24# error: You must define X_SIZE in the hard_config.h file
25#endif
26
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
35#if !defined(SEG_MWR_BASE)
36# error: You must define SEG_MWR_BASE in the hard_config.h file
37#endif
38
39#if !defined(PERI_CLUSTER_INCREMENT)
40# error: You must define PERI_CLUSTER_INCREMENT in the hard_config.h file
41#endif
42
43
44/////////////////////////////////////////////////////////////////////////////
45//      Global variables (all arrays are indexed by the cluster index)
46/////////////////////////////////////////////////////////////////////////////
47
48// Lock protecting exclusive access
49__attribute__((section(".kdata")))
50simple_lock_t  _coproc_lock[X_SIZE*Y_SIZE];
51
52// Coprocessor type
53__attribute__((section(".kdata")))
54unsigned int  _coproc_type[X_SIZE*Y_SIZE];
55
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
72/////////////////////////////////////////////////////////////////////////////
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
78{
79    unsigned int vaddr =
80        SEG_MWR_BASE + 
81        (cluster_xy * PERI_CLUSTER_INCREMENT) + 
82        (index << 2);
83
84    return ioread32( (void*)vaddr );
85}
86
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}
102
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) + 
115        ((channel + 1) * (MWR_CHANNEL_SPAN << 2)) +
116        (index << 2);
117
118    return ioread32( (void*)vaddr );
119}
120
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".
125////////////////////////////////////////////////////////////////////////////yy
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) +
134        ((channel + 1) * (MWR_CHANNEL_SPAN << 2)) +
135        (index << 2);
136       
137    iowrite32( (void*)vaddr, value );
138}
139
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
148               unsigned int irq_id,    // index returned by XCU
149               unsigned int bloup )    // unused : should be 0         
150{
151    // get coprocessor coordinates and characteristics
152    // the processor executing the ISR an the coprocessor
153    // are in the same cluster
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 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;
165
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 );
170
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        }
191
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 
223unsigned int p          = gpid & ((1<<P_WIDTH)-1);
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
228}
229
230
231
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.