tlm_to_gem5.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) 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
6313821Sgabeblack@google.com#include "sim/system.hh"
6413821Sgabeblack@google.com#include "systemc/ext/core/sc_module_name.hh"
6513821Sgabeblack@google.com
6613821Sgabeblack@google.comnamespace sc_gem5
6713821Sgabeblack@google.com{
6813821Sgabeblack@google.com
6913821Sgabeblack@google.comvoid
7013821Sgabeblack@google.comTlmToGem5Bridge::sendEndReq(tlm::tlm_generic_payload &trans)
7113821Sgabeblack@google.com{
7213821Sgabeblack@google.com    tlm::tlm_phase phase = tlm::END_REQ;
7313821Sgabeblack@google.com    auto delay = sc_core::SC_ZERO_TIME;
7413821Sgabeblack@google.com
7513821Sgabeblack@google.com    auto status = socket->nb_transport_bw(trans, phase, delay);
7613821Sgabeblack@google.com    panic_if(status != tlm::TLM_ACCEPTED,
7713821Sgabeblack@google.com             "Unexpected status after sending END_REQ");
7813821Sgabeblack@google.com}
7913821Sgabeblack@google.com
8013821Sgabeblack@google.comvoid
8113821Sgabeblack@google.comTlmToGem5Bridge::sendBeginResp(tlm::tlm_generic_payload &trans,
8213821Sgabeblack@google.com                               sc_core::sc_time &delay)
8313821Sgabeblack@google.com{
8413821Sgabeblack@google.com    tlm::tlm_phase phase = tlm::BEGIN_RESP;
8513821Sgabeblack@google.com
8613821Sgabeblack@google.com    trans.set_response_status(tlm::TLM_OK_RESPONSE);
8713821Sgabeblack@google.com
8813821Sgabeblack@google.com    auto status = socket->nb_transport_bw(trans, phase, delay);
8913821Sgabeblack@google.com
9013821Sgabeblack@google.com    if (status == tlm::TLM_COMPLETED ||
9113821Sgabeblack@google.com        (status == tlm::TLM_UPDATED && phase == tlm::END_RESP)) {
9213821Sgabeblack@google.com        // transaction completed -> no need to wait for tlm::END_RESP
9313821Sgabeblack@google.com        responseInProgress = false;
9413821Sgabeblack@google.com    } else if (status == tlm::TLM_ACCEPTED) {
9513821Sgabeblack@google.com        // we need to wait for tlm::END_RESP
9613821Sgabeblack@google.com        responseInProgress = true;
9713821Sgabeblack@google.com    } else {
9813821Sgabeblack@google.com        panic("Unexpected status after sending BEGIN_RESP");
9913821Sgabeblack@google.com    }
10013821Sgabeblack@google.com}
10113821Sgabeblack@google.com
10213821Sgabeblack@google.comvoid
10313821Sgabeblack@google.comTlmToGem5Bridge::handleBeginReq(tlm::tlm_generic_payload &trans)
10413821Sgabeblack@google.com{
10513821Sgabeblack@google.com    sc_assert(!waitForRetry);
10613821Sgabeblack@google.com    sc_assert(pendingRequest == nullptr);
10713821Sgabeblack@google.com    sc_assert(pendingPacket == nullptr);
10813821Sgabeblack@google.com
10913821Sgabeblack@google.com    trans.acquire();
11013821Sgabeblack@google.com
11113821Sgabeblack@google.com    PacketPtr pkt = nullptr;
11213821Sgabeblack@google.com
11313821Sgabeblack@google.com    Gem5SystemC::Gem5Extension *extension = nullptr;
11413821Sgabeblack@google.com    trans.get_extension(extension);
11513821Sgabeblack@google.com
11613821Sgabeblack@google.com    // If there is an extension, this transaction was initiated by the gem5
11713821Sgabeblack@google.com    // world and we can pipe through the original packet. Otherwise, we
11813821Sgabeblack@google.com    // generate a new packet based on the transaction.
11913821Sgabeblack@google.com    if (extension != nullptr) {
12013821Sgabeblack@google.com        extension->setPipeThrough();
12113821Sgabeblack@google.com        pkt = extension->getPacket();
12213821Sgabeblack@google.com    } else {
12313821Sgabeblack@google.com        pkt = generatePacket(trans);
12413821Sgabeblack@google.com    }
12513821Sgabeblack@google.com
12613821Sgabeblack@google.com    auto tlmSenderState = new TlmSenderState(trans);
12713821Sgabeblack@google.com    pkt->pushSenderState(tlmSenderState);
12813821Sgabeblack@google.com
12913821Sgabeblack@google.com    if (bmp.sendTimingReq(pkt)) { // port is free -> send END_REQ immediately
13013821Sgabeblack@google.com        sendEndReq(trans);
13113821Sgabeblack@google.com        trans.release();
13213821Sgabeblack@google.com    } else { // port is blocked -> wait for retry before sending END_REQ
13313821Sgabeblack@google.com        waitForRetry = true;
13413821Sgabeblack@google.com        pendingRequest = &trans;
13513821Sgabeblack@google.com        pendingPacket = pkt;
13613821Sgabeblack@google.com    }
13713821Sgabeblack@google.com}
13813821Sgabeblack@google.com
13913821Sgabeblack@google.comvoid
14013821Sgabeblack@google.comTlmToGem5Bridge::handleEndResp(tlm::tlm_generic_payload &trans)
14113821Sgabeblack@google.com{
14213821Sgabeblack@google.com    sc_assert(responseInProgress);
14313821Sgabeblack@google.com
14413821Sgabeblack@google.com    responseInProgress = false;
14513821Sgabeblack@google.com
14613821Sgabeblack@google.com    checkTransaction(trans);
14713821Sgabeblack@google.com
14813821Sgabeblack@google.com    if (needToSendRetry) {
14913821Sgabeblack@google.com        bmp.sendRetryResp();
15013821Sgabeblack@google.com        needToSendRetry = false;
15113821Sgabeblack@google.com    }
15213821Sgabeblack@google.com}
15313821Sgabeblack@google.com
15413821Sgabeblack@google.comPacketPtr
15513821Sgabeblack@google.comTlmToGem5Bridge::generatePacket(tlm::tlm_generic_payload &trans)
15613821Sgabeblack@google.com{
15713821Sgabeblack@google.com    MemCmd cmd;
15813821Sgabeblack@google.com
15913821Sgabeblack@google.com    switch (trans.get_command()) {
16013821Sgabeblack@google.com        case tlm::TLM_READ_COMMAND:
16113821Sgabeblack@google.com            cmd = MemCmd::ReadReq;
16213821Sgabeblack@google.com            break;
16313821Sgabeblack@google.com        case tlm::TLM_WRITE_COMMAND:
16413821Sgabeblack@google.com            cmd = MemCmd::WriteReq;
16513821Sgabeblack@google.com            break;
16613821Sgabeblack@google.com        case tlm::TLM_IGNORE_COMMAND:
16713821Sgabeblack@google.com            return nullptr;
16813821Sgabeblack@google.com        default:
16913821Sgabeblack@google.com            SC_REPORT_FATAL("TlmToGem5Bridge",
17013821Sgabeblack@google.com                            "received transaction with unsupported command");
17113821Sgabeblack@google.com    }
17213821Sgabeblack@google.com
17313821Sgabeblack@google.com    Request::Flags flags;
17413821Sgabeblack@google.com    auto req = std::make_shared<Request>(
17513821Sgabeblack@google.com        trans.get_address(), trans.get_data_length(), flags, masterId);
17613821Sgabeblack@google.com
17713821Sgabeblack@google.com    /*
17813821Sgabeblack@google.com     * Allocate a new Packet. The packet will be deleted when it returns from
17913821Sgabeblack@google.com     * the gem5 world as a response.
18013821Sgabeblack@google.com     */
18113821Sgabeblack@google.com    auto pkt = new Packet(req, cmd);
18213821Sgabeblack@google.com    pkt->dataStatic(trans.get_data_ptr());
18313821Sgabeblack@google.com
18413821Sgabeblack@google.com    return pkt;
18513821Sgabeblack@google.com}
18613821Sgabeblack@google.com
18713821Sgabeblack@google.comvoid
18813821Sgabeblack@google.comTlmToGem5Bridge::destroyPacket(PacketPtr pkt)
18913821Sgabeblack@google.com{
19013821Sgabeblack@google.com    delete pkt;
19113821Sgabeblack@google.com}
19213821Sgabeblack@google.com
19313821Sgabeblack@google.comvoid
19413821Sgabeblack@google.comTlmToGem5Bridge::checkTransaction(tlm::tlm_generic_payload &trans)
19513821Sgabeblack@google.com{
19613821Sgabeblack@google.com    if (trans.is_response_error()) {
19713821Sgabeblack@google.com        std::stringstream ss;
19813821Sgabeblack@google.com        ss << "Transaction returned with error, response status = "
19913821Sgabeblack@google.com           << trans.get_response_string();
20013821Sgabeblack@google.com        SC_REPORT_ERROR("TLM-2", ss.str().c_str());
20113821Sgabeblack@google.com    }
20213821Sgabeblack@google.com}
20313821Sgabeblack@google.com
20413821Sgabeblack@google.comvoid
20513821Sgabeblack@google.comTlmToGem5Bridge::peq_cb(tlm::tlm_generic_payload &trans,
20613821Sgabeblack@google.com                        const tlm::tlm_phase &phase)
20713821Sgabeblack@google.com{
20813821Sgabeblack@google.com    switch (phase) {
20913821Sgabeblack@google.com        case tlm::BEGIN_REQ:
21013821Sgabeblack@google.com            handleBeginReq(trans);
21113821Sgabeblack@google.com            break;
21213821Sgabeblack@google.com        case tlm::END_RESP:
21313821Sgabeblack@google.com            handleEndResp(trans);
21413821Sgabeblack@google.com            break;
21513821Sgabeblack@google.com        default:
21613821Sgabeblack@google.com            panic("unimplemented phase in callback");
21713821Sgabeblack@google.com    }
21813821Sgabeblack@google.com}
21913821Sgabeblack@google.com
22013821Sgabeblack@google.comtlm::tlm_sync_enum
22113821Sgabeblack@google.comTlmToGem5Bridge::nb_transport_fw(
22213821Sgabeblack@google.com        tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase,
22313821Sgabeblack@google.com        sc_core::sc_time &delay)
22413821Sgabeblack@google.com{
22513821Sgabeblack@google.com    unsigned len = trans.get_data_length();
22613821Sgabeblack@google.com    unsigned char *byteEnable = trans.get_byte_enable_ptr();
22713821Sgabeblack@google.com    unsigned width = trans.get_streaming_width();
22813821Sgabeblack@google.com
22913821Sgabeblack@google.com    // check the transaction attributes for unsupported features ...
23013821Sgabeblack@google.com    if (byteEnable != 0) {
23113821Sgabeblack@google.com        trans.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE);
23213821Sgabeblack@google.com        return tlm::TLM_COMPLETED;
23313821Sgabeblack@google.com    }
23413821Sgabeblack@google.com    if (width < len) { // is this a burst request?
23513821Sgabeblack@google.com        trans.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE);
23613821Sgabeblack@google.com        return tlm::TLM_COMPLETED;
23713821Sgabeblack@google.com    }
23813821Sgabeblack@google.com
23913821Sgabeblack@google.com    // ... and queue the valid transaction
24013821Sgabeblack@google.com    trans.acquire();
24113821Sgabeblack@google.com    peq.notify(trans, phase, delay);
24213821Sgabeblack@google.com    return tlm::TLM_ACCEPTED;
24313821Sgabeblack@google.com}
24413821Sgabeblack@google.com
24513821Sgabeblack@google.comvoid
24613821Sgabeblack@google.comTlmToGem5Bridge::b_transport(tlm::tlm_generic_payload &trans,
24713821Sgabeblack@google.com                             sc_core::sc_time &t)
24813821Sgabeblack@google.com{
24913821Sgabeblack@google.com    Gem5SystemC::Gem5Extension *extension = nullptr;
25013821Sgabeblack@google.com    trans.get_extension(extension);
25113821Sgabeblack@google.com
25213821Sgabeblack@google.com    PacketPtr pkt = nullptr;
25313821Sgabeblack@google.com
25413821Sgabeblack@google.com    // If there is an extension, this transaction was initiated by the gem5
25513821Sgabeblack@google.com    // world and we can pipe through the original packet.
25613821Sgabeblack@google.com    if (extension != nullptr) {
25713821Sgabeblack@google.com        extension->setPipeThrough();
25813821Sgabeblack@google.com        pkt = extension->getPacket();
25913821Sgabeblack@google.com    } else {
26013821Sgabeblack@google.com        pkt = generatePacket(trans);
26113821Sgabeblack@google.com    }
26213821Sgabeblack@google.com
26313821Sgabeblack@google.com    Tick ticks = bmp.sendAtomic(pkt);
26413821Sgabeblack@google.com
26513821Sgabeblack@google.com    // send an atomic request to gem5
26613821Sgabeblack@google.com    panic_if(pkt->needsResponse() && !pkt->isResponse(),
26713821Sgabeblack@google.com             "Packet sending failed!\n");
26813821Sgabeblack@google.com
26913821Sgabeblack@google.com    auto delay =
27013821Sgabeblack@google.com      sc_core::sc_time((double)(ticks / SimClock::Int::ps), sc_core::SC_PS);
27113821Sgabeblack@google.com
27213821Sgabeblack@google.com    // update time
27313821Sgabeblack@google.com    t += delay;
27413821Sgabeblack@google.com
27513821Sgabeblack@google.com    if (extension == nullptr)
27613821Sgabeblack@google.com        destroyPacket(pkt);
27713821Sgabeblack@google.com
27813821Sgabeblack@google.com    trans.set_response_status(tlm::TLM_OK_RESPONSE);
27913821Sgabeblack@google.com}
28013821Sgabeblack@google.com
28113821Sgabeblack@google.comunsigned int
28213821Sgabeblack@google.comTlmToGem5Bridge::transport_dbg(tlm::tlm_generic_payload &trans)
28313821Sgabeblack@google.com{
28413821Sgabeblack@google.com    Gem5SystemC::Gem5Extension *extension = nullptr;
28513821Sgabeblack@google.com    trans.get_extension(extension);
28613821Sgabeblack@google.com
28713821Sgabeblack@google.com    // If there is an extension, this transaction was initiated by the gem5
28813821Sgabeblack@google.com    // world and we can pipe through the original packet.
28913821Sgabeblack@google.com    if (extension != nullptr) {
29013821Sgabeblack@google.com        extension->setPipeThrough();
29113821Sgabeblack@google.com        bmp.sendFunctional(extension->getPacket());
29213821Sgabeblack@google.com    } else {
29313821Sgabeblack@google.com        auto pkt = generatePacket(trans);
29413821Sgabeblack@google.com        if (pkt) {
29513821Sgabeblack@google.com            bmp.sendFunctional(pkt);
29613821Sgabeblack@google.com            destroyPacket(pkt);
29713821Sgabeblack@google.com        }
29813821Sgabeblack@google.com    }
29913821Sgabeblack@google.com
30013821Sgabeblack@google.com    return trans.get_data_length();
30113821Sgabeblack@google.com}
30213821Sgabeblack@google.com
30313821Sgabeblack@google.combool
30413821Sgabeblack@google.comTlmToGem5Bridge::get_direct_mem_ptr(tlm::tlm_generic_payload &trans,
30513821Sgabeblack@google.com                                    tlm::tlm_dmi &dmi_data)
30613821Sgabeblack@google.com{
30713821Sgabeblack@google.com    return false;
30813821Sgabeblack@google.com}
30913821Sgabeblack@google.com
31013821Sgabeblack@google.combool
31113821Sgabeblack@google.comTlmToGem5Bridge::recvTimingResp(PacketPtr pkt)
31213821Sgabeblack@google.com{
31313821Sgabeblack@google.com    // exclusion rule
31413821Sgabeblack@google.com    // We need to Wait for END_RESP before sending next BEGIN_RESP
31513821Sgabeblack@google.com    if (responseInProgress) {
31613821Sgabeblack@google.com        sc_assert(!needToSendRetry);
31713821Sgabeblack@google.com        needToSendRetry = true;
31813821Sgabeblack@google.com        return false;
31913821Sgabeblack@google.com    }
32013821Sgabeblack@google.com
32113821Sgabeblack@google.com    sc_assert(pkt->isResponse());
32213821Sgabeblack@google.com
32313821Sgabeblack@google.com    /*
32413821Sgabeblack@google.com     * Pay for annotated transport delays.
32513821Sgabeblack@google.com     *
32613821Sgabeblack@google.com     * See recvTimingReq in sc_slave_port.cc for a detailed description.
32713821Sgabeblack@google.com     */
32813821Sgabeblack@google.com    auto delay = sc_core::sc_time::from_value(pkt->payloadDelay);
32913821Sgabeblack@google.com    // reset the delays
33013821Sgabeblack@google.com    pkt->payloadDelay = 0;
33113821Sgabeblack@google.com    pkt->headerDelay = 0;
33213821Sgabeblack@google.com
33313821Sgabeblack@google.com    auto tlmSenderState = dynamic_cast<TlmSenderState*>(pkt->popSenderState());
33413821Sgabeblack@google.com    sc_assert(tlmSenderState != nullptr);
33513821Sgabeblack@google.com
33613821Sgabeblack@google.com    auto &trans = tlmSenderState->trans;
33713821Sgabeblack@google.com
33813821Sgabeblack@google.com    Gem5SystemC::Gem5Extension *extension = nullptr;
33913821Sgabeblack@google.com    trans.get_extension(extension);
34013821Sgabeblack@google.com
34113821Sgabeblack@google.com    // clean up
34213821Sgabeblack@google.com    delete tlmSenderState;
34313821Sgabeblack@google.com
34413821Sgabeblack@google.com    // If there is an extension the packet was piped through and we must not
34513821Sgabeblack@google.com    // delete it. The packet travels back with the transaction.
34613821Sgabeblack@google.com    if (extension == nullptr)
34713821Sgabeblack@google.com        destroyPacket(pkt);
34813821Sgabeblack@google.com    else
34913821Sgabeblack@google.com        sc_assert(extension->isPipeThrough());
35013821Sgabeblack@google.com
35113821Sgabeblack@google.com    sendBeginResp(trans, delay);
35213821Sgabeblack@google.com    trans.release();
35313821Sgabeblack@google.com
35413821Sgabeblack@google.com    return true;
35513821Sgabeblack@google.com}
35613821Sgabeblack@google.com
35713821Sgabeblack@google.comvoid
35813821Sgabeblack@google.comTlmToGem5Bridge::recvReqRetry()
35913821Sgabeblack@google.com{
36013821Sgabeblack@google.com    sc_assert(waitForRetry);
36113821Sgabeblack@google.com    sc_assert(pendingRequest != nullptr);
36213821Sgabeblack@google.com    sc_assert(pendingPacket != nullptr);
36313821Sgabeblack@google.com
36413821Sgabeblack@google.com    if (bmp.sendTimingReq(pendingPacket)) {
36513821Sgabeblack@google.com        waitForRetry = false;
36613821Sgabeblack@google.com        pendingPacket = nullptr;
36713821Sgabeblack@google.com
36813821Sgabeblack@google.com        auto &trans = *pendingRequest;
36913821Sgabeblack@google.com        sendEndReq(trans);
37013821Sgabeblack@google.com        trans.release();
37113821Sgabeblack@google.com
37213821Sgabeblack@google.com        pendingRequest = nullptr;
37313821Sgabeblack@google.com    }
37413821Sgabeblack@google.com}
37513821Sgabeblack@google.com
37613821Sgabeblack@google.comvoid
37713821Sgabeblack@google.comTlmToGem5Bridge::recvRangeChange()
37813821Sgabeblack@google.com{
37913821Sgabeblack@google.com    SC_REPORT_WARNING("TlmToGem5Bridge",
38013821Sgabeblack@google.com                      "received address range change but ignored it");
38113821Sgabeblack@google.com}
38213821Sgabeblack@google.com
38313821Sgabeblack@google.com::Port &
38413821Sgabeblack@google.comTlmToGem5Bridge::gem5_getPort(const std::string &if_name, int idx)
38513821Sgabeblack@google.com{
38613821Sgabeblack@google.com    if (if_name == "gem5")
38713821Sgabeblack@google.com        return bmp;
38813821Sgabeblack@google.com    else if (if_name == "tlm")
38913821Sgabeblack@google.com        return wrapper;
39013821Sgabeblack@google.com
39113821Sgabeblack@google.com    return sc_core::sc_module::gem5_getPort(if_name, idx);
39213821Sgabeblack@google.com}
39313821Sgabeblack@google.com
39413821Sgabeblack@google.comTlmToGem5Bridge::TlmToGem5Bridge(
39513821Sgabeblack@google.com        Params *params, const sc_core::sc_module_name &mn) :
39613821Sgabeblack@google.com    sc_core::sc_module(mn), peq(this, &TlmToGem5Bridge::peq_cb),
39713821Sgabeblack@google.com    waitForRetry(false), pendingRequest(nullptr), pendingPacket(nullptr),
39813821Sgabeblack@google.com    needToSendRetry(false), responseInProgress(false),
39913821Sgabeblack@google.com    bmp(std::string(name()) + "master", *this), socket("tlm_socket"),
40013821Sgabeblack@google.com    wrapper(socket, std::string(name()) + ".tlm", InvalidPortID),
40113821Sgabeblack@google.com    system(params->system),
40213821Sgabeblack@google.com    masterId(params->system->getGlobalMasterId(
40313821Sgabeblack@google.com                std::string("[systemc].") + name()))
40413821Sgabeblack@google.com{
40513821Sgabeblack@google.com}
40613821Sgabeblack@google.com
40713821Sgabeblack@google.comvoid
40813821Sgabeblack@google.comTlmToGem5Bridge::before_end_of_elaboration()
40913821Sgabeblack@google.com{
41013821Sgabeblack@google.com    /*
41113821Sgabeblack@google.com     * Register the TLM non-blocking interface when using gem5 Timing mode and
41213821Sgabeblack@google.com     * the TLM blocking interface when using the gem5 Atomic mode.
41313821Sgabeblack@google.com     * Then the magic (TM) in simple_target_socket automatically transforms
41413821Sgabeblack@google.com     * non-blocking in blocking transactions and vice versa.
41513821Sgabeblack@google.com     *
41613821Sgabeblack@google.com     * NOTE: The mode may change during execution.
41713821Sgabeblack@google.com     */
41813821Sgabeblack@google.com    if (system->isTimingMode()) {
41913821Sgabeblack@google.com        SC_REPORT_INFO("TlmToGem5Bridge", "register non-blocking interface");
42013821Sgabeblack@google.com        socket.register_nb_transport_fw(
42113821Sgabeblack@google.com                this, &TlmToGem5Bridge::nb_transport_fw);
42213821Sgabeblack@google.com    } else if (system->isAtomicMode()) {
42313821Sgabeblack@google.com        SC_REPORT_INFO("TlmToGem5Bridge", "register blocking interface");
42413821Sgabeblack@google.com        socket.register_b_transport(
42513821Sgabeblack@google.com                this, &TlmToGem5Bridge::b_transport);
42613821Sgabeblack@google.com    } else {
42713821Sgabeblack@google.com        panic("gem5 operates neither in Timing nor in Atomic mode");
42813821Sgabeblack@google.com    }
42913821Sgabeblack@google.com
43013821Sgabeblack@google.com    socket.register_transport_dbg(this, &TlmToGem5Bridge::transport_dbg);
43113821Sgabeblack@google.com
43213821Sgabeblack@google.com    sc_core::sc_module::before_end_of_elaboration();
43313821Sgabeblack@google.com}
43413821Sgabeblack@google.com
43513821Sgabeblack@google.com} // namespace sc_gem5
43613821Sgabeblack@google.com
43713821Sgabeblack@google.comsc_gem5::TlmToGem5Bridge *
43813821Sgabeblack@google.comTlmToGem5BridgeParams::create()
43913821Sgabeblack@google.com{
44013821Sgabeblack@google.com    return new sc_gem5::TlmToGem5Bridge(
44113821Sgabeblack@google.com            this, sc_core::sc_module_name(name.c_str()));
44213821Sgabeblack@google.com}
443