source: soft/giet_vm/giet_drivers/xcu_driver.c @ 487

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

Defining the NIC and CMA drivers (validated by the classif application).
Updating other drivers to comply with the new tty0 common file.

File size: 9.4 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////
2// File     : xcu_driver.c
3// Date     : 23/05/2013
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7
8#include <hard_config.h>
9#include <giet_config.h>
10#include <xcu_driver.h>
11#include <tty0.h>
12#include <mapping_info.h>
13#include <utils.h>
14#include <io.h>
15
16#if !defined(X_SIZE)
17# error: You must define X_SIZE in the hard_config.h file
18#endif
19
20#if !defined(Y_SIZE)
21# error: You must define X_SIZE in the hard_config.h file
22#endif
23
24#if !defined(X_WIDTH)
25# error: You must define X_WIDTH in the hard_config.h file
26#endif
27
28#if !defined(Y_WIDTH)
29# error: You must define X_WIDTH in the hard_config.h file
30#endif
31
32#if !defined(NB_PROCS_MAX)
33# error: You must define NB_PROCS_MAX in the hard_config.h file
34#endif
35
36#if !defined( USE_XCU )
37# error: You must define USE_XCU in the hard_config.h file
38#endif
39
40#if !defined( SEG_XCU_BASE )
41# error: You must define SEG_XCU_BASE in the hard_config.h file
42#endif
43
44#if !defined( PERI_CLUSTER_INCREMENT )
45# error: You must define PERI_CLUSTER_INCREMENT in the hard_config.h file
46#endif
47
48///////////////////////////////////////////////////////////////////////////////
49// This low level function returns the value contained in register "index"
50// in the XCU component contained in cluster "cluster_xy"
51///////////////////////////////////////////////////////////////////////////////
52static
53unsigned int _xcu_get_register( unsigned int cluster_xy, // cluster index
54                                unsigned int func,       // function index
55                                unsigned int index )     // register index
56{
57    unsigned int vaddr =
58        SEG_XCU_BASE + 
59        (cluster_xy * PERI_CLUSTER_INCREMENT) +
60        (XCU_REG(func, index) << 2);
61
62    return ioread32( (void*)vaddr );
63}
64
65///////////////////////////////////////////////////////////////////////////////
66// This low level function sets a new value in register "index"
67// in the XCU component contained in cluster "cluster_xy"
68///////////////////////////////////////////////////////////////////////////////
69static
70void _xcu_set_register( unsigned int cluster_xy,       // cluster index
71                        unsigned int func,             // func index
72                        unsigned int index,            // register index
73                        unsigned int value )           // value to be written
74{
75    unsigned int vaddr =
76        SEG_XCU_BASE + 
77        (cluster_xy * PERI_CLUSTER_INCREMENT) +
78        (XCU_REG(func, index) << 2);
79       
80    iowrite32( (void*)vaddr, value );
81}
82
83////////////////////////////////////////////
84void _xcu_set_mask( unsigned int cluster_xy, 
85                    unsigned int channel, 
86                    unsigned int value,
87                    unsigned int irq_type ) 
88{
89#if USE_XCU
90    // parameters checking
91    unsigned int x = cluster_xy >> Y_WIDTH;
92    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
93    if (x >= X_SIZE)                                   _exit(); 
94    if (y >= Y_SIZE)                                   _exit(); 
95    if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit(); 
96
97    unsigned int func = 0;
98    if      (irq_type == IRQ_TYPE_PTI) func = XCU_MSK_PTI_ENABLE;
99    else if (irq_type == IRQ_TYPE_WTI) func = XCU_MSK_WTI_ENABLE;
100    else if (irq_type == IRQ_TYPE_HWI) func = XCU_MSK_HWI_ENABLE;
101    else
102    { 
103        _puts("[GIET ERROR] _xcu_set_mask() receives illegal IRQ type\n");
104        _exit();
105    }
106
107    _xcu_set_register(cluster_xy, func, channel, value);
108
109#else
110    _puts("[GIET ERROR] _xcu_set_mask() should not be used if USE_XCU not set\n");
111    _exit();
112#endif
113}
114
115/////////////////////////////////////////////
116void _xcu_get_index( unsigned int cluster_xy, 
117                     unsigned int channel,   
118                     unsigned int * index, 
119                     unsigned int * irq_type )
120{
121#if USE_XCU
122    // parameters checking
123    unsigned int x = cluster_xy >> Y_WIDTH;
124    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
125    if (x >= X_SIZE)                                   _exit(); 
126    if (y >= Y_SIZE)                                   _exit(); 
127    if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit(); 
128
129    unsigned int prio = _xcu_get_register(cluster_xy, XCU_PRIO, channel);
130    unsigned int pti_ok = (prio & 0x00000001);
131    unsigned int hwi_ok = (prio & 0x00000002);
132    unsigned int wti_ok = (prio & 0x00000004);
133    unsigned int pti_id = (prio & 0x00001F00) >> 8;
134    unsigned int hwi_id = (prio & 0x001F0000) >> 16;
135    unsigned int wti_id = (prio & 0x1F000000) >> 24;
136    if      (pti_ok)
137    {
138        *index    = pti_id;
139        *irq_type = IRQ_TYPE_PTI;
140    }
141    else if (hwi_ok)
142    {
143        *index    = hwi_id;
144        *irq_type = IRQ_TYPE_HWI;
145    }
146    else if (wti_ok) 
147    {
148        *index    = wti_id;
149        *irq_type = IRQ_TYPE_WTI;
150    }
151    else 
152    {
153        *index = 32;
154    }
155 
156#else
157    _puts("[GIET ERROR] _xcu_get_index should not be used if USE_XCU is not set\n");
158    _exit();
159#endif
160}
161
162////////////////////////////////////////////
163void _xcu_send_wti( unsigned int cluster_xy,
164                    unsigned int wti_index,
165                    unsigned int wdata )
166{ 
167#if USE_XCU
168    // parameters checking
169    unsigned int x = cluster_xy >> Y_WIDTH;
170    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
171    if (x >= X_SIZE)               _exit(); 
172    if (y >= Y_SIZE)               _exit(); 
173    if (wti_index >= 32)           _exit(); 
174
175    _xcu_set_register(cluster_xy, XCU_WTI_REG, wti_index, wdata);
176
177#else
178    _puts("[GIET ERROR] _xcu_send_wti() should not be used if USE_XCU is not set\n");
179    _exit();
180#endif
181} 
182
183///////////////////////////////////////////////////
184void _xcu_get_wti_value( unsigned int   cluster_xy,
185                         unsigned int   wti_index,
186                         unsigned int * value )
187{
188#if USE_XCU
189    // parameters checking
190    unsigned int x = cluster_xy >> Y_WIDTH;
191    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
192    if (x >= X_SIZE)               _exit(); 
193    if (y >= Y_SIZE)               _exit(); 
194    if (wti_index >= 32)           _exit(); 
195 
196    *value = _xcu_get_register(cluster_xy, XCU_WTI_REG, wti_index);
197
198#else
199    _puts("[GIET ERROR] in _xcu_get_wti_value() USE_XCU is not set\n");
200    _exit();
201#endif
202}
203
204////////////////////////////////////////////////////
205void _xcu_get_wti_address( unsigned int   wti_index,
206                           unsigned int * address )
207{
208#if USE_XCU
209    if (wti_index >= 32)           _exit(); 
210 
211    *address = SEG_XCU_BASE + (XCU_REG(XCU_WTI_REG, wti_index)<<2); 
212
213#else
214    _puts("[GIET ERROR] in _xcu_get_wti_address() USE_XCU is not set\n");
215    _exit();
216#endif
217}
218
219///////////////////////////////////////////////
220void _xcu_timer_start( unsigned int cluster_xy,
221                       unsigned int pti_index,
222                       unsigned int period )
223{
224#if USE_XCU
225    // parameters checking
226    unsigned int x = cluster_xy >> Y_WIDTH;
227    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
228    if (x >= X_SIZE)             _exit(); 
229    if (y >= Y_SIZE)             _exit(); 
230
231    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, period);
232
233#else
234    _puts("[GIET ERROR] in _xcu_timer_start() USE_XCU is not set\n");
235    _exit();
236#endif
237}
238
239//////////////////////////////////////////////
240void _xcu_timer_stop( unsigned int cluster_xy, 
241                      unsigned int pti_index) 
242{
243#if USE_XCU
244    // parameters checking
245    unsigned int x = cluster_xy >> Y_WIDTH;
246    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
247    if (x >= X_SIZE)             _exit(); 
248    if (y >= Y_SIZE)             _exit(); 
249
250    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, 0);
251
252#else
253    _puts("[GIET ERROR] in _xcu_timer_stop() USE_XCU is not set\n");
254    _exit();
255#endif
256}
257
258///////////////////////////////////////////////////////////
259unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy, 
260                                   unsigned int pti_index ) 
261{
262#if USE_XCU
263    // parameters checking
264    unsigned int x = cluster_xy >> Y_WIDTH;
265    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
266    if (x >= X_SIZE)             _exit(); 
267    if (y >= Y_SIZE)             _exit(); 
268
269    // This return value is not used / avoid a compilation warning.
270    return _xcu_get_register(cluster_xy, XCU_PTI_ACK, pti_index);
271
272#else
273    _puts("[GIET ERROR] in _xcu_timer_reset_irq() USE_XCU is not set\n");
274    _exit();
275    return 0;
276#endif
277}
278
279///////////////////////////////////////////////////
280void _xcu_timer_reset_cpt( unsigned int cluster_xy, 
281                           unsigned int pti_index ) 
282{
283#if USE_XCU
284    // parameters checking
285    unsigned int x = cluster_xy >> Y_WIDTH;
286    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
287    if (x >= X_SIZE)             _exit(); 
288    if (y >= Y_SIZE)             _exit(); 
289
290    unsigned int per = _xcu_get_register(cluster_xy, XCU_PTI_PER, pti_index);
291
292    // we write 0 first because if the timer is currently running,
293    // the corresponding timer counter is not reset
294    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, 0);
295    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, per);
296
297#else
298    _puts("[GIET ERROR] in _xcu_timer_reset_cpt() USE_XCU is not set\n");
299    _exit();
300#endif
301}
302
303
304// Local Variables:
305// tab-width: 4
306// c-basic-offset: 4
307// c-file-offsets:((innamespace . 0)(inline-open . 0))
308// indent-tabs-mode: nil
309// End:
310// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
311
Note: See TracBrowser for help on using the repository browser.