AbstractController.cc revision 10986:4fbe4b0adb4d
110448Snilay@cs.wisc.edu/* 210448Snilay@cs.wisc.edu * Copyright (c) 2011-2014 Mark D. Hill and David A. Wood 310448Snilay@cs.wisc.edu * All rights reserved. 410448Snilay@cs.wisc.edu * 510448Snilay@cs.wisc.edu * Redistribution and use in source and binary forms, with or without 610448Snilay@cs.wisc.edu * modification, are permitted provided that the following conditions are 710448Snilay@cs.wisc.edu * met: redistributions of source code must retain the above copyright 810448Snilay@cs.wisc.edu * notice, this list of conditions and the following disclaimer; 910448Snilay@cs.wisc.edu * redistributions in binary form must reproduce the above copyright 1010448Snilay@cs.wisc.edu * notice, this list of conditions and the following disclaimer in the 1110448Snilay@cs.wisc.edu * documentation and/or other materials provided with the distribution; 1210448Snilay@cs.wisc.edu * neither the name of the copyright holders nor the names of its 1310448Snilay@cs.wisc.edu * contributors may be used to endorse or promote products derived from 1410448Snilay@cs.wisc.edu * this software without specific prior written permission. 1510448Snilay@cs.wisc.edu * 1610448Snilay@cs.wisc.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1710448Snilay@cs.wisc.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1810448Snilay@cs.wisc.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1910448Snilay@cs.wisc.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2010448Snilay@cs.wisc.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2110448Snilay@cs.wisc.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2210447Snilay@cs.wisc.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2310447Snilay@cs.wisc.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2410447Snilay@cs.wisc.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2510447Snilay@cs.wisc.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2610447Snilay@cs.wisc.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2710447Snilay@cs.wisc.edu */ 2810447Snilay@cs.wisc.edu 2910447Snilay@cs.wisc.edu#include "mem/ruby/slicc_interface/AbstractController.hh" 3010447Snilay@cs.wisc.edu 3110447Snilay@cs.wisc.edu#include "debug/RubyQueue.hh" 3210447Snilay@cs.wisc.edu#include "mem/protocol/MemoryMsg.hh" 3310447Snilay@cs.wisc.edu#include "mem/ruby/system/Sequencer.hh" 3410447Snilay@cs.wisc.edu#include "mem/ruby/system/System.hh" 3510447Snilay@cs.wisc.edu#include "sim/system.hh" 3610447Snilay@cs.wisc.edu 3710447Snilay@cs.wisc.eduAbstractController::AbstractController(const Params *p) 3810447Snilay@cs.wisc.edu : MemObject(p), Consumer(this), m_version(p->version), 3910447Snilay@cs.wisc.edu m_clusterID(p->cluster_id), 4010447Snilay@cs.wisc.edu m_masterId(p->system->getMasterId(name())), m_is_blocking(false), 4110447Snilay@cs.wisc.edu m_number_of_TBEs(p->number_of_TBEs), 4210447Snilay@cs.wisc.edu m_transitions_per_cycle(p->transitions_per_cycle), 4310447Snilay@cs.wisc.edu m_buffer_size(p->buffer_size), m_recycle_latency(p->recycle_latency), 4410447Snilay@cs.wisc.edu memoryPort(csprintf("%s.memory", name()), this, ""), 4510447Snilay@cs.wisc.edu m_responseFromMemory_ptr(new MessageBuffer()) 4610447Snilay@cs.wisc.edu{ 4710447Snilay@cs.wisc.edu // Set the sender pointer of the response message buffer from the 4810447Snilay@cs.wisc.edu // memory controller. 4910447Snilay@cs.wisc.edu // This pointer is used for querying for the current time. 5010447Snilay@cs.wisc.edu m_responseFromMemory_ptr->setSender(this); 5110447Snilay@cs.wisc.edu m_responseFromMemory_ptr->setReceiver(this); 5210447Snilay@cs.wisc.edu m_responseFromMemory_ptr->setOrdering(false); 5310447Snilay@cs.wisc.edu 5410447Snilay@cs.wisc.edu if (m_version == 0) { 5510447Snilay@cs.wisc.edu // Combine the statistics from all controllers 5610447Snilay@cs.wisc.edu // of this particular type. 5710447Snilay@cs.wisc.edu Stats::registerDumpCallback(new StatsCallback(this)); 5810447Snilay@cs.wisc.edu } 5910447Snilay@cs.wisc.edu} 6010447Snilay@cs.wisc.edu 6110447Snilay@cs.wisc.eduvoid 6210447Snilay@cs.wisc.eduAbstractController::init() 6310447Snilay@cs.wisc.edu{ 6410447Snilay@cs.wisc.edu params()->ruby_system->registerAbstractController(this); 6510447Snilay@cs.wisc.edu m_delayHistogram.init(10); 6610447Snilay@cs.wisc.edu uint32_t size = Network::getNumberOfVirtualNetworks(); 6710447Snilay@cs.wisc.edu for (uint32_t i = 0; i < size; i++) { 6810447Snilay@cs.wisc.edu m_delayVCHistogram.push_back(new Stats::Histogram()); 6910447Snilay@cs.wisc.edu m_delayVCHistogram[i]->init(10); 7010447Snilay@cs.wisc.edu } 7110447Snilay@cs.wisc.edu} 7210447Snilay@cs.wisc.edu 7310447Snilay@cs.wisc.eduvoid 7410447Snilay@cs.wisc.eduAbstractController::resetStats() 7510447Snilay@cs.wisc.edu{ 7610447Snilay@cs.wisc.edu m_delayHistogram.reset(); 7710447Snilay@cs.wisc.edu uint32_t size = Network::getNumberOfVirtualNetworks(); 7810447Snilay@cs.wisc.edu for (uint32_t i = 0; i < size; i++) { 7910447Snilay@cs.wisc.edu m_delayVCHistogram[i]->reset(); 8010447Snilay@cs.wisc.edu } 8110447Snilay@cs.wisc.edu} 8210447Snilay@cs.wisc.edu 8310447Snilay@cs.wisc.eduvoid 8410447Snilay@cs.wisc.eduAbstractController::regStats() 8510447Snilay@cs.wisc.edu{ 8610447Snilay@cs.wisc.edu m_fully_busy_cycles 8710447Snilay@cs.wisc.edu .name(name() + ".fully_busy_cycles") 8810447Snilay@cs.wisc.edu .desc("cycles for which number of transistions == max transitions") 8910447Snilay@cs.wisc.edu .flags(Stats::nozero); 9010447Snilay@cs.wisc.edu} 9110447Snilay@cs.wisc.edu 9210447Snilay@cs.wisc.eduvoid 9310447Snilay@cs.wisc.eduAbstractController::profileMsgDelay(uint32_t virtualNetwork, Cycles delay) 9410447Snilay@cs.wisc.edu{ 9510447Snilay@cs.wisc.edu assert(virtualNetwork < m_delayVCHistogram.size()); 9610447Snilay@cs.wisc.edu m_delayHistogram.sample(delay); 9710447Snilay@cs.wisc.edu m_delayVCHistogram[virtualNetwork]->sample(delay); 9810447Snilay@cs.wisc.edu} 9910447Snilay@cs.wisc.edu 10010447Snilay@cs.wisc.eduvoid 10110447Snilay@cs.wisc.eduAbstractController::stallBuffer(MessageBuffer* buf, Address addr) 10210447Snilay@cs.wisc.edu{ 10310447Snilay@cs.wisc.edu if (m_waiting_buffers.count(addr) == 0) { 10410447Snilay@cs.wisc.edu MsgVecType* msgVec = new MsgVecType; 10510447Snilay@cs.wisc.edu msgVec->resize(m_in_ports, NULL); 10610447Snilay@cs.wisc.edu m_waiting_buffers[addr] = msgVec; 10710447Snilay@cs.wisc.edu } 10810447Snilay@cs.wisc.edu DPRINTF(RubyQueue, "stalling %s port %d addr %s\n", buf, m_cur_in_port, 10910447Snilay@cs.wisc.edu addr); 11010447Snilay@cs.wisc.edu assert(m_in_ports > m_cur_in_port); 11110447Snilay@cs.wisc.edu (*(m_waiting_buffers[addr]))[m_cur_in_port] = buf; 11210447Snilay@cs.wisc.edu} 11310447Snilay@cs.wisc.edu 11410447Snilay@cs.wisc.eduvoid 11510447Snilay@cs.wisc.eduAbstractController::wakeUpBuffers(Address addr) 11610447Snilay@cs.wisc.edu{ 11710447Snilay@cs.wisc.edu if (m_waiting_buffers.count(addr) > 0) { 11810447Snilay@cs.wisc.edu // 11910447Snilay@cs.wisc.edu // Wake up all possible lower rank (i.e. lower priority) buffers that could 12010447Snilay@cs.wisc.edu // be waiting on this message. 12110447Snilay@cs.wisc.edu // 12210447Snilay@cs.wisc.edu for (int in_port_rank = m_cur_in_port - 1; 12310447Snilay@cs.wisc.edu in_port_rank >= 0; 12410447Snilay@cs.wisc.edu in_port_rank--) { 12510447Snilay@cs.wisc.edu if ((*(m_waiting_buffers[addr]))[in_port_rank] != NULL) { 12610447Snilay@cs.wisc.edu (*(m_waiting_buffers[addr]))[in_port_rank]->reanalyzeMessages(addr); 12710447Snilay@cs.wisc.edu } 12810447Snilay@cs.wisc.edu } 12910447Snilay@cs.wisc.edu delete m_waiting_buffers[addr]; 13010447Snilay@cs.wisc.edu m_waiting_buffers.erase(addr); 13110447Snilay@cs.wisc.edu } 13210447Snilay@cs.wisc.edu} 13310447Snilay@cs.wisc.edu 13410447Snilay@cs.wisc.eduvoid 13510447Snilay@cs.wisc.eduAbstractController::wakeUpAllBuffers(Address addr) 13610447Snilay@cs.wisc.edu{ 13710447Snilay@cs.wisc.edu if (m_waiting_buffers.count(addr) > 0) { 13810447Snilay@cs.wisc.edu // 13910447Snilay@cs.wisc.edu // Wake up all possible lower rank (i.e. lower priority) buffers that could 14010447Snilay@cs.wisc.edu // be waiting on this message. 14110447Snilay@cs.wisc.edu // 14210447Snilay@cs.wisc.edu for (int in_port_rank = m_in_ports - 1; 14310447Snilay@cs.wisc.edu in_port_rank >= 0; 14410447Snilay@cs.wisc.edu in_port_rank--) { 14510447Snilay@cs.wisc.edu if ((*(m_waiting_buffers[addr]))[in_port_rank] != NULL) { 14610447Snilay@cs.wisc.edu (*(m_waiting_buffers[addr]))[in_port_rank]->reanalyzeMessages(addr); 14710447Snilay@cs.wisc.edu } 14810447Snilay@cs.wisc.edu } 14910447Snilay@cs.wisc.edu delete m_waiting_buffers[addr]; 15010447Snilay@cs.wisc.edu m_waiting_buffers.erase(addr); 15110447Snilay@cs.wisc.edu } 15210447Snilay@cs.wisc.edu} 15310447Snilay@cs.wisc.edu 15410447Snilay@cs.wisc.eduvoid 15510447Snilay@cs.wisc.eduAbstractController::wakeUpAllBuffers() 15610447Snilay@cs.wisc.edu{ 15710447Snilay@cs.wisc.edu // 15810447Snilay@cs.wisc.edu // Wake up all possible buffers that could be waiting on any message. 15910447Snilay@cs.wisc.edu // 16010447Snilay@cs.wisc.edu 16110447Snilay@cs.wisc.edu std::vector<MsgVecType*> wokeUpMsgVecs; 16210447Snilay@cs.wisc.edu MsgBufType wokeUpMsgBufs; 16310447Snilay@cs.wisc.edu 16410447Snilay@cs.wisc.edu if(m_waiting_buffers.size() > 0) { 16510447Snilay@cs.wisc.edu for (WaitingBufType::iterator buf_iter = m_waiting_buffers.begin(); 16610447Snilay@cs.wisc.edu buf_iter != m_waiting_buffers.end(); 16710447Snilay@cs.wisc.edu ++buf_iter) { 16810447Snilay@cs.wisc.edu for (MsgVecType::iterator vec_iter = buf_iter->second->begin(); 16910447Snilay@cs.wisc.edu vec_iter != buf_iter->second->end(); 17010447Snilay@cs.wisc.edu ++vec_iter) { 17110447Snilay@cs.wisc.edu // 17210447Snilay@cs.wisc.edu // Make sure the MessageBuffer has not already be reanalyzed 17310447Snilay@cs.wisc.edu // 17410447Snilay@cs.wisc.edu if (*vec_iter != NULL && 17510447Snilay@cs.wisc.edu (wokeUpMsgBufs.count(*vec_iter) == 0)) { 17610447Snilay@cs.wisc.edu (*vec_iter)->reanalyzeAllMessages(); 17710447Snilay@cs.wisc.edu wokeUpMsgBufs.insert(*vec_iter); 17810447Snilay@cs.wisc.edu } 17910447Snilay@cs.wisc.edu } 18010447Snilay@cs.wisc.edu wokeUpMsgVecs.push_back(buf_iter->second); 18110447Snilay@cs.wisc.edu } 18210447Snilay@cs.wisc.edu 18310447Snilay@cs.wisc.edu for (std::vector<MsgVecType*>::iterator wb_iter = wokeUpMsgVecs.begin(); 18410447Snilay@cs.wisc.edu wb_iter != wokeUpMsgVecs.end(); 18510447Snilay@cs.wisc.edu ++wb_iter) { 18610447Snilay@cs.wisc.edu delete (*wb_iter); 18710447Snilay@cs.wisc.edu } 18810447Snilay@cs.wisc.edu 18910447Snilay@cs.wisc.edu m_waiting_buffers.clear(); 19010447Snilay@cs.wisc.edu } 19110447Snilay@cs.wisc.edu} 19210447Snilay@cs.wisc.edu 19310447Snilay@cs.wisc.eduvoid 19410447Snilay@cs.wisc.eduAbstractController::blockOnQueue(Address addr, MessageBuffer* port) 19510447Snilay@cs.wisc.edu{ 19610447Snilay@cs.wisc.edu m_is_blocking = true; 19710447Snilay@cs.wisc.edu m_block_map[addr] = port; 19810447Snilay@cs.wisc.edu} 19910447Snilay@cs.wisc.edu 20010447Snilay@cs.wisc.eduvoid 20110447Snilay@cs.wisc.eduAbstractController::unblock(Address addr) 20210447Snilay@cs.wisc.edu{ 20310447Snilay@cs.wisc.edu m_block_map.erase(addr); 20410447Snilay@cs.wisc.edu if (m_block_map.size() == 0) { 20510447Snilay@cs.wisc.edu m_is_blocking = false; 20610447Snilay@cs.wisc.edu } 20710447Snilay@cs.wisc.edu} 20810447Snilay@cs.wisc.edu 20910447Snilay@cs.wisc.eduBaseMasterPort & 21010447Snilay@cs.wisc.eduAbstractController::getMasterPort(const std::string &if_name, 21110447Snilay@cs.wisc.edu PortID idx) 21210447Snilay@cs.wisc.edu{ 21310447Snilay@cs.wisc.edu return memoryPort; 21410447Snilay@cs.wisc.edu} 21510447Snilay@cs.wisc.edu 21610447Snilay@cs.wisc.eduvoid 21710447Snilay@cs.wisc.eduAbstractController::queueMemoryRead(const MachineID &id, Address addr, 21810447Snilay@cs.wisc.edu Cycles latency) 21910447Snilay@cs.wisc.edu{ 22010447Snilay@cs.wisc.edu RequestPtr req = new Request(addr.getAddress(), 22110447Snilay@cs.wisc.edu RubySystem::getBlockSizeBytes(), 0, 22210447Snilay@cs.wisc.edu m_masterId); 22310447Snilay@cs.wisc.edu 22410447Snilay@cs.wisc.edu PacketPtr pkt = Packet::createRead(req); 22510447Snilay@cs.wisc.edu uint8_t *newData = new uint8_t[RubySystem::getBlockSizeBytes()]; 22610447Snilay@cs.wisc.edu pkt->dataDynamic(newData); 22710447Snilay@cs.wisc.edu 22810447Snilay@cs.wisc.edu SenderState *s = new SenderState(id); 22910447Snilay@cs.wisc.edu pkt->pushSenderState(s); 23010447Snilay@cs.wisc.edu 23110447Snilay@cs.wisc.edu // Use functional rather than timing accesses during warmup 23210447Snilay@cs.wisc.edu if (RubySystem::getWarmupEnabled()) { 23310447Snilay@cs.wisc.edu memoryPort.sendFunctional(pkt); 23410447Snilay@cs.wisc.edu recvTimingResp(pkt); 23510447Snilay@cs.wisc.edu return; 23610447Snilay@cs.wisc.edu } 23710447Snilay@cs.wisc.edu 23810447Snilay@cs.wisc.edu memoryPort.schedTimingReq(pkt, clockEdge(latency)); 23910447Snilay@cs.wisc.edu} 24010447Snilay@cs.wisc.edu 24110447Snilay@cs.wisc.eduvoid 24210447Snilay@cs.wisc.eduAbstractController::queueMemoryWrite(const MachineID &id, Address addr, 24310447Snilay@cs.wisc.edu Cycles latency, const DataBlock &block) 24410447Snilay@cs.wisc.edu{ 24510447Snilay@cs.wisc.edu RequestPtr req = new Request(addr.getAddress(), 24610447Snilay@cs.wisc.edu RubySystem::getBlockSizeBytes(), 0, 24710447Snilay@cs.wisc.edu m_masterId); 24810447Snilay@cs.wisc.edu 24910447Snilay@cs.wisc.edu PacketPtr pkt = Packet::createWrite(req); 25010447Snilay@cs.wisc.edu uint8_t *newData = new uint8_t[RubySystem::getBlockSizeBytes()]; 25110447Snilay@cs.wisc.edu pkt->dataDynamic(newData); 25210447Snilay@cs.wisc.edu memcpy(newData, block.getData(0, RubySystem::getBlockSizeBytes()), 25310447Snilay@cs.wisc.edu RubySystem::getBlockSizeBytes()); 25410447Snilay@cs.wisc.edu 25510447Snilay@cs.wisc.edu SenderState *s = new SenderState(id); 25610447Snilay@cs.wisc.edu pkt->pushSenderState(s); 25710447Snilay@cs.wisc.edu 25810447Snilay@cs.wisc.edu // Use functional rather than timing accesses during warmup 25910447Snilay@cs.wisc.edu if (RubySystem::getWarmupEnabled()) { 26010447Snilay@cs.wisc.edu memoryPort.sendFunctional(pkt); 26110447Snilay@cs.wisc.edu recvTimingResp(pkt); 26210447Snilay@cs.wisc.edu return; 26310447Snilay@cs.wisc.edu } 26410447Snilay@cs.wisc.edu 26510447Snilay@cs.wisc.edu // Create a block and copy data from the block. 26610447Snilay@cs.wisc.edu memoryPort.schedTimingReq(pkt, clockEdge(latency)); 26710447Snilay@cs.wisc.edu} 26810447Snilay@cs.wisc.edu 26910447Snilay@cs.wisc.eduvoid 27010447Snilay@cs.wisc.eduAbstractController::queueMemoryWritePartial(const MachineID &id, Address addr, 27110447Snilay@cs.wisc.edu Cycles latency, 27210447Snilay@cs.wisc.edu const DataBlock &block, int size) 27310447Snilay@cs.wisc.edu{ 27410447Snilay@cs.wisc.edu RequestPtr req = new Request(addr.getAddress(), 27510447Snilay@cs.wisc.edu RubySystem::getBlockSizeBytes(), 0, 27610447Snilay@cs.wisc.edu m_masterId); 27710447Snilay@cs.wisc.edu 27810447Snilay@cs.wisc.edu PacketPtr pkt = Packet::createWrite(req); 27910447Snilay@cs.wisc.edu uint8_t *newData = new uint8_t[size]; 28010447Snilay@cs.wisc.edu pkt->dataDynamic(newData); 28110447Snilay@cs.wisc.edu memcpy(newData, block.getData(addr.getOffset(), size), size); 28210447Snilay@cs.wisc.edu 28310447Snilay@cs.wisc.edu SenderState *s = new SenderState(id); 28410447Snilay@cs.wisc.edu pkt->pushSenderState(s); 28510447Snilay@cs.wisc.edu 28610447Snilay@cs.wisc.edu // Create a block and copy data from the block. 28710447Snilay@cs.wisc.edu memoryPort.schedTimingReq(pkt, clockEdge(latency)); 28810447Snilay@cs.wisc.edu} 28910447Snilay@cs.wisc.edu 29010447Snilay@cs.wisc.eduvoid 29110447Snilay@cs.wisc.eduAbstractController::functionalMemoryRead(PacketPtr pkt) 29210447Snilay@cs.wisc.edu{ 29310447Snilay@cs.wisc.edu memoryPort.sendFunctional(pkt); 29410447Snilay@cs.wisc.edu} 29510447Snilay@cs.wisc.edu 29610447Snilay@cs.wisc.eduint 29710447Snilay@cs.wisc.eduAbstractController::functionalMemoryWrite(PacketPtr pkt) 29810447Snilay@cs.wisc.edu{ 29910447Snilay@cs.wisc.edu int num_functional_writes = 0; 30010447Snilay@cs.wisc.edu 30110447Snilay@cs.wisc.edu // Check the message buffer that runs from the memory to the controller. 30210447Snilay@cs.wisc.edu num_functional_writes += m_responseFromMemory_ptr->functionalWrite(pkt); 30310447Snilay@cs.wisc.edu 30410447Snilay@cs.wisc.edu // Check the buffer from the controller to the memory. 30510447Snilay@cs.wisc.edu if (memoryPort.checkFunctional(pkt)) { 30610447Snilay@cs.wisc.edu num_functional_writes++; 30710447Snilay@cs.wisc.edu } 30810447Snilay@cs.wisc.edu 30910447Snilay@cs.wisc.edu // Update memory itself. 31010447Snilay@cs.wisc.edu memoryPort.sendFunctional(pkt); 31110447Snilay@cs.wisc.edu return num_functional_writes + 1; 31210447Snilay@cs.wisc.edu} 31310447Snilay@cs.wisc.edu 31410447Snilay@cs.wisc.eduvoid 31510447Snilay@cs.wisc.eduAbstractController::recvTimingResp(PacketPtr pkt) 31610447Snilay@cs.wisc.edu{ 31710447Snilay@cs.wisc.edu assert(pkt->isResponse()); 31810447Snilay@cs.wisc.edu 31910447Snilay@cs.wisc.edu std::shared_ptr<MemoryMsg> msg = std::make_shared<MemoryMsg>(clockEdge()); 32010447Snilay@cs.wisc.edu (*msg).m_Addr.setAddress(pkt->getAddr()); 32110447Snilay@cs.wisc.edu (*msg).m_Sender = m_machineID; 32210447Snilay@cs.wisc.edu 32310447Snilay@cs.wisc.edu SenderState *s = dynamic_cast<SenderState *>(pkt->senderState); 32410447Snilay@cs.wisc.edu (*msg).m_OriginalRequestorMachId = s->id; 32510447Snilay@cs.wisc.edu delete s; 32610447Snilay@cs.wisc.edu 32710447Snilay@cs.wisc.edu if (pkt->isRead()) { 328 (*msg).m_Type = MemoryRequestType_MEMORY_READ; 329 (*msg).m_MessageSize = MessageSizeType_Response_Data; 330 331 // Copy data from the packet 332 (*msg).m_DataBlk.setData(pkt->getPtr<uint8_t>(), 0, 333 RubySystem::getBlockSizeBytes()); 334 } else if (pkt->isWrite()) { 335 (*msg).m_Type = MemoryRequestType_MEMORY_WB; 336 (*msg).m_MessageSize = MessageSizeType_Writeback_Control; 337 } else { 338 panic("Incorrect packet type received from memory controller!"); 339 } 340 341 m_responseFromMemory_ptr->enqueue(msg); 342 delete pkt; 343} 344 345bool 346AbstractController::MemoryPort::recvTimingResp(PacketPtr pkt) 347{ 348 controller->recvTimingResp(pkt); 349 return true; 350} 351 352AbstractController::MemoryPort::MemoryPort(const std::string &_name, 353 AbstractController *_controller, 354 const std::string &_label) 355 : QueuedMasterPort(_name, _controller, reqQueue, snoopRespQueue), 356 reqQueue(*_controller, *this, _label), 357 snoopRespQueue(*_controller, *this, _label), 358 controller(_controller) 359{ 360} 361