Changeset 545 for soft/giet_vm/giet_drivers/hba_driver.c
- Timestamp:
- Apr 4, 2015, 11:32:20 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_drivers/hba_driver.c
r540 r545 15 15 #include <hba_driver.h> 16 16 #include <xcu_driver.h> 17 #include <mmc_driver.h> 17 18 #include <kernel_locks.h> 18 19 #include <utils.h> … … 36 37 // command list : up to 32 commands 37 38 __attribute__((section(".kdata"))) 38 hba_cmd_desc_t _hba_cmd_list[32] __attribute__((aligned(0x 10)));39 hba_cmd_desc_t _hba_cmd_list[32] __attribute__((aligned(0x40))); 39 40 40 41 // command tables array : one command table per entry in command list 41 42 __attribute__((section(".kdata"))) 42 hba_cmd_table_t _hba_cmd_table[32] __attribute__((aligned(0x 1000)));43 hba_cmd_table_t _hba_cmd_table[32] __attribute__((aligned(0x40))); 43 44 44 45 // command list write index : next slot to register a command … … 90 91 91 92 #if GIET_DEBUG_IOC_DRIVER 92 _printf("\n[ HBA DEBUG] P[%d,%d,%d] enters _hba_access at cycle %d\n"93 _printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] enters at cycle %d\n" 93 94 " use_irq = %d / to_mem = %d / lba = %x / paddr = %l / count = %d\n", 94 95 x , y , p , _get_proctime() , use_irq , to_mem , lba , buf_paddr, count ); 95 96 #endif 96 97 97 unsigned int pxci; // HBA_PXCI register value98 unsigned int ptw; // command list write pointer99 unsigned int pxis; // HBA_PXIS register value100 hba_cmd_desc_t* cmd_desc; // command descriptor pointer101 hba_cmd_table_t* cmd_table; // command table pointer98 unsigned int pxci; // HBA_PXCI register value 99 unsigned int ptw; // command list write pointer 100 unsigned int pxis; // HBA_PXIS register value 101 hba_cmd_desc_t* cmd_desc; // command descriptor pointer 102 hba_cmd_table_t* cmd_table; // command table pointer 102 103 103 104 // check buffer alignment 104 if( buf_paddr & 0x 1FF )105 { 106 _printf("\n[HBA ERROR] in _hba_access() : buffer not blockaligned\n");105 if( buf_paddr & 0x3F ) 106 { 107 _printf("\n[HBA ERROR] in _hba_access() : buffer not 64 bytes aligned\n"); 107 108 return -1; 108 109 } 109 110 110 // get pointer on the next possible entry in command list 111 ptw = _atomic_increment( &_hba_cmd_ptw , 1 ); 112 113 // poll PXCI register until pointed entry empty 111 // get one entry in Command List 112 // atomic increment on the _hba_cmd_ptw allocator 113 // only the 5 LSB bits are used to index the Command List 114 ptw = _atomic_increment( &_hba_cmd_ptw , 1 ) & 0x1F; 115 116 // blocked until allocated entry in Command List is empty 114 117 do 115 118 { … … 118 121 } 119 122 while ( pxci & (1<<ptw) ); 120 123 121 124 // compute pointers on command descriptor and command table 122 125 cmd_desc = &_hba_cmd_list[ptw]; … … 141 144 if( to_mem ) cmd_desc->flag[0] = 0x00; 142 145 else cmd_desc->flag[0] = 0x40; 143 144 // set command in PXCI[ptw] 145 _hba_set_register( HBA_PXCI, pxci + (1<<ptw) ); 146 146 147 #if USE_IOB // software L2/L3 cache coherence 148 149 // compute physical addresses 150 unsigned long long cmd_desc_paddr; // command descriptor physical address 151 unsigned long long cmd_table_paddr; // command table header physical address 152 unsigned int flags; // unused 153 154 if ( _get_mmu_mode() & 0x4 ) 155 { 156 cmd_desc_paddr = _v2p_translate( (unsigned int)cmd_desc , &flags ); 157 cmd_table_paddr = _v2p_translate( (unsigned int)cmd_table , &flags ); 158 } 159 else 160 { 161 cmd_desc_paddr = (unsigned int)cmd_desc; 162 cmd_table_paddr = (unsigned int)cmd_table; 163 } 164 165 // update external memory for command table 166 _mmc_sync( cmd_table_paddr & (~0x3F) , sizeof(hba_cmd_table_t) ); 167 168 // update external memory for command descriptor 169 _mmc_sync( cmd_desc_paddr & (~0x3F) , sizeof(hba_cmd_desc_t) ); 170 171 // inval or synchronize memory buffer 172 if ( to_mem ) _mmc_inval( buf_paddr, count<<9 ); 173 else _mmc_sync( buf_paddr, count<<9 ); 174 175 #endif // end software L2/L3 cache coherence 147 176 148 177 ///////////////////////////////////////////////////////////////////// … … 151 180 if ( use_irq == 0 ) 152 181 { 153 154 #if GIET_DEBUG_IOC_DRIVER 155 _printf("\n[HBA DEBUG] _hba_access() : P[%d,%d,%d] launch transfer" 156 " in polling mode at cycle %d\n", 157 x , y , p , _get_proctime() ); 182 // start HBA transfer 183 _hba_set_register( HBA_PXCI, (1<<ptw) ); 184 185 #if GIET_DEBUG_IOC_DRIVER 186 _printf("\n[DEBUG HBA] _hba_access() : command %d for P[%d,%d,%d]" 187 " at cycle %d / polling\n", 188 ptw , x , y , p , _get_proctime() ); 158 189 #endif 159 190 // disable IRQs in PXIE register … … 163 194 do 164 195 { 165 pxci = _hba_get_register( HBA_PXCI ) & (1<<ptw);166 167 #if GIET_DEBUG_IOC_DRIVER 168 _printf("\n[ HBA DEBUG] _hba_access() : P[%d,%d,%d] wait on HBA_STATUS ...\n",169 x , y , p );196 pxci = _hba_get_register( HBA_PXCI ); 197 198 #if GIET_DEBUG_IOC_DRIVER 199 _printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] wait on HBA_PXCI / pxci = %x\n", 200 x , y , p , pxci ); 170 201 #endif 171 202 } … … 190 221 191 222 #if GIET_DEBUG_IOC_DRIVER 192 _printf("\n[ HBA DEBUG] _hba_access() : P[%d,%d,%d] launch transfer"193 " in descheduling mode at cycle %d\n",194 x , y , p , _get_proctime() );223 _printf("\n[DEBUG HBA] _hba_access() : command %d for P[%d,%d,%d] " 224 "at cycle %d / descheduling\n", 225 ptw , x , y , p , _get_proctime() ); 195 226 #endif 196 227 unsigned int save_sr; … … 209 240 _set_task_slot( x, y, p, ltid, CTX_RUN_ID, 0 ); 210 241 242 // start HBA transfer 243 _hba_set_register( HBA_PXCI, (1<<ptw) ); 244 211 245 // deschedule task 212 246 _ctx_switch(); 213 247 214 248 #if GIET_DEBUG_IOC_DRIVER 215 _printf("\n[ HBA DEBUG] _hba_access() : P[%d,%d,%d] resume executionat cycle %d\n",216 x , y , p , _get_proctime() );249 _printf("\n[DEBUG HBA] _hba_access() : task %d on P[%d,%d,%d] resume at cycle %d\n", 250 ltid , x , y , p , _get_proctime() ); 217 251 #endif 218 252 … … 225 259 226 260 #if GIET_DEBUG_IOC_DRIVER 227 _printf("\n[ HBA DEBUG] _hba_access() : P[%d,%d,%d] exit at cycle %d\n",261 _printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] exit at cycle %d\n", 228 262 x , y , p , _get_proctime() ); 229 263 #endif … … 238 272 unsigned int _hba_init() 239 273 { 240 unsigned int flags; 241 unsigned int vaddr; 242 unsigned long long paddr; 243 unsigned int c; 244 unsigned int pxclb; 245 unsigned int pxclbu; 246 247 // command list pointers 274 unsigned int cmd_list_vaddr; 275 unsigned int cmd_table_vaddr; 276 unsigned long long cmd_list_paddr; 277 unsigned long long cmd_table_paddr; 278 unsigned int flags; // unused 279 280 // compute Command list & command table physical addresses 281 cmd_list_vaddr = (unsigned int)(&_hba_cmd_list[0]); 282 cmd_table_vaddr = (unsigned int)(&_hba_cmd_table[0]); 283 if ( _get_mmu_mode() & 0x4 ) 284 { 285 cmd_list_paddr = _v2p_translate( cmd_list_vaddr , &flags ); 286 cmd_table_paddr = _v2p_translate( cmd_table_vaddr , &flags ); 287 } 288 else 289 { 290 cmd_list_paddr = (unsigned long long)cmd_list_vaddr; 291 cmd_table_paddr = (unsigned long long)cmd_table_vaddr; 292 } 293 294 // initialise Command List pointers 248 295 _hba_cmd_ptw = 0; 249 296 _hba_cmd_ptr = 0; 250 297 251 // Command list physical addresse 252 vaddr = (unsigned int)(_hba_cmd_list); 253 paddr = _v2p_translate( vaddr , &flags ); 254 pxclb = (unsigned int)paddr; 255 pxclbu = (unsigned int)(paddr>>32); 256 257 // Command tables physical addresses 298 // initialise Command Descriptors in Command List 299 unsigned int c; 300 unsigned long long paddr; 258 301 for( c=0 ; c<32 ; c++ ) 259 302 { 260 // compute command table physical address 261 // for one entry in the command list 262 vaddr = (unsigned int)(&_hba_cmd_table[c]); 263 paddr = _v2p_translate( vaddr , &flags ); 264 265 // initialise the corresponding command descriptor 266 _hba_cmd_list[c].ctba = (unsigned int)paddr; 303 paddr = cmd_table_paddr + c * sizeof(hba_cmd_table_t); 304 _hba_cmd_list[c].ctba = (unsigned int)(paddr); 267 305 _hba_cmd_list[c].ctbau = (unsigned int)(paddr>>32); 268 306 } 269 307 270 // setHBA registers271 _hba_set_register( HBA_PXCLB , pxclb);272 _hba_set_register( HBA_PXCLBU , pxclbu);273 _hba_set_register( HBA_PXIE , 0);274 _hba_set_register( HBA_PXIS , 0);275 _hba_set_register( HBA_PXCI , 0);276 _hba_set_register( HBA_PXCMD , 1);308 // initialise HBA registers 309 _hba_set_register( HBA_PXCLB , (unsigned int)(cmd_list_paddr) ); 310 _hba_set_register( HBA_PXCLBU , (unsigned int)(cmd_list_paddr>>32) ); 311 _hba_set_register( HBA_PXIE , 0 ); 312 _hba_set_register( HBA_PXIS , 0 ); 313 _hba_set_register( HBA_PXCI , 0 ); 314 _hba_set_register( HBA_PXCMD , 1 ); 277 315 278 316 return 0; … … 280 318 281 319 282 ///////////////////////////////////// 320 ///////////////////////////////////////////////////// 283 321 void _hba_isr( unsigned int irq_type, // HWI / WTI 284 322 unsigned int irq_id, // index returned by ICU … … 288 326 unsigned int pxci = _hba_get_register( HBA_PXCI ); 289 327 290 // scan active commands from (_hba_cmd_ptr) to (_hba_cmd_ptw-1) 291 unsigned int c; 292 for ( c = _hba_cmd_ptr ; 293 c != _hba_cmd_ptw ; 294 c = (c + 1) % 32 ) 295 { 296 if ( (pxci & (1<<c)) == 0 ) // command completed 328 // we must handle all completed commands 329 // active commands are between (_hba_cmd_ptr) and (_hba_cmd_ptw-1) 330 unsigned int current; 331 for ( current = _hba_cmd_ptr ; current != _hba_cmd_ptw ; current++ ) 332 { 333 unsigned int ptr = current & 0x1F; 334 335 if ( (pxci & (1<<ptr)) == 0 ) // command completed 297 336 { 298 // increment read pointer;299 _hba_cmd_ptr ++;337 // increment the 32 bits variable _hba_cmd_ptr 338 _hba_cmd_ptr = (_hba_cmd_ptr + 1); 300 339 301 340 // save PXIS register 302 _hba_status[ c] = _hba_get_register( HBA_PXIS );341 _hba_status[ptr] = _hba_get_register( HBA_PXIS ); 303 342 304 343 // reset PXIS register … … 306 345 307 346 // identify waiting task 308 unsigned int remote_procid = _hba_gtid[ c]>>16;309 unsigned int ltid = _hba_gtid[ c] & 0xFFFF;347 unsigned int remote_procid = _hba_gtid[ptr]>>16; 348 unsigned int ltid = _hba_gtid[ptr] & 0xFFFF; 310 349 unsigned int remote_cluster = remote_procid >> P_WIDTH; 311 350 unsigned int remote_x = remote_cluster >> Y_WIDTH; … … 327 366 328 367 #if GIET_DEBUG_IOC_DRIVER 329 unsigned int procid = _get_procid(); 330 unsigned int x = procid >> (Y_WIDTH + P_WIDTH); 331 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 332 unsigned int p = procid & ((1<<P_WIDTH)-1); 333 _printf("\n[HBA DEBUG] Processor[%d,%d,%d] executes _hba_isr() :\n" 334 " resume task %d running on P[%d,%d,%d] / status = %x at cyle %d\n", 335 x , y , p , 336 ltid , remote_x , remote_y , remote_p , _hba_status[c] , _get_proctime() ); 368 _printf("\n[DEBUG HBA] _hba_isr() : command %d completed at cycle %d\n" 369 " resume task %d running on P[%d,%d,%d] / status = %x\n", 370 ptr , _get_proctime() , 371 ltid , remote_x , remote_y , remote_p , _hba_status[ptr] ); 337 372 #endif 338 373 }
Note: See TracChangeset
for help on using the changeset viewer.