Changeset 529 for soft/giet_vm/giet_drivers/bdv_driver.c
- Timestamp:
- Mar 27, 2015, 11:51:33 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_drivers/bdv_driver.c
r496 r529 2 2 // File : bdv_driver.c 3 3 // Date : 23/05/2013 4 // Author : alain greiner 5 // Maintainer: cesar fuguet 4 // Author : alain greiner cesar fuguet 6 5 // Copyright (c) UPMC-LIP6 7 6 /////////////////////////////////////////////////////////////////////////////////// 8 7 // Implementation notes: 9 // 1. In order to share code, the two _bdv_read() and _bdv_write() functions 10 // call the same _bdv_access() function. 11 // 2. All accesses to BDV registers are done by the two 12 // _bdv_set_register() and _bdv_get_register() low-level functions, 13 // that are handling virtual / physical extended addressing. 8 // All accesses to BDV registers are done by the two 9 // _bdv_set_register() and _bdv_get_register() low-level functions, 10 // that are handling virtual / physical extended addressing. 14 11 /////////////////////////////////////////////////////////////////////////////////// 15 12 … … 18 15 #include <bdv_driver.h> 19 16 #include <xcu_driver.h> 20 #include < ioc_driver.h>17 #include <kernel_locks.h> 21 18 #include <utils.h> 22 19 #include <tty0.h> 23 20 #include <ctx_handler.h> 24 25 /////////////////////////////////////////////////////////////////////////////// 26 // BDV global variables 27 /////////////////////////////////////////////////////////////////////////////// 28 21 #include <irq_handler.h> 22 23 /////////////////////////////////////////////////////////////////////////////// 24 // Global variables 25 /////////////////////////////////////////////////////////////////////////////// 26 27 // lock protecting single channel BDV peripheral 29 28 __attribute__((section(".kdata"))) 30 29 spin_lock_t _bdv_lock __attribute__((aligned(64))); 31 30 31 // global index of the waiting task (only used in descheduling mode) 32 __attribute__((section(".kdata"))) 33 unsigned int _bdv_gtid; 34 35 // BDV peripheral status (only used in descheduling mode) 32 36 __attribute__((section(".kdata"))) 33 37 unsigned int _bdv_status; 34 35 __attribute__((section(".kdata")))36 unsigned int _bdv_gtid;37 38 38 39 /////////////////////////////////////////////////////////////////////////////// … … 56 57 57 58 /////////////////////////////////////////////////////////////////////////////// 58 // This function transfer data between a memory buffer and the block device. 59 // The buffer lentgth is (count*block_size) bytes. 60 // Arguments are: 61 // - to_mem : from external storage to memory when non 0. 62 // - mode : BOOT / KERNEL / USER 63 // - lba : first block index on the external storage. 64 // - buf_paddr : physical base address of the memory buffer. 65 // - count : number of blocks to be transfered. 66 // Returns 0 if success, > 0 if error. 67 /////////////////////////////////////////////////////////////////////////////// 68 static unsigned int _bdv_access( unsigned int to_mem, 69 unsigned int mode, 70 unsigned int lba, 71 unsigned long long buf_paddr, 72 unsigned int count) 59 // Extern functions 60 /////////////////////////////////////////////////////////////////////////////// 61 62 ///////////////////////////////////////////////////// 63 unsigned int _bdv_access( unsigned int use_irq, 64 unsigned int to_mem, 65 unsigned int lba, 66 unsigned long long buf_paddr, 67 unsigned int count) 73 68 { 74 69 unsigned int procid = _get_procid(); … … 78 73 79 74 #if GIET_DEBUG_IOC_DRIVER 80 _puts("\n[BDV DEBUG] _bdv_access() : P["); 81 _putd( x ); 82 _puts(","); 83 _putd( y ); 84 _puts(","); 85 _putd( p ); 86 _puts("] enters at cycle "); 87 _putd( _get_proctime() ); 88 _puts("\n - to_mem = "); 89 _putd( to_mem ); 90 _puts("\n - mode = "); 91 _putd( mode ); 92 _puts("\n - paddr = "); 93 _putl( buf_paddr ); 94 _puts("\n - sectors = "); 95 _putd( count ); 96 _puts("\n - lba = "); 97 _putx( lba ); 98 _puts("\n"); 99 #endif 100 101 unsigned int error = 0; 75 _printf("\n[BDV DEBUG] P[%d,%d,%d] enters _bdv_access at cycle %d\n" 76 " use_irq = %d / to_mem = %d / lba = %x / paddr = %l / count = %d\n", 77 x , y , p , _get_proctime() , use_irq , to_mem , lba , buf_paddr, count ); 78 #endif 79 80 // check buffer alignment 81 if( buf_paddr & 0x1FF ) 82 { 83 _printf("\n[BDV ERROR] in _bdv_access() : buffer not block aligned\n"); 84 return -1; 85 } 86 87 unsigned int error; 88 unsigned int status; 102 89 103 90 // get the lock protecting BDV 104 91 _spin_lock_acquire( &_bdv_lock ); 105 106 #if GIET_DEBUG_IOC_DRIVER107 _puts("\n[BDV DEBUG] _bdv_access() : P[");108 _putd( x );109 _puts(",");110 _putd( y );111 _puts(",");112 _putd( p );113 _puts("] get _bdv_lock at cycle ");114 _putd( _get_proctime() );115 _puts("\n");116 #endif117 92 118 93 // set device registers … … 122 97 _bdv_set_register( BLOCK_DEVICE_LBA , lba ); 123 98 124 // In BOOT mode, we launch transfer, and poll the BDV_STATUS 125 // register because IRQs are masked. 126 if ( mode == IOC_BOOT_MODE ) 99 ///////////////////////////////////////////////////////////////////// 100 // In synchronous mode, we launch transfer, 101 // and poll the BDV_STATUS register until completion. 102 ///////////////////////////////////////////////////////////////////// 103 if ( use_irq == 0 ) 127 104 { 128 105 // Launch transfert … … 131 108 132 109 #if GIET_DEBUG_IOC_DRIVER 133 _puts("\n[BDV DEBUG] _bdv_access() : P["); 134 _putd( x ); 135 _puts(","); 136 _putd( y ); 137 _puts(","); 138 _putd( p ); 139 _puts("] launch transfer in polling mode at cycle "); 140 _putd( _get_proctime() ); 141 _puts("\n"); 142 #endif 143 unsigned int status; 110 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] launch transfer" 111 " in polling mode at cycle %d\n", 112 x , y , p , _get_proctime() ); 113 #endif 114 144 115 do 145 116 { … … 147 118 148 119 #if GIET_DEBUG_IOC_DRIVER 149 _puts("\n[BDV DEBUG] _bdv_access() : P["); 150 _putd( x ); 151 _puts(","); 152 _putd( y ); 153 _puts(","); 154 _putd( p ); 155 _puts("] wait on BDV_STATUS register ...\n"); 120 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] wait on BDV_STATUS ...\n", 121 x , y , p ); 156 122 #endif 157 123 } … … 164 130 error = ( (status == BLOCK_DEVICE_READ_ERROR) || 165 131 (status == BLOCK_DEVICE_WRITE_ERROR) ); 166 167 // release lock 168 _spin_lock_release( &_bdv_lock ); 169 } 170 // in USER or KERNEL mode, we deschedule the task. 171 // When the task is rescheduled, we check the _bdv_status variable, 172 // and release the lock. 132 } 133 134 ///////////////////////////////////////////////////////////////// 135 // in descheduling mode, we deschedule the task 136 // and use an interrupt to reschedule the task. 173 137 // We need a critical section, because we must reset the RUN bit 174 // before to launch the transfer, and we don't want to be descheduled 175 // between these two operations. 138 // before to launch the transfer, and we don't want to be 139 // descheduled between these two operations. 140 ///////////////////////////////////////////////////////////////// 176 141 else 177 142 { 178 143 unsigned int save_sr; 144 unsigned int wti_index; 179 145 unsigned int ltid = _get_current_task_id(); 180 146 181 // activates BDV interrupt s147 // activates BDV interrupt 182 148 _bdv_set_register( BLOCK_DEVICE_IRQ_ENABLE, 1 ); 183 149 184 // set the _bdv_status variable185 _bdv_status = BLOCK_DEVICE_BUSY;150 // allocate a WTI mailbox to the calling proc if external IRQ 151 if ( USE_PIC ) _ext_irq_alloc( ISR_BDV , 0 , &wti_index ); 186 152 187 153 // enters critical section … … 197 163 198 164 #if GIET_DEBUG_IOC_DRIVER 199 _puts("\n[BDV DEBUG] _bdv_access() : P["); 200 _putd( x ); 201 _puts(","); 202 _putd( y ); 203 _puts(","); 204 _putd( p ); 205 _puts("] launch transfer in interrupt mode at cycle "); 206 _putd( _get_proctime() ); 207 _puts("\n"); 165 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] launch transfer" 166 " in descheduling mode at cycle %d\n", 167 x , y , p , _get_proctime() ); 208 168 #endif 209 169 … … 212 172 213 173 #if GIET_DEBUG_IOC_DRIVER 214 _puts("\n[BDV DEBUG] _bdv_access() : P["); 215 _putd( x ); 216 _puts(","); 217 _putd( y ); 218 _puts(","); 219 _putd( p ); 220 _puts("] resume execution after descheduling\n"); 221 #endif 174 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] resume execution at cycle %d\n", 175 x , y , p , _get_proctime() ); 176 #endif 177 178 // release WTI mailbox if external IRQ 179 if ( USE_PIC ) _ext_irq_release( ISR_BDV , 0 , wti_index ); 180 222 181 // restore SR 223 182 _it_restore( &save_sr ); … … 226 185 error = ( (_bdv_status == BLOCK_DEVICE_READ_ERROR) || 227 186 (_bdv_status == BLOCK_DEVICE_WRITE_ERROR) ); 228 229 // reset _bdv_status and release lock 230 _bdv_status = BLOCK_DEVICE_IDLE; 231 _spin_lock_release( &_bdv_lock ); 232 } 233 234 #if GIET_DEBUG_IOC_DRIVER 235 _puts("\n[BDV DEBUG] _bdv_access() : P["); 236 _putd( x ); 237 _puts(","); 238 _putd( y ); 239 _puts(","); 240 _putd( p ); 241 _puts("] exit at cycle "); 242 _putd( _get_proctime() ); 243 _puts(" / error = "); 244 _putd( error ); 245 _puts("\n"); 187 } 188 189 // release lock 190 _spin_lock_release( &_bdv_lock ); 191 192 #if GIET_DEBUG_IOC_DRIVER 193 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] exit at cycle %d\n", 194 x , y , p , _get_proctime() ); 246 195 #endif 247 196 … … 249 198 } // end _bdv_access() 250 199 251 ///////////////////////////////////////////////////////////////////////////////252 // External functions253 ///////////////////////////////////////////////////////////////////////////////254 255 200 //////////////////////// 256 201 unsigned int _bdv_init() … … 264 209 _bdv_set_register( BLOCK_DEVICE_IRQ_ENABLE, 0 ); 265 210 return 0; 266 }267 268 ////////////////////////////////////////////////269 unsigned int _bdv_read( unsigned int mode,270 unsigned int lba,271 unsigned long long buffer,272 unsigned int count)273 {274 return _bdv_access( 1, // read access275 mode,276 lba,277 buffer,278 count );279 }280 281 /////////////////////////////////////////////////282 unsigned int _bdv_write( unsigned int mode,283 unsigned int lba,284 unsigned long long buffer,285 unsigned int count )286 {287 return _bdv_access( 0, // write access288 mode,289 lba,290 buffer,291 count );292 }293 294 //////////////////////////////295 unsigned int _bdv_get_status()296 {297 return _bdv_get_register( BLOCK_DEVICE_STATUS );298 }299 300 //////////////////////////////////301 unsigned int _bdv_get_block_size()302 {303 return _bdv_get_register( BLOCK_DEVICE_BLOCK_SIZE );304 211 } 305 212 … … 309 216 unsigned int channel ) // unused 310 217 { 311 // get BDV status (and reset IRQ)218 // get BDV status and reset BDV_IRQ 312 219 unsigned int status = _bdv_get_register( BLOCK_DEVICE_STATUS ); 313 220 … … 316 223 (status == BLOCK_DEVICE_BUSY) ) return; 317 224 318 // save status in kernel buffer _bdv_status319 _bdv_status = status; 225 // register status in global variable 226 _bdv_status = status; 320 227 321 228 // identify task waiting on BDV … … 333 240 ltid, 334 241 CTX_RUN_ID, // CTX_RUN slot 335 1 ); // running 336 337 // requires a context switch for remote processor running the waiting task242 1 ); // running value 243 244 // send a WAKUP WTI to processor running the sleeping task 338 245 _xcu_send_wti( remote_cluster, 339 246 remote_p, 340 0 ); // don't force context switch if not idle341 342 #if GIET_DEBUG_I RQS // we don't take the TTY lock to avoid deadlock247 0 ); // don't force context switch 248 249 #if GIET_DEBUG_IOC_DRIVER 343 250 unsigned int procid = _get_procid(); 344 251 unsigned int x = procid >> (Y_WIDTH + P_WIDTH); 345 252 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 346 253 unsigned int p = procid & ((1<<P_WIDTH)-1); 347 348 _puts("\n[IRQS DEBUG] Processor["); 349 _putd(x ); 350 _puts(","); 351 _putd(y ); 352 _puts(","); 353 _putd(p ); 354 _puts("] enters _bdv_isr() at cycle "); 355 _putd(_get_proctime() ); 356 _puts("\n for task "); 357 _putd(ltid ); 358 _puts(" running on processor["); 359 _putd(remote_x ); 360 _puts(","); 361 _putd(remote_y ); 362 _puts(","); 363 _putd(remote_p ); 364 _puts(" / bdv status = "); 365 _putx(_bdv_status ); 366 _puts("\n"); 367 #endif 368 369 } 254 _printf("\n[IOC DEBUG] Processor[%d,%d,%d] enters _bdv_isr() at cycle %d\n" 255 " for task %d running on P[%d,%d,%d] / bdv_status = %x\n", 256 x , y , p , _get_proctime() , 257 ltid , remote_x , remote_y , remote_p , status ); 258 #endif 259 260 } // end bdv_isr() 370 261 371 262
Note: See TracChangeset
for help on using the changeset viewer.