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

Last change on this file since 449 was 437, checked in by alain, 10 years ago

Introducing dynamic allocation of peripheral channel(TTY, NIC, TIM, CMA)
Removint the ICU driver : ICU component not supported anymore.
Removing the FBF driver.

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>
[263]11#include <tty_driver.h>
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.