tlm_to_gem5.cc revision 14275
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) 2016, Dresden University of Technology (TU Dresden) 2813821Sgabeblack@google.com * All rights reserved. 2913821Sgabeblack@google.com * 3013821Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 3113821Sgabeblack@google.com * modification, are permitted provided that the following conditions are 3213821Sgabeblack@google.com * met: 3313821Sgabeblack@google.com * 3413821Sgabeblack@google.com * 1. Redistributions of source code must retain the above copyright notice, 3513821Sgabeblack@google.com * this list of conditions and the following disclaimer. 3613821Sgabeblack@google.com * 3713821Sgabeblack@google.com * 2. Redistributions in binary form must reproduce the above copyright 3813821Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 3913821Sgabeblack@google.com * documentation and/or other materials provided with the distribution. 4013821Sgabeblack@google.com * 4113821Sgabeblack@google.com * 3. Neither the name of the copyright holder nor the names of its 4213821Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 4313821Sgabeblack@google.com * this software without specific prior written permission. 4413821Sgabeblack@google.com * 4513821Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 4613821Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 4713821Sgabeblack@google.com * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4813821Sgabeblack@google.com * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 4913821Sgabeblack@google.com * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 5013821Sgabeblack@google.com * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 5113821Sgabeblack@google.com * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 5213821Sgabeblack@google.com * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 5313821Sgabeblack@google.com * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 5413821Sgabeblack@google.com * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 5513821Sgabeblack@google.com * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 5613821Sgabeblack@google.com * 5713821Sgabeblack@google.com * Authors: Gabe Black 5813821Sgabeblack@google.com * Christian Menard 5913821Sgabeblack@google.com */ 6013821Sgabeblack@google.com 6113821Sgabeblack@google.com#include "systemc/tlm_bridge/tlm_to_gem5.hh" 6213821Sgabeblack@google.com 6313823Sgabeblack@google.com#include "params/TlmToGem5Bridge32.hh" 6413823Sgabeblack@google.com#include "params/TlmToGem5Bridge64.hh" 6513821Sgabeblack@google.com#include "sim/system.hh" 6613821Sgabeblack@google.com#include "systemc/ext/core/sc_module_name.hh" 6713846Sgabeblack@google.com#include "systemc/ext/core/sc_time.hh" 6813821Sgabeblack@google.com 6913821Sgabeblack@google.comnamespace sc_gem5 7013821Sgabeblack@google.com{ 7113821Sgabeblack@google.com 7214275Sgabeblack@google.comPacketPtr 7314275Sgabeblack@google.compayload2packet(MasterID masterId, tlm::tlm_generic_payload &trans) 7414275Sgabeblack@google.com{ 7514275Sgabeblack@google.com MemCmd cmd; 7614275Sgabeblack@google.com 7714275Sgabeblack@google.com switch (trans.get_command()) { 7814275Sgabeblack@google.com case tlm::TLM_READ_COMMAND: 7914275Sgabeblack@google.com cmd = MemCmd::ReadReq; 8014275Sgabeblack@google.com break; 8114275Sgabeblack@google.com case tlm::TLM_WRITE_COMMAND: 8214275Sgabeblack@google.com cmd = MemCmd::WriteReq; 8314275Sgabeblack@google.com break; 8414275Sgabeblack@google.com case tlm::TLM_IGNORE_COMMAND: 8514275Sgabeblack@google.com return nullptr; 8614275Sgabeblack@google.com default: 8714275Sgabeblack@google.com SC_REPORT_FATAL("TlmToGem5Bridge", 8814275Sgabeblack@google.com "received transaction with unsupported command"); 8914275Sgabeblack@google.com } 9014275Sgabeblack@google.com 9114275Sgabeblack@google.com Request::Flags flags; 9214275Sgabeblack@google.com auto req = std::make_shared<Request>( 9314275Sgabeblack@google.com trans.get_address(), trans.get_data_length(), flags, masterId); 9414275Sgabeblack@google.com 9514275Sgabeblack@google.com /* 9614275Sgabeblack@google.com * Allocate a new Packet. The packet will be deleted when it returns from 9714275Sgabeblack@google.com * the gem5 world as a response. 9814275Sgabeblack@google.com */ 9914275Sgabeblack@google.com auto pkt = new Packet(req, cmd); 10014275Sgabeblack@google.com pkt->dataStatic(trans.get_data_ptr()); 10114275Sgabeblack@google.com 10214275Sgabeblack@google.com return pkt; 10314275Sgabeblack@google.com} 10414275Sgabeblack@google.com 10513823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 10613821Sgabeblack@google.comvoid 10713823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::sendEndReq(tlm::tlm_generic_payload &trans) 10813821Sgabeblack@google.com{ 10913821Sgabeblack@google.com tlm::tlm_phase phase = tlm::END_REQ; 11013821Sgabeblack@google.com auto delay = sc_core::SC_ZERO_TIME; 11113821Sgabeblack@google.com 11213821Sgabeblack@google.com auto status = socket->nb_transport_bw(trans, phase, delay); 11313821Sgabeblack@google.com panic_if(status != tlm::TLM_ACCEPTED, 11413821Sgabeblack@google.com "Unexpected status after sending END_REQ"); 11513821Sgabeblack@google.com} 11613821Sgabeblack@google.com 11713823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 11813821Sgabeblack@google.comvoid 11913823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::sendBeginResp(tlm::tlm_generic_payload &trans, 12013823Sgabeblack@google.com sc_core::sc_time &delay) 12113821Sgabeblack@google.com{ 12213821Sgabeblack@google.com tlm::tlm_phase phase = tlm::BEGIN_RESP; 12313821Sgabeblack@google.com 12413821Sgabeblack@google.com trans.set_response_status(tlm::TLM_OK_RESPONSE); 12513821Sgabeblack@google.com 12613821Sgabeblack@google.com auto status = socket->nb_transport_bw(trans, phase, delay); 12713821Sgabeblack@google.com 12813821Sgabeblack@google.com if (status == tlm::TLM_COMPLETED || 12913821Sgabeblack@google.com (status == tlm::TLM_UPDATED && phase == tlm::END_RESP)) { 13013821Sgabeblack@google.com // transaction completed -> no need to wait for tlm::END_RESP 13113821Sgabeblack@google.com responseInProgress = false; 13213821Sgabeblack@google.com } else if (status == tlm::TLM_ACCEPTED) { 13313821Sgabeblack@google.com // we need to wait for tlm::END_RESP 13413821Sgabeblack@google.com responseInProgress = true; 13513821Sgabeblack@google.com } else { 13613821Sgabeblack@google.com panic("Unexpected status after sending BEGIN_RESP"); 13713821Sgabeblack@google.com } 13813821Sgabeblack@google.com} 13913821Sgabeblack@google.com 14013823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 14113821Sgabeblack@google.comvoid 14213823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::handleBeginReq(tlm::tlm_generic_payload &trans) 14313821Sgabeblack@google.com{ 14413821Sgabeblack@google.com sc_assert(!waitForRetry); 14513821Sgabeblack@google.com sc_assert(pendingRequest == nullptr); 14613821Sgabeblack@google.com sc_assert(pendingPacket == nullptr); 14713821Sgabeblack@google.com 14813821Sgabeblack@google.com trans.acquire(); 14913821Sgabeblack@google.com 15013821Sgabeblack@google.com PacketPtr pkt = nullptr; 15113821Sgabeblack@google.com 15213821Sgabeblack@google.com Gem5SystemC::Gem5Extension *extension = nullptr; 15313821Sgabeblack@google.com trans.get_extension(extension); 15413821Sgabeblack@google.com 15513821Sgabeblack@google.com // If there is an extension, this transaction was initiated by the gem5 15613821Sgabeblack@google.com // world and we can pipe through the original packet. Otherwise, we 15713821Sgabeblack@google.com // generate a new packet based on the transaction. 15813821Sgabeblack@google.com if (extension != nullptr) { 15913821Sgabeblack@google.com extension->setPipeThrough(); 16013821Sgabeblack@google.com pkt = extension->getPacket(); 16113821Sgabeblack@google.com } else { 16214275Sgabeblack@google.com pkt = payload2packet(masterId, trans); 16313821Sgabeblack@google.com } 16413821Sgabeblack@google.com 16513821Sgabeblack@google.com auto tlmSenderState = new TlmSenderState(trans); 16613821Sgabeblack@google.com pkt->pushSenderState(tlmSenderState); 16713821Sgabeblack@google.com 16813821Sgabeblack@google.com if (bmp.sendTimingReq(pkt)) { // port is free -> send END_REQ immediately 16913821Sgabeblack@google.com sendEndReq(trans); 17013821Sgabeblack@google.com trans.release(); 17113821Sgabeblack@google.com } else { // port is blocked -> wait for retry before sending END_REQ 17213821Sgabeblack@google.com waitForRetry = true; 17313821Sgabeblack@google.com pendingRequest = &trans; 17413821Sgabeblack@google.com pendingPacket = pkt; 17513821Sgabeblack@google.com } 17613821Sgabeblack@google.com} 17713821Sgabeblack@google.com 17813823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 17913821Sgabeblack@google.comvoid 18013823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::handleEndResp(tlm::tlm_generic_payload &trans) 18113821Sgabeblack@google.com{ 18213821Sgabeblack@google.com sc_assert(responseInProgress); 18313821Sgabeblack@google.com 18413821Sgabeblack@google.com responseInProgress = false; 18513821Sgabeblack@google.com 18613821Sgabeblack@google.com checkTransaction(trans); 18713821Sgabeblack@google.com 18813821Sgabeblack@google.com if (needToSendRetry) { 18913821Sgabeblack@google.com bmp.sendRetryResp(); 19013821Sgabeblack@google.com needToSendRetry = false; 19113821Sgabeblack@google.com } 19213821Sgabeblack@google.com} 19313821Sgabeblack@google.com 19413823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 19513821Sgabeblack@google.comvoid 19613823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::destroyPacket(PacketPtr pkt) 19713821Sgabeblack@google.com{ 19813821Sgabeblack@google.com delete pkt; 19913821Sgabeblack@google.com} 20013821Sgabeblack@google.com 20113823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 20213821Sgabeblack@google.comvoid 20313823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::checkTransaction(tlm::tlm_generic_payload &trans) 20413821Sgabeblack@google.com{ 20513821Sgabeblack@google.com if (trans.is_response_error()) { 20613821Sgabeblack@google.com std::stringstream ss; 20713821Sgabeblack@google.com ss << "Transaction returned with error, response status = " 20813821Sgabeblack@google.com << trans.get_response_string(); 20913821Sgabeblack@google.com SC_REPORT_ERROR("TLM-2", ss.str().c_str()); 21013821Sgabeblack@google.com } 21113821Sgabeblack@google.com} 21213821Sgabeblack@google.com 21313823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 21413821Sgabeblack@google.comvoid 21513846Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::invalidateDmi(const ::MemBackdoor &backdoor) 21613846Sgabeblack@google.com{ 21713846Sgabeblack@google.com socket->invalidate_direct_mem_ptr( 21813846Sgabeblack@google.com backdoor.range().start(), backdoor.range().end()); 21913846Sgabeblack@google.com} 22013846Sgabeblack@google.com 22113846Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 22213846Sgabeblack@google.comvoid 22313823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::peq_cb(tlm::tlm_generic_payload &trans, 22413823Sgabeblack@google.com const tlm::tlm_phase &phase) 22513821Sgabeblack@google.com{ 22613821Sgabeblack@google.com switch (phase) { 22713821Sgabeblack@google.com case tlm::BEGIN_REQ: 22813821Sgabeblack@google.com handleBeginReq(trans); 22913821Sgabeblack@google.com break; 23013821Sgabeblack@google.com case tlm::END_RESP: 23113821Sgabeblack@google.com handleEndResp(trans); 23213821Sgabeblack@google.com break; 23313821Sgabeblack@google.com default: 23413821Sgabeblack@google.com panic("unimplemented phase in callback"); 23513821Sgabeblack@google.com } 23613821Sgabeblack@google.com} 23713821Sgabeblack@google.com 23813823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 23913821Sgabeblack@google.comtlm::tlm_sync_enum 24013823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::nb_transport_fw( 24113821Sgabeblack@google.com tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, 24213821Sgabeblack@google.com sc_core::sc_time &delay) 24313821Sgabeblack@google.com{ 24413821Sgabeblack@google.com unsigned len = trans.get_data_length(); 24513821Sgabeblack@google.com unsigned char *byteEnable = trans.get_byte_enable_ptr(); 24613821Sgabeblack@google.com unsigned width = trans.get_streaming_width(); 24713821Sgabeblack@google.com 24813821Sgabeblack@google.com // check the transaction attributes for unsupported features ... 24913821Sgabeblack@google.com if (byteEnable != 0) { 25013821Sgabeblack@google.com trans.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE); 25113821Sgabeblack@google.com return tlm::TLM_COMPLETED; 25213821Sgabeblack@google.com } 25313821Sgabeblack@google.com if (width < len) { // is this a burst request? 25413821Sgabeblack@google.com trans.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE); 25513821Sgabeblack@google.com return tlm::TLM_COMPLETED; 25613821Sgabeblack@google.com } 25713821Sgabeblack@google.com 25813821Sgabeblack@google.com // ... and queue the valid transaction 25913821Sgabeblack@google.com trans.acquire(); 26013821Sgabeblack@google.com peq.notify(trans, phase, delay); 26113821Sgabeblack@google.com return tlm::TLM_ACCEPTED; 26213821Sgabeblack@google.com} 26313821Sgabeblack@google.com 26413823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 26513821Sgabeblack@google.comvoid 26613823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::b_transport(tlm::tlm_generic_payload &trans, 26713823Sgabeblack@google.com sc_core::sc_time &t) 26813821Sgabeblack@google.com{ 26913821Sgabeblack@google.com Gem5SystemC::Gem5Extension *extension = nullptr; 27013821Sgabeblack@google.com trans.get_extension(extension); 27113821Sgabeblack@google.com 27213821Sgabeblack@google.com PacketPtr pkt = nullptr; 27313821Sgabeblack@google.com 27413821Sgabeblack@google.com // If there is an extension, this transaction was initiated by the gem5 27513821Sgabeblack@google.com // world and we can pipe through the original packet. 27613821Sgabeblack@google.com if (extension != nullptr) { 27713821Sgabeblack@google.com extension->setPipeThrough(); 27813821Sgabeblack@google.com pkt = extension->getPacket(); 27913821Sgabeblack@google.com } else { 28014275Sgabeblack@google.com pkt = payload2packet(masterId, trans); 28113821Sgabeblack@google.com } 28213821Sgabeblack@google.com 28313846Sgabeblack@google.com MemBackdoorPtr backdoor = nullptr; 28413846Sgabeblack@google.com Tick ticks = bmp.sendAtomicBackdoor(pkt, backdoor); 28513846Sgabeblack@google.com if (backdoor) 28613846Sgabeblack@google.com trans.set_dmi_allowed(true); 28713821Sgabeblack@google.com 28813821Sgabeblack@google.com // send an atomic request to gem5 28913821Sgabeblack@google.com panic_if(pkt->needsResponse() && !pkt->isResponse(), 29013821Sgabeblack@google.com "Packet sending failed!\n"); 29113821Sgabeblack@google.com 29213821Sgabeblack@google.com auto delay = 29313821Sgabeblack@google.com sc_core::sc_time((double)(ticks / SimClock::Int::ps), sc_core::SC_PS); 29413821Sgabeblack@google.com 29513821Sgabeblack@google.com // update time 29613821Sgabeblack@google.com t += delay; 29713821Sgabeblack@google.com 29813821Sgabeblack@google.com if (extension == nullptr) 29913821Sgabeblack@google.com destroyPacket(pkt); 30013821Sgabeblack@google.com 30113821Sgabeblack@google.com trans.set_response_status(tlm::TLM_OK_RESPONSE); 30213821Sgabeblack@google.com} 30313821Sgabeblack@google.com 30413823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 30513821Sgabeblack@google.comunsigned int 30613823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::transport_dbg(tlm::tlm_generic_payload &trans) 30713821Sgabeblack@google.com{ 30813821Sgabeblack@google.com Gem5SystemC::Gem5Extension *extension = nullptr; 30913821Sgabeblack@google.com trans.get_extension(extension); 31013821Sgabeblack@google.com 31113821Sgabeblack@google.com // If there is an extension, this transaction was initiated by the gem5 31213821Sgabeblack@google.com // world and we can pipe through the original packet. 31313821Sgabeblack@google.com if (extension != nullptr) { 31413821Sgabeblack@google.com extension->setPipeThrough(); 31513821Sgabeblack@google.com bmp.sendFunctional(extension->getPacket()); 31613821Sgabeblack@google.com } else { 31714275Sgabeblack@google.com auto pkt = payload2packet(masterId, trans); 31813821Sgabeblack@google.com if (pkt) { 31913821Sgabeblack@google.com bmp.sendFunctional(pkt); 32013821Sgabeblack@google.com destroyPacket(pkt); 32113821Sgabeblack@google.com } 32213821Sgabeblack@google.com } 32313821Sgabeblack@google.com 32413821Sgabeblack@google.com return trans.get_data_length(); 32513821Sgabeblack@google.com} 32613821Sgabeblack@google.com 32713823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 32813821Sgabeblack@google.combool 32913823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::get_direct_mem_ptr(tlm::tlm_generic_payload &trans, 33013823Sgabeblack@google.com tlm::tlm_dmi &dmi_data) 33113821Sgabeblack@google.com{ 33213846Sgabeblack@google.com Gem5SystemC::Gem5Extension *extension = nullptr; 33313846Sgabeblack@google.com trans.get_extension(extension); 33413846Sgabeblack@google.com 33513846Sgabeblack@google.com PacketPtr pkt = nullptr; 33613846Sgabeblack@google.com 33713846Sgabeblack@google.com // If there is an extension, this transaction was initiated by the gem5 33813846Sgabeblack@google.com // world and we can pipe through the original packet. 33913846Sgabeblack@google.com if (extension != nullptr) { 34013846Sgabeblack@google.com extension->setPipeThrough(); 34113846Sgabeblack@google.com pkt = extension->getPacket(); 34213846Sgabeblack@google.com } else { 34314275Sgabeblack@google.com pkt = payload2packet(masterId, trans); 34413846Sgabeblack@google.com pkt->req->setFlags(Request::NO_ACCESS); 34513846Sgabeblack@google.com } 34613846Sgabeblack@google.com 34713846Sgabeblack@google.com MemBackdoorPtr backdoor = nullptr; 34813846Sgabeblack@google.com bmp.sendAtomicBackdoor(pkt, backdoor); 34913846Sgabeblack@google.com if (backdoor) { 35013846Sgabeblack@google.com trans.set_dmi_allowed(true); 35113846Sgabeblack@google.com dmi_data.set_dmi_ptr(backdoor->ptr()); 35213846Sgabeblack@google.com dmi_data.set_start_address(backdoor->range().start()); 35313846Sgabeblack@google.com dmi_data.set_end_address(backdoor->range().end()); 35413846Sgabeblack@google.com 35513846Sgabeblack@google.com typedef tlm::tlm_dmi::dmi_access_e access_t; 35613846Sgabeblack@google.com access_t access = tlm::tlm_dmi::DMI_ACCESS_NONE; 35713846Sgabeblack@google.com if (backdoor->readable()) 35813846Sgabeblack@google.com access = (access_t)(access | tlm::tlm_dmi::DMI_ACCESS_READ); 35913846Sgabeblack@google.com if (backdoor->writeable()) 36013846Sgabeblack@google.com access = (access_t)(access | tlm::tlm_dmi::DMI_ACCESS_WRITE); 36113846Sgabeblack@google.com dmi_data.set_granted_access(access); 36213846Sgabeblack@google.com 36313846Sgabeblack@google.com backdoor->addInvalidationCallback( 36413846Sgabeblack@google.com [this](const MemBackdoor &backdoor) 36513846Sgabeblack@google.com { 36613846Sgabeblack@google.com invalidateDmi(backdoor); 36713846Sgabeblack@google.com } 36813846Sgabeblack@google.com ); 36913846Sgabeblack@google.com } 37013846Sgabeblack@google.com 37113846Sgabeblack@google.com if (extension == nullptr) 37213846Sgabeblack@google.com destroyPacket(pkt); 37313846Sgabeblack@google.com 37413846Sgabeblack@google.com trans.set_response_status(tlm::TLM_OK_RESPONSE); 37513846Sgabeblack@google.com 37613846Sgabeblack@google.com return backdoor != nullptr; 37713821Sgabeblack@google.com} 37813821Sgabeblack@google.com 37913823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 38013821Sgabeblack@google.combool 38113823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::recvTimingResp(PacketPtr pkt) 38213821Sgabeblack@google.com{ 38313821Sgabeblack@google.com // exclusion rule 38413821Sgabeblack@google.com // We need to Wait for END_RESP before sending next BEGIN_RESP 38513821Sgabeblack@google.com if (responseInProgress) { 38613821Sgabeblack@google.com sc_assert(!needToSendRetry); 38713821Sgabeblack@google.com needToSendRetry = true; 38813821Sgabeblack@google.com return false; 38913821Sgabeblack@google.com } 39013821Sgabeblack@google.com 39113821Sgabeblack@google.com sc_assert(pkt->isResponse()); 39213821Sgabeblack@google.com 39313821Sgabeblack@google.com /* 39413821Sgabeblack@google.com * Pay for annotated transport delays. 39513821Sgabeblack@google.com * 39613821Sgabeblack@google.com * See recvTimingReq in sc_slave_port.cc for a detailed description. 39713821Sgabeblack@google.com */ 39813821Sgabeblack@google.com auto delay = sc_core::sc_time::from_value(pkt->payloadDelay); 39913821Sgabeblack@google.com // reset the delays 40013821Sgabeblack@google.com pkt->payloadDelay = 0; 40113821Sgabeblack@google.com pkt->headerDelay = 0; 40213821Sgabeblack@google.com 40313821Sgabeblack@google.com auto tlmSenderState = dynamic_cast<TlmSenderState*>(pkt->popSenderState()); 40413821Sgabeblack@google.com sc_assert(tlmSenderState != nullptr); 40513821Sgabeblack@google.com 40613821Sgabeblack@google.com auto &trans = tlmSenderState->trans; 40713821Sgabeblack@google.com 40813821Sgabeblack@google.com Gem5SystemC::Gem5Extension *extension = nullptr; 40913821Sgabeblack@google.com trans.get_extension(extension); 41013821Sgabeblack@google.com 41113821Sgabeblack@google.com // clean up 41213821Sgabeblack@google.com delete tlmSenderState; 41313821Sgabeblack@google.com 41413821Sgabeblack@google.com // If there is an extension the packet was piped through and we must not 41513821Sgabeblack@google.com // delete it. The packet travels back with the transaction. 41613821Sgabeblack@google.com if (extension == nullptr) 41713821Sgabeblack@google.com destroyPacket(pkt); 41813821Sgabeblack@google.com else 41913821Sgabeblack@google.com sc_assert(extension->isPipeThrough()); 42013821Sgabeblack@google.com 42113821Sgabeblack@google.com sendBeginResp(trans, delay); 42213821Sgabeblack@google.com trans.release(); 42313821Sgabeblack@google.com 42413821Sgabeblack@google.com return true; 42513821Sgabeblack@google.com} 42613821Sgabeblack@google.com 42713823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 42813821Sgabeblack@google.comvoid 42913823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::recvReqRetry() 43013821Sgabeblack@google.com{ 43113821Sgabeblack@google.com sc_assert(waitForRetry); 43213821Sgabeblack@google.com sc_assert(pendingRequest != nullptr); 43313821Sgabeblack@google.com sc_assert(pendingPacket != nullptr); 43413821Sgabeblack@google.com 43513821Sgabeblack@google.com if (bmp.sendTimingReq(pendingPacket)) { 43613821Sgabeblack@google.com waitForRetry = false; 43713821Sgabeblack@google.com pendingPacket = nullptr; 43813821Sgabeblack@google.com 43913821Sgabeblack@google.com auto &trans = *pendingRequest; 44013821Sgabeblack@google.com sendEndReq(trans); 44113821Sgabeblack@google.com trans.release(); 44213821Sgabeblack@google.com 44313821Sgabeblack@google.com pendingRequest = nullptr; 44413821Sgabeblack@google.com } 44513821Sgabeblack@google.com} 44613821Sgabeblack@google.com 44713823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 44813821Sgabeblack@google.comvoid 44913823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::recvRangeChange() 45013821Sgabeblack@google.com{ 45113821Sgabeblack@google.com SC_REPORT_WARNING("TlmToGem5Bridge", 45213821Sgabeblack@google.com "received address range change but ignored it"); 45313821Sgabeblack@google.com} 45413821Sgabeblack@google.com 45513823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 45613821Sgabeblack@google.com::Port & 45713823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::gem5_getPort(const std::string &if_name, int idx) 45813821Sgabeblack@google.com{ 45913821Sgabeblack@google.com if (if_name == "gem5") 46013821Sgabeblack@google.com return bmp; 46113821Sgabeblack@google.com else if (if_name == "tlm") 46213821Sgabeblack@google.com return wrapper; 46313821Sgabeblack@google.com 46413821Sgabeblack@google.com return sc_core::sc_module::gem5_getPort(if_name, idx); 46513821Sgabeblack@google.com} 46613821Sgabeblack@google.com 46713823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 46813823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::TlmToGem5Bridge( 46913821Sgabeblack@google.com Params *params, const sc_core::sc_module_name &mn) : 47013823Sgabeblack@google.com TlmToGem5BridgeBase(mn), peq(this, &TlmToGem5Bridge<BITWIDTH>::peq_cb), 47113821Sgabeblack@google.com waitForRetry(false), pendingRequest(nullptr), pendingPacket(nullptr), 47213821Sgabeblack@google.com needToSendRetry(false), responseInProgress(false), 47313821Sgabeblack@google.com bmp(std::string(name()) + "master", *this), socket("tlm_socket"), 47413821Sgabeblack@google.com wrapper(socket, std::string(name()) + ".tlm", InvalidPortID), 47513821Sgabeblack@google.com system(params->system), 47613821Sgabeblack@google.com masterId(params->system->getGlobalMasterId( 47713821Sgabeblack@google.com std::string("[systemc].") + name())) 47813821Sgabeblack@google.com{ 47913821Sgabeblack@google.com} 48013821Sgabeblack@google.com 48113823Sgabeblack@google.comtemplate <unsigned int BITWIDTH> 48213821Sgabeblack@google.comvoid 48313823Sgabeblack@google.comTlmToGem5Bridge<BITWIDTH>::before_end_of_elaboration() 48413821Sgabeblack@google.com{ 48513821Sgabeblack@google.com /* 48613821Sgabeblack@google.com * Register the TLM non-blocking interface when using gem5 Timing mode and 48713821Sgabeblack@google.com * the TLM blocking interface when using the gem5 Atomic mode. 48813821Sgabeblack@google.com * Then the magic (TM) in simple_target_socket automatically transforms 48913821Sgabeblack@google.com * non-blocking in blocking transactions and vice versa. 49013821Sgabeblack@google.com * 49113821Sgabeblack@google.com * NOTE: The mode may change during execution. 49213821Sgabeblack@google.com */ 49313821Sgabeblack@google.com if (system->isTimingMode()) { 49413821Sgabeblack@google.com SC_REPORT_INFO("TlmToGem5Bridge", "register non-blocking interface"); 49513821Sgabeblack@google.com socket.register_nb_transport_fw( 49613823Sgabeblack@google.com this, &TlmToGem5Bridge<BITWIDTH>::nb_transport_fw); 49713821Sgabeblack@google.com } else if (system->isAtomicMode()) { 49813821Sgabeblack@google.com SC_REPORT_INFO("TlmToGem5Bridge", "register blocking interface"); 49913821Sgabeblack@google.com socket.register_b_transport( 50013823Sgabeblack@google.com this, &TlmToGem5Bridge<BITWIDTH>::b_transport); 50113846Sgabeblack@google.com socket.register_get_direct_mem_ptr( 50213846Sgabeblack@google.com this, &TlmToGem5Bridge<BITWIDTH>::get_direct_mem_ptr); 50313821Sgabeblack@google.com } else { 50413821Sgabeblack@google.com panic("gem5 operates neither in Timing nor in Atomic mode"); 50513821Sgabeblack@google.com } 50613821Sgabeblack@google.com 50713823Sgabeblack@google.com socket.register_transport_dbg( 50813823Sgabeblack@google.com this, &TlmToGem5Bridge<BITWIDTH>::transport_dbg); 50913821Sgabeblack@google.com 51013821Sgabeblack@google.com sc_core::sc_module::before_end_of_elaboration(); 51113821Sgabeblack@google.com} 51213821Sgabeblack@google.com 51313821Sgabeblack@google.com} // namespace sc_gem5 51413821Sgabeblack@google.com 51513823Sgabeblack@google.comsc_gem5::TlmToGem5Bridge<32> * 51613823Sgabeblack@google.comTlmToGem5Bridge32Params::create() 51713821Sgabeblack@google.com{ 51813823Sgabeblack@google.com return new sc_gem5::TlmToGem5Bridge<32>( 51913821Sgabeblack@google.com this, sc_core::sc_module_name(name.c_str())); 52013821Sgabeblack@google.com} 52113823Sgabeblack@google.com 52213823Sgabeblack@google.comsc_gem5::TlmToGem5Bridge<64> * 52313823Sgabeblack@google.comTlmToGem5Bridge64Params::create() 52413823Sgabeblack@google.com{ 52513823Sgabeblack@google.com return new sc_gem5::TlmToGem5Bridge<64>( 52613823Sgabeblack@google.com this, sc_core::sc_module_name(name.c_str())); 52713823Sgabeblack@google.com} 528