16145SN/A/*
212065Snikos.nikoleris@arm.com * Copyright (c) 2017 ARM Limited
312065Snikos.nikoleris@arm.com * All rights reserved.
412065Snikos.nikoleris@arm.com *
512065Snikos.nikoleris@arm.com * The license below extends only to copyright in the software and shall
612065Snikos.nikoleris@arm.com * not be construed as granting a license to any other intellectual
712065Snikos.nikoleris@arm.com * property including but not limited to intellectual property relating
812065Snikos.nikoleris@arm.com * to a hardware implementation of the functionality of the software
912065Snikos.nikoleris@arm.com * licensed hereunder.  You may use the software subject to the license
1012065Snikos.nikoleris@arm.com * terms below provided that you ensure that this notice is replicated
1112065Snikos.nikoleris@arm.com * unmodified and in its entirety in all distributions of the software,
1212065Snikos.nikoleris@arm.com * modified or unmodified, in source code or in binary form.
1312065Snikos.nikoleris@arm.com *
146145SN/A * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
1511903Sleolson@google.com * Copyright (c) 2017 Google Inc.
166145SN/A * All rights reserved.
176145SN/A *
186145SN/A * Redistribution and use in source and binary forms, with or without
196145SN/A * modification, are permitted provided that the following conditions are
206145SN/A * met: redistributions of source code must retain the above copyright
216145SN/A * notice, this list of conditions and the following disclaimer;
226145SN/A * redistributions in binary form must reproduce the above copyright
236145SN/A * notice, this list of conditions and the following disclaimer in the
246145SN/A * documentation and/or other materials provided with the distribution;
256145SN/A * neither the name of the copyright holders nor the names of its
266145SN/A * contributors may be used to endorse or promote products derived from
276145SN/A * this software without specific prior written permission.
286145SN/A *
296145SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
306145SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
316145SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
326145SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
336145SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
346145SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
356145SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
366145SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
376145SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
386145SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
396145SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4011903Sleolson@google.com *
4111903Sleolson@google.com * Authors: Lena Olson
426145SN/A */
436145SN/A
4411793Sbrandon.potter@amd.com#include "mem/ruby/structures/DirectoryMemory.hh"
4511793Sbrandon.potter@amd.com
4612065Snikos.nikoleris@arm.com#include "base/addr_range.hh"
477056SN/A#include "base/intmath.hh"
488232SN/A#include "debug/RubyCache.hh"
499104SN/A#include "debug/RubyStats.hh"
507039SN/A#include "mem/ruby/slicc_interface/RubySlicc_Util.hh"
5111108Sdavid.hashe@amd.com#include "mem/ruby/system/RubySystem.hh"
5211903Sleolson@google.com#include "sim/system.hh"
536145SN/A
547055SN/Ausing namespace std;
557055SN/A
566876SN/ADirectoryMemory::DirectoryMemory(const Params *p)
5712065Snikos.nikoleris@arm.com    : SimObject(p), addrRanges(p->addr_ranges.begin(), p->addr_ranges.end())
586145SN/A{
5912065Snikos.nikoleris@arm.com    m_size_bytes = 0;
6012065Snikos.nikoleris@arm.com    for (const auto &r: addrRanges) {
6112065Snikos.nikoleris@arm.com        m_size_bytes += r.size();
6211903Sleolson@google.com    }
637056SN/A    m_size_bits = floorLog2(m_size_bytes);
647025SN/A    m_num_entries = 0;
656285SN/A}
666285SN/A
677039SN/Avoid
687039SN/ADirectoryMemory::init()
696285SN/A{
707039SN/A    m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes();
7110520Snilay@cs.wisc.edu    m_entries = new AbstractEntry*[m_num_entries];
7210520Snilay@cs.wisc.edu    for (int i = 0; i < m_num_entries; i++)
7310520Snilay@cs.wisc.edu        m_entries[i] = NULL;
746145SN/A}
756145SN/A
766145SN/ADirectoryMemory::~DirectoryMemory()
776145SN/A{
787039SN/A    // free up all the directory entries
7911025Snilay@cs.wisc.edu    for (uint64_t i = 0; i < m_num_entries; i++) {
8010520Snilay@cs.wisc.edu        if (m_entries[i] != NULL) {
8110520Snilay@cs.wisc.edu            delete m_entries[i];
827039SN/A        }
837039SN/A    }
8410520Snilay@cs.wisc.edu    delete [] m_entries;
856285SN/A}
866145SN/A
877039SN/Abool
8811025Snilay@cs.wisc.eduDirectoryMemory::isPresent(Addr address)
896145SN/A{
9012065Snikos.nikoleris@arm.com    for (const auto& r: addrRanges) {
9112065Snikos.nikoleris@arm.com        if (r.contains(address)) {
9212065Snikos.nikoleris@arm.com            return true;
9312065Snikos.nikoleris@arm.com        }
9412065Snikos.nikoleris@arm.com    }
9512065Snikos.nikoleris@arm.com    return false;
966145SN/A}
976145SN/A
9811025Snilay@cs.wisc.eduuint64_t
9911025Snilay@cs.wisc.eduDirectoryMemory::mapAddressToLocalIdx(Addr address)
1006161SN/A{
10112065Snikos.nikoleris@arm.com    uint64_t ret = 0;
10212065Snikos.nikoleris@arm.com    for (const auto& r: addrRanges) {
10312065Snikos.nikoleris@arm.com        if (r.contains(address)) {
10412065Snikos.nikoleris@arm.com            ret += r.getOffset(address);
10512065Snikos.nikoleris@arm.com            break;
10612065Snikos.nikoleris@arm.com        }
10712065Snikos.nikoleris@arm.com        ret += r.size();
1087563SN/A    }
10912065Snikos.nikoleris@arm.com    return ret >> RubySystem::getBlockSizeBits();
1106161SN/A}
1116161SN/A
1128644SN/AAbstractEntry*
11311025Snilay@cs.wisc.eduDirectoryMemory::lookup(Addr address)
1146145SN/A{
1157039SN/A    assert(isPresent(address));
11611118Snilay@cs.wisc.edu    DPRINTF(RubyCache, "Looking up address: %#x\n", address);
1178644SN/A
11810520Snilay@cs.wisc.edu    uint64_t idx = mapAddressToLocalIdx(address);
11910520Snilay@cs.wisc.edu    assert(idx < m_num_entries);
12010520Snilay@cs.wisc.edu    return m_entries[idx];
1218644SN/A}
1228644SN/A
1238644SN/AAbstractEntry*
12411025Snilay@cs.wisc.eduDirectoryMemory::allocate(Addr address, AbstractEntry *entry)
1258644SN/A{
1268644SN/A    assert(isPresent(address));
12711025Snilay@cs.wisc.edu    uint64_t idx;
12811118Snilay@cs.wisc.edu    DPRINTF(RubyCache, "Looking up address: %#x\n", address);
1297025SN/A
13010520Snilay@cs.wisc.edu    idx = mapAddressToLocalIdx(address);
13110520Snilay@cs.wisc.edu    assert(idx < m_num_entries);
13210520Snilay@cs.wisc.edu    entry->changePermission(AccessPermission_Read_Only);
13310520Snilay@cs.wisc.edu    m_entries[idx] = entry;
1346145SN/A
1358644SN/A    return entry;
1366145SN/A}
1376145SN/A
1387039SN/Avoid
1397039SN/ADirectoryMemory::print(ostream& out) const
1407039SN/A{
1417039SN/A}
1427039SN/A
1437039SN/Avoid
1449104SN/ADirectoryMemory::recordRequestType(DirectoryRequestType requestType) {
1459104SN/A    DPRINTF(RubyStats, "Recorded statistic: %s\n",
1469104SN/A            DirectoryRequestType_to_string(requestType));
1479104SN/A}
1489104SN/A
1496876SN/ADirectoryMemory *
1506876SN/ARubyDirectoryMemoryParams::create()
1516876SN/A{
1526876SN/A    return new DirectoryMemory(this);
1536876SN/A}
154