CacheMemory.cc revision 7056
112837Sgabeblack@google.com/*
212837Sgabeblack@google.com * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
312837Sgabeblack@google.com * All rights reserved.
412837Sgabeblack@google.com *
512837Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
612837Sgabeblack@google.com * modification, are permitted provided that the following conditions are
712837Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
812837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
912837Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1012837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1112837Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1212837Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1312837Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1412837Sgabeblack@google.com * this software without specific prior written permission.
1512837Sgabeblack@google.com *
1612837Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712837Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812837Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912837Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012837Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112837Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212837Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312837Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412837Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512837Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612837Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712837Sgabeblack@google.com */
2812837Sgabeblack@google.com
2912837Sgabeblack@google.com#include "base/intmath.hh"
3012901Sgabeblack@google.com#include "mem/ruby/system/CacheMemory.hh"
3113135Sgabeblack@google.com
3212901Sgabeblack@google.comusing namespace std;
3312901Sgabeblack@google.com
3412837Sgabeblack@google.comostream&
3513280Sgabeblack@google.comoperator<<(ostream& out, const CacheMemory& obj)
3612982Sgabeblack@google.com{
3712951Sgabeblack@google.com    obj.print(out);
3813280Sgabeblack@google.com    out << flush;
3913288Sgabeblack@google.com    return out;
4012953Sgabeblack@google.com}
4113260Sgabeblack@google.com
4213288Sgabeblack@google.comCacheMemory *
4313288Sgabeblack@google.comRubyCacheParams::create()
4413288Sgabeblack@google.com{
4513155Sgabeblack@google.com    return new CacheMemory(this);
4612837Sgabeblack@google.com}
4712951Sgabeblack@google.com
4813155Sgabeblack@google.comCacheMemory::CacheMemory(const Params *p)
4913135Sgabeblack@google.com    : SimObject(p)
5012837Sgabeblack@google.com{
5112952Sgabeblack@google.com    m_cache_size = p->size;
5212952Sgabeblack@google.com    m_latency = p->latency;
5312952Sgabeblack@google.com    m_cache_assoc = p->assoc;
5412952Sgabeblack@google.com    m_policy = p->replacement_policy;
5512952Sgabeblack@google.com    m_profiler_ptr = new CacheProfiler(name());
5612952Sgabeblack@google.com}
5713135Sgabeblack@google.com
5813135Sgabeblack@google.comvoid
5913135Sgabeblack@google.comCacheMemory::init()
6013135Sgabeblack@google.com{
6113135Sgabeblack@google.com    m_cache_num_sets = (m_cache_size / m_cache_assoc) /
6213135Sgabeblack@google.com        RubySystem::getBlockSizeBytes();
6313135Sgabeblack@google.com    assert(m_cache_num_sets > 1);
6413135Sgabeblack@google.com    m_cache_num_set_bits = floorLog2(m_cache_num_sets);
6512993Sgabeblack@google.com    assert(m_cache_num_set_bits > 0);
6612993Sgabeblack@google.com
6712952Sgabeblack@google.com    if (m_policy == "PSEUDO_LRU")
6812952Sgabeblack@google.com        m_replacementPolicy_ptr =
6912952Sgabeblack@google.com            new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc);
7012952Sgabeblack@google.com    else if (m_policy == "LRU")
7112952Sgabeblack@google.com        m_replacementPolicy_ptr =
7213135Sgabeblack@google.com            new LRUPolicy(m_cache_num_sets, m_cache_assoc);
7313135Sgabeblack@google.com    else
7413135Sgabeblack@google.com        assert(false);
7513135Sgabeblack@google.com
7613135Sgabeblack@google.com    m_cache.setSize(m_cache_num_sets);
7713135Sgabeblack@google.com    m_locked.setSize(m_cache_num_sets);
7813135Sgabeblack@google.com    for (int i = 0; i < m_cache_num_sets; i++) {
7913135Sgabeblack@google.com        m_cache[i].setSize(m_cache_assoc);
8012993Sgabeblack@google.com        m_locked[i].setSize(m_cache_assoc);
8112993Sgabeblack@google.com        for (int j = 0; j < m_cache_assoc; j++) {
8212952Sgabeblack@google.com            m_cache[i][j] = NULL;
8312952Sgabeblack@google.com            m_locked[i][j] = -1;
8412952Sgabeblack@google.com        }
8512952Sgabeblack@google.com    }
8612952Sgabeblack@google.com}
8713135Sgabeblack@google.com
8813135Sgabeblack@google.comCacheMemory::~CacheMemory()
8913135Sgabeblack@google.com{
9013135Sgabeblack@google.com    if (m_replacementPolicy_ptr != NULL)
9113135Sgabeblack@google.com        delete m_replacementPolicy_ptr;
9213135Sgabeblack@google.com    delete m_profiler_ptr;
9313135Sgabeblack@google.com    for (int i = 0; i < m_cache_num_sets; i++) {
9413135Sgabeblack@google.com        for (int j = 0; j < m_cache_assoc; j++) {
9512993Sgabeblack@google.com            delete m_cache[i][j];
9613194Sgabeblack@google.com        }
9712993Sgabeblack@google.com    }
9812952Sgabeblack@google.com}
9912952Sgabeblack@google.com
10012952Sgabeblack@google.comvoid
10112952Sgabeblack@google.comCacheMemory::printConfig(ostream& out)
10212837Sgabeblack@google.com{
10312837Sgabeblack@google.com    int block_size = RubySystem::getBlockSizeBytes();
10412837Sgabeblack@google.com
10513091Sgabeblack@google.com    out << "Cache config: " << m_cache_name << endl;
10612951Sgabeblack@google.com    out << "  cache_associativity: " << m_cache_assoc << endl;
10712951Sgabeblack@google.com    out << "  num_cache_sets_bits: " << m_cache_num_set_bits << endl;
10812837Sgabeblack@google.com    const int cache_num_sets = 1 << m_cache_num_set_bits;
10913091Sgabeblack@google.com    out << "  num_cache_sets: " << cache_num_sets << endl;
11012951Sgabeblack@google.com    out << "  cache_set_size_bytes: " << cache_num_sets * block_size << endl;
11112951Sgabeblack@google.com    out << "  cache_set_size_Kbytes: "
11212837Sgabeblack@google.com        << double(cache_num_sets * block_size) / (1<<10) << endl;
11313091Sgabeblack@google.com    out << "  cache_set_size_Mbytes: "
11412837Sgabeblack@google.com        << double(cache_num_sets * block_size) / (1<<20) << endl;
11512982Sgabeblack@google.com    out << "  cache_size_bytes: "
11612837Sgabeblack@google.com        << cache_num_sets * block_size * m_cache_assoc << endl;
11713091Sgabeblack@google.com    out << "  cache_size_Kbytes: "
11812837Sgabeblack@google.com        << double(cache_num_sets * block_size * m_cache_assoc) / (1<<10)
11912837Sgabeblack@google.com        << endl;
12012837Sgabeblack@google.com    out << "  cache_size_Mbytes: "
12112837Sgabeblack@google.com        << double(cache_num_sets * block_size * m_cache_assoc) / (1<<20)
12212837Sgabeblack@google.com        << endl;
12312837Sgabeblack@google.com}
12412837Sgabeblack@google.com
12512837Sgabeblack@google.com// convert a Address to its location in the cache
12612837Sgabeblack@google.comIndex
12712837Sgabeblack@google.comCacheMemory::addressToCacheSet(const Address& address) const
12812837Sgabeblack@google.com{
12912837Sgabeblack@google.com    assert(address == line_address(address));
13012837Sgabeblack@google.com    return address.bitSelect(RubySystem::getBlockSizeBits(),
13112837Sgabeblack@google.com        RubySystem::getBlockSizeBits() + m_cache_num_set_bits - 1);
13212837Sgabeblack@google.com}
13312837Sgabeblack@google.com
13412837Sgabeblack@google.com// Given a cache index: returns the index of the tag in a set.
13512837Sgabeblack@google.com// returns -1 if the tag is not found.
13612837Sgabeblack@google.comint
13712837Sgabeblack@google.comCacheMemory::findTagInSet(Index cacheSet, const Address& tag) const
13812837Sgabeblack@google.com{
13912837Sgabeblack@google.com    assert(tag == line_address(tag));
14012837Sgabeblack@google.com    // search the set for the tags
14112837Sgabeblack@google.com    m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag);
14212837Sgabeblack@google.com    if (it != m_tag_index.end())
14312837Sgabeblack@google.com        if (m_cache[cacheSet][it->second]->m_Permission !=
14412837Sgabeblack@google.com            AccessPermission_NotPresent)
14512837Sgabeblack@google.com            return it->second;
14612837Sgabeblack@google.com    return -1; // Not found
14712837Sgabeblack@google.com}
14812837Sgabeblack@google.com
14912837Sgabeblack@google.com// Given a cache index: returns the index of the tag in a set.
15012837Sgabeblack@google.com// returns -1 if the tag is not found.
15112837Sgabeblack@google.comint
15212837Sgabeblack@google.comCacheMemory::findTagInSetIgnorePermissions(Index cacheSet,
15312837Sgabeblack@google.com                                           const Address& tag) const
15412837Sgabeblack@google.com{
15512837Sgabeblack@google.com    assert(tag == line_address(tag));
15612837Sgabeblack@google.com    // search the set for the tags
15712837Sgabeblack@google.com    m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag);
15812837Sgabeblack@google.com    if (it != m_tag_index.end())
15912837Sgabeblack@google.com        return it->second;
16012837Sgabeblack@google.com    return -1; // Not found
16112837Sgabeblack@google.com}
16212837Sgabeblack@google.com
16312837Sgabeblack@google.combool
16412837Sgabeblack@google.comCacheMemory::tryCacheAccess(const Address& address, CacheRequestType type,
16512837Sgabeblack@google.com                            DataBlock*& data_ptr)
16612837Sgabeblack@google.com{
16712837Sgabeblack@google.com    assert(address == line_address(address));
16812837Sgabeblack@google.com    DEBUG_EXPR(CACHE_COMP, HighPrio, address);
16912837Sgabeblack@google.com    Index cacheSet = addressToCacheSet(address);
17012837Sgabeblack@google.com    int loc = findTagInSet(cacheSet, address);
17112837Sgabeblack@google.com    if (loc != -1) {
17212837Sgabeblack@google.com        // Do we even have a tag match?
17312837Sgabeblack@google.com        AbstractCacheEntry* entry = m_cache[cacheSet][loc];
17412837Sgabeblack@google.com        m_replacementPolicy_ptr->
17512837Sgabeblack@google.com            touch(cacheSet, loc, g_eventQueue_ptr->getTime());
17612837Sgabeblack@google.com        data_ptr = &(entry->getDataBlk());
17712837Sgabeblack@google.com
17812837Sgabeblack@google.com        if (entry->m_Permission == AccessPermission_Read_Write) {
17912837Sgabeblack@google.com            return true;
18012837Sgabeblack@google.com        }
18112837Sgabeblack@google.com        if ((entry->m_Permission == AccessPermission_Read_Only) &&
18212837Sgabeblack@google.com            (type == CacheRequestType_LD || type == CacheRequestType_IFETCH)) {
18312837Sgabeblack@google.com            return true;
18412837Sgabeblack@google.com        }
18513091Sgabeblack@google.com        // The line must not be accessible
18613091Sgabeblack@google.com    }
18713091Sgabeblack@google.com    data_ptr = NULL;
18813091Sgabeblack@google.com    return false;
18913091Sgabeblack@google.com}
19013091Sgabeblack@google.com
19113091Sgabeblack@google.combool
19213091Sgabeblack@google.comCacheMemory::testCacheAccess(const Address& address, CacheRequestType type,
19313091Sgabeblack@google.com                             DataBlock*& data_ptr)
19413091Sgabeblack@google.com{
19513091Sgabeblack@google.com    assert(address == line_address(address));
19613091Sgabeblack@google.com    DEBUG_EXPR(CACHE_COMP, HighPrio, address);
19713091Sgabeblack@google.com    Index cacheSet = addressToCacheSet(address);
19813091Sgabeblack@google.com    int loc = findTagInSet(cacheSet, address);
19913091Sgabeblack@google.com
20013091Sgabeblack@google.com    if (loc != -1) {
20113091Sgabeblack@google.com        // Do we even have a tag match?
20213091Sgabeblack@google.com        AbstractCacheEntry* entry = m_cache[cacheSet][loc];
20313091Sgabeblack@google.com        m_replacementPolicy_ptr->
20413091Sgabeblack@google.com            touch(cacheSet, loc, g_eventQueue_ptr->getTime());
20513091Sgabeblack@google.com        data_ptr = &(entry->getDataBlk());
20613091Sgabeblack@google.com
20713091Sgabeblack@google.com        return m_cache[cacheSet][loc]->m_Permission !=
20813091Sgabeblack@google.com            AccessPermission_NotPresent;
20912837Sgabeblack@google.com    }
21012837Sgabeblack@google.com
21113292Sgabeblack@google.com    data_ptr = NULL;
21213292Sgabeblack@google.com    return false;
21313292Sgabeblack@google.com}
21413292Sgabeblack@google.com
21513292Sgabeblack@google.com// tests to see if an address is present in the cache
21613292Sgabeblack@google.combool
21713292Sgabeblack@google.comCacheMemory::isTagPresent(const Address& address) const
21813292Sgabeblack@google.com{
21913292Sgabeblack@google.com    assert(address == line_address(address));
22013292Sgabeblack@google.com    Index cacheSet = addressToCacheSet(address);
22113292Sgabeblack@google.com    int loc = findTagInSet(cacheSet, address);
22213292Sgabeblack@google.com
22313292Sgabeblack@google.com    if (loc == -1) {
22413292Sgabeblack@google.com        // We didn't find the tag
22513292Sgabeblack@google.com        DEBUG_EXPR(CACHE_COMP, LowPrio, address);
22613292Sgabeblack@google.com        DEBUG_MSG(CACHE_COMP, LowPrio, "No tag match");
22713292Sgabeblack@google.com        return false;
22813292Sgabeblack@google.com    }
22913292Sgabeblack@google.com    DEBUG_EXPR(CACHE_COMP, LowPrio, address);
23013292Sgabeblack@google.com    DEBUG_MSG(CACHE_COMP, LowPrio, "found");
23113292Sgabeblack@google.com    return true;
23213292Sgabeblack@google.com}
23313292Sgabeblack@google.com
23413292Sgabeblack@google.com// Returns true if there is:
23513292Sgabeblack@google.com//   a) a tag match on this address or there is
23613292Sgabeblack@google.com//   b) an unused line in the same cache "way"
23713292Sgabeblack@google.combool
23813292Sgabeblack@google.comCacheMemory::cacheAvail(const Address& address) const
23912837Sgabeblack@google.com{
24012837Sgabeblack@google.com    assert(address == line_address(address));
24112837Sgabeblack@google.com
24212951Sgabeblack@google.com    Index cacheSet = addressToCacheSet(address);
24312837Sgabeblack@google.com
24412837Sgabeblack@google.com    for (int i = 0; i < m_cache_assoc; i++) {
24512837Sgabeblack@google.com        AbstractCacheEntry* entry = m_cache[cacheSet][i];
24612837Sgabeblack@google.com        if (entry != NULL) {
24712837Sgabeblack@google.com            if (entry->m_Address == address ||
24812951Sgabeblack@google.com                entry->m_Permission == AccessPermission_NotPresent) {
24912837Sgabeblack@google.com                // Already in the cache or we found an empty entry
25012837Sgabeblack@google.com                return true;
25112951Sgabeblack@google.com            }
25213079Sgabeblack@google.com        } else {
25312951Sgabeblack@google.com            return true;
25413284Sgabeblack@google.com        }
25513284Sgabeblack@google.com    }
25613284Sgabeblack@google.com    return false;
25713284Sgabeblack@google.com}
25813284Sgabeblack@google.com
25913284Sgabeblack@google.comvoid
26013284Sgabeblack@google.comCacheMemory::allocate(const Address& address, AbstractCacheEntry* entry)
26113284Sgabeblack@google.com{
26213284Sgabeblack@google.com    assert(address == line_address(address));
26313284Sgabeblack@google.com    assert(!isTagPresent(address));
26412837Sgabeblack@google.com    assert(cacheAvail(address));
26512951Sgabeblack@google.com    DEBUG_EXPR(CACHE_COMP, HighPrio, address);
26613191Sgabeblack@google.com
26713191Sgabeblack@google.com    // Find the first open slot
26813191Sgabeblack@google.com    Index cacheSet = addressToCacheSet(address);
26913191Sgabeblack@google.com    Vector<AbstractCacheEntry*> &set = m_cache[cacheSet];
27013191Sgabeblack@google.com    for (int i = 0; i < m_cache_assoc; i++) {
27113191Sgabeblack@google.com        if (!set[i] || set[i]->m_Permission == AccessPermission_NotPresent) {
27213191Sgabeblack@google.com            set[i] = entry;  // Init entry
27312951Sgabeblack@google.com            set[i]->m_Address = address;
27412951Sgabeblack@google.com            set[i]->m_Permission = AccessPermission_Invalid;
27513191Sgabeblack@google.com            DPRINTF(RubyCache, "Allocate clearing lock for addr: %x\n",
27613191Sgabeblack@google.com                    address);
27713191Sgabeblack@google.com            m_locked[cacheSet][i] = -1;
27813191Sgabeblack@google.com            m_tag_index[address] = i;
27913191Sgabeblack@google.com
28013191Sgabeblack@google.com            m_replacementPolicy_ptr->
28113191Sgabeblack@google.com                touch(cacheSet, i, g_eventQueue_ptr->getTime());
28213191Sgabeblack@google.com
28313191Sgabeblack@google.com            return;
28413191Sgabeblack@google.com        }
28513191Sgabeblack@google.com    }
28613191Sgabeblack@google.com    ERROR_MSG("Allocate didn't find an available entry");
28712928Sgabeblack@google.com}
28812837Sgabeblack@google.com
28913260Sgabeblack@google.comvoid
29012837Sgabeblack@google.comCacheMemory::deallocate(const Address& address)
29113288Sgabeblack@google.com{
29212837Sgabeblack@google.com    assert(address == line_address(address));
29312837Sgabeblack@google.com    assert(isTagPresent(address));
29412837Sgabeblack@google.com    DEBUG_EXPR(CACHE_COMP, HighPrio, address);
29513260Sgabeblack@google.com    Index cacheSet = addressToCacheSet(address);
29612837Sgabeblack@google.com    int loc = findTagInSet(cacheSet, address);
29713288Sgabeblack@google.com    if (loc != -1) {
29812837Sgabeblack@google.com        delete m_cache[cacheSet][loc];
29912837Sgabeblack@google.com        m_cache[cacheSet][loc] = NULL;
30012837Sgabeblack@google.com        DPRINTF(RubyCache, "Deallocate clearing lock for addr: %x\n",
30113260Sgabeblack@google.com                address);
30212837Sgabeblack@google.com        m_locked[cacheSet][loc] = -1;
30313288Sgabeblack@google.com        m_tag_index.erase(address);
30412837Sgabeblack@google.com    }
30512837Sgabeblack@google.com}
30612837Sgabeblack@google.com
30713260Sgabeblack@google.com// Returns with the physical address of the conflicting cache line
30812837Sgabeblack@google.comAddress
30913288Sgabeblack@google.comCacheMemory::cacheProbe(const Address& address) const
31012837Sgabeblack@google.com{
31112837Sgabeblack@google.com    assert(address == line_address(address));
31212837Sgabeblack@google.com    assert(!cacheAvail(address));
31312837Sgabeblack@google.com
31413260Sgabeblack@google.com    Index cacheSet = addressToCacheSet(address);
31512837Sgabeblack@google.com    return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]->
31613288Sgabeblack@google.com        m_Address;
31712837Sgabeblack@google.com}
31812837Sgabeblack@google.com
31912837Sgabeblack@google.com// looks an address up in the cache
32013260Sgabeblack@google.comAbstractCacheEntry&
32112837Sgabeblack@google.comCacheMemory::lookup(const Address& address)
32213288Sgabeblack@google.com{
32312837Sgabeblack@google.com    assert(address == line_address(address));
32412837Sgabeblack@google.com    Index cacheSet = addressToCacheSet(address);
32512837Sgabeblack@google.com    int loc = findTagInSet(cacheSet, address);
32613260Sgabeblack@google.com    assert(loc != -1);
32712837Sgabeblack@google.com    return *m_cache[cacheSet][loc];
32813288Sgabeblack@google.com}
32912837Sgabeblack@google.com
33012837Sgabeblack@google.com// looks an address up in the cache
33112837Sgabeblack@google.comconst AbstractCacheEntry&
33213260Sgabeblack@google.comCacheMemory::lookup(const Address& address) const
33312837Sgabeblack@google.com{
33413288Sgabeblack@google.com    assert(address == line_address(address));
33512837Sgabeblack@google.com    Index cacheSet = addressToCacheSet(address);
33612837Sgabeblack@google.com    int loc = findTagInSet(cacheSet, address);
33712837Sgabeblack@google.com    assert(loc != -1);
33812837Sgabeblack@google.com    return *m_cache[cacheSet][loc];
33912837Sgabeblack@google.com}
34012837Sgabeblack@google.com
34113194Sgabeblack@google.comAccessPermission
34212837Sgabeblack@google.comCacheMemory::getPermission(const Address& address) const
34312837Sgabeblack@google.com{
34412837Sgabeblack@google.com    assert(address == line_address(address));
34512953Sgabeblack@google.com    return lookup(address).m_Permission;
34612837Sgabeblack@google.com}
34712953Sgabeblack@google.com
34812837Sgabeblack@google.comvoid
34912837Sgabeblack@google.comCacheMemory::changePermission(const Address& address,
35012837Sgabeblack@google.com                              AccessPermission new_perm)
35112951Sgabeblack@google.com{
35212951Sgabeblack@google.com    assert(address == line_address(address));
35312837Sgabeblack@google.com    lookup(address).m_Permission = new_perm;
35412951Sgabeblack@google.com    Index cacheSet = addressToCacheSet(address);
35512837Sgabeblack@google.com    int loc = findTagInSet(cacheSet, address);
35612951Sgabeblack@google.com    if (new_perm != AccessPermission_Read_Write) {
35712837Sgabeblack@google.com        DPRINTF(RubyCache, "Permission clearing lock for addr: %x\n", address);
35812837Sgabeblack@google.com        m_locked[cacheSet][loc] = -1;
35912837Sgabeblack@google.com    }
36012951Sgabeblack@google.com    assert(getPermission(address) == new_perm);
36112837Sgabeblack@google.com}
36212951Sgabeblack@google.com
36312837Sgabeblack@google.com// Sets the most recently used bit for a cache block
36412837Sgabeblack@google.comvoid
36512837Sgabeblack@google.comCacheMemory::setMRU(const Address& address)
36612951Sgabeblack@google.com{
36712837Sgabeblack@google.com    Index cacheSet;
36812951Sgabeblack@google.com
36912837Sgabeblack@google.com    cacheSet = addressToCacheSet(address);
37012837Sgabeblack@google.com    m_replacementPolicy_ptr->
37112837Sgabeblack@google.com        touch(cacheSet, findTagInSet(cacheSet, address),
37212951Sgabeblack@google.com              g_eventQueue_ptr->getTime());
37312837Sgabeblack@google.com}
37412951Sgabeblack@google.com
37512837Sgabeblack@google.comvoid
37612837Sgabeblack@google.comCacheMemory::profileMiss(const CacheMsg& msg)
37712837Sgabeblack@google.com{
37812951Sgabeblack@google.com    m_profiler_ptr->addStatSample(msg.getType(), msg.getAccessMode(),
37912837Sgabeblack@google.com                                  msg.getSize(), msg.getPrefetch());
38012951Sgabeblack@google.com}
38112837Sgabeblack@google.com
38212837Sgabeblack@google.comvoid
38312837Sgabeblack@google.comCacheMemory::recordCacheContents(CacheRecorder& tr) const
38412951Sgabeblack@google.com{
38512837Sgabeblack@google.com    for (int i = 0; i < m_cache_num_sets; i++) {
38612951Sgabeblack@google.com        for (int j = 0; j < m_cache_assoc; j++) {
38712837Sgabeblack@google.com            AccessPermission perm = m_cache[i][j]->m_Permission;
38812837Sgabeblack@google.com            CacheRequestType request_type = CacheRequestType_NULL;
38912837Sgabeblack@google.com            if (perm == AccessPermission_Read_Only) {
39012951Sgabeblack@google.com                if (m_is_instruction_only_cache) {
39112837Sgabeblack@google.com                    request_type = CacheRequestType_IFETCH;
39212951Sgabeblack@google.com                } else {
39312837Sgabeblack@google.com                    request_type = CacheRequestType_LD;
39412837Sgabeblack@google.com                }
39512837Sgabeblack@google.com            } else if (perm == AccessPermission_Read_Write) {
39612951Sgabeblack@google.com                request_type = CacheRequestType_ST;
39712837Sgabeblack@google.com            }
39812951Sgabeblack@google.com
39912837Sgabeblack@google.com            if (request_type != CacheRequestType_NULL) {
40012837Sgabeblack@google.com#if 0
40112837Sgabeblack@google.com                tr.addRecord(m_chip_ptr->getID(), m_cache[i][j].m_Address,
40212951Sgabeblack@google.com                             Address(0), request_type,
40312837Sgabeblack@google.com                             m_replacementPolicy_ptr->getLastAccess(i, j));
40412951Sgabeblack@google.com#endif
40512837Sgabeblack@google.com            }
40612837Sgabeblack@google.com        }
40712837Sgabeblack@google.com    }
40812951Sgabeblack@google.com}
40912837Sgabeblack@google.com
41012951Sgabeblack@google.comvoid
41112837Sgabeblack@google.comCacheMemory::print(ostream& out) const
41212837Sgabeblack@google.com{
41312837Sgabeblack@google.com    out << "Cache dump: " << m_cache_name << endl;
41412951Sgabeblack@google.com    for (int i = 0; i < m_cache_num_sets; i++) {
41512837Sgabeblack@google.com        for (int j = 0; j < m_cache_assoc; j++) {
41612951Sgabeblack@google.com            if (m_cache[i][j] != NULL) {
41712837Sgabeblack@google.com                out << "  Index: " << i
41812837Sgabeblack@google.com                    << " way: " << j
41912837Sgabeblack@google.com                    << " entry: " << *m_cache[i][j] << endl;
42012929Sgabeblack@google.com            } else {
42112929Sgabeblack@google.com                out << "  Index: " << i
42212929Sgabeblack@google.com                    << " way: " << j
42313189Sgabeblack@google.com                    << " entry: NULL" << endl;
42412929Sgabeblack@google.com            }
42512929Sgabeblack@google.com        }
42612929Sgabeblack@google.com    }
42712837Sgabeblack@google.com}
42812837Sgabeblack@google.com
42912837Sgabeblack@google.comvoid
43012951Sgabeblack@google.comCacheMemory::printData(ostream& out) const
43112837Sgabeblack@google.com{
43212837Sgabeblack@google.com    out << "printData() not supported" << endl;
43312837Sgabeblack@google.com}
43412951Sgabeblack@google.com
43512837Sgabeblack@google.comvoid
43612951Sgabeblack@google.comCacheMemory::clearStats() const
43712837Sgabeblack@google.com{
43812837Sgabeblack@google.com    m_profiler_ptr->clearStats();
43912837Sgabeblack@google.com}
44012951Sgabeblack@google.com
44112837Sgabeblack@google.comvoid
44212951Sgabeblack@google.comCacheMemory::printStats(ostream& out) const
44312837Sgabeblack@google.com{
44412837Sgabeblack@google.com    m_profiler_ptr->printStats(out);
44512837Sgabeblack@google.com}
44612951Sgabeblack@google.com
44712837Sgabeblack@google.comvoid
44812951Sgabeblack@google.comCacheMemory::getMemoryValue(const Address& addr, char* value,
44912837Sgabeblack@google.com                            unsigned size_in_bytes)
45012837Sgabeblack@google.com{
45112837Sgabeblack@google.com    AbstractCacheEntry& entry = lookup(line_address(addr));
45212951Sgabeblack@google.com    unsigned startByte = addr.getAddress() - line_address(addr).getAddress();
45312837Sgabeblack@google.com    for (unsigned i = 0; i < size_in_bytes; ++i) {
45412951Sgabeblack@google.com        value[i] = entry.getDataBlk().getByte(i + startByte);
45512837Sgabeblack@google.com    }
45612837Sgabeblack@google.com}
45712837Sgabeblack@google.com
45812951Sgabeblack@google.comvoid
45912837Sgabeblack@google.comCacheMemory::setMemoryValue(const Address& addr, char* value,
46012951Sgabeblack@google.com                            unsigned size_in_bytes)
46112837Sgabeblack@google.com{
46212837Sgabeblack@google.com    AbstractCacheEntry& entry = lookup(line_address(addr));
46312837Sgabeblack@google.com    unsigned startByte = addr.getAddress() - line_address(addr).getAddress();
46412951Sgabeblack@google.com    assert(size_in_bytes > 0);
46512837Sgabeblack@google.com    for (unsigned i = 0; i < size_in_bytes; ++i) {
46612951Sgabeblack@google.com        entry.getDataBlk().setByte(i + startByte, value[i]);
46712837Sgabeblack@google.com    }
46812837Sgabeblack@google.com
46912837Sgabeblack@google.com    // entry = lookup(line_address(addr));
47012951Sgabeblack@google.com}
47112837Sgabeblack@google.com
47212951Sgabeblack@google.comvoid
47312837Sgabeblack@google.comCacheMemory::setLocked(const Address& address, int context)
47412837Sgabeblack@google.com{
47512837Sgabeblack@google.com    DPRINTF(RubyCache, "Setting Lock for addr: %x to %d\n", address, context);
47612951Sgabeblack@google.com    assert(address == line_address(address));
47712837Sgabeblack@google.com    Index cacheSet = addressToCacheSet(address);
47812951Sgabeblack@google.com    int loc = findTagInSet(cacheSet, address);
47912837Sgabeblack@google.com    assert(loc != -1);
48012837Sgabeblack@google.com    m_locked[cacheSet][loc] = context;
48112837Sgabeblack@google.com}
48212951Sgabeblack@google.com
48312837Sgabeblack@google.comvoid
48412951Sgabeblack@google.comCacheMemory::clearLocked(const Address& address)
48512837Sgabeblack@google.com{
48612837Sgabeblack@google.com    DPRINTF(RubyCache, "Clear Lock for addr: %x\n", address);
48712837Sgabeblack@google.com    assert(address == line_address(address));
48812951Sgabeblack@google.com    Index cacheSet = addressToCacheSet(address);
48912837Sgabeblack@google.com    int loc = findTagInSet(cacheSet, address);
49012951Sgabeblack@google.com    assert(loc != -1);
49112837Sgabeblack@google.com    m_locked[cacheSet][loc] = -1;
49212837Sgabeblack@google.com}
49312837Sgabeblack@google.com
49412951Sgabeblack@google.combool
49512837Sgabeblack@google.comCacheMemory::isLocked(const Address& address, int context)
49612951Sgabeblack@google.com{
49712837Sgabeblack@google.com    assert(address == line_address(address));
49812837Sgabeblack@google.com    Index cacheSet = addressToCacheSet(address);
49912837Sgabeblack@google.com    int loc = findTagInSet(cacheSet, address);
50012951Sgabeblack@google.com    assert(loc != -1);
50112837Sgabeblack@google.com    DPRINTF(RubyCache, "Testing Lock for addr: %llx cur %d con %d\n",
50212951Sgabeblack@google.com            address, m_locked[cacheSet][loc], context);
50312837Sgabeblack@google.com    return m_locked[cacheSet][loc] == context;
50412837Sgabeblack@google.com}
50512837Sgabeblack@google.com
50612837Sgabeblack@google.com