Changeset 629
- Timestamp:
- May 17, 2019, 9:27:04 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 30 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/generic/hal_gpt.h
r625 r629 61 61 #define GPT_COW 0x0400 /*! PTE must be copied on write */ 62 62 #define GPT_SWAP 0x0800 /*! PTE swapped on disk (not implemented yet) */ 63 #define GPT_LOCKED 0x1000 /*! PTE is protected against concurrent access*/63 #define GPT_LOCKED 0x1000 /*! PTE is currently accessed by a thread */ 64 64 65 65 /**************************************************************************************** … … 76 76 77 77 /**************************************************************************************** 78 * This function allocates physical memory for first level page table (PT1),78 * This function allocates physical memory for a local GPT, 79 79 * and initializes the GPT descriptor, creating an empty GPT. 80 80 **************************************************************************************** … … 87 87 * This function releases all memory dynamically allocated for a generic page table. 88 88 * For a multi-levels radix tree implementation, it includes all nodes in the tree. 89 * If the calling thread is running in the reference cluster, it checks that user PTE90 * entries are unmapped, and releases the mapped physical pages.91 * The kernel pages are not released.92 89 **************************************************************************************** 93 90 * @ gpt : pointer on generic page table descriptor. … … 96 93 97 94 /**************************************************************************************** 98 * This function prints on the kernel terminal the content of a generic page table. 99 **************************************************************************************** 100 * @ process : pointer on local process descriptor. 101 ***************************************************************************************/ 102 void hal_gpt_display( struct process_s * process ); 103 104 /**************************************************************************************** 105 * This blocking function gets a lock on a PTE (Page Table Entry) identified 106 * by its VPN, and returns only when the PTE has been successfully locked. 107 * If the target PTE is not present, it allocates and maps a physical page. 108 * A big page cannot be locked. 109 **************************************************************************************** 110 * @ gpt : pointer on the generic page table 95 * This blocking function atomically set the GPT_LOCKED attribute in a target PTE 96 * of a remote GPT identified by the <gpt_xp> and <vpn> arguments, after checking 97 * (in a busy waiting loop) that this attribute has been reset. 98 * Then, it returns in the <attr> and <ppn> buffers the current value of the PTE. 99 * It allocates memory required by the GPT implementation to register this lock 100 * in the PTE when required. 101 * WARNING : Only small pages can be locked. 102 **************************************************************************************** 103 * @ gpt_xp : [in] extended pointer on the generic page table. 104 * @ vpn : [in] virtual page number of the target PTE. 105 * @ attr : [out] local buffer for GPT attributes. 106 * @ ppn : [out] local buffer for physical page number. 107 * @ returns 0 if success / return -1 if error (no memory or big page). 108 ***************************************************************************************/ 109 error_t hal_gpt_lock_pte( xptr_t gpt_xp, 110 vpn_t vpn, 111 uint32_t * attr, 112 ppn_t * ppn ); 113 114 /**************************************************************************************** 115 * This function atomically reset the GPT_LOCKED attribute in a target PTE in a 116 * remote GPT identified by the <gpt_xp> and <vpn> arguments. 117 **************************************************************************************** 118 * @ gpt_xp : pointer on the generic page table 111 119 * @ vpn : virtual page number of the target PTE. 112 * @ returns 0 if success / return ENOMEM or EINVAL if error. 113 ***************************************************************************************/ 114 error_t hal_gpt_lock_pte( gpt_t * gpt, 115 vpn_t vpn ); 116 117 /**************************************************************************************** 118 * This function releases the lock on a PTE identified by its VPN. 119 **************************************************************************************** 120 * @ gpt : pointer on the generic page table 121 * @ vpn : virtual page number of the target PTE. 122 * @ returns 0 if success / returns EINVAL if error. 123 ***************************************************************************************/ 124 error_t hal_gpt_unlock_pte( gpt_t * gpt, 125 vpn_t vpn ); 126 127 /**************************************************************************************** 128 * This function maps in a - local or remote - GPT identified by the <gpt_xp> argument 129 * an entry identified by the <vpn> argument, as defined by <ppn> and <attr> arguments. 130 * It allocates physical memory for the GPT PT2, using a RPC_PMEM_GET_PAGES if required. 131 **************************************************************************************** 132 * @ gpt_xp : [in] pointer on the page table 120 ***************************************************************************************/ 121 void hal_gpt_unlock_pte( xptr_t gpt_xp, 122 vpn_t vpn ); 123 124 /**************************************************************************************** 125 * This low level function maps a new PTE or modifies an existing PTE in a remote GPT 126 * identified by the <gpt_xp> and <vpn> arguments, as defined by <ppn> and <attr> args. 127 * This function can be used for both a small page (PTE2), and a big page (PTE1). 128 * 129 * WARNING : For a small page, it checks that the GPT_LOCKED attribute has been 130 * previously set, to prevent concurrent accesses. 131 **************************************************************************************** 132 * @ gpt_xp : [in] extended pointer on the page table 133 133 * @ vpn : [in] virtual page number 134 * @ attr : [in] genericattributes134 * @ attr : [in] GPT attributes 135 135 * @ ppn : [in] physical page number 136 * @ returns 0 if success / returns ENOMEM if error 137 ***************************************************************************************/ 138 error_t hal_gpt_set_pte( xptr_t gpt_xp, 139 vpn_t vpn, 140 uint32_t attr, 141 ppn_t ppn ); 142 143 /**************************************************************************************** 144 * This function unmaps all pages identified by the <vpn> argument from the local GPT 145 * identified by the <gpt> argument. 146 * It does NOT release the physical memory allocated for the unmapped pages. 147 **************************************************************************************** 148 * @ gpt : [in] pointer on the local page table 149 * @ vpn : [in] page index in virtual space 150 ***************************************************************************************/ 151 void hal_gpt_reset_pte( gpt_t * gpt, 136 ***************************************************************************************/ 137 void hal_gpt_set_pte( xptr_t gpt_xp, 138 vpn_t vpn, 139 uint32_t attr, 140 ppn_t ppn ); 141 142 /**************************************************************************************** 143 * This low level function unmaps and unlocks a PTE from a remote GPT identified by the 144 * <gpt_xp> and <vpn> arguments. It does NOT release the allocated physical memory. 145 * This function can be used for both a small page (PTE2), and a big page (PTE1). 146 **************************************************************************************** 147 * @ gpt_xp : [in] extended pointer on the page table 148 * @ vpn : [in] virtual page number. 149 ***************************************************************************************/ 150 void hal_gpt_reset_pte( xptr_t gpt_xp, 152 151 vpn_t vpn ); 153 152 154 153 /**************************************************************************************** 155 * This function returns in the <attr> and <ppn> arguments the current values stored 156 * in a - local or remote - GPT entry, identified by the <gpt> and <vpn> arguments. 157 **************************************************************************************** 158 * @ gpt_xp : [in] extended pointer on the page table 159 * @ vpn : [in] virtual page number 160 * @ attr : [out] generic attributes 161 * @ ppn : [out] physical page number 154 * This low level function returns in the <attr> and <ppn> arguments the current values 155 * of a PTE in a a remote GPT, identified by the <gpt> and <vpn> arguments. 156 * This function can be used for both a small page (PTE2), and a big page (PTE1). 157 **************************************************************************************** 158 * @ gpt_xp : [in] extended pointer on the page table. 159 * @ vpn : [in] virtual page number. 160 * @ attr : [out] local buffer for generic attributes. 161 * @ ppn : [out] local buffer for physical page number. 162 162 ***************************************************************************************/ 163 163 void hal_gpt_get_pte( xptr_t gpt_xp, … … 195 195 196 196 /**************************************************************************************** 197 * This function returns true if the MAPPED and SMALL flags are both set198 * for a PTE defined by <gpt> and <vpn> arguments.199 ****************************************************************************************200 * @ gpt : [in] pointer on the page table201 * @ vpn : [in] virtual page number202 * @ returns true if MAPPED is set.203 ***************************************************************************************/204 bool_t hal_gpt_pte_is_mapped( gpt_t * gpt,205 vpn_t vpn );206 207 /****************************************************************************************208 * This function returns true if the MAPPED, SMALL, and COW flags are all set209 * for a PTE defined by <gpt> and <vpn> arguments.210 ****************************************************************************************211 * @ gpt : [in] pointer on the page table212 * @ vpn : [in] virtual page number213 * @ returns true if COW is set.214 ***************************************************************************************/215 bool_t hal_gpt_pte_is_cow( gpt_t * gpt,216 vpn_t vpn );217 218 /****************************************************************************************219 197 * This function atomically set the COW flag and reset the WRITABLE flag for all PTEs 220 198 * of a remote GPT identified by the <gpt_xp>, <vpn_base>, and <vpn_size arguments. 221 * It does nothing if the remote PTE is not MAPPED and SMALL. 199 * It does NOT require the GPT_LOCKED attribute to be set in the target PTE. 200 * It does nothing if the PTE is not MAPPED and SMALL. 222 201 **************************************************************************************** 223 202 * @ gpt_xp : [in] extended pointer on the remote GPT. … … 233 212 * It modifies an existing entry identified by the <vpn> argument in a remote GPT 234 213 * identified by the <gpt_xp> argument, using remote accesses. 214 * It does NOT require the GPT_LOCKED attribute to be set in the target PTE. 235 215 * It cannot fail, because only MAPPED & SMALL entries are modified. 236 216 **************************************************************************************** -
trunk/hal/generic/hal_remote.h
r619 r629 2 2 * hal_remote.h - Generic Remote Access API definition. 3 3 * 4 * Authors Mohamed Karaoui (2015) 5 * Alain Greiner (2016) 4 * Authors Alain Greiner (2016,2017,2018,2019) 6 5 * 7 6 * Copyright (c) UPMC Sorbonne Universites -
trunk/hal/tsar_mips32/core/hal_gpt.c
r625 r629 38 38 //////////////////////////////////////////////////////////////////////////////////////// 39 39 40 #define TSAR_ MMU_MAPPED 0x8000000041 #define TSAR_ MMU_SMALL 0x4000000042 #define TSAR_ MMU_LOCAL 0x2000000043 #define TSAR_ MMU_REMOTE 0x1000000044 #define TSAR_ MMU_CACHABLE 0x0800000045 #define TSAR_ MMU_WRITABLE 0x0400000046 #define TSAR_ MMU_EXECUTABLE 0x0200000047 #define TSAR_ MMU_USER 0x0100000048 #define TSAR_ MMU_GLOBAL 0x0080000049 #define TSAR_ MMU_DIRTY 0x0040000050 51 #define TSAR_ MMU_COW 0x00000001 // only for small pages52 #define TSAR_ MMU_SWAP 0x00000004 // only for small pages53 #define TSAR_ MMU_LOCKED 0x00000008 // only for small pages40 #define TSAR_PTE_MAPPED 0x80000000 41 #define TSAR_PTE_SMALL 0x40000000 42 #define TSAR_PTE_LOCAL 0x20000000 43 #define TSAR_PTE_REMOTE 0x10000000 44 #define TSAR_PTE_CACHABLE 0x08000000 45 #define TSAR_PTE_WRITABLE 0x04000000 46 #define TSAR_PTE_EXECUTABLE 0x02000000 47 #define TSAR_PTE_USER 0x01000000 48 #define TSAR_PTE_GLOBAL 0x00800000 49 #define TSAR_PTE_DIRTY 0x00400000 50 51 #define TSAR_PTE_COW 0x00000001 // only for small pages 52 #define TSAR_PTE_SWAP 0x00000004 // only for small pages 53 #define TSAR_PTE_LOCKED 0x00000008 // only for small pages 54 54 55 55 //////////////////////////////////////////////////////////////////////////////////////// … … 85 85 uint32_t tsar_attr = 0; 86 86 87 if( gpt_attr & GPT_MAPPED ) tsar_attr |= TSAR_ MMU_MAPPED;88 if( gpt_attr & GPT_SMALL ) tsar_attr |= TSAR_ MMU_SMALL;89 if( gpt_attr & GPT_WRITABLE ) tsar_attr |= TSAR_ MMU_WRITABLE;90 if( gpt_attr & GPT_EXECUTABLE ) tsar_attr |= TSAR_ MMU_EXECUTABLE;91 if( gpt_attr & GPT_CACHABLE ) tsar_attr |= TSAR_ MMU_CACHABLE;92 if( gpt_attr & GPT_USER ) tsar_attr |= TSAR_ MMU_USER;93 if( gpt_attr & GPT_DIRTY ) tsar_attr |= TSAR_ MMU_DIRTY;94 if( gpt_attr & GPT_ACCESSED ) tsar_attr |= TSAR_ MMU_LOCAL;95 if( gpt_attr & GPT_GLOBAL ) tsar_attr |= TSAR_ MMU_GLOBAL;96 if( gpt_attr & GPT_COW ) tsar_attr |= TSAR_ MMU_COW;97 if( gpt_attr & GPT_SWAP ) tsar_attr |= TSAR_ MMU_SWAP;98 if( gpt_attr & GPT_LOCKED ) tsar_attr |= TSAR_ MMU_LOCKED;87 if( gpt_attr & GPT_MAPPED ) tsar_attr |= TSAR_PTE_MAPPED; 88 if( gpt_attr & GPT_SMALL ) tsar_attr |= TSAR_PTE_SMALL; 89 if( gpt_attr & GPT_WRITABLE ) tsar_attr |= TSAR_PTE_WRITABLE; 90 if( gpt_attr & GPT_EXECUTABLE ) tsar_attr |= TSAR_PTE_EXECUTABLE; 91 if( gpt_attr & GPT_CACHABLE ) tsar_attr |= TSAR_PTE_CACHABLE; 92 if( gpt_attr & GPT_USER ) tsar_attr |= TSAR_PTE_USER; 93 if( gpt_attr & GPT_DIRTY ) tsar_attr |= TSAR_PTE_DIRTY; 94 if( gpt_attr & GPT_ACCESSED ) tsar_attr |= TSAR_PTE_LOCAL; 95 if( gpt_attr & GPT_GLOBAL ) tsar_attr |= TSAR_PTE_GLOBAL; 96 if( gpt_attr & GPT_COW ) tsar_attr |= TSAR_PTE_COW; 97 if( gpt_attr & GPT_SWAP ) tsar_attr |= TSAR_PTE_SWAP; 98 if( gpt_attr & GPT_LOCKED ) tsar_attr |= TSAR_PTE_LOCKED; 99 99 100 100 return tsar_attr; … … 108 108 uint32_t gpt_attr = 0; 109 109 110 if( tsar_attr & TSAR_ MMU_MAPPED ) gpt_attr |= GPT_MAPPED;111 if( tsar_attr & TSAR_ MMU_MAPPED ) gpt_attr |= GPT_READABLE;112 if( tsar_attr & TSAR_ MMU_SMALL ) gpt_attr |= GPT_SMALL;113 if( tsar_attr & TSAR_ MMU_WRITABLE ) gpt_attr |= GPT_WRITABLE;114 if( tsar_attr & TSAR_ MMU_EXECUTABLE ) gpt_attr |= GPT_EXECUTABLE;115 if( tsar_attr & TSAR_ MMU_CACHABLE ) gpt_attr |= GPT_CACHABLE;116 if( tsar_attr & TSAR_ MMU_USER ) gpt_attr |= GPT_USER;117 if( tsar_attr & TSAR_ MMU_DIRTY ) gpt_attr |= GPT_DIRTY;118 if( tsar_attr & TSAR_ MMU_LOCAL ) gpt_attr |= GPT_ACCESSED;119 if( tsar_attr & TSAR_ MMU_REMOTE ) gpt_attr |= GPT_ACCESSED;120 if( tsar_attr & TSAR_ MMU_GLOBAL ) gpt_attr |= GPT_GLOBAL;121 if( tsar_attr & TSAR_ MMU_COW ) gpt_attr |= GPT_COW;122 if( tsar_attr & TSAR_ MMU_SWAP ) gpt_attr |= GPT_SWAP;123 if( tsar_attr & TSAR_ MMU_LOCKED ) gpt_attr |= GPT_LOCKED;110 if( tsar_attr & TSAR_PTE_MAPPED ) gpt_attr |= GPT_MAPPED; 111 if( tsar_attr & TSAR_PTE_MAPPED ) gpt_attr |= GPT_READABLE; 112 if( tsar_attr & TSAR_PTE_SMALL ) gpt_attr |= GPT_SMALL; 113 if( tsar_attr & TSAR_PTE_WRITABLE ) gpt_attr |= GPT_WRITABLE; 114 if( tsar_attr & TSAR_PTE_EXECUTABLE ) gpt_attr |= GPT_EXECUTABLE; 115 if( tsar_attr & TSAR_PTE_CACHABLE ) gpt_attr |= GPT_CACHABLE; 116 if( tsar_attr & TSAR_PTE_USER ) gpt_attr |= GPT_USER; 117 if( tsar_attr & TSAR_PTE_DIRTY ) gpt_attr |= GPT_DIRTY; 118 if( tsar_attr & TSAR_PTE_LOCAL ) gpt_attr |= GPT_ACCESSED; 119 if( tsar_attr & TSAR_PTE_REMOTE ) gpt_attr |= GPT_ACCESSED; 120 if( tsar_attr & TSAR_PTE_GLOBAL ) gpt_attr |= GPT_GLOBAL; 121 if( tsar_attr & TSAR_PTE_COW ) gpt_attr |= GPT_COW; 122 if( tsar_attr & TSAR_PTE_SWAP ) gpt_attr |= GPT_SWAP; 123 if( tsar_attr & TSAR_PTE_LOCKED ) gpt_attr |= GPT_LOCKED; 124 124 125 125 return gpt_attr; … … 184 184 uint32_t * pt2; 185 185 uint32_t attr; 186 vpn_t vpn;187 186 kmem_req_t req; 188 bool_t is_ref;189 187 190 188 #if DEBUG_HAL_GPT_DESTROY … … 196 194 #endif 197 195 198 // get pointer on calling process199 process_t * process = CURRENT_THREAD->process;200 201 // compute is_ref202 is_ref = ( GET_CXY( process->ref_xp ) == local_cxy );203 204 196 // get pointer on PT1 205 197 pt1 = (uint32_t *)gpt->ptr; … … 209 201 { 210 202 pte1 = pt1[ix1]; 211 if( (pte1 & TSAR_MMU_MAPPED) != 0 ) // PTE1 valid 203 204 if( (pte1 & TSAR_PTE_MAPPED) != 0 ) // PTE1 mapped 212 205 { 213 if( (pte1 & TSAR_ MMU_SMALL) == 0 ) // BIG page206 if( (pte1 & TSAR_PTE_SMALL) == 0 ) // BIG page 214 207 { 215 if( (pte1 & TSAR_MMU_USER) != 0 ) 216 { 217 // warning message 218 printk("\n[WARNING] in %s : found an USER BIG page / ix1 = %d\n", 219 __FUNCTION__ , ix1 ); 220 221 // release the big physical page if reference cluster 222 if( is_ref ) 223 { 224 vpn = (vpn_t)(ix1 << TSAR_MMU_IX2_WIDTH); 225 hal_gpt_reset_pte( gpt , vpn ); 226 } 227 } 208 printk("\n[WARNING] in %s : mapped big page / ix1 %x\n", 209 __FUNCTION__ , ix1 ); 228 210 } 229 else // SMALL page211 else // PT2 exist 230 212 { 231 213 // get local pointer on PT2 … … 234 216 pt2 = GET_PTR( base_xp ); 235 217 236 // scan the PT2 to release all entries VALID and USER if reference cluster237 if( is_ref)218 // scan the PT2 219 for( ix2 = 0 ; ix2 < 512 ; ix2++ ) 238 220 { 239 for( ix2 = 0 ; ix2 < 512 ; ix2++ ) 221 attr = TSAR_MMU_ATTR_FROM_PTE2( pt2[2 * ix2] ); 222 223 if( (attr & TSAR_PTE_MAPPED) != 0 ) // PTE2 mapped 240 224 { 241 attr = TSAR_MMU_ATTR_FROM_PTE2( pt2[2 * ix2] ); 242 if( ((attr & TSAR_MMU_MAPPED) != 0 ) && ((attr & TSAR_MMU_USER) != 0) ) 243 { 244 // release the physical page 245 vpn = (vpn_t)((ix1 << TSAR_MMU_IX2_WIDTH) | ix2); 246 hal_gpt_reset_pte( gpt , vpn ); 247 } 225 printk("\n[WARNING] in %s : mapped small page / ix1 %x / ix2 %x\n", 226 __FUNCTION__ , ix1, ix2 ); 248 227 } 249 228 } 250 229 251 // release the PT2230 // release the page allocated for the PT2 252 231 req.type = KMEM_PAGE; 253 232 req.ptr = GET_PTR( ppm_base2page( XPTR(local_cxy , pt2 ) ) ); … … 271 250 } // end hal_gpt_destroy() 272 251 273 /////////////////////////////////////////// 274 void hal_gpt_display( process_t * process ) 252 /* 253 254 ///////////////////////////////////////////////////////////////////////////////////// 255 // This static function can be used for debug. 256 ///////////////////////////////////////////////////////////////////////////////////// 257 static void hal_gpt_display( process_t * process ) 275 258 { 276 259 gpt_t * gpt; … … 301 284 { 302 285 pte1 = pt1[ix1]; 303 if( (pte1 & TSAR_ MMU_MAPPED) != 0 )286 if( (pte1 & TSAR_PTE_MAPPED) != 0 ) 304 287 { 305 if( (pte1 & TSAR_ MMU_SMALL) == 0 ) // BIG page288 if( (pte1 & TSAR_PTE_SMALL) == 0 ) // BIG page 306 289 { 307 290 vpn = ix1 << 9; … … 320 303 pte2_ppn = TSAR_MMU_PPN_FROM_PTE2( pt2[2 * ix2 + 1] ); 321 304 322 if( (pte2_attr & TSAR_ MMU_MAPPED) != 0 )305 if( (pte2_attr & TSAR_PTE_MAPPED) != 0 ) 323 306 { 324 307 vpn = (ix1 << 9) | ix2; … … 332 315 } // end hal_gpt_display() 333 316 334 335 ////////////////////////////////////////// 336 error_t hal_gpt_set_pte( xptr_t gpt_xp, 337 vpn_t vpn, 338 uint32_t attr, // GPT attributes 339 ppn_t ppn ) 340 { 341 cxy_t gpt_cxy; // target GPT cluster 342 gpt_t * gpt_ptr; // target GPT local pointer 343 uint32_t * pt1_ptr; // local pointer on PT1 344 xptr_t pte1_xp; // extended pointer on PT1 entry 345 uint32_t pte1; // PT1 entry value if PTE1 346 347 ppn_t pt2_ppn; // PPN of PT2 348 uint32_t * pt2_ptr; // PT2 base address 349 350 uint32_t small; // requested PTE is for a small page 351 352 page_t * page; // pointer on new physical page descriptor 353 xptr_t page_xp; // extended pointer on new page descriptor 354 355 uint32_t ix1; // index in PT1 356 uint32_t ix2; // index in PT2 357 358 uint32_t tsar_attr; // PTE attributes for TSAR MMU 359 360 thread_t * this = CURRENT_THREAD; 361 362 // get cluster and local pointer on GPT 363 gpt_cxy = GET_CXY( gpt_xp ); 364 gpt_ptr = GET_PTR( gpt_xp ); 365 366 #if DEBUG_HAL_GPT_SET_PTE 367 uint32_t cycle = (uint32_t)hal_get_cycles(); 368 if( DEBUG_HAL_GPT_SET_PTE < cycle ) 369 printk("\n[%s] : thread[%x,%x] enter / vpn %x / attr %x / ppn %x / cluster %x / cycle %d\n", 370 __FUNCTION__, this->process->pid, this->trdid, vpn, attr, ppn, gpt_cxy, cycle ); 371 #endif 372 373 // compute indexes in PT1 and PT2 374 ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); 375 ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); 376 377 pt1_ptr = hal_remote_lpt( XPTR( gpt_cxy , &gpt_ptr->ptr ) ); 378 small = attr & GPT_SMALL; 379 380 // compute tsar attributes from generic attributes 381 tsar_attr = gpt2tsar( attr ); 382 383 // build extended pointer on PTE1 = PT1[ix1] 384 pte1_xp = XPTR( gpt_cxy , &pt1_ptr[ix1] ); 317 */ 318 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. 332 ///////////////////////////////////////////////////////////////////////////////////////// 333 static error_t hal_gpt_allocate_pt2( xptr_t pte1_xp, 334 uint32_t * pte1_value ) 335 { 336 cxy_t gpt_cxy; // target GPT cluster = GET_CXY( pte1_xp ); 337 uint32_t pte1; // PTE1 value 338 ppn_t pt2_ppn; // PPN of page containing the new PT2 339 bool_t atomic; 340 page_t * page; 341 xptr_t page_xp; 342 343 // get GPT cluster identifier 344 gpt_cxy = GET_CXY( pte1_xp ); 385 345 386 346 // get current pte1 value 387 347 pte1 = hal_remote_l32( pte1_xp ); 388 348 389 if( small == 0 ) // map a big page in PT1 390 { 391 392 // check PT1 entry not mapped 393 assert( (pte1 == 0) , "try to set a big page in a mapped PT1 entry\n" ); 394 395 // check VPN aligned 396 assert( (ix2 == 0) , "illegal vpn for a big page\n" ); 397 398 // check PPN aligned 399 assert( ((ppn & 0x1FF) == 0) , "illegal ppn for a big page\n" ); 400 401 // set the PTE1 value in PT1 402 pte1 = (tsar_attr & TSAR_MMU_PTE1_ATTR_MASK) | ((ppn >> 9) & TSAR_MMU_PTE1_PPN_MASK); 403 hal_remote_s32( pte1_xp , pte1 ); 404 hal_fence(); 405 406 #if DEBUG_HAL_GPT_SET_PTE 407 if( DEBUG_HAL_GPT_SET_PTE < cycle ) 408 printk("\n[%s] : thread[%x,%x] map PTE1 / cxy %x / ix1 %x / pt1 %x / pte1 %x\n", 409 __FUNCTION__, this->process->pid, this->trdid, gpt_cxy, ix1, pt1_ptr, pte1 ); 410 #endif 411 412 return 0; 413 } 414 else // map a small page in PT1 & PT2 415 { 416 if( (pte1 & TSAR_MMU_MAPPED) == 0 ) // PT1 entry unmapped => map it 417 { 349 if( ((pte1 & TSAR_PTE_MAPPED) == 0) && // PTE1 unmapped and unlocked 350 ((pte1 & TSAR_PTE_LOCKED) == 0) ) // try to allocate a new PT2 351 { 352 // atomically lock the PTE1 to prevent concurrent PTE1 mappings 353 atomic = hal_remote_atomic_cas( pte1_xp, 354 pte1, 355 pte1 | TSAR_PTE_LOCKED ); 356 357 if( atomic ) // PTE1 successfully locked 358 { 418 359 // allocate one physical page for PT2 419 360 if( gpt_cxy == local_cxy ) … … 430 371 } 431 372 432 if( page == NULL ) 433 { 434 printk("\n[PANIC] in %s : no memory for GPT PT2 / process %x / cluster %x\n", 435 __FUNCTION__, this->process->pid, gpt_cxy ); 436 return ENOMEM; 437 } 373 if( page == NULL ) return -1; 438 374 439 375 // get the PT2 PPN … … 441 377 pt2_ppn = ppm_page2ppn( page_xp ); 442 378 443 // build PTD1 value444 pte1 = TSAR_ MMU_MAPPED | TSAR_MMU_SMALL | pt2_ppn;379 // build PTE1 value 380 pte1 = TSAR_PTE_MAPPED | TSAR_PTE_SMALL | pt2_ppn; 445 381 446 382 // set the PTD1 value in PT1 447 383 hal_remote_s32( pte1_xp , pte1 ); 384 hal_fence(); 385 386 #if DEBUG_HAL_GPT_ALLOCATE_PT2 387 thread_t * this = CURRENT_THREAD; 388 uint32_t cycle = (uint32_t)hal_get_cycles(); 389 if( DEBUG_HAL_GPT_ALLOCATE_PT2 < cycle ) 390 printk("\n[%s] : thread[%x,%x] map PTE1 / cxy %x / ix1 %d / pt1 %x / ptd1 %x\n", 391 __FUNCTION__, this->process->pid, this->trdid, gpt_cxy, ix1, pt1_ptr, pte1 ); 392 #endif 393 } 394 else 395 { 396 // poll PTE1 until mapped by another thread 397 while( (pte1 & TSAR_PTE_MAPPED) == 0 ) pte1 = hal_remote_l32( pte1_xp ); 398 } 399 } 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 407 { 408 409 #if DEBUG_HAL_GPT_ALLOCATE_PT2 410 thread_t * this = CURRENT_THREAD; 411 uint32_t cycle = (uint32_t)hal_get_cycles(); 412 if( DEBUG_HAL_GPT_ALLOCATE_PT2 < cycle ) 413 printk("\n[%s] : thread[%x,%x] PTE1 mapped / cxy %x / ix1 %d / pt1 %x / ptd1 %x\n", 414 __FUNCTION__, this->process->pid, this->trdid, gpt_cxy, ix1, pt1_ptr, pte1 ); 415 #endif 416 417 } 418 419 *pte1_value = pte1; 420 return 0; 421 422 } // end hal_gpt_allocate_pt2 423 424 425 426 427 //////////////////////////////////////////// 428 error_t hal_gpt_lock_pte( xptr_t gpt_xp, 429 vpn_t vpn, 430 uint32_t * attr, 431 ppn_t * ppn ) 432 { 433 error_t error; 434 uint32_t * pt1_ptr; // local pointer on PT1 base 435 xptr_t pte1_xp; // extended pointer on PT1[x1] entry 436 uint32_t pte1; // value of PT1[x1] entry 437 438 ppn_t pt2_ppn; // PPN of page containing PT2 439 uint32_t * pt2_ptr; // local pointer on PT2 base 440 xptr_t pte2_attr_xp; // extended pointer on PT2[ix2].attr 441 uint32_t pte2_attr; // PT2[ix2].attr current value 442 xptr_t pte2_ppn_xp; // extended pointer on PT2[ix2].ppn 443 uint32_t pte2_ppn; // PT2[ix2].ppn current value 444 bool_t atomic; 445 446 // get cluster and local pointer on GPT 447 cxy_t gpt_cxy = GET_CXY( gpt_xp ); 448 gpt_t * gpt_ptr = GET_PTR( gpt_xp ); 449 450 // get indexes in PTI & PT2 451 uint32_t ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); // index in PT1 452 uint32_t ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); // index in PT2 453 454 // get local pointer on PT1 455 pt1_ptr = hal_remote_lpt( XPTR( gpt_cxy , &gpt_ptr->ptr ) ); 456 457 // build extended pointer on PTE1 == PT1[ix1] 458 pte1_xp = XPTR( gpt_cxy , &pt1_ptr[ix1] ); 459 460 // get PTE1 value from PT1 461 // allocate a new PT2 for this PTE1 if required 462 error = hal_gpt_allocate_pt2( pte1_xp , &pte1 ); 463 464 if( error ) 465 { 466 printk("\n[ERROR] in %s : cannot allocate memory for PT2\n", __FUNCTION__ ); 467 return -1; 468 } 469 470 if( (pte1 & TSAR_PTE_SMALL) == 0 ) 471 { 472 printk("\n[ERROR] in %s : cannot lock a small page\n", __FUNCTION__ ); 473 return -1; 474 } 475 476 // get pointer on PT2 base from PTE1 477 pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 ); 478 pt2_ptr = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 479 480 // build extended pointers on PT2[ix2].attr and PT2[ix2].ppn 481 pte2_attr_xp = XPTR( gpt_cxy , &pt2_ptr[2 * ix2] ); 482 pte2_ppn_xp = XPTR( gpt_cxy , &pt2_ptr[2 * ix2 + 1] ); 483 484 // wait until PTE2 unlocked, get PTE2.attr and set lock 485 do 486 { 487 // busy waiting until TSAR_MMU_LOCK == 0 488 do 489 { 490 pte2_attr = hal_remote_l32( pte2_attr_xp ); 491 } 492 while( (pte2_attr & TSAR_PTE_LOCKED) != 0 ); 493 494 // try to atomically set the TSAR_MMU_LOCK attribute 495 atomic = hal_remote_atomic_cas( pte2_attr_xp, 496 pte2_attr, 497 (pte2_attr | TSAR_PTE_LOCKED) ); 498 } 499 while( atomic == 0 ); 500 501 // get PTE2.ppn 502 pte2_ppn = hal_remote_l32( pte2_ppn_xp ); 503 504 #if DEBUG_HAL_GPT_LOCK_PTE 505 thread_t * this = CURRENT_THREAD; 506 uint32_t cycle = (uint32_t)hal_get_cycles(); 507 if( DEBUG_HAL_GPT_LOCK_PTE < cycle ) 508 printk("\n[%s] : thread[%x,%x] locks vpn %x / attr %x / ppn %x / cluster %x / cycle %d\n", 509 __FUNCTION__, this->process->pid, this->trdid, vpn, attr, ppn, gpt_cxy, cycle ); 510 #endif 511 512 // return PPN and GPT attributes 513 *ppn = hal_remote_l32( pte2_ppn_xp ) & ((1<<TSAR_MMU_PPN_WIDTH)-1); 514 *attr = tsar2gpt( pte2_attr ); 515 return 0; 516 517 } // end hal_gpt_lock_pte() 518 519 //////////////////////////////////////// 520 void hal_gpt_unlock_pte( xptr_t gpt_xp, 521 vpn_t vpn ) 522 { 523 uint32_t * pt1_ptr; // local pointer on PT1 base 524 xptr_t pte1_xp; // extended pointer on PT1[ix1] 525 uint32_t pte1; // value of PT1[ix1] entry 526 527 ppn_t pt2_ppn; // PPN of page containing PT2 528 uint32_t * pt2_ptr; // PT2 base address 529 uint32_t pte2_attr_xp; // extended pointer on PT2[ix2].attr 530 531 uint32_t attr; // PTE2 attribute 532 533 // get cluster and local pointer on GPT 534 cxy_t gpt_cxy = GET_CXY( gpt_xp ); 535 gpt_t * gpt_ptr = GET_PTR( gpt_xp ); 536 537 // compute indexes in P1 and PT2 538 uint32_t ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); // index in PT1 539 uint32_t ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); // index in PT2 540 541 // get local pointer on PT1 542 pt1_ptr = hal_remote_lpt( XPTR( gpt_cxy , &gpt_ptr->ptr ) ); 543 544 // build extended pointer on PTE1 == PT1[ix1] 545 pte1_xp = XPTR( gpt_cxy , &pt1_ptr[ix1] ); 546 547 // get current pte1 value 548 pte1 = hal_remote_l32( pte1_xp ); 549 550 // check PTE1 attributes 551 assert( (((pte1 & TSAR_PTE_MAPPED) != 0) && ((pte1 & TSAR_PTE_SMALL) != 0)), 552 "try to unlock a big or unmapped PTE1\n"); 553 554 // get pointer on PT2 base from PTE1 555 pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 ); 556 pt2_ptr = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 557 558 // build extended pointers on PT2[ix2].attr 559 pte2_attr_xp = XPTR( gpt_cxy , &pt2_ptr[2 * ix2] ); 560 561 // get PT2[ix2].attr 562 attr = hal_remote_l32( pte2_attr_xp ); 563 564 // reset TSAR_MMU_LOCK attribute 565 hal_remote_s32( pte2_attr_xp , attr & ~TSAR_PTE_LOCKED ); 566 567 #if DEBUG_HAL_GPT_LOCK_PTE 568 thread_t * this = CURRENT_THREAD; 569 uint32_t cycle = (uint32_t)hal_get_cycles(); 570 if( DEBUG_HAL_GPT_LOCK_PTE < cycle ) 571 printk("\n[%s] : thread[%x,%x] unlocks vpn %x / attr %x / ppn %x / cluster %x / cycle %d\n", 572 __FUNCTION__, this->process->pid, this->trdid, vpn, attr, ppn, gpt_cxy, cycle ); 573 #endif 574 575 } // end hal_gpt_unlock_pte() 576 577 /////////////////////////////////////// 578 void hal_gpt_set_pte( xptr_t gpt_xp, 579 vpn_t vpn, 580 uint32_t attr, 581 ppn_t ppn ) 582 { 583 cxy_t gpt_cxy; // target GPT cluster 584 gpt_t * gpt_ptr; // target GPT local pointer 585 586 uint32_t * pt1_ptr; // local pointer on PT1 base 587 xptr_t pte1_xp; // extended pointer on PT1 entry 588 uint32_t pte1; // PT1 entry value if PTE1 589 590 ppn_t pt2_ppn; // PPN of PT2 591 uint32_t * pt2_ptr; // local pointer on PT2 base 592 xptr_t pte2_attr_xp; // extended pointer on PT2[ix2].attr 593 xptr_t pte2_ppn_xp; // extended pointer on PT2[ix2].ppn 594 uint32_t pte2_attr; // current value of PT2[ix2].attr 595 596 uint32_t ix1; // index in PT1 597 uint32_t ix2; // index in PT2 598 599 uint32_t tsar_attr; // PTE attributes for TSAR MMU 600 uint32_t small; // requested PTE is for a small page 601 602 // get cluster and local pointer on GPT 603 gpt_cxy = GET_CXY( gpt_xp ); 604 gpt_ptr = GET_PTR( gpt_xp ); 605 606 // compute indexes in PT1 and PT2 607 ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); 608 ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); 609 610 pt1_ptr = hal_remote_lpt( XPTR( gpt_cxy , &gpt_ptr->ptr ) ); 611 small = attr & GPT_SMALL; 612 613 // compute tsar attributes from generic attributes 614 tsar_attr = gpt2tsar( attr ); 615 616 // build extended pointer on PTE1 = PT1[ix1] 617 pte1_xp = XPTR( gpt_cxy , &pt1_ptr[ix1] ); 618 619 // get current pte1 value 620 pte1 = hal_remote_l32( pte1_xp ); 621 622 if( small == 0 ) ///////////////// map a big page in PT1 623 { 624 625 // check PT1 entry not mapped 626 assert( (pte1 == 0) , "try to set a big page in an already mapped PTE1\n" ); 627 628 // check VPN aligned 629 assert( (ix2 == 0) , "illegal vpn for a big page\n" ); 630 631 // check PPN aligned 632 assert( ((ppn & 0x1FF) == 0) , "illegal ppn for a big page\n" ); 633 634 // set the PTE1 value in PT1 635 pte1 = (tsar_attr & TSAR_MMU_PTE1_ATTR_MASK) | ((ppn >> 9) & TSAR_MMU_PTE1_PPN_MASK); 636 hal_remote_s32( pte1_xp , pte1 ); 637 hal_fence(); 448 638 449 639 #if DEBUG_HAL_GPT_SET_PTE 640 thread_t * this = CURRENT_THREAD; 641 uint32_t cycle = (uint32_t)hal_get_cycles(); 450 642 if( DEBUG_HAL_GPT_SET_PTE < cycle ) 451 printk("\n[%s] : thread[%x,%x] map PT D1 / cxy %x / ix1 %d / pt1 %x / ptd1 %x\n",643 printk("\n[%s] : thread[%x,%x] map PTE1 / cxy %x / ix1 %x / pt1 %x / pte1 %x\n", 452 644 __FUNCTION__, this->process->pid, this->trdid, gpt_cxy, ix1, pt1_ptr, pte1 ); 453 645 #endif 454 } 455 else // pt1 entry mapped => use it 456 { 457 458 #if DEBUG_HAL_GPT_SET_PTE 459 if( DEBUG_HAL_GPT_SET_PTE < cycle ) 460 printk("\n[%s] : thread[%x,%x] get PTD1 / cxy %x / ix1 %d / pt1 %x / ptd1 %x\n", 461 __FUNCTION__, this->process->pid, this->trdid, gpt_cxy, ix1, pt1_ptr, pte1 ); 462 #endif 463 464 } 465 466 // get PT2 base from pte1 646 647 } 648 else ///////////////// map a small page in PT2 649 { 650 651 // PTE1 must be mapped because PTE2 must be locked 652 assert( (pte1 & TSAR_PTE_MAPPED), "PTE1 must be mapped\n" ); 653 654 // get PT2 base from PTE1 467 655 pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 ); 468 656 pt2_ptr = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 469 657 658 // build extended pointers on PT2[ix2].attr and PT2[ix2].ppn 659 pte2_attr_xp = XPTR( gpt_cxy , &pt2_ptr[2 * ix2] ); 660 pte2_ppn_xp = XPTR( gpt_cxy , &pt2_ptr[2 * ix2 + 1] ); 661 662 // get current value of PTE2.attr 663 pte2_attr = hal_remote_l32( pte2_attr_xp ); 664 665 // PTE2 must be locked 666 assert( (pte2_attr & TSAR_PTE_LOCKED), "PTE2 must be locked\n" ); 667 470 668 // set PTE2 in PT2 (in this order) 471 hal_remote_s32( XPTR( gpt_cxy , &pt2_ptr[2 * ix2 + 1] ), ppn );669 hal_remote_s32( pte2_ppn_xp , ppn ); 472 670 hal_fence(); 473 hal_remote_s32( XPTR( gpt_cxy , &pt2_ptr[2 * ix2] ), tsar_attr );671 hal_remote_s32( pte2_attr_xp , tsar_attr ); 474 672 hal_fence(); 475 673 476 674 #if DEBUG_HAL_GPT_SET_PTE 675 thread_t * this = CURRENT_THREAD; 676 uint32_t cycle = (uint32_t)hal_get_cycles(); 477 677 if( DEBUG_HAL_GPT_SET_PTE < cycle ) 478 678 printk("\n[%s] : thread[%x,%x] map PTE2 / cxy %x / ix2 %x / pt2 %x / attr %x / ppn %x\n", … … 480 680 #endif 481 681 482 return 0;483 682 } 484 683 } // end of hal_gpt_set_pte() 684 685 /////////////////////////////////////// 686 void hal_gpt_reset_pte( xptr_t gpt_xp, 687 vpn_t vpn ) 688 { 689 cxy_t gpt_cxy; // target GPT cluster 690 gpt_t * gpt_ptr; // target GPT local pointer 691 692 uint32_t ix1; // index in PT1 693 uint32_t ix2; // index in PT2 694 695 uint32_t * pt1_ptr; // PT1 base address 696 xptr_t pte1_xp; // extended pointer on PT1[ix1] 697 uint32_t pte1; // PT1 entry value 698 699 ppn_t pt2_ppn; // PPN of PT2 700 uint32_t * pt2_ptr; // PT2 base address 701 xptr_t pte2_attr_xp; // extended pointer on PT2[ix2].attr 702 xptr_t pte2_ppn_xp; // extended pointer on PT2[ix2].ppn 703 uint32_t pte2_attr; // current value of PT2[ix2].attr 704 705 // get cluster and local pointer on GPT 706 gpt_cxy = GET_CXY( gpt_xp ); 707 gpt_ptr = GET_PTR( gpt_xp ); 708 709 // get ix1 & ix2 indexes 710 ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); 711 ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); 712 713 // get local pointer on PT1 base 714 pt1_ptr = hal_remote_lpt( XPTR( gpt_cxy , &gpt_ptr->ptr ) ); 715 716 // build extended pointer on PTE1 = PT1[ix1] 717 pte1_xp = XPTR( gpt_cxy , &pt1_ptr[ix1] ); 718 719 // get current PTE1 value 720 pte1 = hal_remote_l32( pte1_xp ); 721 722 if( (pte1 & TSAR_PTE_MAPPED) == 0 ) // PTE1 unmapped => do nothing 723 { 724 return; 725 } 726 727 if( (pte1 & TSAR_PTE_SMALL) == 0 ) // it's a PTE1 => unmap it from PT1 728 { 729 hal_remote_s32( pte1_xp , 0 ); 730 hal_fence(); 731 732 #if DEBUG_HAL_GPT_RESET_PTE 733 thread_t * this = CURRENT_THREAD; 734 uint32_t cycle = (uint32_t)hal_get_cycles(); 735 if( DEBUG_HAL_GPT_RESET_PTE < cycle ) 736 printk("\n[%s] : thread[%x,%x] unmap PTE1 / cxy %x / vpn %x / ix1 %x\n", 737 __FUNCTION__, this->process->pid, this->trdid, gpt_cxy, vpn, ix1 ); 738 #endif 739 740 return; 741 } 742 else // it's a PTE2 => unmap it from PT2 743 { 744 // compute PT2 base address 745 pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 ); 746 pt2_ptr = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 747 748 // build extended pointer on PT2[ix2].attr and PT2[ix2].ppn 749 pte2_attr_xp = XPTR( gpt_cxy , &pt2_ptr[2 * ix2] ); 750 pte2_ppn_xp = XPTR( gpt_cxy , &pt2_ptr[2 * ix2 + 1] ); 751 752 // unmap the PTE2 753 hal_remote_s32( pte2_attr_xp , 0 ); 754 hal_fence(); 755 hal_remote_s32( pte2_ppn_xp , 0 ); 756 hal_fence(); 757 758 #if DEBUG_HAL_GPT_RESET_PTE 759 thread_t * this = CURRENT_THREAD; 760 uint32_t cycle = (uint32_t)hal_get_cycles(); 761 if( DEBUG_HAL_GPT_RESET_PTE < cycle ) 762 printk("\n[%s] : thread[%x,%x] unmap PTE2 / cxy %x / vpn %x / ix2 %x\n", 763 __FUNCTION__, this->process->pid, this->trdid, gpt_cxy, vpn, ix2 ); 764 #endif 765 766 return; 767 } 768 } // end hal_gpt_reset_pte() 485 769 486 770 //////////////////////////////////////// … … 490 774 ppn_t * ppn ) 491 775 { 492 uint32_t * pt1; 493 uint32_t pte1; 494 495 uint32_t * pt2; 496 ppn_t pt2_ppn; 776 uint32_t * pt1; // local pointer on PT1 base 777 uint32_t pte1; // PTE1 value 778 779 uint32_t * pt2; // local pointer on PT2 base 780 ppn_t pt2_ppn; // PPN of page containing the PT2 781 xptr_t pte2_attr_xp; // extended pointer on PT2[ix2].attr 782 xptr_t pte2_ppn_xp; // extended pointer on PT2[ix2].ppn 783 uint32_t pte2_attr; // current value of PT2[ix2].attr 784 ppn_t pte2_ppn; // current value of PT2[ix2].ppn 497 785 498 786 // get cluster and local pointer on GPT … … 505 793 506 794 // get PT1 base 507 pt1 = (uint32_t *)hal_remote_lpt( XPTR( gpt_cxy , &gpt_ptr->ptr ) );795 pt1 = hal_remote_lpt( XPTR( gpt_cxy , &gpt_ptr->ptr ) ); 508 796 509 797 // get pte1 … … 511 799 512 800 // check PTE1 mapped 513 if( (pte1 & TSAR_ MMU_MAPPED) == 0 ) // PT1 entry not present801 if( (pte1 & TSAR_PTE_MAPPED) == 0 ) // PTE1 unmapped 514 802 { 515 803 *attr = 0; … … 519 807 520 808 // access GPT 521 if( (pte1 & TSAR_ MMU_SMALL) == 0 ) // it's a PTE1809 if( (pte1 & TSAR_PTE_SMALL) == 0 ) // it's a PTE1 522 810 { 523 811 // get PPN & ATTR from PT1 … … 525 813 *ppn = TSAR_MMU_PPN_FROM_PTE1( pte1 ) | (vpn & ((1<<TSAR_MMU_IX2_WIDTH)-1)); 526 814 } 527 else // it's a PT D1815 else // it's a PTE2 528 816 { 529 817 // compute PT2 base address … … 531 819 pt2 = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 532 820 533 // get PPN & ATTR from PT2 534 *ppn = hal_remote_l32( XPTR( gpt_cxy , &pt2[2*ix2+1] ) ) & ((1<<TSAR_MMU_PPN_WIDTH)-1); 535 *attr = tsar2gpt( hal_remote_l32( XPTR( gpt_cxy , &pt2[2*ix2] ) ) ); 821 // build extended pointer on PT2[ix2].attr and PT2[ix2].ppn 822 pte2_attr_xp = XPTR( gpt_cxy , &pt2[2 * ix2] ); 823 pte2_ppn_xp = XPTR( gpt_cxy , &pt2[2 * ix2 + 1] ); 824 825 // get current value of PTE2.attr & PTE2.ppn 826 pte2_attr = hal_remote_l32( pte2_attr_xp ); 827 pte2_ppn = hal_remote_l32( pte2_ppn_xp ); 828 829 // return PPN & GPT attributes 830 *ppn = pte2_ppn & ((1<<TSAR_MMU_PPN_WIDTH)-1); 831 *attr = tsar2gpt( pte2_attr ); 536 832 } 537 833 } // end hal_gpt_get_pte() 538 834 539 //////////////////////////////////// 540 void hal_gpt_reset_pte( gpt_t * gpt, 541 vpn_t vpn ) 542 { 543 uint32_t * pt1; // PT1 base address 544 uint32_t pte1; // PT1 entry value 545 546 ppn_t pt2_ppn; // PPN of PT2 547 uint32_t * pt2; // PT2 base address 548 549 // get ix1 & ix2 indexes 550 uint32_t ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); 551 uint32_t ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); 552 553 // get PTE1 value 554 pt1 = gpt->ptr; 555 pte1 = pt1[ix1]; 556 557 if( (pte1 & TSAR_MMU_MAPPED) == 0 ) // PT1 entry not present 558 { 559 return; 560 } 561 562 if( (pte1 & TSAR_MMU_SMALL) == 0 ) // it's a PTE1 563 { 564 // unmap the big page 565 pt1[ix1] = 0; 566 hal_fence(); 567 568 return; 569 } 570 else // it's a PTD1 571 { 572 // compute PT2 base address 573 pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 ); 574 pt2 = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 835 836 /////////////////////////////////////////// 837 error_t hal_gpt_pte_copy( gpt_t * dst_gpt, 838 vpn_t dst_vpn, 839 xptr_t src_gpt_xp, 840 vpn_t src_vpn, 841 bool_t cow, 842 ppn_t * ppn, 843 bool_t * mapped ) 844 { 845 uint32_t src_ix1; // index in SRC PT1 846 uint32_t src_ix2; // index in SRC PT2 847 848 uint32_t dst_ix1; // index in DST PT1 849 uint32_t dst_ix2; // index in DST PT2 850 851 cxy_t src_cxy; // SRC GPT cluster 852 gpt_t * src_gpt; // SRC GPT local pointer 853 854 uint32_t * src_pt1; // local pointer on SRC PT1 855 uint32_t * dst_pt1; // local pointer on DST PT1 856 uint32_t * src_pt2; // local pointer on SRC PT2 857 uint32_t * dst_pt2; // local pointer on DST PT2 858 859 kmem_req_t req; // for PT2 allocation 860 861 uint32_t src_pte1; 862 uint32_t dst_pte1; 863 864 uint32_t src_pte2_attr; 865 uint32_t src_pte2_ppn; 866 867 page_t * page; 868 xptr_t page_xp; 869 870 ppn_t src_pt2_ppn; 871 ppn_t dst_pt2_ppn; 872 873 // get remote src_gpt cluster and local pointer 874 src_cxy = GET_CXY( src_gpt_xp ); 875 src_gpt = GET_PTR( src_gpt_xp ); 876 877 #if DEBUG_HAL_GPT_COPY 878 uint32_t cycle = (uint32_t)hal_get_cycles(); 879 thread_t * this = CURRENT_THREAD; 880 if( DEBUG_HAL_GPT_COPY < cycle ) 881 printk("\n[%s] : thread[%x,%x] enter / src_cxy %x / dst_cxy %x / cycle %d\n", 882 __FUNCTION__, this->process->pid, this->trdid, src_cxy, local_cxy, cycle ); 883 #endif 884 885 // get remote src_gpt cluster and local pointer 886 src_cxy = GET_CXY( src_gpt_xp ); 887 src_gpt = GET_PTR( src_gpt_xp ); 888 889 // get remote src_pt1 and local dst_pt1 890 src_pt1 = (uint32_t *)hal_remote_lpt( XPTR( src_cxy , &src_gpt->ptr ) ); 891 dst_pt1 = (uint32_t *)dst_gpt->ptr; 892 893 // check src_pt1 and dst_pt1 existence 894 assert( (src_pt1 != NULL) , "src_pt1 does not exist\n"); 895 assert( (dst_pt1 != NULL) , "dst_pt1 does not exist\n"); 896 897 // compute SRC indexes 898 src_ix1 = TSAR_MMU_IX1_FROM_VPN( src_vpn ); 899 src_ix2 = TSAR_MMU_IX2_FROM_VPN( src_vpn ); 900 901 // compute DST indexes 902 dst_ix1 = TSAR_MMU_IX1_FROM_VPN( dst_vpn ); 903 dst_ix2 = TSAR_MMU_IX2_FROM_VPN( dst_vpn ); 904 905 // get src_pte1 906 src_pte1 = hal_remote_l32( XPTR( src_cxy , &src_pt1[src_ix1] ) ); 907 908 // do nothing if src_pte1 not MAPPED or not SMALL 909 if( (src_pte1 & TSAR_PTE_MAPPED) && (src_pte1 & TSAR_PTE_SMALL) ) 910 { 911 // get dst_pt1 entry 912 dst_pte1 = dst_pt1[dst_ix1]; 913 914 // map dst_pte1 if required 915 if( (dst_pte1 & TSAR_PTE_MAPPED) == 0 ) 916 { 917 // allocate one physical page for a new PT2 918 req.type = KMEM_PAGE; 919 req.size = 0; // 1 small page 920 req.flags = AF_KERNEL | AF_ZERO; 921 page = (page_t *)kmem_alloc( &req ); 922 923 if( page == NULL ) 924 { 925 printk("\n[ERROR] in %s : cannot allocate PT2\n", __FUNCTION__ ); 926 return -1; 927 } 928 929 // build extended pointer on page descriptor 930 page_xp = XPTR( local_cxy , page ); 931 932 // get PPN for this new PT2 933 dst_pt2_ppn = (ppn_t)ppm_page2ppn( page_xp ); 934 935 // build the new dst_pte1 936 dst_pte1 = TSAR_PTE_MAPPED | TSAR_PTE_SMALL | dst_pt2_ppn; 937 938 // register it in DST_GPT 939 dst_pt1[dst_ix1] = dst_pte1; 940 } 941 942 // get pointer on src_pt2 943 src_pt2_ppn = (ppn_t)TSAR_MMU_PTBA_FROM_PTE1( src_pte1 ); 944 src_pt2 = GET_PTR( ppm_ppn2base( src_pt2_ppn ) ); 945 946 // get pointer on dst_pt2 947 dst_pt2_ppn = (ppn_t)TSAR_MMU_PTBA_FROM_PTE1( dst_pte1 ); 948 dst_pt2 = GET_PTR( ppm_ppn2base( dst_pt2_ppn ) ); 949 950 // get attr and ppn from SRC_PT2 951 src_pte2_attr = hal_remote_l32( XPTR( src_cxy , &src_pt2[2 * src_ix2] ) ); 952 src_pte2_ppn = hal_remote_l32( XPTR( src_cxy , &src_pt2[2 * src_ix2 + 1] ) ); 953 954 // do nothing if src_pte2 not MAPPED 955 if( (src_pte2_attr & TSAR_PTE_MAPPED) != 0 ) 956 { 957 // set PPN in DST PTE2 958 dst_pt2[2 * dst_ix2 + 1] = src_pte2_ppn; 959 960 // set attributes in DST PTE2 961 if( cow && (src_pte2_attr & TSAR_PTE_WRITABLE) ) 962 { 963 dst_pt2[2 * dst_ix2] = (src_pte2_attr | TSAR_PTE_COW) & (~TSAR_PTE_WRITABLE); 964 } 965 else 966 { 967 dst_pt2[2 * dst_ix2] = src_pte2_attr; 968 } 969 970 // return "successfully copied" 971 *mapped = true; 972 *ppn = src_pte2_ppn; 575 973 576 // unmap the small page 577 pt2[2*ix2] = 0; 578 hal_fence(); 579 580 return; 581 } 582 } // end hal_gpt_reset_pte() 974 #if DEBUG_HAL_GPT_COPY 975 cycle = (uint32_t)hal_get_cycles; 976 if( DEBUG_HAL_GPT_COPY < cycle ) 977 printk("\n[%s] : thread[%x,%x] exit / copy done for src_vpn %x / dst_vpn %x / cycle %d\n", 978 __FUNCTION__, this->process->pid, this->trdid, src_vpn, dst_vpn, cycle ); 979 #endif 980 981 hal_fence(); 982 983 return 0; 984 } // end if PTE2 mapped 985 } // end if PTE1 mapped 986 987 // return "nothing done" 988 *mapped = false; 989 *ppn = 0; 990 991 #if DEBUG_HAL_GPT_COPY 992 cycle = (uint32_t)hal_get_cycles; 993 if( DEBUG_HAL_GPT_COPY < cycle ) 994 printk("\n[%s] : thread[%x,%x] exit / nothing done / cycle %d\n", 995 __FUNCTION__, this->process->pid, this->trdid, cycle ); 996 #endif 997 998 hal_fence(); 999 1000 return 0; 1001 1002 } // end hal_gpt_pte_copy() 1003 1004 ///////////////////////////////////////// 1005 void hal_gpt_set_cow( xptr_t gpt_xp, 1006 vpn_t vpn_base, 1007 vpn_t vpn_size ) 1008 { 1009 cxy_t gpt_cxy; 1010 gpt_t * gpt_ptr; 1011 1012 vpn_t vpn; 1013 1014 uint32_t ix1; 1015 uint32_t ix2; 1016 1017 uint32_t * pt1; 1018 uint32_t pte1; 1019 1020 uint32_t * pt2; 1021 ppn_t pt2_ppn; 1022 uint32_t attr; 1023 1024 // get GPT cluster and local pointer 1025 gpt_cxy = GET_CXY( gpt_xp ); 1026 gpt_ptr = GET_PTR( gpt_xp ); 1027 1028 // get local PT1 pointer 1029 pt1 = (uint32_t *)hal_remote_lpt( XPTR( gpt_cxy , &gpt_ptr->ptr ) ); 1030 1031 // loop on pages 1032 for( vpn = vpn_base ; vpn < (vpn_base + vpn_size) ; vpn++ ) 1033 { 1034 ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); 1035 ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); 1036 1037 // get PTE1 value 1038 pte1 = hal_remote_l32( XPTR( gpt_cxy , &pt1[ix1] ) ); 1039 1040 // only MAPPED & SMALL PTEs are modified 1041 if( (pte1 & TSAR_PTE_MAPPED) && (pte1 & TSAR_PTE_SMALL) ) 1042 { 1043 // compute PT2 base address 1044 pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 ); 1045 pt2 = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 1046 1047 assert( (GET_CXY( ppm_ppn2base( pt2_ppn ) ) == gpt_cxy ), 1048 "PT2 and PT1 must be in the same cluster\n"); 1049 1050 // get current PTE2 attributes 1051 attr = hal_remote_l32( XPTR( gpt_cxy , &pt2[2*ix2] ) ); 1052 1053 // only MAPPED PTEs are modified 1054 if( attr & TSAR_PTE_MAPPED ) 1055 { 1056 attr = (attr | TSAR_PTE_COW) & (~TSAR_PTE_WRITABLE); 1057 hal_remote_s32( XPTR( gpt_cxy , &pt2[2*ix2] ) , attr ); 1058 } 1059 } 1060 } // end loop on pages 1061 1062 } // end hal_gpt_set_cow() 1063 1064 ////////////////////////////////////////// 1065 void hal_gpt_update_pte( xptr_t gpt_xp, 1066 vpn_t vpn, 1067 uint32_t attr, // generic GPT attributes 1068 ppn_t ppn ) 1069 { 1070 uint32_t * pt1; // PT1 base addres 1071 uint32_t pte1; // PT1 entry value 1072 1073 ppn_t pt2_ppn; // PPN of PT2 1074 uint32_t * pt2; // PT2 base address 1075 1076 uint32_t ix1; // index in PT1 1077 uint32_t ix2; // index in PT2 1078 1079 uint32_t tsar_attr; // PTE attributes for TSAR MMU 1080 1081 // check attr argument MAPPED and SMALL 1082 if( (attr & GPT_MAPPED) == 0 ) return; 1083 if( (attr & GPT_SMALL ) == 0 ) return; 1084 1085 // get cluster and local pointer on remote GPT 1086 cxy_t gpt_cxy = GET_CXY( gpt_xp ); 1087 gpt_t * gpt_ptr = GET_PTR( gpt_xp ); 1088 1089 // compute indexes in PT1 and PT2 1090 ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); 1091 ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); 1092 1093 // get PT1 base 1094 pt1 = (uint32_t *)hal_remote_lpt( XPTR( gpt_cxy , &gpt_ptr->ptr ) ); 1095 1096 // compute tsar_attr from generic attributes 1097 tsar_attr = gpt2tsar( attr ); 1098 1099 // get PTE1 value 1100 pte1 = hal_remote_l32( XPTR( gpt_cxy , &pt1[ix1] ) ); 1101 1102 if( (pte1 & TSAR_PTE_MAPPED) == 0 ) return; 1103 if( (pte1 & TSAR_PTE_SMALL ) == 0 ) return; 1104 1105 // get PT2 base from PTE1 1106 pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 ); 1107 pt2 = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 1108 1109 // set PTE2 in this order 1110 hal_remote_s32( XPTR( gpt_cxy, &pt2[2 * ix2 + 1] ) , ppn ); 1111 hal_fence(); 1112 hal_remote_s32( XPTR( gpt_cxy, &pt2[2 * ix2] ) , tsar_attr ); 1113 hal_fence(); 1114 1115 } // end hal_gpt_update_pte() 1116 1117 583 1118 584 1119 … … 616 1151 pte1 = pt1[ix1] 617 1152 618 if( (pte1 & TSAR_ MMU_MAPPED) == 0 ) // PT1[ix1] unmapped1153 if( (pte1 & TSAR_PTE_MAPPED) == 0 ) // PT1[ix1] unmapped 619 1154 { 620 1155 // update vpn (next big page) 621 1156 (vpn = ix1 + 1) << 9; 622 1157 } 623 if( (pte1 & TSAR_ MMU_SMALL) == 0 ) // it's a PTE1 (big page)1158 if( (pte1 & TSAR_PTE_SMALL) == 0 ) // it's a PTE1 (big page) 624 1159 { 625 1160 // unmap the big page … … 650 1185 */ 651 1186 652 ////////////////////////////////////// 653 error_t hal_gpt_lock_pte( gpt_t * gpt, 654 vpn_t vpn ) 655 { 656 uint32_t * pt1; // PT1 base address 657 volatile uint32_t * pte1_ptr; // address of PT1 entry 658 uint32_t pte1; // value of PT1 entry 659 660 uint32_t * pt2; // PT2 base address 661 ppn_t pt2_ppn; // PPN of PT2 page if missing PT2 662 volatile uint32_t * pte2_ptr; // address of PT2 entry 663 664 uint32_t attr; 665 bool_t atomic; 666 page_t * page; 667 xptr_t page_xp; 668 669 uint32_t ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); // index in PT1 670 uint32_t ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); // index in PT2 671 672 // get the PTE1 value 673 pt1 = gpt->ptr; 674 pte1_ptr = &pt1[ix1]; 675 pte1 = *pte1_ptr; 676 677 // If present, the page must be small 678 if( ((pte1 & TSAR_MMU_MAPPED) != 0) && ((pte1 & TSAR_MMU_SMALL) == 0) ) 679 { 680 printk("\n[ERROR] in %s : try to lock a big page / PT1[%d] = %x\n", 681 __FUNCTION__ , ix1 , pte1 ); 682 return EINVAL; 683 } 684 685 if( (pte1 & TSAR_MMU_MAPPED) == 0 ) // missing PT1 entry 686 { 687 // allocate one physical page for PT2 688 kmem_req_t req; 689 req.type = KMEM_PAGE; 690 req.size = 0; // 1 small page 691 req.flags = AF_KERNEL | AF_ZERO; 692 page = (page_t *)kmem_alloc( &req ); 693 694 if( page == NULL ) 695 { 696 printk("\n[ERROR] in %s : try to set a small page but cannot allocate PT2\n", 697 __FUNCTION__ ); 698 return ENOMEM; 699 } 700 701 page_xp = XPTR( local_cxy , page ); 702 pt2_ppn = ppm_page2ppn( page_xp ); 703 pt2 = GET_PTR( ppm_page2base( page_xp ) ); 704 705 // try to set the PT1 entry 706 do 707 { 708 atomic = hal_atomic_cas( (void*)pte1_ptr , 0 , 709 TSAR_MMU_MAPPED | TSAR_MMU_SMALL | pt2_ppn ); 710 } 711 while( (atomic == false) && (*pte1_ptr == 0) ); 712 713 if( atomic == false ) // missing PT2 has been allocate by another core 714 { 715 // release the allocated page 716 ppm_free_pages( page ); 717 718 // read again the PTE1 719 pte1 = *pte1_ptr; 720 721 // get the PT2 base address 722 pt2_ppn = TSAR_MMU_PPN_FROM_PTE1( pte1 ); 723 pt2 = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 724 } 725 } 726 else 727 { 728 // This valid entry must be a PTD1 729 if( (pte1 & TSAR_MMU_SMALL) == 0 ) 730 { 731 printk("\n[ERROR] in %s : set a small page in a big PT1 entry / PT1[%d] = %x\n", 732 __FUNCTION__ , ix1 , pte1 ); 733 return EINVAL; 734 } 735 736 // compute PPN of PT2 base 737 pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 ); 738 739 // compute pointer on PT2 base 740 pt2 = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 741 } 742 743 // from here we have the PT2 pointer 744 745 // compute pointer on PTE2 746 pte2_ptr = &pt2[2 * ix2]; 747 748 // try to atomically lock the PTE2 until success 749 do 750 { 751 // busy waiting until TSAR_MMU_LOCK == 0 752 do 753 { 754 attr = *pte2_ptr; 755 hal_rdbar(); 756 } 757 while( (attr & TSAR_MMU_LOCKED) != 0 ); 758 759 atomic = hal_atomic_cas( (void*)pte2_ptr, attr , (attr | TSAR_MMU_LOCKED) ); 760 } 761 while( atomic == 0 ); 762 763 return 0; 764 765 } // end hal_gpt_lock_pte() 766 767 //////////////////////////////////////// 768 error_t hal_gpt_unlock_pte( gpt_t * gpt, 769 vpn_t vpn ) 770 { 771 uint32_t * pt1; // PT1 base address 772 uint32_t pte1; // value of PT1 entry 773 774 uint32_t * pt2; // PT2 base address 775 ppn_t pt2_ppn; // PPN of PT2 page if missing PT2 776 uint32_t * pte2_ptr; // address of PT2 entry 777 778 uint32_t attr; // PTE2 attribute 779 780 // compute indexes in P1 and PT2 781 uint32_t ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); // index in PT1 782 uint32_t ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); // index in PT2 783 784 // get pointer on PT1 base 785 pt1 = (uint32_t*)gpt->ptr; 786 787 // get PTE1 788 pte1 = pt1[ix1]; 789 790 // check PTE1 present and small page 791 if( ((pte1 & TSAR_MMU_MAPPED) == 0) || ((pte1 & TSAR_MMU_SMALL) == 0) ) 792 { 793 printk("\n[ERROR] in %s : try to unlock a big or undefined page / PT1[%d] = %x\n", 794 __FUNCTION__ , ix1 , pte1 ); 795 return EINVAL; 796 } 797 798 // get pointer on PT2 base 799 pt2_ppn = TSAR_MMU_PPN_FROM_PTE1( pte1 ); 800 pt2 = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 801 802 // get pointer on PTE2 803 pte2_ptr = &pt2[2 * ix2]; 804 805 // get PTE2_ATTR 806 attr = *pte2_ptr; 807 808 // check PTE2 present and locked 809 if( ((attr & TSAR_MMU_MAPPED) == 0) || ((attr & TSAR_MMU_LOCKED) == 0) ) 810 { 811 printk("\n[ERROR] in %s : unlock an unlocked/unmapped page / PT1[%d] = %x\n", 812 __FUNCTION__ , ix1 , pte1 ); 813 return EINVAL; 814 } 815 816 // reset GPT_LOCK 817 *pte2_ptr = attr & ~TSAR_MMU_LOCKED; 818 819 return 0; 820 821 } // end hal_gpt_unlock_pte() 822 823 /////////////////////////////////////////// 824 error_t hal_gpt_pte_copy( gpt_t * dst_gpt, 825 vpn_t dst_vpn, 826 xptr_t src_gpt_xp, 827 vpn_t src_vpn, 828 bool_t cow, 829 ppn_t * ppn, 830 bool_t * mapped ) 831 { 832 uint32_t src_ix1; // index in SRC PT1 833 uint32_t src_ix2; // index in SRC PT2 834 835 uint32_t dst_ix1; // index in DST PT1 836 uint32_t dst_ix2; // index in DST PT2 837 838 cxy_t src_cxy; // SRC GPT cluster 839 gpt_t * src_gpt; // SRC GPT local pointer 840 841 uint32_t * src_pt1; // local pointer on SRC PT1 842 uint32_t * dst_pt1; // local pointer on DST PT1 843 uint32_t * src_pt2; // local pointer on SRC PT2 844 uint32_t * dst_pt2; // local pointer on DST PT2 845 846 kmem_req_t req; // for PT2 allocation 847 848 uint32_t src_pte1; 849 uint32_t dst_pte1; 850 851 uint32_t src_pte2_attr; 852 uint32_t src_pte2_ppn; 853 854 page_t * page; 855 xptr_t page_xp; 856 857 ppn_t src_pt2_ppn; 858 ppn_t dst_pt2_ppn; 859 860 // get remote src_gpt cluster and local pointer 861 src_cxy = GET_CXY( src_gpt_xp ); 862 src_gpt = GET_PTR( src_gpt_xp ); 863 864 #if DEBUG_HAL_GPT_COPY 865 uint32_t cycle = (uint32_t)hal_get_cycles(); 866 thread_t * this = CURRENT_THREAD; 867 if( DEBUG_HAL_GPT_COPY < cycle ) 868 printk("\n[%s] : thread[%x,%x] enter / src_cxy %x / dst_cxy %x / cycle %d\n", 869 __FUNCTION__, this->process->pid, this->trdid, src_cxy, local_cxy, cycle ); 870 #endif 871 872 // get remote src_gpt cluster and local pointer 873 src_cxy = GET_CXY( src_gpt_xp ); 874 src_gpt = GET_PTR( src_gpt_xp ); 875 876 // get remote src_pt1 and local dst_pt1 877 src_pt1 = (uint32_t *)hal_remote_lpt( XPTR( src_cxy , &src_gpt->ptr ) ); 878 dst_pt1 = (uint32_t *)dst_gpt->ptr; 879 880 // check src_pt1 and dst_pt1 existence 881 assert( (src_pt1 != NULL) , "src_pt1 does not exist\n"); 882 assert( (dst_pt1 != NULL) , "dst_pt1 does not exist\n"); 883 884 // compute SRC indexes 885 src_ix1 = TSAR_MMU_IX1_FROM_VPN( src_vpn ); 886 src_ix2 = TSAR_MMU_IX2_FROM_VPN( src_vpn ); 887 888 // compute DST indexes 889 dst_ix1 = TSAR_MMU_IX1_FROM_VPN( dst_vpn ); 890 dst_ix2 = TSAR_MMU_IX2_FROM_VPN( dst_vpn ); 891 892 // get src_pte1 893 src_pte1 = hal_remote_l32( XPTR( src_cxy , &src_pt1[src_ix1] ) ); 894 895 // do nothing if src_pte1 not MAPPED or not SMALL 896 if( (src_pte1 & TSAR_MMU_MAPPED) && (src_pte1 & TSAR_MMU_SMALL) ) 897 { 898 // get dst_pt1 entry 899 dst_pte1 = dst_pt1[dst_ix1]; 900 901 // map dst_pte1 if required 902 if( (dst_pte1 & TSAR_MMU_MAPPED) == 0 ) 903 { 904 // allocate one physical page for a new PT2 905 req.type = KMEM_PAGE; 906 req.size = 0; // 1 small page 907 req.flags = AF_KERNEL | AF_ZERO; 908 page = (page_t *)kmem_alloc( &req ); 909 910 if( page == NULL ) 911 { 912 printk("\n[ERROR] in %s : cannot allocate PT2\n", __FUNCTION__ ); 913 return -1; 914 } 915 916 // build extended pointer on page descriptor 917 page_xp = XPTR( local_cxy , page ); 918 919 // get PPN for this new PT2 920 dst_pt2_ppn = (ppn_t)ppm_page2ppn( page_xp ); 921 922 // build the new dst_pte1 923 dst_pte1 = TSAR_MMU_MAPPED | TSAR_MMU_SMALL | dst_pt2_ppn; 924 925 // register it in DST_GPT 926 dst_pt1[dst_ix1] = dst_pte1; 927 } 928 929 // get pointer on src_pt2 930 src_pt2_ppn = (ppn_t)TSAR_MMU_PTBA_FROM_PTE1( src_pte1 ); 931 src_pt2 = GET_PTR( ppm_ppn2base( src_pt2_ppn ) ); 932 933 // get pointer on dst_pt2 934 dst_pt2_ppn = (ppn_t)TSAR_MMU_PTBA_FROM_PTE1( dst_pte1 ); 935 dst_pt2 = GET_PTR( ppm_ppn2base( dst_pt2_ppn ) ); 936 937 // get attr and ppn from SRC_PT2 938 src_pte2_attr = hal_remote_l32( XPTR( src_cxy , &src_pt2[2 * src_ix2] ) ); 939 src_pte2_ppn = hal_remote_l32( XPTR( src_cxy , &src_pt2[2 * src_ix2 + 1] ) ); 940 941 // do nothing if src_pte2 not MAPPED 942 if( (src_pte2_attr & TSAR_MMU_MAPPED) != 0 ) 943 { 944 // set PPN in DST PTE2 945 dst_pt2[2 * dst_ix2 + 1] = src_pte2_ppn; 946 947 // set attributes in DST PTE2 948 if( cow && (src_pte2_attr & TSAR_MMU_WRITABLE) ) 949 { 950 dst_pt2[2 * dst_ix2] = (src_pte2_attr | TSAR_MMU_COW) & (~TSAR_MMU_WRITABLE); 951 } 952 else 953 { 954 dst_pt2[2 * dst_ix2] = src_pte2_attr; 955 } 956 957 // return "successfully copied" 958 *mapped = true; 959 *ppn = src_pte2_ppn; 960 961 #if DEBUG_HAL_GPT_COPY 962 cycle = (uint32_t)hal_get_cycles; 963 if( DEBUG_HAL_GPT_COPY < cycle ) 964 printk("\n[%s] : thread[%x,%x] exit / copy done for src_vpn %x / dst_vpn %x / cycle %d\n", 965 __FUNCTION__, this->process->pid, this->trdid, src_vpn, dst_vpn, cycle ); 966 #endif 967 968 hal_fence(); 969 970 return 0; 971 } // end if PTE2 mapped 972 } // end if PTE1 mapped 973 974 // return "nothing done" 975 *mapped = false; 976 *ppn = 0; 977 978 #if DEBUG_HAL_GPT_COPY 979 cycle = (uint32_t)hal_get_cycles; 980 if( DEBUG_HAL_GPT_COPY < cycle ) 981 printk("\n[%s] : thread[%x,%x] exit / nothing done / cycle %d\n", 982 __FUNCTION__, this->process->pid, this->trdid, cycle ); 983 #endif 984 985 hal_fence(); 986 987 return 0; 988 989 } // end hal_gpt_pte_copy() 990 991 ////////////////////////////////////////// 992 bool_t hal_gpt_pte_is_mapped( gpt_t * gpt, 993 vpn_t vpn ) 994 { 995 uint32_t * pt1; 996 uint32_t pte1; 997 uint32_t pte2_attr; 998 999 uint32_t * pt2; 1000 ppn_t pt2_ppn; 1001 1002 uint32_t ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); 1003 uint32_t ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); 1004 1005 // get PTE1 value 1006 pt1 = gpt->ptr; 1007 pte1 = pt1[ix1]; 1008 1009 if( (pte1 & TSAR_MMU_MAPPED) == 0 ) return false; 1010 1011 if( (pte1 & TSAR_MMU_SMALL) == 0 ) return false; 1012 1013 // compute PT2 base address 1014 pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 ); 1015 pt2 = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 1016 1017 // get pte2_attr 1018 pte2_attr = pt2[2*ix2]; 1019 1020 if( (pte2_attr & TSAR_MMU_MAPPED) == 0 ) return false; 1021 else return true; 1022 1023 } // end hal_gpt_pte_is_mapped() 1024 1025 /////////////////////////////////////// 1026 bool_t hal_gpt_pte_is_cow( gpt_t * gpt, 1027 vpn_t vpn ) 1028 { 1029 uint32_t * pt1; 1030 uint32_t pte1; 1031 uint32_t pte2_attr; 1032 1033 uint32_t * pt2; 1034 ppn_t pt2_ppn; 1035 1036 uint32_t ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); 1037 uint32_t ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); 1038 1039 // get PTE1 value 1040 pt1 = gpt->ptr; 1041 pte1 = pt1[ix1]; 1042 1043 if( (pte1 & TSAR_MMU_MAPPED) == 0 ) return false; 1044 1045 if( (pte1 & TSAR_MMU_SMALL) == 0 ) return false; 1046 1047 // compute PT2 base address 1048 pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 ); 1049 pt2 = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 1050 1051 // get pte2_attr 1052 pte2_attr = pt2[2*ix2]; 1053 1054 if( (pte2_attr & TSAR_MMU_MAPPED) == 0 ) return false; 1055 1056 if( (pte2_attr & TSAR_MMU_COW) == 0 ) return false; 1057 else return true; 1058 1059 } // end hal_gpt_pte_is_cow() 1060 1061 ///////////////////////////////////////// 1062 void hal_gpt_set_cow( xptr_t gpt_xp, 1063 vpn_t vpn_base, 1064 vpn_t vpn_size ) 1065 { 1066 cxy_t gpt_cxy; 1067 gpt_t * gpt_ptr; 1068 1069 vpn_t vpn; 1070 1071 uint32_t ix1; 1072 uint32_t ix2; 1073 1074 uint32_t * pt1; 1075 uint32_t pte1; 1076 1077 uint32_t * pt2; 1078 ppn_t pt2_ppn; 1079 uint32_t attr; 1080 1081 // get GPT cluster and local pointer 1082 gpt_cxy = GET_CXY( gpt_xp ); 1083 gpt_ptr = GET_PTR( gpt_xp ); 1084 1085 // get local PT1 pointer 1086 pt1 = (uint32_t *)hal_remote_lpt( XPTR( gpt_cxy , &gpt_ptr->ptr ) ); 1087 1088 // loop on pages 1089 for( vpn = vpn_base ; vpn < (vpn_base + vpn_size) ; vpn++ ) 1090 { 1091 ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); 1092 ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); 1093 1094 // get PTE1 value 1095 pte1 = hal_remote_l32( XPTR( gpt_cxy , &pt1[ix1] ) ); 1096 1097 // only MAPPED & SMALL PTEs are modified 1098 if( (pte1 & TSAR_MMU_MAPPED) && (pte1 & TSAR_MMU_SMALL) ) 1099 { 1100 // compute PT2 base address 1101 pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 ); 1102 pt2 = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 1103 1104 assert( (GET_CXY( ppm_ppn2base( pt2_ppn ) ) == gpt_cxy ), 1105 "PT2 and PT1 must be in the same cluster\n"); 1106 1107 // get current PTE2 attributes 1108 attr = hal_remote_l32( XPTR( gpt_cxy , &pt2[2*ix2] ) ); 1109 1110 // only MAPPED PTEs are modified 1111 if( attr & TSAR_MMU_MAPPED ) 1112 { 1113 attr = (attr | TSAR_MMU_COW) & (~TSAR_MMU_WRITABLE); 1114 hal_remote_s32( XPTR( gpt_cxy , &pt2[2*ix2] ) , attr ); 1115 } 1116 } 1117 } // end loop on pages 1118 1119 } // end hal_gpt_set_cow() 1120 1121 ////////////////////////////////////////// 1122 void hal_gpt_update_pte( xptr_t gpt_xp, 1123 vpn_t vpn, 1124 uint32_t attr, // generic GPT attributes 1125 ppn_t ppn ) 1126 { 1127 uint32_t * pt1; // PT1 base addres 1128 uint32_t pte1; // PT1 entry value 1129 1130 ppn_t pt2_ppn; // PPN of PT2 1131 uint32_t * pt2; // PT2 base address 1132 1133 uint32_t ix1; // index in PT1 1134 uint32_t ix2; // index in PT2 1135 1136 uint32_t tsar_attr; // PTE attributes for TSAR MMU 1137 1138 // check attr argument MAPPED and SMALL 1139 if( (attr & GPT_MAPPED) == 0 ) return; 1140 if( (attr & GPT_SMALL ) == 0 ) return; 1141 1142 // get cluster and local pointer on remote GPT 1143 cxy_t gpt_cxy = GET_CXY( gpt_xp ); 1144 gpt_t * gpt_ptr = GET_PTR( gpt_xp ); 1145 1146 // compute indexes in PT1 and PT2 1147 ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); 1148 ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); 1149 1150 // get PT1 base 1151 pt1 = (uint32_t *)hal_remote_lpt( XPTR( gpt_cxy , &gpt_ptr->ptr ) ); 1152 1153 // compute tsar_attr from generic attributes 1154 tsar_attr = gpt2tsar( attr ); 1155 1156 // get PTE1 value 1157 pte1 = hal_remote_l32( XPTR( gpt_cxy , &pt1[ix1] ) ); 1158 1159 if( (pte1 & TSAR_MMU_MAPPED) == 0 ) return; 1160 if( (pte1 & TSAR_MMU_SMALL ) == 0 ) return; 1161 1162 // get PT2 base from PTE1 1163 pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 ); 1164 pt2 = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 1165 1166 // set PTE2 in this order 1167 hal_remote_s32( XPTR( gpt_cxy, &pt2[2 * ix2 + 1] ) , ppn ); 1168 hal_fence(); 1169 hal_remote_s32( XPTR( gpt_cxy, &pt2[2 * ix2] ) , tsar_attr ); 1170 hal_fence(); 1171 1172 } // end hal_gpt_update_pte() 1173 1187 -
trunk/hal/tsar_mips32/core/hal_vmm.c
r625 r629 81 81 uint32_t ppn = cxy << 20; 82 82 83 // register PTE1 in slot[0] of kernel GPT 84 error = hal_gpt_set_pte( XPTR( cxy , gpt ) , 0 , attr , ppn ); 85 86 if( error ) 87 { 88 printk("\n[PANIC] in %s : cannot initialize kernel GPT in cluster %x\n", 89 __FUNCTION__ , cxy ); 90 hal_core_sleep(); 91 } 83 // set PT1[0] 84 hal_gpt_set_pte( XPTR( cxy , gpt ) , 0 , attr , ppn ); 92 85 93 86 #if DEBUG_HAL_VMM … … 159 152 160 153 // update user GPT : set PTE1 in slot[0] 161 error = hal_gpt_set_pte( u_gpt_xp , 0 , attr , ppn ); 162 163 if( error ) 164 { 165 printk("\n[ERROR] in %s : cannot update user GPT in cluster %x\n", 166 __FUNCTION__ , cxy ); 167 return -1; 168 } 154 hal_gpt_set_pte( u_gpt_xp , 0 , attr , ppn ); 169 155 170 156 #if DEBUG_HAL_VMM … … 220 206 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); 221 207 222 // build extended pointer s on TXT0 lock, GPTlock and VSL lock208 // build extended pointer on TXT0 lock and VSL lock 223 209 xptr_t txt_lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock ); 224 210 xptr_t vsl_lock_xp = XPTR( local_cxy , &vmm->vsl_lock ); 225 xptr_t gpt_lock_xp = XPTR( local_cxy , &vmm->gpt_lock );226 211 227 212 // get root of vsegs list … … 230 215 // get the locks protecting TXT0, VSL, and GPT 231 216 remote_rwlock_rd_acquire( vsl_lock_xp ); 232 remote_rwlock_rd_acquire( gpt_lock_xp );233 217 remote_busylock_acquire( txt_lock_xp ); 234 218 … … 291 275 // release locks 292 276 remote_busylock_release( txt_lock_xp ); 293 remote_rwlock_rd_release( gpt_lock_xp );294 277 remote_rwlock_rd_release( vsl_lock_xp ); 295 278 -
trunk/hal/tsar_mips32/drivers/soclib_pic.c
r570 r629 156 156 157 157 // check RPC FIFO, and activate or create a RPC thread 158 // (condition is always true, but we use the ack value to avoid a GCC warning) 158 // condition is always true, but we use the ack value 159 // to avoid a GCC warning 159 160 if( ack + 1 ) sched_yield("IPI received"); 160 161 } … … 200 201 201 202 if( src_chdev == NULL ) // strange, but not fatal 202 {203 { 203 204 printk("\n[WARNING] in %s : no handler for HWI %d on core %d in cluster %x\n", 204 205 __FUNCTION__ , index , core->lid , local_cxy ); -
trunk/kernel/fs/fatfs.h
r628 r629 181 181 * 182 182 * WARNING 2 : Most fields are constant values, but the <free_cluster_hint>, 183 * <free_clusters>, <dirty_page_min>, <dirty_page_max>, <lock>, and the <fs_info_buffer> 184 * are shared variables, that can be modified by any thread running in any cluster. 185 * The <fs_info_buffer> contains a copy of the FS_INFO sector, and is only allocated in 186 * the FAT cluster (i.e. in cluster 0). It is used by all to synchronously update the 187 * free clusters info on IOC device. 183 * <free_clusters>, <lock>, and the <fs_info_buffer> are shared variables, 184 * that can be modified by any thread running in any cluster. The <fs_info_buffer> 185 * contains a copy of the FS_INFO sector, and is only allocated in the FAT cluster 186 * (cluster 0). It is used to synchronously update the free clusters info on IOC device. 188 187 * => For all these variables, only the values stored in the FAT cluster must be used. 189 188 ****************************************************************************************/ … … 202 201 203 202 /* shared variables (only the copy in FAT cluster must be used) */ 204 uint32_t dirty_page_min; /*! min dirty page index in FAT mapper */205 uint32_t dirty_page_max; /*! max dirty page index in FAT mapper */206 203 uint32_t free_cluster_hint; /*! cluster[hint+1] is the first free */ 207 204 uint32_t free_clusters; /*! free clusters number */ -
trunk/kernel/fs/vfs.c
r628 r629 2608 2608 #if (DEBUG_VFS_LOOKUP & 1) 2609 2609 if( DEBUG_VFS_LOOKUP < cycle ) 2610 printk("\n[%s] thread[%x,%x] created missing inode <%s> in cluster %x\n",2610 printk("\n[%s] thread[%x,%x] created missing inode for <%s> in cluster %x\n", 2611 2611 __FUNCTION__, process->pid, this->trdid, name, child_cxy ); 2612 2612 #endif … … 2629 2629 2630 2630 // when the missing dentry is not in the parent mapper, 2631 // it is a new dentry thatmust be registered in parent directory mapper2631 // a new dentry must be registered in parent directory mapper 2632 2632 if ( error ) 2633 2633 { … … 2814 2814 2815 2815 // 1. allocate one free cluster in file system to child inode, 2816 // and update the File Allocation Table in both the TAFmapper and IOC device.2816 // and update the File Allocation Table in both the FAT mapper and IOC device. 2817 2817 // It depends on the child inode FS type. 2818 2818 vfs_ctx_t * ctx = hal_remote_lpt( XPTR( child_cxy , &child_ptr->ctx ) ); -
trunk/kernel/kern/kernel_init.c
r628 r629 171 171 "VFS_FILE", // 33 172 172 "VMM_VSL", // 34 173 "VMM_GPT", // 35 174 "VFS_MAIN", // 36 175 "FATFS_FAT", // 37 173 "VFS_MAIN", // 35 174 "FATFS_FAT", // 36 176 175 }; 177 176 -
trunk/kernel/kern/process.c
r626 r629 166 166 #endif 167 167 168 // initialize GPT and VSL locks 169 remote_rwlock_init( XPTR( local_cxy , &vmm->gpt_lock ) , LOCK_VMM_GPT ); 168 // initialize VSL locks 170 169 remote_rwlock_init( XPTR( local_cxy , &vmm->vsl_lock ) , LOCK_VMM_VSL ); 171 170 … … 426 425 427 426 // initialize GPT and VSL locks 428 remote_rwlock_init( XPTR( local_cxy , &vmm->gpt_lock ) , LOCK_VMM_GPT );429 427 remote_rwlock_init( XPTR( local_cxy , &vmm->vsl_lock ) , LOCK_VMM_VSL ); 430 428 … … 1482 1480 1483 1481 // set COW flag in DATA, ANON, REMOTE vsegs for parent process VMM 1484 // this includes all par net process copies in all clusters1482 // this includes all parent process copies in all clusters 1485 1483 if( parent_process_cxy == local_cxy ) // reference is local 1486 1484 { … … 1707 1705 1708 1706 // initialize VSL and GPT locks 1709 remote_rwlock_init( XPTR( local_cxy , &vmm->vsl_lock ) , LOCK_VMM_VSL ); 1710 remote_rwlock_init( XPTR( local_cxy , &vmm->gpt_lock ) , LOCK_VMM_GPT ); 1707 remote_rwlock_init( XPTR( local_cxy , &vmm->vsl_lock ) , LOCK_VMM_VSL ); 1711 1708 1712 1709 // create kernel vsegs in GPT and VSL, as required by the hardware architecture -
trunk/kernel/kern/rpc.c
r628 r629 104 104 "VFS_FILE_CREATE", // 14 105 105 "VFS_FILE_DESTROY", // 15 106 "VFS_FS_ GET_DENTRY", // 16106 "VFS_FS_NEW_DENTRY", // 16 107 107 "VFS_FS_ADD_DENTRY", // 17 108 108 "VFS_FS_REMOVE_DENTRY", // 18 -
trunk/kernel/kern/scheduler.c
r625 r629 63 63 // @ returns pointer on selected thread descriptor 64 64 //////////////////////////////////////////////////////////////////////////////////////////// 65 thread_t * sched_select( scheduler_t * sched )65 static thread_t * sched_select( scheduler_t * sched ) 66 66 { 67 67 thread_t * thread; … … 248 248 uint32_t cycle = (uint32_t)hal_get_cycles(); 249 249 if( DEBUG_SCHED_HANDLE_SIGNALS < cycle ) 250 printk("\n[%s] thread[%x,%x] on core[%x,%d] deleted / %d threads/ cycle %d\n",250 printk("\n[%s] thread[%x,%x] on core[%x,%d] deleted (still %d threads) / cycle %d\n", 251 251 __FUNCTION__, process->pid, thread->trdid, local_cxy, thread->core->lid, count, cycle ); 252 #endif 253 254 #if CONFIG_INSTRUMENTATION_PGFAULTS 255 uint32_t local_nr = thread->info.local_pgfault_nr; 256 uint32_t local_cost = (local_nr == 0) ? 0 : (thread->info.local_pgfault_cost / local_nr); 257 uint32_t global_nr = thread->info.global_pgfault_nr; 258 uint32_t global_cost = (global_nr == 0) ? 0 : (thread->info.global_pgfault_cost / global_nr); 259 uint32_t false_nr = thread->info.false_pgfault_nr; 260 uint32_t false_cost = (false_nr == 0) ? 0 : (thread->info.false_pgfault_cost / false_nr); 261 printk("***** page faults for thread[%x,%x]\n" 262 " - %d local : %d cycles\n" 263 " - %d global : %d cycles\n" 264 " - %d false : %d cycles\n", 265 process->pid, thread->trdid, 266 local_nr, local_cost, 267 global_nr, global_cost, 268 false_nr, false_cost ); 252 269 #endif 253 270 // destroy process descriptor if last thread … … 481 498 482 499 #if (DEBUG_SCHED_YIELD & 0x1) 483 // if( sched->trace ) 484 if( (uint32_t)hal_get_cycles() > DEBUG_SCHED_YIELD ) 500 if( sched->trace ) 485 501 sched_display( lid ); 486 502 #endif … … 535 551 536 552 #if DEBUG_SCHED_YIELD 537 // if( sched->trace ) 538 if( (uint32_t)hal_get_cycles() > DEBUG_SCHED_YIELD ) 553 if( sched->trace ) 539 554 printk("\n[%s] core[%x,%d] / cause = %s\n" 540 555 " thread %x (%s) (%x,%x) => thread %x (%s) (%x,%x) / cycle %d\n", … … 553 568 554 569 #if (DEBUG_SCHED_YIELD & 1) 555 // if( sched->trace ) 556 if( (uint32_t)hal_get_cycles() > DEBUG_SCHED_YIELD ) 570 if( sched->trace ) 557 571 printk("\n[%s] core[%x,%d] / cause = %s\n" 558 572 " thread %x (%s) (%x,%x) continue / cycle %d\n", -
trunk/kernel/kern/thread.c
r625 r629 907 907 908 908 // update target process instrumentation counter 909 process->vmm.pgfault_nr += thread->info.pgfault_nr;909 // process->vmm.pgfault_nr += thread->info.pgfault_nr; 910 910 911 911 // remove thread from process th_tbl[] -
trunk/kernel/kern/thread.h
r625 r629 100 100 typedef struct thread_info_s 101 101 { 102 uint32_t pgfault_nr; /*! cumulated number of page fault */ 103 cycle_t last_cycle; /*! last cycle counter value (date) */ 104 cycle_t usr_cycles; /*! user execution duration (cycles) */ 105 cycle_t sys_cycles; /*! system execution duration (cycles) */ 102 uint32_t false_pgfault_nr; /*! number of local page fault */ 103 uint32_t false_pgfault_cost; /*! cumulated cost */ 104 uint32_t local_pgfault_nr; /*! number of local page fault */ 105 uint32_t local_pgfault_cost; /*! cumulated cost */ 106 uint32_t global_pgfault_nr; /*! number of global page fault */ 107 uint32_t global_pgfault_cost; /*! cumulated cost */ 108 109 cycle_t last_cycle; /*! last cycle counter value (date) */ 110 cycle_t usr_cycles; /*! user execution duration (cycles) */ 111 cycle_t sys_cycles; /*! system execution duration (cycles) */ 106 112 } 107 113 thread_info_t; -
trunk/kernel/kernel_config.h
r628 r629 26 26 #define _KERNEL_CONFIG_H_ 27 27 28 #define CONFIG_ALMOS_VERSION "Version 2. 0 / April2019"28 #define CONFIG_ALMOS_VERSION "Version 2.1 / May 2019" 29 29 30 30 //////////////////////////////////////////////////////////////////////////////////////////// … … 40 40 41 41 #define DEBUG_BUSYLOCK 0 42 #define DEBUG_BUSYLOCK_PID 0 x10001// for busylock detailed debug43 #define DEBUG_BUSYLOCK_TRDID 0 x10000// for busylock detailed debug42 #define DEBUG_BUSYLOCK_PID 0 // for busylock detailed debug 43 #define DEBUG_BUSYLOCK_TRDID 0 // for busylock detailed debug 44 44 45 45 #define DEBUG_CHDEV_CMD_RX 0 … … 136 136 #define DEBUG_PROCESS_ZERO_CREATE 0 137 137 138 #define DEBUG_QUEUELOCK_TYPE 0 // lock type (0 : undefined / 1000 : all types) 138 #define DEBUG_QUEUELOCK_TYPE 0 // lock type 0 is undefined => no debug 139 #define DEBUG_QUEUELOCK_PTR 0 140 #define DEBUG_QUEUELOCK_CXY 0 139 141 140 142 #define DEBUG_RPC_CLIENT_GENERIC 0 … … 165 167 #define DEBUG_RPC_VMM_DELETE_VSEG 0 166 168 167 #define DEBUG_RWLOCK_TYPE 0 // lock type (0 : undefined / 1000 : all types) 169 #define DEBUG_RWLOCK_TYPE 35 // lock type 0 is undefined => no debug 170 #define DEBUG_RWLOCK_PTR 0xb1650 171 #define DEBUG_RWLOCK_CXY 0x11 168 172 169 173 #define DEBUG_SCHED_HANDLE_SIGNALS 2 … … 309 313 #define LOCK_VFS_FILE 33 // remote (RW) protect file descriptor state 310 314 #define LOCK_VMM_VSL 34 // remote (RW) protect VSL (local list of vsegs) 311 #define LOCK_VMM_GPT 35 // remote (RW) protect GPT (local page table) 312 #define LOCK_VFS_MAIN 36 // remote (RW) protect vfs traversal (in root inode) 313 #define LOCK_FATFS_FAT 37 // remote (RW) protect exclusive access to the FATFS FAT 315 #define LOCK_VFS_MAIN 35 // remote (RW) protect vfs traversal (in root inode) 316 #define LOCK_FATFS_FAT 36 // remote (RW) protect exclusive access to the FATFS FAT 314 317 315 318 … … 451 454 //////////////////////////////////////////////////////////////////////////////////////////// 452 455 453 #define CONFIG_INTRUMENTATION_SYSCALLS 0 456 #define CONFIG_INSTRUMENTATION_SYSCALLS 0 457 #define CONFIG_INSTRUMENTATION_PGFAULTS 1 454 458 455 459 -
trunk/kernel/libk/queuelock.c
r623 r629 2 2 * queuelock.c - local kernel lock with waiting queue implementation. 3 3 * 4 * Authors Alain Greiner (2016,2017,2018 )4 * Authors Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 47 47 #if DEBUG_QUEUELOCK_TYPE 48 48 thread_t * this = CURRENT_THREAD; 49 if( DEBUG_QUEUELOCK_TYPE == type ) 49 if( (type == DEBUG_QUEUELOCK_TYPE) && 50 (lock == DEBUG_QUEUELOCK_PTR ) && 51 (local_cxy == DEBUG_QUEUELOCK_CXY ) ) 50 52 printk("\n[%s] thread[%x,%x] initialise lock %s [%x,%x]\n", 51 53 __FUNCTION__, this->process->pid, this->trdid, … … 75 77 76 78 #if DEBUG_QUEUELOCK_TYPE 77 if( (DEBUG_QUEUELOCK_TYPE == lock_type) || (DEBUG_QUEUELOCK_TYPE == 1000) ) 79 if( (lock_type == DEBUG_QUEUELOCK_TYPE) && 80 (lock == DEBUG_QUEUELOCK_PTR ) && 81 (local_cxy == DEBUG_QUEUELOCK_CXY ) ) 78 82 printk("\n[%s ] thread[%x,%x] BLOCK on q_lock %s [%x,%x]\n", 79 83 __FUNCTION__, this->process->pid, this->trdid, … … 100 104 101 105 #if DEBUG_QUEUELOCK_TYPE 102 if( (DEBUG_QUEUELOCK_TYPE == lock_type) || (DEBUG_QUEUELOCK_TYPE == 1000) ) 106 if( (lock_type == DEBUG_QUEUELOCK_TYPE) && 107 (lock == DEBUG_QUEUELOCK_PTR ) && 108 (local_cxy == DEBUG_QUEUELOCK_CXY ) ) 103 109 printk("\n[%s] thread[%x,%x] ACQUIRE q_lock %s [%x,%x]\n", 104 110 __FUNCTION__, this->process->pid, this->trdid, … … 126 132 uint32_t lock_type = lock->lock.type; 127 133 thread_t * this = CURRENT_THREAD; 128 if( (DEBUG_QUEUELOCK_TYPE == lock_type) || (DEBUG_QUEUELOCK_TYPE == 1000) ) 134 if( (lock_type == DEBUG_QUEUELOCK_TYPE) && 135 (lock == DEBUG_QUEUELOCK_PTR ) && 136 (local_cxy == DEBUG_QUEUELOCK_CXY ) ) 129 137 printk("\n[%s] thread[%x,%x] RELEASE q_lock %s [%x,%x]\n", 130 138 __FUNCTION__, this->process->pid, this->trdid, … … 142 150 143 151 #if DEBUG_QUEUELOCK_TYPE 144 if( (DEBUG_QUEUELOCK_TYPE == lock_type) || (DEBUG_QUEUELOCK_TYPE == 1000) ) 152 if( (lock_type == DEBUG_QUEUELOCK_TYPE) && 153 (lock == DEBUG_QUEUELOCK_PTR ) && 154 (local_cxy == DEBUG_QUEUELOCK_CXY ) ) 145 155 printk("\n[%s] thread[%x,%x] UNBLOCK thread [%x,%x] / q_lock %s [%x,%x]\n", 146 156 __FUNCTION__, this->process->pid, this->trdid, thread->process->pid, thread->trdid, -
trunk/kernel/libk/remote_barrier.c
r623 r629 467 467 if( cycle > DEBUG_BARRIER_WAIT ) 468 468 printk("\n[%s] thread[%x,%x] exit / barrier (%x,%x) / cycle %d\n", 469 __FUNCTION__, this-> trdid, this->process->pid, barrier_cxy, barrier_ptr, cycle );469 __FUNCTION__, this->process->pid, this->trdid, barrier_cxy, barrier_ptr, cycle ); 470 470 #endif 471 471 -
trunk/kernel/libk/remote_queuelock.c
r623 r629 2 2 * remote_queuelock.c - remote kernel lock with waiting queue implementation. 3 3 * 4 * Authors Alain Greiner (2016,2017,2018 )4 * Authors Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 56 56 #if DEBUG_QUEUELOCK_TYPE 57 57 thread_t * this = CURRENT_THREAD; 58 if( DEBUG_QUEUELOCK_TYPE == type ) 58 if( (type == DEBUG_QUEUELOCK_TYPE) && 59 (lock_ptr == DEBUG_QUEUELOCK_PTR ) && 60 (lock_cxy == DEBUG_QUEUELOCK_CXY ) ) 59 61 printk("\n[%s] thread[%x,%x] initialise lock %s [%x,%x]\n", 60 62 __FUNCTION__, this->process->pid, this->trdid, … … 91 93 92 94 #if DEBUG_QUEUELOCK_TYPE 93 if( (DEBUG_QUEUELOCK_TYPE == lock_type) || (DEBUG_QUEUELOCK_TYPE == 1000) ) 95 if( (lock_type == DEBUG_QUEUELOCK_TYPE) && 96 (lock_ptr == DEBUG_QUEUELOCK_PTR ) && 97 (lock_cxy == DEBUG_QUEUELOCK_CXY ) ) 94 98 printk("\n[%s] thread[%x,%x] BLOCK on q_lock %s [%x,%x]\n", 95 99 __FUNCTION__, this->process->pid, this->trdid, … … 117 121 118 122 #if DEBUG_QUEUELOCK_TYPE 119 if( (DEBUG_QUEUELOCK_TYPE == lock_type) || (DEBUG_QUEUELOCK_TYPE == 1000) ) 123 if( (lock_type == DEBUG_QUEUELOCK_TYPE) && 124 (lock_ptr == DEBUG_QUEUELOCK_PTR ) && 125 (lock_cxy == DEBUG_QUEUELOCK_CXY ) ) 120 126 printk("\n[%s] thread[%x,%x] ACQUIRE q_lock %s [%x,%x]\n", 121 127 __FUNCTION__, this->process->pid, this->trdid, … … 152 158 thread_t * this = CURRENT_THREAD; 153 159 uint32_t lock_type = hal_remote_l32( XPTR( lock_cxy , &lock_ptr->lock.type ) ); 154 if( (DEBUG_QUEUELOCK_TYPE == lock_type) || (DEBUG_QUEUELOCK_TYPE == 1000) ) 160 if( (lock_type == DEBUG_QUEUELOCK_TYPE) && 161 (lock_ptr == DEBUG_QUEUELOCK_PTR ) && 162 (lock_cxy == DEBUG_QUEUELOCK_CXY ) ) 155 163 printk("\n[%s] thread[%x,%x] RELEASE q_lock %s (%x,%x)\n", 156 164 __FUNCTION__, this->process->pid, this->trdid, … … 171 179 172 180 #if DEBUG_QUEUELOCK_TYPE 173 if( (DEBUG_QUEUELOCK_TYPE == lock_type) || (DEBUG_QUEUELOCK_TYPE == 1000) ) 181 if( (lock_type == DEBUG_QUEUELOCK_TYPE) && 182 (lock_ptr == DEBUG_QUEUELOCK_PTR ) && 183 (lock_cxy == DEBUG_QUEUELOCK_CXY ) ) 174 184 { 175 185 trdid_t trdid = hal_remote_l32( XPTR( thread_cxy , &thread_ptr->trdid ) ); -
trunk/kernel/libk/remote_rwlock.c
r627 r629 55 55 #if DEBUG_RWLOCK_TYPE 56 56 thread_t * this = CURRENT_THREAD; 57 if( DEBUG_RWLOCK_TYPE == type ) 57 if( (type == DEBUG_RWLOCK_TYPE) && 58 ((intptr_t)lock_ptr == DEBUG_RWLOCK_PTR ) && 59 (lock_cxy == DEBUG_RWLOCK_CXY ) ) 58 60 printk("\n[%s] thread[%x,%x] initialise lock %s [%x,%x]\n", 59 61 __FUNCTION__, this->process->pid, this->trdid, … … 93 95 94 96 #if DEBUG_RWLOCK_TYPE 95 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 97 if( (lock_type == DEBUG_RWLOCK_TYPE) && 98 ((intptr_t)lock_ptr == DEBUG_RWLOCK_PTR ) && 99 (lock_cxy == DEBUG_RWLOCK_CXY ) ) 96 100 printk("\n[%s] thread[%x,%x] READ BLOCK on rwlock %s [%x,%x] / taken %d / count %d\n", 97 101 __FUNCTION__, this->process->pid, this->trdid, … … 124 128 125 129 #if DEBUG_RWLOCK_TYPE 126 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 127 printk("\n[%s] thread[%x,%x] READ ACQUIRE rwlock %s [%x,%x] / taken = %d / count = %d\n", 130 if( (lock_type == DEBUG_RWLOCK_TYPE) && 131 ((intptr_t)lock_ptr == DEBUG_RWLOCK_PTR ) && 132 (lock_cxy == DEBUG_RWLOCK_CXY ) ) 133 printk("\n[%s] thread[%x,%x] READ ACQUIRE rwlock %s [%x,%x] / taken %d / count %d\n", 128 134 __FUNCTION__, this->process->pid, this->trdid, 129 135 lock_type_str[lock_type], lock_cxy, lock_ptr, … … 166 172 167 173 #if DEBUG_RWLOCK_TYPE 168 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 174 if( (lock_type == DEBUG_RWLOCK_TYPE) && 175 ((intptr_t)lock_ptr == DEBUG_RWLOCK_PTR ) && 176 (lock_cxy == DEBUG_RWLOCK_CXY ) ) 169 177 printk("\n[%s] thread[%x,%x] WRITE BLOCK on rwlock %s [%x,%x] / taken %d / count %d\n", 170 178 __FUNCTION__, this->process->pid, this->trdid, … … 196 204 197 205 #if DEBUG_RWLOCK_TYPE 198 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 206 if( (lock_type == DEBUG_RWLOCK_TYPE) && 207 ((intptr_t)lock_ptr == DEBUG_RWLOCK_PTR ) && 208 (lock_cxy == DEBUG_RWLOCK_CXY ) ) 199 209 printk("\n[%s] thread[%x,%x] WRITE ACQUIRE rwlock %s [%x,%x] / taken %d / count %d\n", 200 210 __FUNCTION__, this->process->pid, this->trdid, … … 235 245 uint32_t lock_type = hal_remote_l32( XPTR( lock_cxy , &lock_ptr->lock.type ) ); 236 246 xptr_t taken_xp = XPTR( lock_cxy , &lock_ptr->taken ); 237 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 247 if( (lock_type == DEBUG_RWLOCK_TYPE) && 248 ((intptr_t)lock_ptr == DEBUG_RWLOCK_PTR ) && 249 (lock_cxy == DEBUG_RWLOCK_CXY ) ) 238 250 printk("\n[%s] thread[%x,%x] READ RELEASE rwlock %s [%x,%x] / taken %d / count %d\n", 239 251 __FUNCTION__, this->process->pid, this->trdid, … … 258 270 259 271 #if DEBUG_RWLOCK_TYPE 260 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 272 if( (lock_type == DEBUG_RWLOCK_TYPE) && 273 ((intptr_t)lock_ptr == DEBUG_RWLOCK_PTR ) && 274 (lock_cxy == DEBUG_RWLOCK_CXY ) ) 261 275 { 262 276 trdid_t trdid = hal_remote_l32( XPTR( thread_cxy , &thread_ptr->trdid ) ); … … 289 303 290 304 #if DEBUG_RWLOCK_TYPE 291 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 305 if( (lock_type == DEBUG_RWLOCK_TYPE) && 306 ((intptr_t)lock_ptr == DEBUG_RWLOCK_PTR ) && 307 (lock_cxy == DEBUG_RWLOCK_CXY ) ) 292 308 { 293 309 trdid_t trdid = hal_remote_l32( XPTR( thread_cxy , &thread_ptr->trdid ) ); … … 334 350 uint32_t lock_type = hal_remote_l32( XPTR( lock_cxy , &lock_ptr->lock.type ) ); 335 351 xptr_t count_xp = XPTR( lock_cxy , &lock_ptr->count ); 336 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 352 if( (lock_type == DEBUG_RWLOCK_TYPE) && 353 ((intptr_t)lock_ptr == DEBUG_RWLOCK_PTR ) && 354 (lock_cxy == DEBUG_RWLOCK_CXY ) ) 337 355 printk("\n[%s] thread[%x,%x] WRITE RELEASE rwlock %s [%x,%x] / taken %d / count %d\n", 338 356 __FUNCTION__, this->process->pid, this->trdid, … … 356 374 357 375 #if DEBUG_RWLOCK_TYPE 358 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 376 if( (lock_type == DEBUG_RWLOCK_TYPE) && 377 ((intptr_t)lock_ptr == DEBUG_RWLOCK_PTR ) && 378 (lock_cxy == DEBUG_RWLOCK_CXY ) ) 359 379 { 360 380 trdid_t trdid = hal_remote_l32( XPTR( thread_cxy , &thread_ptr->trdid ) ); … … 386 406 387 407 #if DEBUG_RWLOCK_TYPE 388 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 408 if( (lock_type == DEBUG_RWLOCK_TYPE) && 409 ((intptr_t)lock_ptr == DEBUG_RWLOCK_PTR ) && 410 (lock_cxy == DEBUG_RWLOCK_CXY ) ) 389 411 { 390 412 trdid_t trdid = hal_remote_l32( XPTR( thread_cxy , &thread_ptr->trdid ) ); -
trunk/kernel/libk/remote_rwlock.h
r627 r629 42 42 * taken, or if the number of readers is non zero, it registers in the "wr_root" waiting 43 43 * queue, blocks, and deschedules. It set "taken" otherwise. 44 * - when a reader completes its access, it decrement the readers "count", unblock the44 * - when a reader completes its access, it decrement the readers "count", unblock 45 45 * the first waiting writer if there is no other readers, and unblock all waiting 46 46 * readers if there no write request. -
trunk/kernel/libk/rwlock.c
r623 r629 2 2 * rwlock.c - kernel local read/write lock implementation. 3 3 * 4 * Author Alain Greiner (2016,2017,2018 )4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 52 52 #if DEBUG_RWLOCK_TYPE 53 53 thread_t * this = CURRENT_THREAD; 54 if( DEBUG_RWLOCK_TYPE == type ) 54 if( (type == DEBUG_RWLOCK_TYPE) && 55 ((intptr_t)lock == DEBUG_RWLOCK_PTR ) && 56 (local_cxy == DEBUG_RWLOCK_CXY ) ) 55 57 printk("\n[%s] thread[%x,%x] initialise lock %s [%x,%x]\n", 56 58 __FUNCTION__, this->process->pid, this->trdid, … … 80 82 81 83 #if DEBUG_RWLOCK_TYPE 82 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 84 if( (lock_type == DEBUG_RWLOCK_TYPE) && 85 ((intptr_t)lock == DEBUG_RWLOCK_PTR ) && 86 (local_cxy == DEBUG_RWLOCK_CXY ) ) 83 87 printk("\n[%s] thread[%x,%x] READ BLOCK on rwlock %s [%x,%x] / taken %d / count %d\n", 84 88 __FUNCTION__, this->process->pid, this->trdid, … … 105 109 106 110 #if DEBUG_RWLOCK_TYPE 107 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 111 if( (lock_type == DEBUG_RWLOCK_TYPE) && 112 ((intptr_t)lock == DEBUG_RWLOCK_PTR ) && 113 (local_cxy == DEBUG_RWLOCK_CXY ) ) 108 114 printk("\n[%s] thread[%x,%x] READ ACQUIRE rwlock %s [%x,%x] / taken %d / count %d\n", 109 115 __FUNCTION__, this->process->pid, this->trdid, … … 136 142 137 143 #if DEBUG_RWLOCK_TYPE 138 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 144 if( (lock_type == DEBUG_RWLOCK_TYPE) && 145 ((intptr_t)lock == DEBUG_RWLOCK_PTR ) && 146 (local_cxy == DEBUG_RWLOCK_CXY ) ) 139 147 printk("\n[%s] thread[%x,%x] WRITE BLOCK on rwlock %s [%x,%x] / taken %d / count %d\n", 140 148 __FUNCTION__, this->process->pid, this->trdid, … … 161 169 162 170 #if DEBUG_RWLOCK_TYPE 163 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 171 if( (lock_type == DEBUG_RWLOCK_TYPE) && 172 ((intptr_t)lock == DEBUG_RWLOCK_PTR ) && 173 (local_cxy == DEBUG_RWLOCK_CXY ) ) 164 174 printk("\n[%s] thread[%x,%x] WRITE ACQUIRE rwlock %s [%x,%x] / taken %d / count %d\n", 165 175 __FUNCTION__, this->process->pid, this->trdid, … … 187 197 thread_t * this = CURRENT_THREAD; 188 198 uint32_t lock_type = lock->lock.type; 189 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 199 if( (lock_type == DEBUG_RWLOCK_TYPE) && 200 ((intptr_t)lock == DEBUG_RWLOCK_PTR ) && 201 (local_cxy == DEBUG_RWLOCK_CXY ) ) 190 202 printk("\n[%s] thread[%x,%x] READ RELEASE rwlock %s [%x,%x] / taken %d / count %d\n", 191 203 __FUNCTION__, this->process->pid, this->trdid, … … 201 213 202 214 #if DEBUG_RWLOCK_TYPE 203 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 215 if( (lock_type == DEBUG_RWLOCK_TYPE) && 216 ((intptr_t)lock == DEBUG_RWLOCK_PTR ) && 217 (local_cxy == DEBUG_RWLOCK_CXY ) ) 204 218 printk("\n[%s] thread[%x,%x] UNBLOCK thread[%x,%x] / rwlock %s [%x,%x]\n", 205 219 __FUNCTION__, this->process->pid, this->trdid, thread->process->pid, thread->trdid, … … 223 237 224 238 #if DEBUG_RWLOCK_TYPE 225 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 239 if( (lock_type == DEBUG_RWLOCK_TYPE) && 240 ((intptr_t)lock == DEBUG_RWLOCK_PTR ) && 241 (local_cxy == DEBUG_RWLOCK_CXY ) ) 226 242 printk("\n[%s] thread[%x,%x] UNBLOCK thread[%x,%x] / rwlock %s [%x,%x]\n", 227 243 __FUNCTION__, this->process->pid, this->trdid, thread->process->pid, thread->trdid, … … 257 273 thread_t * this = CURRENT_THREAD; 258 274 uint32_t lock_type = lock->lock.type; 259 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 275 if( (lock_type == DEBUG_RWLOCK_TYPE) && 276 ((intptr_t)lock == DEBUG_RWLOCK_PTR ) && 277 (local_cxy == DEBUG_RWLOCK_CXY ) ) 260 278 printk("\n[%s] thread[%x,%x] WRITE RELEASE rwlock %s [%x,%x] / taken %d / count %d\n", 261 279 __FUNCTION__, this->process->pid, this->trdid, … … 270 288 271 289 #if DEBUG_RWLOCK_TYPE 272 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 290 if( (lock_type == DEBUG_RWLOCK_TYPE) && 291 ((intptr_t)lock == DEBUG_RWLOCK_PTR ) && 292 (local_cxy == DEBUG_RWLOCK_CXY ) ) 273 293 printk("\n[%s] thread[%x,%x] UNBLOCK thread[%x,%x] / rwlock %s [%x,%x]\n", 274 294 __FUNCTION__, this->process->pid, this->trdid, thread->process->pid, thread->trdid, … … 291 311 292 312 #if DEBUG_RWLOCK_TYPE 293 if( (DEBUG_RWLOCK_TYPE == lock_type) || (DEBUG_RWLOCK_TYPE == 1000) ) 313 if( (lock_type == DEBUG_RWLOCK_TYPE) && 314 ((intptr_t)lock == DEBUG_RWLOCK_PTR ) && 315 (local_cxy == DEBUG_RWLOCK_CXY ) ) 294 316 printk("\n[%s] thread[%x,%x] UNBLOCK thread[%x,%x] / rwlock %s [%x,%x]\n", 295 317 __FUNCTION__, this->process->pid, this->trdid, thread->process->pid, thread->trdid, -
trunk/kernel/libk/user_dir.c
r619 r629 2 2 * user_dir.c - kernel DIR related operations implementation. 3 3 * 4 * Authors Alain Greiner (2016,2017,2018 )4 * Authors Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 91 91 pid_t ref_pid; // reference process PID 92 92 xptr_t gpt_xp; // extended pointer on reference process GPT 93 uint32_t gpt_attributes; // attributes for all mapped gptentries93 uint32_t attr; // attributes for all GPT entries 94 94 uint32_t dirents_per_page; // number of dirent descriptors per page 95 95 xptr_t page_xp; // extended pointer on page descriptor … … 99 99 uint32_t total_dirents; // total number of dirents in dirent array 100 100 uint32_t total_pages; // total number of pages for dirent array 101 vpn_t vpn; // first page in dirent array vseg 101 vpn_t vpn_base; // first page in dirent array vseg 102 vpn_t vpn; // current page in dirent array vseg 102 103 ppn_t ppn; // ppn of currently allocated physical page 103 104 uint32_t entries; // number of dirent actually comied in one page … … 107 108 uint32_t page_id; // page index in list of physical pages 108 109 kmem_req_t req; // kmem request descriptor 110 ppn_t fake_ppn; // unused, but required by hal_gptlock_pte() 111 uint32_t fake_attr; // unused, but required by hal_gptlock_pte() 109 112 error_t error; 110 113 111 // get cluster, local pointer, and pid of reference userprocess114 // get cluster, local pointer, and pid of reference process 112 115 ref_cxy = GET_CXY( ref_xp ); 113 116 ref_ptr = GET_PTR( ref_xp ); … … 256 259 "unconsistent vseg size for dirent array" ); 257 260 258 // build extended pointer on reference process GPT , PTE attributes and ppn261 // build extended pointer on reference process GPT 259 262 gpt_xp = XPTR( ref_cxy , &ref_ptr->vmm.gpt ); 260 gpt_attributes = GPT_MAPPED | 261 GPT_SMALL | 262 GPT_READABLE | 263 GPT_CACHABLE | 264 GPT_USER ; 263 264 // build PTE attributes 265 attr = GPT_MAPPED | 266 GPT_SMALL | 267 GPT_READABLE | 268 GPT_CACHABLE | 269 GPT_USER ; 265 270 266 271 // get first vpn from vseg descriptor 267 vpn = hal_remote_l32( XPTR( ref_cxy , &vseg->vpn_base ) );272 vpn_base = hal_remote_l32( XPTR( ref_cxy , &vseg->vpn_base ) ); 268 273 269 274 // scan the list of allocated physical pages to map 270 // all physical pages in the in thereference process GPT275 // all physical pages in the reference process GPT 271 276 page_id = 0; 272 277 while( list_is_empty( &root ) == false ) … … 277 282 // compute ppn 278 283 ppn = ppm_page2ppn( XPTR( local_cxy , page ) ); 284 285 // compute vpn 286 vpn = vpn_base + page_id; 279 287 280 error = hal_gpt_set_pte( gpt_xp, 281 vpn + page_id, 282 gpt_attributes, 283 ppn ); 288 // lock the PTE (and create PT2 if required) 289 error = hal_gpt_lock_pte( gpt_xp, 290 vpn, 291 &fake_attr, 292 &fake_ppn ); 284 293 if( error ) 285 294 { 286 295 printk("\n[ERROR] in %s : cannot map vpn %x in GPT\n", 287 __FUNCTION__, (vpn + page_id));296 __FUNCTION__, vpn ); 288 297 289 298 // delete the vseg 290 if( ref_cxy == local_cxy) vmm_delete_vseg( ref_pid, vpn<<CONFIG_PPM_PAGE_SHIFT ); 291 else rpc_vmm_delete_vseg_client( ref_cxy, ref_pid, vpn<<CONFIG_PPM_PAGE_SHIFT ); 299 if( ref_cxy == local_cxy) 300 vmm_delete_vseg( ref_pid, vpn_base << CONFIG_PPM_PAGE_SHIFT ); 301 else 302 rpc_vmm_delete_vseg_client( ref_cxy, ref_pid, vpn_base << CONFIG_PPM_PAGE_SHIFT ); 292 303 293 304 // release the user_dir descriptor … … 298 309 } 299 310 311 // set PTE in GPT 312 hal_gpt_set_pte( gpt_xp, 313 vpn, 314 attr, 315 ppn ); 316 300 317 #if DEBUG_USER_DIR 301 318 if( cycle > DEBUG_USER_DIR ) … … 317 334 dir->current = 0; 318 335 dir->entries = total_dirents; 319 dir->ident = (intptr_t)(vpn << CONFIG_PPM_PAGE_SHIFT);336 dir->ident = (intptr_t)(vpn_base << CONFIG_PPM_PAGE_SHIFT); 320 337 321 338 // build extended pointers on root and lock of user_dir xlist in ref process -
trunk/kernel/libk/user_dir.h
r623 r629 2 2 * user_dir.h - DIR related operations definition. 3 3 * 4 * Authors Alain Greiner (2016,2017,2018 )4 * Authors Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites -
trunk/kernel/mm/vmm.c
r625 r629 741 741 child_vmm = &child_process->vmm; 742 742 743 // initialize the locks protecting the child VSL and GPT 744 remote_rwlock_init( XPTR( local_cxy , &child_vmm->gpt_lock ) , LOCK_VMM_GPT ); 743 // initialize the lock protecting the child VSL 745 744 remote_rwlock_init( XPTR( local_cxy , &child_vmm->vsl_lock ) , LOCK_VMM_VSL ); 746 745 … … 952 951 xptr_t vsl_root_xp = XPTR( local_cxy , &vmm->vsegs_root ); 953 952 xptr_t vsl_lock_xp = XPTR( local_cxy , &vmm->vsl_lock ); 954 xptr_t gpt_lock_xp = XPTR( local_cxy , &vmm->gpt_lock );955 953 956 954 // take the VSL lock … … 1022 1020 } 1023 1021 1024 // take the GPT lock1025 remote_rwlock_wr_acquire( gpt_lock_xp );1026 1027 1022 // release memory allocated to the GPT itself 1028 1023 hal_gpt_destroy( &vmm->gpt ); 1029 1030 // release the GPT lock1031 remote_rwlock_wr_release( gpt_lock_xp );1032 1024 1033 1025 #if DEBUG_VMM_DESTROY … … 1226 1218 { 1227 1219 vmm_t * vmm; // local pointer on process VMM 1220 xptr_t gpt_xp; // extended pointer on GPT 1228 1221 bool_t is_ref; // local process is reference process 1229 1222 uint32_t vseg_type; // vseg type … … 1250 1243 vmm = &process->vmm; 1251 1244 1245 // build extended pointer on GPT 1246 gpt_xp = XPTR( local_cxy , &vmm->gpt ); 1247 1252 1248 // get relevant vseg infos 1253 1249 vseg_type = vseg->type; … … 1268 1264 { 1269 1265 // get ppn and attr 1270 hal_gpt_get_pte( XPTR( local_cxy , &vmm->gpt ), vpn , &attr , &ppn );1266 hal_gpt_get_pte( gpt_xp , vpn , &attr , &ppn ); 1271 1267 1272 1268 if( attr & GPT_MAPPED ) // PTE is mapped … … 1278 1274 #endif 1279 1275 // unmap GPT entry in local GPT 1280 hal_gpt_reset_pte( &vmm->gpt, vpn );1276 hal_gpt_reset_pte( gpt_xp , vpn ); 1281 1277 1282 1278 // get pointers on physical page descriptor … … 1915 1911 { 1916 1912 vseg_t * vseg; // vseg containing vpn 1917 uint32_t new_attr; // newPTE_ATTR value1918 ppn_t new_ppn; // newPTE_PPN value1913 uint32_t attr; // PTE_ATTR value 1914 ppn_t ppn; // PTE_PPN value 1919 1915 uint32_t ref_attr; // PTE_ATTR value in reference GPT 1920 1916 ppn_t ref_ppn; // PTE_PPN value in reference GPT … … 1922 1918 process_t * ref_ptr; // reference process for missing vpn 1923 1919 xptr_t local_gpt_xp; // extended pointer on local GPT 1924 xptr_t local_lock_xp; // extended pointer on local GPT lock1925 1920 xptr_t ref_gpt_xp; // extended pointer on reference GPT 1926 xptr_t ref_lock_xp; // extended pointer on reference GPT lock1927 1921 error_t error; // value returned by called functions 1928 1922 1923 thread_t * this = CURRENT_THREAD; 1924 1925 #if (CONFIG_INSTRUMENTATION_PGFAULTS || DEBUG_VMM_HANDLE_PAGE_FAULT) 1926 uint32_t start_cycle = (uint32_t)hal_get_cycles(); 1927 #endif 1928 1929 1929 #if DEBUG_VMM_HANDLE_PAGE_FAULT 1930 uint32_t cycle = (uint32_t)hal_get_cycles(); 1931 thread_t * this = CURRENT_THREAD; 1932 if( DEBUG_VMM_HANDLE_PAGE_FAULT < cycle ) 1930 if( DEBUG_VMM_HANDLE_PAGE_FAULT < start_cycle ) 1933 1931 printk("\n[%s] thread[%x,%x] enter for vpn %x / cycle %d\n", 1934 __FUNCTION__, this->process->pid, this->trdid, vpn, cycle ); 1935 hal_vmm_display( process , true ); 1932 __FUNCTION__, this->process->pid, this->trdid, vpn, start_cycle ); 1933 #endif 1934 1935 #if (DEBUG_VMM_HANDLE_PAGE_FAULT & 1) 1936 hal_vmm_display( this->process , false ); 1936 1937 #endif 1937 1938 … … 1942 1943 if( error ) 1943 1944 { 1944 printk("\n[ERROR] in %s : vpn %x in process %x not in registered vseg / cycle %d\n",1945 __FUNCTION__ , vpn , process->pid, (uint32_t)hal_get_cycles());1945 printk("\n[ERROR] in %s : vpn %x in thread[%x,%x] not in registered vseg\n", 1946 __FUNCTION__ , vpn , process->pid, this->trdid ); 1946 1947 1947 1948 return EXCP_USER_ERROR; … … 1949 1950 1950 1951 #if DEBUG_VMM_HANDLE_PAGE_FAULT 1951 cycle = (uint32_t)hal_get_cycles(); 1952 if( DEBUG_VMM_HANDLE_PAGE_FAULT < cycle ) 1953 printk("\n[%s] threadr[%x,%x] found vseg %s / cycle %d\n", 1954 __FUNCTION__, this->process->pid, this->trdid, vseg_type_str(vseg->type), cycle ); 1955 #endif 1956 1957 //////////////// private vseg => access only the local GPT 1958 if( (vseg->type == VSEG_TYPE_STACK) || (vseg->type == VSEG_TYPE_CODE) ) 1959 { 1960 // build extended pointer on local GPT and local GPT lock 1961 local_gpt_xp = XPTR( local_cxy , &process->vmm.gpt ); 1962 local_lock_xp = XPTR( local_cxy , &process->vmm.gpt_lock ); 1963 1964 // take local GPT lock in write mode 1965 remote_rwlock_wr_acquire( local_lock_xp ); 1966 1967 // check VPN still unmapped in local GPT 1968 1969 // do nothing if VPN has been mapped by a a concurrent page_fault 1970 hal_gpt_get_pte( local_gpt_xp, 1971 vpn, 1972 &new_attr, 1973 &new_ppn ); 1974 1975 if( (new_attr & GPT_MAPPED) == 0 ) // VPN still unmapped 1976 { 1977 // allocate and initialise a physical page depending on the vseg type 1978 error = vmm_get_one_ppn( vseg , vpn , &new_ppn ); 1979 1980 if( error ) 1981 { 1982 printk("\n[ERROR] in %s : no memory / process = %x / vpn = %x\n", 1983 __FUNCTION__ , process->pid , vpn ); 1984 1985 // release local GPT lock in write mode 1986 remote_rwlock_wr_release( local_lock_xp ); 1987 1988 return EXCP_KERNEL_PANIC; 1989 } 1990 1991 // define new_attr from vseg flags 1992 new_attr = GPT_MAPPED | GPT_SMALL; 1993 if( vseg->flags & VSEG_USER ) new_attr |= GPT_USER; 1994 if( vseg->flags & VSEG_WRITE ) new_attr |= GPT_WRITABLE; 1995 if( vseg->flags & VSEG_EXEC ) new_attr |= GPT_EXECUTABLE; 1996 if( vseg->flags & VSEG_CACHE ) new_attr |= GPT_CACHABLE; 1997 1998 // set PTE (PPN & attribute) to local GPT 1999 error = hal_gpt_set_pte( local_gpt_xp, 2000 vpn, 2001 new_attr, 2002 new_ppn ); 2003 if ( error ) 2004 { 2005 printk("\n[ERROR] in %s : cannot update local GPT / process %x / vpn = %x\n", 2006 __FUNCTION__ , process->pid , vpn ); 2007 2008 // release local GPT lock in write mode 2009 remote_rwlock_wr_release( local_lock_xp ); 2010 2011 return EXCP_KERNEL_PANIC; 2012 } 2013 } 2014 2015 // release local GPT lock in write mode 2016 remote_rwlock_wr_release( local_lock_xp ); 2017 2018 #if DEBUG_VMM_HANDLE_PAGE_FAULT 2019 cycle = (uint32_t)hal_get_cycles(); 2020 if( DEBUG_VMM_HANDLE_PAGE_FAULT < cycle ) 2021 printk("\n[%s] private page fault handled / vpn %x / ppn %x / attr %x / cycle %d\n", 2022 __FUNCTION__, vpn, new_ppn, new_attr, cycle ); 2023 #endif 2024 return EXCP_NON_FATAL; 2025 2026 } // end local GPT access 2027 2028 //////////// public vseg => access reference GPT 2029 else 1952 if( DEBUG_VMM_HANDLE_PAGE_FAULT < start_cycle ) 1953 printk("\n[%s] thread[%x,%x] found vseg %s\n", 1954 __FUNCTION__, this->process->pid, this->trdid, vseg_type_str(vseg->type) ); 1955 #endif 1956 1957 // build extended pointer on local GPT 1958 local_gpt_xp = XPTR( local_cxy , &process->vmm.gpt ); 1959 1960 // lock target PTE in local GPT and get current PPN and attributes 1961 error = hal_gpt_lock_pte( local_gpt_xp, 1962 vpn, 1963 &attr, 1964 &ppn ); 1965 if( error ) 1966 { 1967 printk("\n[PANIC] in %s : cannot lock PTE in local GPT / vpn %x / process %x\n", 1968 __FUNCTION__ , vpn , process->pid ); 1969 1970 return EXCP_KERNEL_PANIC; 1971 } 1972 1973 // handle page fault only if PTE still unmapped after lock 1974 if( (attr & GPT_MAPPED) == 0 ) 2030 1975 { 2031 1976 // get reference process cluster and local pointer … … 2033 1978 ref_ptr = GET_PTR( process->ref_xp ); 2034 1979 2035 // build extended pointer on reference GPT and reference GPT lock 2036 ref_gpt_xp = XPTR( ref_cxy , &ref_ptr->vmm.gpt ); 2037 ref_lock_xp = XPTR( ref_cxy , &ref_ptr->vmm.gpt_lock ); 2038 2039 // build extended pointer on local GPT and local GPT lock 2040 local_gpt_xp = XPTR( local_cxy , &process->vmm.gpt ); 2041 local_lock_xp = XPTR( local_cxy , &process->vmm.gpt_lock ); 2042 2043 // take reference GPT lock in read mode 2044 remote_rwlock_rd_acquire( ref_lock_xp ); 2045 2046 // get directly PPN & attributes from reference GPT 2047 // this can avoids a costly RPC for a false page fault 2048 hal_gpt_get_pte( ref_gpt_xp, 2049 vpn, 2050 &ref_attr, 2051 &ref_ppn ); 2052 2053 // release reference GPT lock in read mode 2054 remote_rwlock_rd_release( ref_lock_xp ); 2055 2056 if( ref_attr & GPT_MAPPED ) // false page fault => update local GPT 1980 // private vseg or (local == reference) => access only the local GPT 1981 if( (vseg->type == VSEG_TYPE_STACK) || 1982 (vseg->type == VSEG_TYPE_CODE) || 1983 (ref_cxy == local_cxy ) ) 2057 1984 { 2058 // take local GPT lock in write mode 2059 remote_rwlock_wr_acquire( local_lock_xp ); 2060 2061 // check VPN still unmapped in local GPT 2062 hal_gpt_get_pte( local_gpt_xp, 1985 // allocate and initialise a physical page depending on the vseg type 1986 error = vmm_get_one_ppn( vseg , vpn , &ppn ); 1987 1988 if( error ) 1989 { 1990 printk("\n[ERROR] in %s : no physical page / process = %x / vpn = %x\n", 1991 __FUNCTION__ , process->pid , vpn ); 1992 1993 // unlock PTE in local GPT 1994 hal_gpt_unlock_pte( local_gpt_xp , vpn ); 1995 1996 return EXCP_KERNEL_PANIC; 1997 } 1998 1999 // define attr from vseg flags 2000 attr = GPT_MAPPED | GPT_SMALL; 2001 if( vseg->flags & VSEG_USER ) attr |= GPT_USER; 2002 if( vseg->flags & VSEG_WRITE ) attr |= GPT_WRITABLE; 2003 if( vseg->flags & VSEG_EXEC ) attr |= GPT_EXECUTABLE; 2004 if( vseg->flags & VSEG_CACHE ) attr |= GPT_CACHABLE; 2005 2006 // set PTE to local GPT 2007 hal_gpt_set_pte( local_gpt_xp, 2063 2008 vpn, 2064 &new_attr, 2065 &new_ppn ); 2066 2067 if( (new_attr & GPT_MAPPED) == 0 ) // VPN still unmapped 2068 { 2069 // update local GPT from reference GPT 2070 error = hal_gpt_set_pte( local_gpt_xp, 2071 vpn, 2072 ref_attr, 2073 ref_ppn ); 2074 if( error ) 2075 { 2076 printk("\n[ERROR] in %s : cannot update local GPT / process %x / vpn %x\n", 2077 __FUNCTION__ , process->pid , vpn ); 2078 2079 // release local GPT lock in write mode 2080 remote_rwlock_wr_release( local_lock_xp ); 2081 2082 return EXCP_KERNEL_PANIC; 2083 } 2084 } 2085 else // VPN has been mapped by a a concurrent page_fault 2086 { 2087 // keep PTE from local GPT 2088 ref_attr = new_attr; 2089 ref_ppn = new_ppn; 2090 } 2091 2092 // release local GPT lock in write mode 2093 remote_rwlock_wr_release( local_lock_xp ); 2094 2009 attr, 2010 ppn ); 2011 2012 #if (CONFIG_INSTRUMENTATION_PGFAULTS || DEBUG_VMM_HANDLE_PAGE_FAULT) 2013 uint32_t end_cycle = (uint32_t)hal_get_cycles(); 2014 #endif 2015 2095 2016 #if DEBUG_VMM_HANDLE_PAGE_FAULT 2096 cycle = (uint32_t)hal_get_cycles(); 2097 if( DEBUG_VMM_HANDLE_PAGE_FAULT < cycle ) 2098 printk("\n[%s] false page fault handled / vpn %x / ppn %x / attr %x / cycle %d\n", 2099 __FUNCTION__, vpn, ref_ppn, ref_attr, cycle ); 2017 if( DEBUG_VMM_HANDLE_PAGE_FAULT < end_cycle ) 2018 printk("\n[%s] local page fault handled / vpn %x / ppn %x / attr %x / cycle %d\n", 2019 __FUNCTION__, vpn, ppn, attr, end_cycle ); 2020 #endif 2021 2022 #if CONFIG_INSTRUMENTATION_PGFAULTS 2023 this->info.local_pgfault_nr++; 2024 this->info.local_pgfault_cost += (end_cycle - start_cycle); 2100 2025 #endif 2101 2026 return EXCP_NON_FATAL; 2102 } 2103 else // true page fault => update reference GPT 2027 2028 } // end local GPT access 2029 2030 // public vseg and (local != reference) => access ref GPT to update local GPT 2031 else 2104 2032 { 2105 // take reference GPT lock in write mode 2106 remote_rwlock_wr_acquire( ref_lock_xp ); 2107 2108 // check VPN still unmapped in reference GPT 2109 // do nothing if VPN has been mapped by a a concurrent page_fault 2033 // build extended pointer on reference GPT 2034 ref_gpt_xp = XPTR( ref_cxy , &ref_ptr->vmm.gpt ); 2035 2036 // get current PPN and attributes from reference GPT 2110 2037 hal_gpt_get_pte( ref_gpt_xp, 2111 2038 vpn, … … 2113 2040 &ref_ppn ); 2114 2041 2115 if( (ref_attr & GPT_MAPPED) == 0 ) // VPN actually unmapped 2116 { 2042 if( ref_attr & GPT_MAPPED ) // false page fault => update local GPT 2043 { 2044 // update local GPT from reference GPT values 2045 hal_gpt_set_pte( local_gpt_xp, 2046 vpn, 2047 ref_attr, 2048 ref_ppn ); 2049 2050 #if (CONFIG_INSTRUMENTATION_PGFAULTS || DEBUG_VMM_HANDLE_PAGE_FAULT) 2051 uint32_t end_cycle = (uint32_t)hal_get_cycles(); 2052 #endif 2053 2054 #if DEBUG_VMM_HANDLE_PAGE_FAULT 2055 if( DEBUG_VMM_HANDLE_PAGE_FAULT < end_cycle ) 2056 printk("\n[%s] false page fault handled / vpn %x / ppn %x / attr %x / cycle %d\n", 2057 __FUNCTION__, vpn, ref_ppn, ref_attr, end_cycle ); 2058 #endif 2059 2060 #if CONFIG_INSTRUMENTATION_PGFAULTS 2061 this->info.false_pgfault_nr++; 2062 this->info.false_pgfault_cost += (end_cycle - start_cycle); 2063 #endif 2064 return EXCP_NON_FATAL; 2065 } 2066 else // true page fault => update both GPTs 2067 { 2117 2068 // allocate and initialise a physical page depending on the vseg type 2118 error = vmm_get_one_ppn( vseg , vpn , & new_ppn );2069 error = vmm_get_one_ppn( vseg , vpn , &ppn ); 2119 2070 2120 2071 if( error ) … … 2123 2074 __FUNCTION__ , process->pid , vpn ); 2124 2075 2125 // release reference GPT lock in write mode2126 remote_rwlock_wr_release( ref_lock_xp);2076 // unlock PTE in local GPT 2077 hal_gpt_unlock_pte( local_gpt_xp , vpn ); 2127 2078 2128 return EXCP_KERNEL_PANIC;2079 return EXCP_KERNEL_PANIC; 2129 2080 } 2130 2081 2131 // define new_attr from vseg flags 2132 new_attr = GPT_MAPPED | GPT_SMALL; 2133 if( vseg->flags & VSEG_USER ) new_attr |= GPT_USER; 2134 if( vseg->flags & VSEG_WRITE ) new_attr |= GPT_WRITABLE; 2135 if( vseg->flags & VSEG_EXEC ) new_attr |= GPT_EXECUTABLE; 2136 if( vseg->flags & VSEG_CACHE ) new_attr |= GPT_CACHABLE; 2137 2138 // update reference GPT 2139 error = hal_gpt_set_pte( ref_gpt_xp, 2140 vpn, 2141 new_attr, 2142 new_ppn ); 2143 2144 // update local GPT (protected by reference GPT lock) 2145 error |= hal_gpt_set_pte( local_gpt_xp, 2082 // lock PTE in reference GPT 2083 error = hal_gpt_lock_pte( ref_gpt_xp, 2146 2084 vpn, 2147 new_attr, 2148 new_ppn ); 2149 2085 &ref_attr, 2086 &ref_ppn ); 2150 2087 if( error ) 2151 2088 { 2152 printk("\n[ ERROR] in %s : cannot update GPT / process %x / vpn =%x\n",2153 __FUNCTION__ , process->pid , vpn);2154 2155 // release reference GPT lock in write mode2156 remote_rwlock_wr_release( ref_lock_xp);2157 2089 printk("\n[PANIC] in %s : cannot lock PTE in ref GPT / vpn %x / process %x\n", 2090 __FUNCTION__ , vpn , process->pid ); 2091 2092 // unlock PTE in local GPT 2093 hal_gpt_unlock_pte( local_gpt_xp , vpn ); 2094 2158 2095 return EXCP_KERNEL_PANIC; 2159 2096 } 2097 2098 // define attr from vseg flags 2099 attr = GPT_MAPPED | GPT_SMALL; 2100 if( vseg->flags & VSEG_USER ) attr |= GPT_USER; 2101 if( vseg->flags & VSEG_WRITE ) attr |= GPT_WRITABLE; 2102 if( vseg->flags & VSEG_EXEC ) attr |= GPT_EXECUTABLE; 2103 if( vseg->flags & VSEG_CACHE ) attr |= GPT_CACHABLE; 2104 2105 // set PTE in reference GPT 2106 hal_gpt_set_pte( ref_gpt_xp, 2107 vpn, 2108 attr, 2109 ppn ); 2110 2111 // set PTE in local GPT 2112 hal_gpt_set_pte( local_gpt_xp, 2113 vpn, 2114 attr, 2115 ppn ); 2116 2117 #if (CONFIG_INSTRUMENTATION_PGFAULTS || DEBUG_VMM_HANDLE_PAGE_FAULT) 2118 uint32_t end_cycle = (uint32_t)hal_get_cycles(); 2119 #endif 2120 2121 #if DEBUG_VMM_HANDLE_PAGE_FAULT 2122 if( DEBUG_VMM_HANDLE_PAGE_FAULT < end_cycle ) 2123 printk("\n[%s] global page fault handled / vpn %x / ppn %x / attr %x / cycle %d\n", 2124 __FUNCTION__, vpn, ppn, attr, end_cycle ); 2125 #endif 2126 2127 #if CONFIG_INSTRUMENTATION_PGFAULTS 2128 this->info.global_pgfault_nr++; 2129 this->info.global_pgfault_cost += (end_cycle - start_cycle); 2130 #endif 2131 return EXCP_NON_FATAL; 2160 2132 } 2161 2162 // release reference GPT lock in write mode2163 remote_rwlock_wr_release( ref_lock_xp );2164 2165 #if DEBUG_VMM_HANDLE_PAGE_FAULT2166 cycle = (uint32_t)hal_get_cycles();2167 if( DEBUG_VMM_HANDLE_PAGE_FAULT < cycle )2168 printk("\n[%s] true page fault handled / vpn %x / ppn %x / attr %x / cycle %d\n",2169 __FUNCTION__, vpn, new_ppn, new_attr, cycle );2170 #endif2171 return EXCP_NON_FATAL;2172 2133 } 2173 2134 } 2135 else // page has been locally mapped by another concurrent thread 2136 { 2137 // unlock PTE in local GPT 2138 hal_gpt_unlock_pte( local_gpt_xp , vpn ); 2139 2140 return EXCP_NON_FATAL; 2141 } 2142 2174 2143 } // end vmm_handle_page_fault() 2175 2144 … … 2179 2148 { 2180 2149 vseg_t * vseg; // vseg containing vpn 2181 cxy_t ref_cxy; // reference cluster for missing vpn 2182 process_t * ref_ptr; // reference process for missing vpn 2183 xptr_t gpt_xp; // extended pointer on GPT 2184 xptr_t gpt_lock_xp; // extended pointer on GPT lock 2150 xptr_t gpt_xp; // extended pointer on GPT (local or reference) 2151 gpt_t * gpt_ptr; // local pointer on GPT (local or reference) 2152 cxy_t gpt_cxy; // GPT cluster identifier 2185 2153 uint32_t old_attr; // current PTE_ATTR value 2186 2154 ppn_t old_ppn; // current PTE_PPN value 2187 2155 uint32_t new_attr; // new PTE_ATTR value 2188 2156 ppn_t new_ppn; // new PTE_PPN value 2157 cxy_t ref_cxy; // reference process cluster 2158 process_t * ref_ptr; // local pointer on reference process 2189 2159 error_t error; 2190 2160 2191 thread_t * this = CURRENT_THREAD;2161 thread_t * this = CURRENT_THREAD; 2192 2162 2193 2163 #if DEBUG_VMM_HANDLE_COW 2194 uint32_t cycle 2164 uint32_t cycle = (uint32_t)hal_get_cycles(); 2195 2165 if( DEBUG_VMM_HANDLE_COW < cycle ) 2196 2166 printk("\n[%s] thread[%x,%x] enter for vpn %x / core[%x,%d] / cycle %d\n", 2197 2167 __FUNCTION__, this->process->pid, this->trdid, vpn, local_cxy, this->core->lid, cycle ); 2168 #endif 2169 2170 #if (DEBUG_VMM_HANDLE_PAGE_FAULT & 1) 2198 2171 hal_vmm_display( process , true ); 2199 2172 #endif 2200 2201 // access local GPT to get GPT_COW flag2202 bool_t cow = hal_gpt_pte_is_cow( &(process->vmm.gpt), vpn );2203 2204 if( cow == false ) return EXCP_USER_ERROR;2205 2173 2206 2174 // get local vseg … … 2210 2178 if( error ) 2211 2179 { 2212 printk("\n[ PANIC] in %svpn %x in thread[%x,%x] not in a registered vseg\n",2180 printk("\n[ERROR] in %s : vpn %x in thread[%x,%x] not in a registered vseg\n", 2213 2181 __FUNCTION__, vpn, process->pid, this->trdid ); 2214 2182 2215 return EXCP_ KERNEL_PANIC;2216 } 2217 2218 #if ( DEBUG_VMM_HANDLE_COW & 1)2183 return EXCP_USER_ERROR; 2184 } 2185 2186 #if DEBUG_VMM_HANDLE_COW 2219 2187 if( DEBUG_VMM_HANDLE_COW < cycle ) 2220 printk("\n[%s] thread[%x,%x] get vseg for vpn %x\n",2221 __FUNCTION__, this->process->pid, this->trdid, v pn);2222 #endif 2223 2224 // get reference GPTcluster and local pointer2188 printk("\n[%s] thread[%x,%x] get vseg %s\n", 2189 __FUNCTION__, this->process->pid, this->trdid, vseg_type_str(vseg->type) ); 2190 #endif 2191 2192 // get reference process cluster and local pointer 2225 2193 ref_cxy = GET_CXY( process->ref_xp ); 2226 2194 ref_ptr = GET_PTR( process->ref_xp ); 2227 2195 2228 // build relevant extended pointers on relevant GPT and GPT lock2229 // - access local GPT for a private vseg2230 // - access reference GPT for a public vseg2196 // build pointers on relevant GPT 2197 // - access only local GPT for a private vseg 2198 // - access reference GPT and all copies for a public vseg 2231 2199 if( (vseg->type == VSEG_TYPE_STACK) || (vseg->type == VSEG_TYPE_CODE) ) 2232 2200 { 2233 gpt_xp = XPTR( local_cxy , &process->vmm.gpt ); 2234 gpt_lock_xp = XPTR( local_cxy , &process->vmm.gpt_lock ); 2201 gpt_cxy = local_cxy; 2202 gpt_ptr = &process->vmm.gpt; 2203 gpt_xp = XPTR( gpt_cxy , gpt_ptr ); 2235 2204 } 2236 2205 else 2237 2206 { 2238 gpt_xp = XPTR( ref_cxy , &ref_ptr->vmm.gpt ); 2239 gpt_lock_xp = XPTR( ref_cxy , &ref_ptr->vmm.gpt_lock ); 2240 } 2241 2242 // take GPT lock in write mode 2243 remote_rwlock_wr_acquire( gpt_lock_xp ); 2244 2245 // get current PTE from reference GPT 2246 hal_gpt_get_pte( gpt_xp, 2247 vpn, 2248 &old_attr, 2249 &old_ppn ); 2250 2251 #if( DEBUG_VMM_HANDLE_COW & 1) 2207 gpt_cxy = ref_cxy; 2208 gpt_ptr = &ref_ptr->vmm.gpt; 2209 gpt_xp = XPTR( gpt_cxy , gpt_ptr ); 2210 } 2211 2212 // lock target PTE in relevant GPT (local or reference) 2213 error = hal_gpt_lock_pte( gpt_xp, 2214 vpn, 2215 &old_attr, 2216 &old_ppn ); 2217 if( error ) 2218 { 2219 printk("\n[PANIC] in %s : cannot lock PTE in GPT / cxy %x / vpn %x / process %x\n", 2220 __FUNCTION__ , gpt_cxy, vpn , process->pid ); 2221 2222 return EXCP_KERNEL_PANIC; 2223 } 2224 2225 #if DEBUG_VMM_HANDLE_COW 2252 2226 if( DEBUG_VMM_HANDLE_COW < cycle ) 2253 2227 printk("\n[%s] thread[%x,%x] get pte for vpn %x : ppn %x / attr %x\n", … … 2255 2229 #endif 2256 2230 2257 // the PTE must be mapped for a COW 2258 if( (old_attr & GPT_MAPPED) == 0 ) 2259 { 2260 printk("\n[PANIC] in %s : VPN %x in process %x unmapped\n", 2261 __FUNCTION__, vpn, process->pid ); 2262 2263 // release GPT lock in write mode 2264 remote_rwlock_wr_release( gpt_lock_xp ); 2265 2266 return EXCP_KERNEL_PANIC; 2231 // return user error if COW attribute not set or PTE2 unmapped 2232 if( ((old_attr & GPT_COW) == 0) || ((old_attr & GPT_MAPPED) == 0) ) 2233 { 2234 hal_gpt_unlock_pte( gpt_xp , vpn ); 2235 2236 return EXCP_USER_ERROR; 2267 2237 } 2268 2238 … … 2282 2252 uint32_t forks = hal_remote_l32( forks_xp ); 2283 2253 2284 #if ( DEBUG_VMM_HANDLE_COW & 1)2254 #if DEBUG_VMM_HANDLE_COW 2285 2255 if( DEBUG_VMM_HANDLE_COW < cycle ) 2286 2256 printk("\n[%s] thread[%x,%x] get forks = %d for vpn %x\n", … … 2296 2266 remote_busylock_release( forks_lock_xp ); 2297 2267 2298 // allocate a new p age2268 // allocate a new physical page depending on vseg type 2299 2269 page_xp = vmm_page_allocate( vseg , vpn ); 2300 2270 … … 2304 2274 __FUNCTION__ , vpn, process->pid ); 2305 2275 2306 // release GPT lock in write mode 2307 remote_rwlock_wr_acquire( gpt_lock_xp ); 2276 hal_gpt_unlock_pte( gpt_xp , vpn ); 2308 2277 2309 2278 return EXCP_KERNEL_PANIC; … … 2313 2282 new_ppn = ppm_page2ppn( page_xp ); 2314 2283 2315 #if ( DEBUG_VMM_HANDLE_COW & 1)2284 #if DEBUG_VMM_HANDLE_COW 2316 2285 if( DEBUG_VMM_HANDLE_COW < cycle ) 2317 2286 printk("\n[%s] thread[%x,%x] get new ppn %x for vpn %x\n", … … 2324 2293 CONFIG_PPM_PAGE_SIZE ); 2325 2294 2326 #if (DEBUG_VMM_HANDLE_COW & 1)2295 #if DEBUG_VMM_HANDLE_COW 2327 2296 if( DEBUG_VMM_HANDLE_COW < cycle ) 2328 2297 printk("\n[%s] thread[%x,%x] copied old page to new page\n", … … 2344 2313 } 2345 2314 2346 // build new_attr : reset COW and set WRITABLE,2347 new_attr = ( old_attr | GPT_WRITABLE) & (~GPT_COW);2348 2349 // update the relevant GPT 2350 // - private vseg => update local GPT2351 // - public vseg => update allGPT copies2315 // build new_attr : set WRITABLE, reset COW, reset LOCKED 2316 new_attr = (((old_attr | GPT_WRITABLE) & (~GPT_COW)) & (~GPT_LOCKED)); 2317 2318 // update the relevant GPT(s) 2319 // - private vseg => update only the local GPT 2320 // - public vseg => update the reference GPT AND all the GPT copies 2352 2321 if( (vseg->type == VSEG_TYPE_STACK) || (vseg->type == VSEG_TYPE_CODE) ) 2353 2322 { 2323 // set the new PTE2 2354 2324 hal_gpt_set_pte( gpt_xp, 2355 2325 vpn, … … 2376 2346 } 2377 2347 2378 // release GPT lock in write mode2379 remote_rwlock_wr_release( gpt_lock_xp );2380 2381 2348 #if DEBUG_VMM_HANDLE_COW 2382 2349 cycle = (uint32_t)hal_get_cycles(); -
trunk/kernel/mm/vmm.h
r625 r629 106 106 * 3. The GPT in the reference cluster can be directly accessed by remote threads to handle 107 107 * false page-fault (page is mapped in the reference GPT, but the PTE copy is missing 108 * in the local GPT). It is also protected by a remote_rwlock. 108 * in the local GPT). As each PTE can be protected by a specific GPT_LOCKED attribute 109 * for exclusive access, it is NOT protected by a global lock. 109 110 ********************************************************************************************/ 110 111 … … 115 116 uint32_t vsegs_nr; /*! total number of local vsegs */ 116 117 117 remote_rwlock_t gpt_lock; /*! lock protecting the local GPT */118 118 gpt_t gpt; /*! Generic Page Table (complete in reference) */ 119 119 … … 165 165 * This function is called by the process_make_fork() function. It partially copies 166 166 * the content of a remote parent process VMM to the local child process VMM: 167 * - AllDATA, ANON, REMOTE vsegs registered in the parent VSL are registered in the167 * - The DATA, ANON, REMOTE vsegs registered in the parent VSL are registered in the 168 168 * child VSL. All valid PTEs in parent GPT are copied to the child GPT, but the 169 169 * WRITABLE flag is reset and the COW flag is set. 170 * - AllCODE vsegs registered in the parent VSL are registered in the child VSL, but the170 * - The CODE vsegs registered in the parent VSL are registered in the child VSL, but the 171 171 * GPT entries are not copied in the child GPT, and will be dynamically updated from 172 172 * the .elf file when a page fault is reported. 173 * - AllFILE vsegs registered in the parent VSL are registered in the child VSL, and all173 * - The FILE vsegs registered in the parent VSL are registered in the child VSL, and all 174 174 * valid GPT entries in parent GPT are copied to the child GPT. The COW flag is not set. 175 175 * - No STACK vseg is copied from parent VMM to child VMM, because the child stack vseg … … 186 186 187 187 /********************************************************************************************* 188 * This function is called by the process_make_fork() function executing the fork syscall.189 * It set the COW flag, and reset the WRITABLE flag of all GPT entries of the DATA, MMAP,190 * a nd REMOTE vsegs of a process identified bythe <process> argument.188 * This function is called by the process_make_fork() function to update the COW attribute 189 * in the parent parent process vsegs. It set the COW flag, and reset the WRITABLE flag of 190 * all GPT entries of the DATA, MMAP, and REMOTE vsegs of the <process> argument. 191 191 * It must be called by a thread running in the reference cluster, that contains the complete 192 192 * VSL and GPT (use the rpc_vmm_set_cow_client() when the calling thread client is remote). … … 201 201 202 202 /********************************************************************************************* 203 * This function modifies aGPT entry identified by the <process> and <vpn> arguments203 * This function modifies one GPT entry identified by the <process> and <vpn> arguments 204 204 * in all clusters containing a process copy. 205 * It must be called by a thread running in the referencecluster.206 * It updates all copies of the process in all clusters, to maintain coherence in GPT copies,207 * using the list of copies stored in the owner process, and using remote_write accesses to208 * update the remote GPTs. It cannot fail, as only mapped entriesin GPT copies are updated.205 * It must be called by a thread running in the process owner cluster. 206 * It is used to update to maintain coherence in GPT copies, using the list of copies 207 * stored in the owner process, and uses remote_write accesses. 208 * It cannot fail, as only mapped PTE2 in GPT copies are updated. 209 209 ********************************************************************************************* 210 210 * @ process : local pointer on local process descriptor. … … 373 373 * is mapped in the reference GPT, but not in the local GPT. For this false page-fault, 374 374 * the local GPT is simply updated from the reference GPT. 375 * 3) if the missing VPN is public, and unmapped in the ref erence GPT, it's a true page fault.375 * 3) if the missing VPN is public, and unmapped in the ref GPT, it is a true page fault. 376 376 * The calling thread allocates a new physical page, computes the attributes, depending 377 377 * on vseg type, and updates directly (without RPC) the local GPT and the reference GPT. 378 378 * Other GPT copies will updated on demand. 379 * Concurrent accesses to the GPT are handled, thanks to the380 * remote_rwlock protecting each GPT copy.379 * Concurrent accesses to the GPT(s) are handled, by locking the target PTE before accessing 380 * the local and/or reference GPT(s). 381 381 ********************************************************************************************* 382 382 * @ process : local pointer on local process. … … 392 392 * It returns a kernel panic if VPN is not in a registered vseg or is not mapped. 393 393 * For a legal mapped vseg there is two cases: 394 * 1) If the missing VPN belongs to a private vseg (STACK or CODE segment types, non 395 * replicated in all clusters), it access the local GPT to get the current PPN and ATTR. 394 * 1) If the missing VPN belongs to a private vseg (STACK), it access only the local GPT. 396 395 * It access the forks counter in the current physical page descriptor. 397 396 * If there is a pending fork, it allocates a new physical page from the cluster defined … … 399 398 * and decrements the pending_fork counter in old physical page descriptor. 400 399 * Finally, it reset the COW flag and set the WRITE flag in local GPT. 401 * 2) If the missing VPN is public, it access the reference GPT to get the current PPN and402 * ATTR.It access the forks counter in the current physical page descriptor.400 * 2) If the missing VPN is public, it access only the reference GPT. 401 * It access the forks counter in the current physical page descriptor. 403 402 * If there is a pending fork, it allocates a new physical page from the cluster defined 404 403 * by the vseg type, copies the old physical page content to the new physical page, … … 406 405 * Finally it calls the vmm_global_update_pte() function to reset the COW flag and set 407 406 * the WRITE flag in all the GPT copies, using a RPC if the reference cluster is remote. 408 * In both cases, concurrent accesses to the GPT are protected by the remote_rwlock409 * atached to the GPT copy in VMM.407 * In both cases, concurrent accesses to the GPT are handled by locking the target PTE 408 * before accessing the GPT. 410 409 ********************************************************************************************* 411 410 * @ process : pointer on local process descriptor copy. -
trunk/kernel/syscalls/sys_barrier.c
r626 r629 184 184 } 185 185 //////// 186 default: { 186 default: 187 { 187 188 assert ( false, "illegal operation type <%x>", operation ); 188 189 } -
trunk/libs/libalmosmkh/almosmkh.h
r626 r629 267 267 * This syscall implements an user-level interactive debugger that can be 268 268 * introduced in any user application to display various kernel distributed structures. 269 * The supported commands are:270 * - p (cxy) : display all processes descriptors in a given cluster.271 * - s (cxy,lid) : display all threads attached to a given core in a given cluster.272 * - v (cxy) : display the calling process VMM in a given cluster.273 * - t (tid) : display all owner process descriptors attached to a TXT terminal.274 * - x : force the calling process to exit.275 * - c : continue calling process execution.276 * - h : list the supported commands277 269 ***************************************************************************************/ 278 270 void idbg( void ); -
trunk/params-hard.mk
r628 r629 2 2 3 3 ARCH = /users/alain/soc/tsar-trunk-svn-2013/platforms/tsar_generic_iob 4 X_SIZE = 25 Y_SIZE = 26 NB_PROCS = 47 NB_TTYS = 34 X_SIZE = 4 5 Y_SIZE = 4 6 NB_PROCS = 1 7 NB_TTYS = 2 8 8 IOC_TYPE = IOC_BDV 9 9 TXT_TYPE = TXT_TTY -
trunk/user/fft/fft.c
r628 r629 538 538 exit(0); 539 539 } 540 printf("\n[ sort] file <%s> closed\n", path );540 printf("\n[fft] file <%s> closed\n", path ); 541 541 542 542 exit( 0 ); … … 570 570 571 571 #if DEBUG_SLAVE 572 printf("\n[fft] %s : thread % xenter / cycle %d\n",572 printf("\n[fft] %s : thread %d enter / cycle %d\n", 573 573 __FUNCTION__, MyNum, (unsigned int)parallel_start ); 574 574 #endif 575 576 // BARRIER 577 get_cycle( &barrier_start ); 578 pthread_barrier_wait( &barrier ); 579 get_cycle( &barrier_stop ); 580 sync_time[MyNum] += (barrier_stop - barrier_start); 581 582 // printf("\n[@@@] %s : thread %d exit first barrier / cycle %d\n", 583 // __FUNCTION__, MyNum, (unsigned int)barrier_stop ); 575 584 576 585 // allocate and initialise local array upriv[] … … 592 601 FFT1D( 1 , data , trans , upriv , twid , MyNum , MyFirst , MyLast ); 593 602 594 // BARRIER595 get_cycle( &barrier_start );596 pthread_barrier_wait( &barrier );597 get_cycle( &barrier_stop );598 599 sync_time[MyNum] += (barrier_stop - barrier_start);600 601 603 #if CHECK 602 604 get_cycle( &barrier_start ); 603 605 pthread_barrier_wait( &barrier ); 604 606 get_cycle( &barrier_stop ); 605 606 607 sync_time[MyNum] += (long)(barrier_stop - barrier_start); 607 608 608 FFT1D( -1 , data , trans , upriv , twid , MyNum , MyFirst , MyLast ); 609 609 #endif … … 688 688 { 689 689 unsigned int i , j; 690 double cks;691 690 unsigned int c_id; 692 691 unsigned int c_offset; 692 double cks; 693 693 694 694 cks = 0.0; … … 849 849 unsigned long long cycle; 850 850 get_cycle( &cycle ); 851 printf("\n[fft] %s : thread % xenter / first %d / last %d / cycle %d\n",851 printf("\n[fft] %s : thread %d enter / first %d / last %d / cycle %d\n", 852 852 __FUNCTION__, MyNum, MyFirst, MyLast, (unsigned int)cycle ); 853 853 #endif … … 858 858 #if( DEBUG_FFT1D & 1 ) 859 859 get_cycle( &cycle ); 860 printf("\n[fft] %s : thread % xafter first transpose / cycle %d\n",860 printf("\n[fft] %s : thread %d after first transpose / cycle %d\n", 861 861 __FUNCTION__, MyNum, (unsigned int)cycle ); 862 862 if( PRINT_ARRAY ) PrintArray( tmp , N ); … … 871 871 #if( DEBUG_FFT1D & 1 ) 872 872 get_cycle( &cycle ); 873 printf("\n[fft] %s : thread % xexit barrier after first transpose / cycle %d\n",873 printf("\n[fft] %s : thread %d exit barrier after first transpose / cycle %d\n", 874 874 __FUNCTION__, MyNum, (unsigned int)cycle ); 875 875 #endif … … 884 884 885 885 #if( DEBUG_FFT1D & 1 ) 886 printf("\n[fft] %s : thread % xafter first twiddle\n", __FUNCTION__, MyNum);886 printf("\n[fft] %s : thread %d after first twiddle\n", __FUNCTION__, MyNum); 887 887 if( PRINT_ARRAY ) PrintArray( tmp , N ); 888 888 #endif … … 894 894 895 895 #if( DEBUG_FFT1D & 1 ) 896 printf("\n[fft] %s : thread % xexit barrier after first twiddle\n", __FUNCTION__, MyNum);896 printf("\n[fft] %s : thread %d exit barrier after first twiddle\n", __FUNCTION__, MyNum); 897 897 #endif 898 898 … … 903 903 904 904 #if( DEBUG_FFT1D & 1 ) 905 printf("\n[fft] %s : thread % xafter second transpose\n", __FUNCTION__, MyNum);905 printf("\n[fft] %s : thread %d after second transpose\n", __FUNCTION__, MyNum); 906 906 if( PRINT_ARRAY ) PrintArray( x , N ); 907 907 #endif … … 913 913 914 914 #if( DEBUG_FFT1D & 1 ) 915 printf("\n[fft] %s : thread % xexit barrier after second transpose\n", __FUNCTION__, MyNum);915 printf("\n[fft] %s : thread %d exit barrier after second transpose\n", __FUNCTION__, MyNum); 916 916 #endif 917 917 … … 926 926 927 927 #if( DEBUG_FFT1D & 1 ) 928 printf("\n[fft] %s : thread % xafter FFT on rows\n", __FUNCTION__, MyNum);928 printf("\n[fft] %s : thread %d after FFT on rows\n", __FUNCTION__, MyNum); 929 929 if( PRINT_ARRAY ) PrintArray( x , N ); 930 930 #endif … … 936 936 937 937 #if( DEBUG_FFT1D & 1 ) 938 printf("\n[fft] %s : thread % xexit barrier after FFT on rows\n", __FUNCTION__, MyNum);938 printf("\n[fft] %s : thread %d exit barrier after FFT on rows\n", __FUNCTION__, MyNum); 939 939 #endif 940 940 sync_time[MyNum] += (long)(barrier_stop - barrier_start); … … 954 954 955 955 #if( DEBUG_FFT1D & 1 ) 956 printf("\n[fft] %s : thread % xexit barrier after third transpose\n", __FUNCTION__, MyNum);956 printf("\n[fft] %s : thread %d exit barrier after third transpose\n", __FUNCTION__, MyNum); 957 957 #endif 958 958 … … 964 964 965 965 #if DEBUG_FFT1D 966 printf("\n[fft] %s : thread % xcompleted\n", __FUNCTION__, MyNum);966 printf("\n[fft] %s : thread %d completed\n", __FUNCTION__, MyNum); 967 967 if( PRINT_ARRAY ) PrintArray( x , N ); 968 968 #endif -
trunk/user/ksh/ksh.c
r628 r629 1187 1187 else 1188 1188 { 1189 printf("\n[ksh] load bin/user/ sort.elf\n");1189 printf("\n[ksh] load bin/user/fft.elf\n"); 1190 1190 } 1191 1191 1192 strcpy( cmd , "load bin/user/ sort.elf" );1192 strcpy( cmd , "load bin/user/fft.elf" ); 1193 1193 execute( cmd ); 1194 1194 */ -
trunk/user/sort/sort.c
r628 r629 29 29 #include <hal_macros.h> 30 30 31 #define ARRAY_LENGTH 1024// number of items31 #define ARRAY_LENGTH 4096 // number of items 32 32 #define MAX_THREADS 1024 // 16 * 16 * 4 33 33 … … 423 423 424 424 #if CHECK_RESULT 425 426 425 int success = 1; 427 426 int * res_array = ( (total_threads == 2) || … … 444 443 if ( success ) printf("\n[sort] success\n"); 445 444 else printf("\n[sort] failure\n"); 446 447 445 #endif 448 446 449 447 #if INSTRUMENTATION 450 451 448 char name[64]; 452 449 char path[128]; 453 450 unsigned long long instru_cycle; 454 451 455 // build a file name from n_items / n_clusters / n_cores456 if( USE_DQT_BARRIER ) snprintf( name , 64 , "sort_dqt_%d_%d_%d",457 458 else snprintf( name , 64 , "sort_smp_%d_%d_%d",459 452 // build file name 453 if( USE_DQT_BARRIER ) 454 snprintf( name , 64 , "sort_dqt_%d_%d_%d", ARRAY_LENGTH, x_size * y_size, ncores ); 455 else 456 snprintf( name , 64 , "sort_smp_%d_%d_%d", ARRAY_LENGTH, x_size * y_size, ncores ); 460 457 461 458 // build file pathname … … 471 468 " - parallel : %d cycles\n", 472 469 name, sequencial, parallel ); 473 474 #if IDBG475 idbg();476 #endif477 470 478 471 // open file
Note: See TracChangeset
for help on using the changeset viewer.