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:
parent
b5770ff5e0
commit
f05cb84ed1
10 changed files with 1293 additions and 0 deletions
240
ext/sst/ExtMaster.cc
Normal file
240
ext/sst/ExtMaster.cc
Normal 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
119
ext/sst/ExtMaster.hh
Normal 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
203
ext/sst/ExtSlave.cc
Normal 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
119
ext/sst/ExtSlave.hh
Normal 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
72
ext/sst/LICENSE
Normal 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
20
ext/sst/Makefile
Normal 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
65
ext/sst/README
Normal 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
272
ext/sst/gem5.cc
Normal 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 ¶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<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
99
ext/sst/gem5.hh
Normal 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 ¶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
|
84
ext/sst/libgem5.cc
Normal file
84
ext/sst/libgem5.cc
Normal 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 ¶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,
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in a new issue