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

Last change on this file since 529 was 529, checked in by alain, 9 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
RevLine 
[258]1///////////////////////////////////////////////////////////////////////////////////
2// File     : xcu_driver.c
3// Date     : 23/05/2013
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7
[320]8#include <hard_config.h>
[258]9#include <giet_config.h>
10#include <xcu_driver.h>
[456]11#include <tty0.h>
[263]12#include <mapping_info.h>
[258]13#include <utils.h>
[345]14#include <io.h>
[258]15
[263]16#if !defined(X_SIZE)
17# error: You must define X_SIZE in the hard_config.h file
[258]18#endif
19
[263]20#if !defined(Y_SIZE)
21# error: You must define X_SIZE in the hard_config.h file
[258]22#endif
23
[263]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
[258]32#if !defined(NB_PROCS_MAX)
33# error: You must define NB_PROCS_MAX in the hard_config.h file
34#endif
35
[320]36#if !defined( USE_XCU )
37# error: You must define USE_XCU in the hard_config.h file
[258]38#endif
39
[320]40#if !defined( SEG_XCU_BASE )
41# error: You must define SEG_XCU_BASE in the hard_config.h file
42#endif
[295]43
[333]44#if !defined( PERI_CLUSTER_INCREMENT )
45# error: You must define PERI_CLUSTER_INCREMENT in the hard_config.h file
[320]46#endif
47
[345]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);
[320]61
[345]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
[437]83////////////////////////////////////////////
[295]84void _xcu_set_mask( unsigned int cluster_xy, 
85                    unsigned int channel, 
86                    unsigned int value,
87                    unsigned int irq_type ) 
[258]88{
89    // parameters checking
[263]90    unsigned int x = cluster_xy >> Y_WIDTH;
91    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[295]92    if (x >= X_SIZE)                                   _exit(); 
93    if (y >= Y_SIZE)                                   _exit(); 
94    if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit(); 
[258]95
[345]96    unsigned int func = 0;
[320]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;
[295]100    else
101    { 
[496]102        _printf("[GIET ERROR] _xcu_set_mask() receives illegal IRQ type\n");
[295]103        _exit();
104    }
105
[345]106    _xcu_set_register(cluster_xy, func, channel, value);
[258]107}
108
[437]109/////////////////////////////////////////////
[295]110void _xcu_get_index( unsigned int cluster_xy, 
111                     unsigned int channel,   
112                     unsigned int * index, 
113                     unsigned int * irq_type )
[258]114{
115    // parameters checking
[263]116    unsigned int x = cluster_xy >> Y_WIDTH;
117    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[295]118    if (x >= X_SIZE)                                   _exit(); 
119    if (y >= Y_SIZE)                                   _exit(); 
120    if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit(); 
[258]121
[345]122    unsigned int prio = _xcu_get_register(cluster_xy, XCU_PRIO, channel);
[258]123    unsigned int pti_ok = (prio & 0x00000001);
124    unsigned int hwi_ok = (prio & 0x00000002);
[295]125    unsigned int wti_ok = (prio & 0x00000004);
[258]126    unsigned int pti_id = (prio & 0x00001F00) >> 8;
127    unsigned int hwi_id = (prio & 0x001F0000) >> 16;
[295]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    }
[258]148}
149
[437]150////////////////////////////////////////////
[295]151void _xcu_send_wti( unsigned int cluster_xy,
152                    unsigned int wti_index,
153                    unsigned int wdata )
[258]154{ 
155    // parameters checking
[263]156    unsigned int x = cluster_xy >> Y_WIDTH;
157    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[295]158    if (x >= X_SIZE)               _exit(); 
159    if (y >= Y_SIZE)               _exit(); 
160    if (wti_index >= 32)           _exit(); 
[258]161
[345]162    _xcu_set_register(cluster_xy, XCU_WTI_REG, wti_index, wdata);
[258]163} 
164
[490]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);
[529]182}
[490]183
[437]184///////////////////////////////////////////////////
[295]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 
[345]196    *value = _xcu_get_register(cluster_xy, XCU_WTI_REG, wti_index);
[295]197}
198
[437]199////////////////////////////////////////////////////
[295]200void _xcu_get_wti_address( unsigned int   wti_index,
201                           unsigned int * address )
202{
[529]203    if (wti_index >= 32)  _exit(); 
[295]204 
[345]205    *address = SEG_XCU_BASE + (XCU_REG(XCU_WTI_REG, wti_index)<<2); 
[295]206}
207
[437]208///////////////////////////////////////////////
[295]209void _xcu_timer_start( unsigned int cluster_xy,
210                       unsigned int pti_index,
211                       unsigned int period )
[258]212{
213    // parameters checking
[263]214    unsigned int x = cluster_xy >> Y_WIDTH;
215    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[295]216    if (x >= X_SIZE)             _exit(); 
217    if (y >= Y_SIZE)             _exit(); 
[258]218
[345]219    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, period);
[258]220}
221
[437]222//////////////////////////////////////////////
[295]223void _xcu_timer_stop( unsigned int cluster_xy, 
224                      unsigned int pti_index) 
[258]225{
226    // parameters checking
[263]227    unsigned int x = cluster_xy >> Y_WIDTH;
228    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[295]229    if (x >= X_SIZE)             _exit(); 
230    if (y >= Y_SIZE)             _exit(); 
[258]231
[345]232    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, 0);
[258]233}
234
[437]235///////////////////////////////////////////////////////////
[529]236void _xcu_timer_reset_irq( unsigned int cluster_xy, 
237                           unsigned int pti_index ) 
[258]238{
239    // parameters checking
[263]240    unsigned int x = cluster_xy >> Y_WIDTH;
241    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[295]242    if (x >= X_SIZE)             _exit(); 
243    if (y >= Y_SIZE)             _exit(); 
[258]244
[320]245    // This return value is not used / avoid a compilation warning.
[529]246    x = _xcu_get_register(cluster_xy, XCU_PTI_ACK, pti_index);
[258]247}
248
[437]249///////////////////////////////////////////////////
[295]250void _xcu_timer_reset_cpt( unsigned int cluster_xy, 
251                           unsigned int pti_index ) 
[258]252{
253    // parameters checking
[263]254    unsigned int x = cluster_xy >> Y_WIDTH;
255    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[295]256    if (x >= X_SIZE)             _exit(); 
257    if (y >= Y_SIZE)             _exit(); 
[258]258
[345]259    unsigned int per = _xcu_get_register(cluster_xy, XCU_PTI_PER, pti_index);
[258]260
261    // we write 0 first because if the timer is currently running,
262    // the corresponding timer counter is not reset
[345]263    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, 0);
264    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, per);
[258]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.