Changeset 407 for trunk/kernel/kern/chdev.c
- Timestamp:
- Nov 7, 2017, 3:08:12 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/chdev.c
r317 r407 25 25 #include <hal_types.h> 26 26 #include <hal_special.h> 27 #include <hal_irqmask.h> 27 28 #include <printk.h> 28 29 #include <boot_info.h> 29 30 #include <xlist.h> 30 31 #include <kmem.h> 32 #include <scheduler.h> 31 33 #include <thread.h> 32 34 #include <rpc.h> … … 37 39 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 38 40 41 #if CONFIG_READ_DEBUG 42 extern uint32_t enter_chdev_cmd; 43 extern uint32_t exit_chdev_cmd; 44 extern uint32_t enter_chdev_server; 45 extern uint32_t exit_chdev_server; 46 #endif 39 47 40 48 //////////////////////////////////////////// … … 105 113 } 106 114 107 //////////////////////////////////////////////// 108 void chdev_register_command( xptr_t chdev_xp, 109 thread_t * thread ) 110 { 111 thread_t * thread_ptr = CURRENT_THREAD; 115 ////////////////////////////////////////////////// 116 void chdev_register_command( xptr_t chdev_xp ) 117 { 118 thread_t * server_ptr; // local pointer on server thread associated to chdev 119 core_t * core_ptr; // local pointer on core running the server thread 120 uint32_t lid; // core running the server thread local index 121 xptr_t lock_xp; // extended pointer on lock protecting the chdev queue 122 uint32_t modified; // non zero if the server thread state was modified 123 uint32_t save_sr; // for critical section 124 125 thread_t * this = CURRENT_THREAD; 126 127 chdev_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) enter / cycle %d\n", 128 __FUNCTION__, local_cxy, this->core->lid, thread_type_str(this->type) , hal_time_stamp() ); 112 129 113 130 // get device descriptor cluster and local pointer … … 116 133 117 134 // build extended pointers on client thread xlist and device root 118 xptr_t xp_list = XPTR( local_cxy , &thread_ptr->wait_list ); 119 xptr_t xp_root = XPTR( chdev_cxy , &chdev_ptr->wait_root ); 120 121 // get lock protecting queue 122 remote_spinlock_lock( XPTR( chdev_cxy , &chdev_ptr->wait_lock ) ); 135 xptr_t list_xp = XPTR( local_cxy , &this->wait_list ); 136 xptr_t root_xp = XPTR( chdev_cxy , &chdev_ptr->wait_root ); 137 138 // get local pointer on server thread 139 server_ptr = (thread_t *)hal_remote_lpt( XPTR( chdev_cxy , &chdev_ptr->server) ); 140 141 chdev_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) / server_cxy %x / server_ptr %x / server_type %\n", 142 __FUNCTION__, local_cxy, this->core->lid, server_cxy, server_ptr, 143 thread_type_str( hal_remote_lw( XPTR( server_cxy , &server_ptr->type) ) ) ); 144 145 // build extended pointer on chdev lock protecting queue 146 lock_xp = XPTR( chdev_cxy , &chdev_ptr->wait_lock ); 147 148 // get local pointer on core running the server thread 149 core_ptr = (core_t *)hal_remote_lpt( XPTR( chdev_cxy , &server_ptr->core ) ); 150 151 // get core local index 152 lid = hal_remote_lw( XPTR( chdev_cxy , &core_ptr->lid ) ); 153 154 // enter critical section 155 hal_disable_irq( &save_sr ); 123 156 124 157 // register client thread in waiting queue 125 xlist_add_last( xp_root , xp_list ); 158 remote_spinlock_lock( lock_xp ); 159 xlist_add_last( root_xp , list_xp ); 160 remote_spinlock_unlock( lock_xp ); 126 161 127 162 // unblock server thread 128 thread_unblock( XPTR( chdev_cxy , &chdev_ptr->server ) , THREAD_BLOCKED_DEV_QUEUE ); 129 130 // release lock 131 remote_spinlock_unlock( XPTR( chdev_cxy , &chdev_ptr->wait_lock ) ); 132 133 // client thread goes to blocked state and deschedule 134 thread_block( thread_ptr , THREAD_BLOCKED_IO ); 135 sched_yield( NULL ); 163 modified = thread_unblock( XPTR( chdev_cxy , server_ptr ), THREAD_BLOCKED_DEV_QUEUE ); 164 165 // send IPI to core running the server thread 166 if( modified ) dev_pic_send_ipi( chdev_cxy , lid ); 167 168 // block client thread 169 assert( thread_can_yield( this ) , __FUNCTION__ , "illegal sched_yield\n" ); 170 171 chdev_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) deschedules / cycle %d\n", 172 __FUNCTION__, local_cxy, this->core->lid, thread_type_str(this->type) , hal_time_stamp() ); 173 174 thread_block( CURRENT_THREAD , THREAD_BLOCKED_IO ); 175 sched_yield(); 176 177 chdev_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) resumes / cycle %d\n", 178 __FUNCTION__, local_cxy, this->core->lid, thread_type_str(this->type) , hal_time_stamp() ); 179 180 // exit critical section 181 hal_restore_irq( save_sr ); 136 182 137 183 } // end chdev_register_command() … … 143 189 cxy_t client_cxy; // cluster of client thread 144 190 thread_t * client_ptr; // local pointer on client thread 145 thread_t * server; // local pointer on thisthread191 thread_t * server; // local pointer on server thread 146 192 xptr_t root_xp; // extended pointer on device waiting queue root 193 xptr_t lock_xp; // extended pointer on lock ptotecting chdev queue 147 194 148 195 server = CURRENT_THREAD; 149 196 197 chdev_dmsg("\n[DBG] %s : enter / server = %x / chdev = %x / cycle %d\n", 198 __FUNCTION__ , server , chdev , hal_time_stamp() ); 199 150 200 root_xp = XPTR( local_cxy , &chdev->wait_root ); 151 152 // take the lock protecting the chdev waiting queue, before entering the 153 // infinite loop handling commands registered in this queue. 154 // In the loop, the lock is released during the handling of one command. 155 156 remote_spinlock_lock( XPTR( local_cxy , &chdev->wait_lock ) ); 157 201 lock_xp = XPTR( local_cxy , &chdev->wait_lock ); 202 203 // This infinite loop is executed by the DEV thread 204 // to handle commands registered in the chdev queue. 158 205 while( 1 ) 159 206 { 207 // get the lock protecting the waiting queue 208 remote_spinlock_lock( lock_xp ); 209 160 210 // check waiting queue state 161 if( xlist_is_empty( root_xp ) ) // block and deschedule ifwaiting queue empty211 if( xlist_is_empty( root_xp ) ) // waiting queue empty 162 212 { 163 213 // release lock 164 remote_spinlock_unlock( XPTR( local_cxy , &chdev->wait_lock ) ); 214 remote_spinlock_unlock( lock_xp ); 215 216 chdev_dmsg("\n[DBG] %s : thread %x deschedule /cycle %d\n", 217 __FUNCTION__ , server , hal_time_stamp() ); 165 218 166 219 // block and deschedule 167 220 thread_block( server , THREAD_BLOCKED_DEV_QUEUE ); 168 sched_yield( NULL ); 221 sched_yield(); 222 223 chdev_dmsg("\n[DBG] %s : thread %x resume /cycle %d\n", 224 __FUNCTION__ , server , hal_time_stamp() ); 225 169 226 } 170 else 227 else // waiting queue not empty 171 228 { 229 230 #if CONFIG_READ_DEBUG 231 enter_chdev_server = hal_time_stamp(); 232 #endif 172 233 // release lock 173 remote_spinlock_unlock( XPTR( local_cxy , &chdev->wait_lock ) ); 234 remote_spinlock_unlock( lock_xp ); 235 236 // get extended pointer on first client thread 237 client_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list ); 238 239 // get client thread cluster, local pointer, and identifier 240 client_cxy = GET_CXY( client_xp ); 241 client_ptr = (thread_t *)GET_PTR( client_xp ); 242 243 // call driver command function to execute I/O operation 244 chdev->cmd( client_xp ); 245 246 // remove the client thread from waiting queue 247 remote_spinlock_lock( lock_xp ); 248 xlist_unlink( XPTR( client_cxy , &client_ptr->wait_list ) ); 249 remote_spinlock_unlock( lock_xp ); 250 251 chdev_dmsg("\n[DBG] %s : thread %x complete operation for client %x / cycle %d\n", 252 __FUNCTION__ , server , client_ptr , hal_time_stamp() ); 253 254 #if CONFIG_READ_DEBUG 255 exit_chdev_server = hal_time_stamp(); 256 #endif 257 174 258 } 175 176 // get extended pointer on first client thread177 client_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list );178 179 // call driver command function to execute I/O operation180 chdev->cmd( client_xp );181 182 // get client thread cluster and local pointer183 client_cxy = GET_CXY( client_xp );184 client_ptr = (thread_t *)GET_PTR( client_xp );185 186 // take the lock, and remove the client thread from waiting queue187 remote_spinlock_lock( XPTR( local_cxy , &chdev->wait_lock ) );188 xlist_unlink( XPTR( client_cxy , &client_ptr->wait_list ) );189 190 259 } // end while 191 192 260 } // end chdev_sequencial_server() 193 261 … … 197 265 cxy_t iob_cxy = GET_CXY( chdev_dir.iob ); 198 266 chdev_t * iob_ptr = (chdev_t *)GET_PTR( chdev_dir.iob ); 199 xptr_t iob_base =hal_remote_lwd( XPTR( iob_cxy , &iob_ptr->base ) );267 uint32_t iob_base = (uint32_t)hal_remote_lwd( XPTR( iob_cxy , &iob_ptr->base ) ); 200 268 201 269 cxy_t pic_cxy = GET_CXY( chdev_dir.pic ); 202 270 chdev_t * pic_ptr = (chdev_t *)GET_PTR( chdev_dir.pic ); 203 xptr_t pic_base = hal_remote_lwd( XPTR( pic_cxy , &pic_ptr->base ) ); 204 205 cxy_t txt0_cxy = GET_CXY( chdev_dir.txt[0] ); 206 chdev_t * txt0_ptr = (chdev_t *)GET_PTR( chdev_dir.txt[0] ); 207 xptr_t txt0_base = hal_remote_lwd( XPTR( txt0_cxy , &txt0_ptr->base ) ); 208 209 cxy_t txt1_cxy = GET_CXY( chdev_dir.txt[1] ); 210 chdev_t * txt1_ptr = (chdev_t *)GET_PTR( chdev_dir.txt[1] ); 211 xptr_t txt1_base = hal_remote_lwd( XPTR( txt1_cxy , &txt1_ptr->base ) ); 212 213 cxy_t txt2_cxy = GET_CXY( chdev_dir.txt[2] ); 214 chdev_t * txt2_ptr = (chdev_t *)GET_PTR( chdev_dir.txt[2] ); 215 xptr_t txt2_base = hal_remote_lwd( XPTR( txt2_cxy , &txt2_ptr->base ) ); 271 uint32_t pic_base = (uint32_t)hal_remote_lwd( XPTR( pic_cxy , &pic_ptr->base ) ); 272 273 cxy_t txt0_tx_cxy = GET_CXY( chdev_dir.txt_tx[0] ); 274 chdev_t * txt0_tx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_tx[0] ); 275 uint32_t txt0_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt0_tx_cxy , &txt0_tx_ptr->base ) ); 276 277 cxy_t txt0_rx_cxy = GET_CXY( chdev_dir.txt_rx[0] ); 278 chdev_t * txt0_rx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_rx[0] ); 279 uint32_t txt0_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt0_rx_cxy , &txt0_rx_ptr->base ) ); 280 281 cxy_t txt1_tx_cxy = GET_CXY( chdev_dir.txt_tx[1] ); 282 chdev_t * txt1_tx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_tx[1] ); 283 uint32_t txt1_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt1_tx_cxy , &txt1_tx_ptr->base ) ); 284 285 cxy_t txt1_rx_cxy = GET_CXY( chdev_dir.txt_rx[1] ); 286 chdev_t * txt1_rx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_rx[1] ); 287 uint32_t txt1_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt1_rx_cxy , &txt1_rx_ptr->base ) ); 288 289 cxy_t txt2_tx_cxy = GET_CXY( chdev_dir.txt_tx[2] ); 290 chdev_t * txt2_tx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_tx[2] ); 291 uint32_t txt2_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt2_tx_cxy , &txt2_tx_ptr->base ) ); 292 293 cxy_t txt2_rx_cxy = GET_CXY( chdev_dir.txt_rx[2] ); 294 chdev_t * txt2_rx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_rx[2] ); 295 uint32_t txt2_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt2_rx_cxy , &txt2_rx_ptr->base ) ); 216 296 217 297 cxy_t ioc_cxy = GET_CXY( chdev_dir.ioc[0] ); 218 298 chdev_t * ioc_ptr = (chdev_t *)GET_PTR( chdev_dir.ioc[0] ); 219 xptr_t ioc_base =hal_remote_lwd( XPTR( ioc_cxy , &ioc_ptr->base ) );299 uint32_t ioc_base = (uint32_t)hal_remote_lwd( XPTR( ioc_cxy , &ioc_ptr->base ) ); 220 300 221 301 cxy_t fbf_cxy = GET_CXY( chdev_dir.fbf[0] ); 222 302 chdev_t * fbf_ptr = (chdev_t *)GET_PTR( chdev_dir.fbf[0] ); 223 xptr_t fbf_base =hal_remote_lwd( XPTR( fbf_cxy , &fbf_ptr->base ) );224 225 cxy_t nic _rx_cxy = GET_CXY( chdev_dir.nic_rx[0] );226 chdev_t * nic _rx_ptr = (chdev_t *)GET_PTR( chdev_dir.nic_rx[0] );227 xptr_t nic_rx_base = hal_remote_lwd( XPTR( nic_rx_cxy , &nic_rx_ptr->base ) );228 229 cxy_t nic _tx_cxy = GET_CXY( chdev_dir.nic_tx[0] );230 chdev_t * nic _tx_ptr = (chdev_t *)GET_PTR( chdev_dir.nic_tx[0] );231 xptr_t nic_tx_base = hal_remote_lwd( XPTR( nic_tx_cxy , &nic_tx_ptr->base ) );303 uint32_t fbf_base = (uint32_t)hal_remote_lwd( XPTR( fbf_cxy , &fbf_ptr->base ) ); 304 305 cxy_t nic0_rx_cxy = GET_CXY( chdev_dir.nic_rx[0] ); 306 chdev_t * nic0_rx_ptr = (chdev_t *)GET_PTR( chdev_dir.nic_rx[0] ); 307 uint32_t nic0_rx_base = (uint32_t)hal_remote_lwd( XPTR( nic0_rx_cxy , &nic0_rx_ptr->base ) ); 308 309 cxy_t nic0_tx_cxy = GET_CXY( chdev_dir.nic_tx[0] ); 310 chdev_t * nic0_tx_ptr = (chdev_t *)GET_PTR( chdev_dir.nic_tx[0] ); 311 uint32_t nic0_tx_base = (uint32_t)hal_remote_lwd( XPTR( nic0_tx_cxy , &nic0_tx_ptr->base ) ); 232 312 233 313 printk("\n***** external chdev directory in cluster %x\n" 234 " - iob = %l / base = %l\n" 235 " - pic = %l / base = %l\n" 236 " - txt[0] = %l / base = %l\n" 237 " - txt[1] = %l / base = %l\n" 238 " - txt[2] = %l / base = %l\n" 239 " - ioc[0] = %l / base = %l\n" 240 " - fbf[0] = %l / base = %l\n" 241 " - nic_rx[0] = %l / base = %l\n" 242 " - nic_tx[0] = %l / base = %l\n", 314 " - iob : cxy = %X / ptr = %X / base = %X\n" 315 " - pic : cxy = %X / ptr = %X / base = %X\n" 316 " - ioc : cxy = %X / ptr = %X / base = %X\n" 317 " - fbf : cxy = %X / ptr = %X / base = %X\n" 318 " - txt_rx[0] : cxy = %X / ptr = %X / base = %X\n" 319 " - txt_tx[0] : cxy = %X / ptr = %X / base = %X\n" 320 " - txt_rx[1] : cxy = %X / ptr = %X / base = %X\n" 321 " - txt_tx[1] : cxy = %X / ptr = %X / base = %X\n" 322 " - txt_rx[2] : cxy = %X / ptr = %X / base = %X\n" 323 " - txt_tx[2] : cxy = %X / ptr = %X / base = %X\n" 324 " - nic_rx[0] : cxy = %X / ptr = %X / base = %X\n" 325 " - nic_tx[0] : cxy = %X / ptr = %X / base = %X\n", 243 326 local_cxy, 244 chdev_dir.iob, iob_base, 245 chdev_dir.pic, pic_base, 246 chdev_dir.txt[0], txt0_base, 247 chdev_dir.txt[1], txt1_base, 248 chdev_dir.txt[2], txt2_base, 249 chdev_dir.ioc[0], ioc_base, 250 chdev_dir.fbf[0], fbf_base, 251 chdev_dir.nic_rx[0], nic_rx_base, 252 chdev_dir.nic_tx[0], nic_tx_base ); 327 iob_cxy , iob_ptr , iob_base , 328 pic_cxy , pic_ptr , pic_base , 329 ioc_cxy , ioc_ptr , ioc_base , 330 fbf_cxy , fbf_ptr , fbf_base , 331 txt0_rx_cxy , txt0_rx_ptr , txt0_rx_base , 332 txt0_tx_cxy , txt0_tx_ptr , txt0_tx_base , 333 txt1_rx_cxy , txt1_rx_ptr , txt1_rx_base , 334 txt1_tx_cxy , txt1_tx_ptr , txt1_tx_base , 335 txt2_rx_cxy , txt2_rx_ptr , txt2_rx_base , 336 txt2_tx_cxy , txt2_tx_ptr , txt2_tx_base , 337 nic0_rx_cxy , nic0_rx_ptr , nic0_rx_base , 338 nic0_tx_cxy , nic0_tx_ptr , nic0_tx_base ); 253 339 254 340 } // end chdev_dir_display()
Note: See TracChangeset
for help on using the changeset viewer.