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

Last change on this file since 476 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
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{
[320]89#if USE_XCU
[258]90    // parameters checking
[263]91    unsigned int x = cluster_xy >> Y_WIDTH;
92    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[295]93    if (x >= X_SIZE)                                   _exit(); 
94    if (y >= Y_SIZE)                                   _exit(); 
95    if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit(); 
[258]96
[345]97    unsigned int func = 0;
[320]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;
[295]101    else
102    { 
[437]103        _puts("[GIET ERROR] _xcu_set_mask() receives illegal IRQ type\n");
[295]104        _exit();
105    }
106
[345]107    _xcu_set_register(cluster_xy, func, channel, value);
[295]108
[258]109#else
[437]110    _puts("[GIET ERROR] _xcu_set_mask() should not be used if USE_XCU not set\n");
[295]111    _exit();
[258]112#endif
113}
114
[437]115/////////////////////////////////////////////
[295]116void _xcu_get_index( unsigned int cluster_xy, 
117                     unsigned int channel,   
118                     unsigned int * index, 
119                     unsigned int * irq_type )
[258]120{
[320]121#if USE_XCU
[258]122    // parameters checking
[263]123    unsigned int x = cluster_xy >> Y_WIDTH;
124    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[295]125    if (x >= X_SIZE)                                   _exit(); 
126    if (y >= Y_SIZE)                                   _exit(); 
127    if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit(); 
[258]128
[345]129    unsigned int prio = _xcu_get_register(cluster_xy, XCU_PRIO, channel);
[258]130    unsigned int pti_ok = (prio & 0x00000001);
131    unsigned int hwi_ok = (prio & 0x00000002);
[295]132    unsigned int wti_ok = (prio & 0x00000004);
[258]133    unsigned int pti_id = (prio & 0x00001F00) >> 8;
134    unsigned int hwi_id = (prio & 0x001F0000) >> 16;
[295]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 
[258]156#else
[437]157    _puts("[GIET ERROR] _xcu_get_index should not be used if USE_XCU is not set\n");
[295]158    _exit();
[258]159#endif
160}
161
[437]162////////////////////////////////////////////
[295]163void _xcu_send_wti( unsigned int cluster_xy,
164                    unsigned int wti_index,
165                    unsigned int wdata )
[258]166{ 
[320]167#if USE_XCU
[258]168    // parameters checking
[263]169    unsigned int x = cluster_xy >> Y_WIDTH;
170    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[295]171    if (x >= X_SIZE)               _exit(); 
172    if (y >= Y_SIZE)               _exit(); 
173    if (wti_index >= 32)           _exit(); 
[258]174
[345]175    _xcu_set_register(cluster_xy, XCU_WTI_REG, wti_index, wdata);
[275]176
[258]177#else
[437]178    _puts("[GIET ERROR] _xcu_send_wti() should not be used if USE_XCU is not set\n");
[295]179    _exit();
[258]180#endif
181} 
182
[437]183///////////////////////////////////////////////////
[295]184void _xcu_get_wti_value( unsigned int   cluster_xy,
185                         unsigned int   wti_index,
186                         unsigned int * value )
187{
[320]188#if USE_XCU
[295]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#else
[437]199    _puts("[GIET ERROR] in _xcu_get_wti_value() USE_XCU is not set\n");
[295]200    _exit();
201#endif
202}
203
[437]204////////////////////////////////////////////////////
[295]205void _xcu_get_wti_address( unsigned int   wti_index,
206                           unsigned int * address )
207{
[320]208#if USE_XCU
[295]209    if (wti_index >= 32)           _exit(); 
210 
[345]211    *address = SEG_XCU_BASE + (XCU_REG(XCU_WTI_REG, wti_index)<<2); 
[295]212
213#else
[437]214    _puts("[GIET ERROR] in _xcu_get_wti_address() USE_XCU is not set\n");
[295]215    _exit();
216#endif
217}
218
[437]219///////////////////////////////////////////////
[295]220void _xcu_timer_start( unsigned int cluster_xy,
221                       unsigned int pti_index,
222                       unsigned int period )
[258]223{
[320]224#if USE_XCU
[258]225    // parameters checking
[263]226    unsigned int x = cluster_xy >> Y_WIDTH;
227    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[295]228    if (x >= X_SIZE)             _exit(); 
229    if (y >= Y_SIZE)             _exit(); 
[258]230
[345]231    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, period);
[275]232
[258]233#else
[437]234    _puts("[GIET ERROR] in _xcu_timer_start() USE_XCU is not set\n");
[295]235    _exit();
[258]236#endif
237}
238
[437]239//////////////////////////////////////////////
[295]240void _xcu_timer_stop( unsigned int cluster_xy, 
241                      unsigned int pti_index) 
[258]242{
[320]243#if USE_XCU
[258]244    // parameters checking
[263]245    unsigned int x = cluster_xy >> Y_WIDTH;
246    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[295]247    if (x >= X_SIZE)             _exit(); 
248    if (y >= Y_SIZE)             _exit(); 
[258]249
[345]250    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, 0);
[275]251
[258]252#else
[437]253    _puts("[GIET ERROR] in _xcu_timer_stop() USE_XCU is not set\n");
[295]254    _exit();
[258]255#endif
256}
257
[437]258///////////////////////////////////////////////////////////
[320]259unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy, 
260                                   unsigned int pti_index ) 
[258]261{
[320]262#if USE_XCU
[258]263    // parameters checking
[263]264    unsigned int x = cluster_xy >> Y_WIDTH;
265    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[295]266    if (x >= X_SIZE)             _exit(); 
267    if (y >= Y_SIZE)             _exit(); 
[258]268
[320]269    // This return value is not used / avoid a compilation warning.
[345]270    return _xcu_get_register(cluster_xy, XCU_PTI_ACK, pti_index);
[295]271
[258]272#else
[437]273    _puts("[GIET ERROR] in _xcu_timer_reset_irq() USE_XCU is not set\n");
[295]274    _exit();
[320]275    return 0;
[258]276#endif
277}
278
[437]279///////////////////////////////////////////////////
[295]280void _xcu_timer_reset_cpt( unsigned int cluster_xy, 
281                           unsigned int pti_index ) 
[258]282{
[320]283#if USE_XCU
[258]284    // parameters checking
[263]285    unsigned int x = cluster_xy >> Y_WIDTH;
286    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[295]287    if (x >= X_SIZE)             _exit(); 
288    if (y >= Y_SIZE)             _exit(); 
[258]289
[345]290    unsigned int per = _xcu_get_register(cluster_xy, XCU_PTI_PER, pti_index);
[258]291
292    // we write 0 first because if the timer is currently running,
293    // the corresponding timer counter is not reset
[345]294    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, 0);
295    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, per);
[295]296
[258]297#else
[437]298    _puts("[GIET ERROR] in _xcu_timer_reset_cpt() USE_XCU is not set\n");
[295]299    _exit();
[258]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.