dramsim2.cc revision 10066
110066Sandreas.hansson@arm.com/* 210066Sandreas.hansson@arm.com * Copyright (c) 2013 ARM Limited 310066Sandreas.hansson@arm.com * All rights reserved 410066Sandreas.hansson@arm.com * 510066Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 610066Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 710066Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 810066Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 910066Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 1010066Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 1110066Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 1210066Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 1310066Sandreas.hansson@arm.com * 1410066Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 1510066Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 1610066Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 1710066Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 1810066Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 1910066Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 2010066Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 2110066Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 2210066Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 2310066Sandreas.hansson@arm.com * this software without specific prior written permission. 2410066Sandreas.hansson@arm.com * 2510066Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610066Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710066Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810066Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910066Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010066Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110066Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210066Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310066Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410066Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510066Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610066Sandreas.hansson@arm.com * 3710066Sandreas.hansson@arm.com * Authors: Andreas Hansson 3810066Sandreas.hansson@arm.com */ 3910066Sandreas.hansson@arm.com 4010066Sandreas.hansson@arm.com#include "DRAMSim2/Callback.h" 4110066Sandreas.hansson@arm.com#include "base/callback.hh" 4210066Sandreas.hansson@arm.com#include "base/trace.hh" 4310066Sandreas.hansson@arm.com#include "debug/DRAMSim2.hh" 4410066Sandreas.hansson@arm.com#include "debug/Drain.hh" 4510066Sandreas.hansson@arm.com#include "mem/dramsim2.hh" 4610066Sandreas.hansson@arm.com#include "sim/system.hh" 4710066Sandreas.hansson@arm.com 4810066Sandreas.hansson@arm.comDRAMSim2::DRAMSim2(const Params* p) : 4910066Sandreas.hansson@arm.com AbstractMemory(p), 5010066Sandreas.hansson@arm.com port(name() + ".port", *this), 5110066Sandreas.hansson@arm.com wrapper(p->deviceConfigFile, p->systemConfigFile, p->filePath, 5210066Sandreas.hansson@arm.com p->traceFile, p->range.size() / 1024 / 1024, p->enableDebug), 5310066Sandreas.hansson@arm.com retryReq(false), retryResp(false), 5410066Sandreas.hansson@arm.com nbrOutstandingReads(0), nbrOutstandingWrites(0), 5510066Sandreas.hansson@arm.com drainManager(NULL), 5610066Sandreas.hansson@arm.com sendResponseEvent(this), tickEvent(this) 5710066Sandreas.hansson@arm.com{ 5810066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, 5910066Sandreas.hansson@arm.com "Instantiated DRAMSim2 with clock %d ns and queue size %d\n", 6010066Sandreas.hansson@arm.com wrapper.clockPeriod(), wrapper.queueSize()); 6110066Sandreas.hansson@arm.com 6210066Sandreas.hansson@arm.com DRAMSim::TransactionCompleteCB* read_cb = 6310066Sandreas.hansson@arm.com new DRAMSim::Callback<DRAMSim2, void, unsigned, uint64_t, uint64_t>( 6410066Sandreas.hansson@arm.com this, &DRAMSim2::readComplete); 6510066Sandreas.hansson@arm.com DRAMSim::TransactionCompleteCB* write_cb = 6610066Sandreas.hansson@arm.com new DRAMSim::Callback<DRAMSim2, void, unsigned, uint64_t, uint64_t>( 6710066Sandreas.hansson@arm.com this, &DRAMSim2::writeComplete); 6810066Sandreas.hansson@arm.com wrapper.setCallbacks(read_cb, write_cb); 6910066Sandreas.hansson@arm.com 7010066Sandreas.hansson@arm.com // Register a callback to compensate for the destructor not 7110066Sandreas.hansson@arm.com // being called. The callback prints the DRAMSim2 stats. 7210066Sandreas.hansson@arm.com Callback* cb = new MakeCallback<DRAMSim2Wrapper, 7310066Sandreas.hansson@arm.com &DRAMSim2Wrapper::printStats>(wrapper); 7410066Sandreas.hansson@arm.com registerExitCallback(cb); 7510066Sandreas.hansson@arm.com} 7610066Sandreas.hansson@arm.com 7710066Sandreas.hansson@arm.comvoid 7810066Sandreas.hansson@arm.comDRAMSim2::init() 7910066Sandreas.hansson@arm.com{ 8010066Sandreas.hansson@arm.com if (!port.isConnected()) { 8110066Sandreas.hansson@arm.com fatal("DRAMSim2 %s is unconnected!\n", name()); 8210066Sandreas.hansson@arm.com } else { 8310066Sandreas.hansson@arm.com port.sendRangeChange(); 8410066Sandreas.hansson@arm.com } 8510066Sandreas.hansson@arm.com 8610066Sandreas.hansson@arm.com if (system()->cacheLineSize() != wrapper.burstSize()) 8710066Sandreas.hansson@arm.com fatal("DRAMSim2 burst size %d does not match cache line size %d\n", 8810066Sandreas.hansson@arm.com wrapper.burstSize(), system()->cacheLineSize()); 8910066Sandreas.hansson@arm.com} 9010066Sandreas.hansson@arm.com 9110066Sandreas.hansson@arm.comvoid 9210066Sandreas.hansson@arm.comDRAMSim2::startup() 9310066Sandreas.hansson@arm.com{ 9410066Sandreas.hansson@arm.com // kick off the clock ticks 9510066Sandreas.hansson@arm.com schedule(tickEvent, clockEdge()); 9610066Sandreas.hansson@arm.com} 9710066Sandreas.hansson@arm.com 9810066Sandreas.hansson@arm.comvoid 9910066Sandreas.hansson@arm.comDRAMSim2::sendResponse() 10010066Sandreas.hansson@arm.com{ 10110066Sandreas.hansson@arm.com assert(!retryResp); 10210066Sandreas.hansson@arm.com assert(!responseQueue.empty()); 10310066Sandreas.hansson@arm.com 10410066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Attempting to send response\n"); 10510066Sandreas.hansson@arm.com 10610066Sandreas.hansson@arm.com bool success = port.sendTimingResp(responseQueue.front()); 10710066Sandreas.hansson@arm.com if (success) { 10810066Sandreas.hansson@arm.com responseQueue.pop_front(); 10910066Sandreas.hansson@arm.com 11010066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Have %d read, %d write, %d responses outstanding\n", 11110066Sandreas.hansson@arm.com nbrOutstandingReads, nbrOutstandingWrites, 11210066Sandreas.hansson@arm.com responseQueue.size()); 11310066Sandreas.hansson@arm.com 11410066Sandreas.hansson@arm.com if (!responseQueue.empty() && !sendResponseEvent.scheduled()) 11510066Sandreas.hansson@arm.com schedule(sendResponseEvent, curTick()); 11610066Sandreas.hansson@arm.com 11710066Sandreas.hansson@arm.com // check if we were asked to drain and if we are now done 11810066Sandreas.hansson@arm.com if (drainManager && nbrOutstanding() == 0) { 11910066Sandreas.hansson@arm.com drainManager->signalDrainDone(); 12010066Sandreas.hansson@arm.com drainManager = NULL; 12110066Sandreas.hansson@arm.com } 12210066Sandreas.hansson@arm.com } else { 12310066Sandreas.hansson@arm.com retryResp = true; 12410066Sandreas.hansson@arm.com 12510066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Waiting for response retry\n"); 12610066Sandreas.hansson@arm.com 12710066Sandreas.hansson@arm.com assert(!sendResponseEvent.scheduled()); 12810066Sandreas.hansson@arm.com } 12910066Sandreas.hansson@arm.com} 13010066Sandreas.hansson@arm.com 13110066Sandreas.hansson@arm.comunsigned int 13210066Sandreas.hansson@arm.comDRAMSim2::nbrOutstanding() const 13310066Sandreas.hansson@arm.com{ 13410066Sandreas.hansson@arm.com return nbrOutstandingReads + nbrOutstandingWrites + responseQueue.size(); 13510066Sandreas.hansson@arm.com} 13610066Sandreas.hansson@arm.com 13710066Sandreas.hansson@arm.comvoid 13810066Sandreas.hansson@arm.comDRAMSim2::tick() 13910066Sandreas.hansson@arm.com{ 14010066Sandreas.hansson@arm.com wrapper.tick(); 14110066Sandreas.hansson@arm.com 14210066Sandreas.hansson@arm.com // is the connected port waiting for a retry, if so check the 14310066Sandreas.hansson@arm.com // state and send a retry if conditions have changed 14410066Sandreas.hansson@arm.com if (retryReq && nbrOutstanding() < wrapper.queueSize()) { 14510066Sandreas.hansson@arm.com retryReq = false; 14610066Sandreas.hansson@arm.com port.sendRetry(); 14710066Sandreas.hansson@arm.com } 14810066Sandreas.hansson@arm.com 14910066Sandreas.hansson@arm.com schedule(tickEvent, curTick() + wrapper.clockPeriod() * SimClock::Int::ns); 15010066Sandreas.hansson@arm.com} 15110066Sandreas.hansson@arm.com 15210066Sandreas.hansson@arm.comTick 15310066Sandreas.hansson@arm.comDRAMSim2::recvAtomic(PacketPtr pkt) 15410066Sandreas.hansson@arm.com{ 15510066Sandreas.hansson@arm.com access(pkt); 15610066Sandreas.hansson@arm.com 15710066Sandreas.hansson@arm.com // 50 ns is just an arbitrary value at this point 15810066Sandreas.hansson@arm.com return pkt->memInhibitAsserted() ? 0 : 50000; 15910066Sandreas.hansson@arm.com} 16010066Sandreas.hansson@arm.com 16110066Sandreas.hansson@arm.comvoid 16210066Sandreas.hansson@arm.comDRAMSim2::recvFunctional(PacketPtr pkt) 16310066Sandreas.hansson@arm.com{ 16410066Sandreas.hansson@arm.com pkt->pushLabel(name()); 16510066Sandreas.hansson@arm.com 16610066Sandreas.hansson@arm.com functionalAccess(pkt); 16710066Sandreas.hansson@arm.com 16810066Sandreas.hansson@arm.com // potentially update the packets in our response queue as well 16910066Sandreas.hansson@arm.com for (auto i = responseQueue.begin(); i != responseQueue.end(); ++i) 17010066Sandreas.hansson@arm.com pkt->checkFunctional(*i); 17110066Sandreas.hansson@arm.com 17210066Sandreas.hansson@arm.com pkt->popLabel(); 17310066Sandreas.hansson@arm.com} 17410066Sandreas.hansson@arm.com 17510066Sandreas.hansson@arm.combool 17610066Sandreas.hansson@arm.comDRAMSim2::recvTimingReq(PacketPtr pkt) 17710066Sandreas.hansson@arm.com{ 17810066Sandreas.hansson@arm.com // we should never see a new request while in retry 17910066Sandreas.hansson@arm.com assert(!retryReq); 18010066Sandreas.hansson@arm.com 18110066Sandreas.hansson@arm.com // @todo temporary hack to deal with memory corruption issues until 18210066Sandreas.hansson@arm.com // 4-phase transactions are complete 18310066Sandreas.hansson@arm.com for (int x = 0; x < pendingDelete.size(); x++) 18410066Sandreas.hansson@arm.com delete pendingDelete[x]; 18510066Sandreas.hansson@arm.com pendingDelete.clear(); 18610066Sandreas.hansson@arm.com 18710066Sandreas.hansson@arm.com if (pkt->memInhibitAsserted()) { 18810066Sandreas.hansson@arm.com // snooper will supply based on copy of packet 18910066Sandreas.hansson@arm.com // still target's responsibility to delete packet 19010066Sandreas.hansson@arm.com pendingDelete.push_back(pkt); 19110066Sandreas.hansson@arm.com return true; 19210066Sandreas.hansson@arm.com } 19310066Sandreas.hansson@arm.com 19410066Sandreas.hansson@arm.com // if we cannot accept we need to send a retry once progress can 19510066Sandreas.hansson@arm.com // be made 19610066Sandreas.hansson@arm.com bool can_accept = nbrOutstanding() < wrapper.queueSize(); 19710066Sandreas.hansson@arm.com 19810066Sandreas.hansson@arm.com // keep track of the transaction 19910066Sandreas.hansson@arm.com if (pkt->isRead()) { 20010066Sandreas.hansson@arm.com if (can_accept) { 20110066Sandreas.hansson@arm.com outstandingReads[pkt->getAddr()].push(pkt); 20210066Sandreas.hansson@arm.com 20310066Sandreas.hansson@arm.com // we count a transaction as outstanding until it has left the 20410066Sandreas.hansson@arm.com // queue in the controller, and the response has been sent 20510066Sandreas.hansson@arm.com // back, note that this will differ for reads and writes 20610066Sandreas.hansson@arm.com ++nbrOutstandingReads; 20710066Sandreas.hansson@arm.com } 20810066Sandreas.hansson@arm.com } else if (pkt->isWrite()) { 20910066Sandreas.hansson@arm.com if (can_accept) { 21010066Sandreas.hansson@arm.com outstandingWrites[pkt->getAddr()].push(pkt); 21110066Sandreas.hansson@arm.com 21210066Sandreas.hansson@arm.com ++nbrOutstandingWrites; 21310066Sandreas.hansson@arm.com 21410066Sandreas.hansson@arm.com // perform the access for writes 21510066Sandreas.hansson@arm.com accessAndRespond(pkt); 21610066Sandreas.hansson@arm.com } 21710066Sandreas.hansson@arm.com } else { 21810066Sandreas.hansson@arm.com // keep it simple and just respond if necessary 21910066Sandreas.hansson@arm.com accessAndRespond(pkt); 22010066Sandreas.hansson@arm.com return true; 22110066Sandreas.hansson@arm.com } 22210066Sandreas.hansson@arm.com 22310066Sandreas.hansson@arm.com if (can_accept) { 22410066Sandreas.hansson@arm.com // we should never have a situation when we think there is space, 22510066Sandreas.hansson@arm.com // and there isn't 22610066Sandreas.hansson@arm.com assert(wrapper.canAccept()); 22710066Sandreas.hansson@arm.com 22810066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Enqueueing address %lld\n", pkt->getAddr()); 22910066Sandreas.hansson@arm.com 23010066Sandreas.hansson@arm.com // @todo what about the granularity here, implicit assumption that 23110066Sandreas.hansson@arm.com // a transaction matches the burst size of the memory (which we 23210066Sandreas.hansson@arm.com // cannot determine without parsing the ini file ourselves) 23310066Sandreas.hansson@arm.com wrapper.enqueue(pkt->isWrite(), pkt->getAddr()); 23410066Sandreas.hansson@arm.com 23510066Sandreas.hansson@arm.com return true; 23610066Sandreas.hansson@arm.com } else { 23710066Sandreas.hansson@arm.com retryReq = true; 23810066Sandreas.hansson@arm.com return false; 23910066Sandreas.hansson@arm.com } 24010066Sandreas.hansson@arm.com} 24110066Sandreas.hansson@arm.com 24210066Sandreas.hansson@arm.comvoid 24310066Sandreas.hansson@arm.comDRAMSim2::recvRetry() 24410066Sandreas.hansson@arm.com{ 24510066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Retrying\n"); 24610066Sandreas.hansson@arm.com 24710066Sandreas.hansson@arm.com assert(retryResp); 24810066Sandreas.hansson@arm.com retryResp = false; 24910066Sandreas.hansson@arm.com sendResponse(); 25010066Sandreas.hansson@arm.com} 25110066Sandreas.hansson@arm.com 25210066Sandreas.hansson@arm.comvoid 25310066Sandreas.hansson@arm.comDRAMSim2::accessAndRespond(PacketPtr pkt) 25410066Sandreas.hansson@arm.com{ 25510066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Access for address %lld\n", pkt->getAddr()); 25610066Sandreas.hansson@arm.com 25710066Sandreas.hansson@arm.com bool needsResponse = pkt->needsResponse(); 25810066Sandreas.hansson@arm.com 25910066Sandreas.hansson@arm.com // do the actual memory access which also turns the packet into a 26010066Sandreas.hansson@arm.com // response 26110066Sandreas.hansson@arm.com access(pkt); 26210066Sandreas.hansson@arm.com 26310066Sandreas.hansson@arm.com // turn packet around to go back to requester if response expected 26410066Sandreas.hansson@arm.com if (needsResponse) { 26510066Sandreas.hansson@arm.com // access already turned the packet into a response 26610066Sandreas.hansson@arm.com assert(pkt->isResponse()); 26710066Sandreas.hansson@arm.com 26810066Sandreas.hansson@arm.com // @todo someone should pay for this 26910066Sandreas.hansson@arm.com pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; 27010066Sandreas.hansson@arm.com 27110066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Queuing response for address %lld\n", 27210066Sandreas.hansson@arm.com pkt->getAddr()); 27310066Sandreas.hansson@arm.com 27410066Sandreas.hansson@arm.com // queue it to be sent back 27510066Sandreas.hansson@arm.com responseQueue.push_back(pkt); 27610066Sandreas.hansson@arm.com 27710066Sandreas.hansson@arm.com // if we are not already waiting for a retry, or are scheduled 27810066Sandreas.hansson@arm.com // to send a response, schedule an event 27910066Sandreas.hansson@arm.com if (!retryResp && !sendResponseEvent.scheduled()) 28010066Sandreas.hansson@arm.com schedule(sendResponseEvent, curTick()); 28110066Sandreas.hansson@arm.com } else { 28210066Sandreas.hansson@arm.com // @todo the packet is going to be deleted, and the DRAMPacket 28310066Sandreas.hansson@arm.com // is still having a pointer to it 28410066Sandreas.hansson@arm.com pendingDelete.push_back(pkt); 28510066Sandreas.hansson@arm.com } 28610066Sandreas.hansson@arm.com} 28710066Sandreas.hansson@arm.com 28810066Sandreas.hansson@arm.comvoid DRAMSim2::readComplete(unsigned id, uint64_t addr, uint64_t cycle) 28910066Sandreas.hansson@arm.com{ 29010066Sandreas.hansson@arm.com assert(cycle == divCeil(curTick(), 29110066Sandreas.hansson@arm.com wrapper.clockPeriod() * SimClock::Int::ns)); 29210066Sandreas.hansson@arm.com 29310066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Read to address %lld complete\n", addr); 29410066Sandreas.hansson@arm.com 29510066Sandreas.hansson@arm.com // get the outstanding reads for the address in question 29610066Sandreas.hansson@arm.com auto p = outstandingReads.find(addr); 29710066Sandreas.hansson@arm.com assert(p != outstandingReads.end()); 29810066Sandreas.hansson@arm.com 29910066Sandreas.hansson@arm.com // first in first out, which is not necessarily true, but it is 30010066Sandreas.hansson@arm.com // the best we can do at this point 30110066Sandreas.hansson@arm.com PacketPtr pkt = p->second.front(); 30210066Sandreas.hansson@arm.com p->second.pop(); 30310066Sandreas.hansson@arm.com 30410066Sandreas.hansson@arm.com if (p->second.empty()) 30510066Sandreas.hansson@arm.com outstandingReads.erase(p); 30610066Sandreas.hansson@arm.com 30710066Sandreas.hansson@arm.com // no need to check for drain here as the next call will add a 30810066Sandreas.hansson@arm.com // response to the response queue straight away 30910066Sandreas.hansson@arm.com assert(nbrOutstandingReads != 0); 31010066Sandreas.hansson@arm.com --nbrOutstandingReads; 31110066Sandreas.hansson@arm.com 31210066Sandreas.hansson@arm.com // perform the actual memory access 31310066Sandreas.hansson@arm.com accessAndRespond(pkt); 31410066Sandreas.hansson@arm.com} 31510066Sandreas.hansson@arm.com 31610066Sandreas.hansson@arm.comvoid DRAMSim2::writeComplete(unsigned id, uint64_t addr, uint64_t cycle) 31710066Sandreas.hansson@arm.com{ 31810066Sandreas.hansson@arm.com assert(cycle == divCeil(curTick(), 31910066Sandreas.hansson@arm.com wrapper.clockPeriod() * SimClock::Int::ns)); 32010066Sandreas.hansson@arm.com 32110066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Write to address %lld complete\n", addr); 32210066Sandreas.hansson@arm.com 32310066Sandreas.hansson@arm.com // get the outstanding reads for the address in question 32410066Sandreas.hansson@arm.com auto p = outstandingWrites.find(addr); 32510066Sandreas.hansson@arm.com assert(p != outstandingWrites.end()); 32610066Sandreas.hansson@arm.com 32710066Sandreas.hansson@arm.com // we have already responded, and this is only to keep track of 32810066Sandreas.hansson@arm.com // what is outstanding 32910066Sandreas.hansson@arm.com p->second.pop(); 33010066Sandreas.hansson@arm.com if (p->second.empty()) 33110066Sandreas.hansson@arm.com outstandingWrites.erase(p); 33210066Sandreas.hansson@arm.com 33310066Sandreas.hansson@arm.com assert(nbrOutstandingWrites != 0); 33410066Sandreas.hansson@arm.com --nbrOutstandingWrites; 33510066Sandreas.hansson@arm.com 33610066Sandreas.hansson@arm.com // check if we were asked to drain and if we are now done 33710066Sandreas.hansson@arm.com if (drainManager && nbrOutstanding() == 0) { 33810066Sandreas.hansson@arm.com drainManager->signalDrainDone(); 33910066Sandreas.hansson@arm.com drainManager = NULL; 34010066Sandreas.hansson@arm.com } 34110066Sandreas.hansson@arm.com} 34210066Sandreas.hansson@arm.com 34310066Sandreas.hansson@arm.comBaseSlavePort& 34410066Sandreas.hansson@arm.comDRAMSim2::getSlavePort(const std::string &if_name, PortID idx) 34510066Sandreas.hansson@arm.com{ 34610066Sandreas.hansson@arm.com if (if_name != "port") { 34710066Sandreas.hansson@arm.com return MemObject::getSlavePort(if_name, idx); 34810066Sandreas.hansson@arm.com } else { 34910066Sandreas.hansson@arm.com return port; 35010066Sandreas.hansson@arm.com } 35110066Sandreas.hansson@arm.com} 35210066Sandreas.hansson@arm.com 35310066Sandreas.hansson@arm.comunsigned int 35410066Sandreas.hansson@arm.comDRAMSim2::drain(DrainManager* dm) 35510066Sandreas.hansson@arm.com{ 35610066Sandreas.hansson@arm.com // check our outstanding reads and writes and if any they need to 35710066Sandreas.hansson@arm.com // drain 35810066Sandreas.hansson@arm.com if (nbrOutstanding() != 0) { 35910066Sandreas.hansson@arm.com setDrainState(Drainable::Draining); 36010066Sandreas.hansson@arm.com drainManager = dm; 36110066Sandreas.hansson@arm.com return 1; 36210066Sandreas.hansson@arm.com } else { 36310066Sandreas.hansson@arm.com setDrainState(Drainable::Drained); 36410066Sandreas.hansson@arm.com return 0; 36510066Sandreas.hansson@arm.com } 36610066Sandreas.hansson@arm.com} 36710066Sandreas.hansson@arm.com 36810066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::MemoryPort(const std::string& _name, 36910066Sandreas.hansson@arm.com DRAMSim2& _memory) 37010066Sandreas.hansson@arm.com : SlavePort(_name, &_memory), memory(_memory) 37110066Sandreas.hansson@arm.com{ } 37210066Sandreas.hansson@arm.com 37310066Sandreas.hansson@arm.comAddrRangeList 37410066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::getAddrRanges() const 37510066Sandreas.hansson@arm.com{ 37610066Sandreas.hansson@arm.com AddrRangeList ranges; 37710066Sandreas.hansson@arm.com ranges.push_back(memory.getAddrRange()); 37810066Sandreas.hansson@arm.com return ranges; 37910066Sandreas.hansson@arm.com} 38010066Sandreas.hansson@arm.com 38110066Sandreas.hansson@arm.comTick 38210066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvAtomic(PacketPtr pkt) 38310066Sandreas.hansson@arm.com{ 38410066Sandreas.hansson@arm.com return memory.recvAtomic(pkt); 38510066Sandreas.hansson@arm.com} 38610066Sandreas.hansson@arm.com 38710066Sandreas.hansson@arm.comvoid 38810066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvFunctional(PacketPtr pkt) 38910066Sandreas.hansson@arm.com{ 39010066Sandreas.hansson@arm.com memory.recvFunctional(pkt); 39110066Sandreas.hansson@arm.com} 39210066Sandreas.hansson@arm.com 39310066Sandreas.hansson@arm.combool 39410066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvTimingReq(PacketPtr pkt) 39510066Sandreas.hansson@arm.com{ 39610066Sandreas.hansson@arm.com // pass it to the memory controller 39710066Sandreas.hansson@arm.com return memory.recvTimingReq(pkt); 39810066Sandreas.hansson@arm.com} 39910066Sandreas.hansson@arm.com 40010066Sandreas.hansson@arm.comvoid 40110066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvRetry() 40210066Sandreas.hansson@arm.com{ 40310066Sandreas.hansson@arm.com memory.recvRetry(); 40410066Sandreas.hansson@arm.com} 40510066Sandreas.hansson@arm.com 40610066Sandreas.hansson@arm.comDRAMSim2* 40710066Sandreas.hansson@arm.comDRAMSim2Params::create() 40810066Sandreas.hansson@arm.com{ 40910066Sandreas.hansson@arm.com return new DRAMSim2(this); 41010066Sandreas.hansson@arm.com} 411