gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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  * Authors: Andrew Bardsley
38  */
39 
40 #include "mem/external_slave.hh"
41 
42 #include <cctype>
43 #include <iomanip>
44 
45 #include "base/trace.hh"
46 #include "debug/ExternalPort.hh"
47 
53 {
54  public:
55  class ResponseEvent : public Event
56  {
57  public:
59 
60  ResponseEvent(StubSlavePort &owner_) : owner(owner_) { }
61 
62  void process();
63  };
64 
66 
70 
73  bool mustRetry;
74 
75  StubSlavePort(const std::string &name_,
76  ExternalSlave &owner_) :
77  ExternalSlave::Port(name_, owner_),
78  responseEvent(*this), responsePacket(NULL), mustRetry(false)
79  { }
80 
81  Tick recvAtomic(PacketPtr packet);
82  void recvFunctional(PacketPtr packet);
83  bool recvTimingReq(PacketPtr packet);
84  bool recvTimingSnoopResp(PacketPtr packet);
85  void recvRespRetry();
86  void recvFunctionalSnoop(PacketPtr packet);
87 };
88 
89 class StubSlavePortHandler : public
91 {
92  public:
94  const std::string &name_,
95  ExternalSlave &owner,
96  const std::string &port_data)
97  {
98  StringWrap name(name_);
99 
100  DPRINTF(ExternalPort, "finding stub port '%s'\n", port_data);
101  return new StubSlavePort(name_, owner);
102  }
103 };
104 
105 Tick
107 {
108  if (DTRACE(ExternalPort)) {
109  unsigned int M5_VAR_USED size = packet->getSize();
110 
111  DPRINTF(ExternalPort, "StubSlavePort: recvAtomic a: 0x%x size: %d"
112  " data: ...\n", packet->getAddr(), size);
113  DDUMP(ExternalPort, packet->getConstPtr<uint8_t>(), size);
114  }
115 
116  return 0;
117 }
118 
119 void
121 {
122  recvAtomic(packet);
123 }
124 
125 void
127 {
131 
133  owner.responsePacket = NULL;
134 
135  if (owner.mustRetry)
137  owner.mustRetry = false;
138  }
139 }
140 
141 bool
143 {
144  if (responsePacket) {
145  mustRetry = true;
146 
147  return false;
148  } else {
149  recvAtomic(packet);
150 
151  responsePacket = packet;
153 
154  return true;
155  }
156 }
157 
158 bool
160 {
161  fatal("StubSlavePort: function: %s\n", __func__);
162  return false;
163 }
164 
165 void
167 {
168  assert(responsePacket);
169  /* Stub handles only one response at a time so responseEvent should never
170  * be scheduled at this point. Retrys shouldn't need to schedule, we
171  * can safely send the response here */
173 }
174 
175 void
177 {
178  fatal("StubSlavePort: unimplemented function: %s\n", __func__);
179 }
180 
181 std::map<std::string, ExternalSlave::Handler *>
183 
186 {
187  return owner.addrRanges;
188 }
189 
190 ExternalSlave::ExternalSlave(ExternalSlaveParams *params) :
191  MemObject(params),
192  externalPort(NULL),
193  portName(params->name + ".port"),
194  portType(params->port_type),
195  portData(params->port_data),
196  addrRanges(params->addr_ranges.begin(), params->addr_ranges.end())
197 {
198  /* Register the stub handler if it hasn't already been registered */
199  if (portHandlers.find("stub") == portHandlers.end())
201 }
202 
204 ExternalSlave::getSlavePort(const std::string &if_name,
205  PortID idx)
206 {
207  if (if_name == "port") {
208  DPRINTF(ExternalPort, "Trying to bind external port: %s %s\n",
209  portType, portName);
210 
211  if (!externalPort) {
212  auto handlerIter = portHandlers.find(portType);
213 
214  if (handlerIter == portHandlers.end())
215  fatal("Can't find port handler type '%s'\n", portType);
216 
217  externalPort = portHandlers[portType]->getExternalPort(portName,
218  *this, portData);
219 
220  if (!externalPort) {
221  fatal("%s: Can't find external port type: %s"
222  " port_data: '%s'\n", portName, portType, portData);
223  }
224  }
225  return *externalPort;
226  } else {
227  return MemObject::getSlavePort(if_name, idx);
228  }
229 }
230 
231 void
233 {
234  if (!externalPort) {
235  fatal("ExternalSlave %s: externalPort not set!\n", name());
236  } else if (!externalPort->isConnected()) {
237  fatal("ExternalSlave %s is unconnected!\n", name());
238  } else {
240  }
241 }
242 
244 ExternalSlaveParams::create()
245 {
246  return new ExternalSlave(this);
247 }
248 
249 void
250 ExternalSlave::registerHandler(const std::string &handler_name,
251  Handler *handler)
252 {
253  portHandlers[handler_name] = handler;
254 }
#define DPRINTF(x,...)
Definition: trace.hh:212
ExternalSlave::Port * getExternalPort(const std::string &name_, ExternalSlave &owner, const std::string &port_data)
Create or find an external port which can be bound.
Ports are used to interface memory objects to each other.
Definition: port.hh:63
const std::string & name()
Definition: trace.cc:49
static void registerHandler(const std::string &handler_name, Handler *handler)
Register a handler which can provide ports with port_type == handler_name.
ResponseEvent responseEvent
const std::string name() const
Return port name (for DPRINTF).
Definition: port.hh:99
AddrRangeList addrRanges
The Range of addresses supported by the devices on the external side of this port.
PacketPtr responsePacket
Stub can handle a single request at a time.
bool recvTimingReq(PacketPtr packet)
Receive a timing request from the master port.
std::string portData
Handler-specific port configuration.
#define DDUMP(x, data, count)
Definition: trace.hh:211
AddrRangeList getAddrRanges() const
Any or all of recv...
std::string portName
Name of the bound port.
virtual BaseSlavePort & getSlavePort(const std::string &if_name, PortID idx=InvalidPortID)
Get a slave port with a given name and index.
Definition: mem_object.cc:58
Tick recvAtomic(PacketPtr packet)
Receive an atomic request packet from the master port.
A BaseSlavePort is a protocol-agnostic slave port, responsible only for the structural connection to ...
Definition: port.hh:139
void recvFunctional(PacketPtr packet)
Receive a functional request packet from the master port.
StubSlavePort(const std::string &name_, ExternalSlave &owner_)
Port * externalPort
The peer port for the gem5 port "port".
bool sendTimingResp(PacketPtr pkt)
Attempt to send a timing response to the master port by calling its corresponding receive function...
Definition: port.cc:251
Tick curTick()
The current simulated tick.
Definition: core.hh:47
#define DTRACE(x)
Definition: trace.hh:210
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition: packet.hh:340
uint64_t Tick
Tick count type.
Definition: types.hh:63
#define fatal(...)
Definition: misc.hh:163
bool recvTimingSnoopResp(PacketPtr packet)
Receive a timing snoop response from the master port.
std::string portType
Key to select a port handler.
ResponseEvent(StubSlavePort &owner_)
BaseSlavePort & getSlavePort(const std::string &if_name, PortID idx=InvalidPortID)
SlavePort interface.
ExternalSlave is a memory object representing a binding from a gem5 master to a slave port in a syste...
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Definition: packet.hh:358
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
void sendRangeChange() const
Called by the owner to send a range change.
Definition: port.hh:410
void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
std::string portName
Descriptive name (for DPRINTF output)
Definition: port.hh:69
static const int NumArgumentRegs M5_VAR_USED
Definition: process.cc:83
static std::map< std::string, Handler * > portHandlers
Registered handlers.
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:845
int size()
Definition: pagetable.hh:146
virtual const std::string name() const
Definition: sim_object.hh:117
void sendRetryReq()
Send a retry to the master port that previously attempted a sendTimingReq to this slave port and fail...
Definition: port.cc:265
Definition: eventq.hh:185
ExternalSlave(ExternalSlaveParams *params)
The MemObject class extends the ClockedObject with accessor functions to get its master and slave por...
Definition: mem_object.hh:60
bool isConnected() const
Definition: port.cc:110
void recvFunctionalSnoop(PacketPtr packet)
Derive from this class to create an external port interface.
void schedule(Event &event, Tick when)
Definition: eventq.hh:728
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:181
const T * getConstPtr() const
Definition: packet.hh:967
unsigned getSize() const
Definition: packet.hh:649
ExternalSlave & owner
bool mustRetry
Received a new request while processing a first.
void recvRespRetry()
Called by the master port if sendTimingResp was called on this slave port (causing recvTimingResp to ...
Implement a `stub' port which just responds to requests by printing a message.
Addr getAddr() const
Definition: packet.hh:639

Generated on Fri Jun 9 2017 13:03:49 for gem5 by doxygen 1.8.6