ExtMaster.cc revision 11315
110779SCurtis.Dunham@arm.com// Copyright (c) 2015 ARM Limited 210779SCurtis.Dunham@arm.com// All rights reserved. 310779SCurtis.Dunham@arm.com// 410779SCurtis.Dunham@arm.com// The license below extends only to copyright in the software and shall 510779SCurtis.Dunham@arm.com// not be construed as granting a license to any other intellectual 610779SCurtis.Dunham@arm.com// property including but not limited to intellectual property relating 710779SCurtis.Dunham@arm.com// to a hardware implementation of the functionality of the software 810779SCurtis.Dunham@arm.com// licensed hereunder. You may use the software subject to the license 910779SCurtis.Dunham@arm.com// terms below provided that you ensure that this notice is replicated 1010779SCurtis.Dunham@arm.com// unmodified and in its entirety in all distributions of the software, 1110779SCurtis.Dunham@arm.com// modified or unmodified, in source code or in binary form. 1210779SCurtis.Dunham@arm.com// 1310779SCurtis.Dunham@arm.com// Redistribution and use in source and binary forms, with or without 1410779SCurtis.Dunham@arm.com// modification, are permitted provided that the following conditions are 1510779SCurtis.Dunham@arm.com// met: redistributions of source code must retain the above copyright 1610779SCurtis.Dunham@arm.com// notice, this list of conditions and the following disclaimer; 1710779SCurtis.Dunham@arm.com// redistributions in binary form must reproduce the above copyright 1810779SCurtis.Dunham@arm.com// notice, this list of conditions and the following disclaimer in the 1910779SCurtis.Dunham@arm.com// documentation and/or other materials provided with the distribution; 2010779SCurtis.Dunham@arm.com// neither the name of the copyright holders nor the names of its 2110779SCurtis.Dunham@arm.com// contributors may be used to endorse or promote products derived from 2210779SCurtis.Dunham@arm.com// this software without specific prior written permission. 2310779SCurtis.Dunham@arm.com// 2410779SCurtis.Dunham@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2510779SCurtis.Dunham@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2610779SCurtis.Dunham@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2710779SCurtis.Dunham@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2810779SCurtis.Dunham@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2910779SCurtis.Dunham@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3010779SCurtis.Dunham@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3110779SCurtis.Dunham@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3210779SCurtis.Dunham@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3310779SCurtis.Dunham@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3410779SCurtis.Dunham@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3510779SCurtis.Dunham@arm.com 3610779SCurtis.Dunham@arm.com// Copyright 2009-2014 Sandia Coporation. Under the terms 3710779SCurtis.Dunham@arm.com// of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. 3810779SCurtis.Dunham@arm.com// Government retains certain rights in this software. 3910779SCurtis.Dunham@arm.com// 4010779SCurtis.Dunham@arm.com// Copyright (c) 2009-2014, Sandia Corporation 4110779SCurtis.Dunham@arm.com// All rights reserved. 4210779SCurtis.Dunham@arm.com// 4310779SCurtis.Dunham@arm.com// For license information, see the LICENSE file in the current directory. 4410779SCurtis.Dunham@arm.com 4510779SCurtis.Dunham@arm.com#include "gem5.hh" 4610779SCurtis.Dunham@arm.com 4711315SCurtis.Dunham@arm.com#ifdef fatal // gem5 sets this 4811315SCurtis.Dunham@arm.com#undef fatal 4911315SCurtis.Dunham@arm.com#endif 5011315SCurtis.Dunham@arm.com 5110779SCurtis.Dunham@arm.com#include <sst_config.h> 5210779SCurtis.Dunham@arm.com 5310779SCurtis.Dunham@arm.com#include <mem/packet.hh> 5410779SCurtis.Dunham@arm.com 5510779SCurtis.Dunham@arm.com#include <sst/core/component.h> 5610779SCurtis.Dunham@arm.com#include <sst/core/params.h> 5710779SCurtis.Dunham@arm.com#include <sst/core/link.h> 5810779SCurtis.Dunham@arm.com#include <sst/elements/memHierarchy/memNIC.h> 5910779SCurtis.Dunham@arm.com 6010779SCurtis.Dunham@arm.comusing namespace SST; 6110779SCurtis.Dunham@arm.comusing namespace SST::gem5; 6210779SCurtis.Dunham@arm.comusing namespace SST::MemHierarchy; 6310779SCurtis.Dunham@arm.com 6410779SCurtis.Dunham@arm.comExtMaster::ExtMaster(gem5Component *g, Output &o, ::ExternalMaster& p, 6510779SCurtis.Dunham@arm.com std::string &n) : 6610779SCurtis.Dunham@arm.com Port(n, p), out(o), port(p), simPhase(CONSTRUCTION), 6710779SCurtis.Dunham@arm.com gem5(g), name(n) 6810779SCurtis.Dunham@arm.com{ 6910779SCurtis.Dunham@arm.com Params _p; // will be ignored 7010779SCurtis.Dunham@arm.com nic = dynamic_cast<MemNIC*>(gem5->loadModuleWithComponent("memHierarchy.memNIC", g, _p)); 7110779SCurtis.Dunham@arm.com 7210779SCurtis.Dunham@arm.com MemNIC::ComponentInfo ci; 7310779SCurtis.Dunham@arm.com ci.num_vcs = 1; 7410779SCurtis.Dunham@arm.com ci.link_port = "network"; 7510779SCurtis.Dunham@arm.com ci.link_bandwidth = "16GB/s"; 7610779SCurtis.Dunham@arm.com ci.link_inbuf_size = "1KB"; 7710779SCurtis.Dunham@arm.com ci.link_outbuf_size = "1KB"; 7810779SCurtis.Dunham@arm.com ci.network_addr = 0; // hard coded at the moment 7910779SCurtis.Dunham@arm.com ci.type = MemNIC::TypeDirectoryCtrl; 8010779SCurtis.Dunham@arm.com nic->moduleInit(ci, new Event::Handler<ExtMaster> 8110779SCurtis.Dunham@arm.com (this, &ExtMaster::handleEvent)); 8210779SCurtis.Dunham@arm.com} 8310779SCurtis.Dunham@arm.com 8410779SCurtis.Dunham@arm.comvoid 8510779SCurtis.Dunham@arm.comExtMaster::init(unsigned phase) 8610779SCurtis.Dunham@arm.com{ 8710779SCurtis.Dunham@arm.com simPhase = INIT; 8810779SCurtis.Dunham@arm.com 8910779SCurtis.Dunham@arm.com if (phase == 0) { 9010779SCurtis.Dunham@arm.com assert(nic); 9110779SCurtis.Dunham@arm.com for (auto range : getAddrRanges()) { 9210779SCurtis.Dunham@arm.com MemNIC::ComponentTypeInfo ti; 9310779SCurtis.Dunham@arm.com ti.rangeStart = range.start(); 9410779SCurtis.Dunham@arm.com ti.rangeEnd = range.end(); 9510779SCurtis.Dunham@arm.com ti.interleaveSize = 0; 9610779SCurtis.Dunham@arm.com ti.interleaveStep = 0; 9710779SCurtis.Dunham@arm.com nic->addTypeInfo(ti); 9810779SCurtis.Dunham@arm.com ranges.insert(range); 9910779SCurtis.Dunham@arm.com } 10010779SCurtis.Dunham@arm.com } 10110779SCurtis.Dunham@arm.com 10210779SCurtis.Dunham@arm.com nic->init(phase); 10310779SCurtis.Dunham@arm.com} 10410779SCurtis.Dunham@arm.com 10510779SCurtis.Dunham@arm.comvoid 10610779SCurtis.Dunham@arm.comExtMaster::setup(void) 10710779SCurtis.Dunham@arm.com{ 10810779SCurtis.Dunham@arm.com nic->setup(); 10910779SCurtis.Dunham@arm.com 11010779SCurtis.Dunham@arm.com simPhase = RUN; 11110779SCurtis.Dunham@arm.com} 11210779SCurtis.Dunham@arm.com 11310779SCurtis.Dunham@arm.comvoid 11410779SCurtis.Dunham@arm.comExtMaster::finish(void) 11510779SCurtis.Dunham@arm.com{ 11610779SCurtis.Dunham@arm.com nic->finish(); 11710779SCurtis.Dunham@arm.com} 11810779SCurtis.Dunham@arm.com 11910779SCurtis.Dunham@arm.comvoid 12010779SCurtis.Dunham@arm.comExtMaster::clock(void) 12110779SCurtis.Dunham@arm.com{ 12210779SCurtis.Dunham@arm.com nic->clock(); 12310779SCurtis.Dunham@arm.com} 12410779SCurtis.Dunham@arm.com 12510779SCurtis.Dunham@arm.comvoid 12610779SCurtis.Dunham@arm.comExtMaster::handleEvent(SST::Event* event) 12710779SCurtis.Dunham@arm.com{ 12810779SCurtis.Dunham@arm.com if (simPhase == CONSTRUCTION) { 12910779SCurtis.Dunham@arm.com out.fatal(CALL_INFO, 1, "received Event during Construction phase\n"); 13010779SCurtis.Dunham@arm.com } 13110779SCurtis.Dunham@arm.com 13210779SCurtis.Dunham@arm.com MemEvent *ev = dynamic_cast<MemEvent*>(event); 13310779SCurtis.Dunham@arm.com if (!ev) { 13410779SCurtis.Dunham@arm.com out.fatal(CALL_INFO, 1, "Can't handle non-MemEvent Event's\n"); 13510779SCurtis.Dunham@arm.com } 13610779SCurtis.Dunham@arm.com 13710779SCurtis.Dunham@arm.com Command cmdI = ev->getCmd(); // command in - SST 13810779SCurtis.Dunham@arm.com MemCmd::Command cmdO; // command out - gem5 13910779SCurtis.Dunham@arm.com bool data = false; 14010779SCurtis.Dunham@arm.com 14110779SCurtis.Dunham@arm.com switch (cmdI) { 14210779SCurtis.Dunham@arm.com case GetS: cmdO = MemCmd::ReadReq; break; 14310779SCurtis.Dunham@arm.com case GetX: cmdO = MemCmd::WriteReq; data = true; break; 14410779SCurtis.Dunham@arm.com case GetSEx: 14510779SCurtis.Dunham@arm.com case PutS: 14610779SCurtis.Dunham@arm.com case PutM: 14710779SCurtis.Dunham@arm.com case PutE: 14810779SCurtis.Dunham@arm.com case PutX: 14910779SCurtis.Dunham@arm.com case PutXE: 15010779SCurtis.Dunham@arm.com case Inv: 15110779SCurtis.Dunham@arm.com case FetchInv: 15210779SCurtis.Dunham@arm.com case FetchInvX: 15310779SCurtis.Dunham@arm.com 15410779SCurtis.Dunham@arm.com case NACK: 15510779SCurtis.Dunham@arm.com 15610779SCurtis.Dunham@arm.com case NULLCMD: 15710779SCurtis.Dunham@arm.com case GetSResp: 15810779SCurtis.Dunham@arm.com case GetXResp: 15910779SCurtis.Dunham@arm.com case FetchResp: 16010779SCurtis.Dunham@arm.com case FetchXResp: 16110779SCurtis.Dunham@arm.com out.fatal(CALL_INFO, 1, "Don't know how to convert " 16210779SCurtis.Dunham@arm.com "SST command %s to gem5\n", 16310779SCurtis.Dunham@arm.com CommandString[cmdI]); 16410779SCurtis.Dunham@arm.com } 16510779SCurtis.Dunham@arm.com 16610779SCurtis.Dunham@arm.com Request::FlagsType flags = 0; 16710779SCurtis.Dunham@arm.com if (ev->queryFlag(MemEvent::F_LOCKED)) 16811158SCurtis.Dunham@arm.com flags |= Request::LOCKED_RMW; 16910779SCurtis.Dunham@arm.com if (ev->queryFlag(MemEvent::F_NONCACHEABLE)) 17010779SCurtis.Dunham@arm.com flags |= Request::UNCACHEABLE; 17110779SCurtis.Dunham@arm.com if (ev->isLoadLink()) { 17210779SCurtis.Dunham@arm.com assert(cmdI == GetS); 17310779SCurtis.Dunham@arm.com cmdO = MemCmd::LoadLockedReq; 17410779SCurtis.Dunham@arm.com } else if (ev->isStoreConditional()) { 17510779SCurtis.Dunham@arm.com assert(cmdI == GetX); 17610779SCurtis.Dunham@arm.com cmdO = MemCmd::StoreCondReq; 17710779SCurtis.Dunham@arm.com } 17810779SCurtis.Dunham@arm.com 17910779SCurtis.Dunham@arm.com auto req = new Request(ev->getAddr(), ev->getSize(), flags, 0); 18010779SCurtis.Dunham@arm.com req->setThreadContext(ev->getGroupId(), 0); 18110779SCurtis.Dunham@arm.com 18210779SCurtis.Dunham@arm.com auto pkt = new Packet(req, cmdO); 18310779SCurtis.Dunham@arm.com pkt->allocate(); 18410779SCurtis.Dunham@arm.com if (data) { 18510779SCurtis.Dunham@arm.com pkt->setData(ev->getPayload().data()); 18610779SCurtis.Dunham@arm.com } 18710779SCurtis.Dunham@arm.com pkt->pushSenderState(new SenderState(ev)); 18810779SCurtis.Dunham@arm.com 18910779SCurtis.Dunham@arm.com if (blocked() || !sendTimingReq(pkt)) 19010779SCurtis.Dunham@arm.com sendQ.push_back(pkt); 19110779SCurtis.Dunham@arm.com} 19210779SCurtis.Dunham@arm.com 19310779SCurtis.Dunham@arm.combool 19410779SCurtis.Dunham@arm.comExtMaster::recvTimingResp(PacketPtr pkt) { 19510779SCurtis.Dunham@arm.com if (simPhase == INIT) { 19610779SCurtis.Dunham@arm.com out.fatal(CALL_INFO, 1, "not prepared to handle INIT-phase traffic\n"); 19710779SCurtis.Dunham@arm.com } 19810779SCurtis.Dunham@arm.com 19910779SCurtis.Dunham@arm.com // get original SST packet from gem5 SenderState 20010779SCurtis.Dunham@arm.com auto senderState = dynamic_cast<SenderState*>(pkt->popSenderState()); 20110779SCurtis.Dunham@arm.com if (!senderState) 20210779SCurtis.Dunham@arm.com out.fatal(CALL_INFO, 1, "gem5 senderState corrupt\n"); 20310779SCurtis.Dunham@arm.com 20410779SCurtis.Dunham@arm.com // make (new) response packet, discard (old) original request 20510779SCurtis.Dunham@arm.com MemEvent* ev = senderState->event; 20610779SCurtis.Dunham@arm.com delete senderState; 20710779SCurtis.Dunham@arm.com 20810779SCurtis.Dunham@arm.com MemEvent* resp = ev->makeResponse(); 20910779SCurtis.Dunham@arm.com delete ev; 21010779SCurtis.Dunham@arm.com 21110779SCurtis.Dunham@arm.com // copy the payload and then destroy gem5 packet 21210779SCurtis.Dunham@arm.com resp->setPayload(pkt->getSize(), pkt->getPtr<uint8_t>()); 21310779SCurtis.Dunham@arm.com delete pkt->req; 21410779SCurtis.Dunham@arm.com delete pkt; 21510779SCurtis.Dunham@arm.com 21610779SCurtis.Dunham@arm.com nic->send(resp); 21710779SCurtis.Dunham@arm.com return true; 21810779SCurtis.Dunham@arm.com} 21910779SCurtis.Dunham@arm.com 22010779SCurtis.Dunham@arm.comvoid 22110779SCurtis.Dunham@arm.comExtMaster::recvReqRetry() { 22210779SCurtis.Dunham@arm.com while (blocked() && sendTimingReq(sendQ.front())) { 22310779SCurtis.Dunham@arm.com sendQ.pop_front(); 22410779SCurtis.Dunham@arm.com } 22510779SCurtis.Dunham@arm.com} 22610779SCurtis.Dunham@arm.com 22710779SCurtis.Dunham@arm.comvoid 22810779SCurtis.Dunham@arm.comExtMaster::recvRangeChange() { 22910779SCurtis.Dunham@arm.com for (auto range : getAddrRanges()) { 23010779SCurtis.Dunham@arm.com if (ranges.find(range) == ranges.end()) { // i.e. if not found, 23110779SCurtis.Dunham@arm.com MemNIC::ComponentTypeInfo ti; // indicating a new range. 23210779SCurtis.Dunham@arm.com ti.rangeStart = range.start(); 23310779SCurtis.Dunham@arm.com ti.rangeEnd = range.end(); 23410779SCurtis.Dunham@arm.com ti.interleaveSize = 0; 23510779SCurtis.Dunham@arm.com ti.interleaveStep = 0; 23610779SCurtis.Dunham@arm.com nic->addTypeInfo(ti); 23710779SCurtis.Dunham@arm.com ranges.insert(range); 23810779SCurtis.Dunham@arm.com } 23910779SCurtis.Dunham@arm.com } 24010779SCurtis.Dunham@arm.com} 241