gem5_to_tlm.cc revision 13821
113821Sgabeblack@google.com/* 213821Sgabeblack@google.com * Copyright 2019 Google, Inc. 313821Sgabeblack@google.com * 413821Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 513821Sgabeblack@google.com * modification, are permitted provided that the following conditions are 613821Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 713821Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 813821Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 913821Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1013821Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1113821Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1213821Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1313821Sgabeblack@google.com * this software without specific prior written permission. 1413821Sgabeblack@google.com * 1513821Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1613821Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1713821Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1813821Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1913821Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2013821Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2113821Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2213821Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2313821Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2413821Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2513821Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2613821Sgabeblack@google.com * 2713821Sgabeblack@google.com * Copyright (c) 2015, University of Kaiserslautern 2813821Sgabeblack@google.com * Copyright (c) 2016, Dresden University of Technology (TU Dresden) 2913821Sgabeblack@google.com * All rights reserved. 3013821Sgabeblack@google.com * 3113821Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 3213821Sgabeblack@google.com * modification, are permitted provided that the following conditions are 3313821Sgabeblack@google.com * met: 3413821Sgabeblack@google.com * 3513821Sgabeblack@google.com * 1. Redistributions of source code must retain the above copyright notice, 3613821Sgabeblack@google.com * this list of conditions and the following disclaimer. 3713821Sgabeblack@google.com * 3813821Sgabeblack@google.com * 2. Redistributions in binary form must reproduce the above copyright 3913821Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 4013821Sgabeblack@google.com * documentation and/or other materials provided with the distribution. 4113821Sgabeblack@google.com * 4213821Sgabeblack@google.com * 3. Neither the name of the copyright holder nor the names of its 4313821Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 4413821Sgabeblack@google.com * this software without specific prior written permission. 4513821Sgabeblack@google.com * 4613821Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 4713821Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 4813821Sgabeblack@google.com * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4913821Sgabeblack@google.com * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 5013821Sgabeblack@google.com * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 5113821Sgabeblack@google.com * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 5213821Sgabeblack@google.com * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 5313821Sgabeblack@google.com * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 5413821Sgabeblack@google.com * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 5513821Sgabeblack@google.com * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 5613821Sgabeblack@google.com * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 5713821Sgabeblack@google.com * 5813821Sgabeblack@google.com * Authors: Gabe Black 5913821Sgabeblack@google.com * Matthias Jung 6013821Sgabeblack@google.com * Abdul Mutaal Ahmad 6113821Sgabeblack@google.com * Christian Menard 6213821Sgabeblack@google.com */ 6313821Sgabeblack@google.com 6413821Sgabeblack@google.com#include "systemc/tlm_bridge/gem5_to_tlm.hh" 6513821Sgabeblack@google.com 6613821Sgabeblack@google.com#include "sim/system.hh" 6713821Sgabeblack@google.com#include "systemc/tlm_bridge/sc_ext.hh" 6813821Sgabeblack@google.com#include "systemc/tlm_bridge/sc_mm.hh" 6913821Sgabeblack@google.com 7013821Sgabeblack@google.comnamespace sc_gem5 7113821Sgabeblack@google.com{ 7213821Sgabeblack@google.com 7313821Sgabeblack@google.com/** 7413821Sgabeblack@google.com * Instantiate a tlm memory manager that takes care about all the 7513821Sgabeblack@google.com * tlm transactions in the system. 7613821Sgabeblack@google.com */ 7713821Sgabeblack@google.comGem5SystemC::MemoryManager mm; 7813821Sgabeblack@google.com 7913821Sgabeblack@google.com/** 8013821Sgabeblack@google.com * Convert a gem5 packet to a TLM payload by copying all the relevant 8113821Sgabeblack@google.com * information to a previously allocated tlm payload 8213821Sgabeblack@google.com */ 8313821Sgabeblack@google.comvoid 8413821Sgabeblack@google.compacket2payload(PacketPtr packet, tlm::tlm_generic_payload &trans) 8513821Sgabeblack@google.com{ 8613821Sgabeblack@google.com trans.set_address(packet->getAddr()); 8713821Sgabeblack@google.com 8813821Sgabeblack@google.com /* Check if this transaction was allocated by mm */ 8913821Sgabeblack@google.com sc_assert(trans.has_mm()); 9013821Sgabeblack@google.com 9113821Sgabeblack@google.com unsigned int size = packet->getSize(); 9213821Sgabeblack@google.com unsigned char *data = packet->getPtr<unsigned char>(); 9313821Sgabeblack@google.com 9413821Sgabeblack@google.com trans.set_data_length(size); 9513821Sgabeblack@google.com trans.set_streaming_width(size); 9613821Sgabeblack@google.com trans.set_data_ptr(data); 9713821Sgabeblack@google.com 9813821Sgabeblack@google.com if (packet->isRead()) { 9913821Sgabeblack@google.com trans.set_command(tlm::TLM_READ_COMMAND); 10013821Sgabeblack@google.com } else if (packet->isInvalidate()) { 10113821Sgabeblack@google.com /* Do nothing */ 10213821Sgabeblack@google.com } else if (packet->isWrite()) { 10313821Sgabeblack@google.com trans.set_command(tlm::TLM_WRITE_COMMAND); 10413821Sgabeblack@google.com } else { 10513821Sgabeblack@google.com SC_REPORT_FATAL("Gem5ToTlmBridge", "No R/W packet"); 10613821Sgabeblack@google.com } 10713821Sgabeblack@google.com} 10813821Sgabeblack@google.com 10913821Sgabeblack@google.comvoid 11013821Sgabeblack@google.comGem5ToTlmBridge::pec(Gem5SystemC::PayloadEvent<Gem5ToTlmBridge> *pe, 11113821Sgabeblack@google.com tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase) 11213821Sgabeblack@google.com{ 11313821Sgabeblack@google.com sc_core::sc_time delay; 11413821Sgabeblack@google.com 11513821Sgabeblack@google.com if (phase == tlm::END_REQ || 11613821Sgabeblack@google.com (&trans == blockingRequest && phase == tlm::BEGIN_RESP)) { 11713821Sgabeblack@google.com sc_assert(&trans == blockingRequest); 11813821Sgabeblack@google.com blockingRequest = nullptr; 11913821Sgabeblack@google.com 12013821Sgabeblack@google.com // Did another request arrive while blocked, schedule a retry. 12113821Sgabeblack@google.com if (needToSendRequestRetry) { 12213821Sgabeblack@google.com needToSendRequestRetry = false; 12313821Sgabeblack@google.com bsp.sendRetryReq(); 12413821Sgabeblack@google.com } 12513821Sgabeblack@google.com } 12613821Sgabeblack@google.com if (phase == tlm::BEGIN_RESP) { 12713821Sgabeblack@google.com auto &extension = Gem5SystemC::Gem5Extension::getExtension(trans); 12813821Sgabeblack@google.com auto packet = extension.getPacket(); 12913821Sgabeblack@google.com 13013821Sgabeblack@google.com sc_assert(!blockingResponse); 13113821Sgabeblack@google.com 13213821Sgabeblack@google.com bool need_retry = false; 13313821Sgabeblack@google.com 13413821Sgabeblack@google.com /* 13513821Sgabeblack@google.com * If the packet was piped through and needs a response, we don't need 13613821Sgabeblack@google.com * to touch the packet and can forward it directly as a response. 13713821Sgabeblack@google.com * Otherwise, we need to make a response and send the transformed 13813821Sgabeblack@google.com * packet. 13913821Sgabeblack@google.com */ 14013821Sgabeblack@google.com if (extension.isPipeThrough()) { 14113821Sgabeblack@google.com if (packet->isResponse()) { 14213821Sgabeblack@google.com need_retry = !bsp.sendTimingResp(packet); 14313821Sgabeblack@google.com } 14413821Sgabeblack@google.com } else if (packet->needsResponse()) { 14513821Sgabeblack@google.com packet->makeResponse(); 14613821Sgabeblack@google.com need_retry = !bsp.sendTimingResp(packet); 14713821Sgabeblack@google.com } 14813821Sgabeblack@google.com 14913821Sgabeblack@google.com if (need_retry) { 15013821Sgabeblack@google.com blockingResponse = &trans; 15113821Sgabeblack@google.com } else { 15213821Sgabeblack@google.com if (phase == tlm::BEGIN_RESP) { 15313821Sgabeblack@google.com // Send END_RESP and we're finished: 15413821Sgabeblack@google.com tlm::tlm_phase fw_phase = tlm::END_RESP; 15513821Sgabeblack@google.com sc_core::sc_time delay = sc_core::SC_ZERO_TIME; 15613821Sgabeblack@google.com socket->nb_transport_fw(trans, fw_phase, delay); 15713821Sgabeblack@google.com // Release the transaction with all the extensions. 15813821Sgabeblack@google.com trans.release(); 15913821Sgabeblack@google.com } 16013821Sgabeblack@google.com } 16113821Sgabeblack@google.com } 16213821Sgabeblack@google.com delete pe; 16313821Sgabeblack@google.com} 16413821Sgabeblack@google.com 16513821Sgabeblack@google.com// Similar to TLM's blocking transport (LT) 16613821Sgabeblack@google.comTick 16713821Sgabeblack@google.comGem5ToTlmBridge::recvAtomic(PacketPtr packet) 16813821Sgabeblack@google.com{ 16913821Sgabeblack@google.com panic_if(packet->cacheResponding(), 17013821Sgabeblack@google.com "Should not see packets where cache is responding"); 17113821Sgabeblack@google.com 17213821Sgabeblack@google.com panic_if(!(packet->isRead() || packet->isWrite()), 17313821Sgabeblack@google.com "Should only see read and writes at TLM memory\n"); 17413821Sgabeblack@google.com 17513821Sgabeblack@google.com sc_core::sc_time delay = sc_core::SC_ZERO_TIME; 17613821Sgabeblack@google.com 17713821Sgabeblack@google.com // Prepare the transaction. 17813821Sgabeblack@google.com tlm::tlm_generic_payload *trans = mm.allocate(); 17913821Sgabeblack@google.com trans->acquire(); 18013821Sgabeblack@google.com packet2payload(packet, *trans); 18113821Sgabeblack@google.com 18213821Sgabeblack@google.com // Attach the packet pointer to the TLM transaction to keep track. 18313821Sgabeblack@google.com auto *extension = new Gem5SystemC::Gem5Extension(packet); 18413821Sgabeblack@google.com trans->set_auto_extension(extension); 18513821Sgabeblack@google.com 18613821Sgabeblack@google.com // Execute b_transport: 18713821Sgabeblack@google.com if (packet->cmd == MemCmd::SwapReq) { 18813821Sgabeblack@google.com SC_REPORT_FATAL("Gem5ToTlmBridge", "SwapReq not supported"); 18913821Sgabeblack@google.com } else if (packet->isRead()) { 19013821Sgabeblack@google.com socket->b_transport(*trans, delay); 19113821Sgabeblack@google.com } else if (packet->isInvalidate()) { 19213821Sgabeblack@google.com // do nothing 19313821Sgabeblack@google.com } else if (packet->isWrite()) { 19413821Sgabeblack@google.com socket->b_transport(*trans, delay); 19513821Sgabeblack@google.com } else { 19613821Sgabeblack@google.com SC_REPORT_FATAL("Gem5ToTlmBridge", "Typo of request not supported"); 19713821Sgabeblack@google.com } 19813821Sgabeblack@google.com 19913821Sgabeblack@google.com if (packet->needsResponse()) { 20013821Sgabeblack@google.com packet->makeResponse(); 20113821Sgabeblack@google.com } 20213821Sgabeblack@google.com 20313821Sgabeblack@google.com trans->release(); 20413821Sgabeblack@google.com 20513821Sgabeblack@google.com return delay.value(); 20613821Sgabeblack@google.com} 20713821Sgabeblack@google.com 20813821Sgabeblack@google.comvoid 20913821Sgabeblack@google.comGem5ToTlmBridge::recvFunctionalSnoop(PacketPtr packet) 21013821Sgabeblack@google.com{ 21113821Sgabeblack@google.com // Snooping should be implemented with tlm_dbg_transport. 21213821Sgabeblack@google.com SC_REPORT_FATAL("Gem5ToTlmBridge", 21313821Sgabeblack@google.com "unimplemented func.: recvFunctionalSnoop"); 21413821Sgabeblack@google.com} 21513821Sgabeblack@google.com 21613821Sgabeblack@google.com// Similar to TLM's non-blocking transport (AT). 21713821Sgabeblack@google.combool 21813821Sgabeblack@google.comGem5ToTlmBridge::recvTimingReq(PacketPtr packet) 21913821Sgabeblack@google.com{ 22013821Sgabeblack@google.com panic_if(packet->cacheResponding(), 22113821Sgabeblack@google.com "Should not see packets where cache is responding"); 22213821Sgabeblack@google.com 22313821Sgabeblack@google.com panic_if(!(packet->isRead() || packet->isWrite()), 22413821Sgabeblack@google.com "Should only see read and writes at TLM memory\n"); 22513821Sgabeblack@google.com 22613821Sgabeblack@google.com 22713821Sgabeblack@google.com // We should never get a second request after noting that a retry is 22813821Sgabeblack@google.com // required. 22913821Sgabeblack@google.com sc_assert(!needToSendRequestRetry); 23013821Sgabeblack@google.com 23113821Sgabeblack@google.com // Remember if a request comes in while we're blocked so that a retry 23213821Sgabeblack@google.com // can be sent to gem5. 23313821Sgabeblack@google.com if (blockingRequest) { 23413821Sgabeblack@google.com needToSendRequestRetry = true; 23513821Sgabeblack@google.com return false; 23613821Sgabeblack@google.com } 23713821Sgabeblack@google.com 23813821Sgabeblack@google.com /* 23913821Sgabeblack@google.com * NOTE: normal tlm is blocking here. But in our case we return false 24013821Sgabeblack@google.com * and tell gem5 when a retry can be done. This is the main difference 24113821Sgabeblack@google.com * in the protocol: 24213821Sgabeblack@google.com * if (requestInProgress) 24313821Sgabeblack@google.com * { 24413821Sgabeblack@google.com * wait(endRequestEvent); 24513821Sgabeblack@google.com * } 24613821Sgabeblack@google.com * requestInProgress = trans; 24713821Sgabeblack@google.com */ 24813821Sgabeblack@google.com 24913821Sgabeblack@google.com // Prepare the transaction. 25013821Sgabeblack@google.com tlm::tlm_generic_payload *trans = mm.allocate(); 25113821Sgabeblack@google.com trans->acquire(); 25213821Sgabeblack@google.com packet2payload(packet, *trans); 25313821Sgabeblack@google.com 25413821Sgabeblack@google.com // Attach the packet pointer to the TLM transaction to keep track. 25513821Sgabeblack@google.com auto *extension = new Gem5SystemC::Gem5Extension(packet); 25613821Sgabeblack@google.com trans->set_auto_extension(extension); 25713821Sgabeblack@google.com 25813821Sgabeblack@google.com /* 25913821Sgabeblack@google.com * Pay for annotated transport delays. 26013821Sgabeblack@google.com * 26113821Sgabeblack@google.com * The header delay marks the point in time, when the packet first is seen 26213821Sgabeblack@google.com * by the transactor. This is the point in time when the transactor needs 26313821Sgabeblack@google.com * to send the BEGIN_REQ to the SystemC world. 26413821Sgabeblack@google.com * 26513821Sgabeblack@google.com * NOTE: We drop the payload delay here. Normally, the receiver would be 26613821Sgabeblack@google.com * responsible for handling the payload delay. In this case, however, 26713821Sgabeblack@google.com * the receiver is a SystemC module and has no notion of the gem5 26813821Sgabeblack@google.com * transport protocol and we cannot simply forward the 26913821Sgabeblack@google.com * payload delay to the receiving module. Instead, we expect the 27013821Sgabeblack@google.com * receiving SystemC module to model the payload delay by deferring 27113821Sgabeblack@google.com * the END_REQ. This could lead to incorrect delays, if the XBar 27213821Sgabeblack@google.com * payload delay is longer than the time the receiver needs to accept 27313821Sgabeblack@google.com * the request (time between BEGIN_REQ and END_REQ). 27413821Sgabeblack@google.com * 27513821Sgabeblack@google.com * TODO: We could detect the case described above by remembering the 27613821Sgabeblack@google.com * payload delay and comparing it to the time between BEGIN_REQ and 27713821Sgabeblack@google.com * END_REQ. Then, a warning should be printed. 27813821Sgabeblack@google.com */ 27913821Sgabeblack@google.com auto delay = sc_core::sc_time::from_value(packet->payloadDelay); 28013821Sgabeblack@google.com // Reset the delays 28113821Sgabeblack@google.com packet->payloadDelay = 0; 28213821Sgabeblack@google.com packet->headerDelay = 0; 28313821Sgabeblack@google.com 28413821Sgabeblack@google.com // Starting TLM non-blocking sequence (AT) Refer to IEEE1666-2011 SystemC 28513821Sgabeblack@google.com // Standard Page 507 for a visualisation of the procedure. 28613821Sgabeblack@google.com tlm::tlm_phase phase = tlm::BEGIN_REQ; 28713821Sgabeblack@google.com tlm::tlm_sync_enum status; 28813821Sgabeblack@google.com status = socket->nb_transport_fw(*trans, phase, delay); 28913821Sgabeblack@google.com // Check returned value: 29013821Sgabeblack@google.com if (status == tlm::TLM_ACCEPTED) { 29113821Sgabeblack@google.com sc_assert(phase == tlm::BEGIN_REQ); 29213821Sgabeblack@google.com // Accepted but is now blocking until END_REQ (exclusion rule). 29313821Sgabeblack@google.com blockingRequest = trans; 29413821Sgabeblack@google.com } else if (status == tlm::TLM_UPDATED) { 29513821Sgabeblack@google.com // The Timing annotation must be honored: 29613821Sgabeblack@google.com sc_assert(phase == tlm::END_REQ || phase == tlm::BEGIN_RESP); 29713821Sgabeblack@google.com 29813821Sgabeblack@google.com auto *pe = new Gem5SystemC::PayloadEvent<Gem5ToTlmBridge>( 29913821Sgabeblack@google.com *this, &Gem5ToTlmBridge::pec, "PEQ"); 30013821Sgabeblack@google.com Tick nextEventTick = curTick() + delay.value(); 30113821Sgabeblack@google.com system->wakeupEventQueue(nextEventTick); 30213821Sgabeblack@google.com system->schedule(pe, nextEventTick); 30313821Sgabeblack@google.com } else if (status == tlm::TLM_COMPLETED) { 30413821Sgabeblack@google.com // Transaction is over nothing has do be done. 30513821Sgabeblack@google.com sc_assert(phase == tlm::END_RESP); 30613821Sgabeblack@google.com trans->release(); 30713821Sgabeblack@google.com } 30813821Sgabeblack@google.com 30913821Sgabeblack@google.com return true; 31013821Sgabeblack@google.com} 31113821Sgabeblack@google.com 31213821Sgabeblack@google.combool 31313821Sgabeblack@google.comGem5ToTlmBridge::recvTimingSnoopResp(PacketPtr packet) 31413821Sgabeblack@google.com{ 31513821Sgabeblack@google.com // Snooping should be implemented with tlm_dbg_transport. 31613821Sgabeblack@google.com SC_REPORT_FATAL("Gem5ToTlmBridge", 31713821Sgabeblack@google.com "unimplemented func.: recvTimingSnoopResp"); 31813821Sgabeblack@google.com return false; 31913821Sgabeblack@google.com} 32013821Sgabeblack@google.com 32113821Sgabeblack@google.combool 32213821Sgabeblack@google.comGem5ToTlmBridge::tryTiming(PacketPtr packet) 32313821Sgabeblack@google.com{ 32413821Sgabeblack@google.com panic("tryTiming(PacketPtr) isn't implemented."); 32513821Sgabeblack@google.com} 32613821Sgabeblack@google.com 32713821Sgabeblack@google.comvoid 32813821Sgabeblack@google.comGem5ToTlmBridge::recvRespRetry() 32913821Sgabeblack@google.com{ 33013821Sgabeblack@google.com /* Retry a response */ 33113821Sgabeblack@google.com sc_assert(blockingResponse); 33213821Sgabeblack@google.com 33313821Sgabeblack@google.com tlm::tlm_generic_payload *trans = blockingResponse; 33413821Sgabeblack@google.com blockingResponse = nullptr; 33513821Sgabeblack@google.com PacketPtr packet = 33613821Sgabeblack@google.com Gem5SystemC::Gem5Extension::getExtension(trans).getPacket(); 33713821Sgabeblack@google.com 33813821Sgabeblack@google.com bool need_retry = !bsp.sendTimingResp(packet); 33913821Sgabeblack@google.com 34013821Sgabeblack@google.com sc_assert(!need_retry); 34113821Sgabeblack@google.com 34213821Sgabeblack@google.com sc_core::sc_time delay = sc_core::SC_ZERO_TIME; 34313821Sgabeblack@google.com tlm::tlm_phase phase = tlm::END_RESP; 34413821Sgabeblack@google.com socket->nb_transport_fw(*trans, phase, delay); 34513821Sgabeblack@google.com // Release transaction with all the extensions 34613821Sgabeblack@google.com trans->release(); 34713821Sgabeblack@google.com} 34813821Sgabeblack@google.com 34913821Sgabeblack@google.com// Similar to TLM's debug transport. 35013821Sgabeblack@google.comvoid 35113821Sgabeblack@google.comGem5ToTlmBridge::recvFunctional(PacketPtr packet) 35213821Sgabeblack@google.com{ 35313821Sgabeblack@google.com // Prepare the transaction. 35413821Sgabeblack@google.com tlm::tlm_generic_payload *trans = mm.allocate(); 35513821Sgabeblack@google.com trans->acquire(); 35613821Sgabeblack@google.com packet2payload(packet, *trans); 35713821Sgabeblack@google.com 35813821Sgabeblack@google.com // Attach the packet pointer to the TLM transaction to keep track. 35913821Sgabeblack@google.com auto *extension = new Gem5SystemC::Gem5Extension(packet); 36013821Sgabeblack@google.com trans->set_auto_extension(extension); 36113821Sgabeblack@google.com 36213821Sgabeblack@google.com /* Execute Debug Transport: */ 36313821Sgabeblack@google.com unsigned int bytes = socket->transport_dbg(*trans); 36413821Sgabeblack@google.com if (bytes != trans->get_data_length()) { 36513821Sgabeblack@google.com SC_REPORT_FATAL("Gem5ToTlmBridge", 36613821Sgabeblack@google.com "debug transport was not completed"); 36713821Sgabeblack@google.com } 36813821Sgabeblack@google.com 36913821Sgabeblack@google.com trans->release(); 37013821Sgabeblack@google.com} 37113821Sgabeblack@google.com 37213821Sgabeblack@google.comtlm::tlm_sync_enum 37313821Sgabeblack@google.comGem5ToTlmBridge::nb_transport_bw(tlm::tlm_generic_payload &trans, 37413821Sgabeblack@google.com tlm::tlm_phase &phase, sc_core::sc_time &delay) 37513821Sgabeblack@google.com{ 37613821Sgabeblack@google.com auto *pe = new Gem5SystemC::PayloadEvent<Gem5ToTlmBridge>( 37713821Sgabeblack@google.com *this, &Gem5ToTlmBridge::pec, "PE"); 37813821Sgabeblack@google.com Tick nextEventTick = curTick() + delay.value(); 37913821Sgabeblack@google.com system->wakeupEventQueue(nextEventTick); 38013821Sgabeblack@google.com system->schedule(pe, nextEventTick); 38113821Sgabeblack@google.com return tlm::TLM_ACCEPTED; 38213821Sgabeblack@google.com} 38313821Sgabeblack@google.com 38413821Sgabeblack@google.comGem5ToTlmBridge::Gem5ToTlmBridge( 38513821Sgabeblack@google.com Params *params, const sc_core::sc_module_name &mn) : 38613821Sgabeblack@google.com sc_core::sc_module(mn), bsp(std::string(name()) + ".gem5", *this), 38713821Sgabeblack@google.com socket("tlm_socket"), 38813821Sgabeblack@google.com wrapper(socket, std::string(name()) + ".tlm", InvalidPortID), 38913821Sgabeblack@google.com system(params->system), blockingRequest(nullptr), 39013821Sgabeblack@google.com needToSendRequestRetry(false), blockingResponse(nullptr), 39113821Sgabeblack@google.com addrRanges(params->addr_ranges.begin(), params->addr_ranges.end()) 39213821Sgabeblack@google.com{ 39313821Sgabeblack@google.com} 39413821Sgabeblack@google.com 39513821Sgabeblack@google.com::Port & 39613821Sgabeblack@google.comGem5ToTlmBridge::gem5_getPort(const std::string &if_name, int idx) 39713821Sgabeblack@google.com{ 39813821Sgabeblack@google.com if (if_name == "gem5") 39913821Sgabeblack@google.com return bsp; 40013821Sgabeblack@google.com else if (if_name == "tlm") 40113821Sgabeblack@google.com return wrapper; 40213821Sgabeblack@google.com 40313821Sgabeblack@google.com return sc_core::sc_module::gem5_getPort(if_name, idx); 40413821Sgabeblack@google.com} 40513821Sgabeblack@google.com 40613821Sgabeblack@google.comvoid 40713821Sgabeblack@google.comGem5ToTlmBridge::before_end_of_elaboration() 40813821Sgabeblack@google.com{ 40913821Sgabeblack@google.com bsp.sendRangeChange(); 41013821Sgabeblack@google.com 41113821Sgabeblack@google.com socket.register_nb_transport_bw(this, &Gem5ToTlmBridge::nb_transport_bw); 41213821Sgabeblack@google.com sc_core::sc_module::before_end_of_elaboration(); 41313821Sgabeblack@google.com} 41413821Sgabeblack@google.com 41513821Sgabeblack@google.com} // namespace sc_gem5 41613821Sgabeblack@google.com 41713821Sgabeblack@google.comsc_gem5::Gem5ToTlmBridge * 41813821Sgabeblack@google.comGem5ToTlmBridgeParams::create() 41913821Sgabeblack@google.com{ 42013821Sgabeblack@google.com return new sc_gem5::Gem5ToTlmBridge( 42113821Sgabeblack@google.com this, sc_core::sc_module_name(name.c_str())); 42213821Sgabeblack@google.com} 423