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