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

Last change on this file since 496 was 496, checked in by alain, 9 years ago

1) Introduce access functions to MMC intrumentation registers.
2) Use _printf for error or debug messages.

File size: 6.2 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    // get the lock protecting exclusive access to MEMC
101    _spin_lock_acquire( &_mmc_lock[x][y] );
102
103    // write inval arguments
104    _mmc_set_register(cluster_xy, 0, MEMC_ADDR_LO   , (unsigned int)buf_paddr );
105    _mmc_set_register(cluster_xy, 0, MEMC_ADDR_HI   , (unsigned int)(buf_paddr>>32) );
106    _mmc_set_register(cluster_xy, 0, MEMC_BUF_LENGTH, buf_length );
107    _mmc_set_register(cluster_xy, 0, MEMC_CMD_TYPE  , MEMC_CMD_INVAL );
108
109    // release the lock
110    _spin_lock_release( &_mmc_lock[x][y] );
111}
112
113///////////////////////////////////////
114void _mmc_sync( paddr_t      buf_paddr,
115                unsigned int buf_length )
116{
117    // compute cluster coordinates
118    unsigned int cluster_xy = (unsigned int)(buf_paddr>>(40-X_WIDTH-Y_WIDTH));
119    unsigned int x          = cluster_xy >> Y_WIDTH;
120    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
121
122    // parameters checking
123    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
124    {
125        _puts( "\n[GIET ERROR] in _mmc_sync() : illegal cluster coordinates");
126        _exit();
127    }
128
129    // get the lock protecting exclusive access to MEMC
130    _spin_lock_acquire( &_mmc_lock[x][y] );
131
132    // write inval arguments
133    _mmc_set_register(cluster_xy, 0, MEMC_ADDR_LO   , (unsigned int)buf_paddr);
134    _mmc_set_register(cluster_xy, 0, MEMC_ADDR_HI   , (unsigned int)(buf_paddr>>32));
135    _mmc_set_register(cluster_xy, 0, MEMC_BUF_LENGTH, buf_length);
136    _mmc_set_register(cluster_xy, 0, MEMC_CMD_TYPE  , MEMC_CMD_SYNC);
137
138    // release the lock
139    _spin_lock_release( &_mmc_lock[x][y] );
140}
141
142/////////////////////////////////////////////
143unsigned int _mmc_instrument( unsigned int x, 
144                              unsigned int y,
145                              unsigned int reg )
146{
147    // parameters checking
148    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
149    {
150        _puts( "\n[GIET ERROR] in _mmc_instrument() : illegal cluster coordinates");
151        _exit();
152    }
153
154    unsigned int cluster_xy = (x << Y_WIDTH) + y;
155    return( _mmc_get_register(cluster_xy , 1 , reg) );
156}
157
158///////////////////////////////////////////////////////
159void _mmc_isr( unsigned int irq_type,  // should be HWI
160               unsigned int irq_id,    // index returned by ICU
161               unsigned int channel )  // unused
162{
163    unsigned int gpid       = _get_procid();
164    unsigned int cluster_xy = gpid >> P_WIDTH;
165    unsigned int x          = cluster_xy >> Y_WIDTH;
166    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
167    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
168
169    _puts("[GIET ERROR] MMC IRQ received by processor[");
170    _putd( x );
171    _puts(",");
172    _putd( y );
173    _puts(",");
174    _putd( p );
175    _puts("] but _mmc_isr() not implemented\n");
176}
177
178
179
180// Local Variables:
181// tab-width: 4
182// c-basic-offset: 4
183// c-file-offsets:((innamespace . 0)(inline-open . 0))
184// indent-tabs-mode: nil
185// End:
186// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
187
Note: See TracBrowser for help on using the repository browser.