DirectoryMemory.cc revision 8232
12689Sktlim@umich.edu/*
22689Sktlim@umich.edu * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
32689Sktlim@umich.edu * All rights reserved.
42689Sktlim@umich.edu *
52689Sktlim@umich.edu * Redistribution and use in source and binary forms, with or without
62689Sktlim@umich.edu * modification, are permitted provided that the following conditions are
72689Sktlim@umich.edu * met: redistributions of source code must retain the above copyright
82689Sktlim@umich.edu * notice, this list of conditions and the following disclaimer;
92689Sktlim@umich.edu * redistributions in binary form must reproduce the above copyright
102689Sktlim@umich.edu * notice, this list of conditions and the following disclaimer in the
112689Sktlim@umich.edu * documentation and/or other materials provided with the distribution;
122689Sktlim@umich.edu * neither the name of the copyright holders nor the names of its
132689Sktlim@umich.edu * contributors may be used to endorse or promote products derived from
142689Sktlim@umich.edu * this software without specific prior written permission.
152689Sktlim@umich.edu *
162689Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172689Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182689Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192689Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202689Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212689Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222689Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232689Sktlim@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242689Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252689Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262689Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272689Sktlim@umich.edu */
282689Sktlim@umich.edu
292689Sktlim@umich.edu#include "base/intmath.hh"
302689Sktlim@umich.edu#include "debug/RubyCache.hh"
312689Sktlim@umich.edu#include "mem/ruby/slicc_interface/RubySlicc_Util.hh"
322689Sktlim@umich.edu#include "mem/ruby/system/DirectoryMemory.hh"
332689Sktlim@umich.edu#include "mem/ruby/system/System.hh"
342521SN/A
353960Sgblack@eecs.umich.eduusing namespace std;
364194Ssaidi@eecs.umich.edu
371070SN/Aint DirectoryMemory::m_num_directories = 0;
381070SN/Aint DirectoryMemory::m_num_directories_bits = 0;
392521SN/Auint64_t DirectoryMemory::m_total_size_bytes = 0;
402680Sktlim@umich.eduint DirectoryMemory::m_numa_high_bit = 0;
412521SN/A
422522SN/ADirectoryMemory::DirectoryMemory(const Params *p)
432037SN/A    : SimObject(p)
4456SN/A{
455512SMichael.Adler@intel.com    m_version = p->version;
462378SN/A    m_size_bytes = p->size;
472521SN/A    m_size_bits = floorLog2(m_size_bytes);
482378SN/A    m_num_entries = 0;
494762Snate@binkert.org    m_use_map = p->use_map;
504762Snate@binkert.org    m_map_levels = p->map_levels;
512378SN/A    m_numa_high_bit = p->numa_high_bit;
522SN/A}
532SN/A
542107SN/Avoid
552SN/ADirectoryMemory::init()
562SN/A{
572SN/A    m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes();
582SN/A
592SN/A    if (m_use_map) {
601070SN/A        m_sparseMemory = new SparseMemory(m_map_levels);
615034Smilesck@eecs.umich.edu    } else {
622378SN/A        m_entries = new Directory_Entry*[m_num_entries];
632521SN/A        for (int i = 0; i < m_num_entries; i++)
642640Sstever@eecs.umich.edu            m_entries[i] = NULL;
652640Sstever@eecs.umich.edu        m_ram = g_system_ptr->getMemoryVector();
662378SN/A    }
672378SN/A
684997Sgblack@eecs.umich.edu    m_num_directories++;
692378SN/A    m_num_directories_bits = floorLog2(m_num_directories);
702902Ssaidi@eecs.umich.edu    m_total_size_bytes += m_size_bytes;
712SN/A
721070SN/A    if (m_numa_high_bit == 0) {
731070SN/A        m_numa_high_bit = RubySystem::getMemorySizeBits() - 1;
741070SN/A    }
752378SN/A    assert(m_numa_high_bit != 0);
761070SN/A}
774838Ssaidi@eecs.umich.edu
784838Ssaidi@eecs.umich.eduDirectoryMemory::~DirectoryMemory()
791070SN/A{
802520SN/A    // free up all the directory entries
812520SN/A    if (m_entries != NULL) {
822520SN/A        for (uint64 i = 0; i < m_num_entries; i++) {
832520SN/A            if (m_entries[i] != NULL) {
842520SN/A                delete m_entries[i];
852520SN/A            }
862520SN/A        }
872520SN/A        delete [] m_entries;
882520SN/A    } else if (m_use_map) {
892521SN/A        delete m_sparseMemory;
902521SN/A    }
912521SN/A}
922521SN/A
932520SN/Avoid
941070SN/ADirectoryMemory::printConfig(ostream& out) const
952158SN/A{
961070SN/A    out << "DirectoryMemory module config: " << m_name << endl
974762Snate@binkert.org        << "  version: " << m_version << endl
983812Ssaidi@eecs.umich.edu        << "  memory_bits: " << m_size_bits << endl
993812Ssaidi@eecs.umich.edu        << "  memory_size_bytes: " << m_size_bytes << endl
1003812Ssaidi@eecs.umich.edu        << "  memory_size_Kbytes: " << double(m_size_bytes) / (1<<10) << endl
1013812Ssaidi@eecs.umich.edu        << "  memory_size_Mbytes: " << double(m_size_bytes) / (1<<20) << endl
1024762Snate@binkert.org        << "  memory_size_Gbytes: " << double(m_size_bytes) / (1<<30) << endl;
1035222Sksewell@umich.edu}
1045222Sksewell@umich.edu
1053812Ssaidi@eecs.umich.edu// Static method
1064762Snate@binkert.orgvoid
1071070SN/ADirectoryMemory::printGlobalConfig(ostream & out)
1083812Ssaidi@eecs.umich.edu{
1093812Ssaidi@eecs.umich.edu    out << "DirectoryMemory Global Config: " << endl;
1101070SN/A    out << "  number of directory memories: " << m_num_directories << endl;
1113812Ssaidi@eecs.umich.edu    if (m_num_directories > 1) {
1123812Ssaidi@eecs.umich.edu        out << "  number of selection bits: " << m_num_directories_bits << endl
1133812Ssaidi@eecs.umich.edu            << "  selection bits: " << m_numa_high_bit
1143812Ssaidi@eecs.umich.edu            << "-" << m_numa_high_bit-m_num_directories_bits
1151070SN/A            << endl;
1163812Ssaidi@eecs.umich.edu    }
1173812Ssaidi@eecs.umich.edu    out << "  total memory size bytes: " << m_total_size_bytes << endl;
1183812Ssaidi@eecs.umich.edu    out << "  total memory bits: " << floorLog2(m_total_size_bytes) << endl;
1191070SN/A}
1203812Ssaidi@eecs.umich.edu
1213812Ssaidi@eecs.umich.eduuint64
1221070SN/ADirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address)
1233812Ssaidi@eecs.umich.edu{
1243812Ssaidi@eecs.umich.edu    if (m_num_directories_bits == 0)
1251074SN/A        return 0;
1263812Ssaidi@eecs.umich.edu
1273812Ssaidi@eecs.umich.edu    uint64 ret = address.bitSelect(m_numa_high_bit - m_num_directories_bits + 1,
1281074SN/A                                   m_numa_high_bit);
1293812Ssaidi@eecs.umich.edu    return ret;
1303812Ssaidi@eecs.umich.edu}
1313812Ssaidi@eecs.umich.edu
1323812Ssaidi@eecs.umich.edubool
1333812Ssaidi@eecs.umich.eduDirectoryMemory::isPresent(PhysAddress address)
1342378SN/A{
1352378SN/A    bool ret = (mapAddressToDirectoryVersion(address) == m_version);
1361070SN/A    return ret;
137878SN/A}
1382SN/A
1392SN/Auint64
1402SN/ADirectoryMemory::mapAddressToLocalIdx(PhysAddress address)
1412SN/A{
1422378SN/A    uint64 ret;
1431070SN/A    if (m_num_directories_bits > 0) {
1441070SN/A        ret = address.bitRemove(m_numa_high_bit - m_num_directories_bits + 1,
1452378SN/A                                m_numa_high_bit);
1462378SN/A    } else {
1472378SN/A        ret = address.getAddress();
1482378SN/A    }
1492SN/A
1502SN/A    return ret >> (RubySystem::getBlockSizeBits());
1511808SN/A}
1524095Sbinkertn@umich.edu
1531808SN/ADirectory_Entry&
1542901Ssaidi@eecs.umich.eduDirectoryMemory::lookup(PhysAddress address)
1554762Snate@binkert.org{
1562901Ssaidi@eecs.umich.edu    assert(isPresent(address));
1572901Ssaidi@eecs.umich.edu    Directory_Entry* entry;
1582901Ssaidi@eecs.umich.edu    uint64 idx;
1592901Ssaidi@eecs.umich.edu    DPRINTF(RubyCache, "address: %s\n", address);
1602901Ssaidi@eecs.umich.edu
1613960Sgblack@eecs.umich.edu    if (m_use_map) {
1623960Sgblack@eecs.umich.edu        if (m_sparseMemory->exist(address)) {
1634095Sbinkertn@umich.edu            entry = m_sparseMemory->lookup(address);
1644095Sbinkertn@umich.edu            assert(entry != NULL);
1654095Sbinkertn@umich.edu        } else {
1663960Sgblack@eecs.umich.edu            // Note: SparseMemory internally creates a new Directory Entry
1673960Sgblack@eecs.umich.edu            m_sparseMemory->add(address);
168180SN/A            entry = m_sparseMemory->lookup(address);
1695712Shsul@eecs.umich.edu        }
1702SN/A    } else {
1715712Shsul@eecs.umich.edu        idx = mapAddressToLocalIdx(address);
1725712Shsul@eecs.umich.edu        assert(idx < m_num_entries);
1735712Shsul@eecs.umich.edu        entry = m_entries[idx];
1745712Shsul@eecs.umich.edu
1751806SN/A        if (entry == NULL) {
1761806SN/A            entry = new Directory_Entry();
1772680Sktlim@umich.edu            entry->getDataBlk().assign(m_ram->getBlockPtr(address));
1782680Sktlim@umich.edu            m_entries[idx] = entry;
1791806SN/A        }
1802680Sktlim@umich.edu    }
1811806SN/A
1821806SN/A    return *entry;
1832680Sktlim@umich.edu}
1841806SN/A
1851070SN/A#if 0
1865512SMichael.Adler@intel.comDirectory_Entry&
1875512SMichael.Adler@intel.comDirectoryMemory::lookup(PhysAddress address)
1884095Sbinkertn@umich.edu{
1895512SMichael.Adler@intel.com    assert(isPresent(address));
1904095Sbinkertn@umich.edu    Index index = address.memoryModuleIndex();
1914095Sbinkertn@umich.edu
1924095Sbinkertn@umich.edu    if (index < 0 || index > m_size) {
1934095Sbinkertn@umich.edu        WARN_EXPR(address.getAddress());
1944095Sbinkertn@umich.edu        WARN_EXPR(index);
1954095Sbinkertn@umich.edu        WARN_EXPR(m_size);
1964095Sbinkertn@umich.edu        ERROR_MSG("Directory Memory Assertion: accessing memory out of range");
1971070SN/A    }
1984095Sbinkertn@umich.edu    Directory_Entry* entry = m_entries[index];
1994095Sbinkertn@umich.edu
2004095Sbinkertn@umich.edu    // allocate the directory entry on demand.
2014095Sbinkertn@umich.edu    if (entry == NULL) {
2024095Sbinkertn@umich.edu        entry = new Directory_Entry;
2031070SN/A        entry->getDataBlk().assign(m_ram->getBlockPtr(address));
2041070SN/A
2051806SN/A        // store entry to the table
206180SN/A        m_entries[index] = entry;
20775SN/A    }
208180SN/A
2091129SN/A    return *entry;
2101129SN/A}
2115713Shsul@eecs.umich.edu#endif
2122114SN/A
2132680Sktlim@umich.eduvoid
2144194Ssaidi@eecs.umich.eduDirectoryMemory::invalidateBlock(PhysAddress address)
2155713Shsul@eecs.umich.edu{
2161129SN/A    if (m_use_map) {
2171129SN/A        assert(m_sparseMemory->exist(address));
2181129SN/A        m_sparseMemory->remove(address);
2195713Shsul@eecs.umich.edu    }
220180SN/A#if 0
2215713Shsul@eecs.umich.edu    else {
2222680Sktlim@umich.edu        assert(isPresent(address));
2235713Shsul@eecs.umich.edu
224180SN/A        Index index = address.memoryModuleIndex();
225180SN/A
2265713Shsul@eecs.umich.edu        if (index < 0 || index > m_size) {
2275713Shsul@eecs.umich.edu            ERROR_MSG("Directory Memory Assertion: "
2285713Shsul@eecs.umich.edu                      "accessing memory out of range.");
2292SN/A        }
2302SN/A
2312378SN/A        if (m_entries[index] != NULL){
2322378SN/A            delete m_entries[index];
2332378SN/A            m_entries[index] = NULL;
2342378SN/A        }
2352378SN/A    }
2362378SN/A#endif
2373162Ssaidi@eecs.umich.edu}
2383162Ssaidi@eecs.umich.edu
2392378SN/Avoid
2402378SN/ADirectoryMemory::print(ostream& out) const
2412378SN/A{
2422378SN/A}
2431070SN/A
2441070SN/Avoid
2451070SN/ADirectoryMemory::printStats(ostream& out) const
2462378SN/A{
2471984SN/A    if (m_use_map) {
2485183Ssaidi@eecs.umich.edu        m_sparseMemory->printStats(out);
2495183Ssaidi@eecs.umich.edu    }
2505183Ssaidi@eecs.umich.edu}
2511070SN/A
2521070SN/ADirectoryMemory *
2531070SN/ARubyDirectoryMemoryParams::create()
2541070SN/A{
2551070SN/A    return new DirectoryMemory(this);
2561070SN/A}
2572378SN/A