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

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

1) Removing the IOC driver (integrated in the FAT library).
2) Simplifying the BDV, HBA, SDC, RDK drivers: they support
only two modes (synchronous => polling / descheduling => IRQ),
and only one access function (for both read/write).

File size: 8.9 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    // parameters checking
90    unsigned int x = cluster_xy >> Y_WIDTH;
91    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
92    if (x >= X_SIZE)                                   _exit(); 
93    if (y >= Y_SIZE)                                   _exit(); 
94    if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit(); 
95
96    unsigned int func = 0;
97    if      (irq_type == IRQ_TYPE_PTI) func = XCU_MSK_PTI_ENABLE;
98    else if (irq_type == IRQ_TYPE_WTI) func = XCU_MSK_WTI_ENABLE;
99    else if (irq_type == IRQ_TYPE_HWI) func = XCU_MSK_HWI_ENABLE;
100    else
101    { 
102        _printf("[GIET ERROR] _xcu_set_mask() receives illegal IRQ type\n");
103        _exit();
104    }
105
106    _xcu_set_register(cluster_xy, func, channel, value);
107}
108
109/////////////////////////////////////////////
110void _xcu_get_index( unsigned int cluster_xy, 
111                     unsigned int channel,   
112                     unsigned int * index, 
113                     unsigned int * irq_type )
114{
115    // parameters checking
116    unsigned int x = cluster_xy >> Y_WIDTH;
117    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
118    if (x >= X_SIZE)                                   _exit(); 
119    if (y >= Y_SIZE)                                   _exit(); 
120    if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit(); 
121
122    unsigned int prio = _xcu_get_register(cluster_xy, XCU_PRIO, channel);
123    unsigned int pti_ok = (prio & 0x00000001);
124    unsigned int hwi_ok = (prio & 0x00000002);
125    unsigned int wti_ok = (prio & 0x00000004);
126    unsigned int pti_id = (prio & 0x00001F00) >> 8;
127    unsigned int hwi_id = (prio & 0x001F0000) >> 16;
128    unsigned int wti_id = (prio & 0x1F000000) >> 24;
129    if      (pti_ok)
130    {
131        *index    = pti_id;
132        *irq_type = IRQ_TYPE_PTI;
133    }
134    else if (hwi_ok)
135    {
136        *index    = hwi_id;
137        *irq_type = IRQ_TYPE_HWI;
138    }
139    else if (wti_ok) 
140    {
141        *index    = wti_id;
142        *irq_type = IRQ_TYPE_WTI;
143    }
144    else 
145    {
146        *index = 32;
147    }
148}
149
150////////////////////////////////////////////
151void _xcu_send_wti( unsigned int cluster_xy,
152                    unsigned int wti_index,
153                    unsigned int wdata )
154{ 
155    // parameters checking
156    unsigned int x = cluster_xy >> Y_WIDTH;
157    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
158    if (x >= X_SIZE)               _exit(); 
159    if (y >= Y_SIZE)               _exit(); 
160    if (wti_index >= 32)           _exit(); 
161
162    _xcu_set_register(cluster_xy, XCU_WTI_REG, wti_index, wdata);
163} 
164
165////////////////////////////////////////////
166void _xcu_send_wti_paddr( unsigned int cluster_xy,
167                          unsigned int wti_index,
168                          unsigned int wdata )
169{ 
170    // parameters checking
171    unsigned int x = cluster_xy >> Y_WIDTH;
172    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
173    if (x >= X_SIZE)               _exit(); 
174    if (y >= Y_SIZE)               _exit(); 
175    if (wti_index >= 32)           _exit(); 
176
177    paddr_t paddr =
178         SEG_XCU_BASE + ((paddr_t)cluster_xy << 32) + 
179        (XCU_REG(XCU_WTI_REG, wti_index) << 2);
180
181    _physical_write(paddr, wdata);
182}
183
184///////////////////////////////////////////////////
185void _xcu_get_wti_value( unsigned int   cluster_xy,
186                         unsigned int   wti_index,
187                         unsigned int * value )
188{
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
199////////////////////////////////////////////////////
200void _xcu_get_wti_address( unsigned int   wti_index,
201                           unsigned int * address )
202{
203    if (wti_index >= 32)  _exit(); 
204 
205    *address = SEG_XCU_BASE + (XCU_REG(XCU_WTI_REG, wti_index)<<2); 
206}
207
208///////////////////////////////////////////////
209void _xcu_timer_start( unsigned int cluster_xy,
210                       unsigned int pti_index,
211                       unsigned int period )
212{
213    // parameters checking
214    unsigned int x = cluster_xy >> Y_WIDTH;
215    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
216    if (x >= X_SIZE)             _exit(); 
217    if (y >= Y_SIZE)             _exit(); 
218
219    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, period);
220}
221
222//////////////////////////////////////////////
223void _xcu_timer_stop( unsigned int cluster_xy, 
224                      unsigned int pti_index) 
225{
226    // parameters checking
227    unsigned int x = cluster_xy >> Y_WIDTH;
228    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
229    if (x >= X_SIZE)             _exit(); 
230    if (y >= Y_SIZE)             _exit(); 
231
232    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, 0);
233}
234
235///////////////////////////////////////////////////////////
236void _xcu_timer_reset_irq( unsigned int cluster_xy, 
237                           unsigned int pti_index ) 
238{
239    // parameters checking
240    unsigned int x = cluster_xy >> Y_WIDTH;
241    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
242    if (x >= X_SIZE)             _exit(); 
243    if (y >= Y_SIZE)             _exit(); 
244
245    // This return value is not used / avoid a compilation warning.
246    x = _xcu_get_register(cluster_xy, XCU_PTI_ACK, pti_index);
247}
248
249///////////////////////////////////////////////////
250void _xcu_timer_reset_cpt( unsigned int cluster_xy, 
251                           unsigned int pti_index ) 
252{
253    // parameters checking
254    unsigned int x = cluster_xy >> Y_WIDTH;
255    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
256    if (x >= X_SIZE)             _exit(); 
257    if (y >= Y_SIZE)             _exit(); 
258
259    unsigned int per = _xcu_get_register(cluster_xy, XCU_PTI_PER, pti_index);
260
261    // we write 0 first because if the timer is currently running,
262    // the corresponding timer counter is not reset
263    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, 0);
264    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, per);
265}
266
267
268// Local Variables:
269// tab-width: 4
270// c-basic-offset: 4
271// c-file-offsets:((innamespace . 0)(inline-open . 0))
272// indent-tabs-mode: nil
273// End:
274// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
275
Note: See TracBrowser for help on using the repository browser.