Deleted Added
sdiff udiff text old ( 13823:040971e0f728 ) new ( 13846:af21c0a800fb )
full compact
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

--- 66 unchanged lines hidden (view full) ---

75/**
76 * Instantiate a tlm memory manager that takes care about all the
77 * tlm transactions in the system.
78 */
79Gem5SystemC::MemoryManager mm;
80
81/**
82 * Convert a gem5 packet to a TLM payload by copying all the relevant
83 * information to new tlm payload.
84 */
85tlm::tlm_generic_payload *
86packet2payload(PacketPtr packet)
87{
88 tlm::tlm_generic_payload *trans = mm.allocate();
89 trans->acquire();
90
91 trans->set_address(packet->getAddr());
92
93 /* Check if this transaction was allocated by mm */
94 sc_assert(trans->has_mm());
95
96 unsigned int size = packet->getSize();
97 unsigned char *data = packet->getPtr<unsigned char>();
98
99 trans->set_data_length(size);
100 trans->set_streaming_width(size);
101 trans->set_data_ptr(data);
102
103 if ((packet->req->getFlags() & Request::NO_ACCESS) != 0) {
104 /* Do nothing */
105 trans->set_command(tlm::TLM_IGNORE_COMMAND);
106 } else if (packet->isRead()) {
107 trans->set_command(tlm::TLM_READ_COMMAND);
108 } else if (packet->isInvalidate()) {
109 /* Do nothing */
110 trans->set_command(tlm::TLM_IGNORE_COMMAND);
111 } else if (packet->isWrite()) {
112 trans->set_command(tlm::TLM_WRITE_COMMAND);
113 } else {
114 SC_REPORT_FATAL("Gem5ToTlmBridge", "No R/W packet");
115 }
116
117 // Attach the packet pointer to the TLM transaction to keep track.
118 auto *extension = new Gem5SystemC::Gem5Extension(packet);
119 trans->set_auto_extension(extension);
120
121 return trans;
122}
123
124template <unsigned int BITWIDTH>
125void
126Gem5ToTlmBridge<BITWIDTH>::pec(
127 Gem5SystemC::PayloadEvent<Gem5ToTlmBridge<BITWIDTH>> *pe,
128 tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase)
129{

--- 44 unchanged lines hidden (view full) ---

174 // Release the transaction with all the extensions.
175 trans.release();
176 }
177 }
178 }
179 delete pe;
180}
181
182template <unsigned int BITWIDTH>
183MemBackdoorPtr
184Gem5ToTlmBridge<BITWIDTH>::getBackdoor(tlm::tlm_generic_payload &trans)
185{
186 sc_dt::uint64 start = trans.get_address();
187 sc_dt::uint64 end = start + trans.get_data_length();
188
189 // Check for a back door we already know about.
190 AddrRange r(start, end);
191 auto it = backdoorMap.contains(r);
192 if (it != backdoorMap.end())
193 return it->second;
194
195 // If not, ask the target for one.
196 tlm::tlm_dmi dmi_data;
197 if (!socket->get_direct_mem_ptr(trans, dmi_data))
198 return nullptr;
199
200 // If the target gave us one, translate it to a gem5 MemBackdoor and
201 // store it in our cache.
202 AddrRange dmi_r(dmi_data.get_start_address(), dmi_data.get_end_address());
203 auto backdoor = new MemBackdoor(
204 dmi_r, dmi_data.get_dmi_ptr(), MemBackdoor::NoAccess);
205 backdoor->readable(dmi_data.is_read_allowed());
206 backdoor->writeable(dmi_data.is_write_allowed());
207
208 backdoorMap.insert(dmi_r, backdoor);
209
210 return backdoor;
211}
212
213// Similar to TLM's blocking transport (LT)
214template <unsigned int BITWIDTH>
215Tick
216Gem5ToTlmBridge<BITWIDTH>::recvAtomic(PacketPtr packet)
217{
218 panic_if(packet->cacheResponding(),
219 "Should not see packets where cache is responding");
220
221 // Prepare the transaction.
222 auto *trans = packet2payload(packet);
223
224 sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
225
226 if (trans->get_command() != tlm::TLM_IGNORE_COMMAND) {
227 // Execute b_transport:
228 socket->b_transport(*trans, delay);
229 }
230
231 if (packet->needsResponse())
232 packet->makeResponse();
233
234 trans->release();
235
236 return delay.value();
237}
238
239template <unsigned int BITWIDTH>
240Tick
241Gem5ToTlmBridge<BITWIDTH>::recvAtomicBackdoor(
242 PacketPtr packet, MemBackdoorPtr &backdoor)
243{
244 panic_if(packet->cacheResponding(),
245 "Should not see packets where cache is responding");
246
247 sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
248
249 // Prepare the transaction.
250 auto *trans = packet2payload(packet);
251
252 if (trans->get_command() != tlm::TLM_IGNORE_COMMAND) {
253 // Execute b_transport:
254 socket->b_transport(*trans, delay);
255 // If the hint said we could use DMI, set that up.
256 if (trans->is_dmi_allowed())
257 backdoor = getBackdoor(*trans);
258 } else {
259 // There's no transaction to piggy back on, so just request the
260 // backdoor normally.
261 backdoor = getBackdoor(*trans);
262 }
263
264 if (packet->needsResponse())
265 packet->makeResponse();
266
267 trans->release();
268
269 return delay.value();
270}
271
272template <unsigned int BITWIDTH>
273void

--- 34 unchanged lines hidden (view full) ---

308 * if (requestInProgress)
309 * {
310 * wait(endRequestEvent);
311 * }
312 * requestInProgress = trans;
313 */
314
315 // Prepare the transaction.
316 auto *trans = packet2payload(packet);
317
318 /*
319 * Pay for annotated transport delays.
320 *
321 * The header delay marks the point in time, when the packet first is seen
322 * by the transactor. This is the point in time when the transactor needs
323 * to send the BEGIN_REQ to the SystemC world.
324 *
325 * NOTE: We drop the payload delay here. Normally, the receiver would be

--- 84 unchanged lines hidden (view full) ---

410}
411
412// Similar to TLM's debug transport.
413template <unsigned int BITWIDTH>
414void
415Gem5ToTlmBridge<BITWIDTH>::recvFunctional(PacketPtr packet)
416{
417 // Prepare the transaction.
418 auto *trans = packet2payload(packet);
419
420 /* Execute Debug Transport: */
421 unsigned int bytes = socket->transport_dbg(*trans);
422 if (bytes != trans->get_data_length()) {
423 SC_REPORT_FATAL("Gem5ToTlmBridge",
424 "debug transport was not completed");
425 }
426
427 trans->release();

--- 8 unchanged lines hidden (view full) ---

436 *this, &Gem5ToTlmBridge::pec, "PE");
437 Tick nextEventTick = curTick() + delay.value();
438 system->wakeupEventQueue(nextEventTick);
439 system->schedule(pe, nextEventTick);
440 return tlm::TLM_ACCEPTED;
441}
442
443template <unsigned int BITWIDTH>
444void
445Gem5ToTlmBridge<BITWIDTH>::invalidate_direct_mem_ptr(
446 sc_dt::uint64 start_range, sc_dt::uint64 end_range)
447{
448 AddrRange r(start_range, end_range);
449
450 for (;;) {
451 auto it = backdoorMap.intersects(r);
452 if (it == backdoorMap.end())
453 break;
454
455 it->second->invalidate();
456 delete it->second;
457 backdoorMap.erase(it);
458 };
459}
460
461template <unsigned int BITWIDTH>
462Gem5ToTlmBridge<BITWIDTH>::Gem5ToTlmBridge(
463 Params *params, const sc_core::sc_module_name &mn) :
464 Gem5ToTlmBridgeBase(mn), bsp(std::string(name()) + ".gem5", *this),
465 socket("tlm_socket"),
466 wrapper(socket, std::string(name()) + ".tlm", InvalidPortID),
467 system(params->system), blockingRequest(nullptr),
468 needToSendRequestRetry(false), blockingResponse(nullptr),
469 addrRanges(params->addr_ranges.begin(), params->addr_ranges.end())

--- 14 unchanged lines hidden (view full) ---

484
485template <unsigned int BITWIDTH>
486void
487Gem5ToTlmBridge<BITWIDTH>::before_end_of_elaboration()
488{
489 bsp.sendRangeChange();
490
491 socket.register_nb_transport_bw(this, &Gem5ToTlmBridge::nb_transport_bw);
492 socket.register_invalidate_direct_mem_ptr(
493 this, &Gem5ToTlmBridge::invalidate_direct_mem_ptr);
494 sc_core::sc_module::before_end_of_elaboration();
495}
496
497} // namespace sc_gem5
498
499sc_gem5::Gem5ToTlmBridge<32> *
500Gem5ToTlmBridge32Params::create()
501{
502 return new sc_gem5::Gem5ToTlmBridge<32>(
503 this, sc_core::sc_module_name(name.c_str()));
504}
505
506sc_gem5::Gem5ToTlmBridge<64> *
507Gem5ToTlmBridge64Params::create()
508{
509 return new sc_gem5::Gem5ToTlmBridge<64>(
510 this, sc_core::sc_module_name(name.c_str()));
511}