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

Last change on this file since 816 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
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.