Changeset 576
- Timestamp:
- May 21, 2015, 3:03:39 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_drivers/hba_driver.c
r563 r576 27 27 /////////////////////////////////////////////////////////////////////////////////// 28 28 29 // global index ot the task, for each entry in the command list 30 __attribute__((section(".kdata"))) 31 unsigned int _hba_gtid[32]; 32 33 // status of the command, for each entry in the command list 34 __attribute__((section(".kdata"))) 35 unsigned int _hba_status[32]; 29 ////////////////////////////////////////////////////////////////////////////////// 30 // The global variable hba_boot_mode defines the way the HBA component is used 31 // and must be defined in both kernel_init.c and boot.c files. 32 // - during the boot phase, only one processor has access to the HBA in synchronous 33 // mode, there is no need for the allocator to use a lock 34 // - after the boot phase, the HBA device can be used by several processors. The 35 // allocator is protected by a sqt_lock. 36 ////////////////////////////////////////////////////////////////////////////////// 37 38 extern unsigned int _hba_boot_mode; 39 40 __attribute__((section(".kdata"))) 41 sqt_lock_t _hba_allocator_lock __attribute__((aligned(64))); 42 43 // state of each slot (allocated to a task or not) 44 // access must be protected by the allocator_lock in descheduling mode 45 __attribute__((section(".kdata"))) 46 unsigned int _hba_allocated_cmd[32]; 47 48 // state of the command (active or not), for each possible slot 49 // used only in descheduling mode 50 __attribute__((section(".kdata"))) 51 unsigned int _hba_active_cmd[32]; 52 53 // global index of the task, for each entry in the command list 54 __attribute__((section(".kdata"))) 55 unsigned int _hba_gtid[32]; 56 57 // status of HBA commands 58 __attribute__((section(".kdata"))) 59 unsigned int _hba_status; 36 60 37 61 // command list : up to 32 commands 38 62 __attribute__((section(".kdata"))) 39 hba_cmd_desc_t _hba_cmd_list[32] __attribute__((aligned(0x40)));63 hba_cmd_desc_t _hba_cmd_list[32] __attribute__((aligned(0x40))); 40 64 41 65 // command tables array : one command table per entry in command list 42 66 __attribute__((section(".kdata"))) 43 hba_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"))) 47 unsigned int _hba_cmd_ptw; 48 49 // command list read index : next slot to poll a completed command 50 __attribute__((section(".kdata"))) 51 unsigned int _hba_cmd_ptr; 67 hba_cmd_table_t _hba_cmd_table[32] __attribute__((aligned(0x40))); 68 52 69 53 70 ////////////////////////////////////////////////////////////////////////////// … … 75 92 76 93 /////////////////////////////////////////////////////////////////////////////// 77 // This function register a command in both the command list 78 // and the command table, and updates the HBA_PXCI register. 94 // This blocking fonction allocates a free command index to the task. 95 // The hba_allocator_lock is used except in boot mode. 96 // It returns the allocated command index (between 0 and 31) 97 /////////////////////////////////////////////////////////////////////////////// 98 unsigned int _hba_cmd_alloc() 99 { 100 unsigned int found = 0; 101 unsigned int c; // command index for the loop 102 unsigned int cmd_id = -1; // allocated command index when found 103 104 while ( found == 0) 105 { 106 if ( !_hba_boot_mode ) 107 _sqt_lock_acquire(&_hba_allocator_lock); 108 109 for ( c = 0; c < 32 ; c++ ) 110 { 111 if (_hba_allocated_cmd[c] == 0) 112 { 113 found = 1; 114 cmd_id = c; 115 _hba_allocated_cmd[c] = 1; 116 break; 117 } 118 } 119 120 if ( !_hba_boot_mode ) 121 _sqt_lock_release(&_hba_allocator_lock); 122 } 123 124 return cmd_id; 125 } 126 127 /////////////////////////////////////////////////////////////////////////////// 128 // This function releases the command index in the hba_allocated_cmd table. 129 // There is no need to take the lock because only the task which owns the 130 // command can release it. 131 // return 0 if success, -1 if error 132 /////////////////////////////////////////////////////////////////////////////// 133 unsigned int _hba_cmd_release(unsigned int cmd_id) 134 { 135 if ( _hba_allocated_cmd[cmd_id] == 0 ) 136 { 137 _printf("\n[HBA ERROR] in _hba_access() : ask to release a command which is not allocated\n"); 138 return -1; 139 } 140 141 _hba_allocated_cmd[cmd_id] = 0; 142 return 0; 143 } 144 145 146 /////////////////////////////////////////////////////////////////////////////// 147 // This function gets a command index with the hba_cmd_alloc function. Then it 148 // registers a command in both the command list and the command table. It 149 // updates the HBA_PXCI register and the hba_active_cmd in descheduling mode. 150 // At the end the command slot is released. 79 151 // return 0 if success, -1 if error 80 152 /////////////////////////////////////////////////////////////////////////////// … … 97 169 #endif 98 170 171 unsigned int cmd_id; // command index 99 172 unsigned int pxci; // HBA_PXCI register value 100 unsigned int ptw; // command list write pointer101 173 unsigned int pxis; // HBA_PXIS register value 102 174 hba_cmd_desc_t* cmd_desc; // command descriptor pointer … … 111 183 112 184 // 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) ); 185 cmd_id = _hba_cmd_alloc(); 124 186 125 187 // compute pointers on command descriptor and command table 126 cmd_desc = &_hba_cmd_list[ ptw];127 cmd_table = &_hba_cmd_table[ ptw];188 cmd_desc = &_hba_cmd_list[cmd_id]; 189 cmd_table = &_hba_cmd_table[cmd_id]; 128 190 129 191 // set buffer descriptor in command table … … 182 244 { 183 245 // start HBA transfer 184 _hba_set_register( HBA_PXCI, (1<< ptw) );246 _hba_set_register( HBA_PXCI, (1<<cmd_id) ); 185 247 186 248 #if GIET_DEBUG_IOC_DRIVER … … 188 250 _printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] get slot %d in Cmd List " 189 251 " at cycle %d / polling\n", 190 ptw , x , y , p, _get_proctime() );252 x , y , p , cmd_id, _get_proctime() ); 191 253 #endif 192 254 // disable IRQs in PXIE register 193 255 _hba_set_register( HBA_PXIE , 0 ); 194 256 195 // poll PXCI[ ptw] until command completed by HBA257 // poll PXCI[cmd_id] until command completed by HBA 196 258 do 197 259 { … … 204 266 #endif 205 267 } 206 while( pxci & (1<< ptw) );268 while( pxci & (1<<cmd_id) ); 207 269 208 270 // get PXIS register … … 227 289 _printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] get slot %d in Cmd List " 228 290 "at cycle %d / descheduling\n", 229 ptw , x , y , p, _get_proctime() );291 x , y , p , cmd_id, _get_proctime() ); 230 292 #endif 231 293 unsigned int save_sr; … … 235 297 _hba_set_register( HBA_PXIE , 0x00000001 ); 236 298 237 // set _hba_gtid[ ptw]238 _hba_gtid[ ptw] = (procid<<16) + ltid;299 // set _hba_gtid[cmd_id] 300 _hba_gtid[cmd_id] = (procid<<16) + ltid; 239 301 240 302 // enters critical section … … 245 307 246 308 // start HBA transfer 247 _hba_set_register( HBA_PXCI, (1<<ptw) ); 309 _hba_set_register( HBA_PXCI, (1<<cmd_id) ); 310 311 // set _hba_active_cmd[cmd_id] 312 _hba_active_cmd[cmd_id] = 1; 248 313 249 314 // deschedule task … … 260 325 261 326 // get command status 262 pxis = _hba_status[ptw]; 263 } 264 265 #if GIET_DEBUG_IOC_DRIVER 266 if (_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; 327 pxis = _hba_status; 328 } 329 330 // release the cmd index 331 unsigned int release_success; 332 release_success = _hba_cmd_release(cmd_id); 333 334 #if GIET_DEBUG_IOC_DRIVER 335 if (_get_proctime() > GIET_DEBUG_IOC_DRIVER) 336 _printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] release slot %d in Cmd List " 337 "and exit at cycle %d\n", 338 x , y , p, cmd_id, 339 _get_proctime() ); 340 #endif 341 342 if ( release_success != 0 ) return -1; 343 else if ( pxis & 0x40000000 ) return pxis; 344 else return 0; 273 345 274 346 } // end _hba_access() … … 298 370 } 299 371 300 // initialise Command List pointers 301 _hba_cmd_ptw = 0; 302 _hba_cmd_ptr = 0; 303 304 // initialise Command Descriptors in Command List 372 // initialise allocator lock if not in boot mode 373 if ( !_hba_boot_mode ) 374 _sqt_lock_init(&_hba_allocator_lock); 375 376 // initialise Command Descriptors in Command List, allocated command table 377 // and active command table 305 378 unsigned int c; 306 379 unsigned long long paddr; … … 310 383 _hba_cmd_list[c].ctba = (unsigned int)(paddr); 311 384 _hba_cmd_list[c].ctbau = (unsigned int)(paddr>>32); 385 _hba_allocated_cmd[c] = 0; 386 _hba_active_cmd[c] = 0; 312 387 } 313 388 … … 329 404 unsigned int channel ) // unused 330 405 { 406 // save PXIS register if there is no previous error 407 if ( !(_hba_status & 0x40000000)) 408 _hba_status = _hba_get_register( HBA_PXIS ); 409 410 // reset PXIS register 411 _hba_set_register( HBA_PXIS , 0 ); 412 413 unsigned int cmd_id; // cmd index for the loops 414 415 // save the current list of active cmd in a 32 bits word 416 unsigned int current_active_cmd = 0; 417 for ( cmd_id = 0 ; cmd_id < 32 ; cmd_id ++ ) 418 { 419 if ( _hba_active_cmd[cmd_id] == 1 ) current_active_cmd += (1 << cmd_id); 420 } 421 331 422 // 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 423 unsigned int current_pxci = _hba_get_register( HBA_PXCI ); 424 425 for ( cmd_id = 0 ; cmd_id < 32 ; cmd_id ++ ) 426 { 427 if ( ( (current_active_cmd & (1<<cmd_id)) != 0) && // active command 428 ( (current_pxci & (1<<cmd_id)) == 0 ) ) // completed command 342 429 { 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 430 // desactivate the command 431 _hba_active_cmd[cmd_id] = 0; 432 352 433 // identify waiting task 353 unsigned int remote_procid = _hba_gtid[ ptr]>>16;354 unsigned int ltid = _hba_gtid[ ptr] & 0xFFFF;434 unsigned int remote_procid = _hba_gtid[cmd_id]>>16; 435 unsigned int ltid = _hba_gtid[cmd_id] & 0xFFFF; 355 436 unsigned int remote_cluster = remote_procid >> P_WIDTH; 356 437 unsigned int remote_x = remote_cluster >> Y_WIDTH; … … 374 455 if (_get_proctime() > GIET_DEBUG_IOC_DRIVER) 375 456 _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; 457 " resume task %d running on P[%d,%d,%d]\n", 458 cmd_id , _get_proctime() , 459 ltid , remote_x , remote_y , remote_p ); 460 #endif 384 461 } 385 462 }
Note: See TracChangeset
for help on using the changeset viewer.