Changes in trunk/kernel/devices/dev_icu.c [1:3]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/devices/dev_icu.c
r1 r3 24 24 #include <hal_types.h> 25 25 #include <hal_special.h> 26 #include < device.h>26 #include <chdev.h> 27 27 #include <thread.h> 28 28 #include <cluster.h> … … 37 37 ///////////////////////////////////////////////////////////////////////////////////////// 38 38 39 extern devices_directory_t devices_dir; // allocated in kernel_init.c 40 41 extern devices_input_irq_t devices_input_irq; // allocated in kernel_init.c 42 43 44 /////////////////////////////////// 45 void dev_icu_init( xptr_t dev_xp, 46 uint32_t hwi_nr, 47 uint32_t wti_nr, 48 uint32_t pti_nr ) 49 { 50 // get ICU device cluster and local pointer 51 cxy_t dev_cxy = GET_CXY( dev_xp ); 52 device_t * dev_ptr = (device_t *)GET_PTR( dev_xp ); 53 54 if( dev_cxy != local_cxy ) 55 { 56 printk("\n[PANIC] %s for cluster %x must be local\n", 57 __FUNCTION__ , local_cxy ); 58 hal_core_sleep(); 59 } 60 61 // set ICU device extension fields 62 dev_ptr->ext.icu.hwi_nr = hwi_nr; 63 dev_ptr->ext.icu.wti_nr = wti_nr; 64 dev_ptr->ext.icu.pti_nr = pti_nr; 65 dev_ptr->ext.icu.wti_bitmap = 0; 66 spinlock_init( &dev_ptr->ext.icu.wti_lock ); 39 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 40 41 extern chdev_pic_input_t chdev_pic_input; // allocated in kernel_init.c 42 43 ///////////////////////////////// 44 void dev_icu_init( chdev_t * icu, 45 uint32_t hwi_nr, 46 uint32_t wti_nr, 47 uint32_t pti_nr ) 48 { 49 // set ICU chdev extension fields 50 icu->ext.icu.hwi_nr = hwi_nr; 51 icu->ext.icu.wti_nr = wti_nr; 52 icu->ext.icu.pti_nr = pti_nr; 53 icu->ext.icu.wti_bitmap = 0; 54 spinlock_init( &icu->ext.icu.wti_lock ); 67 55 68 // get implementation index from ICU device descriptor 69 uint32_t impl = dev_ptr->impl; 70 71 // set field "name" in device descriptor 72 // and call the relevant driver init function 56 // get implementation 57 uint32_t impl = icu->impl; 58 59 // call the relevant driver init function 73 60 if( impl == IMPL_ICU_XCU ) 74 61 { 75 memcpy( dev_ptr->name , "ICU_XCU" , 16 ); 76 77 uint32_t lid; 78 cluster_t * cluster = LOCAL_CLUSTER; 79 for( lid = 0 ; lid < cluster->cores_nr ; lid++ ) 62 uint32_t lid; 63 for( lid = 0 ; lid < LOCAL_CLUSTER->cores_nr ; lid++ ) 80 64 { 81 soclib_xcu_init( dev_ptr, lid );65 soclib_xcu_init( icu , lid ); 82 66 } 83 67 } 84 68 else 85 69 { 86 printk("\n[PANIC] %s : undefined ICU implementation for cluste %x\n", 87 __FUNCTION__ , local_cxy ); 88 hal_core_sleep(); 70 assert( false , __FUNCTION__ , "undefined ICU implementation" ); 89 71 } 90 72 } // end dev_icu_init() 91 73 92 74 ///////////////////////////////////////////////////////////////////////////////////// 93 // This static function check the irq_type / irq_index arguments for a remote ICU.75 // This static function check the irq_type / irq_index arguments. 94 76 // It is called by the dev_icu_enable_irq() & dev_icu_disable_irq() functions. 95 // returns 0 if OK / returns non zero if invalid arguments96 77 ///////////////////////////////////////////////////////////////////////////////////// 97 static inline void dev_icu_check_irq( xptr_t icu_xp,78 static inline void dev_icu_check_irq( chdev_t * icu, 98 79 uint32_t irq_type, 99 80 uint32_t irq_index ) 100 81 { 101 // get cluster and local pointer on remote ICU102 cxy_t icu_cxy = GET_CXY( icu_xp );103 device_t * icu_ptr = (device_t *)GET_PTR( icu_xp );104 105 82 if( irq_type == HWI_TYPE ) 106 83 { 107 if( irq_index >= hal_remote_lw( XPTR( icu_cxy , &icu_ptr->ext.icu.hwi_nr ) ) ) 108 { 109 printk("\n[PANIC] in %s : illegal HWI index = %d for ICU in cluster %x\n", 110 __FUNCTION__ , irq_index , icu_cxy ); 111 hal_core_sleep(); 112 } 84 assert( (irq_index < icu->ext.icu.hwi_nr) , __FUNCTION__ , "illegal HWI" ); 113 85 } 114 86 if( irq_type == WTI_TYPE ) 115 87 { 116 if( irq_index >= hal_remote_lw( XPTR( icu_cxy , &icu_ptr->ext.icu.wti_nr ) ) ) 117 { 118 printk("\n[PANIC] in %s : illegal WTI index = %d for ICU in cluster %x\n", 119 __FUNCTION__ , irq_index , icu_cxy ); 120 hal_core_sleep(); 121 } 88 assert( (irq_index < icu->ext.icu.wti_nr) , __FUNCTION__ , "illegal WTI" ); 122 89 } 123 90 if( irq_type == PTI_TYPE ) 124 91 { 125 if( irq_index >= hal_remote_lw( XPTR( icu_cxy , &icu_ptr->ext.icu.pti_nr ) ) ) 126 { 127 printk("\n[PANIC] in %s : illegal PTI index = %d for ICU in cluster %x\n", 128 __FUNCTION__ , irq_index , icu_cxy ); 129 hal_core_sleep(); 130 } 131 } 132 } // end dev_icu check irq() 133 134 //////////////////////////////////////////// 135 void dev_icu_enable_irq( cxy_t icu_cxy, 136 lid_t lid, 92 assert( (irq_index < icu->ext.icu.pti_nr) , __FUNCTION__ , "illegal PTI" ); 93 } 94 } // end dev_icu_check_irq() 95 96 //////////////////////////////////////// 97 void dev_icu_enable_irq( lid_t lid, 137 98 uint32_t irq_type, 138 99 uint32_t irq_index, 139 xptr_t src_dev_xp)140 { 141 // get extended pointer & local pointer on remote ICU device142 xptr_t icu_xp = devices_dir.icu[icu_cxy];143 device_t * icu_ptr = (device_t *)GET_PTR( icu_xp );100 chdev_t * src_chdev ) 101 { 102 // get local pointer on local ICU chdev 103 xptr_t icu_xp = chdev_dir.icu[local_cxy]; 104 chdev_t * icu = (chdev_t *)GET_PTR( icu_xp ); 144 105 145 106 // check IRQ type and index 146 dev_icu_check_irq( icu _xp, irq_type , irq_index );107 dev_icu_check_irq( icu , irq_type , irq_index ); 147 108 148 109 // (1) call implementation specific ICU driver to enable IRQ 149 if( icu_ptr->impl == IMPL_ICU_XCU ) 150 { 151 soclib_xcu_enable_irq( icu_xp , 1<<irq_index , irq_type , lid ); 152 } 153 else 154 { 155 printk("\n[PANIC] in %s : undefined ICU implementation" , __FUNCTION__ ); 156 hal_core_sleep(); 157 } 158 159 // (2) get selected remote core local pointer, and register 160 // source device xptr in relevant interrupt vector 161 162 core_t * core_ptr = hal_remote_lpt( XPTR( icu_cxy , &LOCAL_CLUSTER->core_tbl[lid] ) ); 163 xptr_t core_xp = XPTR( icu_cxy , core_ptr ); 164 core_set_irq_vector_entry( core_xp , irq_type , irq_index , src_dev_xp ); 165 166 // (3) get extended pointer on source device, and 167 // register IRQ type and index in source device descriptor 168 169 cxy_t src_dev_cxy = GET_CXY( src_dev_xp ); 170 device_t * src_dev_ptr = (device_t *)GET_PTR( src_dev_xp ); 171 172 hal_remote_sw( XPTR( src_dev_cxy , &src_dev_ptr->irq_type ) , irq_type ); 173 hal_remote_sw( XPTR( src_dev_cxy , &src_dev_ptr->irq_id ) , irq_index ); 110 if( icu->impl == IMPL_ICU_XCU ) 111 { 112 soclib_xcu_enable_irq( icu , 1<<irq_index , irq_type , lid ); 113 } 114 115 // (2) get selected core local pointer, and register 116 // source chdev pointer in relevant interrupt vector 117 core_t * core = &LOCAL_CLUSTER->core_tbl[lid]; 118 core_set_irq_vector_entry( core , irq_type , irq_index , src_chdev ); 119 120 // (3) register IRQ type and index in source chdev descriptor 121 src_chdev->irq_type = irq_type; 122 src_chdev->irq_id = irq_index; 174 123 175 124 } // end dev_icu_enable_irq() 176 125 177 ///////////////////////////////////////////// 178 void dev_icu_disable_irq( cxy_t icu_cxy, 179 lid_t lid, 126 ///////////////////////////////////////// 127 void dev_icu_disable_irq( lid_t lid, 180 128 uint32_t irq_type, 181 129 uint32_t irq_index ) 182 130 { 183 // get extended pointer & local pointer on remote ICU device184 xptr_t icu_xp = devices_dir.icu[icu_cxy];185 device_t * icu_ptr = (device_t *)GET_PTR( icu_xp );131 // get local pointer on local ICU chdev 132 xptr_t icu_xp = chdev_dir.icu[local_cxy]; 133 chdev_t * icu = (chdev_t *)GET_PTR( icu_xp ); 186 134 187 135 // check IRQ type and index 188 dev_icu_check_irq( icu _xp, irq_type , irq_index );136 dev_icu_check_irq( icu , irq_type , irq_index ); 189 137 190 138 // (1) call the implementation specific ICU driver to disable IRQ 191 if( icu_ptr->impl == IMPL_ICU_XCU ) 192 { 193 soclib_xcu_disable_irq( icu_xp , 1<<irq_index , irq_type , lid ); 194 } 195 else 196 { 197 printk("\n[PANIC] in %s : undefined ICU implementation" , __FUNCTION__ ); 198 hal_core_sleep(); 139 if( icu->impl == IMPL_ICU_XCU ) 140 { 141 soclib_xcu_disable_irq( icu , 1<<irq_index , irq_type , lid ); 199 142 } 200 143 201 144 // (2) get selected remote core local pointer, and remove 202 // the source device xptr from relevant interrupt vector 203 204 core_t * core_ptr = hal_remote_lpt( XPTR( icu_cxy , &LOCAL_CLUSTER->core_tbl[lid] ) ); 205 xptr_t core_xp = XPTR( icu_cxy , core_ptr ); 206 core_set_irq_vector_entry( core_xp , irq_type , irq_index , XPTR_NULL ); 145 // the source chdev xptr from relevant interrupt vector 146 147 core_t * core = &LOCAL_CLUSTER->core_tbl[lid]; 148 core_set_irq_vector_entry( core , irq_type , irq_index , NULL ); 207 149 208 150 } // end dev_icu_disable_irq() … … 212 154 uint32_t period ) 213 155 { 214 // get pointer on local ICU device descriptor215 core_t * core = CURRENT_CORE;216 device_t * icu = core->icu;156 // get local pointer on local ICU chdev 157 xptr_t icu_xp = chdev_dir.icu[local_cxy]; 158 chdev_t * icu = (chdev_t *)GET_PTR( icu_xp ); 217 159 218 160 // check PTI index 219 if( pti_index >= icu->ext.icu.pti_nr ) 220 { 221 printk("\n[PANIC] in %s : illegal PTI index = %d\n", __FUNCTION__ , pti_index ); 222 hal_core_sleep(); 223 } 161 assert( (pti_index < icu->ext.icu.pti_nr) , __FUNCTION__ , "illegal PTI index" ); 224 162 225 163 // call the implementation specific driver ICU to set period … … 233 171 void dev_icu_ack_timer( uint32_t pti_index ) 234 172 { 235 // get pointer on local ICU device descriptor236 core_t * core = CURRENT_CORE;237 device_t * icu = core->icu;173 // get local pointer on local ICU chdev 174 xptr_t icu_xp = chdev_dir.icu[local_cxy]; 175 chdev_t * icu = (chdev_t *)GET_PTR( icu_xp ); 238 176 239 177 // check PTI index 240 if( pti_index >= icu->ext.icu.pti_nr ) 241 { 242 printk("\n[PANIC] in %s : illegal PTI index = %d\n", __FUNCTION__ , pti_index ); 243 hal_core_sleep(); 244 } 178 assert( (pti_index < icu->ext.icu.pti_nr) , __FUNCTION__ , "illegal PTI index" ); 245 179 246 180 // call the implementation specific driver ICU to acknowledge PTI IRQ … … 249 183 soclib_xcu_ack_timer( icu , pti_index ); 250 184 } 251 else252 {253 printk("\n[PANIC] in %s : undefined ICU implementation" , __FUNCTION__ );254 hal_core_sleep();255 }256 257 185 } // end dev_icu_ack_timer() 258 186 … … 270 198 uint32_t y = cxy & ((1<<y_width)-1); 271 199 272 if( (x >= x_size) || (y >= y_size) ) 273 { 274 hal_core_sleep("%s : illegal cluster identifier = %x\n", __FUNCTION__ , cxy ); 275 } 276 if( lid >= cores_nr ) 277 { 278 hal_core_sleep("%s : illegal core local index = %d\n", __FUNCTION__ , lid ); 279 } 280 281 // get extended pointer on target ICU device 282 xptr_t icu_xp = devices_dir.icu[cxy]; 200 assert( ((x < x_size) && (y < y_size)) , __FUNCTION__ , "illegal cluster identifier" ); 201 202 assert( (lid < cores_nr) , __FUNCTION__ , "illegal core local index" ); 203 204 // get extended pointer on target ICU chdev 205 xptr_t icu_xp = chdev_dir.icu[cxy]; 283 206 284 207 // get target ICU cluster and local pointer 285 cxy_t cxy_icu= GET_CXY( icu_xp );286 device_t * ptr_icu = (device_t *)GET_PTR( icu_xp );287 288 // get driver implementation from target ICU device289 uint32_t impl = hal_remote_lw( XPTR( cxy_icu , &ptr_icu->impl ) );208 cxy_t icu_cxy = GET_CXY( icu_xp ); 209 chdev_t * icu_ptr = (chdev_t *)GET_PTR( icu_xp ); 210 211 // get implementation from remote ICU chdev 212 uint32_t impl = hal_remote_lw( XPTR( icu_cxy , &icu_ptr->impl ) ); 290 213 291 214 // call the implementation specific ICU driver to send IPI … … 293 216 { 294 217 soclib_xcu_send_ipi( icu_xp , lid ); 295 }296 else297 {298 printk("\n[PANIC] in %s : undefined ICU implementation" , __FUNCTION__ );299 hal_core_sleep();300 218 } 301 219 } // end dev_icu_send_ipi() … … 307 225 uint32_t wti_status; // WTI index + 1 / no pending WTI if 0 308 226 uint32_t pti_status; // PTI index + 1 / no pending PTI if 0 309 xptr_t src_dev_xp; // extended pointer on source device descriptor 310 cxy_t src_dev_cxy; // source device cluster 311 device_t * src_dev_ptr; // source device local pointer 227 chdev_t * src_chdev; // pointer on source chdev descriptor 312 228 uint32_t index; // IRQ index 313 229 314 // get pointer on local ICU device descriptor315 230 core_t * core = CURRENT_CORE; 316 device_t * icu = core->icu; 231 232 // get local pointer on local ICU chdev 233 xptr_t icu_xp = chdev_dir.icu[local_cxy]; 234 chdev_t * icu = (chdev_t *)GET_PTR( icu_xp ); 317 235 318 236 // call the implementation specific ICU driver … … 322 240 soclib_xcu_get_status( icu , core->lid , &hwi_status , &wti_status , &pti_status ); 323 241 } 324 else325 {326 printk("\n[PANIC] in %s : undefined ICU implementation" , __FUNCTION__ );327 hal_core_sleep();328 }329 242 330 243 // analyse ICU status and handle up to 3 pending IRQ (one WTI, one HWI, one PTI) 331 244 332 if( wti_status ) // pending WTI TODO what about IPIs ??? [AG]245 if( wti_status ) // pending WTI 333 246 { 334 247 index = wti_status - 1; 335 248 336 // get extended pointer on IRQ source device 337 src_dev_xp = core->wti_vector[index]; 338 src_dev_cxy = GET_CXY( src_dev_xp ); 339 src_dev_ptr = (device_t *)GET_PTR( src_dev_xp ); 340 341 if( src_dev_xp == XPTR_NULL ) // strange, but not fatal => disable IRQ 342 { 343 printk("\n[WARNING] in %s : no handler for WTI %d on core %d in cluster %x\n", 344 __FUNCTION__ , index , core->lid , local_cxy ); 345 core->spurious_irqs ++; 346 dev_icu_disable_irq( local_cxy , core->lid , WTI_TYPE , index ); 347 } 348 else if( src_dev_cxy != local_cxy ) // WTI must be handled in device cluster 249 if( index < LOCAL_CLUSTER->cores_nr ) // it is an IPI 349 250 { 350 printk("\n[PANIC] in %s : non local WTI %d on core %d in cluster %x\n", 351 __FUNCTION__ , index , core->lid , local_cxy ); 352 hal_core_sleep(); 251 assert( (index == core->lid) , __FUNCTION__ , "illegal IPI index" ); 252 253 // TODO acknowledge WTI [AG] 254 255 // TODO force scheduling [AG] 353 256 } 354 else // call relevant ISR257 else // it is an external device 355 258 { 356 icu_dmsg("\n[INFO] %s received WTI : index = %d for cpu %d in cluster %d\n", 357 __FUNCTION__ , index , core->lid , local_cxy ); 358 359 src_dev_ptr->isr( src_dev_ptr ); 259 // get pointer on IRQ source chdev 260 src_chdev = core->wti_vector[index]; 261 262 if( src_chdev == NULL ) // strange, but not fatal => disable IRQ 263 { 264 printk("\n[WARNING] in %s : no handler for WTI %d on core %d in cluster %x\n", 265 __FUNCTION__ , index , core->lid , local_cxy ); 266 core->spurious_irqs ++; 267 dev_icu_disable_irq( core->lid , WTI_TYPE , index ); 268 } 269 else // call relevant ISR 270 { 271 icu_dmsg("\n[INFO] %s received WTI : index = %d for cpu %d in cluster %d\n", 272 __FUNCTION__ , index , core->lid , local_cxy ); 273 274 // call ISR 275 src_chdev->isr( src_chdev ); 276 } 360 277 } 361 278 } … … 365 282 index = hwi_status - 1; 366 283 367 // get pointer on IRQ source device 368 src_dev_xp = core->wti_vector[index]; 369 src_dev_cxy = GET_CXY( src_dev_xp ); 370 src_dev_ptr = (device_t *)GET_PTR( src_dev_xp ); 371 372 if( src_dev_xp == XPTR_NULL ) // strange, but not fatal => disable IRQ 284 // get pointer on IRQ source chdev 285 src_chdev = core->hwi_vector[index]; 286 287 if( src_chdev == NULL ) // strange, but not fatal => disable IRQ 373 288 { 374 289 printk("\n[WARNING] in %s : no handler for HWI %d on core %d in cluster %x\n", 375 290 __FUNCTION__ , index , core->lid , local_cxy ); 376 291 core->spurious_irqs ++; 377 dev_icu_disable_irq( local_cxy ,core->lid , HWI_TYPE , index );292 dev_icu_disable_irq( core->lid , HWI_TYPE , index ); 378 293 } 379 else if( src_dev_cxy != local_cxy ) // HWI must be handled in device cluster380 {381 printk("\n[PANIC] in %s : non local HWI %d on core %d in cluster %x\n",382 __FUNCTION__ , index , core->lid , local_cxy );383 hal_core_sleep();384 }385 294 else // call relevant ISR 386 295 { … … 388 297 __FUNCTION__ , index , core->lid , local_cxy ); 389 298 390 src_dev_ptr->isr( src_dev_ptr ); 299 // call ISR 300 src_chdev->isr( src_chdev ); 391 301 } 392 302 } … … 402 312 dev_icu_ack_timer( index ); 403 313 404 // execute all actions related to TICK event314 // TODO execute all actions related to TICK event 405 315 core_clock( core ); 406 316 } … … 410 320 uint32_t dev_icu_wti_alloc() 411 321 { 412 // get pointer on local ICU device descriptor413 core_t * core = CURRENT_CORE;414 device_t * icu = core->icu;415 416 // get bitmap pointer, lock , and size417 bitmap_t * bitmap = &icu->ext.icu.wti_bitmap;322 // get local pointer on local ICU chdev 323 xptr_t icu_xp = chdev_dir.icu[local_cxy]; 324 chdev_t * icu = (chdev_t *)GET_PTR( icu_xp ); 325 326 // get bitmap pointer, lock pointer, and size 327 uint32_t * bitmap = &icu->ext.icu.wti_bitmap; 418 328 spinlock_t * lock = &icu->ext.icu.wti_lock; 419 329 uint32_t size = icu->ext.icu.wti_nr; … … 437 347 void dev_icu_wti_release( uint32_t index ) 438 348 { 439 // get pointer on local ICU devicedescriptor440 core_t * core = CURRENT_CORE;441 device_t * icu = core->icu;349 // get pointer on local ICU chdev descriptor 350 xptr_t icu_xp = chdev_dir.icu[local_cxy]; 351 chdev_t * icu_ptr = (chdev_t *)GET_PTR( icu_xp ); 442 352 443 353 // get bitmap pointer, lock, and size 444 bitmap_t * bitmap = &icu ->ext.icu.wti_bitmap;445 spinlock_t * lock = &icu ->ext.icu.wti_lock;446 uint32_t size = icu ->ext.icu.wti_nr;354 bitmap_t * bitmap = &icu_ptr->ext.icu.wti_bitmap; 355 spinlock_t * lock = &icu_ptr->ext.icu.wti_lock; 356 uint32_t size = icu_ptr->ext.icu.wti_nr; 447 357 448 358 // check index 449 if( index >= size ) 450 { 451 printk("\n[PANIC] in %s : illegal WTI index = %d on core %d in cluster %x\n", 452 __FUNCTION__ , index , core->lid , local_cxy ); 453 hal_core_sleep(); 454 } 359 assert( (index < size) , __FUNCTION__ , "illegal WTI index" ); 455 360 456 361 // get lock protecting WTI allocator … … 462 367 // release lock 463 368 spinlock_unlock( lock ); 369 464 370 } // end dev_icu_wti_release() 465 371 466 /////////////////////////////////////// 467 xptr_t dev_icu_wti_xptr( cxy_t cxy, 468 uint32_t wti_id ) 469 { 470 uint32_t * ptr = NULL; // local pointer on mailbox 471 472 // get pointer on local ICU device descriptor 473 core_t * core = CURRENT_CORE; 474 device_t * icu = core->icu; 372 ////////////////////////////////////////////// 373 uint32_t * dev_icu_wti_ptr( uint32_t wti_id ) 374 { 375 uint32_t * wti_ptr = NULL; 376 377 // get pointer on local ICU chdev descriptor 378 xptr_t icu_xp = chdev_dir.icu[local_cxy]; 379 chdev_t * icu = (chdev_t *)GET_PTR( icu_xp ); 475 380 476 381 // call implementation specific ICU driver 477 382 if( icu->impl == IMPL_ICU_XCU ) 478 383 { 479 ptr = soclib_xcu_wti_ptr( icu , wti_id ); 480 } 481 else 482 { 483 printk("\n[PANIC] in %s : undefined ICU implementation" , __FUNCTION__ ); 484 hal_core_sleep(); 485 } 486 487 // return extended pointer on mailbox 488 return XPTR( cxy , ptr ); 489 384 wti_ptr = soclib_xcu_wti_ptr( icu , wti_id ); 385 } 386 387 return wti_ptr; 490 388 } // end dev_icu_wti_xptr() 491 389
Note: See TracChangeset
for help on using the changeset viewer.