mem: Add ExternalMaster and ExternalSlave ports
This patch adds two MemoryObject's: ExternalMaster and ExternalSlave. Each object has a single port which can be bound to an externally- provided bridge to a port of another simulation system at initialisation.
This commit is contained in:
parent
83f7e7afaf
commit
d6732895a5
7 changed files with 747 additions and 0 deletions
52
src/mem/ExternalMaster.py
Normal file
52
src/mem/ExternalMaster.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
# Copyright (c) 2014 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.
|
||||
#
|
||||
# Authors: Andrew Bardsley
|
||||
# Curtis Dunham
|
||||
|
||||
from m5.params import *
|
||||
from MemObject import MemObject
|
||||
|
||||
class ExternalMaster(MemObject):
|
||||
type = 'ExternalMaster'
|
||||
cxx_header = "mem/external_master.hh"
|
||||
|
||||
port = MasterPort("Master port")
|
||||
|
||||
port_type = Param.String('stub', 'Registered external port handler'
|
||||
' to pass this port to in instantiation')
|
||||
port_data = Param.String('stub', 'A string to pass to the port'
|
||||
' handler (in a format specific to the handler) to describe how'
|
||||
' the port should be bound/bindable/discoverable')
|
54
src/mem/ExternalSlave.py
Normal file
54
src/mem/ExternalSlave.py
Normal file
|
@ -0,0 +1,54 @@
|
|||
# Copyright (c) 2014 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.
|
||||
#
|
||||
# Authors: Andrew Bardsley
|
||||
|
||||
from m5.params import *
|
||||
from MemObject import MemObject
|
||||
|
||||
class ExternalSlave(MemObject):
|
||||
type = 'ExternalSlave'
|
||||
cxx_header = "mem/external_slave.hh"
|
||||
|
||||
port = SlavePort("Slave port")
|
||||
|
||||
addr_ranges = VectorParam.AddrRange([], 'Addresses served by'
|
||||
' this port\'s external agent')
|
||||
|
||||
port_type = Param.String('stub', 'Registered external port handler'
|
||||
' to pass this port to in instantiation')
|
||||
port_data = Param.String('stub', 'A string to pass to the port'
|
||||
' handler (in a format specific to the handler) to describe how'
|
||||
' the port should be bound/bindable/discoverable')
|
|
@ -40,6 +40,8 @@ SimObject('AbstractMemory.py')
|
|||
SimObject('AddrMapper.py')
|
||||
SimObject('Bridge.py')
|
||||
SimObject('DRAMCtrl.py')
|
||||
SimObject('ExternalMaster.py')
|
||||
SimObject('ExternalSlave.py')
|
||||
SimObject('MemObject.py')
|
||||
SimObject('SimpleMemory.py')
|
||||
SimObject('XBar.py')
|
||||
|
@ -50,6 +52,8 @@ Source('bridge.cc')
|
|||
Source('coherent_xbar.cc')
|
||||
Source('drampower.cc')
|
||||
Source('dram_ctrl.cc')
|
||||
Source('external_master.cc')
|
||||
Source('external_slave.cc')
|
||||
Source('mem_object.cc')
|
||||
Source('mport.cc')
|
||||
Source('noncoherent_xbar.cc')
|
||||
|
@ -88,6 +92,7 @@ DebugFlag('CommMonitor')
|
|||
DebugFlag('DRAM')
|
||||
DebugFlag('DRAMPower')
|
||||
DebugFlag('DRAMState')
|
||||
DebugFlag('ExternalPort')
|
||||
DebugFlag('LLSC')
|
||||
DebugFlag('MMU')
|
||||
DebugFlag('MemoryAccess')
|
||||
|
|
107
src/mem/external_master.cc
Normal file
107
src/mem/external_master.cc
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2014 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.
|
||||
*
|
||||
* Authors: Andrew Bardsley
|
||||
* Curtis Dunham
|
||||
*/
|
||||
|
||||
#include <cctype>
|
||||
#include <iomanip>
|
||||
|
||||
#include "debug/ExternalPort.hh"
|
||||
#include "mem/external_master.hh"
|
||||
|
||||
std::map<std::string, ExternalMaster::Handler *>
|
||||
ExternalMaster::portHandlers;
|
||||
|
||||
ExternalMaster::ExternalMaster(ExternalMasterParams *params) :
|
||||
MemObject(params),
|
||||
externalPort(NULL),
|
||||
portName(params->name + ".port"),
|
||||
portType(params->port_type),
|
||||
portData(params->port_data)
|
||||
{}
|
||||
|
||||
BaseMasterPort &
|
||||
ExternalMaster::getMasterPort(const std::string &if_name,
|
||||
PortID idx)
|
||||
{
|
||||
if (if_name == "port") {
|
||||
DPRINTF(ExternalPort, "Trying to bind external port: %s %s\n",
|
||||
portType, portName);
|
||||
|
||||
if (!externalPort) {
|
||||
auto handlerIter = portHandlers.find(portType);
|
||||
|
||||
if (handlerIter == portHandlers.end())
|
||||
fatal("Can't find port handler type '%s'\n", portType);
|
||||
|
||||
externalPort = portHandlers[portType]->getExternalPort(portName,
|
||||
*this, portData);
|
||||
|
||||
if (!externalPort) {
|
||||
fatal("%s: Can't find external port type: %s"
|
||||
" port_data: '%s'\n", portName, portType, portData);
|
||||
}
|
||||
}
|
||||
return *externalPort;
|
||||
} else {
|
||||
return MemObject::getMasterPort(if_name, idx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ExternalMaster::init()
|
||||
{
|
||||
if (!externalPort) {
|
||||
fatal("ExternalMaster %s: externalPort not set!\n", name());
|
||||
} else if (!externalPort->isConnected()) {
|
||||
fatal("ExternalMaster %s is unconnected!\n", name());
|
||||
}
|
||||
}
|
||||
|
||||
ExternalMaster *
|
||||
ExternalMasterParams::create()
|
||||
{
|
||||
return new ExternalMaster(this);
|
||||
}
|
||||
|
||||
void
|
||||
ExternalMaster::registerHandler(const std::string &handler_name,
|
||||
Handler *handler)
|
||||
{
|
||||
portHandlers[handler_name] = handler;
|
||||
}
|
135
src/mem/external_master.hh
Normal file
135
src/mem/external_master.hh
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2014 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.
|
||||
*
|
||||
* Authors: Andrew Bardsley
|
||||
* Curtis Dunham
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* ExternalMaster is a memory object representing a binding from
|
||||
* a gem5 slave to a master port in a system external to gem5.
|
||||
*
|
||||
* During initialisation, a `handler' for the port type specified in the
|
||||
* port's port_type parameter is found from the registered port handlers
|
||||
* provided with registerHandler. Once a handler is found, it is passed the
|
||||
* port_data parameter of the port which can be used to identify the external
|
||||
* port which is to be bound to. A port handler will usually construct a
|
||||
* bridge object in the external system to accomodate the port-to-port
|
||||
* mapping but this bridge is not exposed to gem5 other than be the
|
||||
* presentation of the MasterPort which can be bound.
|
||||
*
|
||||
* The external port must provide a gem5 MasterPort interface.
|
||||
*/
|
||||
|
||||
#ifndef __MEM_EXTERNAL_MASTER__
|
||||
#define __MEM_EXTERNAL_MASTER__
|
||||
|
||||
#include "mem/mem_object.hh"
|
||||
#include "params/ExternalMaster.hh"
|
||||
|
||||
class ExternalMaster : public MemObject
|
||||
{
|
||||
public:
|
||||
/** Derive from this class to create an external port interface */
|
||||
class Port : public MasterPort
|
||||
{
|
||||
protected:
|
||||
ExternalMaster &owner;
|
||||
|
||||
public:
|
||||
Port(const std::string &name_,
|
||||
ExternalMaster &owner_) :
|
||||
MasterPort(name_, &owner_), owner(owner_)
|
||||
{ }
|
||||
|
||||
~Port() { }
|
||||
|
||||
/** Any or all of recv... can be overloaded to provide the port's
|
||||
* functionality */
|
||||
};
|
||||
|
||||
/* Handlers are specific to *types* of port not specific port
|
||||
* instantiations. A handler will typically build a bridge to the
|
||||
* external port from gem5 and provide gem5 with a MasterPort that can be
|
||||
* bound to for each call to Handler::getExternalPort.*/
|
||||
class Handler
|
||||
{
|
||||
public:
|
||||
/** Create or find an external port which can be bound. Returns
|
||||
* NULL on failure */
|
||||
virtual Port *getExternalPort(
|
||||
const std::string &name, ExternalMaster &owner,
|
||||
const std::string &port_data) = 0;
|
||||
};
|
||||
|
||||
protected:
|
||||
/** The peer port for the gem5 port "port" */
|
||||
Port *externalPort;
|
||||
|
||||
/** Name of the bound port. This will be name() + ".port" */
|
||||
std::string portName;
|
||||
|
||||
/** Key to select a port handler */
|
||||
std::string portType;
|
||||
|
||||
/** Handler-specific port configuration */
|
||||
std::string portData;
|
||||
|
||||
/** Registered handlers. Handlers are chosen using the port_type
|
||||
* parameter on ExternalMasters. port_types form a global namespace
|
||||
* across the simulation and so handlers are registered into a global
|
||||
* structure */
|
||||
static std::map<std::string, Handler *> portHandlers;
|
||||
|
||||
public:
|
||||
ExternalMaster(ExternalMasterParams *params);
|
||||
|
||||
/** MasterPort interface. Responds only to port "port" */
|
||||
BaseMasterPort &getMasterPort(const std::string &if_name,
|
||||
PortID idx = InvalidPortID);
|
||||
|
||||
/** Register a handler which can provide ports with port_type ==
|
||||
* handler_name */
|
||||
static void registerHandler(const std::string &handler_name,
|
||||
Handler *handler);
|
||||
|
||||
void init();
|
||||
};
|
||||
|
||||
|
||||
#endif // __MEM_EXTERNAL_MASTER__
|
252
src/mem/external_slave.cc
Normal file
252
src/mem/external_slave.cc
Normal file
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2014 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.
|
||||
*
|
||||
* Authors: Andrew Bardsley
|
||||
*/
|
||||
|
||||
#include <cctype>
|
||||
#include <iomanip>
|
||||
|
||||
#include "debug/ExternalPort.hh"
|
||||
#include "mem/external_slave.hh"
|
||||
|
||||
/** Implement a `stub' port which just responds to requests by printing
|
||||
* a message. The stub port can be used to configure and test a system
|
||||
* where the external port is used for a peripheral before connecting
|
||||
* the external port */
|
||||
class StubSlavePort : public ExternalSlave::Port
|
||||
{
|
||||
public:
|
||||
class ResponseEvent : public Event
|
||||
{
|
||||
public:
|
||||
StubSlavePort &owner;
|
||||
|
||||
ResponseEvent(StubSlavePort &owner_) : owner(owner_) { }
|
||||
|
||||
void process();
|
||||
};
|
||||
|
||||
ResponseEvent responseEvent;
|
||||
|
||||
/** Stub can handle a single request at a time. This will be
|
||||
* NULL when no packet is in flight */
|
||||
PacketPtr responsePacket;
|
||||
|
||||
/** Received a new request while processing a first. Need to ask for
|
||||
* a retry after completing this packet */
|
||||
bool mustRetry;
|
||||
|
||||
StubSlavePort(const std::string &name_,
|
||||
ExternalSlave &owner_) :
|
||||
ExternalSlave::Port(name_, owner_),
|
||||
responseEvent(*this), responsePacket(NULL)
|
||||
{ }
|
||||
|
||||
Tick recvAtomic(PacketPtr packet);
|
||||
void recvFunctional(PacketPtr packet);
|
||||
bool recvTimingReq(PacketPtr packet);
|
||||
bool recvTimingSnoopResp(PacketPtr packet);
|
||||
void recvRetry();
|
||||
void recvFunctionalSnoop(PacketPtr packet);
|
||||
};
|
||||
|
||||
class StubSlavePortHandler : public
|
||||
ExternalSlave::Handler
|
||||
{
|
||||
public:
|
||||
ExternalSlave::Port *getExternalPort(
|
||||
const std::string &name_,
|
||||
ExternalSlave &owner,
|
||||
const std::string &port_data)
|
||||
{
|
||||
StringWrap name(name_);
|
||||
|
||||
DPRINTF(ExternalPort, "finding stub port '%s'\n", port_data);
|
||||
return new StubSlavePort(name_, owner);
|
||||
}
|
||||
};
|
||||
|
||||
Tick
|
||||
StubSlavePort::recvAtomic(PacketPtr packet)
|
||||
{
|
||||
if (DTRACE(ExternalPort)) {
|
||||
unsigned int M5_VAR_USED size = packet->getSize();
|
||||
|
||||
DPRINTF(ExternalPort, "StubSlavePort: recvAtomic a: 0x%x size: %d"
|
||||
" data: ...\n", packet->getAddr(), size);
|
||||
DDUMP(ExternalPort, packet->getPtr<uint8_t>(), size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
StubSlavePort::recvFunctional(PacketPtr packet)
|
||||
{
|
||||
recvAtomic(packet);
|
||||
}
|
||||
|
||||
void
|
||||
StubSlavePort::ResponseEvent::process()
|
||||
{
|
||||
owner.responsePacket->makeResponse();
|
||||
owner.responsePacket->firstWordDelay = 0;
|
||||
owner.responsePacket->lastWordDelay = 0;
|
||||
|
||||
if (owner.sendTimingResp(owner.responsePacket)) {
|
||||
owner.responsePacket = NULL;
|
||||
|
||||
if (owner.mustRetry)
|
||||
owner.sendRetry();
|
||||
owner.mustRetry = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
StubSlavePort::recvTimingReq(PacketPtr packet)
|
||||
{
|
||||
if (responsePacket) {
|
||||
mustRetry = true;
|
||||
|
||||
return false;
|
||||
} else {
|
||||
recvAtomic(packet);
|
||||
|
||||
responsePacket = packet;
|
||||
owner.schedule(responseEvent, curTick());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
StubSlavePort::recvTimingSnoopResp(PacketPtr packet)
|
||||
{
|
||||
fatal("StubSlavePort: function: %s\n", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
StubSlavePort::recvRetry()
|
||||
{
|
||||
assert(responsePacket);
|
||||
/* Stub handles only one response at a time so responseEvent should never
|
||||
* be scheduled at this point. Retrys shouldn't need to schedule, we
|
||||
* can safely send the response here */
|
||||
responseEvent.process();
|
||||
}
|
||||
|
||||
void
|
||||
StubSlavePort::recvFunctionalSnoop(PacketPtr packet)
|
||||
{
|
||||
fatal("StubSlavePort: unimplemented function: %s\n", __func__);
|
||||
}
|
||||
|
||||
std::map<std::string, ExternalSlave::Handler *>
|
||||
ExternalSlave::portHandlers;
|
||||
|
||||
AddrRangeList
|
||||
ExternalSlave::Port::getAddrRanges() const
|
||||
{
|
||||
return owner.addrRanges;
|
||||
}
|
||||
|
||||
ExternalSlave::ExternalSlave(ExternalSlaveParams *params) :
|
||||
MemObject(params),
|
||||
externalPort(NULL),
|
||||
portName(params->name + ".port"),
|
||||
portType(params->port_type),
|
||||
portData(params->port_data),
|
||||
addrRanges(params->addr_ranges.begin(), params->addr_ranges.end())
|
||||
{
|
||||
/* Register the stub handler if it hasn't already been registered */
|
||||
if (portHandlers.find("stub") == portHandlers.end())
|
||||
registerHandler("stub", new StubSlavePortHandler);
|
||||
}
|
||||
|
||||
BaseSlavePort &
|
||||
ExternalSlave::getSlavePort(const std::string &if_name,
|
||||
PortID idx)
|
||||
{
|
||||
if (if_name == "port") {
|
||||
DPRINTF(ExternalPort, "Trying to bind external port: %s %s\n",
|
||||
portType, portName);
|
||||
|
||||
if (!externalPort) {
|
||||
auto handlerIter = portHandlers.find(portType);
|
||||
|
||||
if (handlerIter == portHandlers.end())
|
||||
fatal("Can't find port handler type '%s'\n", portType);
|
||||
|
||||
externalPort = portHandlers[portType]->getExternalPort(portName,
|
||||
*this, portData);
|
||||
|
||||
if (!externalPort) {
|
||||
fatal("%s: Can't find external port type: %s"
|
||||
" port_data: '%s'\n", portName, portType, portData);
|
||||
}
|
||||
}
|
||||
return *externalPort;
|
||||
} else {
|
||||
return MemObject::getSlavePort(if_name, idx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ExternalSlave::init()
|
||||
{
|
||||
if (!externalPort) {
|
||||
fatal("ExternalSlave %s: externalPort not set!\n", name());
|
||||
} else if (!externalPort->isConnected()) {
|
||||
fatal("ExternalSlave %s is unconnected!\n", name());
|
||||
} else {
|
||||
externalPort->sendRangeChange();
|
||||
}
|
||||
}
|
||||
|
||||
ExternalSlave *
|
||||
ExternalSlaveParams::create()
|
||||
{
|
||||
return new ExternalSlave(this);
|
||||
}
|
||||
|
||||
void
|
||||
ExternalSlave::registerHandler(const std::string &handler_name,
|
||||
Handler *handler)
|
||||
{
|
||||
portHandlers[handler_name] = handler;
|
||||
}
|
142
src/mem/external_slave.hh
Normal file
142
src/mem/external_slave.hh
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2014 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.
|
||||
*
|
||||
* Authors: Andrew Bardsley
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* ExternalSlave is a memory object representing a binding from
|
||||
* a gem5 master to a slave port in a system external to gem5.
|
||||
*
|
||||
* During initialisation, a `handler' for the port type specified in the
|
||||
* port's port_type parameter is found from the registered port handlers
|
||||
* provided with registerHandler. Once a handler is found, it is passed the
|
||||
* port_data parameter of the port which can be used to identify the external
|
||||
* port which is to be bound to. A port handler will usually construct a
|
||||
* bridge object in the external system to accomodate the port-to-port
|
||||
* mapping but this bridge is not exposed to gem5 other than be the
|
||||
* presentation of the SlavePort which can be bound.
|
||||
*
|
||||
* The external port must provide a gem5 SlavePort interface (with the
|
||||
* exception of getAddrRanges which is provided by the ExternalSlave
|
||||
* object).
|
||||
*/
|
||||
|
||||
#ifndef __MEM_EXTERNAL_SLAVE__
|
||||
#define __MEM_EXTERNAL_SLAVE__
|
||||
|
||||
#include "mem/mem_object.hh"
|
||||
#include "params/ExternalSlave.hh"
|
||||
|
||||
class ExternalSlave : public MemObject
|
||||
{
|
||||
public:
|
||||
/** Derive from this class to create an external port interface */
|
||||
class Port : public SlavePort
|
||||
{
|
||||
protected:
|
||||
ExternalSlave &owner;
|
||||
|
||||
public:
|
||||
Port(const std::string &name_,
|
||||
ExternalSlave &owner_) :
|
||||
SlavePort(name_, &owner_), owner(owner_)
|
||||
{ }
|
||||
|
||||
~Port() { }
|
||||
|
||||
/** Any or all of recv... can be overloaded to provide the port's
|
||||
* functionality */
|
||||
|
||||
AddrRangeList getAddrRanges() const;
|
||||
};
|
||||
|
||||
/* Handlers are specific to *types* of port not specific port
|
||||
* instantiations. A handler will typically build a bridge to the
|
||||
* external port from gem5 and provide gem5 with a SlavePort that can be
|
||||
* bound to for each call to Handler::getExternalPort.*/
|
||||
class Handler
|
||||
{
|
||||
public:
|
||||
/** Create or find an external port which can be bound. Returns
|
||||
* NULL on failure */
|
||||
virtual Port *getExternalPort(
|
||||
const std::string &name, ExternalSlave &owner,
|
||||
const std::string &port_data) = 0;
|
||||
};
|
||||
|
||||
protected:
|
||||
/** The peer port for the gem5 port "port" */
|
||||
Port *externalPort;
|
||||
|
||||
/** Name of the bound port. This will be name() + ".port" */
|
||||
std::string portName;
|
||||
|
||||
/** Key to select a port handler */
|
||||
std::string portType;
|
||||
|
||||
/** Handler-specific port configuration */
|
||||
std::string portData;
|
||||
|
||||
/** The Range of addresses supported by the devices on the external
|
||||
* side of this port */
|
||||
AddrRangeList addrRanges;
|
||||
|
||||
/** Registered handlers. Handlers are chosen using the port_type
|
||||
* parameter on ExternalSlaves. port_types form a global namespace
|
||||
* across the simulation and so handlers are registered into a global
|
||||
* structure */
|
||||
static std::map<std::string, Handler *> portHandlers;
|
||||
|
||||
public:
|
||||
ExternalSlave(ExternalSlaveParams *params);
|
||||
|
||||
/** SlavePort interface. Responds only to port "port" */
|
||||
BaseSlavePort &getSlavePort(const std::string &if_name,
|
||||
PortID idx = InvalidPortID);
|
||||
|
||||
/** Register a handler which can provide ports with port_type ==
|
||||
* handler_name */
|
||||
static void registerHandler(const std::string &handler_name,
|
||||
Handler *handler);
|
||||
|
||||
void init();
|
||||
};
|
||||
|
||||
|
||||
#endif // __MEM_EXTERNAL_SLAVE__
|
Loading…
Reference in a new issue