RubyPort.cc (8505:442804117f95) | RubyPort.cc (8532:8f27cf8971fe) |
---|---|
1/* 2 * Copyright (c) 2009 Advanced Micro Devices, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 286 unchanged lines hidden (view full) --- 295 296bool 297RubyPort::M5Port::doFunctionalRead(PacketPtr pkt) 298{ 299 Address address(pkt->getAddr()); 300 Address line_address(address); 301 line_address.makeLineAddress(); 302 | 1/* 2 * Copyright (c) 2009 Advanced Micro Devices, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 286 unchanged lines hidden (view full) --- 295 296bool 297RubyPort::M5Port::doFunctionalRead(PacketPtr pkt) 298{ 299 Address address(pkt->getAddr()); 300 Address line_address(address); 301 line_address.makeLineAddress(); 302 |
303 AccessPermission accessPerm = AccessPermission_NotPresent; | 303 AccessPermission access_perm = AccessPermission_NotPresent; |
304 int num_controllers = ruby_system->m_abs_cntrl_vec.size(); 305 | 304 int num_controllers = ruby_system->m_abs_cntrl_vec.size(); 305 |
306 // In this loop, we try to figure which controller has a read only or 307 // a read write copy of the given address. Any valid copy would suffice 308 // for a functional read. 309 | |
310 DPRINTF(RubyPort, "Functional Read request for %s\n",address); | 306 DPRINTF(RubyPort, "Functional Read request for %s\n",address); |
311 for(int i = 0;i < num_controllers;++i) 312 { 313 accessPerm = ruby_system->m_abs_cntrl_vec[i] 314 ->getAccessPermission(line_address); 315 if(accessPerm == AccessPermission_Read_Only || 316 accessPerm == AccessPermission_Read_Write) 317 { 318 unsigned startByte = address.getAddress() - line_address.getAddress(); | |
319 | 307 |
320 uint8* data = pkt->getPtr<uint8_t>(true); 321 unsigned int size_in_bytes = pkt->getSize(); 322 DataBlock& block = ruby_system->m_abs_cntrl_vec[i] | 308 unsigned int num_ro = 0; 309 unsigned int num_rw = 0; 310 unsigned int num_busy = 0; 311 unsigned int num_backing_store = 0; 312 unsigned int num_invalid = 0; 313 314 // In this loop we count the number of controllers that have the given 315 // address in read only, read write and busy states. 316 for (int i = 0; i < num_controllers; ++i) { 317 access_perm = ruby_system->m_abs_cntrl_vec[i]-> 318 getAccessPermission(line_address); 319 if (access_perm == AccessPermission_Read_Only) 320 num_ro++; 321 else if (access_perm == AccessPermission_Read_Write) 322 num_rw++; 323 else if (access_perm == AccessPermission_Busy) 324 num_busy++; 325 else if (access_perm == AccessPermission_Backing_Store) 326 // See RubySlicc_Exports.sm for details, but Backing_Store is meant 327 // to represent blocks in memory *for Broadcast/Snooping protocols*, 328 // where memory has no idea whether it has an exclusive copy of data 329 // or not. 330 num_backing_store++; 331 else if (access_perm == AccessPermission_Invalid || 332 access_perm == AccessPermission_NotPresent) 333 num_invalid++; 334 } 335 assert(num_rw <= 1); 336 337 uint8* data = pkt->getPtr<uint8_t>(true); 338 unsigned int size_in_bytes = pkt->getSize(); 339 unsigned startByte = address.getAddress() - line_address.getAddress(); 340 341 // This if case is meant to capture what happens in a Broadcast/Snoop 342 // protocol where the block does not exist in the cache hierarchy. You 343 // only want to read from the Backing_Store memory if there is no copy in 344 // the cache hierarchy, otherwise you want to try to read the RO or RW 345 // copies existing in the cache hierarchy (covered by the else statement). 346 // The reason is because the Backing_Store memory could easily be stale, if 347 // there are copies floating around the cache hierarchy, so you want to read 348 // it only if it's not in the cache hierarchy at all. 349 if (num_invalid == (num_controllers - 1) && 350 num_backing_store == 1) 351 { 352 DPRINTF(RubyPort, "only copy in Backing_Store memory, read from it\n"); 353 for (int i = 0; i < num_controllers; ++i) { 354 access_perm = ruby_system->m_abs_cntrl_vec[i] 355 ->getAccessPermission(line_address); 356 if (access_perm == AccessPermission_Backing_Store) { 357 DataBlock& block = ruby_system->m_abs_cntrl_vec[i] |
323 ->getDataBlock(line_address); 324 | 358 ->getDataBlock(line_address); 359 |
325 DPRINTF(RubyPort, "reading from %s block %s\n", 326 ruby_system->m_abs_cntrl_vec[i]->name(), block); 327 for (unsigned i = 0; i < size_in_bytes; ++i) | 360 DPRINTF(RubyPort, "reading from %s block %s\n", 361 ruby_system->m_abs_cntrl_vec[i]->name(), block); 362 for (unsigned i = 0; i < size_in_bytes; ++i) { 363 data[i] = block.getByte(i + startByte); 364 } 365 return true; 366 } 367 } 368 } else { 369 // In Broadcast/Snoop protocols, this covers if you know the block 370 // exists somewhere in the caching hierarchy, then you want to read any 371 // valid RO or RW block. In directory protocols, same thing, you want 372 // to read any valid readable copy of the block. 373 DPRINTF(RubyPort, "num_busy = %d, num_ro = %d, num_rw = %d\n", 374 num_busy, num_ro, num_rw); 375 // In this loop, we try to figure which controller has a read only or 376 // a read write copy of the given address. Any valid copy would suffice 377 // for a functional read. 378 for(int i = 0;i < num_controllers;++i) { 379 access_perm = ruby_system->m_abs_cntrl_vec[i] 380 ->getAccessPermission(line_address); 381 if(access_perm == AccessPermission_Read_Only || 382 access_perm == AccessPermission_Read_Write) |
328 { | 383 { |
329 data[i] = block.getByte(i + startByte); | 384 DataBlock& block = ruby_system->m_abs_cntrl_vec[i] 385 ->getDataBlock(line_address); 386 387 DPRINTF(RubyPort, "reading from %s block %s\n", 388 ruby_system->m_abs_cntrl_vec[i]->name(), block); 389 for (unsigned i = 0; i < size_in_bytes; ++i) { 390 data[i] = block.getByte(i + startByte); 391 } 392 return true; |
330 } | 393 } |
331 return true; | |
332 } 333 } 334 return false; 335} 336 337bool 338RubyPort::M5Port::doFunctionalWrite(PacketPtr pkt) 339{ 340 Address addr(pkt->getAddr()); 341 Address line_addr = line_address(addr); | 394 } 395 } 396 return false; 397} 398 399bool 400RubyPort::M5Port::doFunctionalWrite(PacketPtr pkt) 401{ 402 Address addr(pkt->getAddr()); 403 Address line_addr = line_address(addr); |
342 AccessPermission accessPerm = AccessPermission_NotPresent; | 404 AccessPermission access_perm = AccessPermission_NotPresent; |
343 int num_controllers = ruby_system->m_abs_cntrl_vec.size(); 344 345 DPRINTF(RubyPort, "Functional Write request for %s\n",addr); 346 347 unsigned int num_ro = 0; 348 unsigned int num_rw = 0; 349 unsigned int num_busy = 0; | 405 int num_controllers = ruby_system->m_abs_cntrl_vec.size(); 406 407 DPRINTF(RubyPort, "Functional Write request for %s\n",addr); 408 409 unsigned int num_ro = 0; 410 unsigned int num_rw = 0; 411 unsigned int num_busy = 0; |
412 unsigned int num_backing_store = 0; 413 unsigned int num_invalid = 0; |
|
350 351 // In this loop we count the number of controllers that have the given 352 // address in read only, read write and busy states. | 414 415 // In this loop we count the number of controllers that have the given 416 // address in read only, read write and busy states. |
353 for(int i = 0;i < num_controllers;++i) 354 { 355 accessPerm = ruby_system->m_abs_cntrl_vec[i]-> | 417 for(int i = 0;i < num_controllers;++i) { 418 access_perm = ruby_system->m_abs_cntrl_vec[i]-> |
356 getAccessPermission(line_addr); | 419 getAccessPermission(line_addr); |
357 if(accessPerm == AccessPermission_Read_Only) num_ro++; 358 else if(accessPerm == AccessPermission_Read_Write) num_rw++; 359 else if(accessPerm == AccessPermission_Busy) num_busy++; | 420 if (access_perm == AccessPermission_Read_Only) 421 num_ro++; 422 else if (access_perm == AccessPermission_Read_Write) 423 num_rw++; 424 else if (access_perm == AccessPermission_Busy) 425 num_busy++; 426 else if (access_perm == AccessPermission_Backing_Store) 427 // See RubySlicc_Exports.sm for details, but Backing_Store is meant 428 // to represent blocks in memory *for Broadcast/Snooping protocols*, 429 // where memory has no idea whether it has an exclusive copy of data 430 // or not. 431 num_backing_store++; 432 else if (access_perm == AccessPermission_Invalid || 433 access_perm == AccessPermission_NotPresent) 434 num_invalid++; |
360 } 361 362 // If the number of read write copies is more than 1, then there is bug in 363 // coherence protocol. Otherwise, if all copies are in stable states, i.e. 364 // num_busy == 0, we update all the copies. If there is at least one copy 365 // in busy state, then we check if there is read write copy. If yes, then | 435 } 436 437 // If the number of read write copies is more than 1, then there is bug in 438 // coherence protocol. Otherwise, if all copies are in stable states, i.e. 439 // num_busy == 0, we update all the copies. If there is at least one copy 440 // in busy state, then we check if there is read write copy. If yes, then |
366 // also we let the access go through. | 441 // also we let the access go through. Or, if there is no copy in the cache 442 // hierarchy at all, we still want to do the write to the memory 443 // (Backing_Store) instead of failing. |
367 368 DPRINTF(RubyPort, "num_busy = %d, num_ro = %d, num_rw = %d\n", 369 num_busy, num_ro, num_rw); 370 assert(num_rw <= 1); | 444 445 DPRINTF(RubyPort, "num_busy = %d, num_ro = %d, num_rw = %d\n", 446 num_busy, num_ro, num_rw); 447 assert(num_rw <= 1); |
371 if((num_busy == 0 && num_ro > 0) || num_rw == 1) 372 { 373 uint8* data = pkt->getPtr<uint8_t>(true); 374 unsigned int size_in_bytes = pkt->getSize(); 375 unsigned startByte = addr.getAddress() - line_addr.getAddress(); | |
376 | 448 |
377 for(int i = 0; i < num_controllers;++i) 378 { 379 accessPerm = ruby_system->m_abs_cntrl_vec[i]-> | 449 uint8* data = pkt->getPtr<uint8_t>(true); 450 unsigned int size_in_bytes = pkt->getSize(); 451 unsigned startByte = addr.getAddress() - line_addr.getAddress(); 452 453 if ((num_busy == 0 && num_ro > 0) || num_rw == 1 || 454 (num_invalid == (num_controllers - 1) && num_backing_store == 1)) 455 { 456 for(int i = 0; i < num_controllers;++i) { 457 access_perm = ruby_system->m_abs_cntrl_vec[i]-> |
380 getAccessPermission(line_addr); | 458 getAccessPermission(line_addr); |
381 if(accessPerm == AccessPermission_Read_Only || 382 accessPerm == AccessPermission_Read_Write|| 383 accessPerm == AccessPermission_Maybe_Stale) | 459 if(access_perm == AccessPermission_Read_Only || 460 access_perm == AccessPermission_Read_Write|| 461 access_perm == AccessPermission_Maybe_Stale || 462 access_perm == AccessPermission_Backing_Store) |
384 { 385 DataBlock& block = ruby_system->m_abs_cntrl_vec[i] 386 ->getDataBlock(line_addr); 387 388 DPRINTF(RubyPort, "%s\n",block); | 463 { 464 DataBlock& block = ruby_system->m_abs_cntrl_vec[i] 465 ->getDataBlock(line_addr); 466 467 DPRINTF(RubyPort, "%s\n",block); |
389 for (unsigned i = 0; i < size_in_bytes; ++i) 390 { | 468 for (unsigned i = 0; i < size_in_bytes; ++i) { |
391 block.setByte(i + startByte, data[i]); 392 } 393 DPRINTF(RubyPort, "%s\n",block); 394 } 395 } 396 return true; 397 } 398 return false; --- 200 unchanged lines hidden --- | 469 block.setByte(i + startByte, data[i]); 470 } 471 DPRINTF(RubyPort, "%s\n",block); 472 } 473 } 474 return true; 475 } 476 return false; --- 200 unchanged lines hidden --- |