DirectoryMemory.cc revision 6876
15443Sgblack@eecs.umich.edu
25443Sgblack@eecs.umich.edu/*
35443Sgblack@eecs.umich.edu * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
45443Sgblack@eecs.umich.edu * All rights reserved.
55443Sgblack@eecs.umich.edu *
65443Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
75443Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
85443Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
95443Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
105443Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
115443Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
125443Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
135443Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
145443Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
155443Sgblack@eecs.umich.edu * this software without specific prior written permission.
165443Sgblack@eecs.umich.edu *
175443Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
185443Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
195443Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
205443Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
215443Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
225443Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
235443Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
245443Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
255443Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
265443Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
275443Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
285443Sgblack@eecs.umich.edu */
295443Sgblack@eecs.umich.edu
305443Sgblack@eecs.umich.edu/*
315443Sgblack@eecs.umich.edu * DirectoryMemory.cc
325443Sgblack@eecs.umich.edu *
3311793Sbrandon.potter@amd.com * Description: See DirectoryMemory.hh
3411793Sbrandon.potter@amd.com *
3512334Sgabeblack@google.com * $Id$
368232Snate@binkert.org *
375443Sgblack@eecs.umich.edu */
385443Sgblack@eecs.umich.edu
395443Sgblack@eecs.umich.edu#include "mem/ruby/system/System.hh"
405635Sgblack@eecs.umich.edu#include "mem/ruby/system/DirectoryMemory.hh"
415635Sgblack@eecs.umich.edu#include "mem/ruby/slicc_interface/RubySlicc_Util.hh"
425635Sgblack@eecs.umich.edu#include "mem/ruby/slicc_interface/AbstractController.hh"
435443Sgblack@eecs.umich.edu#include "mem/gems_common/util.hh"
445635Sgblack@eecs.umich.edu
455635Sgblack@eecs.umich.eduint DirectoryMemory::m_num_directories = 0;
465635Sgblack@eecs.umich.eduint DirectoryMemory::m_num_directories_bits = 0;
475635Sgblack@eecs.umich.eduuint64_t DirectoryMemory::m_total_size_bytes = 0;
485635Sgblack@eecs.umich.edu
495635Sgblack@eecs.umich.eduDirectoryMemory::DirectoryMemory(const Params *p)
505635Sgblack@eecs.umich.edu    : SimObject(p)
515635Sgblack@eecs.umich.edu{
525642Sgblack@eecs.umich.edu    m_version = p->version;
535642Sgblack@eecs.umich.edu    m_size_bytes = p->size_mb * static_cast<uint64>(1<<20);
545642Sgblack@eecs.umich.edu    m_size_bits = log_int(m_size_bytes);
555443Sgblack@eecs.umich.edu    m_controller = p->controller;
565443Sgblack@eecs.umich.edu}
575443Sgblack@eecs.umich.edu
585443Sgblack@eecs.umich.eduvoid DirectoryMemory::init()
595443Sgblack@eecs.umich.edu{
605443Sgblack@eecs.umich.edu  m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes();
615443Sgblack@eecs.umich.edu  m_entries = new Directory_Entry*[m_num_entries];
625443Sgblack@eecs.umich.edu  for (int i=0; i < m_num_entries; i++)
635443Sgblack@eecs.umich.edu    m_entries[i] = NULL;
645443Sgblack@eecs.umich.edu
655443Sgblack@eecs.umich.edu  m_ram = g_system_ptr->getMemoryVector();
665443Sgblack@eecs.umich.edu
675443Sgblack@eecs.umich.edu  m_num_directories++;
685443Sgblack@eecs.umich.edu  m_num_directories_bits = log_int(m_num_directories);
695443Sgblack@eecs.umich.edu  m_total_size_bytes += m_size_bytes;
705443Sgblack@eecs.umich.edu}
715443Sgblack@eecs.umich.edu
725443Sgblack@eecs.umich.eduDirectoryMemory::~DirectoryMemory()
735443Sgblack@eecs.umich.edu{
745443Sgblack@eecs.umich.edu  // free up all the directory entries
7510905Sandreas.sandberg@arm.com  for (uint64 i=0;i<m_num_entries;i++) {
765443Sgblack@eecs.umich.edu    if (m_entries[i] != NULL) {
775443Sgblack@eecs.umich.edu      delete m_entries[i];
7810905Sandreas.sandberg@arm.com    }
7910905Sandreas.sandberg@arm.com  }
8010905Sandreas.sandberg@arm.com  if (m_entries != NULL) {
815443Sgblack@eecs.umich.edu    delete [] m_entries;
825443Sgblack@eecs.umich.edu  }
835443Sgblack@eecs.umich.edu}
8410905Sandreas.sandberg@arm.com
855443Sgblack@eecs.umich.eduvoid DirectoryMemory::printConfig(ostream& out) const
865443Sgblack@eecs.umich.edu{
8710905Sandreas.sandberg@arm.com  out << "DirectoryMemory module config: " << m_name << endl;
8810905Sandreas.sandberg@arm.com  out << "  controller: " << m_controller->getName() << endl;
8910905Sandreas.sandberg@arm.com  out << "  version: " << m_version << endl;
905443Sgblack@eecs.umich.edu  out << "  memory_bits: " << m_size_bits << endl;
915443Sgblack@eecs.umich.edu  out << "  memory_size_bytes: " << m_size_bytes << endl;
9210642Scdirik@micron.com  out << "  memory_size_Kbytes: " << double(m_size_bytes) / (1<<10) << endl;
9310642Scdirik@micron.com  out << "  memory_size_Mbytes: " << double(m_size_bytes) / (1<<20) << endl;
9410642Scdirik@micron.com  out << "  memory_size_Gbytes: " << double(m_size_bytes) / (1<<30) << endl;
9510642Scdirik@micron.com}
9610642Scdirik@micron.com
9710642Scdirik@micron.com// Static method
9810642Scdirik@micron.comvoid DirectoryMemory::printGlobalConfig(ostream & out)
9910642Scdirik@micron.com{
1005642Sgblack@eecs.umich.edu  out << "DirectoryMemory Global Config: " << endl;
1015642Sgblack@eecs.umich.edu  out << "  number of directory memories: " << m_num_directories << endl;
10210642Scdirik@micron.com  if (m_num_directories > 1) {
10310642Scdirik@micron.com    out << "  number of selection bits: " << m_num_directories_bits << endl;
10410642Scdirik@micron.com    out << "  selection bits: " << RubySystem::getBlockSizeBits()+m_num_directories_bits-1
10510642Scdirik@micron.com        << "-" << RubySystem::getBlockSizeBits() << endl;
1065443Sgblack@eecs.umich.edu  }
10710642Scdirik@micron.com  out << "  total memory size bytes: " << m_total_size_bytes << endl;
1085443Sgblack@eecs.umich.edu  out << "  total memory size bits: " << log_int(m_total_size_bytes) << endl;
1095443Sgblack@eecs.umich.edu
1105443Sgblack@eecs.umich.edu}
1115443Sgblack@eecs.umich.edu
1125443Sgblack@eecs.umich.eduint DirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address)
1135443Sgblack@eecs.umich.edu{
11411321Ssteve.reinhardt@amd.com  if (m_num_directories_bits == 0) return 0;
1155443Sgblack@eecs.umich.edu  int ret = address.bitSelect(RubySystem::getBlockSizeBits(),
1165443Sgblack@eecs.umich.edu                              RubySystem::getBlockSizeBits()+m_num_directories_bits-1);
1176067Sgblack@eecs.umich.edu  return ret;
1185443Sgblack@eecs.umich.edu}
1195443Sgblack@eecs.umich.edu
1205443Sgblack@eecs.umich.edu// Public method
1216067Sgblack@eecs.umich.edubool DirectoryMemory::isPresent(PhysAddress address)
1226067Sgblack@eecs.umich.edu{
1236067Sgblack@eecs.umich.edu  bool ret = (mapAddressToDirectoryVersion(address) == m_version);
1246067Sgblack@eecs.umich.edu  return ret;
1256067Sgblack@eecs.umich.edu}
1266067Sgblack@eecs.umich.edu
1276067Sgblack@eecs.umich.eduint DirectoryMemory::mapAddressToLocalIdx(PhysAddress address)
1286067Sgblack@eecs.umich.edu{
1296067Sgblack@eecs.umich.edu  int ret = address.getAddress() >> (RubySystem::getBlockSizeBits() + m_num_directories_bits);
1306067Sgblack@eecs.umich.edu  return ret;
1316067Sgblack@eecs.umich.edu}
1326067Sgblack@eecs.umich.edu
1336067Sgblack@eecs.umich.eduDirectory_Entry& DirectoryMemory::lookup(PhysAddress address)
1346067Sgblack@eecs.umich.edu{
1355443Sgblack@eecs.umich.edu  assert(isPresent(address));
1365443Sgblack@eecs.umich.edu  Directory_Entry* entry;
1375443Sgblack@eecs.umich.edu  int idx = mapAddressToLocalIdx(address);
1385443Sgblack@eecs.umich.edu  entry = m_entries[idx];
1395443Sgblack@eecs.umich.edu  if (entry == NULL) {
1405443Sgblack@eecs.umich.edu    entry = new Directory_Entry;
1415443Sgblack@eecs.umich.edu    entry->getDataBlk().assign(m_ram->getBlockPtr(address));
1425443Sgblack@eecs.umich.edu    m_entries[idx] = entry;
1435443Sgblack@eecs.umich.edu  }
1445443Sgblack@eecs.umich.edu  return (*entry);
1455443Sgblack@eecs.umich.edu}
1465443Sgblack@eecs.umich.edu/*
1475443Sgblack@eecs.umich.eduDirectory_Entry& DirectoryMemory::lookup(PhysAddress address)
1485443Sgblack@eecs.umich.edu{
1495443Sgblack@eecs.umich.edu  assert(isPresent(address));
1505443Sgblack@eecs.umich.edu  Index index = address.memoryModuleIndex();
1515443Sgblack@eecs.umich.edu
1525443Sgblack@eecs.umich.edu  if (index < 0 || index > m_size) {
1536067Sgblack@eecs.umich.edu    WARN_EXPR(address.getAddress());
1545443Sgblack@eecs.umich.edu    WARN_EXPR(index);
1555443Sgblack@eecs.umich.edu    WARN_EXPR(m_size);
1565443Sgblack@eecs.umich.edu    ERROR_MSG("Directory Memory Assertion: accessing memory out of range.");
1575443Sgblack@eecs.umich.edu  }
1585443Sgblack@eecs.umich.edu  Directory_Entry* entry = m_entries[index];
1595443Sgblack@eecs.umich.edu
1605443Sgblack@eecs.umich.edu  // allocate the directory entry on demand.
1615443Sgblack@eecs.umich.edu  if (entry == NULL) {
1625443Sgblack@eecs.umich.edu    entry = new Directory_Entry;
1635443Sgblack@eecs.umich.edu    entry->getDataBlk().assign(m_ram->getBlockPtr(address));
1645443Sgblack@eecs.umich.edu
1655443Sgblack@eecs.umich.edu    // store entry to the table
1665443Sgblack@eecs.umich.edu    m_entries[index] = entry;
1675443Sgblack@eecs.umich.edu  }
1685443Sgblack@eecs.umich.edu
1695443Sgblack@eecs.umich.edu  return (*entry);
1705443Sgblack@eecs.umich.edu}
1715443Sgblack@eecs.umich.edu*/
1725443Sgblack@eecs.umich.edu
1735443Sgblack@eecs.umich.eduvoid DirectoryMemory::invalidateBlock(PhysAddress address)
1746067Sgblack@eecs.umich.edu{
1755443Sgblack@eecs.umich.edu  /*
1765443Sgblack@eecs.umich.edu  assert(isPresent(address));
1775606Snate@binkert.org
1785443Sgblack@eecs.umich.edu  Index index = address.memoryModuleIndex();
1795443Sgblack@eecs.umich.edu
1805443Sgblack@eecs.umich.edu  if (index < 0 || index > m_size) {
1815443Sgblack@eecs.umich.edu    ERROR_MSG("Directory Memory Assertion: accessing memory out of range.");
1825443Sgblack@eecs.umich.edu  }
1836067Sgblack@eecs.umich.edu
1845444Sgblack@eecs.umich.edu  if(m_entries[index] != NULL){
1855444Sgblack@eecs.umich.edu    delete m_entries[index];
1865444Sgblack@eecs.umich.edu    m_entries[index] = NULL;
1876067Sgblack@eecs.umich.edu  }
1885444Sgblack@eecs.umich.edu  */
1896067Sgblack@eecs.umich.edu}
1905443Sgblack@eecs.umich.edu
19110642Scdirik@micron.comvoid DirectoryMemory::print(ostream& out) const
19210642Scdirik@micron.com{
19310642Scdirik@micron.com
1945444Sgblack@eecs.umich.edu}
1955444Sgblack@eecs.umich.edu
1965443Sgblack@eecs.umich.eduDirectoryMemory *
1975443Sgblack@eecs.umich.eduRubyDirectoryMemoryParams::create()
1985443Sgblack@eecs.umich.edu{
1995443Sgblack@eecs.umich.edu    return new DirectoryMemory(this);
2005443Sgblack@eecs.umich.edu}
2015443Sgblack@eecs.umich.edu