303c303
< AccessPermission accessPerm = AccessPermission_NotPresent;
---
> AccessPermission access_perm = AccessPermission_NotPresent;
306,309d305
< // In this loop, we try to figure which controller has a read only or
< // a read write copy of the given address. Any valid copy would suffice
< // for a functional read.
<
311,318d306
< for(int i = 0;i < num_controllers;++i)
< {
< accessPerm = ruby_system->m_abs_cntrl_vec[i]
< ->getAccessPermission(line_address);
< if(accessPerm == AccessPermission_Read_Only ||
< accessPerm == AccessPermission_Read_Write)
< {
< unsigned startByte = address.getAddress() - line_address.getAddress();
320,322c308,357
< uint8* data = pkt->getPtr<uint8_t>(true);
< unsigned int size_in_bytes = pkt->getSize();
< DataBlock& block = ruby_system->m_abs_cntrl_vec[i]
---
> unsigned int num_ro = 0;
> unsigned int num_rw = 0;
> unsigned int num_busy = 0;
> unsigned int num_backing_store = 0;
> unsigned int num_invalid = 0;
>
> // In this loop we count the number of controllers that have the given
> // address in read only, read write and busy states.
> for (int i = 0; i < num_controllers; ++i) {
> access_perm = ruby_system->m_abs_cntrl_vec[i]->
> getAccessPermission(line_address);
> if (access_perm == AccessPermission_Read_Only)
> num_ro++;
> else if (access_perm == AccessPermission_Read_Write)
> num_rw++;
> else if (access_perm == AccessPermission_Busy)
> num_busy++;
> else if (access_perm == AccessPermission_Backing_Store)
> // See RubySlicc_Exports.sm for details, but Backing_Store is meant
> // to represent blocks in memory *for Broadcast/Snooping protocols*,
> // where memory has no idea whether it has an exclusive copy of data
> // or not.
> num_backing_store++;
> else if (access_perm == AccessPermission_Invalid ||
> access_perm == AccessPermission_NotPresent)
> num_invalid++;
> }
> assert(num_rw <= 1);
>
> uint8* data = pkt->getPtr<uint8_t>(true);
> unsigned int size_in_bytes = pkt->getSize();
> unsigned startByte = address.getAddress() - line_address.getAddress();
>
> // This if case is meant to capture what happens in a Broadcast/Snoop
> // protocol where the block does not exist in the cache hierarchy. You
> // only want to read from the Backing_Store memory if there is no copy in
> // the cache hierarchy, otherwise you want to try to read the RO or RW
> // copies existing in the cache hierarchy (covered by the else statement).
> // The reason is because the Backing_Store memory could easily be stale, if
> // there are copies floating around the cache hierarchy, so you want to read
> // it only if it's not in the cache hierarchy at all.
> if (num_invalid == (num_controllers - 1) &&
> num_backing_store == 1)
> {
> DPRINTF(RubyPort, "only copy in Backing_Store memory, read from it\n");
> for (int i = 0; i < num_controllers; ++i) {
> access_perm = ruby_system->m_abs_cntrl_vec[i]
> ->getAccessPermission(line_address);
> if (access_perm == AccessPermission_Backing_Store) {
> DataBlock& block = ruby_system->m_abs_cntrl_vec[i]
325,327c360,382
< DPRINTF(RubyPort, "reading from %s block %s\n",
< ruby_system->m_abs_cntrl_vec[i]->name(), block);
< for (unsigned i = 0; i < size_in_bytes; ++i)
---
> DPRINTF(RubyPort, "reading from %s block %s\n",
> ruby_system->m_abs_cntrl_vec[i]->name(), block);
> for (unsigned i = 0; i < size_in_bytes; ++i) {
> data[i] = block.getByte(i + startByte);
> }
> return true;
> }
> }
> } else {
> // In Broadcast/Snoop protocols, this covers if you know the block
> // exists somewhere in the caching hierarchy, then you want to read any
> // valid RO or RW block. In directory protocols, same thing, you want
> // to read any valid readable copy of the block.
> DPRINTF(RubyPort, "num_busy = %d, num_ro = %d, num_rw = %d\n",
> num_busy, num_ro, num_rw);
> // In this loop, we try to figure which controller has a read only or
> // a read write copy of the given address. Any valid copy would suffice
> // for a functional read.
> for(int i = 0;i < num_controllers;++i) {
> access_perm = ruby_system->m_abs_cntrl_vec[i]
> ->getAccessPermission(line_address);
> if(access_perm == AccessPermission_Read_Only ||
> access_perm == AccessPermission_Read_Write)
329c384,392
< data[i] = block.getByte(i + startByte);
---
> DataBlock& block = ruby_system->m_abs_cntrl_vec[i]
> ->getDataBlock(line_address);
>
> DPRINTF(RubyPort, "reading from %s block %s\n",
> ruby_system->m_abs_cntrl_vec[i]->name(), block);
> for (unsigned i = 0; i < size_in_bytes; ++i) {
> data[i] = block.getByte(i + startByte);
> }
> return true;
331d393
< return true;
342c404
< AccessPermission accessPerm = AccessPermission_NotPresent;
---
> AccessPermission access_perm = AccessPermission_NotPresent;
349a412,413
> unsigned int num_backing_store = 0;
> unsigned int num_invalid = 0;
353,355c417,418
< for(int i = 0;i < num_controllers;++i)
< {
< accessPerm = ruby_system->m_abs_cntrl_vec[i]->
---
> for(int i = 0;i < num_controllers;++i) {
> access_perm = ruby_system->m_abs_cntrl_vec[i]->
357,359c420,434
< if(accessPerm == AccessPermission_Read_Only) num_ro++;
< else if(accessPerm == AccessPermission_Read_Write) num_rw++;
< else if(accessPerm == AccessPermission_Busy) num_busy++;
---
> if (access_perm == AccessPermission_Read_Only)
> num_ro++;
> else if (access_perm == AccessPermission_Read_Write)
> num_rw++;
> else if (access_perm == AccessPermission_Busy)
> num_busy++;
> else if (access_perm == AccessPermission_Backing_Store)
> // See RubySlicc_Exports.sm for details, but Backing_Store is meant
> // to represent blocks in memory *for Broadcast/Snooping protocols*,
> // where memory has no idea whether it has an exclusive copy of data
> // or not.
> num_backing_store++;
> else if (access_perm == AccessPermission_Invalid ||
> access_perm == AccessPermission_NotPresent)
> num_invalid++;
366c441,443
< // also we let the access go through.
---
> // also we let the access go through. Or, if there is no copy in the cache
> // hierarchy at all, we still want to do the write to the memory
> // (Backing_Store) instead of failing.
371,375d447
< if((num_busy == 0 && num_ro > 0) || num_rw == 1)
< {
< uint8* data = pkt->getPtr<uint8_t>(true);
< unsigned int size_in_bytes = pkt->getSize();
< unsigned startByte = addr.getAddress() - line_addr.getAddress();
377,379c449,457
< for(int i = 0; i < num_controllers;++i)
< {
< accessPerm = ruby_system->m_abs_cntrl_vec[i]->
---
> uint8* data = pkt->getPtr<uint8_t>(true);
> unsigned int size_in_bytes = pkt->getSize();
> unsigned startByte = addr.getAddress() - line_addr.getAddress();
>
> if ((num_busy == 0 && num_ro > 0) || num_rw == 1 ||
> (num_invalid == (num_controllers - 1) && num_backing_store == 1))
> {
> for(int i = 0; i < num_controllers;++i) {
> access_perm = ruby_system->m_abs_cntrl_vec[i]->
381,383c459,462
< if(accessPerm == AccessPermission_Read_Only ||
< accessPerm == AccessPermission_Read_Write||
< accessPerm == AccessPermission_Maybe_Stale)
---
> if(access_perm == AccessPermission_Read_Only ||
> access_perm == AccessPermission_Read_Write||
> access_perm == AccessPermission_Maybe_Stale ||
> access_perm == AccessPermission_Backing_Store)
389,390c468
< for (unsigned i = 0; i < size_in_bytes; ++i)
< {
---
> for (unsigned i = 0; i < size_in_bytes; ++i) {