gem5  v20.1.0.0
external_slave.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2014 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #include "mem/external_slave.hh"
39 
40 #include <cctype>
41 #include <iomanip>
42 
43 #include "base/trace.hh"
44 #include "debug/ExternalPort.hh"
45 
51 {
52  public:
53  void processResponseEvent();
54 
56 
60 
63  bool mustRetry;
64 
65  StubSlavePort(const std::string &name_,
66  ExternalSlave &owner_) :
67  ExternalSlave::ExternalPort(name_, owner_),
68  responseEvent([this]{ processResponseEvent(); }, name()),
69  responsePacket(NULL), mustRetry(false)
70  { }
71 
72  Tick recvAtomic(PacketPtr packet);
73  void recvFunctional(PacketPtr packet);
74  bool recvTimingReq(PacketPtr packet);
75  bool recvTimingSnoopResp(PacketPtr packet);
76  void recvRespRetry();
77  void recvFunctionalSnoop(PacketPtr packet);
78 };
79 
80 class StubSlavePortHandler : public
82 {
83  public:
85  const std::string &name_,
86  ExternalSlave &owner,
87  const std::string &port_data)
88  {
89  StringWrap name(name_);
90 
91  DPRINTF(ExternalPort, "finding stub port '%s'\n", port_data);
92  return new StubSlavePort(name_, owner);
93  }
94 };
95 
96 Tick
98 {
99  if (DTRACE(ExternalPort)) {
100  unsigned int M5_VAR_USED size = packet->getSize();
101 
102  DPRINTF(ExternalPort, "StubSlavePort: recvAtomic a: 0x%x size: %d"
103  " data: ...\n", packet->getAddr(), size);
104  DDUMP(ExternalPort, packet->getConstPtr<uint8_t>(), size);
105  }
106 
107  return 0;
108 }
109 
110 void
112 {
113  recvAtomic(packet);
114 }
115 
116 void
118 {
122 
124  responsePacket = NULL;
125 
126  if (mustRetry)
127  sendRetryReq();
128  mustRetry = false;
129  }
130 }
131 
132 bool
134 {
135  if (responsePacket) {
136  mustRetry = true;
137 
138  return false;
139  } else {
140  recvAtomic(packet);
141 
142  responsePacket = packet;
144 
145  return true;
146  }
147 }
148 
149 bool
151 {
152  fatal("StubSlavePort: function: %s\n", __func__);
153  return false;
154 }
155 
156 void
158 {
159  assert(responsePacket);
160  /* Stub handles only one response at a time so responseEvent should never
161  * be scheduled at this point. Retrys shouldn't need to schedule, we
162  * can safely send the response here */
164 }
165 
166 void
168 {
169  fatal("StubSlavePort: unimplemented function: %s\n", __func__);
170 }
171 
172 std::map<std::string, ExternalSlave::Handler *>
174 
177 {
178  return owner.addrRanges;
179 }
180 
181 ExternalSlave::ExternalSlave(ExternalSlaveParams *params) :
182  SimObject(params),
183  externalPort(NULL),
184  portName(params->name + ".port"),
185  portType(params->port_type),
186  portData(params->port_data),
187  addrRanges(params->addr_ranges.begin(), params->addr_ranges.end())
188 {
189  /* Register the stub handler if it hasn't already been registered */
190  if (portHandlers.find("stub") == portHandlers.end())
192 }
193 
194 Port &
195 ExternalSlave::getPort(const std::string &if_name, PortID idx)
196 {
197  if (if_name == "port") {
198  DPRINTF(ExternalPort, "Trying to bind external port: %s %s\n",
199  portType, portName);
200 
201  if (!externalPort) {
202  auto handlerIter = portHandlers.find(portType);
203 
204  if (handlerIter == portHandlers.end())
205  fatal("Can't find port handler type '%s'\n", portType);
206 
207  externalPort = portHandlers[portType]->getExternalPort(portName,
208  *this, portData);
209 
210  if (!externalPort) {
211  fatal("%s: Can't find external port type: %s"
212  " port_data: '%s'\n", portName, portType, portData);
213  }
214  }
215  return *externalPort;
216  } else {
217  return SimObject::getPort(if_name, idx);
218  }
219 }
220 
221 void
223 {
224  if (!externalPort) {
225  fatal("ExternalSlave %s: externalPort not set!\n", name());
226  } else if (!externalPort->isConnected()) {
227  fatal("ExternalSlave %s is unconnected!\n", name());
228  } else {
230  }
231 }
232 
234 ExternalSlaveParams::create()
235 {
236  return new ExternalSlave(this);
237 }
238 
239 void
240 ExternalSlave::registerHandler(const std::string &handler_name,
241  Handler *handler)
242 {
243  portHandlers[handler_name] = handler;
244 }
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
StubSlavePort::mustRetry
bool mustRetry
Received a new request while processing a first.
Definition: external_slave.cc:63
ExternalSlave::ExternalPort::ExternalPort
ExternalPort(const std::string &name_, ExternalSlave &owner_)
Definition: external_slave.hh:75
StubSlavePort::responseEvent
EventFunctionWrapper responseEvent
Definition: external_slave.cc:55
Packet::getAddr
Addr getAddr() const
Definition: packet.hh:754
ResponsePort::sendTimingResp
bool sendTimingResp(PacketPtr pkt)
Attempt to send a timing response to the request port by calling its corresponding receive function.
Definition: port.hh:367
ExternalSlave::ExternalPort::owner
ExternalSlave & owner
Definition: external_slave.hh:72
Packet::payloadDelay
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Definition: packet.hh:412
external_slave.hh
ExternalSlave::portName
std::string portName
Name of the bound port.
Definition: external_slave.hh:107
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
StubSlavePortHandler::getExternalPort
ExternalSlave::ExternalPort * getExternalPort(const std::string &name_, ExternalSlave &owner, const std::string &port_data)
Create or find an external port which can be bound.
Definition: external_slave.cc:84
PortID
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:237
StubSlavePort::recvTimingSnoopResp
bool recvTimingSnoopResp(PacketPtr packet)
Receive a timing snoop response from the peer.
Definition: external_slave.cc:150
DTRACE
#define DTRACE(x)
Definition: debug.hh:146
Packet::getSize
unsigned getSize() const
Definition: packet.hh:764
StubSlavePort::recvRespRetry
void recvRespRetry()
Called by the peer if sendTimingResp was called on this protocol (causing recvTimingResp to be called...
Definition: external_slave.cc:157
StubSlavePort
Implement a ‘stub’ port which just responds to requests by printing a message.
Definition: external_slave.cc:50
ExternalSlave::registerHandler
static void registerHandler(const std::string &handler_name, Handler *handler)
Register a handler which can provide ports with port_type == handler_name.
Definition: external_slave.cc:240
Packet::headerDelay
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition: packet.hh:394
ExternalSlave::externalPort
ExternalPort * externalPort
The peer port for the gem5 port "port".
Definition: external_slave.hh:104
EventFunctionWrapper
Definition: eventq.hh:1101
ExternalSlave::getPort
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Port interface.
Definition: external_slave.cc:195
ExternalSlave::ExternalPort
Derive from this class to create an external port interface.
Definition: external_slave.hh:69
EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1005
ExternalSlave
Definition: external_slave.hh:65
SimObject::getPort
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Definition: sim_object.cc:123
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
StubSlavePort::StubSlavePort
StubSlavePort(const std::string &name_, ExternalSlave &owner_)
Definition: external_slave.cc:65
Port
Ports are used to interface objects to each other.
Definition: port.hh:56
StubSlavePort::recvFunctionalSnoop
void recvFunctionalSnoop(PacketPtr packet)
Definition: external_slave.cc:167
ExternalSlave::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: external_slave.cc:222
ExternalSlave::Handler
Definition: external_slave.hh:92
Port::name
const std::string name() const
Return port name (for DPRINTF).
Definition: port.hh:106
Packet::makeResponse
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
Definition: packet.hh:1004
SimObject::params
const Params * params() const
Definition: sim_object.hh:119
name
const std::string & name()
Definition: trace.cc:50
StubSlavePort::responsePacket
PacketPtr responsePacket
Stub can handle a single request at a time.
Definition: external_slave.cc:59
StubSlavePort::recvTimingReq
bool recvTimingReq(PacketPtr packet)
Receive a timing request from the peer.
Definition: external_slave.cc:133
DDUMP
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
Definition: trace.hh:233
EventFunctionWrapper::process
void process()
Definition: eventq.hh:1127
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:133
ExternalSlave::portHandlers
static std::map< std::string, Handler * > portHandlers
Registered handlers.
Definition: external_slave.hh:123
ExternalSlave::portData
std::string portData
Handler-specific port configuration.
Definition: external_slave.hh:113
ExternalSlave::addrRanges
AddrRangeList addrRanges
The Range of addresses supported by the devices on the external side of this port.
Definition: external_slave.hh:117
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
Port::isConnected
bool isConnected() const
Is this port currently connected to a peer?
Definition: port.hh:128
StringWrap
Definition: trace.hh:134
StubSlavePort::recvFunctional
void recvFunctional(PacketPtr packet)
Receive a functional request packet from the peer.
Definition: external_slave.cc:111
trace.hh
ResponsePort::sendRetryReq
void sendRetryReq()
Send a retry to the request port that previously attempted a sendTimingReq to this response port and ...
Definition: port.hh:398
std::list< AddrRange >
StubSlavePort::processResponseEvent
void processResponseEvent()
Definition: external_slave.cc:117
ResponsePort::sendRangeChange
void sendRangeChange() const
Called by the owner to send a range change.
Definition: port.hh:293
ExternalSlave::ExternalPort::getAddrRanges
AddrRangeList getAddrRanges() const
Any or all of recv...
Definition: external_slave.cc:176
Packet::getConstPtr
const T * getConstPtr() const
Definition: packet.hh:1166
ExternalSlave::portType
std::string portType
Key to select a port handler.
Definition: external_slave.hh:110
ExternalSlave::ExternalSlave
ExternalSlave(ExternalSlaveParams *params)
Definition: external_slave.cc:181
StubSlavePortHandler
Definition: external_slave.cc:80
StubSlavePort::recvAtomic
Tick recvAtomic(PacketPtr packet)
Receive an atomic request packet from the peer.
Definition: external_slave.cc:97
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:92

Generated on Wed Sep 30 2020 14:02:13 for gem5 by doxygen 1.8.17