Changeset 647 for trunk/kernel/devices/dev_ioc.c
- Timestamp:
- Oct 22, 2019, 1:48:51 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/devices/dev_ioc.c
r637 r647 50 50 void dev_ioc_init( chdev_t * ioc ) 51 51 { 52 // the PIC chdev must be initialized before the IOC chdev, because 53 // the IOC chdev initialisation requires the routing of an external IRQ 54 xptr_t pic_xp = chdev_dir.pic; 55 56 assert( (pic_xp != XPTR_NULL) , "PIC not initialised before IOC" ); 57 58 // get implementation and channel from chdev descriptor 59 uint32_t impl = ioc->impl; 52 // get channel from chdev descriptor 60 53 uint32_t channel = ioc->channel; 61 54 … … 64 57 65 58 // call driver init function 66 hal_drivers_ioc_init( ioc , impl);59 hal_drivers_ioc_init( ioc ); 67 60 68 61 // select a core to execute the IOC server thread … … 90 83 ioc->server = new_thread; 91 84 92 // set "chdev field in thread descriptor85 // set "chdev" field in thread descriptor 93 86 new_thread->chdev = ioc; 94 87 … … 98 91 } // end dev_ioc_init() 99 92 100 ////////////////////////////////////////////////////////////////////////////////// 101 // This static function is called by dev_ioc_read() & dev_ioc_write() functions. 102 // It builds and registers the command in the calling thread descriptor. 103 // Then, it registers the calling thead in IOC chdev waiting queue. 104 // Finally it blocks on the THREAD_BLOCKED_IO condition and deschedule. 105 ////////////////////////////////////i///////////////////////////////////////////// 106 static error_t dev_ioc_access( uint32_t cmd_type, 107 uint8_t * buffer, 108 uint32_t lba, 109 uint32_t count ) 93 /////////////////////////////////////////////// 94 error_t dev_ioc_move_data( uint32_t cmd_type, 95 xptr_t buffer_xp, 96 uint32_t lba, 97 uint32_t count ) 110 98 { 111 99 thread_t * this = CURRENT_THREAD; // pointer on client thread 112 100 113 #if ( DE V_IOC_RX ||DEV_IOC_TX )101 #if ( DEBUG_DEV_IOC_RX || DEBUG_DEV_IOC_TX ) 114 102 uint32_t cycle = (uint32_t)hal_get_cycles(); 115 103 #endif … … 118 106 if( chdev_dir.iob ) 119 107 { 120 if (cmd_type == IOC_READ) dev_mmc_inval( XPTR( local_cxy , buffer ) , count<<9 ); 121 else dev_mmc_sync ( XPTR( local_cxy , buffer ) , count<<9 ); 108 if( (cmd_type == IOC_SYNC_READ) || (cmd_type == IOC_READ) ) 109 { 110 dev_mmc_inval( buffer_xp , count<<9 ); 111 } 112 else // (cmd_type == IOC_SYNC_WRITE) or (cmd_type == IOC_WRITE) 113 { 114 dev_mmc_sync ( buffer_xp , count<<9 ); 115 } 122 116 } 123 117 124 118 // get extended pointer on IOC chdev descriptor 125 xptr_t dev_xp= chdev_dir.ioc[0];119 xptr_t ioc_xp = chdev_dir.ioc[0]; 126 120 127 121 // check dev_xp 128 assert( (dev_xp != XPTR_NULL) , "undefined IOC chdev descriptor" );129 130 // register command in calling thread descriptor131 this->ioc_cmd.dev_xp = dev_xp;132 this->ioc_cmd.type = cmd_type;133 this->ioc_cmd.buf_xp = XPTR( local_cxy , buffer );134 this->ioc_cmd.lba = lba;135 this->ioc_cmd.count = count;136 137 // register client thread in IOC chdev waiting queue, activate server thread,138 // block client thread on THREAD_BLOCKED_IO and deschedule.139 // it is re-activated by the ISR signaling IO operation completion.140 chdev_register_command( dev_xp );141 142 #if(DEV_IOC_RX & 1)143 if( (DEV_IOC_RX < cycle) && (cmd_type != IOC_WRITE) )144 printk("\n[%s] thread[%x,%x] resumes for RX\n",145 __FUNCTION__, this->process->pid , this->trdid )146 #endif147 148 #if(DEV_IOC_TX & 1)149 if( (DEV_IOC_RX < cycle) && (cmd_type == IOC_WRITE) )150 printk("\n[%s] thread[%x,%x] resumes for TX\n",151 __FUNCTION__, this->process->pid , this->trdid )152 #endif153 154 // return I/O operation status155 return this->ioc_cmd.error;156 157 } // end dev_ioc_access()158 159 ////////////////////////////////////////////160 error_t dev_ioc_read( uint8_t * buffer,161 uint32_t lba,162 uint32_t count )163 {164 165 #if DEBUG_DEV_IOC_RX166 uint32_t cycle = (uint32_t)hal_get_cycles();167 thread_t * this = CURRENT_THREAD;168 if( DEBUG_DEV_IOC_RX < cycle )169 printk("\n[%s] thread[%x,%x] enters / lba %x / buffer %x / cycle %d\n",170 __FUNCTION__ , this->process->pid, this->trdid, lba, buffer, cycle );171 #endif172 173 return dev_ioc_access( IOC_READ , buffer , lba , count );174 }175 176 ////////////////////////////////////////////177 error_t dev_ioc_write( uint8_t * buffer,178 uint32_t lba,179 uint32_t count )180 {181 182 #if DEBUG_DEV_IOC_TX183 uint32_t cycle = (uint32_t)hal_get_cycles();184 thread_t * this = CURRENT_THREAD;185 if( DEBUG_DEV_IOC_TX < cycle )186 printk("\n[%s] thread[%x,%x] enters / lba %x / buffer %x / cycle %d\n",187 __FUNCTION__ , this->process->pid, this->trdid, lba, buffer, cycle );188 #endif189 190 return dev_ioc_access( IOC_WRITE , buffer , lba , count );191 }192 193 194 195 196 197 //////////////////////////////////////////////////////////////////////////////////198 // This static function is called by dev_ioc_sync_read() & dev_ioc_sync_write().199 // It builds and registers the command in the calling thread descriptor, and200 // calls directly the blocking IOC driver command, that returns only when the201 // IO operation is completed.202 ////////////////////////////////////i/////////////////////////////////////////////203 error_t dev_ioc_sync_access( uint32_t cmd_type,204 xptr_t buffer_xp,205 uint32_t lba,206 uint32_t count )207 {208 // get pointer on calling thread209 thread_t * this = CURRENT_THREAD;210 211 // software L2/L3 cache coherence for memory buffer212 if( chdev_dir.iob )213 {214 if (cmd_type == IOC_SYNC_READ) dev_mmc_inval( buffer_xp , count<<9 );215 else dev_mmc_sync ( buffer_xp , count<<9 );216 }217 218 // get extended pointer on IOC[0] chdev219 xptr_t ioc_xp = chdev_dir.ioc[0];220 221 // check ioc_xp222 122 assert( (ioc_xp != XPTR_NULL) , "undefined IOC chdev descriptor" ); 223 123 … … 229 129 this->ioc_cmd.count = count; 230 130 231 // get driver command function 232 cxy_t ioc_cxy = GET_CXY( ioc_xp ); 233 chdev_t * ioc_ptr = GET_PTR( ioc_xp ); 234 dev_cmd_t * cmd = (dev_cmd_t *)hal_remote_lpt( XPTR( ioc_cxy , &ioc_ptr->cmd ) ); 235 236 // get core local index for the core handling the IOC IRQ 237 thread_t * server = (thread_t *)hal_remote_lpt( XPTR( ioc_cxy , &ioc_ptr->server ) ); 238 core_t * core = (core_t *)hal_remote_lpt( XPTR( ioc_cxy , &server->core ) ); 239 lid_t lid = (lid_t)hal_remote_l32( XPTR( ioc_cxy , &core->lid ) ); 240 241 // mask the IRQ 242 dev_pic_disable_irq( lid , ioc_xp ); 243 244 // call driver function 245 cmd( XPTR( local_cxy , this ) ); 246 247 // unmask the IRQ 248 dev_pic_enable_irq( lid , ioc_xp ); 249 250 // return I/O operation status from calling thread descriptor 131 // for a synchronous acces, the driver is directly called by the client thread 132 if( (cmd_type == IOC_SYNC_READ) || (cmd_type == IOC_SYNC_WRITE) ) 133 { 134 135 #if DEBUG_DEV_IOC_RX 136 uint32_t cycle = (uint32_t)hal_get_cycles(); 137 if( (DEBUG_DEV_IOC_RX < cycle) && (cmd_type == IOC_SYNC_READ) ) 138 printk("\n[%s] thread[%x,%x] enters for SYNC_READ / lba %x / buffer[%x,%x] / cycle %d\n", 139 __FUNCTION__ , this->process->pid, this->trdid, lba, 140 GET_CXY(buffer_xp), GET_PTR(buffer_xp), cycle ); 141 #endif 142 143 #if DEBUG_DEV_IOC_TX 144 uint32_t cycle = (uint32_t)hal_get_cycles(); 145 if( (DEBUG_DEV_IOC_TX < cycle) && (cmd_type == IOC_SYNC_WRITE) ) 146 printk("\n[%s] thread[%x,%x] enters for SYNC_WRITE / lba %x / buffer[%x,%x] / cycle %d\n", 147 __FUNCTION__ , this->process->pid, this->trdid, lba, 148 GET_CXY(buffer_xp), GET_PTR(buffer_xp), cycle ); 149 #endif 150 // get driver command function 151 cxy_t ioc_cxy = GET_CXY( ioc_xp ); 152 chdev_t * ioc_ptr = GET_PTR( ioc_xp ); 153 dev_cmd_t * cmd = (dev_cmd_t *)hal_remote_lpt( XPTR( ioc_cxy , &ioc_ptr->cmd ) ); 154 155 // call driver function 156 cmd( XPTR( local_cxy , this ) ); 157 158 #if DEBUG_DEV_IOC_RX 159 if( (DEBUG_DEV_IOC_RX < cycle) && (cmd_type == IOC_SYNC_READ) ) 160 printk("\n[%s] thread[%x,%x] resumes for IOC_SYNC_READ\n", 161 __FUNCTION__, this->process->pid , this->trdid ) 162 #endif 163 164 #if DEBUG_DEV_IOC_TX 165 if( (DEBUG_DEV_IOC_RX < cycle) && (cmd_type == IOC_SYNC_WRITE) ) 166 printk("\n[%s] thread[%x,%x] resumes for IOC_SYNC_WRITE\n", 167 __FUNCTION__, this->process->pid , this->trdid ) 168 #endif 169 170 } 171 // for an asynchronous access, the client thread registers in the chdev waiting queue, 172 // activates server thread, blocks on THREAD_BLOCKED_IO and deschedules. 173 // It is re-activated by the server thread after IO operation completion. 174 else // (cmd_type == IOC_READ) || (cmd_type == IOC_WRITE) 175 { 176 177 #if DEBUG_DEV_IOC_RX 178 uint32_t cycle = (uint32_t)hal_get_cycles(); 179 if( (DEBUG_DEV_IOC_RX < cycle) && (cmd_type == IOC_READ) ) 180 printk("\n[%s] thread[%x,%x] enters for READ / lba %x / buffer[%x,%x] / cycle %d\n", 181 __FUNCTION__ , this->process->pid, this->trdid, lba, 182 GET_CXY(buffer_xp), GET_PTR(buffer_xp), cycle ); 183 #endif 184 185 #if DEBUG_DEV_IOC_TX 186 uint32_t cycle = (uint32_t)hal_get_cycles(); 187 if( (DEBUG_DEV_IOC_TX < cycle) && (cmd_type == IOC_WRITE) ) 188 printk("\n[%s] thread[%x,%x] enters for WRITE / lba %x / buffer[%x,%x] / cycle %d\n", 189 __FUNCTION__ , this->process->pid, this->trdid, lba, 190 GET_CXY(buffer_xp), GET_PTR(buffer_xp), cycle ); 191 #endif 192 chdev_register_command( ioc_xp ); 193 194 #if(DEBUG_DEV_IOC_RX ) 195 if( (DEBUG_DEV_IOC_RX < cycle) && (cmd_type == IOC_READ) ) 196 printk("\n[%s] thread[%x,%x] resumes for IOC_READ\n", 197 __FUNCTION__, this->process->pid , this->trdid ) 198 #endif 199 200 #if(DEBUG_DEV_IOC_TX & 1) 201 if( (DEBUG_DEV_IOC_RX < cycle) && (cmd_type == IOC_WRITE) ) 202 printk("\n[%s] thread[%x,%x] resumes for IOC_WRITE\n", 203 __FUNCTION__, this->process->pid , this->trdid ) 204 #endif 205 206 } 207 208 // return I/O operation status 251 209 return this->ioc_cmd.error; 252 210 253 } // end dev_ioc_sync_access() 254 255 //////////////////////////////////////////////// 256 error_t dev_ioc_sync_read( xptr_t buffer_xp, 257 uint32_t lba, 258 uint32_t count ) 259 { 260 261 #if DEBUG_DEV_IOC_RX 262 thread_t * this = CURRENT_THREAD; 263 uint32_t cycle = (uint32_t)hal_get_cycles(); 264 if( DEBUG_DEV_IOC_RX < cycle ) 265 printk("\n[%s] thread[%x,%x] : lba %x / buffer(%x,%x) / count %d / cycle %d\n", 266 __FUNCTION__ , this->process->pid, this->trdid, 267 lba, GET_CXY(buffer_xp), GET_PTR(buffer_xp), count, cycle ); 268 #endif 269 270 return dev_ioc_sync_access( IOC_SYNC_READ , buffer_xp , lba , count ); 271 } 272 273 ///////////////////////////////////////////////// 274 error_t dev_ioc_sync_write( xptr_t buffer_xp, 275 uint32_t lba, 276 uint32_t count ) 277 { 278 279 #if DEBUG_DEV_IOC_TX 280 thread_t * this = CURRENT_THREAD; 281 uint32_t cycle = (uint32_t)hal_get_cycles(); 282 if( DEBUG_DEV_IOC_TX < cycle ) 283 printk("\n[%s] thread[%x,%x] : lba %x / buffer(%x,%x) / count %d / cycle %d\n", 284 __FUNCTION__ , this->process->pid, this->trdid, 285 lba, GET_CXY(buffer_xp), GET_PTR(buffer_xp), count, cycle ); 286 #endif 287 288 return dev_ioc_sync_access( IOC_SYNC_WRITE , buffer_xp , lba , count ); 289 } 290 211 } // end dev_ioc_move_data() 212 213
Note: See TracChangeset
for help on using the changeset viewer.