mem_sink.cc revision 13784
112967Smatteo.andreozzi@arm.com/* 212967Smatteo.andreozzi@arm.com * Copyright (c) 2018 ARM Limited 312967Smatteo.andreozzi@arm.com * All rights reserved 412967Smatteo.andreozzi@arm.com * 512967Smatteo.andreozzi@arm.com * The license below extends only to copyright in the software and shall 612967Smatteo.andreozzi@arm.com * not be construed as granting a license to any other intellectual 712967Smatteo.andreozzi@arm.com * property including but not limited to intellectual property relating 812967Smatteo.andreozzi@arm.com * to a hardware implementation of the functionality of the software 912967Smatteo.andreozzi@arm.com * licensed hereunder. You may use the software subject to the license 1012967Smatteo.andreozzi@arm.com * terms below provided that you ensure that this notice is replicated 1112967Smatteo.andreozzi@arm.com * unmodified and in its entirety in all distributions of the software, 1212967Smatteo.andreozzi@arm.com * modified or unmodified, in source code or in binary form. 1312967Smatteo.andreozzi@arm.com * 1412967Smatteo.andreozzi@arm.com * Redistribution and use in source and binary forms, with or without 1512967Smatteo.andreozzi@arm.com * modification, are permitted provided that the following conditions are 1612967Smatteo.andreozzi@arm.com * met: redistributions of source code must retain the above copyright 1712967Smatteo.andreozzi@arm.com * notice, this list of conditions and the following disclaimer; 1812967Smatteo.andreozzi@arm.com * redistributions in binary form must reproduce the above copyright 1912967Smatteo.andreozzi@arm.com * notice, this list of conditions and the following disclaimer in the 2012967Smatteo.andreozzi@arm.com * documentation and/or other materials provided with the distribution; 2112967Smatteo.andreozzi@arm.com * neither the name of the copyright holders nor the names of its 2212967Smatteo.andreozzi@arm.com * contributors may be used to endorse or promote products derived from 2312967Smatteo.andreozzi@arm.com * this software without specific prior written permission. 2412967Smatteo.andreozzi@arm.com * 2512967Smatteo.andreozzi@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2612967Smatteo.andreozzi@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2712967Smatteo.andreozzi@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2812967Smatteo.andreozzi@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2912967Smatteo.andreozzi@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3012967Smatteo.andreozzi@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3112967Smatteo.andreozzi@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3212967Smatteo.andreozzi@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3312967Smatteo.andreozzi@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3412967Smatteo.andreozzi@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3512967Smatteo.andreozzi@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3612967Smatteo.andreozzi@arm.com * 3712967Smatteo.andreozzi@arm.com * Author: Matteo Andreozzi 3812967Smatteo.andreozzi@arm.com */ 3912967Smatteo.andreozzi@arm.com 4012967Smatteo.andreozzi@arm.com#include "debug/Drain.hh" 4112967Smatteo.andreozzi@arm.com#include "debug/QOS.hh" 4212967Smatteo.andreozzi@arm.com#include "mem_sink.hh" 4312967Smatteo.andreozzi@arm.com#include "sim/system.hh" 4412967Smatteo.andreozzi@arm.com 4512967Smatteo.andreozzi@arm.comnamespace QoS { 4612967Smatteo.andreozzi@arm.com 4712967Smatteo.andreozzi@arm.comMemSinkCtrl::MemSinkCtrl(const QoSMemSinkCtrlParams* p) 4812967Smatteo.andreozzi@arm.com : MemCtrl(p), requestLatency(p->request_latency), 4912967Smatteo.andreozzi@arm.com responseLatency(p->response_latency), 5012967Smatteo.andreozzi@arm.com memoryPacketSize(p->memory_packet_size), 5112967Smatteo.andreozzi@arm.com readBufferSize(p->read_buffer_size), 5212967Smatteo.andreozzi@arm.com writeBufferSize(p->write_buffer_size), port(name() + ".port", *this), 5312967Smatteo.andreozzi@arm.com retryRdReq(false), retryWrReq(false), nextRequest(0), nextReqEvent(this) 5412967Smatteo.andreozzi@arm.com{ 5512967Smatteo.andreozzi@arm.com // Resize read and write queue to allocate space 5612967Smatteo.andreozzi@arm.com // for configured QoS priorities 5712967Smatteo.andreozzi@arm.com readQueue.resize(numPriorities()); 5812967Smatteo.andreozzi@arm.com writeQueue.resize(numPriorities()); 5912967Smatteo.andreozzi@arm.com} 6012967Smatteo.andreozzi@arm.com 6112967Smatteo.andreozzi@arm.comMemSinkCtrl::~MemSinkCtrl() 6212967Smatteo.andreozzi@arm.com{} 6312967Smatteo.andreozzi@arm.com 6412967Smatteo.andreozzi@arm.comvoid 6512967Smatteo.andreozzi@arm.comMemSinkCtrl::init() 6612967Smatteo.andreozzi@arm.com{ 6712967Smatteo.andreozzi@arm.com MemCtrl::init(); 6812967Smatteo.andreozzi@arm.com 6912967Smatteo.andreozzi@arm.com // Allow unconnected memories as this is used in several ruby 7012967Smatteo.andreozzi@arm.com // systems at the moment 7112967Smatteo.andreozzi@arm.com if (port.isConnected()) { 7212967Smatteo.andreozzi@arm.com port.sendRangeChange(); 7312967Smatteo.andreozzi@arm.com } 7412967Smatteo.andreozzi@arm.com} 7512967Smatteo.andreozzi@arm.com 7612967Smatteo.andreozzi@arm.combool 7712967Smatteo.andreozzi@arm.comMemSinkCtrl::readQueueFull(const uint64_t packets) const 7812967Smatteo.andreozzi@arm.com{ 7912967Smatteo.andreozzi@arm.com return (totalReadQueueSize + packets > readBufferSize); 8012967Smatteo.andreozzi@arm.com} 8112967Smatteo.andreozzi@arm.com 8212967Smatteo.andreozzi@arm.combool 8312967Smatteo.andreozzi@arm.comMemSinkCtrl::writeQueueFull(const uint64_t packets) const 8412967Smatteo.andreozzi@arm.com{ 8512967Smatteo.andreozzi@arm.com return (totalWriteQueueSize + packets > writeBufferSize); 8612967Smatteo.andreozzi@arm.com} 8712967Smatteo.andreozzi@arm.com 8812967Smatteo.andreozzi@arm.comTick 8912967Smatteo.andreozzi@arm.comMemSinkCtrl::recvAtomic(PacketPtr pkt) 9012967Smatteo.andreozzi@arm.com{ 9112967Smatteo.andreozzi@arm.com panic_if(pkt->cacheResponding(), 9212967Smatteo.andreozzi@arm.com "%s Should not see packets where cache is responding\n", 9312967Smatteo.andreozzi@arm.com __func__); 9412967Smatteo.andreozzi@arm.com 9512967Smatteo.andreozzi@arm.com access(pkt); 9612967Smatteo.andreozzi@arm.com return responseLatency; 9712967Smatteo.andreozzi@arm.com} 9812967Smatteo.andreozzi@arm.com 9912967Smatteo.andreozzi@arm.comvoid 10012967Smatteo.andreozzi@arm.comMemSinkCtrl::recvFunctional(PacketPtr pkt) 10112967Smatteo.andreozzi@arm.com{ 10212967Smatteo.andreozzi@arm.com pkt->pushLabel(name()); 10312967Smatteo.andreozzi@arm.com 10412967Smatteo.andreozzi@arm.com functionalAccess(pkt); 10512967Smatteo.andreozzi@arm.com 10612967Smatteo.andreozzi@arm.com pkt->popLabel(); 10712967Smatteo.andreozzi@arm.com} 10812967Smatteo.andreozzi@arm.com 10913784Sgabeblack@google.comPort & 11013784Sgabeblack@google.comMemSinkCtrl::getPort(const std::string &interface, PortID idx) 11112967Smatteo.andreozzi@arm.com{ 11212967Smatteo.andreozzi@arm.com if (interface != "port") { 11313784Sgabeblack@google.com return MemObject::getPort(interface, idx); 11412967Smatteo.andreozzi@arm.com } else { 11512967Smatteo.andreozzi@arm.com return port; 11612967Smatteo.andreozzi@arm.com } 11712967Smatteo.andreozzi@arm.com} 11812967Smatteo.andreozzi@arm.com 11912967Smatteo.andreozzi@arm.combool 12012967Smatteo.andreozzi@arm.comMemSinkCtrl::recvTimingReq(PacketPtr pkt) 12112967Smatteo.andreozzi@arm.com{ 12212967Smatteo.andreozzi@arm.com // Request accepted 12312967Smatteo.andreozzi@arm.com bool req_accepted = true; 12412967Smatteo.andreozzi@arm.com 12512967Smatteo.andreozzi@arm.com panic_if(!(pkt->isRead() || pkt->isWrite()), 12612967Smatteo.andreozzi@arm.com "%s. Should only see " 12712967Smatteo.andreozzi@arm.com "read and writes at memory controller\n", 12812967Smatteo.andreozzi@arm.com __func__); 12912967Smatteo.andreozzi@arm.com 13012967Smatteo.andreozzi@arm.com panic_if(pkt->cacheResponding(), 13112967Smatteo.andreozzi@arm.com "%s. Should not see packets where cache is responding\n", 13212967Smatteo.andreozzi@arm.com __func__); 13312967Smatteo.andreozzi@arm.com 13412967Smatteo.andreozzi@arm.com DPRINTF(QOS, 13512967Smatteo.andreozzi@arm.com "%s: MASTER %s request %s addr %lld size %d\n", 13612967Smatteo.andreozzi@arm.com __func__, 13712967Smatteo.andreozzi@arm.com _system->getMasterName(pkt->req->masterId()), 13812967Smatteo.andreozzi@arm.com pkt->cmdString(), pkt->getAddr(), pkt->getSize()); 13912967Smatteo.andreozzi@arm.com 14012967Smatteo.andreozzi@arm.com uint64_t required_entries = divCeil(pkt->getSize(), memoryPacketSize); 14112967Smatteo.andreozzi@arm.com 14212967Smatteo.andreozzi@arm.com assert(required_entries); 14312967Smatteo.andreozzi@arm.com 14412967Smatteo.andreozzi@arm.com // Schedule packet 14512967Smatteo.andreozzi@arm.com uint8_t pkt_priority = qosSchedule({&readQueue, &writeQueue}, 14612967Smatteo.andreozzi@arm.com memoryPacketSize, pkt); 14712967Smatteo.andreozzi@arm.com 14812967Smatteo.andreozzi@arm.com if (pkt->isRead()) { 14912967Smatteo.andreozzi@arm.com if (readQueueFull(required_entries)) { 15012967Smatteo.andreozzi@arm.com DPRINTF(QOS, 15112967Smatteo.andreozzi@arm.com "%s Read queue full, not accepting\n", __func__); 15212967Smatteo.andreozzi@arm.com // Remember that we have to retry this port 15312967Smatteo.andreozzi@arm.com retryRdReq = true; 15412967Smatteo.andreozzi@arm.com numReadRetries++; 15512967Smatteo.andreozzi@arm.com req_accepted = false; 15612967Smatteo.andreozzi@arm.com } else { 15712967Smatteo.andreozzi@arm.com // Enqueue the incoming packet into corresponding 15812967Smatteo.andreozzi@arm.com // QoS priority queue 15912967Smatteo.andreozzi@arm.com readQueue.at(pkt_priority).push_back(pkt); 16012967Smatteo.andreozzi@arm.com queuePolicy->enqueuePacket(pkt); 16112967Smatteo.andreozzi@arm.com } 16212967Smatteo.andreozzi@arm.com } else { 16312967Smatteo.andreozzi@arm.com if (writeQueueFull(required_entries)) { 16412967Smatteo.andreozzi@arm.com DPRINTF(QOS, 16512967Smatteo.andreozzi@arm.com "%s Write queue full, not accepting\n", __func__); 16612967Smatteo.andreozzi@arm.com // Remember that we have to retry this port 16712967Smatteo.andreozzi@arm.com retryWrReq = true; 16812967Smatteo.andreozzi@arm.com numWriteRetries++; 16912967Smatteo.andreozzi@arm.com req_accepted = false; 17012967Smatteo.andreozzi@arm.com } else { 17112967Smatteo.andreozzi@arm.com // Enqueue the incoming packet into corresponding QoS 17212967Smatteo.andreozzi@arm.com // priority queue 17312967Smatteo.andreozzi@arm.com writeQueue.at(pkt_priority).push_back(pkt); 17412967Smatteo.andreozzi@arm.com queuePolicy->enqueuePacket(pkt); 17512967Smatteo.andreozzi@arm.com } 17612967Smatteo.andreozzi@arm.com } 17712967Smatteo.andreozzi@arm.com 17812967Smatteo.andreozzi@arm.com if (req_accepted) { 17912967Smatteo.andreozzi@arm.com // The packet is accepted - log it 18012967Smatteo.andreozzi@arm.com logRequest(pkt->isRead()? READ : WRITE, 18112967Smatteo.andreozzi@arm.com pkt->req->masterId(), 18212967Smatteo.andreozzi@arm.com pkt->qosValue(), 18312967Smatteo.andreozzi@arm.com pkt->getAddr(), 18412967Smatteo.andreozzi@arm.com required_entries); 18512967Smatteo.andreozzi@arm.com } 18612967Smatteo.andreozzi@arm.com 18712967Smatteo.andreozzi@arm.com // Check if we have to process next request event 18812967Smatteo.andreozzi@arm.com if (!nextReqEvent.scheduled()) { 18912967Smatteo.andreozzi@arm.com DPRINTF(QOS, 19012967Smatteo.andreozzi@arm.com "%s scheduling next request at " 19112967Smatteo.andreozzi@arm.com "time %d (next is %d)\n", __func__, 19212967Smatteo.andreozzi@arm.com std::max(curTick(), nextRequest), nextRequest); 19312967Smatteo.andreozzi@arm.com schedule(nextReqEvent, std::max(curTick(), nextRequest)); 19412967Smatteo.andreozzi@arm.com } 19512967Smatteo.andreozzi@arm.com return req_accepted; 19612967Smatteo.andreozzi@arm.com} 19712967Smatteo.andreozzi@arm.com 19812967Smatteo.andreozzi@arm.comvoid 19912967Smatteo.andreozzi@arm.comMemSinkCtrl::processNextReqEvent() 20012967Smatteo.andreozzi@arm.com{ 20112967Smatteo.andreozzi@arm.com PacketPtr pkt = nullptr; 20212967Smatteo.andreozzi@arm.com 20312967Smatteo.andreozzi@arm.com // Evaluate bus direction 20412967Smatteo.andreozzi@arm.com busStateNext = selectNextBusState(); 20512967Smatteo.andreozzi@arm.com 20612967Smatteo.andreozzi@arm.com // Record turnaround stats and update current state direction 20712967Smatteo.andreozzi@arm.com recordTurnaroundStats(); 20812967Smatteo.andreozzi@arm.com 20912967Smatteo.andreozzi@arm.com // Set current bus state 21012967Smatteo.andreozzi@arm.com setCurrentBusState(); 21112967Smatteo.andreozzi@arm.com 21212967Smatteo.andreozzi@arm.com // Access current direction buffer 21312967Smatteo.andreozzi@arm.com std::vector<PacketQueue>* queue_ptr = (busState == READ ? &readQueue : 21412967Smatteo.andreozzi@arm.com &writeQueue); 21512967Smatteo.andreozzi@arm.com 21612967Smatteo.andreozzi@arm.com DPRINTF(QOS, 21712967Smatteo.andreozzi@arm.com "%s DUMPING %s queues status\n", __func__, 21812967Smatteo.andreozzi@arm.com (busState == WRITE ? "WRITE" : "READ")); 21912967Smatteo.andreozzi@arm.com 22012967Smatteo.andreozzi@arm.com if (DTRACE(QOS)) { 22112967Smatteo.andreozzi@arm.com for (uint8_t i = 0; i < numPriorities(); ++i) { 22212967Smatteo.andreozzi@arm.com std::string plist = ""; 22312967Smatteo.andreozzi@arm.com for (auto& e : (busState == WRITE ? writeQueue[i]: readQueue[i])) { 22412967Smatteo.andreozzi@arm.com plist += (std::to_string(e->req->masterId())) + " "; 22512967Smatteo.andreozzi@arm.com } 22612967Smatteo.andreozzi@arm.com DPRINTF(QOS, 22712967Smatteo.andreozzi@arm.com "%s priority Queue [%i] contains %i elements, " 22812967Smatteo.andreozzi@arm.com "packets are: [%s]\n", __func__, i, 22912967Smatteo.andreozzi@arm.com busState == WRITE ? writeQueueSizes[i] : 23012967Smatteo.andreozzi@arm.com readQueueSizes[i], 23112967Smatteo.andreozzi@arm.com plist); 23212967Smatteo.andreozzi@arm.com } 23312967Smatteo.andreozzi@arm.com } 23412967Smatteo.andreozzi@arm.com 23512967Smatteo.andreozzi@arm.com uint8_t curr_prio = numPriorities(); 23612967Smatteo.andreozzi@arm.com 23712967Smatteo.andreozzi@arm.com for (auto queue = (*queue_ptr).rbegin(); 23812967Smatteo.andreozzi@arm.com queue != (*queue_ptr).rend(); ++queue) { 23912967Smatteo.andreozzi@arm.com 24012967Smatteo.andreozzi@arm.com curr_prio--; 24112967Smatteo.andreozzi@arm.com 24212967Smatteo.andreozzi@arm.com DPRINTF(QOS, 24312967Smatteo.andreozzi@arm.com "%s checking %s queue [%d] priority [%d packets]\n", 24412967Smatteo.andreozzi@arm.com __func__, (busState == READ? "READ" : "WRITE"), 24512967Smatteo.andreozzi@arm.com curr_prio, queue->size()); 24612967Smatteo.andreozzi@arm.com 24712967Smatteo.andreozzi@arm.com if (!queue->empty()) { 24812967Smatteo.andreozzi@arm.com // Call the queue policy to select packet from priority queue 24912967Smatteo.andreozzi@arm.com auto p_it = queuePolicy->selectPacket(&(*queue)); 25012967Smatteo.andreozzi@arm.com pkt = *p_it; 25112967Smatteo.andreozzi@arm.com queue->erase(p_it); 25212967Smatteo.andreozzi@arm.com 25312967Smatteo.andreozzi@arm.com DPRINTF(QOS, 25412967Smatteo.andreozzi@arm.com "%s scheduling packet address %d for master %s from " 25512967Smatteo.andreozzi@arm.com "priority queue %d\n", __func__, pkt->getAddr(), 25612967Smatteo.andreozzi@arm.com _system->getMasterName(pkt->req->masterId()), 25712967Smatteo.andreozzi@arm.com curr_prio); 25812967Smatteo.andreozzi@arm.com break; 25912967Smatteo.andreozzi@arm.com } 26012967Smatteo.andreozzi@arm.com } 26112967Smatteo.andreozzi@arm.com 26212967Smatteo.andreozzi@arm.com assert(pkt); 26312967Smatteo.andreozzi@arm.com 26412967Smatteo.andreozzi@arm.com // Setup next request service time - do it here as retry request 26512967Smatteo.andreozzi@arm.com // hands over control to the port 26612967Smatteo.andreozzi@arm.com nextRequest = curTick() + requestLatency; 26712967Smatteo.andreozzi@arm.com 26812967Smatteo.andreozzi@arm.com uint64_t removed_entries = divCeil(pkt->getSize(), memoryPacketSize); 26912967Smatteo.andreozzi@arm.com 27012967Smatteo.andreozzi@arm.com DPRINTF(QOS, 27112967Smatteo.andreozzi@arm.com "%s scheduled packet address %d for master %s size is %d, " 27212967Smatteo.andreozzi@arm.com "corresponds to %d memory packets\n", __func__, pkt->getAddr(), 27312967Smatteo.andreozzi@arm.com _system->getMasterName(pkt->req->masterId()), 27412967Smatteo.andreozzi@arm.com pkt->getSize(), removed_entries); 27512967Smatteo.andreozzi@arm.com 27612967Smatteo.andreozzi@arm.com // Schedule response 27712967Smatteo.andreozzi@arm.com panic_if(!pkt->needsResponse(), 27812967Smatteo.andreozzi@arm.com "%s response not required\n", __func__); 27912967Smatteo.andreozzi@arm.com 28012967Smatteo.andreozzi@arm.com // Do the actual memory access which also turns the packet 28112967Smatteo.andreozzi@arm.com // into a response 28212967Smatteo.andreozzi@arm.com access(pkt); 28312967Smatteo.andreozzi@arm.com 28412967Smatteo.andreozzi@arm.com // Log the response 28512967Smatteo.andreozzi@arm.com logResponse(pkt->isRead()? READ : WRITE, 28612967Smatteo.andreozzi@arm.com pkt->req->masterId(), 28712967Smatteo.andreozzi@arm.com pkt->qosValue(), 28812967Smatteo.andreozzi@arm.com pkt->getAddr(), 28912967Smatteo.andreozzi@arm.com removed_entries, responseLatency); 29012967Smatteo.andreozzi@arm.com 29112967Smatteo.andreozzi@arm.com // Schedule the response 29213564Snikos.nikoleris@arm.com port.schedTimingResp(pkt, curTick() + responseLatency); 29312967Smatteo.andreozzi@arm.com DPRINTF(QOS, 29412967Smatteo.andreozzi@arm.com "%s response scheduled at time %d\n", 29512967Smatteo.andreozzi@arm.com __func__, curTick() + responseLatency); 29612967Smatteo.andreozzi@arm.com 29712967Smatteo.andreozzi@arm.com // Finally - handle retry requests - this handles control 29812967Smatteo.andreozzi@arm.com // to the port, so do it last 29912967Smatteo.andreozzi@arm.com if (busState == READ && retryRdReq) { 30012967Smatteo.andreozzi@arm.com retryRdReq = false; 30112967Smatteo.andreozzi@arm.com port.sendRetryReq(); 30212967Smatteo.andreozzi@arm.com } else if (busState == WRITE && retryWrReq) { 30312967Smatteo.andreozzi@arm.com retryWrReq = false; 30412967Smatteo.andreozzi@arm.com port.sendRetryReq(); 30512967Smatteo.andreozzi@arm.com } 30612967Smatteo.andreozzi@arm.com 30712967Smatteo.andreozzi@arm.com // Check if we have to schedule another request event 30812967Smatteo.andreozzi@arm.com if ((totalReadQueueSize || totalWriteQueueSize) && 30912967Smatteo.andreozzi@arm.com !nextReqEvent.scheduled()) { 31012967Smatteo.andreozzi@arm.com 31112967Smatteo.andreozzi@arm.com schedule(nextReqEvent, curTick() + requestLatency); 31212967Smatteo.andreozzi@arm.com DPRINTF(QOS, 31312967Smatteo.andreozzi@arm.com "%s scheduling next request event at tick %d\n", 31412967Smatteo.andreozzi@arm.com __func__, curTick() + requestLatency); 31512967Smatteo.andreozzi@arm.com } 31612967Smatteo.andreozzi@arm.com} 31712967Smatteo.andreozzi@arm.com 31812967Smatteo.andreozzi@arm.comDrainState 31912967Smatteo.andreozzi@arm.comMemSinkCtrl::drain() 32012967Smatteo.andreozzi@arm.com{ 32112967Smatteo.andreozzi@arm.com if (totalReadQueueSize || totalWriteQueueSize) { 32212967Smatteo.andreozzi@arm.com DPRINTF(Drain, 32312967Smatteo.andreozzi@arm.com "%s queues have requests, waiting to drain\n", 32412967Smatteo.andreozzi@arm.com __func__); 32512967Smatteo.andreozzi@arm.com return DrainState::Draining; 32612967Smatteo.andreozzi@arm.com } else { 32712967Smatteo.andreozzi@arm.com return DrainState::Drained; 32812967Smatteo.andreozzi@arm.com } 32912967Smatteo.andreozzi@arm.com} 33012967Smatteo.andreozzi@arm.com 33112967Smatteo.andreozzi@arm.comvoid 33212967Smatteo.andreozzi@arm.comMemSinkCtrl::regStats() 33312967Smatteo.andreozzi@arm.com{ 33412967Smatteo.andreozzi@arm.com MemCtrl::regStats(); 33512967Smatteo.andreozzi@arm.com 33612967Smatteo.andreozzi@arm.com // Initialize all the stats 33712967Smatteo.andreozzi@arm.com using namespace Stats; 33812967Smatteo.andreozzi@arm.com 33912967Smatteo.andreozzi@arm.com numReadRetries.name(name() + ".numReadRetries") 34012967Smatteo.andreozzi@arm.com .desc("Number of read retries"); 34112967Smatteo.andreozzi@arm.com numWriteRetries.name(name() + ".numWriteRetries") 34212967Smatteo.andreozzi@arm.com .desc("Number of write retries"); 34312967Smatteo.andreozzi@arm.com} 34412967Smatteo.andreozzi@arm.com 34512967Smatteo.andreozzi@arm.comMemSinkCtrl::MemoryPort::MemoryPort(const std::string& n, 34612967Smatteo.andreozzi@arm.com MemSinkCtrl& m) 34713564Snikos.nikoleris@arm.com : QueuedSlavePort(n, &m, queue, true), memory(m), queue(memory, *this, true) 34812967Smatteo.andreozzi@arm.com{} 34912967Smatteo.andreozzi@arm.com 35012967Smatteo.andreozzi@arm.comAddrRangeList 35112967Smatteo.andreozzi@arm.comMemSinkCtrl::MemoryPort::getAddrRanges() const 35212967Smatteo.andreozzi@arm.com{ 35312967Smatteo.andreozzi@arm.com AddrRangeList ranges; 35412967Smatteo.andreozzi@arm.com ranges.push_back(memory.getAddrRange()); 35512967Smatteo.andreozzi@arm.com return ranges; 35612967Smatteo.andreozzi@arm.com} 35712967Smatteo.andreozzi@arm.com 35812967Smatteo.andreozzi@arm.comTick 35912967Smatteo.andreozzi@arm.comMemSinkCtrl::MemoryPort::recvAtomic(PacketPtr pkt) 36012967Smatteo.andreozzi@arm.com{ 36112967Smatteo.andreozzi@arm.com return memory.recvAtomic(pkt); 36212967Smatteo.andreozzi@arm.com} 36312967Smatteo.andreozzi@arm.com 36412967Smatteo.andreozzi@arm.comvoid 36512967Smatteo.andreozzi@arm.comMemSinkCtrl::MemoryPort::recvFunctional(PacketPtr pkt) 36612967Smatteo.andreozzi@arm.com{ 36712967Smatteo.andreozzi@arm.com pkt->pushLabel(memory.name()); 36812967Smatteo.andreozzi@arm.com 36912967Smatteo.andreozzi@arm.com if (!queue.trySatisfyFunctional(pkt)) { 37012967Smatteo.andreozzi@arm.com // Default implementation of SimpleTimingPort::recvFunctional() 37112967Smatteo.andreozzi@arm.com // calls recvAtomic() and throws away the latency; we can save a 37212967Smatteo.andreozzi@arm.com // little here by just not calculating the latency. 37312967Smatteo.andreozzi@arm.com memory.recvFunctional(pkt); 37412967Smatteo.andreozzi@arm.com } 37512967Smatteo.andreozzi@arm.com 37612967Smatteo.andreozzi@arm.com pkt->popLabel(); 37712967Smatteo.andreozzi@arm.com} 37812967Smatteo.andreozzi@arm.com 37912967Smatteo.andreozzi@arm.combool 38012967Smatteo.andreozzi@arm.comMemSinkCtrl::MemoryPort::recvTimingReq(PacketPtr pkt) 38112967Smatteo.andreozzi@arm.com{ 38212967Smatteo.andreozzi@arm.com return memory.recvTimingReq(pkt); 38312967Smatteo.andreozzi@arm.com} 38412967Smatteo.andreozzi@arm.com 38512967Smatteo.andreozzi@arm.com} // namespace QoS 38612967Smatteo.andreozzi@arm.com 38712967Smatteo.andreozzi@arm.comQoS::MemSinkCtrl* 38812967Smatteo.andreozzi@arm.comQoSMemSinkCtrlParams::create() 38912967Smatteo.andreozzi@arm.com{ 39012967Smatteo.andreozzi@arm.com return new QoS::MemSinkCtrl(this); 39112967Smatteo.andreozzi@arm.com} 39212967Smatteo.andreozzi@arm.com 393