Changeset 495
- Timestamp:
- Feb 8, 2015, 12:55:35 PM (10 years ago)
- Location:
- soft/giet_vm/giet_common
- Files:
-
- 2 added
- 7 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_common/io.h
r408 r495 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 7 // Utility functions to write or read memory mapped hardware registers 8 // The main service provided by those functions is to force an actual 9 // read (volatile attribute) or write (sync operation) to memory. 8 10 /////////////////////////////////////////////////////////////////////////////////// 9 11 -
soft/giet_vm/giet_common/kernel_locks.c
r466 r495 1 1 /////////////////////////////////////////////////////////////////////////////////// 2 // File : locks.c2 // File : kernel_locks.c 3 3 // Date : 01/12/2014 4 4 // Author : alain greiner … … 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 7 8 #include " locks.h"8 #include "kernel_locks.h" 9 9 #include "giet_config.h" 10 10 #include "hard_config.h" … … 12 12 #include "tty0.h" 13 13 #include "kernel_malloc.h" 14 #include "io.h" 14 15 15 16 /////////////////////////////////////////////////// 16 17 unsigned int _atomic_increment( unsigned int* ptr, 17 unsigned intincrement )18 int increment ) 18 19 { 19 20 unsigned int value; … … 35 36 } 36 37 38 37 39 /////////////////////////////////////////////////////////////////////////////////// 38 40 // Simple lock access functions … … 53 55 54 56 asm volatile ( "1515: \n" 55 "lw $2, 0(%0) \n" /* $2 <= lock current value */56 "bnez $2, 1515b \n" /* retry if lock already taken */57 "ll $2, 0(%0) \n" /* ll_buffer <= lock current value */58 "bnez $2, 1515b \n" /* retry if lock already taken */59 "li $3, 1 \n" /* $3 <= argument for sc */60 "sc $3, 0(%0) \n" /* try to set lock */61 "beqz $3, 1515b \n" /* retry if sc failure */57 "lw $2, 0(%0) \n" 58 "bnez $2, 1515b \n" 59 "ll $2, 0(%0) \n" 60 "bnez $2, 1515b \n" 61 "li $3, 1 \n" 62 "sc $3, 0(%0) \n" 63 "beqz $3, 1515b \n" 62 64 : 63 65 : "r"(lock) … … 74 76 void _simple_lock_release( simple_lock_t* lock ) 75 77 { 76 asm volatile ( "sync \n" /* for consistency */ 77 "sw $0, 0(%0) \n" /* release lock */ 78 : 79 : "r"(lock) 80 : "memory" ); 78 asm volatile ( "sync" ); // for consistency 79 80 lock->value = 0; 81 81 82 82 #if GIET_DEBUG_SIMPLE_LOCK … … 107 107 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 108 108 unsigned int l = gpid & ((1<<P_WIDTH)-1); 109 _puts("\n[DEBUG SPIN_LOCK] P["); 110 _putd( x ); 111 _puts(","); 112 _putd( y ); 113 _puts(","); 114 _putd( l ); 115 _puts("] init lock "); 116 _putx( (unsigned int)lock ); 117 _puts(" (current = "); 118 _putd( lock->current ); 119 _puts(" / free = "); 120 _putd( lock->free ); 121 _puts(" )\n"); 109 _nolock_printf("\n[DEBUG SPIN_LOCK] P[%d,%d,%d] initializes lock %x at cycle %d\n", 110 x, y, l, (unsigned int)lock, _get_proctime() ); 122 111 #endif 123 112 … … 136 125 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 137 126 unsigned int l = gpid & ((1<<P_WIDTH)-1); 138 _puts("\n[DEBUG SPIN_LOCK] P["); 139 _putd( x ); 140 _puts(","); 141 _putd( y ); 142 _puts(","); 143 _putd( l ); 144 _puts("] get ticket "); 145 _putx( ticket ); 146 _puts(" for lock "); 147 _putx( (unsigned int)lock ); 148 _puts(" (current = "); 149 _putd( lock->current ); 150 _puts(" / free = "); 151 _putd( lock->free ); 152 _puts(" )\n"); 153 #endif 154 127 _nolock_printf("\n[DEBUG SPIN_LOCK] P[%d,%d,%d] get ticket %d for lock %x at cycle %d" 128 " / current = %d / free = %d\n", 129 x, y, l, ticket, (unsigned int)lock, _get_proctime(), 130 lock->current, lock->free ); 131 #endif 155 132 156 133 // poll the spin_lock current slot index 157 asm volatile("5678: \n" 158 "lw $10, 0(%0) \n" 159 "move $11, %1 \n" 160 "bne $10, $11, 5678b \n" 161 : 162 : "r"(lock), "r"(ticket) 163 : "$10", "$11" ); 134 while ( ioread32( &lock->current ) != ticket ) asm volatile ("nop"); 164 135 165 136 #if GIET_DEBUG_SPIN_LOCK 166 _puts("\n[DEBUG SPIN_LOCK] P["); 167 _putd( x ); 168 _puts(","); 169 _putd( y ); 170 _puts(","); 171 _putd( l ); 172 _puts("] get lock "); 173 _putx( (unsigned int)lock ); 174 _puts(" (current = "); 175 _putd( lock->current ); 176 _puts(" / free = "); 177 _putd( lock->free ); 178 _puts(" )\n"); 137 _nolock_printf("\n[DEBUG SPIN_LOCK] P[%d,%d,%d] get lock %x at cycle %d" 138 " / current = %d / free = %d\n", 139 x, y, l, (unsigned int)lock, _get_proctime(), 140 lock->current, lock->free ); 179 141 #endif 180 142 … … 184 146 void _spin_lock_release( spin_lock_t* lock ) 185 147 { 186 unsigned int current = lock->current; 187 188 if ( current == (GIET_LOCK_MAX_TICKET - 1) ) current = 0; 189 else current = current + 1; 190 191 asm volatile ( "sync \n" /* for consistency */ 192 "sw %1, 0(%0) \n" /* release lock */ 193 : 194 : "r"(lock), "r"(current) 195 : "memory" ); 196 148 asm volatile ( "sync" ); // for consistency 149 150 lock->current = lock->current + 1; 197 151 198 152 #if GIET_DEBUG_SPIN_LOCK 199 unsigned int gpid = _get_procid(); 200 unsigned int x = gpid >> (Y_WIDTH + P_WIDTH); 201 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 202 unsigned int l = gpid & ((1<<P_WIDTH)-1); 203 _puts("\n[DEBUG SPIN_LOCK] P["); 204 _putd( x ); 205 _puts(","); 206 _putd( y ); 207 _puts(","); 208 _putd( l ); 209 _puts("] release lock "); 210 _putx( (unsigned int)lock ); 211 _puts(" (current = "); 212 _putd( lock->current ); 213 _puts(" / free = "); 214 _putd( lock->free ); 215 _puts(" )\n"); 216 #endif 217 218 } 219 220 /////////////////////////////////////////////////////////////////////////////////// 221 // SBT lock access functions 222 /////////////////////////////////////////////////////////////////////////////////// 223 224 /////////////////////////////////////////////////////////////////////////////////// 225 // This recursive function is used by the _sbt_lock_init() function 226 // to initializes the SBT nodes (mainly the parent and child pointers). 227 // It traverses the SBT from top to bottom. 228 /////////////////////////////////////////////////////////////////////////////////// 229 static void _sbt_lock_build( sbt_lock_t* lock, // pointer on the SBT lock 230 unsigned int x, // SBT node x coordinate 231 unsigned int y, // SBT node y coordinate 232 unsigned int level, // SBT node level 233 lock_node_t* parent ) // pointer on parent node 234 { 235 236 #if GIET_DEBUG_SBT_LOCK 153 _nolock_printf("\n[DEBUG SPIN_LOCK] P[%d,%d,%d] release lock %x at cycle %d" 154 " / current = %d / free = %d\n", 155 x, y, l, (unsigned int)lock, _get_proctime(), 156 lock->current, lock->free ); 157 #endif 158 159 } 160 161 162 163 /////////////////////////////////////////////////////////////////////////////////// 164 // SQT lock access functions 165 /////////////////////////////////////////////////////////////////////////////////// 166 167 /////////////////////////////////////////////////////////////////////////////////// 168 // This recursive function is used by the _sqt_lock_init() function 169 // to initializes the SQT nodes (mainly the parent and child pointers). 170 // It traverses the SQT from top to bottom. 171 // The SQT can be uncomplete (when xmax or ymax are not power of 2), 172 // and the recursion stops when the (x,y) coordinates exceed the footprint. 173 /////////////////////////////////////////////////////////////////////////////////// 174 static 175 void _sqt_lock_build( sqt_lock_t* lock, // pointer on the SQT lock 176 unsigned int x, // node X coordinate 177 unsigned int y, // node Y coordinate 178 unsigned int level, // node level 179 sqt_lock_node_t* parent, // pointer on parent node 180 unsigned int xmax, // SQT X size 181 unsigned int ymax ) // SQT Y size 182 { 183 184 #if GIET_DEBUG_SQT_LOCK 237 185 unsigned int gpid = _get_procid(); 238 186 unsigned int px = gpid >> (Y_WIDTH + P_WIDTH); … … 242 190 243 191 // get target node pointer 244 lock_node_t* node = lock->node[x][y][level];192 sqt_lock_node_t* node = lock->node[x][y][level]; 245 193 246 194 if (level == 0 ) // terminal case 247 195 { 248 196 // initializes target node 249 node->taken = 0; 250 node->level = level; 197 node->current = 0; 198 node->free = 0; 199 node->level = 0; 251 200 node->parent = parent; 252 node->child0 = NULL; 253 node->child1 = NULL; 254 node->x = x; 255 node->y = y; 256 257 #if GIET_DEBUG_SBT_LOCK 258 _nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] initialises SBT node[%d,%d,%d] : " 259 "parent = %x / childO = %x / child1 = %x\n", 260 px , py , pl , node->x , node->y , node->level , 261 (unsigned int)node->parent , (unsigned int)node->child0 , (unsigned int)node->child1 ); 201 node->child[0] = NULL; 202 node->child[1] = NULL; 203 node->child[2] = NULL; 204 node->child[3] = NULL; 205 206 #if GIET_DEBUG_SQT_LOCK 207 _nolock_printf("\n[DEBUG SQT_LOCK] P[%d,%d,%d] initialises SQT node[%d,%d,%d] : \n" 208 " parent = %x / childO = %x / child1 = %x / child2 = %x / child3 = %x\n", 209 px , py , pl , x , y , level , 210 (unsigned int)node->parent , 211 (unsigned int)node->child[0] , 212 (unsigned int)node->child[1] , 213 (unsigned int)node->child[2] , 214 (unsigned int)node->child[3] ); 262 215 #endif 263 216 … … 265 218 else // non terminal case 266 219 { 267 unsigned int x0; // x coordinate for child0 268 unsigned int y0; // y coordinate for child0; 269 unsigned int x1; // x coordinate for child1; 270 unsigned int y1; // y coordinate for child1; 220 unsigned int cx[4]; // x coordinate for children 221 unsigned int cy[4]; // y coordinate for children 222 unsigned int i; // child index 271 223 272 224 // the child0 coordinates are equal to the parent coordinates 273 // the child1 coordinates are incremented depending on the level value 274 if ( level & 0x1 ) // odd level => X binary tree 225 // other childs coordinates are incremented depending on the level value 226 cx[0] = x; 227 cy[0] = y; 228 229 cx[1] = x + (1 << (level-1)); 230 cy[1] = y; 231 232 cx[2] = x; 233 cy[2] = y + (1 << (level-1)); 234 235 cx[3] = x + (1 << (level-1)); 236 cy[3] = y + (1 << (level-1)); 237 238 // initializes target node 239 for ( i = 0 ; i < 4 ; i++ ) 275 240 { 276 x0 = x; 277 y0 = y; 278 x1 = x + (1 << ((level-1)>>1)); 279 y1 = y; 280 } 281 else // even level => Y binary tree 282 { 283 x0 = x; 284 y0 = y; 285 x1 = x; 286 y1 = y + (1 << ((level-1)>>1)); 241 if ( (cx[i] < xmax) && (cy[i] < ymax) ) 242 node->child[i] = lock->node[cx[i]][cy[i]][level-1]; 243 else 244 node->child[i] = NULL; 287 245 } 288 289 // initializes target node 290 node->taken = 0; 246 node->current = 0; 247 node->free = 0; 291 248 node->level = level; 292 249 node->parent = parent; 293 node->child0 = lock->node[x0][y0][level-1]; 294 node->child1 = lock->node[x1][y1][level-1]; 295 296 #if GIET_DEBUG_SBT_LOCK 297 _nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] initialises SBT node[%d,%d,%d] : " 298 "parent = %x / childO = %x / child1 = %x\n", 250 251 #if GIET_DEBUG_SQT_LOCK 252 _nolock_printf("\n[DEBUG SQT_LOCK] P[%d,%d,%d] initialises SQT node[%d,%d,%d] : \n" 253 " parent = %x / childO = %x / child1 = %x / child2 = %x / child3 = %x\n", 299 254 px , py , pl , x , y , level , 300 (unsigned int)node->parent , (unsigned int)node->child0 , (unsigned int)node->child1 ); 301 #endif 302 303 // recursive calls for children nodes 304 _sbt_lock_build( lock , x0 , y0 , level-1 , node ); 305 _sbt_lock_build( lock , x1 , y1 , level-1 , node ); 255 (unsigned int)node->parent , 256 (unsigned int)node->child[0] , 257 (unsigned int)node->child[1] , 258 (unsigned int)node->child[2] , 259 (unsigned int)node->child[3] ); 260 #endif 261 262 // recursive calls for children nodes 263 for ( i = 0 ; i < 4 ; i++ ) 264 { 265 if ( (cx[i] < xmax) && (cy[i] < ymax) ) 266 _sqt_lock_build( lock, 267 cx[i], 268 cy[i], 269 level-1, 270 node, 271 xmax, 272 ymax ); 273 } 306 274 } 307 308 } // end _sbt_lock_build() 309 310 ////////////////////////////////////////////////////////////////////////////////// 311 // This recursive function is used by the sbt_lock_acquire() function to 312 // get the SBT lock: It tries to get each "partial" lock on the path from bottom 313 // to top, using an atomic LL/SC, and starting from bottom. 314 // It is blocking : it poll each "partial lock until it can be taken. 315 // The lock is finally obtained when all "partial" locks, at all levels are taken. 316 ////////////////////////////////////////////////////////////////////////////////// 317 static void _sbt_lock_take( lock_node_t* node ) 318 { 319 // try to take "partial" lock 320 unsigned int* taken = &node->taken; 321 322 asm volatile ( "1945: \n" 323 "lw $2, 0(%0) \n" /* $2 <= lock current value */ 324 "bnez $2, 1945b \n" /* retry if lock already taken */ 325 "ll $2, 0(%0) \n" /* ll_buffer <= lock current value */ 326 "bnez $2, 1945b \n" /* retry if lock already taken */ 327 "li $3, 1 \n" /* $3 <= argument for sc */ 328 "sc $3, 0(%0) \n" /* try to set lock */ 329 "beqz $3, 1945b \n" /* retry if sc failure */ 330 : 331 : "r"(taken) 332 : "$2", "$3", "memory" ); 333 334 #if GIET_DEBUG_SBT_LOCK 275 } // end _sqt_lock_build() 276 277 ///////////////////////////////////////////////////////////////////////////////// 278 // This external function initialises the distributed SQT lock. 279 // It allocates memory for the distributed SQT nodes in clusters, 280 // and initializes the SQT nodes pointers array (stored in cluster[0][0]. 281 // The SQT can be "uncomplete" as SQT lock nodes are only build in clusters 282 // containing processors. 283 // The actual number of SQT locks nodes in a cluster[x][y] depends on (x,y): 284 // At least 1 node / at most 5 nodes per cluster: 285 // - lock arbitrating between all processors of 1 cluster has level 0, 286 // - lock arbitrating between all processors of 4 clusters has level 1, 287 // - lock arbitrating between all processors of 16 clusters has level 2, 288 // - lock arbitrating between all processors of 64 clusters has level 3, 289 // - lock arbitrating between all processors of 256 clusters has level 4, 290 ///////////////////////////////////////////////////////////////////////////////// 291 void _sqt_lock_init( sqt_lock_t* lock ) 292 { 293 unsigned int levels; 294 unsigned int xmax; 295 unsigned int ymax; 296 297 // compute the smallest SQT covering all processors 298 _get_sqt_footprint( &xmax, &ymax, &levels ); 299 300 301 #if GIET_DEBUG_SQT_LOCK 335 302 unsigned int gpid = _get_procid(); 336 303 unsigned int px = gpid >> (Y_WIDTH + P_WIDTH); 337 304 unsigned int py = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 338 305 unsigned int pl = gpid & ((1<<P_WIDTH)-1); 339 _nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] get partial SBT lock[%d,%d,%d] : vaddr = %x\n", 340 px , py , pl , node->x , node->y , node->level , (unsigned int)node ); 341 #endif 342 343 // try to take the parent node lock until top is reached 344 if ( node->parent != NULL ) _sbt_lock_take( node->parent ); 345 346 } // end _sbt_lock_take() 306 _nolock_printf("\n[DEBUG SQT_LOCK] P[%d,%d,%d] initialises SQT lock %x : \n" 307 " xmax = %d / ymax = %d / levels = %d\n", 308 px , py , pl , (unsigned int)lock , 309 xmax , ymax , levels ); 310 #endif 311 347 312 348 349 ///////////////////////////////////////////////////////////////////////////////// 350 // This recursive function is used by the sbt_lock_release() function to 351 // release the SBT lock: It reset all "partial" locks on the path from bottom 352 // to top, using a normal write, and starting from bottom. 353 ///////////////////////////////////////////////////////////////////////////////// 354 static void _sbt_lock_free( lock_node_t* node ) 355 { 356 // reset "partial" lock 357 node->taken = 0; 358 359 #if GIET_DEBUG_SBT_LOCK 360 unsigned int gpid = _get_procid(); 361 unsigned int px = gpid >> (Y_WIDTH + P_WIDTH); 362 unsigned int py = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 363 unsigned int pl = gpid & ((1<<P_WIDTH)-1); 364 _nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] release partial SBT lock[%d,%d,%d] : vaddr = %x\n", 365 px , py , pl , node->x , node->y , node->level , (unsigned int)node ); 366 #endif 367 368 // reset parent node until top is reached 369 if ( node->parent != NULL ) _sbt_lock_free( node->parent ); 370 371 } // end _sbt_lock_free() 372 373 ////////////////////////////////////////////////////////////////////////////////// 374 // This external function initialises the distributed SBT lock. 375 ////////////////////////////////////////////////////////////////////////////////// 376 void _sbt_lock_init( sbt_lock_t* lock ) 377 { 378 unsigned int levels = 0; // depth of the SBT (number of levels) 379 380 // compute SBT levels 381 if ((X_SIZE == 1 ) && (Y_SIZE == 1 )) levels = 1; 382 else if ((X_SIZE == 2 ) && (Y_SIZE == 1 )) levels = 2; 383 else if ((X_SIZE == 2 ) && (Y_SIZE == 2 )) levels = 3; 384 else if ((X_SIZE == 4 ) && (Y_SIZE == 2 )) levels = 4; 385 else if ((X_SIZE == 4 ) && (Y_SIZE == 4 )) levels = 5; 386 else if ((X_SIZE == 8 ) && (Y_SIZE == 4 )) levels = 6; 387 else if ((X_SIZE == 8 ) && (Y_SIZE == 8 )) levels = 7; 388 else if ((X_SIZE == 16) && (Y_SIZE == 8 )) levels = 8; 389 else if ((X_SIZE == 16) && (Y_SIZE == 16)) levels = 9; 390 else 313 unsigned int x; // x coordinate for one SQT node 314 unsigned int y; // y coordinate for one SQT node 315 unsigned int l; // level for one SQT node 316 317 for ( x = 0 ; x < xmax ; x++ ) 391 318 { 392 _nolock_printf("\n[GIET ERROR] _sbt_lock_init() :illegal X_SIZE/Y_SIZE \n"); 393 _exit(); 394 } 395 396 #if GIET_DEBUG_SBT_LOCK 397 unsigned int gpid = _get_procid(); 398 unsigned int px = gpid >> (Y_WIDTH + P_WIDTH); 399 unsigned int py = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 400 unsigned int pl = gpid & ((1<<P_WIDTH)-1); 401 _nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] initialises SBT lock %x : %d levels\n", 402 px , py , pl , (unsigned int)lock , levels ); 403 #endif 404 405 // allocates memory for the SBT nodes and initializes SBT nodes pointers array 406 // the actual number of SBT nodes in a cluster(x,y) depends on (x,y): 407 // At least 1 node / at most 9 nodes per cluster. 408 unsigned int x; // x coordinate for one SBT node 409 unsigned int y; // y coordinate for one SBT node 410 unsigned int l; // level for one SBT node 411 for ( x = 0 ; x < X_SIZE ; x++ ) 412 { 413 for ( y = 0 ; y < Y_SIZE ; y++ ) 319 for ( y = 0 ; y < ymax ; y++ ) 414 320 { 415 321 for ( l = 0 ; l < levels ; l++ ) // level 0 nodes … … 417 323 418 324 if ( ( (l == 0) && ((x&0x00) == 0) && ((y&0x00) == 0) ) || 419 ( (l == 1) && ((x&0x01) == 0) && ((y&0x00) == 0) ) || 420 ( (l == 2) && ((x&0x01) == 0) && ((y&0x01) == 0) ) || 421 ( (l == 3) && ((x&0x03) == 0) && ((y&0x01) == 0) ) || 422 ( (l == 4) && ((x&0x03) == 0) && ((y&0x03) == 0) ) || 423 ( (l == 5) && ((x&0x07) == 0) && ((y&0x03) == 0) ) || 424 ( (l == 6) && ((x&0x07) == 0) && ((y&0x07) == 0) ) || 425 ( (l == 7) && ((x&0x0F) == 0) && ((y&0x07) == 0) ) || 426 ( (l == 8) && ((x&0x0F) == 0) && ((y&0x0F) == 0) ) ) 325 ( (l == 1) && ((x&0x01) == 0) && ((y&0x01) == 0) ) || 326 ( (l == 2) && ((x&0x03) == 0) && ((y&0x03) == 0) ) || 327 ( (l == 3) && ((x&0x07) == 0) && ((y&0x07) == 0) ) || 328 ( (l == 4) && ((x&0x0F) == 0) && ((y&0x0F) == 0) ) ) 427 329 { 428 lock->node[x][y][l] = (lock_node_t*)_remote_malloc( sizeof(lock_node_t), 429 x, y ); 430 431 #if GIET_DEBUG_SBT_LOCK 432 _nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] allocates SBT node[%d,%d,%d] : vaddr = %x\n", 330 lock->node[x][y][l] = 331 (sqt_lock_node_t*)_remote_malloc( sizeof(sqt_lock_node_t), 332 x, y ); 333 334 #if GIET_DEBUG_SQT_LOCK 335 _nolock_printf("\n[DEBUG SQT_LOCK] P[%d,%d,%d] allocates SQT node[%d,%d,%d]" 336 " : vaddr = %x\n", 433 337 px , py , pl , x , y , l , (unsigned int)lock->node[x][y][l] ); 434 338 #endif … … 438 342 } 439 343 440 #if GIET_DEBUG_SBT_LOCK 441 _nolock_printf("\n[DEBUG SBT_LOCK] SBT nodes initialisation starts\n"); 442 #endif 443 444 // recursively initialize all SBT nodes from root to bottom 445 _sbt_lock_build( lock, // pointer on the SBT lock descriptor 344 // recursively initialize all SQT nodes from root to bottom 345 _sqt_lock_build( lock, // pointer on the SQT lock descriptor 446 346 0, // x coordinate 447 347 0, // y coordinate 448 levels-1, // level in SBT 449 NULL ); // pointer on the parent node 348 levels-1, // level in SQT 349 NULL, // pointer on the parent node 350 xmax, // SQT footprint X size 351 ymax ); // SQT footprint X size 450 352 451 353 asm volatile ("sync" ::: "memory"); 452 354 453 #if GIET_DEBUG_S BT_LOCK454 _nolock_printf("\n[DEBUG S BT_LOCK] SBT nodes initialisation completed\n");455 #endif 456 457 } // end _s bt_lock_init()355 #if GIET_DEBUG_SQT_LOCK 356 _nolock_printf("\n[DEBUG SQT_LOCK] SQT nodes initialisation completed\n"); 357 #endif 358 359 } // end _sqt_lock_init() 458 360 459 361 ////////////////////////////////////////////////////////////////////////////////// 460 // This external function get thes SBT lock. 362 // This recursive function is used by the sqt_lock_acquire() function to get 363 // a distributed SQT lock: It tries to get each local queuing lock on the path 364 // from bottom to top, and starting from bottom. 365 // It is blocking : it polls each "partial lock until it can be taken. 366 // The lock is finally obtained when all locks, at all levels are taken. 367 ////////////////////////////////////////////////////////////////////////////////// 368 static 369 void _sqt_lock_take( sqt_lock_node_t* node ) 370 { 371 // get next free ticket from local lock 372 unsigned int ticket = _atomic_increment( &node->free, 1 ); 373 374 #if GIET_DEBUG_SQT_LOCK 375 unsigned int gpid = _get_procid(); 376 unsigned int x = gpid >> (Y_WIDTH + P_WIDTH); 377 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 378 unsigned int l = gpid & ((1<<P_WIDTH)-1); 379 _nolock_printf("\n[DEBUG SQT_LOCK] P[%d,%d,%d] get ticket %d for SQT lock %x" 380 " / level = %d / current = %d / free = %d\n", 381 x , y , l , ticket , (unsigned int)node , 382 node->level , node->current , node->free ); 383 #endif 384 385 // poll the local lock current index 386 while ( ioread32( &node->current ) != ticket ) asm volatile( "nop" ); 387 388 #if GIET_DEBUG_SQT_LOCK 389 _nolock_printf("\n[DEBUG SQT_LOCK] P[%d,%d,%d] get SQT lock %x" 390 " / level = %d / current = %d / free = %d\n", 391 x , y , l , (unsigned int)node , 392 node->level , node->current , node->free ); 393 #endif 394 395 // try to take the parent node lock until top is reached 396 if ( node->parent != NULL ) _sqt_lock_take( node->parent ); 397 398 } // end _sqt_lock_take() 399 400 ////////////////////////////////////////////////////////////////////////////////// 401 // This external function get thes SQT lock. 461 402 // Returns only when the lock has been taken. 462 403 ///////////////////////////////////////////////////////////////////////////////// 463 void _s bt_lock_acquire( sbt_lock_t* lock )404 void _sqt_lock_acquire( sqt_lock_t* lock ) 464 405 { 465 406 // get cluster coordinates … … 468 409 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 469 410 470 // try to recursively take the "partial" locks (from bottom to top) 471 _sbt_lock_take( lock->node[x][y][0] ); 472 } 473 474 475 ///////////////////////////////////////////////////////////////////////////////// 476 // This external function releases the SBT lock. 477 ///////////////////////////////////////////////////////////////////////////////// 478 void _sbt_lock_release( sbt_lock_t* lock ) 479 { 411 // try to recursively take the distributed locks (from bottom to top) 412 _sqt_lock_take( lock->node[x][y][0] ); 413 } 414 415 416 ///////////////////////////////////////////////////////////////////////////////// 417 // This recursive function is used by the sqt_lock_release() function to 418 // release distributed SQT lock: It releases all local locks on the path from 419 // bottom to top, using a normal read/write, and starting from bottom. 420 ///////////////////////////////////////////////////////////////////////////////// 421 static 422 void _sqt_lock_give( sqt_lock_node_t* node ) 423 { 424 // release the local lock 425 node->current = node->current + 1; 426 427 #if GIET_DEBUG_SQT_LOCK 428 unsigned int gpid = _get_procid(); 429 unsigned int x = gpid >> (Y_WIDTH + P_WIDTH); 430 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 431 unsigned int l = gpid & ((1<<P_WIDTH)-1); 432 _nolock_printf("\n[DEBUG SQT_LOCK] P[%d,%d,%d] release SQT lock %x" 433 " / level = %d / current = %d / free = %d\n", 434 x , y , l , (unsigned int)node, 435 node->level , node->current , node->free ); 436 #endif 437 438 // reset parent node until top is reached 439 if ( node->parent != NULL ) _sqt_lock_give( node->parent ); 440 441 } // end _sqt_lock_give() 442 443 444 ///////////////////////////////////////////////////////////////////////////////// 445 // This external function releases the SQT lock. 446 ///////////////////////////////////////////////////////////////////////////////// 447 void _sqt_lock_release( sqt_lock_t* lock ) 448 { 449 asm volatile ( "sync" ); // for consistency 450 480 451 // get cluster coordinates 481 452 unsigned int gpid = _get_procid(); … … 483 454 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 484 455 485 // recursively reset the "partial"locks (from bottom to top)486 _s bt_lock_free( lock->node[x][y][0] );456 // recursively reset the distributed locks (from bottom to top) 457 _sqt_lock_give( lock->node[x][y][0] ); 487 458 } 488 459 -
soft/giet_vm/giet_common/kernel_locks.h
r466 r495 1 1 /////////////////////////////////////////////////////////////////////////////////// 2 // File : locks.h2 // File : kernel_locks.h 3 3 // Date : 01/12/2014 4 4 // Author : alain greiner … … 34 34 typedef struct spin_lock_s 35 35 { 36 unsigned int current; // current slot index 36 unsigned int current; // current slot index: 37 37 unsigned int free; // next free tiket index 38 38 unsigned int padding[14]; // for 64 bytes alignment … … 40 40 41 41 extern unsigned int _atomic_increment( unsigned int* ptr, 42 unsignedint increment );42 int increment ); 43 43 44 44 extern void _spin_lock_init( spin_lock_t* lock ); … … 48 48 extern void _spin_lock_release( spin_lock_t* lock ); 49 49 50 50 51 ////////////////////////////////////////////////////////////////////////////////// 51 // S BT lock structures and access functions52 // SQT lock structures and access functions 52 53 ////////////////////////////////////////////////////////////////////////////////// 53 54 54 typedef struct lock_node_s55 typedef struct sqt_lock_node_s 55 56 { 56 unsigned int taken; // lock taken if non zero 57 unsigned int current; // current ticket index 58 unsigned int free; // next free ticket index 57 59 unsigned int level; // hierarchical level (0 is bottom) 58 struct lock_node_s* parent; // pointer on parent node (NULL for root) 59 struct lock_node_s* child0; // pointer on children node 60 struct lock_node_s* child1; // pointer on children node 61 unsigned int x; // cluster x coordinate 62 unsigned int y; // cluster y coordinate 63 unsigned int padding[9]; // for 64 bytes alignment 64 } lock_node_t; 60 struct sqt_lock_node_s* parent; // parent node (NULL for root) 61 struct sqt_lock_node_s* child[4]; // children node 62 unsigned int padding[8]; // for 64 bytes alignment 63 } sqt_lock_node_t; 65 64 66 typedef struct s bt_lock_s65 typedef struct sqt_lock_s 67 66 { 68 unsigned int ntasks; // total number of expected tasks 69 lock_node_t* node[X_SIZE][Y_SIZE][9]; // array of pointers on SBT nodes 70 } sbt_lock_t; 67 sqt_lock_node_t* node[X_SIZE][Y_SIZE][5]; // array of pointers on SBT nodes 68 } sqt_lock_t; 71 69 72 extern void _s bt_lock_init( sbt_lock_t* lock );70 extern void _sqt_lock_init( sqt_lock_t* lock ); 73 71 74 extern void _s bt_lock_acquire( sbt_lock_t* lock );72 extern void _sqt_lock_acquire( sqt_lock_t* lock ); 75 73 76 extern void _sbt_lock_release( sbt_lock_t* lock ); 74 extern void _sqt_lock_release( sqt_lock_t* lock ); 75 77 76 78 77 #endif -
soft/giet_vm/giet_common/kernel_malloc.c
r466 r495 6 6 //////////////////////////////////////////////////////////////////////////////// 7 7 // Implementation note: 8 // - As this code is used to implement the S BT lock ptotecting TTY0,8 // - As this code is used to implement the SQT lock ptotecting TTY0, 9 9 // all functions here use the kernel _nolock_printf() function. 10 10 // - It must exist one vseg with the HEAP type in each cluster. The length … … 37 37 #include "mapping_info.h" 38 38 #include "kernel_malloc.h" 39 #include " locks.h"39 #include "kernel_locks.h" 40 40 #include "tty0.h" 41 41 #include "utils.h" … … 45 45 /////////////////////////////////////////////////////////////////////////////// 46 46 47 extern kernel_heap_t kernel_heap[X_SIZE][Y_SIZE]; 47 __attribute__((section(".kdata"))) 48 kernel_heap_t kernel_heap[X_SIZE][Y_SIZE]; 48 49 49 50 /////////////////////////////////////////////////////////////////////////////// … … 83 84 (size <= 0x80000000) ? 31 :\ 84 85 32 86 85 87 #if GIET_DEBUG_SYS_MALLOC 86 88 //////////////////////////////////////////////// … … 115 117 " - free[22] = %x\n" 116 118 " - free[23] = %x\n", 117 kernel_heap[x][y].x, kernel_heap[x][y].y,119 x, y, 118 120 kernel_heap[x][y].heap_base, kernel_heap[x][y].heap_size, 119 121 kernel_heap[x][y].free[0] , kernel_heap[x][y].free[1], … … 135 137 136 138 137 ///////////////////////////////////////////// 138 void_get_heap_info( unsigned int* heap_base,139 unsigned int* heap_size,140 unsigned int x,141 unsigned int y )139 ///////////////////////////////////////////////////// 140 unsigned int _get_heap_info( unsigned int* heap_base, 141 unsigned int* heap_size, 142 unsigned int x, 143 unsigned int y ) 142 144 { 143 145 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; … … 155 157 if ( (x >= X_SIZE) || (y >= Y_SIZE) ) 156 158 { 157 _nolock_printf(" [GIET ERROR] _get_heap_info() illegal (%d,%d) coordinates\n",158 x , y );159 _nolock_printf("\n[GIET ERROR] _get_heap_info()" 160 " illegal (%d,%d) coordinates\n", x , y ); 159 161 _exit(); 160 162 } … … 172 174 *heap_base = vsegs[vseg_id].vbase; 173 175 *heap_size = vobjs[vobj_id].length; 174 return ;176 return 0; 175 177 } 176 178 } 177 179 178 // exit if not found 179 _nolock_printf("[GIET ERROR] _get_heap_info() heap[%d][%d] vseg not found\n", 180 x , y ); 181 _exit(); 182 180 return 1; 183 181 } // end _get_heap_info() 184 182 … … 191 189 unsigned int heap_size; 192 190 unsigned int heap_index; 193 194 191 unsigned int index; 195 192 unsigned int x; 196 193 unsigned int y; 194 unsigned int ko; 197 195 198 196 for ( x = 0 ; x < X_SIZE ; x++ ) … … 201 199 { 202 200 // get heap_base, heap size, and heap index 203 _get_heap_info( &heap_base, &heap_size, x, y ); 204 heap_index = GET_SIZE_INDEX( heap_size ); 205 206 // checking heap segment constraints 207 if ( heap_size != (1<<heap_index) ) 201 ko = _get_heap_info( &heap_base, &heap_size, x, y ); 202 203 if ( ko ) // no kernel heap found in cluster[x][y] 208 204 { 209 _nolock_printf("[GIET ERROR] in _heap_init()" 210 " kernel_heap[â°d,â°d] not power of 2\n", x , y ); 211 _exit(); 205 // initialise kernel_heap[x][y] descriptor 206 kernel_heap[x][y].heap_base = 0; 207 kernel_heap[x][y].heap_size = 0; 208 _spin_lock_init( &kernel_heap[x][y].lock ); 212 209 } 213 if ( heap_base % heap_size )210 else // kernel heap found in cluster[x][y] 214 211 { 215 _nolock_printf("[GIET ERROR] in _heap_init()" 216 " kernel_heap[â°d,â°d] not aligned\n", x , y ); 217 _exit(); 212 heap_index = GET_SIZE_INDEX( heap_size ); 213 214 // check heap[x][y] constraints 215 if ( heap_size != (1<<heap_index) ) 216 { 217 _nolock_printf("\n[GIET ERROR] in _heap_init()" 218 " kernel_heap[â°d,â°d] not power of 2\n", x , y ); 219 _exit(); 220 } 221 if ( heap_base % heap_size ) 222 { 223 _nolock_printf("\n[GIET ERROR] in _heap_init()" 224 " kernel_heap[â°d,â°d] not aligned\n", x , y ); 225 _exit(); 226 } 227 228 // initialise the free[] array 229 for ( index = 0 ; index < 32 ; index++ ) 230 { 231 if (index == heap_index) kernel_heap[x][y].free[index] = heap_base; 232 else kernel_heap[x][y].free[index] = 0; 233 } 234 235 // initialise kernel_heap[x][y] descriptor 236 kernel_heap[x][y].heap_base = heap_base; 237 kernel_heap[x][y].heap_size = heap_size; 238 _spin_lock_init( &kernel_heap[x][y].lock ); 218 239 } 219 240 220 // initialise the free[] array221 for ( index = 0 ; index < 32 ; index++ )222 {223 if (index == heap_index) kernel_heap[x][y].free[index] = heap_base;224 else kernel_heap[x][y].free[index] = 0;225 }226 unsigned int* ptr = (unsigned int*)heap_base;227 *ptr = 0;228 229 // initialise kernel_heap[x][y] descriptor230 kernel_heap[x][y].x = x;231 kernel_heap[x][y].y = y;232 kernel_heap[x][y].heap_base = heap_base;233 kernel_heap[x][y].heap_size = heap_size;234 235 _spin_lock_init( &kernel_heap[x][y].lock );236 237 241 #if GIET_DEBUG_SYS_MALLOC 238 _nolock_printf("\n[DEBUG KERNEL_MALLOC] Completing kernel_heap[%d][%d] initialisation\n",239 x, y );242 _nolock_printf("\n[DEBUG KERNEL_MALLOC] Completing kernel_heap[%d][%d]" 243 " initialisation\n", x, y ); 240 244 _display_free_array(x,y); 241 245 #endif … … 248 252 249 253 ////////////////////////////////////////////// 250 unsigned int split_block( kernel_heap_t* heap,251 unsigned int vaddr,252 unsigned int searched_index,253 unsigned int requested_index )254 unsigned int _split_block( kernel_heap_t* heap, 255 unsigned int vaddr, 256 unsigned int searched_index, 257 unsigned int requested_index ) 254 258 { 255 259 // push the upper half block into free[searched_index-1] … … 258 262 heap->free[searched_index-1] = (unsigned int)new; 259 263 260 if ( searched_index == requested_index + 1 ) // terminal case:return lower half block264 if ( searched_index == requested_index + 1 ) // return lower half block 261 265 { 262 266 return vaddr; … … 264 268 else // non terminal case : lower half block must be split again 265 269 { 266 return split_block( heap, vaddr, searched_index-1, requested_index );267 } 268 } // end split_block()270 return _split_block( heap, vaddr, searched_index-1, requested_index ); 271 } 272 } // end _split_block() 269 273 270 274 271 275 272 276 ///////////////////////////////////////////// 273 unsigned int get_block( kernel_heap_t* heap,274 unsigned int searched_index,275 unsigned int requested_index )277 unsigned int _get_block( kernel_heap_t* heap, 278 unsigned int searched_index, 279 unsigned int requested_index ) 276 280 { 277 281 // test terminal case … … 285 289 if ( vaddr == 0 ) // block not found : search in free[searched_index+1] 286 290 { 287 return get_block( heap, searched_index+1, requested_index );291 return _get_block( heap, searched_index+1, requested_index ); 288 292 } 289 293 else // block found : pop it from free[searched_index] … … 300 304 else // split is required 301 305 { 302 return split_block( heap, vaddr, searched_index, requested_index );306 return _split_block( heap, vaddr, searched_index, requested_index ); 303 307 } 304 308 } 305 309 } 306 } // end get_block()310 } // end _get_block() 307 311 308 312 … … 314 318 { 315 319 // checking arguments 316 if ( size == 0)317 { 318 _nolock_printf(" [GIET ERROR] _remote_malloc() : requested size = 0\n");320 if ( x >= X_SIZE ) 321 { 322 _nolock_printf("\n[GIET ERROR] _remote_malloc() : x coordinate too large\n"); 319 323 _exit(); 320 324 } 321 if ( x >= X_SIZE )322 { 323 _nolock_printf(" [GIET ERROR] _remote_malloc() : xcoordinate too large\n");325 if ( y >= Y_SIZE ) 326 { 327 _nolock_printf("\n[GIET ERROR] _remote_malloc() : y coordinate too large\n"); 324 328 _exit(); 325 329 } 326 if ( y >= Y_SIZE)327 { 328 _nolock_printf(" [GIET ERROR] _remote_malloc() : y coordinate too large\n");330 if ( kernel_heap[x][y].heap_size == 0 ) 331 { 332 _nolock_printf("\n[GIET ERROR] _remote_malloc() : No heap[%d][%d]\n", x, y ); 329 333 _exit(); 334 330 335 } 331 336 … … 340 345 341 346 // call the recursive function get_block 342 unsigned int base = get_block( &kernel_heap[x][y],343 requested_index,344 requested_index );347 unsigned int base = _get_block( &kernel_heap[x][y], 348 requested_index, 349 requested_index ); 345 350 // release the lock 346 351 _spin_lock_release( &kernel_heap[x][y].lock ); 347 352 353 if ( base == 0 ) 354 { 355 _nolock_printf("\n[GIET ERROR] _remote_malloc() : no more space " 356 "in heap[%d][%d]", x, y ); 357 } 358 348 359 #if GIET_DEBUG_SYS_MALLOC 349 360 _nolock_printf("\n[DEBUG KERNEL_MALLOC] malloc vaddr %x from kernel_heap[%d][%d]\n", … … 354 365 return (void*)base; 355 366 356 } // end remote_malloc()367 } // end _remote_malloc() 357 368 358 369 -
soft/giet_vm/giet_common/kernel_malloc.h
r466 r495 11 11 #define KERNEL_MALLOC_H_ 12 12 13 #include " locks.h"13 #include "kernel_locks.h" 14 14 #include "hard_config.h" 15 15 … … 25 25 { 26 26 spin_lock_t lock; // lock protecting exclusive access 27 unsigned int x; // cluster X coordinate28 unsigned int y; // cluster Y coordinate29 27 unsigned int heap_base; // heap base address 30 28 unsigned int heap_size; // heap size (bytes) -
soft/giet_vm/giet_common/tty0.c
r466 r495 13 13 #include <tty_driver.h> 14 14 #include <utils.h> 15 #include <locks.h> 15 #include <kernel_locks.h> 16 17 ///////////////////////////////////////////////////////////////////////////// 18 // The global variable tty0_boot_mode define the type of lock used, 19 // and must be defined in both kernel_init.c and boot.c files. 20 // - the boot code must use a spin_lock because the kernel heap is not set. 21 // - the kernel code can use a sqt_lock when the kernel heap is set. 22 ///////////////////////////////////////////////////////////////////////////// 23 24 extern unsigned int _tty0_boot_mode; 25 26 __attribute__((section(".kdata"))) 27 sqt_lock_t _tty0_sqt_lock __attribute__((aligned(64))); 28 29 __attribute__((section(".kdata"))) 30 spin_lock_t _tty0_spin_lock __attribute__((aligned(64))); 16 31 17 32 ////////////////////////////////////////////// … … 20 35 { 21 36 unsigned int n; 37 unsigned int k; 22 38 23 39 for ( n = 0 ; n < nbytes ; n++ ) 24 40 { 25 // return error if TTY_TX buffer full 26 if ( (_tty_get_register( 0, TTY_STATUS ) & 0x2) ) return 1; 41 // test TTY_TX buffer full 42 if ( (_tty_get_register( 0, TTY_STATUS ) & 0x2) ) // buffer full 43 { 44 // retry if full 45 for( k = 0 ; k < 10000 ; k++ ) 46 { 47 if ( (_tty_get_register( 0, TTY_STATUS ) & 0x2) == 0) break; 48 } 49 // return error if full after 10000 retry 50 return 1; 51 } 27 52 28 53 // write one byte … … 240 265 unsigned int lpid = procid & ((1<<P_WIDTH)-1); 241 266 _puts("\n\n[GIET ERROR] in _printf() for processor["); 242 _putd( x ); 267 _putd( x ); 243 268 _puts(","); 244 269 _putd( y ); … … 268 293 // get TTY0 lock 269 294 _it_disable( &save_sr ); 270 _sbt_lock_acquire( &_tty_tx_lock[0] ); 295 if ( _tty0_boot_mode ) _spin_lock_acquire( &_tty0_spin_lock ); 296 else _sqt_lock_acquire( &_tty0_sqt_lock ); 271 297 272 298 va_start( args , format ); … … 275 301 276 302 // release TTY0 lock 277 _sbt_lock_release( &_tty_tx_lock[0] ); 303 if ( _tty0_boot_mode ) _spin_lock_release( &_tty0_spin_lock ); 304 else _sqt_lock_release( &_tty0_sqt_lock ); 278 305 _it_restore( &save_sr ); 279 306 } -
soft/giet_vm/giet_common/utils.c
r490 r495 814 814 815 815 816 ///////////////////////////////////////////// 817 void _get_sqt_footprint( unsigned int* width, 818 unsigned int* heigth, 819 unsigned int* levels ) 820 { 821 mapping_header_t* header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 822 mapping_cluster_t* cluster = _get_cluster_base(header); 823 824 unsigned int x; 825 unsigned int y; 826 unsigned int cid; 827 unsigned int w = 0; 828 unsigned int h = 0; 829 830 // scan all clusters to compute SQT footprint (w,h) 831 for ( x = 0 ; x < X_SIZE ; x++ ) 832 { 833 for ( y = 0 ; y < Y_SIZE ; y++ ) 834 { 835 cid = x * Y_SIZE + y; 836 if ( cluster[cid].procs ) // cluster contains processors 837 { 838 if ( x > w ) w = x; 839 if ( y > h ) h = y; 840 } 841 } 842 } 843 *width = w + 1; 844 *heigth = h + 1; 845 846 // compute SQT levels 847 unsigned int z = (h > w) ? h : w; 848 *levels = (z < 1) ? 1 : (z < 2) ? 2 : (z < 4) ? 3 : (z < 8) ? 4 : 5; 849 } 850 851 852 816 853 /////////////////////////////////////////////////////////////////////////////////// 817 854 // Required by GCC -
soft/giet_vm/giet_common/utils.h
r490 r495 191 191 unsigned int buf_size ); 192 192 193 extern void _get_sqt_footprint( unsigned int* width, 194 unsigned int* heigth, 195 unsigned int* levels ); 196 193 197 /////////////////////////////////////////////////////////////////////////////////// 194 198 // Required by GCC -
soft/giet_vm/giet_common/vmem.c
r476 r495 11 11 #include <giet_config.h> 12 12 13 ///////////////////////////////////////// /////////13 ///////////////////////////////////////// 14 14 void _v2p_translate( page_table_t* ptab, 15 15 unsigned int vpn, … … 36 36 if ( (pte1 & PTE_V) == 0 ) 37 37 { 38 _puts("\n[VMEM ERROR] _v2p_translate() : pte1 unmapped\n"); 38 _printf("\n[VMEM ERROR] _v2p_translate() : pte1 unmapped\n" 39 " vpn = %x / ptab = %x / pte1_vaddr = %x / pte1_value = %x\n", 40 vpn , (unsigned int)ptab, &(ptab->pt1[ix1]) , pte1 ); 39 41 _exit(); 40 42 } … … 50 52 { 51 53 52 // get physical addresses of pte2 (two 32 bits words)53 ptba = ( unsigned long long) (pte1 & 0x0FFFFFFF) << 12;54 // get physical addresses of pte2 55 ptba = ((unsigned long long)(pte1 & 0x0FFFFFFF)) << 12; 54 56 pte2_paddr = ptba + 8*ix2; 57 58 // split physical address in two 32 bits words 55 59 pte2_lsb = (unsigned int) pte2_paddr; 56 60 pte2_msb = (unsigned int) (pte2_paddr >> 32); … … 87 91 if ( (flags_value & PTE_V) == 0 ) 88 92 { 89 _puts("\n[VMEM ERROR] _v2p_translate() : pte2 unmapped\n"); 93 _printf("\n[VMEM ERROR] _v2p_translate() : pte2 unmapped\n" 94 " vpn = %x / ptab = %x / pte1_value = %x\n" 95 " pte2_paddr = %l / ppn = %x / flags = %x\n", 96 vpn , ptab , pte1 , pte2_paddr , ppn_value , flags_value ); 90 97 _exit(); 91 98 }
Note: See TracChangeset
for help on using the changeset viewer.