Changeset 630 for trunk/hal/tsar_mips32/core/hal_gpt.c
- Timestamp:
- May 21, 2019, 6:00:06 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/tsar_mips32/core/hal_gpt.c
r629 r630 318 318 319 319 ///////////////////////////////////////////////////////////////////////////////////////// 320 // This static function check that a PTE1 entry, in the PT1 of a possibly remote GPT, 321 // identified by the <pte1_xp> argument is mapped. If this entry is not mapped, 322 // it allocates a - local or remote - PT2, updates the PTE1 value in PT1, and 323 // returns the PTE1 value in the <pte1> buffer. 324 // It uses the TSR_MMU_LOCKED attribute in PTE1 to handle possible concurrent 325 // mappings of the missing PTE1: 326 // - If the PTE1 is unmapped and unlocked => it tries to atomically lock this PTE1, 327 // and map it if lock is successful. 328 // - If the PTE1 is unmapped but locked => it poll the PTE1 value, unti the mapping 329 // is done by the other thread. 330 // - If the PTE1 is already mapped => it does nothing 331 // It returns an error if it cannot allocate memory fot a new PT2. 320 // This static function returns in the <ptd1_value> buffer the current value of 321 // the PT1 entry identified by the <pte1_xp> argument, that must contain a PTD1 322 // (i.e. a pointer on a PT2). If this PT1 entry is not mapped yet, it allocates a 323 // new PT2 and updates the PT1 entry, using the TSAR_MMU_LOCKED attribute in PT1 324 // entry, to handle possible concurrent mappings of the missing PTD1: 325 // 1) If the PT1 entry is unmapped, it tries to atomically lock this PTD1. 326 // - if the atomic lock is successful it allocates a new PT1, and updates the PTD1. 327 // - else, it simply waits, in a polling loop, the mapping done by another thread. 328 // In both cases, returns the PTD1 value, when the mapping is completed. 329 // 2) If the PT1 entry is already mapped, it returns the PTD1 value, and does 330 // nothing else. 332 331 ///////////////////////////////////////////////////////////////////////////////////////// 333 static error_t hal_gpt_allocate_pt2( xptr_t pt e1_xp,334 uint32_t * pte1_value )335 { 336 cxy_t gpt_cxy; // target GPT cluster = GET_CXY( pt e1_xp );337 uint32_t pt e1; // PTE1 value332 static error_t hal_gpt_allocate_pt2( xptr_t ptd1_xp, 333 uint32_t * ptd1_value ) 334 { 335 cxy_t gpt_cxy; // target GPT cluster = GET_CXY( ptd1_xp ); 336 uint32_t ptd1; // PTD1 value 338 337 ppn_t pt2_ppn; // PPN of page containing the new PT2 339 338 bool_t atomic; … … 342 341 343 342 // get GPT cluster identifier 344 gpt_cxy = GET_CXY( pte1_xp ); 345 346 // get current pte1 value 347 pte1 = hal_remote_l32( pte1_xp ); 348 349 if( ((pte1 & TSAR_PTE_MAPPED) == 0) && // PTE1 unmapped and unlocked 350 ((pte1 & TSAR_PTE_LOCKED) == 0) ) // try to allocate a new PT2 343 gpt_cxy = GET_CXY( ptd1_xp ); 344 345 // get current ptd1 value 346 ptd1 = hal_remote_l32( ptd1_xp ); 347 348 if( (ptd1 & TSAR_PTE_MAPPED) == 0) // PTD1 unmapped and unlocked 351 349 { 352 // atomically lock the PT E1 to prevent concurrent PTE1 mappings353 atomic = hal_remote_atomic_cas( pt e1_xp,354 pt e1,355 pt e1 | TSAR_PTE_LOCKED );356 357 if( atomic ) // PT E1 successfully locked350 // atomically lock the PTD1 to prevent concurrent PTD1 mappings 351 atomic = hal_remote_atomic_cas( ptd1_xp, 352 ptd1, 353 ptd1 | TSAR_PTE_LOCKED ); 354 355 if( atomic ) // PTD1 successfully locked 358 356 { 359 357 // allocate one physical page for PT2 … … 377 375 pt2_ppn = ppm_page2ppn( page_xp ); 378 376 379 // build PT E1 value380 pt e1 = TSAR_PTE_MAPPED | TSAR_PTE_SMALL | pt2_ppn;377 // build PTD1 378 ptd1 = TSAR_PTE_MAPPED | TSAR_PTE_SMALL | pt2_ppn; 381 379 382 380 // set the PTD1 value in PT1 383 hal_remote_s32( pt e1_xp , pte1 );381 hal_remote_s32( ptd1_xp , ptd1 ); 384 382 hal_fence(); 385 383 … … 388 386 uint32_t cycle = (uint32_t)hal_get_cycles(); 389 387 if( DEBUG_HAL_GPT_ALLOCATE_PT2 < cycle ) 390 printk("\n[%s] : thread[%x,%x] map PT E1 / cxy %x / ix1 %d / pt1 %x / ptd1 %x\n",391 __FUNCTION__, this->process->pid, this->trdid, gpt_cxy, ix1, pt1_ptr, pt e1 );388 printk("\n[%s] : thread[%x,%x] map PTD1 / cxy %x / ix1 %d / pt1 %x / ptd1 %x\n", 389 __FUNCTION__, this->process->pid, this->trdid, gpt_cxy, ix1, pt1_ptr, ptd1 ); 392 390 #endif 393 391 } 394 else 392 else // PTD1 modified by another thread 395 393 { 396 // poll PT E1 until mapped by another thread397 while( (pt e1 & TSAR_PTE_MAPPED) == 0 ) pte1 = hal_remote_l32( pte1_xp );394 // poll PTD1 until mapped by another thread 395 while( (ptd1 & TSAR_PTE_MAPPED) == 0 ) ptd1 = hal_remote_l32( ptd1_xp ); 398 396 } 399 397 } 400 else if( ((pte1 & TSAR_PTE_MAPPED) == 0) && 401 ((pte1 & TSAR_PTE_LOCKED) != 0) ) 402 { 403 // poll PTE1 until mapped by another thread 404 while( (pte1 & TSAR_PTE_MAPPED) == 0 ) pte1 = hal_remote_l32( pte1_xp ); 405 } 406 else // PTE1 mapped => just use it 398 else // PTD1 mapped => just use it 407 399 { 408 400 … … 411 403 uint32_t cycle = (uint32_t)hal_get_cycles(); 412 404 if( DEBUG_HAL_GPT_ALLOCATE_PT2 < cycle ) 413 printk("\n[%s] : thread[%x,%x] PT E1 mapped / cxy %x / ix1 %d / pt1 %x / ptd1 %x\n",414 __FUNCTION__, this->process->pid, this->trdid, gpt_cxy, ix1, pt1_ptr, pt e1 );405 printk("\n[%s] : thread[%x,%x] PTD1 mapped / cxy %x / ix1 %d / pt1 %x / ptd1 %x\n", 406 __FUNCTION__, this->process->pid, this->trdid, gpt_cxy, ix1, pt1_ptr, ptd1 ); 415 407 #endif 416 408 417 409 } 418 410 419 *pt e1_value = pte1;411 *ptd1_value = ptd1; 420 412 return 0; 421 413
Note: See TracChangeset
for help on using the changeset viewer.