From f05cb84ed1a61f81c26e4ea22f98454d12f069aa Mon Sep 17 00:00:00 2001 From: Curtis Dunham Date: Wed, 8 Apr 2015 15:56:06 -0500 Subject: [PATCH] ext: Add SST connector This patch adds a connector that allows gem5 to be used as a component in SST (Structural Simulation Toolkit, sst-simulator.org). At a high level, this allows memory traffic to pass between the two simulators. SST Links are roughly analogous to gem5 Ports, although Links do not have a notion of master and slave. This distinction is important to gem5, so when connecting a gem5 CPU to an SST cache, an ExternalSlave must be used, and similarly when connecting the memory side of SST cache to a gem5 port (for memory <-> I/O), an ExternalMaster must be used. These connectors handle the administrative aspects of gem5 (initialization, simulation, shutdown) as well as translating SST's MemEvents into gem5 Packets and vice-versa. --- ext/sst/ExtMaster.cc | 240 ++++++++++++++++++++++++++++++++++++++ ext/sst/ExtMaster.hh | 119 +++++++++++++++++++ ext/sst/ExtSlave.cc | 203 ++++++++++++++++++++++++++++++++ ext/sst/ExtSlave.hh | 119 +++++++++++++++++++ ext/sst/LICENSE | 72 ++++++++++++ ext/sst/Makefile | 20 ++++ ext/sst/README | 65 +++++++++++ ext/sst/gem5.cc | 272 +++++++++++++++++++++++++++++++++++++++++++ ext/sst/gem5.hh | 99 ++++++++++++++++ ext/sst/libgem5.cc | 84 +++++++++++++ 10 files changed, 1293 insertions(+) create mode 100644 ext/sst/ExtMaster.cc create mode 100644 ext/sst/ExtMaster.hh create mode 100644 ext/sst/ExtSlave.cc create mode 100644 ext/sst/ExtSlave.hh create mode 100644 ext/sst/LICENSE create mode 100644 ext/sst/Makefile create mode 100644 ext/sst/README create mode 100644 ext/sst/gem5.cc create mode 100644 ext/sst/gem5.hh create mode 100644 ext/sst/libgem5.cc diff --git a/ext/sst/ExtMaster.cc b/ext/sst/ExtMaster.cc new file mode 100644 index 000000000..d8febbcf1 --- /dev/null +++ b/ext/sst/ExtMaster.cc @@ -0,0 +1,240 @@ +// Copyright (c) 2015 ARM Limited +// All rights reserved. +// +// The license below extends only to copyright in the software and shall +// not be construed as granting a license to any other intellectual +// property including but not limited to intellectual property relating +// to a hardware implementation of the functionality of the software +// licensed hereunder. You may use the software subject to the license +// terms below provided that you ensure that this notice is replicated +// unmodified and in its entirety in all distributions of the software, +// modified or unmodified, in source code or in binary form. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Copyright 2009-2014 Sandia Coporation. Under the terms +// of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. +// Government retains certain rights in this software. +// +// Copyright (c) 2009-2014, Sandia Corporation +// All rights reserved. +// +// For license information, see the LICENSE file in the current directory. + +#include "gem5.hh" + +#include + +#include + +#include +#include +#include +#include + +#ifdef fatal // gem5 sets this +#undef fatal +#endif + +using namespace SST; +using namespace SST::gem5; +using namespace SST::MemHierarchy; + +ExtMaster::ExtMaster(gem5Component *g, Output &o, ::ExternalMaster& p, + std::string &n) : + Port(n, p), out(o), port(p), simPhase(CONSTRUCTION), + gem5(g), name(n) +{ + Params _p; // will be ignored + nic = dynamic_cast(gem5->loadModuleWithComponent("memHierarchy.memNIC", g, _p)); + + MemNIC::ComponentInfo ci; + ci.num_vcs = 1; + ci.link_port = "network"; + ci.link_bandwidth = "16GB/s"; + ci.link_inbuf_size = "1KB"; + ci.link_outbuf_size = "1KB"; + ci.network_addr = 0; // hard coded at the moment + ci.type = MemNIC::TypeDirectoryCtrl; + nic->moduleInit(ci, new Event::Handler + (this, &ExtMaster::handleEvent)); +} + +void +ExtMaster::init(unsigned phase) +{ + simPhase = INIT; + + if (phase == 0) { + assert(nic); + for (auto range : getAddrRanges()) { + MemNIC::ComponentTypeInfo ti; + ti.rangeStart = range.start(); + ti.rangeEnd = range.end(); + ti.interleaveSize = 0; + ti.interleaveStep = 0; + nic->addTypeInfo(ti); + ranges.insert(range); + } + } + + nic->init(phase); +} + +void +ExtMaster::setup(void) +{ + nic->setup(); + + simPhase = RUN; +} + +void +ExtMaster::finish(void) +{ + nic->finish(); +} + +void +ExtMaster::clock(void) +{ + nic->clock(); +} + +void +ExtMaster::handleEvent(SST::Event* event) +{ + if (simPhase == CONSTRUCTION) { + out.fatal(CALL_INFO, 1, "received Event during Construction phase\n"); + } + + MemEvent *ev = dynamic_cast(event); + if (!ev) { + out.fatal(CALL_INFO, 1, "Can't handle non-MemEvent Event's\n"); + } + + Command cmdI = ev->getCmd(); // command in - SST + MemCmd::Command cmdO; // command out - gem5 + bool data = false; + + switch (cmdI) { + case GetS: cmdO = MemCmd::ReadReq; break; + case GetX: cmdO = MemCmd::WriteReq; data = true; break; + case GetSEx: + case PutS: + case PutM: + case PutE: + case PutX: + case PutXE: + case Inv: + case FetchInv: + case FetchInvX: + + case NACK: + + case NULLCMD: + case GetSResp: + case GetXResp: + case FetchResp: + case FetchXResp: + out.fatal(CALL_INFO, 1, "Don't know how to convert " + "SST command %s to gem5\n", + CommandString[cmdI]); + } + + Request::FlagsType flags = 0; + if (ev->queryFlag(MemEvent::F_LOCKED)) + flags |= Request::LOCKED; + if (ev->queryFlag(MemEvent::F_NONCACHEABLE)) + flags |= Request::UNCACHEABLE; + if (ev->isLoadLink()) { + assert(cmdI == GetS); + cmdO = MemCmd::LoadLockedReq; + } else if (ev->isStoreConditional()) { + assert(cmdI == GetX); + cmdO = MemCmd::StoreCondReq; + } + + auto req = new Request(ev->getAddr(), ev->getSize(), flags, 0); + req->setThreadContext(ev->getGroupId(), 0); + + auto pkt = new Packet(req, cmdO); + pkt->allocate(); + if (data) { + pkt->setData(ev->getPayload().data()); + } + pkt->pushSenderState(new SenderState(ev)); + + if (blocked() || !sendTimingReq(pkt)) + sendQ.push_back(pkt); +} + +bool +ExtMaster::recvTimingResp(PacketPtr pkt) { + if (simPhase == INIT) { + out.fatal(CALL_INFO, 1, "not prepared to handle INIT-phase traffic\n"); + } + + // get original SST packet from gem5 SenderState + auto senderState = dynamic_cast(pkt->popSenderState()); + if (!senderState) + out.fatal(CALL_INFO, 1, "gem5 senderState corrupt\n"); + + // make (new) response packet, discard (old) original request + MemEvent* ev = senderState->event; + delete senderState; + + MemEvent* resp = ev->makeResponse(); + delete ev; + + // copy the payload and then destroy gem5 packet + resp->setPayload(pkt->getSize(), pkt->getPtr()); + delete pkt->req; + delete pkt; + + nic->send(resp); + return true; +} + +void +ExtMaster::recvReqRetry() { + while (blocked() && sendTimingReq(sendQ.front())) { + sendQ.pop_front(); + } +} + +void +ExtMaster::recvRangeChange() { + for (auto range : getAddrRanges()) { + if (ranges.find(range) == ranges.end()) { // i.e. if not found, + MemNIC::ComponentTypeInfo ti; // indicating a new range. + ti.rangeStart = range.start(); + ti.rangeEnd = range.end(); + ti.interleaveSize = 0; + ti.interleaveStep = 0; + nic->addTypeInfo(ti); + ranges.insert(range); + } + } +} diff --git a/ext/sst/ExtMaster.hh b/ext/sst/ExtMaster.hh new file mode 100644 index 000000000..2f68a406c --- /dev/null +++ b/ext/sst/ExtMaster.hh @@ -0,0 +1,119 @@ +// Copyright (c) 2015 ARM Limited +// All rights reserved. +// +// The license below extends only to copyright in the software and shall +// not be construed as granting a license to any other intellectual +// property including but not limited to intellectual property relating +// to a hardware implementation of the functionality of the software +// licensed hereunder. You may use the software subject to the license +// terms below provided that you ensure that this notice is replicated +// unmodified and in its entirety in all distributions of the software, +// modified or unmodified, in source code or in binary form. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Copyright 2009-2014 Sandia Coporation. Under the terms +// of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. +// Government retains certain rights in this software. +// +// Copyright (c) 2009-2014, Sandia Corporation +// All rights reserved. +// +// For license information, see the LICENSE file in the current directory. + +#ifndef EXT_SST_EXTMASTER_HH +#define EXT_SST_EXTMASTER_HH + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +namespace SST { + +using MemHierarchy::MemEvent; +class Link; +class Event; + +namespace MemHierarchy { +class MemNIC; +} + +namespace gem5 { + +class gem5Component; + +class ExtMaster : public ExternalMaster::Port { + + enum Phase { CONSTRUCTION, INIT, RUN }; + + Output& out; + const ExternalMaster& port; + Phase simPhase; + + gem5Component *const gem5; + const std::string name; + std::list sendQ; + bool blocked() { return !sendQ.empty(); } + + MemHierarchy::MemNIC * nic; + + struct SenderState : public Packet::SenderState + { + MemEvent *event; + SenderState(MemEvent* e) : event(e) {} + }; + + std::set ranges; + +public: + bool recvTimingResp(PacketPtr); + void recvReqRetry(); + + ExtMaster(gem5Component*, Output&, ExternalMaster&, std::string&); + void init(unsigned phase); + void setup(); + void finish(); + + void clock(); + + // receive Requests from SST bound for a gem5 slave; + // this module is "external" from gem5's perspective, thus ExternalMaster. + void handleEvent(SST::Event*); + +protected: + virtual void recvRangeChange(); +}; + +} // namespace gem5 +} // namespace SST + +#endif diff --git a/ext/sst/ExtSlave.cc b/ext/sst/ExtSlave.cc new file mode 100644 index 000000000..57df21d92 --- /dev/null +++ b/ext/sst/ExtSlave.cc @@ -0,0 +1,203 @@ +// Copyright (c) 2015 ARM Limited +// All rights reserved. +// +// The license below extends only to copyright in the software and shall +// not be construed as granting a license to any other intellectual +// property including but not limited to intellectual property relating +// to a hardware implementation of the functionality of the software +// licensed hereunder. You may use the software subject to the license +// terms below provided that you ensure that this notice is replicated +// unmodified and in its entirety in all distributions of the software, +// modified or unmodified, in source code or in binary form. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Copyright 2009-2014 Sandia Coporation. Under the terms +// of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. +// Government retains certain rights in this software. +// +// Copyright (c) 2009-2014, Sandia Corporation +// All rights reserved. +// +// For license information, see the LICENSE file in the current directory. + +#include "gem5.hh" + +#include +#include + +#include +#include +#include + +#ifdef fatal // gem5 sets this +#undef fatal +#endif + +using namespace SST; +using namespace SST::gem5; +using namespace SST::MemHierarchy; + +ExtSlave::ExtSlave(gem5Component *g5c, Output &out, + ::ExternalSlave& port, std::string &name) : + Port(name, port), + comp(g5c), out(out), simPhase(CONSTRUCTION), initPackets(NULL), + link(comp->configureLink(name, new Event::Handler(this, + &ExtSlave::handleEvent))) +{ + if (!link) { + out.fatal(CALL_INFO, 1, "Failed to configure link %s\n", name.c_str()); + } +} + +void ExtSlave::init(unsigned phase) +{ + simPhase = INIT; + if (initPackets) { + while (!initPackets->empty()) { + link->sendInitData(initPackets->front()); + initPackets->pop_front(); + } + delete initPackets; + initPackets = NULL; + } +} + +void +ExtSlave::recvFunctional(PacketPtr pkt) +{ + if (simPhase == CONSTRUCTION) { + if (initPackets == NULL) { + initPackets = new std::list; + } + ::MemCmd::Command pktCmd = (::MemCmd::Command)pkt->cmd.toInt(); + assert(pktCmd == ::MemCmd::WriteReq || pktCmd == ::MemCmd::Writeback); + Addr a = pkt->getAddr(); + MemEvent* ev = new MemEvent(comp, a, a, GetX); + ev->setPayload(pkt->getSize(), pkt->getPtr()); + initPackets->push_back(ev); + } else { + panic("Functional accesses not allowed after construction phase"); + } +} + +bool +ExtSlave::recvTimingReq(PacketPtr pkt) +{ + Command cmd; + switch ((::MemCmd::Command)pkt->cmd.toInt()) { + case ::MemCmd::HardPFReq: + case ::MemCmd::SoftPFReq: + case ::MemCmd::LoadLockedReq: + case ::MemCmd::ReadExReq: + case ::MemCmd::ReadReq: cmd = GetS; break; + case ::MemCmd::StoreCondReq: + case ::MemCmd::WriteReq: cmd = GetX; break; + default: + out.fatal(CALL_INFO, 1, "Don't know how to convert gem5 packet " + "command %s to SST\n", pkt->cmd.toString().c_str()); + } + + auto ev = new MemEvent(comp, pkt->getAddr(), pkt->getAddr(), cmd); + ev->setPayload(pkt->getSize(), pkt->getPtr()); + if ((::MemCmd::Command)pkt->cmd.toInt() == ::MemCmd::LoadLockedReq) + ev->setLoadLink(); + else if ((::MemCmd::Command)pkt->cmd.toInt() == ::MemCmd::StoreCondReq) + ev->setStoreConditional(); + + if (pkt->req->isLocked()) ev->setFlag(MemEvent::F_LOCKED); + if (pkt->req->isUncacheable()) ev->setFlag(MemEvent::F_NONCACHEABLE); + if (pkt->req->hasContextId()) ev->setGroupId(pkt->req->contextId()); +// Prefetches not working with SST; it maybe be dropping them, treating them +// as not deserving of responses, or something else -- not sure yet. +// ev->setPrefetchFlag(pkt->req->isPrefetch()); + + if (simPhase == INIT) { + link->sendInitData(ev); + delete pkt->req; + delete pkt; + } else { + if (pkt->needsResponse()) { + PacketMap[ev->getID()] = pkt; + } + link->send(ev); + } + return true; +} + + +void +ExtSlave::handleEvent(Event* ev) +{ + MemEvent* event = dynamic_cast(ev); + if (!event) { + out.fatal(CALL_INFO, 1, "ExtSlave handleEvent received non-MemEvent\n"); + delete ev; + return; + } + Event::id_type id = event->getID(); + + PacketMap_t::iterator mi = PacketMap.find(id); + if (mi != PacketMap.end()) { // replying to prior request + PacketPtr pkt = mi->second; + PacketMap.erase(mi); + + pkt->makeResponse(); // Convert to a response packet + pkt->setData(event->getPayload().data()); + + // Resolve the success of Store Conditionals + if (pkt->isLLSC() && pkt->isWrite()) { + pkt->req->setExtraData(event->isAtomic()); + } + + // Clear out bus delay notifications + pkt->headerDelay = pkt->payloadDelay = 0; + + if (blocked() || !sendTimingResp(pkt)) { + respQ.push_back(pkt); + } + } else { // we can handle unexpected invalidates, but nothing else. + Command cmd = event->getCmd(); + assert(cmd == Inv); + + // make Req/Pkt for Snoop/no response needed + // presently no consideration for masterId, packet type, flags... + RequestPtr req = new Request(event->getAddr(), event->getSize(), 0, 0); + auto pkt = new Packet(req, ::MemCmd::InvalidationReq); + + // Clear out bus delay notifications + pkt->headerDelay = pkt->payloadDelay = 0; + + sendTimingSnoopReq(pkt); + } + delete event; +} + +void +ExtSlave::recvRespRetry() +{ + while (blocked() && sendTimingResp(respQ.front())) { + respQ.pop_front(); + } +} diff --git a/ext/sst/ExtSlave.hh b/ext/sst/ExtSlave.hh new file mode 100644 index 000000000..de91a6f7b --- /dev/null +++ b/ext/sst/ExtSlave.hh @@ -0,0 +1,119 @@ +// Copyright (c) 2015 ARM Limited +// All rights reserved. +// +// The license below extends only to copyright in the software and shall +// not be construed as granting a license to any other intellectual +// property including but not limited to intellectual property relating +// to a hardware implementation of the functionality of the software +// licensed hereunder. You may use the software subject to the license +// terms below provided that you ensure that this notice is replicated +// unmodified and in its entirety in all distributions of the software, +// modified or unmodified, in source code or in binary form. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Copyright 2009-2014 Sandia Coporation. Under the terms +// of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. +// Government retains certain rights in this software. +// +// Copyright (c) 2009-2014, Sandia Corporation +// All rights reserved. +// +// For license information, see the LICENSE file in the current directory. + +#ifndef EXT_SST_EXTSLAVE_HH +#define EXT_SST_EXTSLAVE_HH + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace SST { +class Link; +class Event; +class MemEvent; +namespace gem5 { + +class gem5Component; + +class ExtSlave : public ExternalSlave::Port { + public: + const std::string name; + + bool + recvTimingSnoopResp(PacketPtr packet) + { + fatal("recvTimingSnoopResp unimplemented"); + return false; + } + + bool recvTimingReq(PacketPtr packet); + + void recvFunctional(PacketPtr packet); + + void recvRespRetry(); + + Tick + recvAtomic(PacketPtr packet) + { + fatal("recvAtomic unimplemented"); + } + + enum Phase { CONSTRUCTION, INIT, RUN }; + + gem5Component *comp; + Output &out; + Phase simPhase; + + std::list* initPackets; + Link* link; + std::list respQ; + bool blocked() { return !respQ.empty(); } + + typedef std::map PacketMap_t; + PacketMap_t PacketMap; // SST Event id -> gem5 Packet* + +public: + ExtSlave(gem5Component*, Output&, ExternalSlave&, std::string&); + void init(unsigned phase); + + void + setup() + { + simPhase = RUN; + } + + void handleEvent(Event*); +}; + +} +} + +#endif diff --git a/ext/sst/LICENSE b/ext/sst/LICENSE new file mode 100644 index 000000000..787cadce8 --- /dev/null +++ b/ext/sst/LICENSE @@ -0,0 +1,72 @@ +** This license only applies to the source files in this directory. + +Copyright (c) 2015 ARM Limited +All rights reserved. + +The license below extends only to copyright in the software and shall +not be construed as granting a license to any other intellectual +property including but not limited to intellectual property relating +to a hardware implementation of the functionality of the software +licensed hereunder. You may use the software subject to the license +terms below provided that you ensure that this notice is replicated +unmodified and in its entirety in all distributions of the software, +modified or unmodified, in source code or in binary form. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer; +redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution; +neither the name of the copyright holders nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Copyright 2009-2014 Sandia Corporation. Under the terms +of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. +Government retains certain rights in this software. + +Copyright (c) 2009-2014, Sandia Corporation + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Sandia Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ext/sst/Makefile b/ext/sst/Makefile new file mode 100644 index 000000000..3eb0a8e6c --- /dev/null +++ b/ext/sst/Makefile @@ -0,0 +1,20 @@ +# These two variables are designed to be modifiable. +SST_VERSION=SST-trunk +GEM5_LIB=gem5_opt + +LDFLAGS=-shared -fno-common ${shell pkg-config ${SST_VERSION} --libs} -L../../build/ARM +CXXFLAGS=-std=c++0x -g -O2 -fPIC ${shell pkg-config ${SST_VERSION} --cflags} ${shell python-config --includes} -I../../build/ARM +CPPFLAGS+=-MMD -MP +SRC=$(wildcard *.cc) + +.PHONY: clean all + +all: libgem5.so + +libgem5.so: $(SRC:%.cc=%.o) + ${CXX} ${CPPFLAGS} ${LDFLAGS} $? -o $@ -l${GEM5_LIB} + +-include $(SRC:%.cc=%.d) + +clean: + ${RM} *.[do] libgem5.so diff --git a/ext/sst/README b/ext/sst/README new file mode 100644 index 000000000..c9870ab85 --- /dev/null +++ b/ext/sst/README @@ -0,0 +1,65 @@ +This directory contains a connector that allows gem5 to be used as a +component in SST (Structural Simulation Toolkit, sst-simulator.org). More +specifically, it creates a .so that wraps the libgem5_*.so library. At a +high level, this allows memory traffic to pass between the two simulators. +SST Links are roughly analogous to gem5 Ports, although Links do not have +a notion of master and slave. This distinction is important to gem5, so +when connecting a gem5 CPU to an SST cache, an ExternalSlave must be used, +and similarly when connecting the memory side of SST cache to a gem5 port +(for memory <-> I/O), an ExternalMaster must be used. + +The connector handles the administrative aspects of gem5 +(initialization, simulation, shutdown) as well as translating +SST's MemEvents into gem5 Packets and vice-versa. + +Step-by-step instructions: + +0. install SST and its dependencies + +Note: the Makefile assumes you installed from an SVN checkout, not a release. +If you install a release, modify SST_VERSION at the top of the Makefile. + +0b. set/append to the PKG_CONFIG_PATH variable the path where SST installed + its pkgconfig, if not in a system-wide location. + +Then from gem5 root: + +1. build gem5 library: +% scons build/ARM/libgem5_opt.so + +Note: if you would rather use a fast, debug, etc. variant instead, +modify GEM5_LIB at the top of the Makefile. + +2. build gem5 SST component: +% make -C ext/sst + +3. run SST like so: +% sst --add-lib-path + +=========== + +Note: if you want to use an arch other than ARM (not tested/supported), +tweak the Makefile to get includes from that build directory instead. + +=========== + +This directory provides: +1. an SST "Component" for gem5; +2. a class that implements gem5's "ExternalMaster" interface to connect with + SST "Link"s exchanging "memEvents" + (sst/elements/memHierarchy stuff - caches, memories, etc.) + This lets gem5 receive packets from SST, as in + an SST LL$ (a master external to gem5) <-> I/O devices. +3. a class that implements gem5's "ExternalSlave" interface to connect with + SST "Link"s exchanging "memEvents" once again with the packet flow reversed: + gem5 CPU <-> SST L1 cache (a slave external to gem5) +4. an example configuration that uses both as follows: + gem5 CPUs + ^ + | [ExternalSlave] + v + SST cache hierarchy <-> SST memory + ^ + | [ExternalMaster] + v + gem5 I/O devices (terminal, disk, etc.) diff --git a/ext/sst/gem5.cc b/ext/sst/gem5.cc new file mode 100644 index 000000000..29cea8363 --- /dev/null +++ b/ext/sst/gem5.cc @@ -0,0 +1,272 @@ +// Copyright (c) 2015 ARM Limited +// All rights reserved. +// +// The license below extends only to copyright in the software and shall +// not be construed as granting a license to any other intellectual +// property including but not limited to intellectual property relating +// to a hardware implementation of the functionality of the software +// licensed hereunder. You may use the software subject to the license +// terms below provided that you ensure that this notice is replicated +// unmodified and in its entirety in all distributions of the software, +// modified or unmodified, in source code or in binary form. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Copyright 2009-2014 Sandia Coporation. Under the terms +// of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. +// Government retains certain rights in this software. +// +// Copyright (c) 2009-2014, Sandia Corporation +// All rights reserved. +// +// For license information, see the LICENSE file in the current directory. + +#include +#include // Before serialization to prevent spurious warnings +#include + +#include "gem5.hh" + +// System headers +#include +#include + +// gem5 Headers +#include +#include +#include +#include +#include +#include +#include + +#ifdef fatal // gem5 sets this +#undef fatal +#endif + +// More SST Headers +#include +#include +#include +#include + +using namespace SST; +using namespace SST::gem5; + +gem5Component::gem5Component(ComponentId_t id, Params ¶ms) : + SST::Component(id) +{ + dbg.init("@t:gem5:@p():@l " + getName() + ": ", 0, 0, + (Output::output_location_t)params.find_integer("comp_debug", 0)); + info.init("gem5:" + getName() + ": ", 0, 0, Output::STDOUT); + + TimeConverter *clock = registerClock( + params.find_string("frequency", "1GHz"), + new Clock::Handler(this, &gem5Component::clockTick)); + + // This sets how many gem5 cycles we'll need to simulate per clock tick + sim_cycles = clock->getFactor(); + + // Disable gem5's inform() messages. + want_info = false; + + std::string cmd = params.find_string("cmd", ""); + if (cmd.empty()) { + _abort(gem5Component, "Component %s must have a 'cmd' parameter.\n", + getName().c_str()); + } + + std::vector args; + args.push_back(const_cast("sst.x")); // TODO: Compute this somehow? + splitCommandArgs(cmd, args); + args.push_back(const_cast("--initialize-only")); + dbg.output(CALL_INFO, "Command string: [sst.x %s --initialize-only]\n", + cmd.c_str()); + for (size_t i = 0; i < args.size(); ++i) { + dbg.output(CALL_INFO, " Arg [%02zu] = %s\n", i, args[i]); + } + + std::vector flags; + std::string gem5DbgFlags = params.find_string("gem5DebugFlags", ""); + splitCommandArgs(gem5DbgFlags, flags); + for (auto flag : flags) { + dbg.output(CALL_INFO, " Setting Debug Flag [%s]\n", flag); + setDebugFlag(flag); + } + + ExternalMaster::registerHandler("sst", this); // these are idempotent + ExternalSlave ::registerHandler("sst", this); + + // Initialize m5 special signal handling. + initSignals(); + + initPython(args.size(), &args[0]); + + // tell the simulator not to end without us + registerAsPrimaryComponent(); + primaryComponentDoNotEndSim(); + + clocks_processed = 0; +} + +gem5Component::~gem5Component(void) +{ + Py_Finalize(); +} + +void +gem5Component::init(unsigned phase) +{ + for (auto m : masters) { + m->init(phase); + } + for (auto s : slaves) { + s->init(phase); + } +} + +void +gem5Component::setup(void) +{ + // Switch connectors from initData to regular Sends + for (auto m : masters) { + m->setup(); + } + for (auto s : slaves) { + s->setup(); + } +} + +void +gem5Component::finish(void) +{ + for (auto m : masters) { + m->finish(); + } + info.output("Complete. Clocks Processed: %"PRIu64"\n", clocks_processed); +} + +bool +gem5Component::clockTick(Cycle_t cycle) +{ + dbg.output(CALL_INFO, "Cycle %lu\n", cycle); + + for (auto m : masters) { + m->clock(); + } + + GlobalSimLoopExitEvent *event = simulate(sim_cycles); + ++clocks_processed; + if (event != simulate_limit_event) { + info.output("exiting: curTick()=%lu cause=`%s` code=%d\n", + curTick(), event->getCause().c_str(), event->getCode()); + primaryComponentOKToEndSim(); + return true; + } + + return false; +} + + +void +gem5Component::splitCommandArgs(std::string &cmd, + std::vector &args) +{ + std::string sep1("\\"); + std::string sep2(" "); + std::string sep3("\"\'"); + + boost::escaped_list_separator els(sep1, sep2, sep3); + boost::tokenizer> tok(cmd, els); + + for (auto beg : tok) { + args.push_back(strdup(beg.c_str())); + } +} + + +void +gem5Component::initPython(int argc, char *argv[]) +{ + const char * m5MainCommands[] = { + "import m5", + "m5.main()", + 0 // sentinel is required + }; + + PyObject *mainModule,*mainDict; + + Py_SetProgramName(argv[0]); // optional but recommended + + Py_Initialize(); + + int ret = initM5Python(); + if (ret != 0) { + _abort(gem5Component, "Python failed to initialize. Code: %d\n", ret); + } + + PySys_SetArgv(argc, argv); + + mainModule = PyImport_AddModule("__main__"); + assert(mainModule); + + mainDict = PyModule_GetDict(mainModule); + assert(mainDict); + + PyObject *result; + const char **command = m5MainCommands; + + // evaluate each command in the m5MainCommands array (basically a + // bunch of python statements. + while (*command) { + result = PyRun_String(*command, Py_file_input, mainDict, mainDict); + if (!result) { + PyErr_Print(); + break; + } + Py_DECREF(result); + + command++; + } +} + +ExternalMaster::Port* +gem5Component::getExternalPort(const std::string &name, + ExternalMaster &owner, const std::string &port_data) +{ + std::string s(name); // bridges non-& result and &-arg + auto master = new ExtMaster(this, info, owner, s); + masters.push_back(master); + return master; +} + +ExternalSlave::Port* +gem5Component::getExternalPort(const std::string &name, + ExternalSlave &owner, const std::string &port_data) +{ + std::string s(name); // bridges non-& result and &-arg + auto slave = new ExtSlave(this, info, owner, s); + slaves.push_back(slave); + return slave; +} diff --git a/ext/sst/gem5.hh b/ext/sst/gem5.hh new file mode 100644 index 000000000..6b2f1a17e --- /dev/null +++ b/ext/sst/gem5.hh @@ -0,0 +1,99 @@ +// Copyright (c) 2015 ARM Limited +// All rights reserved. +// +// The license below extends only to copyright in the software and shall +// not be construed as granting a license to any other intellectual +// property including but not limited to intellectual property relating +// to a hardware implementation of the functionality of the software +// licensed hereunder. You may use the software subject to the license +// terms below provided that you ensure that this notice is replicated +// unmodified and in its entirety in all distributions of the software, +// modified or unmodified, in source code or in binary form. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Copyright 2009-2014 Sandia Coporation. Under the terms +// of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. +// Government retains certain rights in this software. +// +// Copyright (c) 2009-2014, Sandia Corporation +// All rights reserved. +// +// For license information, see the LICENSE file in the current directory. + +#ifndef EXT_SST_GEM5_HH +#define EXT_SST_GEM5_HH + +#include +#include + +#include +#include +#include + +#include + +#include "ExtMaster.hh" +#include "ExtSlave.hh" + +namespace SST { +namespace gem5 { + +class gem5Component : public SST::Component, + public ExternalSlave::Handler, + public ExternalMaster::Handler { +private: + + Output dbg; + Output info; + uint64_t sim_cycles; + uint64_t clocks_processed; + + std::vector masters; + std::vector slaves; + + void splitCommandArgs(std::string &cmd, std::vector &args); + void initPython(int argc, char *argv[]); + +public: + gem5Component(ComponentId_t id, Params ¶ms); + ~gem5Component(); + virtual void init(unsigned); + virtual void setup(); + virtual void finish(); + bool clockTick(Cycle_t); + + virtual ExternalMaster::Port *getExternalPort( + const std::string &name, ExternalMaster &owner, + const std::string &port_data); + + virtual ExternalSlave::Port *getExternalPort( + const std::string &name, ExternalSlave &owner, + const std::string &port_data); +}; + +} +} + +#endif diff --git a/ext/sst/libgem5.cc b/ext/sst/libgem5.cc new file mode 100644 index 000000000..f490d6f84 --- /dev/null +++ b/ext/sst/libgem5.cc @@ -0,0 +1,84 @@ +// Copyright (c) 2015 ARM Limited +// All rights reserved. +// +// The license below extends only to copyright in the software and shall +// not be construed as granting a license to any other intellectual +// property including but not limited to intellectual property relating +// to a hardware implementation of the functionality of the software +// licensed hereunder. You may use the software subject to the license +// terms below provided that you ensure that this notice is replicated +// unmodified and in its entirety in all distributions of the software, +// modified or unmodified, in source code or in binary form. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Copyright 2009-2014 Sandia Coporation. Under the terms +// of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. +// Government retains certain rights in this software. +// +// Copyright (c) 2009-2014, Sandia Corporation +// All rights reserved. +// +// For license information, see the LICENSE file in the current directory. + +#include + +#include +#include +#include + +#include "gem5.hh" + +static +SST::Component* create_gem5(SST::ComponentId_t id, SST::Params ¶ms) +{ + return new SST::gem5::gem5Component(id, params); +} + + +static const SST::ElementInfoParam gem5_params[] = { + {"cmd", "gem5 command to execute."}, + {"comp_debug", "Debug information from the component: 0 (off), 1 (stdout)," + " 2 (stderr), 3(file)"}, + {"frequency", "Frequency with which to call into gem5"}, + {NULL, NULL} +}; + +static const SST::ElementInfoComponent components[] = { + { "gem5", + "gem5 simulation component", + NULL, + create_gem5, + gem5_params + }, + { NULL, NULL, NULL, NULL, NULL } +}; + +extern "C" { + SST::ElementLibraryInfo gem5_eli = { + "gem5", + "gem5 Simulation", + components, + }; +}