gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
tlm_to_gem5.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2019 Google, Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met: redistributions of source code must retain the above copyright
7  * notice, this list of conditions and the following disclaimer;
8  * redistributions in binary form must reproduce the above copyright
9  * notice, this list of conditions and the following disclaimer in the
10  * documentation and/or other materials provided with the distribution;
11  * neither the name of the copyright holders nor the names of its
12  * contributors may be used to endorse or promote products derived from
13  * this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  * Copyright (c) 2016, Dresden University of Technology (TU Dresden)
28  * All rights reserved.
29  *
30  * Redistribution and use in source and binary forms, with or without
31  * modification, are permitted provided that the following conditions are
32  * met:
33  *
34  * 1. Redistributions of source code must retain the above copyright notice,
35  * this list of conditions and the following disclaimer.
36  *
37  * 2. Redistributions in binary form must reproduce the above copyright
38  * notice, this list of conditions and the following disclaimer in the
39  * documentation and/or other materials provided with the distribution.
40  *
41  * 3. Neither the name of the copyright holder nor the names of its
42  * contributors may be used to endorse or promote products derived from
43  * this software without specific prior written permission.
44  *
45  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
46  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
47  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
49  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
50  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
51  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
52  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
53  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
54  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
55  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56  *
57  * Authors: Gabe Black
58  * Christian Menard
59  */
60 
62 
63 #include "params/TlmToGem5Bridge32.hh"
64 #include "params/TlmToGem5Bridge64.hh"
65 #include "sim/system.hh"
68 
69 namespace sc_gem5
70 {
71 
74 {
75  MemCmd cmd;
76 
77  switch (trans.get_command()) {
79  cmd = MemCmd::ReadReq;
80  break;
82  cmd = MemCmd::WriteReq;
83  break;
85  return nullptr;
86  default:
87  SC_REPORT_FATAL("TlmToGem5Bridge",
88  "received transaction with unsupported command");
89  }
90 
91  Request::Flags flags;
92  auto req = std::make_shared<Request>(
93  trans.get_address(), trans.get_data_length(), flags, masterId);
94 
95  /*
96  * Allocate a new Packet. The packet will be deleted when it returns from
97  * the gem5 world as a response.
98  */
99  auto pkt = new Packet(req, cmd);
100  pkt->dataStatic(trans.get_data_ptr());
101 
102  return pkt;
103 }
104 
105 template <unsigned int BITWIDTH>
106 void
108 {
110  auto delay = sc_core::SC_ZERO_TIME;
111 
112  auto status = socket->nb_transport_bw(trans, phase, delay);
114  "Unexpected status after sending END_REQ");
115 }
116 
117 template <unsigned int BITWIDTH>
118 void
120  sc_core::sc_time &delay)
121 {
123 
125 
126  auto status = socket->nb_transport_bw(trans, phase, delay);
127 
128  if (status == tlm::TLM_COMPLETED ||
129  (status == tlm::TLM_UPDATED && phase == tlm::END_RESP)) {
130  // transaction completed -> no need to wait for tlm::END_RESP
131  responseInProgress = false;
132  } else if (status == tlm::TLM_ACCEPTED) {
133  // we need to wait for tlm::END_RESP
134  responseInProgress = true;
135  } else {
136  panic("Unexpected status after sending BEGIN_RESP");
137  }
138 }
139 
140 template <unsigned int BITWIDTH>
141 void
143 {
144  sc_assert(!waitForRetry);
145  sc_assert(pendingRequest == nullptr);
146  sc_assert(pendingPacket == nullptr);
147 
148  trans.acquire();
149 
150  PacketPtr pkt = nullptr;
151 
152  Gem5SystemC::Gem5Extension *extension = nullptr;
153  trans.get_extension(extension);
154 
155  // If there is an extension, this transaction was initiated by the gem5
156  // world and we can pipe through the original packet. Otherwise, we
157  // generate a new packet based on the transaction.
158  if (extension != nullptr) {
159  extension->setPipeThrough();
160  pkt = extension->getPacket();
161  } else {
162  pkt = payload2packet(masterId, trans);
163  }
164 
165  auto tlmSenderState = new TlmSenderState(trans);
166  pkt->pushSenderState(tlmSenderState);
167 
168  if (bmp.sendTimingReq(pkt)) { // port is free -> send END_REQ immediately
169  sendEndReq(trans);
170  trans.release();
171  } else { // port is blocked -> wait for retry before sending END_REQ
172  waitForRetry = true;
173  pendingRequest = &trans;
174  pendingPacket = pkt;
175  }
176 }
177 
178 template <unsigned int BITWIDTH>
179 void
181 {
182  sc_assert(responseInProgress);
183 
184  responseInProgress = false;
185 
186  checkTransaction(trans);
187 
188  if (needToSendRetry) {
189  bmp.sendRetryResp();
190  needToSendRetry = false;
191  }
192 }
193 
194 template <unsigned int BITWIDTH>
195 void
197 {
198  delete pkt;
199 }
200 
201 template <unsigned int BITWIDTH>
202 void
204 {
205  if (trans.is_response_error()) {
206  std::stringstream ss;
207  ss << "Transaction returned with error, response status = "
208  << trans.get_response_string();
209  SC_REPORT_ERROR("TLM-2", ss.str().c_str());
210  }
211 }
212 
213 template <unsigned int BITWIDTH>
214 void
215 TlmToGem5Bridge<BITWIDTH>::invalidateDmi(const ::MemBackdoor &backdoor)
216 {
217  socket->invalidate_direct_mem_ptr(
218  backdoor.range().start(), backdoor.range().end());
219 }
220 
221 template <unsigned int BITWIDTH>
222 void
224  const tlm::tlm_phase &phase)
225 {
226  switch (phase) {
227  case tlm::BEGIN_REQ:
228  handleBeginReq(trans);
229  break;
230  case tlm::END_RESP:
231  handleEndResp(trans);
232  break;
233  default:
234  panic("unimplemented phase in callback");
235  }
236 }
237 
238 template <unsigned int BITWIDTH>
242  sc_core::sc_time &delay)
243 {
244  unsigned len = trans.get_data_length();
245  unsigned char *byteEnable = trans.get_byte_enable_ptr();
246  unsigned width = trans.get_streaming_width();
247 
248  // check the transaction attributes for unsupported features ...
249  if (byteEnable != 0) {
251  return tlm::TLM_COMPLETED;
252  }
253  if (width < len) { // is this a burst request?
255  return tlm::TLM_COMPLETED;
256  }
257 
258  // ... and queue the valid transaction
259  trans.acquire();
260  peq.notify(trans, phase, delay);
261  return tlm::TLM_ACCEPTED;
262 }
263 
264 template <unsigned int BITWIDTH>
265 void
268 {
269  Gem5SystemC::Gem5Extension *extension = nullptr;
270  trans.get_extension(extension);
271 
272  PacketPtr pkt = nullptr;
273 
274  // If there is an extension, this transaction was initiated by the gem5
275  // world and we can pipe through the original packet.
276  if (extension != nullptr) {
277  extension->setPipeThrough();
278  pkt = extension->getPacket();
279  } else {
280  pkt = payload2packet(masterId, trans);
281  }
282 
283  MemBackdoorPtr backdoor = nullptr;
284  Tick ticks = bmp.sendAtomicBackdoor(pkt, backdoor);
285  if (backdoor)
286  trans.set_dmi_allowed(true);
287 
288  // send an atomic request to gem5
289  panic_if(pkt->needsResponse() && !pkt->isResponse(),
290  "Packet sending failed!\n");
291 
292  auto delay =
294 
295  // update time
296  t += delay;
297 
298  if (extension == nullptr)
299  destroyPacket(pkt);
300 
302 }
303 
304 template <unsigned int BITWIDTH>
305 unsigned int
307 {
308  Gem5SystemC::Gem5Extension *extension = nullptr;
309  trans.get_extension(extension);
310 
311  // If there is an extension, this transaction was initiated by the gem5
312  // world and we can pipe through the original packet.
313  if (extension != nullptr) {
314  extension->setPipeThrough();
315  bmp.sendFunctional(extension->getPacket());
316  } else {
317  auto pkt = payload2packet(masterId, trans);
318  if (pkt) {
319  bmp.sendFunctional(pkt);
320  destroyPacket(pkt);
321  }
322  }
323 
324  return trans.get_data_length();
325 }
326 
327 template <unsigned int BITWIDTH>
328 bool
330  tlm::tlm_dmi &dmi_data)
331 {
332  Gem5SystemC::Gem5Extension *extension = nullptr;
333  trans.get_extension(extension);
334 
335  PacketPtr pkt = nullptr;
336 
337  // If there is an extension, this transaction was initiated by the gem5
338  // world and we can pipe through the original packet.
339  if (extension != nullptr) {
340  extension->setPipeThrough();
341  pkt = extension->getPacket();
342  } else {
343  pkt = payload2packet(masterId, trans);
344  pkt->req->setFlags(Request::NO_ACCESS);
345  }
346 
347  MemBackdoorPtr backdoor = nullptr;
348  bmp.sendAtomicBackdoor(pkt, backdoor);
349  if (backdoor) {
350  trans.set_dmi_allowed(true);
351  dmi_data.set_dmi_ptr(backdoor->ptr());
352  dmi_data.set_start_address(backdoor->range().start());
353  dmi_data.set_end_address(backdoor->range().end());
354 
355  typedef tlm::tlm_dmi::dmi_access_e access_t;
356  access_t access = tlm::tlm_dmi::DMI_ACCESS_NONE;
357  if (backdoor->readable())
358  access = (access_t)(access | tlm::tlm_dmi::DMI_ACCESS_READ);
359  if (backdoor->writeable())
360  access = (access_t)(access | tlm::tlm_dmi::DMI_ACCESS_WRITE);
361  dmi_data.set_granted_access(access);
362 
363  backdoor->addInvalidationCallback(
364  [this](const MemBackdoor &backdoor)
365  {
366  invalidateDmi(backdoor);
367  }
368  );
369  }
370 
371  if (extension == nullptr)
372  destroyPacket(pkt);
373 
375 
376  return backdoor != nullptr;
377 }
378 
379 template <unsigned int BITWIDTH>
380 bool
382 {
383  // exclusion rule
384  // We need to Wait for END_RESP before sending next BEGIN_RESP
385  if (responseInProgress) {
386  sc_assert(!needToSendRetry);
387  needToSendRetry = true;
388  return false;
389  }
390 
391  sc_assert(pkt->isResponse());
392 
393  /*
394  * Pay for annotated transport delays.
395  *
396  * See recvTimingReq in sc_slave_port.cc for a detailed description.
397  */
398  auto delay = sc_core::sc_time::from_value(pkt->payloadDelay);
399  // reset the delays
400  pkt->payloadDelay = 0;
401  pkt->headerDelay = 0;
402 
403  auto tlmSenderState = dynamic_cast<TlmSenderState*>(pkt->popSenderState());
404  sc_assert(tlmSenderState != nullptr);
405 
406  auto &trans = tlmSenderState->trans;
407 
408  Gem5SystemC::Gem5Extension *extension = nullptr;
409  trans.get_extension(extension);
410 
411  // clean up
412  delete tlmSenderState;
413 
414  // If there is an extension the packet was piped through and we must not
415  // delete it. The packet travels back with the transaction.
416  if (extension == nullptr)
417  destroyPacket(pkt);
418  else
419  sc_assert(extension->isPipeThrough());
420 
421  sendBeginResp(trans, delay);
422  trans.release();
423 
424  return true;
425 }
426 
427 template <unsigned int BITWIDTH>
428 void
430 {
431  sc_assert(waitForRetry);
432  sc_assert(pendingRequest != nullptr);
433  sc_assert(pendingPacket != nullptr);
434 
435  if (bmp.sendTimingReq(pendingPacket)) {
436  waitForRetry = false;
437  pendingPacket = nullptr;
438 
439  auto &trans = *pendingRequest;
440  sendEndReq(trans);
441  trans.release();
442 
443  pendingRequest = nullptr;
444  }
445 }
446 
447 template <unsigned int BITWIDTH>
448 void
450 {
451  SC_REPORT_WARNING("TlmToGem5Bridge",
452  "received address range change but ignored it");
453 }
454 
455 template <unsigned int BITWIDTH>
456 ::Port &
457 TlmToGem5Bridge<BITWIDTH>::gem5_getPort(const std::string &if_name, int idx)
458 {
459  if (if_name == "gem5")
460  return bmp;
461  else if (if_name == "tlm")
462  return wrapper;
463 
464  return sc_core::sc_module::gem5_getPort(if_name, idx);
465 }
466 
467 template <unsigned int BITWIDTH>
469  Params *params, const sc_core::sc_module_name &mn) :
470  TlmToGem5BridgeBase(mn), peq(this, &TlmToGem5Bridge<BITWIDTH>::peq_cb),
471  waitForRetry(false), pendingRequest(nullptr), pendingPacket(nullptr),
472  needToSendRetry(false), responseInProgress(false),
473  bmp(std::string(name()) + "master", *this), socket("tlm_socket"),
474  wrapper(socket, std::string(name()) + ".tlm", InvalidPortID),
475  system(params->system),
476  masterId(params->system->getGlobalMasterId(
477  std::string("[systemc].") + name()))
478 {
479 }
480 
481 template <unsigned int BITWIDTH>
482 void
484 {
485  /*
486  * Register the TLM non-blocking interface when using gem5 Timing mode and
487  * the TLM blocking interface when using the gem5 Atomic mode.
488  * Then the magic (TM) in simple_target_socket automatically transforms
489  * non-blocking in blocking transactions and vice versa.
490  *
491  * NOTE: The mode may change during execution.
492  */
493  if (system->isTimingMode()) {
494  SC_REPORT_INFO("TlmToGem5Bridge", "register non-blocking interface");
495  socket.register_nb_transport_fw(
497  } else if (system->isAtomicMode()) {
498  SC_REPORT_INFO("TlmToGem5Bridge", "register blocking interface");
499  socket.register_b_transport(
501  socket.register_get_direct_mem_ptr(
503  } else {
504  panic("gem5 operates neither in Timing nor in Atomic mode");
505  }
506 
507  socket.register_transport_dbg(
509 
511 }
512 
513 } // namespace sc_gem5
514 
516 TlmToGem5Bridge32Params::create()
517 {
518  return new sc_gem5::TlmToGem5Bridge<32>(
519  this, sc_core::sc_module_name(name.c_str()));
520 }
521 
523 TlmToGem5Bridge64Params::create()
524 {
525  return new sc_gem5::TlmToGem5Bridge<64>(
526  this, sc_core::sc_module_name(name.c_str()));
527 }
void sendEndReq(tlm::tlm_generic_payload &trans)
Definition: tlm_to_gem5.cc:107
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
void set_response_status(const tlm_response_status response_status)
Definition: gp.hh:204
void get_extension(T *&ext) const
Definition: gp.hh:364
unsigned int transport_dbg(tlm::tlm_generic_payload &trans)
Definition: tlm_to_gem5.cc:306
Definition: packet.hh:76
const std::string & name()
Definition: trace.cc:54
bool recvTimingResp(PacketPtr pkt)
Definition: tlm_to_gem5.cc:381
bool writeable() const
Definition: backdoor.hh:99
const PortID InvalidPortID
Definition: types.hh:238
dmi_access_e
Definition: dmi.hh:37
Tick ps
picosecond
Definition: core.cc:69
void set_dmi_ptr(unsigned char *p)
Definition: dmi.hh:81
bool get_direct_mem_ptr(tlm::tlm_generic_payload &trans, tlm::tlm_dmi &dmi_data)
Definition: tlm_to_gem5.cc:329
void set_start_address(sc_dt::uint64 addr)
Definition: dmi.hh:82
const char * name() const
Definition: sc_object.cc:46
void sendBeginResp(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay)
Definition: tlm_to_gem5.cc:119
void b_transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &t)
Definition: tlm_to_gem5.cc:266
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:586
unsigned char * get_byte_enable_ptr() const
Definition: gp.hh:219
#define SC_REPORT_INFO(msg_type, msg)
tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, sc_core::sc_time &t)
Definition: tlm_to_gem5.cc:240
sc_dt::uint64 get_address() const
Definition: gp.hh:184
#define SC_REPORT_WARNING(msg_type, msg)
void addInvalidationCallback(CbFunction func)
Definition: backdoor.hh:124
RequestPtr req
A pointer to the original request.
Definition: packet.hh:327
void handleBeginReq(tlm::tlm_generic_payload &trans)
Definition: tlm_to_gem5.cc:142
static sc_time from_value(sc_dt::uint64)
Definition: sc_time.cc:212
bool is_response_error() const
Definition: gp.hh:197
Bitfield< 5, 0 > status
std::string get_response_string() const
Definition: gp.cc:275
void peq_cb(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase)
Definition: tlm_to_gem5.cc:223
unsigned char * get_data_ptr() const
Definition: gp.hh:188
bool isAtomicMode() const
Is the system in atomic mode?
Definition: system.hh:139
bool needsResponse() const
Definition: packet.hh:542
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition: packet.hh:366
TlmToGem5Bridge(Params *p, const sc_core::sc_module_name &mn)
Definition: tlm_to_gem5.cc:468
void destroyPacket(PacketPtr pkt)
Definition: tlm_to_gem5.cc:196
uint64_t Tick
Tick count type.
Definition: types.hh:63
unsigned int get_data_length() const
Definition: gp.hh:192
Addr end() const
Get the end address of the range.
Definition: addr_range.hh:302
bool isResponse() const
Definition: packet.hh:532
::Port & gem5_getPort(const std::string &if_name, int idx=-1) override
Definition: tlm_to_gem5.cc:457
void set_granted_access(dmi_access_e a)
Definition: dmi.hh:86
const AddrRange & range() const
Definition: backdoor.hh:78
Bitfield< 18, 16 > len
Bitfield< 21 > ss
uint16_t MasterID
Definition: request.hh:86
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Definition: packet.hh:384
unsigned int get_streaming_width() const
Definition: gp.hh:211
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:255
Bitfield< 15 > system
Definition: misc.hh:999
bool readable() const
Definition: backdoor.hh:89
uint8_t * ptr() const
Definition: backdoor.hh:82
TlmToGem5BridgeBaseParams Params
Definition: tlm_to_gem5.hh:166
#define sc_assert(expr)
The request should not cause a memory access.
Definition: request.hh:138
const sc_time SC_ZERO_TIME
Definition: sc_time.cc:292
void set_dmi_allowed(bool dmi_allowed)
Definition: gp.hh:239
void checkTransaction(tlm::tlm_generic_payload &trans)
Definition: tlm_to_gem5.cc:203
void invalidateDmi(const ::MemBackdoor &backdoor)
Definition: tlm_to_gem5.cc:215
tlm_command get_command() const
Definition: gp.hh:180
virtual ::Port & gem5_getPort(const std::string &if_name, int idx=-1)
Definition: sc_module.cc:119
tlm_utils::simple_target_socket< TlmToGem5Bridge< BITWIDTH >, BITWIDTH > socket
Definition: tlm_to_gem5.hh:127
bool isPipeThrough() const
Definition: sc_ext.hh:61
#define SC_REPORT_ERROR(msg_type, msg)
void before_end_of_elaboration() override
Definition: tlm_to_gem5.cc:483
Bitfield< 4 > width
void pushSenderState(SenderState *sender_state)
Push a new sender state to the packet and make the current sender state the predecessor of the new on...
Definition: packet.cc:319
Addr start() const
Get the start address of the range.
Definition: addr_range.hh:297
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
Definition: packet.cc:327
PacketPtr payload2packet(MasterID masterId, tlm::tlm_generic_payload &trans)
Definition: tlm_to_gem5.cc:73
tlm_sync_enum
Definition: fw_bw_ifs.hh:31
#define SC_REPORT_FATAL(msg_type, msg)
Bitfield< 5 > t
void set_end_address(sc_dt::uint64 addr)
Definition: dmi.hh:83
bool isTimingMode() const
Is the system in timing mode?
Definition: system.hh:150
PacketPtr getPacket()
Definition: sc_ext.cc:67
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:185
void handleEndResp(tlm::tlm_generic_payload &trans)
Definition: tlm_to_gem5.cc:180
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:104
virtual void before_end_of_elaboration()
Definition: sc_module.hh:250

Generated on Fri Feb 28 2020 16:27:05 for gem5 by doxygen 1.8.13