Changeset 614 for trunk/kernel/devices
- Timestamp:
- Jan 15, 2019, 1:59:32 PM (6 years ago)
- Location:
- trunk/kernel/devices
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/devices/dev_ioc.c
r605 r614 91 91 // This static function is called by dev_ioc_read() & dev_ioc_write() functions. 92 92 // It builds and registers the command in the calling thread descriptor. 93 // Then, it registers the calling thead in IOC chdev waiting queue.93 // Then, it registers the calling thead in IOC chdev waiting queue. 94 94 // Finally it blocks on the THREAD_BLOCKED_IO condition and deschedule. 95 95 ////////////////////////////////////i///////////////////////////////////////////// … … 108 108 if( chdev_dir.iob ) 109 109 { 110 if ( cmd_type == IOC_READ) dev_mmc_inval( XPTR( local_cxy , buffer ) , count<<9 );111 else 110 if (cmd_type == IOC_READ) dev_mmc_inval( XPTR( local_cxy , buffer ) , count<<9 ); 111 else dev_mmc_sync ( XPTR( local_cxy , buffer ) , count<<9 ); 112 112 } 113 113 … … 162 162 163 163 return dev_ioc_access( IOC_READ , buffer , lba , count ); 164 165 #if DEBUG_DEV_IOC_RX166 cycle = (uint32_t)hal_get_cycles();167 if( DEBUG_DEV_IOC_RX < cycle )168 printk("\n[%s] thread[%x,%x] exit / lba %x / buffer %x / cycle %d\n",169 __FUNCTION__ , this->process->pid, this->trdid, lba, buffer, cycle );170 #endif171 172 164 } 173 165 … … 187 179 188 180 return dev_ioc_access( IOC_WRITE , buffer , lba , count ); 189 190 #if DEBUG_DEV_IOC_TX191 cycle = (uint32_t)hal_get_cycles();192 if( DEBUG_DEV_IOC_TX < cycle )193 printk("\n[%s] thread[%x,%x] exit / lba %x / buffer %x / cycle %d\n",194 __FUNCTION__ , this->process->pid, this->trdid, lba, buffer, cycle );195 #endif196 197 181 } 182 183 184 185 186 187 ////////////////////////////////////////////////////////////////////////////////// 188 // This static function is called by dev_ioc_sync_read() & dev_ioc_sync_write(). 189 // It builds and registers the command in the calling thread descriptor, and 190 // calls directly the blocking IOC driver command, that returns only when the 191 // IO operation is completed. 192 ////////////////////////////////////i///////////////////////////////////////////// 193 error_t dev_ioc_sync_access( uint32_t cmd_type, 194 uint8_t * buffer, 195 uint32_t lba, 196 uint32_t count ) 197 { 198 // get pointer on calling thread 199 thread_t * this = CURRENT_THREAD; 200 201 // software L2/L3 cache coherence for memory buffer 202 if( chdev_dir.iob ) 203 { 204 if (cmd_type == IOC_SYNC_READ) dev_mmc_inval( XPTR(local_cxy,buffer) , count<<9 ); 205 else dev_mmc_sync ( XPTR(local_cxy,buffer) , count<<9 ); 206 } 207 208 // get extended pointer on IOC[0] chdev 209 xptr_t ioc_xp = chdev_dir.ioc[0]; 210 211 // check ioc_xp 212 assert( (ioc_xp != XPTR_NULL) , "undefined IOC chdev descriptor" ); 213 214 // register command in calling thread descriptor 215 this->ioc_cmd.dev_xp = ioc_xp; 216 this->ioc_cmd.type = cmd_type; 217 this->ioc_cmd.buf_xp = XPTR( local_cxy , buffer ); 218 this->ioc_cmd.lba = lba; 219 this->ioc_cmd.count = count; 220 221 // get driver command function 222 cxy_t ioc_cxy = GET_CXY( ioc_xp ); 223 chdev_t * ioc_ptr = GET_PTR( ioc_xp ); 224 dev_cmd_t * cmd = (dev_cmd_t *)hal_remote_lpt( XPTR( ioc_cxy , &ioc_ptr->cmd ) ); 225 226 // get core local index for the core handling the IOC IRQ 227 thread_t * server = (thread_t *)hal_remote_lpt( XPTR( ioc_cxy , &ioc_ptr->server ) ); 228 core_t * core = (core_t *)hal_remote_lpt( XPTR( ioc_cxy , &server->core ) ); 229 lid_t lid = (lid_t)hal_remote_l32( XPTR( ioc_cxy , &core->lid ) ); 230 231 // mask the IRQ 232 dev_pic_disable_irq( lid , ioc_xp ); 233 234 // call driver function 235 cmd( XPTR( local_cxy , this ) ); 236 237 // unmask the IRQ 238 dev_pic_enable_irq( lid , ioc_xp ); 239 240 // return I/O operation status from calling thread descriptor 241 return this->ioc_cmd.error; 242 243 } // end ioc_sync_access() 198 244 199 245 ///////////////////////////////////////////// … … 202 248 uint32_t count ) 203 249 { 204 // get pointer on calling thread205 thread_t * this = CURRENT_THREAD;206 250 207 251 #if DEBUG_DEV_IOC_RX 208 uint32_t cycle = (uint32_t)hal_get_cycles(); 252 thread_t * this = CURRENT_THREAD; 253 uint32_t cycle = (uint32_t)hal_get_cycles(); 254 if( DEBUG_DEV_IOC_RX < cycle ) 255 printk("\n[%s] thread[%x,%x] : lba %x / buffer %x / cycle %d\n", 256 __FUNCTION__ , this->process->pid, this->trdid, lba, buffer, cycle ); 257 #endif 258 259 return dev_ioc_sync_access( IOC_SYNC_READ , buffer , lba , count ); 260 } 261 262 ////////////////////////////////////////////// 263 error_t dev_ioc_sync_write( uint8_t * buffer, 264 uint32_t lba, 265 uint32_t count ) 266 { 267 268 #if DEBUG_DEV_IOC_RX 269 thread_t * this = CURRENT_THREAD; 270 uint32_t cycle = (uint32_t)hal_get_cycles(); 209 271 if( DEBUG_DEV_IOC_RX < cycle ) 210 272 printk("\n[%s] thread[%x,%x] enters / lba %x / buffer %x / cycle %d\n", … … 212 274 #endif 213 275 214 // software L2/L3 cache coherence for memory buffer 215 if( chdev_dir.iob ) dev_mmc_inval( XPTR( local_cxy , buffer ) , count<<9 ); 216 217 // get extended pointer on IOC[0] chdev 218 xptr_t ioc_xp = chdev_dir.ioc[0]; 219 220 assert( (ioc_xp != XPTR_NULL) , "undefined IOC chdev descriptor" ); 221 222 // register command in calling thread descriptor 223 this->ioc_cmd.dev_xp = ioc_xp; 224 this->ioc_cmd.type = IOC_SYNC_READ; 225 this->ioc_cmd.buf_xp = XPTR( local_cxy , buffer ); 226 this->ioc_cmd.lba = lba; 227 this->ioc_cmd.count = count; 228 229 // get driver command function 230 cxy_t ioc_cxy = GET_CXY( ioc_xp ); 231 chdev_t * ioc_ptr = (chdev_t *)GET_PTR( ioc_xp ); 232 dev_cmd_t * cmd = (dev_cmd_t *)hal_remote_lpt( XPTR( ioc_cxy , &ioc_ptr->cmd ) ); 233 234 // get core local index for the core handling the IOC IRQ 235 thread_t * server = (thread_t *)hal_remote_lpt( XPTR( ioc_cxy , &ioc_ptr->server ) ); 236 core_t * core = (core_t *)hal_remote_lpt( XPTR( ioc_cxy , &server->core ) ); 237 lid_t lid = (lid_t)hal_remote_l32( XPTR( ioc_cxy , &core->lid ) ); 238 239 // mask the IRQ 240 dev_pic_disable_irq( lid , ioc_xp ); 241 242 // call driver function 243 cmd( XPTR( local_cxy , this ) ); 244 245 // unmask the IRQ 246 dev_pic_enable_irq( lid , ioc_xp ); 247 248 #if DEBUG_DEV_IOC_RX 249 cycle = (uint32_t)hal_get_cycles(); 250 if( DEBUG_DEV_IOC_RX < cycle ) 251 printk("\n[%s] thread[%x,%x] exit / lba %x / buffer %x / cycle %d\n", 252 __FUNCTION__ , this->process->pid, this->trdid, lba, buffer, cycle ); 253 #endif 254 255 // return I/O operation status from calling thread descriptor 256 return this->ioc_cmd.error; 257 258 } // end ioc_sync_read() 259 276 return dev_ioc_sync_access( IOC_SYNC_WRITE , buffer , lba , count ); 277 } 278 -
trunk/kernel/devices/dev_ioc.h
r457 r614 38 38 * magnetic hard disk or a SD card, that can store blocks of data in a linear array 39 39 * of sectors indexed by a simple lba (logic block address). 40 * It supports three command types: 41 * - READ : move blocks from device to memory, with a descheduling policy. 42 * - WRITE : move blocks from memory to device, with a descheduling policy. 43 * - SYNC_READ : move blocks from device to memory, with a busy waiting policy. 40 * It supports four command types: 41 * - READ : move blocks from device to memory, with a descheduling policy. 42 * - WRITE : move blocks from memory to device, with a descheduling policy. 43 * - SYNC_READ : move blocks from device to memory, with a busy waiting policy. 44 * - SYNC_WRITE : move blocks from memory to device, with a busy waiting policy. 44 45 45 46 * A READ or WRITE operation requires dynamic ressource allocation. The calling thread … … 64 65 * 3) release the WTI mailbox to the client cluster WTI allocator. 65 66 * 66 * The SYNC_READ operation is used by the kernel in the initialisation phase. It does67 * not uses the IOC device waiting queue and server thread, and does not use the IOC IRQ,68 * but implement a busy-waiting policy for the calling thread.67 * The SYNC_READ and SYNC_WRITE operations are used by the kernel in the initialisation 68 * phase. These operations do not not use the IOC device waiting queue, the server thread, 69 * and the IOC IRQ, but implement a busy-waiting policy for the calling thread. 69 70 *****************************************************************************************/ 70 71 … … 85 86 *****************************************************************************************/ 86 87 87 enum ioc_impl_e 88 typedef enum 88 89 { 89 90 IMPL_IOC_BDV = 0, … … 99 100 *****************************************************************************************/ 100 101 101 enum102 typedef enum 102 103 { 103 104 IOC_READ = 0, 104 105 IOC_WRITE = 1, 105 106 IOC_SYNC_READ = 2, 106 }; 107 IOC_SYNC_WRITE = 3, 108 } 109 cmd_type_t; 107 110 108 111 typedef struct ioc_command_s … … 131 134 132 135 /****************************************************************************************** 133 * This blocking function try to tranferone or several contiguous blocks of data136 * This blocking function moves one or several contiguous blocks of data 134 137 * from the block device to a local memory buffer. The corresponding request is actually 135 138 * registered in the device pending request queue, and the calling thread is descheduled, … … 147 150 148 151 /****************************************************************************************** 149 * This blocking function try to tranferone or several contiguous blocks of data152 * This blocking function moves one or several contiguous blocks of data 150 153 * from a local memory buffer to the block device. The corresponding request is actually 151 154 * registered in the device pending request queue, and the calling thread is descheduled, … … 163 166 164 167 /****************************************************************************************** 165 * This blocking function try to tranferone or several contiguous blocks of data166 * from the block device to a memory buffer.168 * This blocking function moves one or several contiguous blocks of data 169 * from the block device to a local memory buffer. 167 170 * It does not uses the IOC device waiting queue and server thread, and does not use 168 171 * the IOC IRQ, but call directly the relevant IOC driver, implementing a busy-waiting … … 179 182 uint32_t count ); 180 183 184 /****************************************************************************************** 185 * This blocking function moves one or several contiguous blocks of data 186 * from a local memory buffer to the block device. 187 * It does not uses the IOC device waiting queue and server thread, and does not use 188 * the IOC IRQ, but call directly the relevant IOC driver, implementing a busy-waiting 189 * policy for the calling thread. 190 * It must be called in the client cluster. 191 ****************************************************************************************** 192 * @ buffer : local pointer on source buffer in memory (must be block aligned). 193 * @ lba : first block index on device. 194 * @ count : number of blocks to transfer. 195 * @ returns 0 if success / returns EINVAL if error. 196 *****************************************************************************************/ 197 error_t dev_ioc_sync_write( uint8_t * buffer, 198 uint32_t lba, 199 uint32_t count ); 200 181 201 #endif /* _DEV_IOC_H */
Note: See TracChangeset
for help on using the changeset viewer.