source: soft/giet_vm/giet_drivers/hba_driver.c @ 567

Last change on this file since 567 was 563, checked in by alain, 10 years ago

1) Introduce a new driver "sdc_driver" for SD Card uding directly the 4 bits SD bus.
2) Improve the debug for all IOC drivers (debug activated only if _get_time() > GIET_DEBUG_IOC_DRIVER).

File size: 13.7 KB
Line 
1//////////////////////////////////////////////////////////////////////////////////
2// File     : hba_driver.c
3// Date     : 23/11/2013
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7// Implementation notes:
8// All accesses to HBA registers are done by the two
9// _hba_set_register() and _hba_get_register() low-level functions,
10// that are handling virtual / physical extended addressing.
11///////////////////////////////////////////////////////////////////////////////////
12
13#include <giet_config.h>
14#include <hard_config.h>
15#include <hba_driver.h>
16#include <xcu_driver.h>
17#include <mmc_driver.h>
18#include <kernel_locks.h>
19#include <utils.h>
20#include <tty0.h>
21#include <ctx_handler.h>
22#include <irq_handler.h>
23#include <vmem.h>
24
25///////////////////////////////////////////////////////////////////////////////////
26//               Global variables
27///////////////////////////////////////////////////////////////////////////////////
28
29// global index ot the task, for each entry in the command list
30__attribute__((section(".kdata")))
31unsigned int _hba_gtid[32];
32
33// status of the command, for each entry in the command list
34__attribute__((section(".kdata")))
35unsigned int _hba_status[32];
36
37// command list : up to 32 commands
38__attribute__((section(".kdata")))
39hba_cmd_desc_t  _hba_cmd_list[32] __attribute__((aligned(0x40)));   
40
41// command tables array : one command table per entry in command list
42__attribute__((section(".kdata")))
43hba_cmd_table_t _hba_cmd_table[32] __attribute__((aligned(0x40))); 
44
45// command list write index : next slot to register a command
46__attribute__((section(".kdata")))
47unsigned int     _hba_cmd_ptw;
48
49// command list read index : next slot to poll a completed command
50__attribute__((section(".kdata")))
51unsigned int     _hba_cmd_ptr;
52
53//////////////////////////////////////////////////////////////////////////////
54// This low level function returns the value of register (index)
55//////////////////////////////////////////////////////////////////////////////
56unsigned int _hba_get_register( unsigned int index )
57{
58    unsigned int* vaddr = (unsigned int*)SEG_IOC_BASE + index;
59    return _io_extended_read( vaddr );
60}
61
62//////////////////////////////////////////////////////////////////////////////
63// This low level function set a new value in register (index) 
64//////////////////////////////////////////////////////////////////////////////
65void _hba_set_register( unsigned int index,
66                        unsigned int value )
67{
68    unsigned int* vaddr = (unsigned int*)SEG_IOC_BASE + index;
69    _io_extended_write( vaddr, value );
70}
71
72///////////////////////////////////////////////////////////////////////////////
73//      Extern functions
74///////////////////////////////////////////////////////////////////////////////
75
76///////////////////////////////////////////////////////////////////////////////
77// This function register a command in both the command list
78// and the command table, and updates the HBA_PXCI register.
79// return 0 if success, -1 if error
80///////////////////////////////////////////////////////////////////////////////
81unsigned int _hba_access( unsigned int       use_irq,
82                          unsigned int       to_mem,
83                          unsigned int       lba, 
84                          unsigned long long buf_paddr,
85                          unsigned int       count )   
86{
87    unsigned int procid  = _get_procid();
88    unsigned int x       = procid >> (Y_WIDTH + P_WIDTH);
89    unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH) - 1);
90    unsigned int p       = procid & ((1<<P_WIDTH)-1);
91
92#if GIET_DEBUG_IOC_DRIVER
93if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
94_printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] enters at cycle %d\n"
95        "  use_irq = %d / to_mem = %d / lba = %x / paddr = %l / count = %d\n",
96        x , y , p , _get_proctime() , use_irq , to_mem , lba , buf_paddr, count );
97#endif
98
99    unsigned int       pxci;              // HBA_PXCI register value
100    unsigned int       ptw;               // command list write pointer
101    unsigned int       pxis;              // HBA_PXIS register value
102    hba_cmd_desc_t*    cmd_desc;          // command descriptor pointer   
103    hba_cmd_table_t*   cmd_table;         // command table pointer
104
105    // check buffer alignment
106    if( buf_paddr & 0x3F )
107    {
108        _printf("\n[HBA ERROR] in _hba_access() : buffer not 64 bytes aligned\n");
109        return -1;
110    }
111
112    // get one entry in Command List
113    // atomic increment on the _hba_cmd_ptw allocator
114    // only the 5 LSB bits are used to index the Command List
115    ptw = _atomic_increment( &_hba_cmd_ptw , 1 ) & 0x1F;
116
117    // blocked until allocated entry in Command List is empty
118    do
119    {
120        // get PXCI register
121        pxci = _hba_get_register( HBA_PXCI );
122    } 
123    while ( pxci & (1<<ptw) );
124
125    // compute pointers on command descriptor and command table   
126    cmd_desc  = &_hba_cmd_list[ptw];
127    cmd_table = &_hba_cmd_table[ptw];
128
129    // set  buffer descriptor in command table
130    cmd_table->buffer.dba  = (unsigned int)(buf_paddr);
131    cmd_table->buffer.dbau = (unsigned int)(buf_paddr >> 32);
132    cmd_table->buffer.dbc  = count * 512;
133
134    // initialize command table header
135    cmd_table->header.lba0 = (char)lba;
136    cmd_table->header.lba1 = (char)(lba>>8);
137    cmd_table->header.lba2 = (char)(lba>>16);
138    cmd_table->header.lba3 = (char)(lba>>24);
139    cmd_table->header.lba4 = 0;
140    cmd_table->header.lba5 = 0;
141
142    // initialise command descriptor
143    cmd_desc->prdtl[0] = 1;
144    cmd_desc->prdtl[1] = 0;
145    if( to_mem ) cmd_desc->flag[0] = 0x00;
146    else         cmd_desc->flag[0] = 0x40;     
147
148#if USE_IOB    // software L2/L3 cache coherence
149
150    // compute physical addresses
151    unsigned long long cmd_desc_paddr;    // command descriptor physical address
152    unsigned long long cmd_table_paddr;   // command table header physical address
153    unsigned int       flags;             // unused
154
155    if ( _get_mmu_mode() & 0x4 )
156    {
157        cmd_desc_paddr  = _v2p_translate( (unsigned int)cmd_desc  , &flags );
158        cmd_table_paddr = _v2p_translate( (unsigned int)cmd_table , &flags );
159    }
160    else
161    {
162        cmd_desc_paddr  = (unsigned int)cmd_desc;
163        cmd_table_paddr = (unsigned int)cmd_table;
164    }
165
166    // update external memory for command table
167    _mmc_sync( cmd_table_paddr & (~0x3F) , sizeof(hba_cmd_table_t) );
168
169    // update external memory for command descriptor
170    _mmc_sync( cmd_desc_paddr & (~0x3F) , sizeof(hba_cmd_desc_t) );
171
172    // inval or synchronize memory buffer
173    if ( to_mem )  _mmc_inval( buf_paddr, count<<9 );
174    else           _mmc_sync( buf_paddr, count<<9 );
175
176#endif     // end software L2/L3 cache coherence
177
178    /////////////////////////////////////////////////////////////////////
179    // In synchronous mode, we poll the PXCI register until completion
180    /////////////////////////////////////////////////////////////////////
181    if ( use_irq == 0 ) 
182    {
183        // start HBA transfer
184        _hba_set_register( HBA_PXCI, (1<<ptw) );
185
186#if GIET_DEBUG_IOC_DRIVER
187if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
188_printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] get slot %d in Cmd List "
189        " at cycle %d / polling\n",
190        ptw , x , y , p , _get_proctime() );
191#endif
192        // disable IRQs in PXIE register
193        _hba_set_register( HBA_PXIE , 0 );
194
195        // poll PXCI[ptw] until command completed by HBA
196        do
197        {
198            pxci = _hba_get_register( HBA_PXCI );
199
200#if GIET_DEBUG_IOC_DRIVER
201if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
202_printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] wait on HBA_PXCI / pxci = %x\n",
203        x , y , p , pxci );
204#endif
205        }
206        while( pxci & (1<<ptw) ); 
207             
208        // get PXIS register
209        pxis = _hba_get_register( HBA_PXIS );
210
211        // reset PXIS register
212        _hba_set_register( HBA_PXIS , 0 );
213    }
214
215    /////////////////////////////////////////////////////////////////
216    // in descheduling mode, we deschedule the task
217    // and use an interrupt to reschedule the task.
218    // We need a critical section, because we must reset the RUN bit
219        // before to launch the transfer, and we don't want to be
220    // descheduled between these two operations.
221    /////////////////////////////////////////////////////////////////
222    else
223    {
224
225#if GIET_DEBUG_IOC_DRIVER
226if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
227_printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] get slot %d in Cmd List "
228        "at cycle %d / descheduling\n",
229        ptw , x , y , p , _get_proctime() );
230#endif
231        unsigned int save_sr;
232        unsigned int ltid = _get_current_task_id();
233
234        // activates HBA interrupts
235        _hba_set_register( HBA_PXIE , 0x00000001 ); 
236
237        // set _hba_gtid[ptw]
238        _hba_gtid[ptw] = (procid<<16) + ltid;
239
240        // enters critical section
241        _it_disable( &save_sr ); 
242
243        // reset runnable
244        _set_task_slot( x, y, p, ltid, CTX_RUN_ID, 0 ); 
245
246        // start HBA transfer
247        _hba_set_register( HBA_PXCI, (1<<ptw) );
248
249        // deschedule task
250        _ctx_switch();                     
251
252#if GIET_DEBUG_IOC_DRIVER
253if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
254_printf("\n[DEBUG HBA] _hba_access() : task %d on P[%d,%d,%d] resume at cycle %d\n",
255        ltid , x , y , p , _get_proctime() );
256#endif
257
258        // restore SR
259        _it_restore( &save_sr );
260
261        // get command status
262        pxis = _hba_status[ptw];
263    }   
264
265#if GIET_DEBUG_IOC_DRIVER
266if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
267_printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] exit at cycle %d\n",
268        x , y , p , _get_proctime() );
269#endif
270
271    if ( pxis & 0x40000000 ) return pxis;
272    else                     return 0;
273
274} // end _hba_access()
275
276
277////////////////////////
278unsigned int _hba_init()
279{
280    unsigned int       cmd_list_vaddr;
281    unsigned int       cmd_table_vaddr;
282    unsigned long long cmd_list_paddr;
283    unsigned long long cmd_table_paddr;
284    unsigned int       flags;            // unused
285
286    // compute Command list & command table physical addresses
287    cmd_list_vaddr  = (unsigned int)(&_hba_cmd_list[0]);
288    cmd_table_vaddr = (unsigned int)(&_hba_cmd_table[0]);
289    if ( _get_mmu_mode() & 0x4 )
290    {
291        cmd_list_paddr  = _v2p_translate( cmd_list_vaddr  , &flags );
292        cmd_table_paddr = _v2p_translate( cmd_table_vaddr , &flags );
293    }
294    else
295    {
296        cmd_list_paddr  = (unsigned long long)cmd_list_vaddr;
297        cmd_table_paddr = (unsigned long long)cmd_table_vaddr;
298    }
299
300    // initialise Command List pointers
301    _hba_cmd_ptw = 0;
302    _hba_cmd_ptr = 0;
303
304    // initialise Command Descriptors in Command List
305    unsigned int         c;     
306    unsigned long long   paddr;
307    for( c=0 ; c<32 ; c++ )
308    {
309        paddr = cmd_table_paddr + c * sizeof(hba_cmd_table_t);
310        _hba_cmd_list[c].ctba  = (unsigned int)(paddr);
311        _hba_cmd_list[c].ctbau = (unsigned int)(paddr>>32);
312    }
313
314    // initialise HBA registers
315    _hba_set_register( HBA_PXCLB  , (unsigned int)(cmd_list_paddr) );
316    _hba_set_register( HBA_PXCLBU , (unsigned int)(cmd_list_paddr>>32) );
317    _hba_set_register( HBA_PXIE   , 0 );
318    _hba_set_register( HBA_PXIS   , 0 );
319    _hba_set_register( HBA_PXCI   , 0 );
320    _hba_set_register( HBA_PXCMD  , 1 );
321
322    return 0;
323}
324
325
326/////////////////////////////////////////////////////
327void _hba_isr( unsigned int irq_type,   // HWI / WTI
328               unsigned int irq_id,     // index returned by ICU
329               unsigned int channel )   // unused
330{
331    // get HBA_PXCI containing commands status
332    unsigned int pxci = _hba_get_register( HBA_PXCI );
333
334    // we must handle all completed commands
335    // active commands are between  (_hba_cmd_ptr) and (_hba_cmd_ptw-1)
336    unsigned int current;
337    for ( current = _hba_cmd_ptr ; current != _hba_cmd_ptw ; current++ )
338    {
339        unsigned int ptr = current & 0x1F;
340       
341        if ( (pxci & (1<<ptr)) == 0 )    // command completed
342        {
343            // increment the 32 bits variable _hba_cmd_ptr
344            _hba_cmd_ptr = (_hba_cmd_ptr + 1);
345
346            // save PXIS register
347            _hba_status[ptr] = _hba_get_register( HBA_PXIS );
348
349            // reset PXIS register
350            _hba_set_register( HBA_PXIS , 0 );
351 
352            // identify waiting task
353            unsigned int remote_procid  = _hba_gtid[ptr]>>16;
354            unsigned int ltid           = _hba_gtid[ptr] & 0xFFFF;
355            unsigned int remote_cluster = remote_procid >> P_WIDTH;
356            unsigned int remote_x       = remote_cluster >> Y_WIDTH;
357            unsigned int remote_y       = remote_cluster & ((1<<Y_WIDTH)-1);
358            unsigned int remote_p       = remote_procid & ((1<<P_WIDTH)-1);
359 
360            // re-activates waiting task
361            _set_task_slot( remote_x,
362                            remote_y,
363                            remote_p,
364                            ltid,
365                            CTX_RUN_ID,
366                            1 );
367
368            // send a WAKUP WTI to processor running the waiting task
369            _xcu_send_wti( remote_cluster , 
370                           remote_p , 
371                           0 );          // don't force context switch
372
373#if GIET_DEBUG_IOC_DRIVER 
374if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
375_printf("\n[DEBUG HBA] _hba_isr() : command %d completed at cycle %d\n"
376        "  resume task %d running on P[%d,%d,%d] / status = %x\n",
377        ptr , _get_proctime() ,
378        ltid , remote_x , remote_y , remote_p , _hba_status[ptr] );
379#endif
380        }
381        else                         // command non completed
382        {
383            break;
384        }
385    }
386} // end _hba_isr()
387
388// Local Variables:
389// tab-width: 4
390// c-basic-offset: 4
391// c-file-offsets:((innamespace . 0)(inline-open . 0))
392// indent-tabs-mode: nil
393// End:
394// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
395
Note: See TracBrowser for help on using the repository browser.