source: soft/giet_vm/giet_drivers/mmc_driver.c @ 776

Last change on this file since 776 was 754, checked in by cfuguet, 9 years ago
  • Support to have a single terminal (NB_TTY_CHANNEL = 1). In this case, the terminal is shared by the system and the applications.
  • Support platforms without NIC and CMA.
  • In the MMC driver, do not initialize the distributed driver structure in clusters without memory cache (IO clusters in the LETI platform).
File size: 8.6 KB
RevLine 
[258]1///////////////////////////////////////////////////////////////////////////////////
2// File     : mmc_driver.c
3// Date     : 23/05/2013
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7
[481]8#include <hard_config.h>
[258]9#include <mmc_driver.h>
[456]10#include <tty0.h>
[496]11#include <kernel_locks.h>
[754]12#include <kernel_malloc.h>
[258]13#include <utils.h>
[481]14
[345]15#include <io.h>
[258]16
[263]17#if !defined(X_SIZE)
18# error: You must define X_SIZE in the hard_config.h file
[258]19#endif
20
[263]21#if !defined(Y_SIZE)
22# error: You must define X_SIZE in the hard_config.h file
[258]23#endif
24
[263]25#if !defined(X_WIDTH)
26# error: You must define X_WIDTH in the hard_config.h file
27#endif
28
29#if !defined(Y_WIDTH)
30# error: You must define X_WIDTH in the hard_config.h file
31#endif
32
[320]33#if !defined(SEG_MMC_BASE)
34# error: You must define SEG_MMC_BASE in the hard_config.h file
35#endif
36
[333]37#if !defined(PERI_CLUSTER_INCREMENT)
38# error: You must define PERI_CLUSTER_INCREMENT in the hard_config.h file
[320]39#endif
40
[345]41///////////////////////////////////////////////////////////////////////////////
[630]42//     Global variables
43///////////////////////////////////////////////////////////////////////////////
44// Two kinds of locks protecting the MMC components (one per cluster):
45// - the _mmc_lock array contains spin_locks allocated in cluster[0,0].
46//   They must be used by the boot code because the kernel heap is not set.
47// - the _mmc_distributed_locks array contains pointers on distributed
48//   spin_loks allocated in the distributed heap in each cluster.
49//   Each cluster contains the lock protecting its own mmc_component.
50//   They can be used by the kernel code.
[615]51// The global variable mmc_boot_mode define the type of lock which is used,
52// and must be defined in both kernel_init.c and boot.c files.
[496]53///////////////////////////////////////////////////////////////////////////////
54
[630]55__attribute__((section(".kdata")))
56unsigned int  _mmc_boot_mode;
[615]57
[496]58__attribute__((section(".kdata")))
[615]59spin_lock_t           _mmc_lock[X_SIZE][Y_SIZE]  __attribute__((aligned(64)));
[496]60
[615]61__attribute__((section(".kdata")))
62spin_lock_t*          _mmc_distributed_lock[X_SIZE][Y_SIZE];
63
64//////////////////////////////////////////////////////////////////////////////
65// This function initializes the distributed locks stored in the kernel heaps
66//////////////////////////////////////////////////////////////////////////////
67
68void _mmc_init_locks()
69{
[630]70    unsigned int x;    // cluster X coordinate
71    unsigned int y;    // cluster Y coordinate
[615]72   
[630]73    for ( x = 0 ; x < X_SIZE ; x++ )
[615]74    {
[630]75        for ( y = 0 ; y < Y_SIZE ; y++ )
[615]76        {
[630]77            if ( _mmc_boot_mode )
78            {
79                _spin_lock_init( &_mmc_lock[x][y] );
80            }
81            else
82            {
[754]83                // get heap_base & heap size
84                unsigned int heap_base;
85                unsigned int heap_size;
86                if ( _get_heap_info( &heap_base, &heap_size, x, y ) ) continue;
87
[630]88                _mmc_distributed_lock[x][y] = _remote_malloc( sizeof(spin_lock_t), x, y );
89                _spin_lock_init( _mmc_distributed_lock[x][y] );
90            }
[615]91        }
92    }
93}
94
[496]95///////////////////////////////////////////////////////////////////////////////
[456]96// This low level function returns the value contained in register
97// defined by the ("func" / "index") arguments,
[345]98// in the MMC component contained in cluster "cluster_xy"
99///////////////////////////////////////////////////////////////////////////////
100static
101unsigned int _mmc_get_register( unsigned int cluster_xy, // cluster index
102                                unsigned int func,       // function index
103                                unsigned int index )     // register index
104{
105    unsigned int vaddr =
106        SEG_MMC_BASE + 
107        (cluster_xy * PERI_CLUSTER_INCREMENT) +
108        (MMC_REG(func, index) << 2);
109
110    return ioread32( (void*)vaddr );
111}
112
113///////////////////////////////////////////////////////////////////////////////
[456]114// This low level function sets a new value in register
115// defined by the ("func" / "index") arguments,
[345]116// in the MMC component contained in cluster "cluster_xy"
117///////////////////////////////////////////////////////////////////////////////
118static
119void _mmc_set_register( unsigned int cluster_xy,       // cluster index
120                        unsigned int func,             // func index
121                        unsigned int index,            // register index
122                        unsigned int value )           // value to be written
123{
124    unsigned int vaddr =
125        SEG_MMC_BASE + 
126        (cluster_xy * PERI_CLUSTER_INCREMENT) +
127        (MMC_REG(func, index) << 2);
128       
129    iowrite32( (void*)vaddr, value );
130}
131
[437]132/////////////////////////////////////////
[297]133void _mmc_inval( paddr_t      buf_paddr,
134                 unsigned int buf_length )
[258]135{
[263]136    // compute cluster coordinates
137    unsigned int cluster_xy = (unsigned int)(buf_paddr>>(40-X_WIDTH-Y_WIDTH));
138    unsigned int x          = cluster_xy >> Y_WIDTH;
139    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
[258]140
[263]141    // parameters checking
142    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
143    {
[496]144        _puts("\n[GIET ERROR] in _mmc_inval() : illegal cluster coordinates\n");
[263]145        _exit();
146    }
147
[545]148    if ( buf_paddr & 0x3F )
149    {
150        _puts("\n[GIET ERROR] in _mmc_inval() : paddr not 64 bytes aligned\n");
151        _exit();
152    }
153
[496]154    // get the lock protecting exclusive access to MEMC
[615]155    if ( _mmc_boot_mode ) _spin_lock_acquire( &_mmc_lock[x][y] );
156    else                  _spin_lock_acquire( _mmc_distributed_lock[x][y] );
[258]157
158    // write inval arguments
[496]159    _mmc_set_register(cluster_xy, 0, MEMC_ADDR_LO   , (unsigned int)buf_paddr );
160    _mmc_set_register(cluster_xy, 0, MEMC_ADDR_HI   , (unsigned int)(buf_paddr>>32) );
161    _mmc_set_register(cluster_xy, 0, MEMC_BUF_LENGTH, buf_length );
162    _mmc_set_register(cluster_xy, 0, MEMC_CMD_TYPE  , MEMC_CMD_INVAL );
[258]163
164    // release the lock
[615]165    if ( _mmc_boot_mode ) _spin_lock_release( &_mmc_lock[x][y] );
166    else                  _spin_lock_release( _mmc_distributed_lock[x][y] );
[258]167}
[437]168
169///////////////////////////////////////
[297]170void _mmc_sync( paddr_t      buf_paddr,
171                unsigned int buf_length )
[258]172{
[263]173    // compute cluster coordinates
174    unsigned int cluster_xy = (unsigned int)(buf_paddr>>(40-X_WIDTH-Y_WIDTH));
175    unsigned int x          = cluster_xy >> Y_WIDTH;
176    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
[258]177
[263]178    // parameters checking
179    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
180    {
[496]181        _puts( "\n[GIET ERROR] in _mmc_sync() : illegal cluster coordinates");
[263]182        _exit();
183    }
184
[545]185    if ( buf_paddr & 0x3F )
186    {
187        _puts("\n[GIET ERROR] in _mmc_sync() : paddr not 64 bytes aligned\n");
188        _exit();
189    }
190
[496]191    // get the lock protecting exclusive access to MEMC
[615]192    if ( _mmc_boot_mode ) _spin_lock_acquire( &_mmc_lock[x][y] );
193    else                  _spin_lock_acquire( _mmc_distributed_lock[x][y] );
[258]194
195    // write inval arguments
[345]196    _mmc_set_register(cluster_xy, 0, MEMC_ADDR_LO   , (unsigned int)buf_paddr);
197    _mmc_set_register(cluster_xy, 0, MEMC_ADDR_HI   , (unsigned int)(buf_paddr>>32));
198    _mmc_set_register(cluster_xy, 0, MEMC_BUF_LENGTH, buf_length);
199    _mmc_set_register(cluster_xy, 0, MEMC_CMD_TYPE  , MEMC_CMD_SYNC);
[258]200
[345]201    // release the lock
[615]202    if ( _mmc_boot_mode ) _spin_lock_release( &_mmc_lock[x][y] );
203    else                  _spin_lock_release( _mmc_distributed_lock[x][y] );
[258]204}
205
[496]206/////////////////////////////////////////////
207unsigned int _mmc_instrument( unsigned int x, 
208                              unsigned int y,
209                              unsigned int reg )
210{
211    // parameters checking
212    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
213    {
214        _puts( "\n[GIET ERROR] in _mmc_instrument() : illegal cluster coordinates");
215        _exit();
216    }
217
218    unsigned int cluster_xy = (x << Y_WIDTH) + y;
219    return( _mmc_get_register(cluster_xy , 1 , reg) );
220}
221
[437]222///////////////////////////////////////////////////////
[297]223void _mmc_isr( unsigned int irq_type,  // should be HWI
224               unsigned int irq_id,    // index returned by ICU
225               unsigned int channel )  // unused
226{
[426]227    unsigned int gpid       = _get_procid();
228    unsigned int cluster_xy = gpid >> P_WIDTH;
[298]229    unsigned int x          = cluster_xy >> Y_WIDTH;
230    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
[437]231    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
[298]232
[437]233    _puts("[GIET ERROR] MMC IRQ received by processor[");
234    _putd( x );
235    _puts(",");
236    _putd( y );
237    _puts(",");
238    _putd( p );
239    _puts("] but _mmc_isr() not implemented\n");
[297]240}
241
242
243
[258]244// Local Variables:
245// tab-width: 4
246// c-basic-offset: 4
247// c-file-offsets:((innamespace . 0)(inline-open . 0))
248// indent-tabs-mode: nil
249// End:
250// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
251
Note: See TracBrowser for help on using the repository browser.