gem5_to_tlm.cc revision 13823
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 6613823Sgabeblack@google.com#include "params/Gem5ToTlmBridge32.hh" 6713823Sgabeblack@google.com#include "params/Gem5ToTlmBridge64.hh" 6813821Sgabeblack@google.com#include "sim/system.hh" 6913821Sgabeblack@google.com#include "systemc/tlm_bridge/sc_ext.hh" 7013821Sgabeblack@google.com#include "systemc/tlm_bridge/sc_mm.hh" 7113821Sgabeblack@google.com 7213821Sgabeblack@google.comnamespace sc_gem5 7313821Sgabeblack@google.com{ 7413821Sgabeblack@google.com 7513821Sgabeblack@google.com/** 7613821Sgabeblack@google.com * Instantiate a tlm memory manager that takes care about all the 7713821Sgabeblack@google.com * tlm transactions in the system. 7813821Sgabeblack@google.com */ 7913821Sgabeblack@google.comGem5SystemC::MemoryManager mm; 8013821Sgabeblack@google.com 8113821Sgabeblack@google.com/** 8213821Sgabeblack@google.com * Convert a gem5 packet to a TLM payload by copying all the relevant 8313821Sgabeblack@google.com * information to a previously allocated tlm payload 8413821Sgabeblack@google.com */ 8513821Sgabeblack@google.comvoid 8613821Sgabeblack@google.compacket2payload(PacketPtr packet, tlm::tlm_generic_payload &trans) 8713821Sgabeblack@google.com{ 8813821Sgabeblack@google.com trans.set_address(packet->getAddr()); 8913821Sgabeblack@google.com 9013821Sgabeblack@google.com /* Check if this transaction was allocated by mm */ 9113821Sgabeblack@google.com sc_assert(trans.has_mm()); 9213821Sgabeblack@google.com 9313821Sgabeblack@google.com unsigned int size = packet->getSize(); 9413821Sgabeblack@google.com unsigned char *data = packet->getPtr<unsigned char>(); 9513821Sgabeblack@google.com 9613821Sgabeblack@google.com trans.set_data_length(size); 9713821Sgabeblack@google.com trans.set_streaming_width(size); 9813821Sgabeblack@google.com trans.set_data_ptr(data); 9913821Sgabeblack@google.com 10013821Sgabeblack@google.com if (packet->isRead()) { 10113821Sgabeblack@google.com trans.set_command(tlm::TLM_READ_COMMAND); 10213821Sgabeblack@google.com } else if (packet->isInvalidate()) { 10313821Sgabeblack@google.com /* Do nothing */ 10413821Sgabeblack@google.com } else if (packet->isWrite()) { 10513821Sgabeblack@google.com trans.set_command(tlm::TLM_WRITE_COMMAND); 10613821Sgabeblack@google.com } else { 10713821Sgabeblack@google.com SC_REPORT_FATAL("Gem5ToTlmBridge", "No R/W packet"); 10813821Sgabeblack@google.com } 10913821Sgabeblack@google.com} 11013821Sgabeblack@google.com 11113823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 11213821Sgabeblack@google.comvoid 11313823Sgabeblack@google.comGem5ToTlmBridge<BITWIDTH>::pec( 11413823Sgabeblack@google.com Gem5SystemC::PayloadEvent<Gem5ToTlmBridge<BITWIDTH>> *pe, 11513821Sgabeblack@google.com tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase) 11613821Sgabeblack@google.com{ 11713821Sgabeblack@google.com sc_core::sc_time delay; 11813821Sgabeblack@google.com 11913821Sgabeblack@google.com if (phase == tlm::END_REQ || 12013821Sgabeblack@google.com (&trans == blockingRequest && phase == tlm::BEGIN_RESP)) { 12113821Sgabeblack@google.com sc_assert(&trans == blockingRequest); 12213821Sgabeblack@google.com blockingRequest = nullptr; 12313821Sgabeblack@google.com 12413821Sgabeblack@google.com // Did another request arrive while blocked, schedule a retry. 12513821Sgabeblack@google.com if (needToSendRequestRetry) { 12613821Sgabeblack@google.com needToSendRequestRetry = false; 12713821Sgabeblack@google.com bsp.sendRetryReq(); 12813821Sgabeblack@google.com } 12913821Sgabeblack@google.com } 13013821Sgabeblack@google.com if (phase == tlm::BEGIN_RESP) { 13113821Sgabeblack@google.com auto &extension = Gem5SystemC::Gem5Extension::getExtension(trans); 13213821Sgabeblack@google.com auto packet = extension.getPacket(); 13313821Sgabeblack@google.com 13413821Sgabeblack@google.com sc_assert(!blockingResponse); 13513821Sgabeblack@google.com 13613821Sgabeblack@google.com bool need_retry = false; 13713821Sgabeblack@google.com 13813821Sgabeblack@google.com /* 13913821Sgabeblack@google.com * If the packet was piped through and needs a response, we don't need 14013821Sgabeblack@google.com * to touch the packet and can forward it directly as a response. 14113821Sgabeblack@google.com * Otherwise, we need to make a response and send the transformed 14213821Sgabeblack@google.com * packet. 14313821Sgabeblack@google.com */ 14413821Sgabeblack@google.com if (extension.isPipeThrough()) { 14513821Sgabeblack@google.com if (packet->isResponse()) { 14613821Sgabeblack@google.com need_retry = !bsp.sendTimingResp(packet); 14713821Sgabeblack@google.com } 14813821Sgabeblack@google.com } else if (packet->needsResponse()) { 14913821Sgabeblack@google.com packet->makeResponse(); 15013821Sgabeblack@google.com need_retry = !bsp.sendTimingResp(packet); 15113821Sgabeblack@google.com } 15213821Sgabeblack@google.com 15313821Sgabeblack@google.com if (need_retry) { 15413821Sgabeblack@google.com blockingResponse = &trans; 15513821Sgabeblack@google.com } else { 15613821Sgabeblack@google.com if (phase == tlm::BEGIN_RESP) { 15713821Sgabeblack@google.com // Send END_RESP and we're finished: 15813821Sgabeblack@google.com tlm::tlm_phase fw_phase = tlm::END_RESP; 15913821Sgabeblack@google.com sc_core::sc_time delay = sc_core::SC_ZERO_TIME; 16013821Sgabeblack@google.com socket->nb_transport_fw(trans, fw_phase, delay); 16113821Sgabeblack@google.com // Release the transaction with all the extensions. 16213821Sgabeblack@google.com trans.release(); 16313821Sgabeblack@google.com } 16413821Sgabeblack@google.com } 16513821Sgabeblack@google.com } 16613821Sgabeblack@google.com delete pe; 16713821Sgabeblack@google.com} 16813821Sgabeblack@google.com 16913821Sgabeblack@google.com// Similar to TLM's blocking transport (LT) 17013823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 17113821Sgabeblack@google.comTick 17213823Sgabeblack@google.comGem5ToTlmBridge<BITWIDTH>::recvAtomic(PacketPtr packet) 17313821Sgabeblack@google.com{ 17413821Sgabeblack@google.com panic_if(packet->cacheResponding(), 17513821Sgabeblack@google.com "Should not see packets where cache is responding"); 17613821Sgabeblack@google.com 17713821Sgabeblack@google.com panic_if(!(packet->isRead() || packet->isWrite()), 17813821Sgabeblack@google.com "Should only see read and writes at TLM memory\n"); 17913821Sgabeblack@google.com 18013821Sgabeblack@google.com sc_core::sc_time delay = sc_core::SC_ZERO_TIME; 18113821Sgabeblack@google.com 18213821Sgabeblack@google.com // Prepare the transaction. 18313821Sgabeblack@google.com tlm::tlm_generic_payload *trans = mm.allocate(); 18413821Sgabeblack@google.com trans->acquire(); 18513821Sgabeblack@google.com packet2payload(packet, *trans); 18613821Sgabeblack@google.com 18713821Sgabeblack@google.com // Attach the packet pointer to the TLM transaction to keep track. 18813821Sgabeblack@google.com auto *extension = new Gem5SystemC::Gem5Extension(packet); 18913821Sgabeblack@google.com trans->set_auto_extension(extension); 19013821Sgabeblack@google.com 19113821Sgabeblack@google.com // Execute b_transport: 19213821Sgabeblack@google.com if (packet->cmd == MemCmd::SwapReq) { 19313821Sgabeblack@google.com SC_REPORT_FATAL("Gem5ToTlmBridge", "SwapReq not supported"); 19413821Sgabeblack@google.com } else if (packet->isRead()) { 19513821Sgabeblack@google.com socket->b_transport(*trans, delay); 19613821Sgabeblack@google.com } else if (packet->isInvalidate()) { 19713821Sgabeblack@google.com // do nothing 19813821Sgabeblack@google.com } else if (packet->isWrite()) { 19913821Sgabeblack@google.com socket->b_transport(*trans, delay); 20013821Sgabeblack@google.com } else { 20113821Sgabeblack@google.com SC_REPORT_FATAL("Gem5ToTlmBridge", "Typo of request not supported"); 20213821Sgabeblack@google.com } 20313821Sgabeblack@google.com 20413821Sgabeblack@google.com if (packet->needsResponse()) { 20513821Sgabeblack@google.com packet->makeResponse(); 20613821Sgabeblack@google.com } 20713821Sgabeblack@google.com 20813821Sgabeblack@google.com trans->release(); 20913821Sgabeblack@google.com 21013821Sgabeblack@google.com return delay.value(); 21113821Sgabeblack@google.com} 21213821Sgabeblack@google.com 21313823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 21413821Sgabeblack@google.comvoid 21513823Sgabeblack@google.comGem5ToTlmBridge<BITWIDTH>::recvFunctionalSnoop(PacketPtr packet) 21613821Sgabeblack@google.com{ 21713821Sgabeblack@google.com // Snooping should be implemented with tlm_dbg_transport. 21813821Sgabeblack@google.com SC_REPORT_FATAL("Gem5ToTlmBridge", 21913821Sgabeblack@google.com "unimplemented func.: recvFunctionalSnoop"); 22013821Sgabeblack@google.com} 22113821Sgabeblack@google.com 22213821Sgabeblack@google.com// Similar to TLM's non-blocking transport (AT). 22313823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 22413821Sgabeblack@google.combool 22513823Sgabeblack@google.comGem5ToTlmBridge<BITWIDTH>::recvTimingReq(PacketPtr packet) 22613821Sgabeblack@google.com{ 22713821Sgabeblack@google.com panic_if(packet->cacheResponding(), 22813821Sgabeblack@google.com "Should not see packets where cache is responding"); 22913821Sgabeblack@google.com 23013821Sgabeblack@google.com panic_if(!(packet->isRead() || packet->isWrite()), 23113821Sgabeblack@google.com "Should only see read and writes at TLM memory\n"); 23213821Sgabeblack@google.com 23313821Sgabeblack@google.com 23413821Sgabeblack@google.com // We should never get a second request after noting that a retry is 23513821Sgabeblack@google.com // required. 23613821Sgabeblack@google.com sc_assert(!needToSendRequestRetry); 23713821Sgabeblack@google.com 23813821Sgabeblack@google.com // Remember if a request comes in while we're blocked so that a retry 23913821Sgabeblack@google.com // can be sent to gem5. 24013821Sgabeblack@google.com if (blockingRequest) { 24113821Sgabeblack@google.com needToSendRequestRetry = true; 24213821Sgabeblack@google.com return false; 24313821Sgabeblack@google.com } 24413821Sgabeblack@google.com 24513821Sgabeblack@google.com /* 24613821Sgabeblack@google.com * NOTE: normal tlm is blocking here. But in our case we return false 24713821Sgabeblack@google.com * and tell gem5 when a retry can be done. This is the main difference 24813821Sgabeblack@google.com * in the protocol: 24913821Sgabeblack@google.com * if (requestInProgress) 25013821Sgabeblack@google.com * { 25113821Sgabeblack@google.com * wait(endRequestEvent); 25213821Sgabeblack@google.com * } 25313821Sgabeblack@google.com * requestInProgress = trans; 25413821Sgabeblack@google.com */ 25513821Sgabeblack@google.com 25613821Sgabeblack@google.com // Prepare the transaction. 25713821Sgabeblack@google.com tlm::tlm_generic_payload *trans = mm.allocate(); 25813821Sgabeblack@google.com trans->acquire(); 25913821Sgabeblack@google.com packet2payload(packet, *trans); 26013821Sgabeblack@google.com 26113821Sgabeblack@google.com // Attach the packet pointer to the TLM transaction to keep track. 26213821Sgabeblack@google.com auto *extension = new Gem5SystemC::Gem5Extension(packet); 26313821Sgabeblack@google.com trans->set_auto_extension(extension); 26413821Sgabeblack@google.com 26513821Sgabeblack@google.com /* 26613821Sgabeblack@google.com * Pay for annotated transport delays. 26713821Sgabeblack@google.com * 26813821Sgabeblack@google.com * The header delay marks the point in time, when the packet first is seen 26913821Sgabeblack@google.com * by the transactor. This is the point in time when the transactor needs 27013821Sgabeblack@google.com * to send the BEGIN_REQ to the SystemC world. 27113821Sgabeblack@google.com * 27213821Sgabeblack@google.com * NOTE: We drop the payload delay here. Normally, the receiver would be 27313821Sgabeblack@google.com * responsible for handling the payload delay. In this case, however, 27413821Sgabeblack@google.com * the receiver is a SystemC module and has no notion of the gem5 27513821Sgabeblack@google.com * transport protocol and we cannot simply forward the 27613821Sgabeblack@google.com * payload delay to the receiving module. Instead, we expect the 27713821Sgabeblack@google.com * receiving SystemC module to model the payload delay by deferring 27813821Sgabeblack@google.com * the END_REQ. This could lead to incorrect delays, if the XBar 27913821Sgabeblack@google.com * payload delay is longer than the time the receiver needs to accept 28013821Sgabeblack@google.com * the request (time between BEGIN_REQ and END_REQ). 28113821Sgabeblack@google.com * 28213821Sgabeblack@google.com * TODO: We could detect the case described above by remembering the 28313821Sgabeblack@google.com * payload delay and comparing it to the time between BEGIN_REQ and 28413821Sgabeblack@google.com * END_REQ. Then, a warning should be printed. 28513821Sgabeblack@google.com */ 28613821Sgabeblack@google.com auto delay = sc_core::sc_time::from_value(packet->payloadDelay); 28713821Sgabeblack@google.com // Reset the delays 28813821Sgabeblack@google.com packet->payloadDelay = 0; 28913821Sgabeblack@google.com packet->headerDelay = 0; 29013821Sgabeblack@google.com 29113821Sgabeblack@google.com // Starting TLM non-blocking sequence (AT) Refer to IEEE1666-2011 SystemC 29213821Sgabeblack@google.com // Standard Page 507 for a visualisation of the procedure. 29313821Sgabeblack@google.com tlm::tlm_phase phase = tlm::BEGIN_REQ; 29413821Sgabeblack@google.com tlm::tlm_sync_enum status; 29513821Sgabeblack@google.com status = socket->nb_transport_fw(*trans, phase, delay); 29613821Sgabeblack@google.com // Check returned value: 29713821Sgabeblack@google.com if (status == tlm::TLM_ACCEPTED) { 29813821Sgabeblack@google.com sc_assert(phase == tlm::BEGIN_REQ); 29913821Sgabeblack@google.com // Accepted but is now blocking until END_REQ (exclusion rule). 30013821Sgabeblack@google.com blockingRequest = trans; 30113821Sgabeblack@google.com } else if (status == tlm::TLM_UPDATED) { 30213821Sgabeblack@google.com // The Timing annotation must be honored: 30313821Sgabeblack@google.com sc_assert(phase == tlm::END_REQ || phase == tlm::BEGIN_RESP); 30413821Sgabeblack@google.com 30513821Sgabeblack@google.com auto *pe = new Gem5SystemC::PayloadEvent<Gem5ToTlmBridge>( 30613821Sgabeblack@google.com *this, &Gem5ToTlmBridge::pec, "PEQ"); 30713821Sgabeblack@google.com Tick nextEventTick = curTick() + delay.value(); 30813821Sgabeblack@google.com system->wakeupEventQueue(nextEventTick); 30913821Sgabeblack@google.com system->schedule(pe, nextEventTick); 31013821Sgabeblack@google.com } else if (status == tlm::TLM_COMPLETED) { 31113821Sgabeblack@google.com // Transaction is over nothing has do be done. 31213821Sgabeblack@google.com sc_assert(phase == tlm::END_RESP); 31313821Sgabeblack@google.com trans->release(); 31413821Sgabeblack@google.com } 31513821Sgabeblack@google.com 31613821Sgabeblack@google.com return true; 31713821Sgabeblack@google.com} 31813821Sgabeblack@google.com 31913823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 32013821Sgabeblack@google.combool 32113823Sgabeblack@google.comGem5ToTlmBridge<BITWIDTH>::recvTimingSnoopResp(PacketPtr packet) 32213821Sgabeblack@google.com{ 32313821Sgabeblack@google.com // Snooping should be implemented with tlm_dbg_transport. 32413821Sgabeblack@google.com SC_REPORT_FATAL("Gem5ToTlmBridge", 32513821Sgabeblack@google.com "unimplemented func.: recvTimingSnoopResp"); 32613821Sgabeblack@google.com return false; 32713821Sgabeblack@google.com} 32813821Sgabeblack@google.com 32913823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 33013821Sgabeblack@google.combool 33113823Sgabeblack@google.comGem5ToTlmBridge<BITWIDTH>::tryTiming(PacketPtr packet) 33213821Sgabeblack@google.com{ 33313821Sgabeblack@google.com panic("tryTiming(PacketPtr) isn't implemented."); 33413821Sgabeblack@google.com} 33513821Sgabeblack@google.com 33613823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 33713821Sgabeblack@google.comvoid 33813823Sgabeblack@google.comGem5ToTlmBridge<BITWIDTH>::recvRespRetry() 33913821Sgabeblack@google.com{ 34013821Sgabeblack@google.com /* Retry a response */ 34113821Sgabeblack@google.com sc_assert(blockingResponse); 34213821Sgabeblack@google.com 34313821Sgabeblack@google.com tlm::tlm_generic_payload *trans = blockingResponse; 34413821Sgabeblack@google.com blockingResponse = nullptr; 34513821Sgabeblack@google.com PacketPtr packet = 34613821Sgabeblack@google.com Gem5SystemC::Gem5Extension::getExtension(trans).getPacket(); 34713821Sgabeblack@google.com 34813821Sgabeblack@google.com bool need_retry = !bsp.sendTimingResp(packet); 34913821Sgabeblack@google.com 35013821Sgabeblack@google.com sc_assert(!need_retry); 35113821Sgabeblack@google.com 35213821Sgabeblack@google.com sc_core::sc_time delay = sc_core::SC_ZERO_TIME; 35313821Sgabeblack@google.com tlm::tlm_phase phase = tlm::END_RESP; 35413821Sgabeblack@google.com socket->nb_transport_fw(*trans, phase, delay); 35513821Sgabeblack@google.com // Release transaction with all the extensions 35613821Sgabeblack@google.com trans->release(); 35713821Sgabeblack@google.com} 35813821Sgabeblack@google.com 35913821Sgabeblack@google.com// Similar to TLM's debug transport. 36013823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 36113821Sgabeblack@google.comvoid 36213823Sgabeblack@google.comGem5ToTlmBridge<BITWIDTH>::recvFunctional(PacketPtr packet) 36313821Sgabeblack@google.com{ 36413821Sgabeblack@google.com // Prepare the transaction. 36513821Sgabeblack@google.com tlm::tlm_generic_payload *trans = mm.allocate(); 36613821Sgabeblack@google.com trans->acquire(); 36713821Sgabeblack@google.com packet2payload(packet, *trans); 36813821Sgabeblack@google.com 36913821Sgabeblack@google.com // Attach the packet pointer to the TLM transaction to keep track. 37013821Sgabeblack@google.com auto *extension = new Gem5SystemC::Gem5Extension(packet); 37113821Sgabeblack@google.com trans->set_auto_extension(extension); 37213821Sgabeblack@google.com 37313821Sgabeblack@google.com /* Execute Debug Transport: */ 37413821Sgabeblack@google.com unsigned int bytes = socket->transport_dbg(*trans); 37513821Sgabeblack@google.com if (bytes != trans->get_data_length()) { 37613821Sgabeblack@google.com SC_REPORT_FATAL("Gem5ToTlmBridge", 37713821Sgabeblack@google.com "debug transport was not completed"); 37813821Sgabeblack@google.com } 37913821Sgabeblack@google.com 38013821Sgabeblack@google.com trans->release(); 38113821Sgabeblack@google.com} 38213821Sgabeblack@google.com 38313823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 38413821Sgabeblack@google.comtlm::tlm_sync_enum 38513823Sgabeblack@google.comGem5ToTlmBridge<BITWIDTH>::nb_transport_bw(tlm::tlm_generic_payload &trans, 38613821Sgabeblack@google.com tlm::tlm_phase &phase, sc_core::sc_time &delay) 38713821Sgabeblack@google.com{ 38813821Sgabeblack@google.com auto *pe = new Gem5SystemC::PayloadEvent<Gem5ToTlmBridge>( 38913821Sgabeblack@google.com *this, &Gem5ToTlmBridge::pec, "PE"); 39013821Sgabeblack@google.com Tick nextEventTick = curTick() + delay.value(); 39113821Sgabeblack@google.com system->wakeupEventQueue(nextEventTick); 39213821Sgabeblack@google.com system->schedule(pe, nextEventTick); 39313821Sgabeblack@google.com return tlm::TLM_ACCEPTED; 39413821Sgabeblack@google.com} 39513821Sgabeblack@google.com 39613823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 39713823Sgabeblack@google.comGem5ToTlmBridge<BITWIDTH>::Gem5ToTlmBridge( 39813821Sgabeblack@google.com Params *params, const sc_core::sc_module_name &mn) : 39913823Sgabeblack@google.com Gem5ToTlmBridgeBase(mn), bsp(std::string(name()) + ".gem5", *this), 40013821Sgabeblack@google.com socket("tlm_socket"), 40113821Sgabeblack@google.com wrapper(socket, std::string(name()) + ".tlm", InvalidPortID), 40213821Sgabeblack@google.com system(params->system), blockingRequest(nullptr), 40313821Sgabeblack@google.com needToSendRequestRetry(false), blockingResponse(nullptr), 40413821Sgabeblack@google.com addrRanges(params->addr_ranges.begin(), params->addr_ranges.end()) 40513821Sgabeblack@google.com{ 40613821Sgabeblack@google.com} 40713821Sgabeblack@google.com 40813823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 40913821Sgabeblack@google.com::Port & 41013823Sgabeblack@google.comGem5ToTlmBridge<BITWIDTH>::gem5_getPort(const std::string &if_name, int idx) 41113821Sgabeblack@google.com{ 41213821Sgabeblack@google.com if (if_name == "gem5") 41313821Sgabeblack@google.com return bsp; 41413821Sgabeblack@google.com else if (if_name == "tlm") 41513821Sgabeblack@google.com return wrapper; 41613821Sgabeblack@google.com 41713821Sgabeblack@google.com return sc_core::sc_module::gem5_getPort(if_name, idx); 41813821Sgabeblack@google.com} 41913821Sgabeblack@google.com 42013823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 42113821Sgabeblack@google.comvoid 42213823Sgabeblack@google.comGem5ToTlmBridge<BITWIDTH>::before_end_of_elaboration() 42313821Sgabeblack@google.com{ 42413821Sgabeblack@google.com bsp.sendRangeChange(); 42513821Sgabeblack@google.com 42613821Sgabeblack@google.com socket.register_nb_transport_bw(this, &Gem5ToTlmBridge::nb_transport_bw); 42713821Sgabeblack@google.com sc_core::sc_module::before_end_of_elaboration(); 42813821Sgabeblack@google.com} 42913821Sgabeblack@google.com 43013821Sgabeblack@google.com} // namespace sc_gem5 43113821Sgabeblack@google.com 43213823Sgabeblack@google.comsc_gem5::Gem5ToTlmBridge<32> * 43313823Sgabeblack@google.comGem5ToTlmBridge32Params::create() 43413821Sgabeblack@google.com{ 43513823Sgabeblack@google.com return new sc_gem5::Gem5ToTlmBridge<32>( 43613821Sgabeblack@google.com this, sc_core::sc_module_name(name.c_str())); 43713821Sgabeblack@google.com} 43813823Sgabeblack@google.com 43913823Sgabeblack@google.comsc_gem5::Gem5ToTlmBridge<64> * 44013823Sgabeblack@google.comGem5ToTlmBridge64Params::create() 44113823Sgabeblack@google.com{ 44213823Sgabeblack@google.com return new sc_gem5::Gem5ToTlmBridge<64>( 44313823Sgabeblack@google.com this, sc_core::sc_module_name(name.c_str())); 44413823Sgabeblack@google.com} 445