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.
This commit is contained in:
Curtis Dunham 2015-04-08 15:56:06 -05:00
parent b5770ff5e0
commit f05cb84ed1
10 changed files with 1293 additions and 0 deletions

240
ext/sst/ExtMaster.cc Normal file
View file

@ -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 <sst_config.h>
#include <mem/packet.hh>
#include <sst/core/component.h>
#include <sst/core/params.h>
#include <sst/core/link.h>
#include <sst/elements/memHierarchy/memNIC.h>
#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<MemNIC*>(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<ExtMaster>
(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<MemEvent*>(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<SenderState*>(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<uint8_t>());
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);
}
}
}

119
ext/sst/ExtMaster.hh Normal file
View file

@ -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 <list>
#include <set>
#include <sst/core/serialization.h>
#include <sst/core/component.h>
#include <sst/elements/memHierarchy/memEvent.h>
#include <sim/sim_object.hh>
#include <mem/packet.hh>
#include <mem/request.hh>
#include <mem/external_master.hh>
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<PacketPtr> sendQ;
bool blocked() { return !sendQ.empty(); }
MemHierarchy::MemNIC * nic;
struct SenderState : public Packet::SenderState
{
MemEvent *event;
SenderState(MemEvent* e) : event(e) {}
};
std::set<AddrRange> 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

203
ext/sst/ExtSlave.cc Normal file
View file

@ -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 <sst_config.h>
#include <sst/core/serialization.h>
#include <sst/core/params.h>
#include <sst/core/output.h>
#include <sst/core/link.h>
#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<ExtSlave>(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<MemEvent*>;
}
::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<uint8_t>());
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<uint8_t>());
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<MemEvent*>(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();
}
}

119
ext/sst/ExtSlave.hh Normal file
View file

@ -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 <sst/core/serialization.h>
#include <sst/core/component.h>
#include <sst/core/output.h>
#include <sst/core/interfaces/simpleMem.h>
#include <sim/sim_object.hh>
#include <mem/packet.hh>
#include <mem/request.hh>
#include <mem/external_slave.hh>
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<MemEvent*>* initPackets;
Link* link;
std::list<PacketPtr> respQ;
bool blocked() { return !respQ.empty(); }
typedef std::map<Event::id_type, ::Packet*> 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

72
ext/sst/LICENSE Normal file
View file

@ -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.

20
ext/sst/Makefile Normal file
View file

@ -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

65
ext/sst/README Normal file
View file

@ -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 <path to ./ext/sst> <config script, e.g. ext/sst/*.py>
===========
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.)

272
ext/sst/gem5.cc Normal file
View file

@ -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 <sst_config.h>
#include <Python.h> // Before serialization to prevent spurious warnings
#include <sst/core/serialization.h>
#include "gem5.hh"
// System headers
#include <boost/tokenizer.hpp>
#include <string>
// gem5 Headers
#include <sim/core.hh>
#include <sim/init.hh>
#include <sim/init_signals.hh>
#include <sim/system.hh>
#include <sim/sim_object.hh>
#include <base/misc.hh>
#include <base/debug.hh>
#ifdef fatal // gem5 sets this
#undef fatal
#endif
// More SST Headers
#include <sst/core/params.h>
#include <sst/core/link.h>
#include <sst/core/timeConverter.h>
#include <sst/core/debug.h>
using namespace SST;
using namespace SST::gem5;
gem5Component::gem5Component(ComponentId_t id, Params &params) :
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<gem5Component>(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<char*> args;
args.push_back(const_cast<char*>("sst.x")); // TODO: Compute this somehow?
splitCommandArgs(cmd, args);
args.push_back(const_cast<char*>("--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<char*> 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<char *> &args)
{
std::string sep1("\\");
std::string sep2(" ");
std::string sep3("\"\'");
boost::escaped_list_separator<char> els(sep1, sep2, sep3);
boost::tokenizer<boost::escaped_list_separator<char>> 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;
}

99
ext/sst/gem5.hh Normal file
View file

@ -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 <string>
#include <vector>
#include <sst/core/serialization.h>
#include <sst/core/component.h>
#include <sst/core/output.h>
#include <sim/simulate.hh>
#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<ExtMaster*> masters;
std::vector<ExtSlave*> slaves;
void splitCommandArgs(std::string &cmd, std::vector<char*> &args);
void initPython(int argc, char *argv[]);
public:
gem5Component(ComponentId_t id, Params &params);
~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

84
ext/sst/libgem5.cc Normal file
View file

@ -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 <sst_config.h>
#include <sst/core/serialization.h>
#include <sst/core/element.h>
#include <sst/core/component.h>
#include "gem5.hh"
static
SST::Component* create_gem5(SST::ComponentId_t id, SST::Params &params)
{
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,
};
}