Changeset 657 for trunk/kernel/devices/dev_fbf.c
- Timestamp:
- Mar 18, 2020, 11:16:59 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/devices/dev_fbf.c
r647 r657 2 2 * dev_fbf.c - FBF (Frame Buffer) generic device API implementation. 3 3 * 4 * Author Alain Greiner (2016,2017,2018,2019 )4 * Author Alain Greiner (2016,2017,2018,2019,2020) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 26 26 #include <hal_gpt.h> 27 27 #include <hal_drivers.h> 28 #include <hal_irqmask.h> 29 #include <hal_macros.h> 30 #include <hal_uspace.h> 31 #include <hal_vmm.h> 28 32 #include <thread.h> 29 33 #include <printk.h> 30 34 #include <string.h> 35 #include <memcpy.h> 31 36 #include <chdev.h> 32 37 #include <dev_fbf.h> … … 41 46 char * dev_fbf_cmd_str( uint32_t cmd_type ) 42 47 { 43 if ( cmd_type == FBF_READ ) return "READ"; 44 else if( cmd_type == FBF_WRITE ) return "WRITE"; 45 else if( cmd_type == FBF_GET_CONFIG ) return "GET_CONFIG"; 46 else return "undefined"; 48 if ( cmd_type == FBF_GET_CONFIG ) return "GET_CONFIG"; 49 else if( cmd_type == FBF_CREATE_WINDOW ) return "CREATE_WINDOW"; 50 else if( cmd_type == FBF_DELETE_WINDOW ) return "DELETE_WINDOW"; 51 else if( cmd_type == FBF_MOVE_WINDOW ) return "MOVE_WINDOW"; 52 else if( cmd_type == FBF_REFRESH_WINDOW ) return "REFRESH_WINDOW"; 53 else if( cmd_type == FBF_DIRECT_WRITE ) return "DIRECT_WRITE"; 54 else if( cmd_type == FBF_DIRECT_READ ) return "DIRECT_READ"; 55 else return "undefined"; 47 56 } 48 57 … … 50 59 void dev_fbf_init( chdev_t * fbf ) 51 60 { 61 uint32_t wid; 62 52 63 // set chdev name 53 64 strcpy( fbf->name, "fbf" ); 54 65 55 // call driver init function 66 // initialize lock protecting the windows 67 remote_rwlock_init( XPTR( local_cxy , &fbf->ext.fbf.windows_lock ), 68 LOCK_FBF_WINDOWS ); 69 70 // initialize root of windows xlist 71 xlist_root_init( XPTR( local_cxy , &fbf->ext.fbf.windows_root ) ); 72 73 // initialize windows_tbl[] array 74 for( wid = 0 ; wid < CONFIG_FBF_WINDOWS_MAX_NR ; wid++ ) 75 { 76 fbf->ext.fbf.windows_tbl[wid] = XPTR_NULL; 77 } 78 79 // initialize wid allocator bitmap 80 bitmap_init( fbf->ext.fbf.windows_bitmap , CONFIG_FBF_WINDOWS_MAX_NR ); 81 82 // call driver init function to initialize the harware FBF 83 // and initialize the width, height, and subsampling FBF chdev fields 56 84 hal_drivers_fbf_init( fbf ); 57 85 … … 66 94 xptr_t dev_xp = chdev_dir.fbf[0]; 67 95 68 96 assert( (dev_xp != XPTR_NULL) , "undefined FBF chdev descriptor" ); 69 97 70 98 // get FBF chdev cluster and local pointer … … 79 107 } // end dev_fbf_get_config() 80 108 81 ///////////////////////////////////////////////////// 82 error_t dev_fbf_move_data( uint32_t cmd_type, 83 void * user_buffer, 84 uint32_t length, 85 uint32_t offset ) 86 { 87 // get pointer on calling thread 88 thread_t * this = CURRENT_THREAD; 109 /////////////////////////////////////////////// 110 uint32_t dev_fbf_create_window( uint32_t nlines, 111 uint32_t npixels, 112 uint32_t l_min, 113 uint32_t p_min, 114 intptr_t * user_buffer ) 115 { 116 kmem_req_t req; 117 fbf_window_t * window; // window descriptor (created in local cluster) 118 vseg_t * vseg; // vseg descriptor (created in reference cluster) 119 intptr_t vseg_base; // vseg base address in user space 120 121 // get local pointers on calling thread and process 122 thread_t * this = CURRENT_THREAD; 123 process_t * process = this->process; 89 124 90 125 #if DEBUG_DEV_FBF 91 126 uint32_t cycle = (uint32_t)hal_get_cycles(); 92 127 if( DEBUG_DEV_FBF < cycle ) 93 printk("\n[%s] thread[%x,%x] : %s / buffer %x / length %d / offset %x / cycle %d\n", 94 __FUNCTION__ , this->process->pid, this->trdid, 95 dev_fbf_cmd_str(cmd_type), user_buffer, length, offset, cycle ); 128 printk("\n[%s] thread[%x,%x] enter : nlines %d / npixels %d / l_min %d / p_min %d / cycle %d\n", 129 __FUNCTION__ , process->pid, this->trdid, nlines, npixels, l_min, p_min, cycle ); 130 #endif 131 132 // get cluster and pointers on FBF chdev 133 xptr_t fbf_xp = chdev_dir.fbf[0]; 134 cxy_t fbf_cxy = GET_CXY( fbf_xp ); 135 chdev_t * fbf_ptr = GET_PTR( fbf_xp ); 136 137 // check fbf_xp definition 138 assert( (fbf_xp != XPTR_NULL) , "undefined FBF chdev descriptor" ); 139 140 // get FBF width and height 141 uint32_t fbf_width = hal_remote_l32( XPTR( fbf_cxy , &fbf_ptr->ext.fbf.width ) ); 142 uint32_t fbf_height = hal_remote_l32( XPTR( fbf_cxy , &fbf_ptr->ext.fbf.height ) ); 143 144 // check new window size and coordinates 145 if( (((l_min + nlines) > fbf_height) || ((p_min + npixels) > fbf_width)) ) 146 { 147 printk("\n[ERROR] in %s / thread[%x,%x]" 148 "illegal new coordinates (%d,%d) for window (%d,%d) in fbf (%d,%d)\n", 149 process->pid, this->trdid, p_min, l_min, npixels, nlines, fbf_width, fbf_height ); 150 return -1; 151 } 152 153 // build extended pointers on windows lock, root, and wid allocator 154 xptr_t windows_lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock ); 155 xptr_t windows_root_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_root ); 156 xptr_t windows_bitmap_xp = XPTR( fbf_cxy , fbf_ptr->ext.fbf.windows_bitmap ); 157 158 // allocate memory for the window descriptor in local cluster 159 req.type = KMEM_KCM; 160 req.order = bits_log2( sizeof(fbf_window_t) ); 161 req.flags = AF_ZERO | AF_KERNEL; 162 window = kmem_alloc( &req ); 163 164 if( window == NULL ) 165 { 166 printk("\n[ERROR] in %s / thread[%x,%x] cannot allocate window descriptor\n", 167 __FUNCTION__, process->pid, this->trdid ); 168 return -1; 169 } 170 171 #if (DEBUG_DEV_FBF & 1) 172 cycle = (uint32_t)hal_get_cycles(); 173 if( DEBUG_DEV_FBF < cycle ) 174 printk("\n[%s] thread[%x,%x] created window descriptor %x / cycle %d\n", 175 __FUNCTION__ , process->pid, this->trdid, window, cycle ); 176 #endif 177 178 // getpointers on reference process 179 xptr_t ref_xp = process->ref_xp; 180 process_t * ref_ptr = GET_PTR( ref_xp ); 181 cxy_t ref_cxy = GET_CXY( ref_xp ); 182 183 // allocate a new vseg, and introduce it in the reference process VSL 184 if( ref_cxy == local_cxy ) 185 { 186 vseg = vmm_create_vseg( process, // owner process 187 VSEG_TYPE_ANON, // localised, public 188 0, // base, unused for ANON 189 nlines * npixels, // size 190 0, // file_offset, unused for ANON 191 0, // file_size, unused for ANON 192 XPTR_NULL, // mapper_xp, unused for ANON 193 local_cxy ); // mapping cluster 194 } 195 else 196 { 197 rpc_vmm_create_vseg_client( ref_cxy, 198 ref_ptr, 199 VSEG_TYPE_ANON, 200 0, // base, unused for ANON 201 nlines * npixels, // size 202 0, // file_offset, unused for ANON 203 0, // file size, unused for ANON 204 XPTR_NULL, // mapper_xp, unused for ANON 205 local_cxy, 206 &vseg ); 207 } 208 209 if( vseg == NULL ) 210 { 211 printk("\n[ERROR] in %s / thread[%x,%x] cannot create vseg in reference cluster\n", 212 __FUNCTION__, process->pid, this->trdid ); 213 req.ptr = (void *)window; 214 kmem_free( &req ); 215 return -1; 216 } 217 218 // get vseg base 219 vseg_base = (intptr_t)hal_remote_lpt( XPTR( ref_cxy , &vseg->min ) ); 220 221 #if (DEBUG_DEV_FBF & 1) 222 cycle = (uint32_t)hal_get_cycles(); 223 if( DEBUG_DEV_FBF < cycle ) 224 printk("\n[%s] thread[%x,%x] allocated vseg / base %x / cycle %d\n", 225 __FUNCTION__ , process->pid, this->trdid, vseg_base, cycle ); 226 #endif 227 228 // take the lock protecting windows in write mode 229 remote_rwlock_wr_acquire( windows_lock_xp ); 230 231 // allocate a wid from allocator in FBF descriptor extension 232 uint32_t wid = bitmap_remote_alloc( windows_bitmap_xp , CONFIG_FBF_WINDOWS_MAX_NR ); 233 234 if( wid == 0xFFFFFFFF ) 235 { 236 printk("\n[ERROR] in %s / thread[%x,%x] cannot allocate buffer for window\n", 237 __FUNCTION__, process->pid, this->trdid ); 238 req.ptr = (void *)window; 239 kmem_free( &req ); 240 vmm_remove_vseg( process , vseg ); 241 return -1; 242 } 243 244 // initialize window descriptor 245 window->pid = process->pid; 246 window->wid = wid; 247 window->height = nlines; 248 window->width = npixels; 249 window->l_min = l_min; 250 window->p_min = p_min; 251 window->hidden = false; 252 window->buffer = (uint8_t *)vseg_base; 253 254 // register new window in xlist rooted in FBF extension 255 xlist_add_last( windows_root_xp , XPTR( local_cxy , &window->xlist ) ); 256 257 // build extended pointer on relevant entry in windows_tbl[] array 258 xptr_t windows_tbl_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_tbl[wid] ); 259 260 // register new window in windows_tbl[] stored in FBF extension 261 hal_remote_s64( windows_tbl_xp , XPTR( local_cxy , window ) ); 262 263 // release the lock protecting windows in write mode 264 remote_rwlock_wr_release( windows_lock_xp ); 265 266 #if DEBUG_DEV_FBF 267 cycle = (uint32_t)hal_get_cycles(); 268 if( DEBUG_DEV_FBF < cycle ) 269 printk("\n[%s] thread[%x,%x] exit / wid %d / buffer %x / cycle %d\n", 270 __FUNCTION__ , this->process->pid, this->trdid, wid , window->buffer, cycle ); 271 #endif 272 273 #if (DEBUG_DEV_FBF & 1) 274 hal_vmm_display( ref_xp , true ); 275 #endif 276 277 // return pointer on allocated buffer 278 *user_buffer = vseg_base; 279 280 return wid; 281 282 } // end dev_fbf_create_window() 283 284 //////////////////////////////////////////////////////////////////////////////////////// 285 // This static function is called by the dev_fbf_display() function. 286 // For a partial FBF line, identified by the <f_line>, <f_p_min>, <f_p_max> arguments 287 // in FBF reference, and for one remote window, identified by the <window_xp> argument, 288 // it updates the target buffer identified by <t_buffer>, and containing exactly 289 // (f_p_max - f_p_min) pixels. 290 // Depending on the actual overlap between the window and the <t_buffer> representing 291 // the partial FBF line, it moves up to (f_p_max - f_p_min) pixels from the window 292 // buffer to the target buffer. The number of moved pixels can be nul if no overlap. 293 //////////////////////////////////////////////////////////////////////////////////////// 294 // @ f_line : [in] line index in FBF reference (from 0 to fbf_height-1). 295 // @ f_p_min : [in] first pixel in FBF line. 296 // @ f_p_max : [in] last pixel in FBF line (excluded). 297 // @ window_xp : [in] extended pointer on checked window . 298 // @ t_buffer : [out] local pointer on target buffer to be updated. 299 /////////////////////////////////////////////////////////////////////////////////////// 300 __attribute__ ((noinline)) static void handle_one_window( uint32_t f_line, 301 uint32_t f_p_min, 302 uint32_t f_p_max, 303 xptr_t window_xp, 304 uint8_t * t_buffer ) 305 { 306 // get remote window descriptor cluster and local pointer 307 cxy_t window_cxy = GET_CXY( window_xp ); 308 fbf_window_t * window_ptr = GET_PTR( window_xp ); 309 310 // get remote window min/max coordinates in FBF reference 311 uint32_t w_l_min = hal_remote_l32( XPTR( window_cxy , &window_ptr->l_min ) ); 312 uint32_t w_p_min = hal_remote_l32( XPTR( window_cxy , &window_ptr->p_min ) ); 313 uint32_t w_height = hal_remote_l32( XPTR( window_cxy , &window_ptr->height ) ); 314 uint32_t w_width = hal_remote_l32( XPTR( window_cxy , &window_ptr->width ) ); 315 uint32_t w_l_max = w_l_min + w_height; 316 uint32_t w_p_max = w_p_min + w_width; 317 318 // does nothing if partial FBF line does not overlap the window 319 if( (f_line < w_l_min) || (f_line >= w_l_max) || 320 (f_p_max < w_p_min) || (f_p_min >= w_p_max) ) return; 321 322 // get pointer on window buffer in user space 323 uint8_t * w_buffer = hal_remote_lpt( XPTR( window_cxy , &window_ptr->buffer ) ); 324 325 // get min & max indexes for pixels to be moved in FBF reference 326 uint32_t f_pixel_min = (f_p_min < w_p_min) ? w_p_min : f_p_min; 327 uint32_t f_pixel_max = (f_p_max < w_p_max) ? f_p_max : w_p_max; 328 329 // compute number of pixels to move from w_buffer to f_buffer 330 uint32_t npixels = f_pixel_max - f_pixel_min; 331 332 // compute offset in target buffer 333 uint32_t t_offset = f_pixel_min - f_p_min; 334 335 // compute line index in window 336 uint32_t w_line = f_line - w_l_min; 337 338 // compute offset in window buffer 339 uint32_t w_offset = (w_line * w_height) + f_pixel_min - w_p_min; 340 341 // move pixels from w_buffer (user space) to t_buffer in kernel space 342 hal_copy_from_uspace( XPTR( local_cxy , &t_buffer[t_offset] ), 343 &w_buffer[w_offset], 344 npixels ); 345 346 } // end handle_one_window() 347 348 //////////////////////////////////////////////////////////////////////////////////////// 349 // This static function is called by dev_fbf_refresh_window(), dev_fbf_move_window(), 350 // dev_fbf_resize_window(), and dev_fbf_delete_window(). It updates all lines of the 351 // window identified by the <window_xp>, <line_first>, and <line_last>> arguments. 352 // It scan all registered windows to take into account the overlap priorities defined 353 // by the windows xlist. It does not take the lock protecting the xlist, that must be 354 // taken by the calling function. 355 //////////////////////////////////////////////////////////////////////////////////////// 356 // @ window_xp : [in] extended pointer on window defining the FBF pixels to refresh. 357 // @ line_first : [in] first line index. 358 // @ line_last : [in] last line index (excluded). 359 //////////////////////////////////////////////////////////////////////////////////////// 360 error_t fbf_update( xptr_t window_xp, 361 uint32_t line_first, 362 uint32_t line_last ) 363 { 364 uint32_t line; // iterator to scan the FBF lines 365 uint32_t pixel; // iterator to scan pixels in one FBF line 366 xptr_t iter_xp; // iterator to scan the list of windows 367 error_t error; 368 369 // this intermediate buffer stores one line in 370 // target window, to handle other windows overlap 371 uint8_t line_buffer[CONFIG_FBF_WINDOWS_MAX_WIDTH]; 372 373 // get pointer on calling thread and core lid 374 thread_t * this = CURRENT_THREAD; 375 376 // get window cluster and local pointer 377 cxy_t window_cxy = GET_CXY( window_xp ); 378 fbf_window_t * window_ptr = GET_PTR( window_xp ); 379 380 #if DEBUG_DEV_FBF 381 uint32_t wid = hal_remote_l32( XPTR( window_cxy , &window_ptr->wid ) ); 382 uint32_t lid = this->core->lid; 383 uint32_t cycle = (uint32_t)hal_get_cycles(); 384 if( DEBUG_DEV_FBF < cycle ) 385 printk("\n[%s] core[%x,%d] enter / wid %d / cycle %d\n", 386 __FUNCTION__, local_cxy, lid, wid, cycle ); 96 387 #endif 97 388 … … 101 392 chdev_t * fbf_ptr = GET_PTR( fbf_xp ); 102 393 103 // check fbf_xp definition 104 assert( (fbf_xp != XPTR_NULL) , "undefined FBF chdev descriptor" ); 394 // get frame buffer width 395 uint32_t fbf_width = hal_remote_l32( XPTR( fbf_cxy , &fbf_ptr->ext.fbf.width ) ); 396 397 // get pointer on driver command function 398 dev_cmd_t * cmd = hal_remote_lpt( XPTR( fbf_cxy , &fbf_ptr->cmd ) ); 399 400 // build extended pointers on windows xlist root 401 xptr_t windows_root_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_root ); 402 403 // get window size and coordinates 404 uint32_t p_min = hal_remote_l32( XPTR( window_cxy , &window_ptr->p_min ) ); 405 uint32_t l_min = hal_remote_l32( XPTR( window_cxy , &window_ptr->l_min ) ); 406 uint32_t w_pixels = hal_remote_l32( XPTR( window_cxy , &window_ptr->width ) ); 407 408 error = 0; 409 410 // loop on target window lines (FBF coordinates) 411 for( line = l_min + line_first ; line < (l_min + line_last) ; line++ ) 412 { 413 // reset the line buffer to default value 414 for( pixel = 0 ; pixel < w_pixels ; pixel++ ) line_buffer[pixel] = 127; 415 416 // loop on all windows 417 XLIST_FOREACH( windows_root_xp , iter_xp ) 418 { 419 // get pointers on remote window 420 xptr_t tgt_xp = XLIST_ELEMENT( iter_xp , fbf_window_t , xlist ); 421 fbf_window_t * tgt_ptr = GET_PTR( window_xp ); 422 cxy_t tgt_cxy = GET_CXY( window_xp ); 423 424 bool_t hidden = hal_remote_l32( XPTR( tgt_cxy , &tgt_ptr->hidden ) ); 425 426 // fill the line_buf for this window if not hidden 427 if( hidden == false ) handle_one_window( line, // line index 428 p_min, // pixel_min 429 p_min + w_pixels, // pixel_max 430 tgt_xp, // window_xp 431 line_buffer ); 432 } // end for windows 433 434 // compute offset in FBF 435 uint32_t fbf_offset = p_min + (line * fbf_width); 436 437 // register command in calling thread descriptor 438 this->fbf_cmd.dev_xp = fbf_xp; 439 this->fbf_cmd.type = FBF_DRIVER_KERNEL_WRITE; 440 this->fbf_cmd.buffer = line_buffer; 441 this->fbf_cmd.npixels = w_pixels; 442 this->fbf_cmd.offset = fbf_offset; 443 444 // call driver to display one line 445 cmd( XPTR( local_cxy , this ) ); 446 447 error |= this->fbf_cmd.error; 448 449 } // end for lines 450 451 #if DEBUG_DEV_FBF 452 cycle = (uint32_t)hal_get_cycles(); 453 if( DEBUG_DEV_FBF < cycle ) 454 printk("\n[%s] core[%x,%d] exit / wid %d / cycle %d\n", 455 __FUNCTION__, local_cxy, this->core->lid, wid, cycle ); 456 #endif 457 458 // return I/O operation status 459 return error; 460 461 } // end fbf_update() 462 463 ////////////////////////////////////////////// 464 error_t dev_fbf_delete_window( uint32_t wid ) 465 { 466 kmem_req_t req; 467 468 thread_t * this = CURRENT_THREAD; 469 process_t * process = this->process; 470 471 #if DEBUG_DEV_FBF 472 uint32_t cycle = (uint32_t)hal_get_cycles(); 473 if( DEBUG_DEV_FBF < cycle ) 474 printk("\n[%s] thread[%x,%x] enters : wid %d / cycle %d\n", 475 __FUNCTION__ , process->pid, this->trdid, wid, cycle ); 476 #endif 477 478 // get cluster and pointers on FBF chdev 479 xptr_t fbf_xp = chdev_dir.fbf[0]; 480 cxy_t fbf_cxy = GET_CXY( fbf_xp ); 481 chdev_t * fbf_ptr = GET_PTR( fbf_xp ); 482 483 // build extended pointers on windows lock, and wid allocator 484 xptr_t windows_lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock ); 485 xptr_t wid_bitmap_xp = XPTR( fbf_cxy , fbf_ptr->ext.fbf.windows_bitmap ); 486 487 // build extended pointer on relevant entry in windows_tbl[] array 488 xptr_t windows_tbl_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_tbl[wid] ); 489 490 // get extended pointer on remote window descriptor 491 xptr_t window_xp = hal_remote_l64( windows_tbl_xp ); 492 493 if( window_xp == XPTR_NULL ) 494 { 495 printk("\n[ERROR] in %s / thread[%x,%x] / wid %d non registered\n", 496 __FUNCTION__, process->pid, this->trdid, wid ); 497 return -1; 498 } 499 500 // get cluster and local pointer on remote window 501 cxy_t window_cxy = GET_CXY( window_xp ); 502 fbf_window_t * window_ptr = GET_PTR( window_xp ); 503 504 // get process owner PID 505 pid_t owner_pid = hal_remote_l32( XPTR( window_cxy , &window_ptr->pid ) ); 506 507 // check caller PID / owner PID 508 if( owner_pid != process->pid ) 509 { 510 printk("\n[ERROR] in %s : caller PID (%x) != owner PID (%x)\n", 511 __FUNCTION__, process->pid , owner_pid ); 512 return -1; 513 } 514 515 // get associated buffer, and number of lines 516 uint8_t * buffer = hal_remote_lpt( XPTR( window_cxy , &window_ptr->buffer ) ); 517 uint32_t nlines = hal_remote_l32( XPTR( window_cxy , &window_ptr->height ) ); 518 519 // 1. take the lock protecting windows in write mode 520 remote_rwlock_wr_acquire( windows_lock_xp ); 521 522 // 2. update the FBF window 523 fbf_update( window_xp , 0 , nlines ); 524 525 // 3. remove the window from windows_tbl[] array 526 hal_remote_s64( windows_tbl_xp , XPTR_NULL ); 527 528 // 4. remove the window from xlist 529 xlist_unlink( XPTR( window_cxy , &window_ptr->xlist ) ); 530 531 // 5. release wid to bitmap 532 bitmap_remote_clear( wid_bitmap_xp , wid ); 533 534 // 6. release the lock protecting windows in write mode 535 remote_rwlock_wr_release( windows_lock_xp ); 536 537 // 7. release memory allocated for window descriptor 538 req.type = KMEM_KCM; 539 req.ptr = window_ptr; 540 kmem_remote_free( window_cxy , &req ); 541 542 // 8. release the associated vseg 543 vmm_global_delete_vseg( process , (intptr_t)buffer ); 544 545 #if DEBUG_DEV_FBF 546 cycle = (uint32_t)hal_get_cycles(); 547 if( DEBUG_DEV_FBF < cycle ) 548 printk("\n[%s] thread[%x,%x] exit / cycle %d\n", 549 __FUNCTION__ , process->pid, this->trdid, cycle ); 550 #endif 551 552 return 0; 553 554 } // end dev_fbf_delete_window() 555 556 //////////////////////////////////////////// 557 error_t dev_fbf_move_window( uint32_t wid, 558 uint32_t l_min, 559 uint32_t p_min ) 560 { 561 thread_t * this = CURRENT_THREAD; 562 process_t * process = this->process; 563 564 #if DEBUG_DEV_FBF 565 uint32_t cycle = (uint32_t)hal_get_cycles(); 566 if( DEBUG_DEV_FBF < cycle ) 567 printk("\n[%s] thread[%x,%x] enters : wid %d / l_min %d / p_min %d / cycle %d\n", 568 __FUNCTION__ , process->pid, this->trdid, wid, l_min, p_min, cycle ); 569 #endif 570 571 // get cluster and pointers on FBF chdev 572 xptr_t fbf_xp = chdev_dir.fbf[0]; 573 cxy_t fbf_cxy = GET_CXY( fbf_xp ); 574 chdev_t * fbf_ptr = GET_PTR( fbf_xp ); 575 576 // build extended pointers on windows lock and root 577 xptr_t windows_lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock ); 578 xptr_t windows_root_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_root ); 579 580 // build extended pointer on relevant entry in windows_tbl[] array 581 xptr_t windows_tbl_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_tbl[wid] ); 582 583 // get extended pointer on remote window descriptor 584 xptr_t window_xp = hal_remote_l64( windows_tbl_xp ); 585 586 if( window_xp == XPTR_NULL ) 587 { 588 printk("\n[ERROR] in %s / thread[%x,%x] / wid %d non registered\n", 589 __FUNCTION__, process->pid, this->trdid, wid ); 590 return -1; 591 } 592 593 // get cluster and local pointer for remote window 594 cxy_t window_cxy = GET_CXY( window_xp ); 595 fbf_window_t * window_ptr = GET_PTR( window_xp ); 596 597 // get process owner PID, coordinates, and number of lines 598 pid_t owner_pid = hal_remote_l32( XPTR( window_cxy , &window_ptr->pid ) ); 599 uint32_t p_zero = hal_remote_l32( XPTR( window_cxy , &window_ptr->p_min ) ); 600 uint32_t l_zero = hal_remote_l32( XPTR( window_cxy , &window_ptr->l_min ) ); 601 uint32_t nlines = hal_remote_l32( XPTR( window_cxy , &window_ptr->height ) ); 602 603 // check caller PID / owner PID 604 if( owner_pid != process->pid ) 605 { 606 printk("\n[ERROR] in %s : caller PID (%x) != owner PID (%x)\n", 607 __FUNCTION__, process->pid , owner_pid ); 608 return -1; 609 } 610 611 // does nothing if no change 612 if( (p_zero == p_min) && (l_zero == l_min) ) return 0; 613 614 // 1. take the lock protecting windows in write mode 615 remote_rwlock_wr_acquire( windows_lock_xp ); 616 617 #if ( DEBUG_DEV_FBF & 1 ) 618 printk("\n[%s] lock taken\n", __FUNCTION__ ); 619 #endif 620 621 // 2. gives the window the lowest priority 622 xptr_t xlist_entry_xp = XPTR( window_cxy , &window_ptr->xlist ); 623 xlist_unlink( xlist_entry_xp ); 624 xlist_add_first( windows_root_xp , xlist_entry_xp ); 625 626 #if ( DEBUG_DEV_FBF & 1 ) 627 printk("\n[%s] set low priority \n", __FUNCTION__ ); 628 #endif 629 630 // 3. set the "hidden" flag in window descriptor 631 hal_remote_s32( XPTR( window_cxy , &window_ptr->hidden ) , true ); 632 633 #if ( DEBUG_DEV_FBF & 1 ) 634 printk("\n[%s] hidden set\n", __FUNCTION__ ); 635 #endif 636 637 // 4. refresh the FBF for the current window position 638 fbf_update( window_xp , 0 , nlines ); 639 640 #if ( DEBUG_DEV_FBF & 1 ) 641 printk("\n[%s] refreshed old position\n", __FUNCTION__ ); 642 #endif 643 644 // 5. set the new coordinates in the window descriptor, 645 hal_remote_s32( XPTR( window_cxy , &window_ptr->l_min ), l_min ); 646 hal_remote_s32( XPTR( window_cxy , &window_ptr->p_min ), p_min ); 647 648 #if ( DEBUG_DEV_FBF & 1 ) 649 printk("\n[%s] l_min & p_min updated\n", __FUNCTION__ ); 650 #endif 651 652 // 6. gives the window the highest priority 653 xlist_unlink( xlist_entry_xp ); 654 xlist_add_last( windows_root_xp , xlist_entry_xp ); 655 656 #if ( DEBUG_DEV_FBF & 1 ) 657 printk("\n[%s] set high priority\n", __FUNCTION__ ); 658 #endif 659 660 // 7. reset the "hidden" flag in window descriptor 661 hal_remote_s32( XPTR( window_cxy , &window_ptr->hidden ) , false ); 662 663 #if ( DEBUG_DEV_FBF & 1 ) 664 printk("\n[%s] hidden reset\n", __FUNCTION__ ); 665 #endif 666 667 // 8. refresh the FBF for the new window position 668 fbf_update( window_xp , 0 , nlines ); 669 670 #if ( DEBUG_DEV_FBF & 1 ) 671 printk("\n[%s] refresh new position\n", __FUNCTION__ ); 672 #endif 673 674 // 9. release the lock protecting windows in write mode 675 remote_rwlock_wr_release( windows_lock_xp ); 676 677 #if DEBUG_DEV_FBF 678 cycle = (uint32_t)hal_get_cycles(); 679 if( DEBUG_DEV_FBF < cycle ) 680 printk("\n[%s] thread[%x,%x] exit / cycle %d\n", 681 __FUNCTION__ , process->pid, this->trdid, cycle ); 682 #endif 683 684 return 0; 685 686 } // end dev_fbf_move_window() 687 688 ///////////////////////////////////////////// 689 error_t dev_fbf_resize_window( uint32_t wid, 690 uint32_t width, 691 uint32_t height ) 692 { 693 thread_t * this = CURRENT_THREAD; 694 process_t * process = this->process; 695 696 #if DEBUG_DEV_FBF 697 uint32_t cycle = (uint32_t)hal_get_cycles(); 698 if( DEBUG_DEV_FBF < cycle ) 699 printk("\n[%s] thread[%x,%x] enters : wid %d / width %d / height %d / cycle %d\n", 700 __FUNCTION__ , process->pid , this->trdid , wid, width , height , cycle ); 701 #endif 702 703 // get cluster and pointers on FBF chdev 704 xptr_t fbf_xp = chdev_dir.fbf[0]; 705 cxy_t fbf_cxy = GET_CXY( fbf_xp ); 706 chdev_t * fbf_ptr = GET_PTR( fbf_xp ); 707 708 // build extended pointers on windows lock and root 709 xptr_t windows_lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock ); 710 xptr_t windows_root_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_root ); 711 712 // build extended pointer on relevant entry in windows_tbl[] array 713 xptr_t windows_tbl_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_tbl[wid] ); 714 715 // get extended pointer on remote window descriptor 716 xptr_t window_xp = hal_remote_l64( windows_tbl_xp ); 717 718 if( window_xp == XPTR_NULL ) 719 { 720 printk("\n[ERROR] in %s / thread[%x,%x] / wid %d non registered\n", 721 __FUNCTION__, process->pid, this->trdid, wid ); 722 return -1; 723 } 724 725 // get cluster and local pointer for remote window 726 cxy_t window_cxy = GET_CXY( window_xp ); 727 fbf_window_t * window_ptr = GET_PTR( window_xp ); 728 729 // get process owner PID, width, height, and buffer 730 pid_t owner_pid = hal_remote_l32( XPTR( window_cxy , &window_ptr->pid ) ); 731 uint32_t nlines = hal_remote_l32( XPTR( window_cxy , &window_ptr->height ) ); 732 uint32_t npixels = hal_remote_l32( XPTR( window_cxy , &window_ptr->width ) ); 733 void * base = hal_remote_lpt( XPTR( window_cxy , &window_ptr->buffer ) ); 734 735 // check caller PID / owner PID 736 if( owner_pid != process->pid ) 737 { 738 printk("\n[ERROR] in %s : caller PID (%x) != owner PID (%x)\n", 739 __FUNCTION__, process->pid , owner_pid ); 740 return -1; 741 } 742 743 // does nothing if no change 744 if( (width == npixels) && (height == nlines) ) return 0; 745 746 // compute old_size and new size 747 uint32_t old_size = nlines * npixels; 748 uint32_t new_size = width * height; 749 750 // 1. take the lock protecting windows in write mode 751 remote_rwlock_wr_acquire( windows_lock_xp ); 752 753 #if ( DEBUG_DEV_FBF & 1 ) 754 printk("\n[%s] lock taken\n", __FUNCTION__ ); 755 #endif 756 757 // 2. gives the window the lowest priority (remove, then add first) 758 xptr_t xlist_entry_xp = XPTR( window_cxy , &window_ptr->xlist ); 759 xlist_unlink( xlist_entry_xp ); 760 xlist_add_first( windows_root_xp , xlist_entry_xp ); 761 762 #if ( DEBUG_DEV_FBF & 1 ) 763 printk("\n[%s] set low priority\n", __FUNCTION__ ); 764 #endif 765 766 // 3. set the "hidden" flag in window descriptor 767 hal_remote_s32( XPTR( window_cxy , &window_ptr->hidden ) , true ); 768 769 #if ( DEBUG_DEV_FBF & 1 ) 770 printk("\n[%s] hidden set\n", __FUNCTION__ ); 771 #endif 772 773 // 4. refresh the FBF for the current window size 774 fbf_update( window_xp , 0 , nlines ); 775 776 #if ( DEBUG_DEV_FBF & 1 ) 777 printk("\n[%s] refreshed old window\n", __FUNCTION__ ); 778 #endif 779 780 // 5. set the new width & height in the window descriptor, 781 hal_remote_s32( XPTR( window_cxy , &window_ptr->width ), width ); 782 hal_remote_s32( XPTR( window_cxy , &window_ptr->height ), height ); 783 784 #if ( DEBUG_DEV_FBF & 1 ) 785 printk("\n[%s] width & height updated\n", __FUNCTION__ ); 786 #endif 787 788 // 6. resize vseg if required 789 vmm_global_resize_vseg( process, (intptr_t)base, (intptr_t)base, width * height ); 790 791 #if ( DEBUG_DEV_FBF & 1 ) 792 printk("\n[%s] vseg resized\n", __FUNCTION__ ); 793 #endif 794 795 // 7. fill buffer extension if required 796 if( new_size > old_size ) memset( base + old_size , 0 , new_size - old_size ); 797 798 #if ( DEBUG_DEV_FBF & 1 ) 799 printk("\n[%s] buffer extension initialized\n", __FUNCTION__ ); 800 #endif 801 802 // 8. gives the window the highest priority 803 xlist_unlink( xlist_entry_xp ); 804 xlist_add_last( windows_root_xp , xlist_entry_xp ); 805 806 #if ( DEBUG_DEV_FBF & 1 ) 807 printk("\n[%s] set high priority\n", __FUNCTION__ ); 808 #endif 809 810 // 9. reset the "hidden" flag in window descriptor 811 hal_remote_s32( XPTR( window_cxy , &window_ptr->hidden ) , false ); 812 813 #if ( DEBUG_DEV_FBF & 1 ) 814 printk("\n[%s] hidden reset\n", __FUNCTION__ ); 815 #endif 816 817 // 10. refresh the FBF for the new window position 818 fbf_update( window_xp , 0 , height ); 819 820 #if ( DEBUG_DEV_FBF & 1 ) 821 printk("\n[%s] refresh new position\n", __FUNCTION__ ); 822 #endif 823 824 // 11. release the lock protecting windows in write mode 825 remote_rwlock_wr_release( windows_lock_xp ); 826 827 #if DEBUG_DEV_FBF 828 cycle = (uint32_t)hal_get_cycles(); 829 if( DEBUG_DEV_FBF < cycle ) 830 printk("\n[%s] thread[%x,%x] exit / cycle %d\n", 831 __FUNCTION__ , process->pid, this->trdid, cycle ); 832 #endif 833 834 return 0; 835 836 } // end dev_fbf_resize_window() 837 838 /////////////////////////////////////////////// 839 error_t dev_fbf_refresh_window( uint32_t wid, 840 uint32_t line_first, 841 uint32_t line_last ) 842 { 843 // get local pointers on calling thread and process 844 thread_t * this = CURRENT_THREAD; 845 process_t * process = this->process; 846 847 #if DEBUG_DEV_FBF 848 uint32_t cycle = (uint32_t)hal_get_cycles(); 849 if( DEBUG_DEV_FBF < cycle ) 850 printk("\n[%s] thread[%x,%x] enters for wid %d / first %d / last %d / cycle %d\n", 851 __FUNCTION__ , process->pid, this->trdid, wid, line_first, line_last, cycle ); 852 #endif 853 854 // get cluster and pointers on FBF chdev 855 xptr_t fbf_xp = chdev_dir.fbf[0]; 856 cxy_t fbf_cxy = GET_CXY( fbf_xp ); 857 chdev_t * fbf_ptr = GET_PTR( fbf_xp ); 858 859 // build extended pointer on windows lock 860 xptr_t windows_lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock ); 861 862 // build extended pointer on relevant entry in windows_tbl[] array 863 xptr_t windows_tbl_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_tbl[wid] ); 864 865 // get pointers on remote window descriptor 866 xptr_t window_xp = hal_remote_l64( windows_tbl_xp ); 867 cxy_t window_cxy = GET_CXY( window_xp ); 868 fbf_window_t * window_ptr = GET_PTR( window_xp ); 869 870 // check <wid> argument 871 if( window_xp == XPTR_NULL ) 872 { 873 printk("\n[ERROR] in %s / thread[%x,%x] / wid %d non registered\n", 874 __FUNCTION__, process->pid, this->trdid, wid ); 875 return -1; 876 } 877 878 // get process owner PID 879 pid_t owner_pid = hal_remote_l32( XPTR( window_cxy , &window_ptr->pid ) ); 880 881 // check caller PID / owner PID 882 if( owner_pid != process->pid ) 883 { 884 printk("\n[ERROR] in %s : caller PID (%x) != owner PID (%x)\n", 885 __FUNCTION__, process->pid , owner_pid ); 886 return -1; 887 } 888 889 // get number of lines in window 890 uint32_t nlines = hal_remote_l32( XPTR( window_cxy , &window_ptr->height ) ); 891 892 // check <line_first> and <line_last> arguments 893 if( (line_first >= nlines) || (line_last > nlines) || (line_first >= line_last) ) 894 { 895 printk("\n[ERROR] in %s : illegal (l_first %d , l_last %d) / height %d\n", 896 __FUNCTION__, line_first, line_last, nlines ); 897 return -1; 898 } 899 900 // take the lock protecting windows xlist in read mode 901 remote_rwlock_rd_acquire( windows_lock_xp ); 902 903 // update FBF 904 fbf_update( window_xp , line_first , line_last ); 905 906 // release the lock protecting windows xlist in write mode 907 remote_rwlock_rd_release( windows_lock_xp ); 908 909 #if DEBUG_DEV_FBF 910 cycle = (uint32_t)hal_get_cycles(); 911 if( DEBUG_DEV_FBF < cycle ) 912 printk("\n[%s] thread[%x,%x] exit for wid %d / cycle %d\n", 913 __FUNCTION__, process->pid, this->trdid, wid, cycle ); 914 #endif 915 916 return 0; 917 918 } // end dev_fbf_refresh_window() 919 920 /////////////////////////////////////////////// 921 // TODO Deprecated : january 2020 [AG] 922 /////////////////////////////////////////////// 923 error_t dev_fbf_move_data( bool_t is_write, 924 void * user_buffer, 925 uint32_t npixels, 926 uint32_t offset ) 927 { 928 // get pointer on calling thread 929 thread_t * this = CURRENT_THREAD; 930 931 #if DEBUG_DEV_FBF 932 uint32_t cycle = (uint32_t)hal_get_cycles(); 933 if( DEBUG_DEV_FBF < cycle ) 934 printk("\n[%s] thread[%x,%x] : buffer %x / npixels %d / offset %x / cycle %d\n", 935 __FUNCTION__ , this->process->pid, this->trdid, 936 user_buffer, npixels, offset, cycle ); 937 #endif 938 939 // get pointers on FBF chdev 940 xptr_t fbf_xp = chdev_dir.fbf[0]; 941 cxy_t fbf_cxy = GET_CXY( fbf_xp ); 942 chdev_t * fbf_ptr = GET_PTR( fbf_xp ); 105 943 106 944 // get frame buffer width and height … … 108 946 uint32_t height = hal_remote_l32 ( XPTR( fbf_cxy , &fbf_ptr->ext.fbf.height ) ); 109 947 110 // check offset and length versus FBF size 111 assert( ((offset + length) <= (width * height)) , 112 "offset %d / length %d / width %d / height %d\n", offset, length, width, height ); 948 // check offset and npixels versus FBF size 949 if( ((offset + npixels) > (width * height)) ) 950 { 951 printk("\n[ERROR] in %s : offset (%d) + npixels (%d) / width (%d) / height (%d)\n", 952 __FUNCTION__, offset, npixels, width, height ); 953 return -1; 954 } 113 955 114 956 // register command in calling thread descriptor 115 957 this->fbf_cmd.dev_xp = fbf_xp; 116 this->fbf_cmd.type = cmd_type;958 this->fbf_cmd.type = is_write ? FBF_DRIVER_USER_WRITE : FBF_DRIVER_USER_READ; 117 959 this->fbf_cmd.buffer = user_buffer; 118 960 this->fbf_cmd.offset = offset; 119 this->fbf_cmd. length = length;961 this->fbf_cmd.npixels = npixels; 120 962 121 963 // get driver command function … … 130 972 cycle = (uint32_t)hal_get_cycles(); 131 973 if( DEBUG_DEV_FBF < cycle ) 132 printk("\n[%s] thread[%x,%x] completes %s / error = %d / cycle %d\n", 133 __FUNCTION__ , this->process->pid, this->trdid, 134 dev_fbf_cmd_str(cmd_type), error , cycle ); 974 printk("\n[%s] thread[%x,%x] exit / cycle %d\n", 975 __FUNCTION__ , this->process->pid, this->trdid, cycle ); 135 976 #endif 136 977 … … 139 980 140 981 } // end dev_fbf_move_data() 982 983
Note: See TracChangeset
for help on using the changeset viewer.