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

Last change on this file since 565 was 545, checked in by alain, 10 years ago

Cosmetic

File size: 6.4 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////
2// File     : mmc_driver.c
3// Date     : 23/05/2013
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7
8#include <hard_config.h>
9#include <mmc_driver.h>
10#include <tty0.h>
11#include <kernel_locks.h>
12#include <utils.h>
13
14#include <io.h>
15
16#if !defined(X_SIZE)
17# error: You must define X_SIZE in the hard_config.h file
18#endif
19
20#if !defined(Y_SIZE)
21# error: You must define X_SIZE in the hard_config.h file
22#endif
23
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
32#if !defined(SEG_MMC_BASE)
33# error: You must define SEG_MMC_BASE in the hard_config.h file
34#endif
35
36#if !defined(PERI_CLUSTER_INCREMENT)
37# error: You must define PERI_CLUSTER_INCREMENT in the hard_config.h file
38#endif
39
40///////////////////////////////////////////////////////////////////////////////
41// Distributed locks protecting MMC components (one per cluster)
42///////////////////////////////////////////////////////////////////////////////
43
44__attribute__((section(".kdata")))
45spin_lock_t  _mmc_lock[X_SIZE][Y_SIZE]  __attribute__((aligned(64)));
46
47///////////////////////////////////////////////////////////////////////////////
48// This low level function returns the value contained in register
49// defined by the ("func" / "index") arguments,
50// in the MMC component contained in cluster "cluster_xy"
51///////////////////////////////////////////////////////////////////////////////
52static
53unsigned int _mmc_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_MMC_BASE + 
59        (cluster_xy * PERI_CLUSTER_INCREMENT) +
60        (MMC_REG(func, index) << 2);
61
62    return ioread32( (void*)vaddr );
63}
64
65///////////////////////////////////////////////////////////////////////////////
66// This low level function sets a new value in register
67// defined by the ("func" / "index") arguments,
68// in the MMC component contained in cluster "cluster_xy"
69///////////////////////////////////////////////////////////////////////////////
70static
71void _mmc_set_register( unsigned int cluster_xy,       // cluster index
72                        unsigned int func,             // func index
73                        unsigned int index,            // register index
74                        unsigned int value )           // value to be written
75{
76    unsigned int vaddr =
77        SEG_MMC_BASE + 
78        (cluster_xy * PERI_CLUSTER_INCREMENT) +
79        (MMC_REG(func, index) << 2);
80       
81    iowrite32( (void*)vaddr, value );
82}
83
84/////////////////////////////////////////
85void _mmc_inval( paddr_t      buf_paddr,
86                 unsigned int buf_length )
87{
88    // compute cluster coordinates
89    unsigned int cluster_xy = (unsigned int)(buf_paddr>>(40-X_WIDTH-Y_WIDTH));
90    unsigned int x          = cluster_xy >> Y_WIDTH;
91    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
92
93    // parameters checking
94    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
95    {
96        _puts("\n[GIET ERROR] in _mmc_inval() : illegal cluster coordinates\n");
97        _exit();
98    }
99
100    if ( buf_paddr & 0x3F )
101    {
102        _puts("\n[GIET ERROR] in _mmc_inval() : paddr not 64 bytes aligned\n");
103        _exit();
104    }
105
106    // get the lock protecting exclusive access to MEMC
107    _spin_lock_acquire( &_mmc_lock[x][y] );
108
109    // write inval arguments
110    _mmc_set_register(cluster_xy, 0, MEMC_ADDR_LO   , (unsigned int)buf_paddr );
111    _mmc_set_register(cluster_xy, 0, MEMC_ADDR_HI   , (unsigned int)(buf_paddr>>32) );
112    _mmc_set_register(cluster_xy, 0, MEMC_BUF_LENGTH, buf_length );
113    _mmc_set_register(cluster_xy, 0, MEMC_CMD_TYPE  , MEMC_CMD_INVAL );
114
115    // release the lock
116    _spin_lock_release( &_mmc_lock[x][y] );
117}
118
119///////////////////////////////////////
120void _mmc_sync( paddr_t      buf_paddr,
121                unsigned int buf_length )
122{
123    // compute cluster coordinates
124    unsigned int cluster_xy = (unsigned int)(buf_paddr>>(40-X_WIDTH-Y_WIDTH));
125    unsigned int x          = cluster_xy >> Y_WIDTH;
126    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
127
128    // parameters checking
129    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
130    {
131        _puts( "\n[GIET ERROR] in _mmc_sync() : illegal cluster coordinates");
132        _exit();
133    }
134
135    if ( buf_paddr & 0x3F )
136    {
137        _puts("\n[GIET ERROR] in _mmc_sync() : paddr not 64 bytes aligned\n");
138        _exit();
139    }
140
141    // get the lock protecting exclusive access to MEMC
142    _spin_lock_acquire( &_mmc_lock[x][y] );
143
144    // write inval arguments
145    _mmc_set_register(cluster_xy, 0, MEMC_ADDR_LO   , (unsigned int)buf_paddr);
146    _mmc_set_register(cluster_xy, 0, MEMC_ADDR_HI   , (unsigned int)(buf_paddr>>32));
147    _mmc_set_register(cluster_xy, 0, MEMC_BUF_LENGTH, buf_length);
148    _mmc_set_register(cluster_xy, 0, MEMC_CMD_TYPE  , MEMC_CMD_SYNC);
149
150    // release the lock
151    _spin_lock_release( &_mmc_lock[x][y] );
152}
153
154/////////////////////////////////////////////
155unsigned int _mmc_instrument( unsigned int x, 
156                              unsigned int y,
157                              unsigned int reg )
158{
159    // parameters checking
160    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
161    {
162        _puts( "\n[GIET ERROR] in _mmc_instrument() : illegal cluster coordinates");
163        _exit();
164    }
165
166    unsigned int cluster_xy = (x << Y_WIDTH) + y;
167    return( _mmc_get_register(cluster_xy , 1 , reg) );
168}
169
170///////////////////////////////////////////////////////
171void _mmc_isr( unsigned int irq_type,  // should be HWI
172               unsigned int irq_id,    // index returned by ICU
173               unsigned int channel )  // unused
174{
175    unsigned int gpid       = _get_procid();
176    unsigned int cluster_xy = gpid >> P_WIDTH;
177    unsigned int x          = cluster_xy >> Y_WIDTH;
178    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
179    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
180
181    _puts("[GIET ERROR] MMC IRQ received by processor[");
182    _putd( x );
183    _puts(",");
184    _putd( y );
185    _puts(",");
186    _putd( p );
187    _puts("] but _mmc_isr() not implemented\n");
188}
189
190
191
192// Local Variables:
193// tab-width: 4
194// c-basic-offset: 4
195// c-file-offsets:((innamespace . 0)(inline-open . 0))
196// indent-tabs-mode: nil
197// End:
198// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
199
Note: See TracBrowser for help on using the repository browser.