gem5  v20.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 
59 
60 #include "params/TlmToGem5Bridge32.hh"
61 #include "params/TlmToGem5Bridge64.hh"
62 #include "sim/system.hh"
65 
66 namespace sc_gem5
67 {
68 
71 {
72  MemCmd cmd;
73 
74  switch (trans.get_command()) {
76  cmd = MemCmd::ReadReq;
77  break;
79  cmd = MemCmd::WriteReq;
80  break;
82  return nullptr;
83  default:
84  SC_REPORT_FATAL("TlmToGem5Bridge",
85  "received transaction with unsupported command");
86  }
87 
88  Request::Flags flags;
89  auto req = std::make_shared<Request>(
90  trans.get_address(), trans.get_data_length(), flags, masterId);
91 
92  /*
93  * Allocate a new Packet. The packet will be deleted when it returns from
94  * the gem5 world as a response.
95  */
96  auto pkt = new Packet(req, cmd);
97  pkt->dataStatic(trans.get_data_ptr());
98 
99  return pkt;
100 }
101 
102 template <unsigned int BITWIDTH>
103 void
105 {
107  auto delay = sc_core::SC_ZERO_TIME;
108 
109  auto status = socket->nb_transport_bw(trans, phase, delay);
111  "Unexpected status after sending END_REQ");
112 }
113 
114 template <unsigned int BITWIDTH>
115 void
117  sc_core::sc_time &delay)
118 {
120 
122 
123  auto status = socket->nb_transport_bw(trans, phase, delay);
124 
125  if (status == tlm::TLM_COMPLETED ||
126  (status == tlm::TLM_UPDATED && phase == tlm::END_RESP)) {
127  // transaction completed -> no need to wait for tlm::END_RESP
128  responseInProgress = false;
129  } else if (status == tlm::TLM_ACCEPTED) {
130  // we need to wait for tlm::END_RESP
131  responseInProgress = true;
132  } else {
133  panic("Unexpected status after sending BEGIN_RESP");
134  }
135 }
136 
137 template <unsigned int BITWIDTH>
138 void
140 {
141  sc_assert(!waitForRetry);
142  sc_assert(pendingRequest == nullptr);
143  sc_assert(pendingPacket == nullptr);
144 
145  trans.acquire();
146 
147  PacketPtr pkt = nullptr;
148 
149  Gem5SystemC::Gem5Extension *extension = nullptr;
150  trans.get_extension(extension);
151 
152  // If there is an extension, this transaction was initiated by the gem5
153  // world and we can pipe through the original packet. Otherwise, we
154  // generate a new packet based on the transaction.
155  if (extension != nullptr) {
156  extension->setPipeThrough();
157  pkt = extension->getPacket();
158  } else {
159  pkt = payload2packet(masterId, trans);
160  }
161 
162  auto tlmSenderState = new TlmSenderState(trans);
163  pkt->pushSenderState(tlmSenderState);
164 
165  if (bmp.sendTimingReq(pkt)) { // port is free -> send END_REQ immediately
166  sendEndReq(trans);
167  trans.release();
168  } else { // port is blocked -> wait for retry before sending END_REQ
169  waitForRetry = true;
170  pendingRequest = &trans;
171  pendingPacket = pkt;
172  }
173 }
174 
175 template <unsigned int BITWIDTH>
176 void
178 {
179  sc_assert(responseInProgress);
180 
181  responseInProgress = false;
182 
183  checkTransaction(trans);
184 
185  if (needToSendRetry) {
186  bmp.sendRetryResp();
187  needToSendRetry = false;
188  }
189 }
190 
191 template <unsigned int BITWIDTH>
192 void
194 {
195  delete pkt;
196 }
197 
198 template <unsigned int BITWIDTH>
199 void
201 {
202  if (trans.is_response_error()) {
203  std::stringstream ss;
204  ss << "Transaction returned with error, response status = "
205  << trans.get_response_string();
206  SC_REPORT_ERROR("TLM-2", ss.str().c_str());
207  }
208 }
209 
210 template <unsigned int BITWIDTH>
211 void
212 TlmToGem5Bridge<BITWIDTH>::invalidateDmi(const ::MemBackdoor &backdoor)
213 {
214  socket->invalidate_direct_mem_ptr(
215  backdoor.range().start(), backdoor.range().end());
216 }
217 
218 template <unsigned int BITWIDTH>
219 void
221  const tlm::tlm_phase &phase)
222 {
223  switch (phase) {
224  case tlm::BEGIN_REQ:
225  handleBeginReq(trans);
226  break;
227  case tlm::END_RESP:
228  handleEndResp(trans);
229  break;
230  default:
231  panic("unimplemented phase in callback");
232  }
233 }
234 
235 template <unsigned int BITWIDTH>
239  sc_core::sc_time &delay)
240 {
241  unsigned len = trans.get_data_length();
242  unsigned char *byteEnable = trans.get_byte_enable_ptr();
243  unsigned width = trans.get_streaming_width();
244 
245  // check the transaction attributes for unsupported features ...
246  if (byteEnable != 0) {
248  return tlm::TLM_COMPLETED;
249  }
250  if (width < len) { // is this a burst request?
252  return tlm::TLM_COMPLETED;
253  }
254 
255  // ... and queue the valid transaction
256  trans.acquire();
257  peq.notify(trans, phase, delay);
258  return tlm::TLM_ACCEPTED;
259 }
260 
261 template <unsigned int BITWIDTH>
262 void
265 {
266  Gem5SystemC::Gem5Extension *extension = nullptr;
267  trans.get_extension(extension);
268 
269  PacketPtr pkt = nullptr;
270 
271  // If there is an extension, this transaction was initiated by the gem5
272  // world and we can pipe through the original packet.
273  if (extension != nullptr) {
274  extension->setPipeThrough();
275  pkt = extension->getPacket();
276  } else {
277  pkt = payload2packet(masterId, trans);
278  }
279 
280  MemBackdoorPtr backdoor = nullptr;
281  Tick ticks = bmp.sendAtomicBackdoor(pkt, backdoor);
282  if (backdoor)
283  trans.set_dmi_allowed(true);
284 
285  // send an atomic request to gem5
286  panic_if(pkt->needsResponse() && !pkt->isResponse(),
287  "Packet sending failed!\n");
288 
289  auto delay =
291 
292  // update time
293  t += delay;
294 
295  if (extension == nullptr)
296  destroyPacket(pkt);
297 
299 }
300 
301 template <unsigned int BITWIDTH>
302 unsigned int
304 {
305  Gem5SystemC::Gem5Extension *extension = nullptr;
306  trans.get_extension(extension);
307 
308  // If there is an extension, this transaction was initiated by the gem5
309  // world and we can pipe through the original packet.
310  if (extension != nullptr) {
311  extension->setPipeThrough();
312  bmp.sendFunctional(extension->getPacket());
313  } else {
314  auto pkt = payload2packet(masterId, trans);
315  if (pkt) {
316  bmp.sendFunctional(pkt);
317  destroyPacket(pkt);
318  }
319  }
320 
321  return trans.get_data_length();
322 }
323 
324 template <unsigned int BITWIDTH>
325 bool
327  tlm::tlm_dmi &dmi_data)
328 {
329  Gem5SystemC::Gem5Extension *extension = nullptr;
330  trans.get_extension(extension);
331 
332  PacketPtr pkt = nullptr;
333 
334  // If there is an extension, this transaction was initiated by the gem5
335  // world and we can pipe through the original packet.
336  if (extension != nullptr) {
337  extension->setPipeThrough();
338  pkt = extension->getPacket();
339  } else {
340  pkt = payload2packet(masterId, trans);
341  pkt->req->setFlags(Request::NO_ACCESS);
342  }
343 
344  MemBackdoorPtr backdoor = nullptr;
345  bmp.sendAtomicBackdoor(pkt, backdoor);
346  if (backdoor) {
347  trans.set_dmi_allowed(true);
348  dmi_data.set_dmi_ptr(backdoor->ptr());
349  dmi_data.set_start_address(backdoor->range().start());
350  dmi_data.set_end_address(backdoor->range().end());
351 
352  typedef tlm::tlm_dmi::dmi_access_e access_t;
353  access_t access = tlm::tlm_dmi::DMI_ACCESS_NONE;
354  if (backdoor->readable())
355  access = (access_t)(access | tlm::tlm_dmi::DMI_ACCESS_READ);
356  if (backdoor->writeable())
357  access = (access_t)(access | tlm::tlm_dmi::DMI_ACCESS_WRITE);
358  dmi_data.set_granted_access(access);
359 
360  backdoor->addInvalidationCallback(
361  [this](const MemBackdoor &backdoor)
362  {
363  invalidateDmi(backdoor);
364  }
365  );
366  }
367 
368  if (extension == nullptr)
369  destroyPacket(pkt);
370 
372 
373  return backdoor != nullptr;
374 }
375 
376 template <unsigned int BITWIDTH>
377 bool
379 {
380  // exclusion rule
381  // We need to Wait for END_RESP before sending next BEGIN_RESP
382  if (responseInProgress) {
383  sc_assert(!needToSendRetry);
384  needToSendRetry = true;
385  return false;
386  }
387 
388  sc_assert(pkt->isResponse());
389 
390  /*
391  * Pay for annotated transport delays.
392  *
393  * See recvTimingReq in sc_slave_port.cc for a detailed description.
394  */
395  auto delay = sc_core::sc_time::from_value(pkt->payloadDelay);
396  // reset the delays
397  pkt->payloadDelay = 0;
398  pkt->headerDelay = 0;
399 
400  auto tlmSenderState = dynamic_cast<TlmSenderState*>(pkt->popSenderState());
401  sc_assert(tlmSenderState != nullptr);
402 
403  auto &trans = tlmSenderState->trans;
404 
405  Gem5SystemC::Gem5Extension *extension = nullptr;
406  trans.get_extension(extension);
407 
408  // clean up
409  delete tlmSenderState;
410 
411  // If there is an extension the packet was piped through and we must not
412  // delete it. The packet travels back with the transaction.
413  if (extension == nullptr)
414  destroyPacket(pkt);
415  else
416  sc_assert(extension->isPipeThrough());
417 
418  sendBeginResp(trans, delay);
419  trans.release();
420 
421  return true;
422 }
423 
424 template <unsigned int BITWIDTH>
425 void
427 {
428  sc_assert(waitForRetry);
429  sc_assert(pendingRequest != nullptr);
430  sc_assert(pendingPacket != nullptr);
431 
432  if (bmp.sendTimingReq(pendingPacket)) {
433  waitForRetry = false;
434  pendingPacket = nullptr;
435 
436  auto &trans = *pendingRequest;
437  sendEndReq(trans);
438  trans.release();
439 
440  pendingRequest = nullptr;
441  }
442 }
443 
444 template <unsigned int BITWIDTH>
445 void
447 {
448  SC_REPORT_WARNING("TlmToGem5Bridge",
449  "received address range change but ignored it");
450 }
451 
452 template <unsigned int BITWIDTH>
453 ::Port &
454 TlmToGem5Bridge<BITWIDTH>::gem5_getPort(const std::string &if_name, int idx)
455 {
456  if (if_name == "gem5")
457  return bmp;
458  else if (if_name == "tlm")
459  return wrapper;
460 
461  return sc_core::sc_module::gem5_getPort(if_name, idx);
462 }
463 
464 template <unsigned int BITWIDTH>
466  Params *params, const sc_core::sc_module_name &mn) :
467  TlmToGem5BridgeBase(mn), peq(this, &TlmToGem5Bridge<BITWIDTH>::peq_cb),
468  waitForRetry(false), pendingRequest(nullptr), pendingPacket(nullptr),
469  needToSendRetry(false), responseInProgress(false),
470  bmp(std::string(name()) + "master", *this), socket("tlm_socket"),
471  wrapper(socket, std::string(name()) + ".tlm", InvalidPortID),
472  system(params->system),
473  masterId(params->system->getGlobalMasterId(
474  std::string("[systemc].") + name()))
475 {
476 }
477 
478 template <unsigned int BITWIDTH>
479 void
481 {
482  /*
483  * Register the TLM non-blocking interface when using gem5 Timing mode and
484  * the TLM blocking interface when using the gem5 Atomic mode.
485  * Then the magic (TM) in simple_target_socket automatically transforms
486  * non-blocking in blocking transactions and vice versa.
487  *
488  * NOTE: The mode may change during execution.
489  */
490  if (system->isTimingMode()) {
491  SC_REPORT_INFO("TlmToGem5Bridge", "register non-blocking interface");
492  socket.register_nb_transport_fw(
494  } else if (system->isAtomicMode()) {
495  SC_REPORT_INFO("TlmToGem5Bridge", "register blocking interface");
496  socket.register_b_transport(
498  socket.register_get_direct_mem_ptr(
500  } else {
501  panic("gem5 operates neither in Timing nor in Atomic mode");
502  }
503 
504  socket.register_transport_dbg(
506 
508 }
509 
510 } // namespace sc_gem5
511 
513 TlmToGem5Bridge32Params::create()
514 {
515  return new sc_gem5::TlmToGem5Bridge<32>(
516  this, sc_core::sc_module_name(name.c_str()));
517 }
518 
520 TlmToGem5Bridge64Params::create()
521 {
522  return new sc_gem5::TlmToGem5Bridge<64>(
523  this, sc_core::sc_module_name(name.c_str()));
524 }
void sendEndReq(tlm::tlm_generic_payload &trans)
Definition: tlm_to_gem5.cc:104
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:163
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:303
Definition: packet.hh:70
const std::string & name()
Definition: trace.cc:50
bool recvTimingResp(PacketPtr pkt)
Definition: tlm_to_gem5.cc:378
bool writeable() const
Definition: backdoor.hh:97
const PortID InvalidPortID
Definition: types.hh:236
dmi_access_e
Definition: dmi.hh:37
Tick ps
picosecond
Definition: core.cc:66
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:326
void set_start_address(sc_dt::uint64 addr)
Definition: dmi.hh:82
const char * name() const
Definition: sc_object.cc:44
void sendBeginResp(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay)
Definition: tlm_to_gem5.cc:116
void b_transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &t)
Definition: tlm_to_gem5.cc:263
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
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:237
sc_dt::uint64 get_address() const
Definition: gp.hh:184
#define SC_REPORT_WARNING(msg_type, msg)
void addInvalidationCallback(CbFunction func)
Definition: backdoor.hh:122
RequestPtr req
A pointer to the original request.
Definition: packet.hh:321
void handleBeginReq(tlm::tlm_generic_payload &trans)
Definition: tlm_to_gem5.cc:139
static sc_time from_value(sc_dt::uint64)
Definition: sc_time.cc:210
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:220
unsigned char * get_data_ptr() const
Definition: gp.hh:188
bool isAtomicMode() const
Is the system in atomic mode?
Definition: system.hh:131
bool needsResponse() const
Definition: packet.hh:536
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition: packet.hh:360
TlmToGem5Bridge(Params *p, const sc_core::sc_module_name &mn)
Definition: tlm_to_gem5.cc:465
void destroyPacket(PacketPtr pkt)
Definition: tlm_to_gem5.cc:193
uint64_t Tick
Tick count type.
Definition: types.hh:61
unsigned int get_data_length() const
Definition: gp.hh:192
Addr end() const
Get the end address of the range.
Definition: addr_range.hh:298
bool isResponse() const
Definition: packet.hh:526
::Port & gem5_getPort(const std::string &if_name, int idx=-1) override
Definition: tlm_to_gem5.cc:454
void set_granted_access(dmi_access_e a)
Definition: dmi.hh:86
const AddrRange & range() const
Definition: backdoor.hh:76
Bitfield< 18, 16 > len
Bitfield< 21 > ss
uint16_t MasterID
Definition: request.hh:84
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Definition: packet.hh:378
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:249
Bitfield< 15 > system
Definition: misc.hh:997
bool readable() const
Definition: backdoor.hh:87
uint8_t * ptr() const
Definition: backdoor.hh:80
TlmToGem5BridgeBaseParams Params
Definition: tlm_to_gem5.hh:163
#define sc_assert(expr)
const sc_time SC_ZERO_TIME
Definition: sc_time.cc:290
The request should not cause a memory access.
Definition: request.hh:134
void set_dmi_allowed(bool dmi_allowed)
Definition: gp.hh:239
void checkTransaction(tlm::tlm_generic_payload &trans)
Definition: tlm_to_gem5.cc:200
void invalidateDmi(const ::MemBackdoor &backdoor)
Definition: tlm_to_gem5.cc:212
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:117
tlm_utils::simple_target_socket< TlmToGem5Bridge< BITWIDTH >, BITWIDTH > socket
Definition: tlm_to_gem5.hh:124
bool isPipeThrough() const
Definition: sc_ext.hh:57
#define SC_REPORT_ERROR(msg_type, msg)
void before_end_of_elaboration() override
Definition: tlm_to_gem5.cc:480
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:316
Addr start() const
Get the start address of the range.
Definition: addr_range.hh:293
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
Definition: packet.cc:324
PacketPtr payload2packet(MasterID masterId, tlm::tlm_generic_payload &trans)
Definition: tlm_to_gem5.cc:70
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:142
PacketPtr getPacket()
Definition: sc_ext.cc:63
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:181
void handleEndResp(tlm::tlm_generic_payload &trans)
Definition: tlm_to_gem5.cc:177
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:103
virtual void before_end_of_elaboration()
Definition: sc_module.hh:248

Generated on Thu May 28 2020 16:21:38 for gem5 by doxygen 1.8.13