112047Schristian.menard@tu-dresden.de/*
212047Schristian.menard@tu-dresden.de * Copyright (c) 2016, Dresden University of Technology (TU Dresden)
312047Schristian.menard@tu-dresden.de * All rights reserved.
412047Schristian.menard@tu-dresden.de *
512047Schristian.menard@tu-dresden.de * Redistribution and use in source and binary forms, with or without
612047Schristian.menard@tu-dresden.de * modification, are permitted provided that the following conditions are
712047Schristian.menard@tu-dresden.de * met:
812047Schristian.menard@tu-dresden.de *
912047Schristian.menard@tu-dresden.de * 1. Redistributions of source code must retain the above copyright notice,
1012047Schristian.menard@tu-dresden.de *    this list of conditions and the following disclaimer.
1112047Schristian.menard@tu-dresden.de *
1212047Schristian.menard@tu-dresden.de * 2. Redistributions in binary form must reproduce the above copyright
1312047Schristian.menard@tu-dresden.de *    notice, this list of conditions and the following disclaimer in the
1412047Schristian.menard@tu-dresden.de *    documentation and/or other materials provided with the distribution.
1512047Schristian.menard@tu-dresden.de *
1612047Schristian.menard@tu-dresden.de * 3. Neither the name of the copyright holder nor the names of its
1712047Schristian.menard@tu-dresden.de *    contributors may be used to endorse or promote products derived from
1812047Schristian.menard@tu-dresden.de *    this software without specific prior written permission.
1912047Schristian.menard@tu-dresden.de *
2012047Schristian.menard@tu-dresden.de * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2112047Schristian.menard@tu-dresden.de * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2212047Schristian.menard@tu-dresden.de * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2312047Schristian.menard@tu-dresden.de * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
2412047Schristian.menard@tu-dresden.de * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2512047Schristian.menard@tu-dresden.de * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2612047Schristian.menard@tu-dresden.de * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2712047Schristian.menard@tu-dresden.de * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2812047Schristian.menard@tu-dresden.de * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2912047Schristian.menard@tu-dresden.de * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3012047Schristian.menard@tu-dresden.de * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3112047Schristian.menard@tu-dresden.de *
3212047Schristian.menard@tu-dresden.de * Authors: Christian Menard
3312047Schristian.menard@tu-dresden.de */
3412047Schristian.menard@tu-dresden.de
3512047Schristian.menard@tu-dresden.de#include <sstream>
3612047Schristian.menard@tu-dresden.de
3712047Schristian.menard@tu-dresden.de#include "master_transactor.hh"
3812047Schristian.menard@tu-dresden.de#include "params/ExternalMaster.hh"
3912047Schristian.menard@tu-dresden.de#include "sc_ext.hh"
4012047Schristian.menard@tu-dresden.de#include "sc_master_port.hh"
4112047Schristian.menard@tu-dresden.de#include "sim/system.hh"
4212047Schristian.menard@tu-dresden.de
4312047Schristian.menard@tu-dresden.denamespace Gem5SystemC
4412047Schristian.menard@tu-dresden.de{
4512047Schristian.menard@tu-dresden.de
4612047Schristian.menard@tu-dresden.dePacketPtr
4712047Schristian.menard@tu-dresden.deSCMasterPort::generatePacket(tlm::tlm_generic_payload& trans)
4812047Schristian.menard@tu-dresden.de{
4912047Schristian.menard@tu-dresden.de    Request::Flags flags;
5012749Sgiacomo.travaglini@arm.com    auto req = std::make_shared<Request>(
5112749Sgiacomo.travaglini@arm.com        trans.get_address(), trans.get_data_length(), flags,
5212749Sgiacomo.travaglini@arm.com        owner.masterId);
5312047Schristian.menard@tu-dresden.de
5412047Schristian.menard@tu-dresden.de    MemCmd cmd;
5512047Schristian.menard@tu-dresden.de
5612047Schristian.menard@tu-dresden.de    switch (trans.get_command()) {
5712047Schristian.menard@tu-dresden.de        case tlm::TLM_READ_COMMAND:
5812047Schristian.menard@tu-dresden.de            cmd = MemCmd::ReadReq;
5912047Schristian.menard@tu-dresden.de            break;
6012047Schristian.menard@tu-dresden.de        case tlm::TLM_WRITE_COMMAND:
6112047Schristian.menard@tu-dresden.de            cmd = MemCmd::WriteReq;
6212047Schristian.menard@tu-dresden.de            break;
6312047Schristian.menard@tu-dresden.de        default:
6412047Schristian.menard@tu-dresden.de            SC_REPORT_FATAL("SCMasterPort",
6512047Schristian.menard@tu-dresden.de                            "received transaction with unsupported command");
6612047Schristian.menard@tu-dresden.de    }
6712047Schristian.menard@tu-dresden.de
6812047Schristian.menard@tu-dresden.de    /*
6912047Schristian.menard@tu-dresden.de     * Allocate a new Packet. The packet will be deleted when it returns from
7012047Schristian.menard@tu-dresden.de     * the gem5 world as a response.
7112047Schristian.menard@tu-dresden.de     */
7212047Schristian.menard@tu-dresden.de    auto pkt = new Packet(req, cmd);
7312047Schristian.menard@tu-dresden.de    pkt->dataStatic(trans.get_data_ptr());
7412047Schristian.menard@tu-dresden.de
7512047Schristian.menard@tu-dresden.de    return pkt;
7612047Schristian.menard@tu-dresden.de}
7712047Schristian.menard@tu-dresden.de
7812047Schristian.menard@tu-dresden.devoid
7912047Schristian.menard@tu-dresden.deSCMasterPort::destroyPacket(PacketPtr pkt)
8012047Schristian.menard@tu-dresden.de{
8112047Schristian.menard@tu-dresden.de    delete pkt;
8212047Schristian.menard@tu-dresden.de}
8312047Schristian.menard@tu-dresden.de
8412047Schristian.menard@tu-dresden.deSCMasterPort::SCMasterPort(const std::string& name_,
8512047Schristian.menard@tu-dresden.de                           const std::string& systemc_name,
8612047Schristian.menard@tu-dresden.de                           ExternalMaster& owner_,
8712047Schristian.menard@tu-dresden.de                           Gem5SimControl& simControl)
8812047Schristian.menard@tu-dresden.de  : ExternalMaster::Port(name_, owner_),
8912047Schristian.menard@tu-dresden.de    peq(this, &SCMasterPort::peq_cb),
9012047Schristian.menard@tu-dresden.de    waitForRetry(false),
9112047Schristian.menard@tu-dresden.de    pendingRequest(nullptr),
9212047Schristian.menard@tu-dresden.de    pendingPacket(nullptr),
9312047Schristian.menard@tu-dresden.de    needToSendRetry(false),
9412047Schristian.menard@tu-dresden.de    responseInProgress(false),
9512047Schristian.menard@tu-dresden.de    transactor(nullptr),
9612047Schristian.menard@tu-dresden.de    simControl(simControl)
9712047Schristian.menard@tu-dresden.de{
9812047Schristian.menard@tu-dresden.de    system =
9912047Schristian.menard@tu-dresden.de        dynamic_cast<const ExternalMasterParams*>(owner_.params())->system;
10012047Schristian.menard@tu-dresden.de}
10112047Schristian.menard@tu-dresden.de
10212047Schristian.menard@tu-dresden.devoid
10312047Schristian.menard@tu-dresden.deSCMasterPort::bindToTransactor(Gem5MasterTransactor* transactor)
10412047Schristian.menard@tu-dresden.de{
10512047Schristian.menard@tu-dresden.de    sc_assert(this->transactor == nullptr);
10612047Schristian.menard@tu-dresden.de
10712047Schristian.menard@tu-dresden.de    this->transactor = transactor;
10812047Schristian.menard@tu-dresden.de
10912047Schristian.menard@tu-dresden.de    /*
11012047Schristian.menard@tu-dresden.de     * Register the TLM non-blocking interface when using gem5 Timing mode and
11112047Schristian.menard@tu-dresden.de     * the TLM blocking interface when using the gem5 Atomic mode.
11212047Schristian.menard@tu-dresden.de     * Then the magic (TM) in simple_target_socket automatically transforms
11312047Schristian.menard@tu-dresden.de     * non-blocking in blocking transactions and vice versa.
11412047Schristian.menard@tu-dresden.de     *
11512047Schristian.menard@tu-dresden.de     * NOTE: The mode may change during execution.
11612047Schristian.menard@tu-dresden.de     */
11712047Schristian.menard@tu-dresden.de    if (system->isTimingMode()) {
11812047Schristian.menard@tu-dresden.de        SC_REPORT_INFO("SCMasterPort", "register non-blocking interface");
11912047Schristian.menard@tu-dresden.de        transactor->socket.register_nb_transport_fw(this,
12012047Schristian.menard@tu-dresden.de                                &SCMasterPort::nb_transport_fw);
12112047Schristian.menard@tu-dresden.de    } else if (system->isAtomicMode()) {
12212047Schristian.menard@tu-dresden.de        SC_REPORT_INFO("SCMasterPort", "register blocking interface");
12312047Schristian.menard@tu-dresden.de        transactor->socket.register_b_transport(this,
12412047Schristian.menard@tu-dresden.de                                &SCMasterPort::b_transport);
12512047Schristian.menard@tu-dresden.de    } else {
12612047Schristian.menard@tu-dresden.de        panic("gem5 operates neither in Timing nor in Atomic mode");
12712047Schristian.menard@tu-dresden.de    }
12812047Schristian.menard@tu-dresden.de
12912047Schristian.menard@tu-dresden.de    transactor->socket.register_transport_dbg(this,
13012047Schristian.menard@tu-dresden.de                                              &SCMasterPort::transport_dbg);
13112047Schristian.menard@tu-dresden.de}
13212047Schristian.menard@tu-dresden.de
13312047Schristian.menard@tu-dresden.devoid
13412047Schristian.menard@tu-dresden.deSCMasterPort::checkTransaction(tlm::tlm_generic_payload& trans)
13512047Schristian.menard@tu-dresden.de{
13612047Schristian.menard@tu-dresden.de    if (trans.is_response_error()) {
13712047Schristian.menard@tu-dresden.de        std::stringstream ss;
13812047Schristian.menard@tu-dresden.de        ss << "Transaction returned with error, response status = "
13912047Schristian.menard@tu-dresden.de           << trans.get_response_string();
14012047Schristian.menard@tu-dresden.de        SC_REPORT_ERROR("TLM-2", ss.str().c_str());
14112047Schristian.menard@tu-dresden.de    }
14212047Schristian.menard@tu-dresden.de}
14312047Schristian.menard@tu-dresden.de
14412047Schristian.menard@tu-dresden.detlm::tlm_sync_enum
14512047Schristian.menard@tu-dresden.deSCMasterPort::nb_transport_fw(tlm::tlm_generic_payload& trans,
14612047Schristian.menard@tu-dresden.de                              tlm::tlm_phase& phase, sc_core::sc_time& delay)
14712047Schristian.menard@tu-dresden.de{
14812047Schristian.menard@tu-dresden.de    uint64_t adr = trans.get_address();
14912047Schristian.menard@tu-dresden.de    unsigned len = trans.get_data_length();
15012047Schristian.menard@tu-dresden.de    unsigned char* byteEnable = trans.get_byte_enable_ptr();
15112047Schristian.menard@tu-dresden.de    unsigned width = trans.get_streaming_width();
15212047Schristian.menard@tu-dresden.de
15312047Schristian.menard@tu-dresden.de    // check the transaction attributes for unsupported features ...
15412047Schristian.menard@tu-dresden.de    if (byteEnable != 0) {
15512047Schristian.menard@tu-dresden.de        trans.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE);
15612047Schristian.menard@tu-dresden.de        return tlm::TLM_COMPLETED;
15712047Schristian.menard@tu-dresden.de    }
15812047Schristian.menard@tu-dresden.de    if (width < len) { // is this a burst request?
15912047Schristian.menard@tu-dresden.de        trans.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE);
16012047Schristian.menard@tu-dresden.de        return tlm::TLM_COMPLETED;
16112047Schristian.menard@tu-dresden.de    }
16212047Schristian.menard@tu-dresden.de
16312047Schristian.menard@tu-dresden.de    // ... and queue the valid transaction
16412047Schristian.menard@tu-dresden.de    trans.acquire();
16512047Schristian.menard@tu-dresden.de    peq.notify(trans, phase, delay);
16612047Schristian.menard@tu-dresden.de    return tlm::TLM_ACCEPTED;
16712047Schristian.menard@tu-dresden.de}
16812047Schristian.menard@tu-dresden.de
16912047Schristian.menard@tu-dresden.devoid
17012047Schristian.menard@tu-dresden.deSCMasterPort::peq_cb(tlm::tlm_generic_payload& trans,
17112047Schristian.menard@tu-dresden.de                       const tlm::tlm_phase& phase)
17212047Schristian.menard@tu-dresden.de{
17312047Schristian.menard@tu-dresden.de    // catch up with SystemC time
17412047Schristian.menard@tu-dresden.de    simControl.catchup();
17512047Schristian.menard@tu-dresden.de    assert(curTick() == sc_core::sc_time_stamp().value());
17612047Schristian.menard@tu-dresden.de
17712047Schristian.menard@tu-dresden.de    switch (phase) {
17812047Schristian.menard@tu-dresden.de        case tlm::BEGIN_REQ:
17912047Schristian.menard@tu-dresden.de            handleBeginReq(trans);
18012047Schristian.menard@tu-dresden.de            break;
18112047Schristian.menard@tu-dresden.de        case tlm::END_RESP:
18212047Schristian.menard@tu-dresden.de            handleEndResp(trans);
18312047Schristian.menard@tu-dresden.de            break;
18412047Schristian.menard@tu-dresden.de        default:
18512047Schristian.menard@tu-dresden.de            panic("unimplemented phase in callback");
18612047Schristian.menard@tu-dresden.de    }
18712047Schristian.menard@tu-dresden.de
18812047Schristian.menard@tu-dresden.de    // the functions called above may have scheduled gem5 events
18912047Schristian.menard@tu-dresden.de    // -> notify the event loop handler
19012047Schristian.menard@tu-dresden.de    simControl.notify();
19112047Schristian.menard@tu-dresden.de}
19212047Schristian.menard@tu-dresden.de
19312047Schristian.menard@tu-dresden.devoid
19412047Schristian.menard@tu-dresden.deSCMasterPort::handleBeginReq(tlm::tlm_generic_payload& trans)
19512047Schristian.menard@tu-dresden.de{
19612047Schristian.menard@tu-dresden.de    sc_assert(!waitForRetry);
19712047Schristian.menard@tu-dresden.de    sc_assert(pendingRequest == nullptr);
19812047Schristian.menard@tu-dresden.de    sc_assert(pendingPacket == nullptr);
19912047Schristian.menard@tu-dresden.de
20012047Schristian.menard@tu-dresden.de    trans.acquire();
20112047Schristian.menard@tu-dresden.de
20212047Schristian.menard@tu-dresden.de    PacketPtr pkt = nullptr;
20312047Schristian.menard@tu-dresden.de
20412047Schristian.menard@tu-dresden.de    Gem5Extension* extension = nullptr;
20512047Schristian.menard@tu-dresden.de    trans.get_extension(extension);
20612047Schristian.menard@tu-dresden.de
20712047Schristian.menard@tu-dresden.de    // If there is an extension, this transaction was initiated by the gem5
20812047Schristian.menard@tu-dresden.de    // world and we can pipe through the original packet. Otherwise, we
20912047Schristian.menard@tu-dresden.de    // generate a new packet based on the transaction.
21012047Schristian.menard@tu-dresden.de    if (extension != nullptr) {
21112047Schristian.menard@tu-dresden.de        extension->setPipeThrough();
21212047Schristian.menard@tu-dresden.de        pkt = extension->getPacket();
21312047Schristian.menard@tu-dresden.de    } else {
21412047Schristian.menard@tu-dresden.de        pkt = generatePacket(trans);
21512047Schristian.menard@tu-dresden.de    }
21612047Schristian.menard@tu-dresden.de
21712047Schristian.menard@tu-dresden.de    auto tlmSenderState = new TlmSenderState(trans);
21812047Schristian.menard@tu-dresden.de    pkt->pushSenderState(tlmSenderState);
21912047Schristian.menard@tu-dresden.de
22012047Schristian.menard@tu-dresden.de    if (sendTimingReq(pkt)) { // port is free -> send END_REQ immediately
22112047Schristian.menard@tu-dresden.de        sendEndReq(trans);
22212047Schristian.menard@tu-dresden.de        trans.release();
22312047Schristian.menard@tu-dresden.de    } else { // port is blocked -> wait for retry before sending END_REQ
22412047Schristian.menard@tu-dresden.de        waitForRetry = true;
22512047Schristian.menard@tu-dresden.de        pendingRequest = &trans;
22612047Schristian.menard@tu-dresden.de        pendingPacket = pkt;
22712047Schristian.menard@tu-dresden.de    }
22812047Schristian.menard@tu-dresden.de}
22912047Schristian.menard@tu-dresden.de
23012047Schristian.menard@tu-dresden.devoid
23112047Schristian.menard@tu-dresden.deSCMasterPort::handleEndResp(tlm::tlm_generic_payload& trans)
23212047Schristian.menard@tu-dresden.de{
23312047Schristian.menard@tu-dresden.de    sc_assert(responseInProgress);
23412047Schristian.menard@tu-dresden.de
23512047Schristian.menard@tu-dresden.de    responseInProgress = false;
23612047Schristian.menard@tu-dresden.de
23712047Schristian.menard@tu-dresden.de    checkTransaction(trans);
23812047Schristian.menard@tu-dresden.de
23912047Schristian.menard@tu-dresden.de    if (needToSendRetry) {
24012047Schristian.menard@tu-dresden.de        sendRetryResp();
24112047Schristian.menard@tu-dresden.de        needToSendRetry = false;
24212047Schristian.menard@tu-dresden.de    }
24312047Schristian.menard@tu-dresden.de}
24412047Schristian.menard@tu-dresden.de
24512047Schristian.menard@tu-dresden.devoid
24612047Schristian.menard@tu-dresden.deSCMasterPort::sendEndReq(tlm::tlm_generic_payload& trans)
24712047Schristian.menard@tu-dresden.de{
24812047Schristian.menard@tu-dresden.de    tlm::tlm_phase phase = tlm::END_REQ;
24912047Schristian.menard@tu-dresden.de    auto delay = sc_core::SC_ZERO_TIME;
25012047Schristian.menard@tu-dresden.de
25112047Schristian.menard@tu-dresden.de    auto status = transactor->socket->nb_transport_bw(trans, phase, delay);
25212047Schristian.menard@tu-dresden.de    panic_if(status != tlm::TLM_ACCEPTED,
25312047Schristian.menard@tu-dresden.de             "Unexpected status after sending END_REQ");
25412047Schristian.menard@tu-dresden.de}
25512047Schristian.menard@tu-dresden.de
25612047Schristian.menard@tu-dresden.devoid
25712047Schristian.menard@tu-dresden.deSCMasterPort::b_transport(tlm::tlm_generic_payload& trans,
25812047Schristian.menard@tu-dresden.de                        sc_core::sc_time& t)
25912047Schristian.menard@tu-dresden.de{
26012047Schristian.menard@tu-dresden.de    Gem5Extension* extension = nullptr;
26112047Schristian.menard@tu-dresden.de    trans.get_extension(extension);
26212047Schristian.menard@tu-dresden.de
26312047Schristian.menard@tu-dresden.de    PacketPtr pkt = nullptr;
26412047Schristian.menard@tu-dresden.de
26512047Schristian.menard@tu-dresden.de    // If there is an extension, this transaction was initiated by the gem5
26612047Schristian.menard@tu-dresden.de    // world and we can pipe through the original packet.
26712047Schristian.menard@tu-dresden.de    if (extension != nullptr) {
26812047Schristian.menard@tu-dresden.de        extension->setPipeThrough();
26912047Schristian.menard@tu-dresden.de        pkt = extension->getPacket();
27012047Schristian.menard@tu-dresden.de    } else {
27112047Schristian.menard@tu-dresden.de        pkt = generatePacket(trans);
27212047Schristian.menard@tu-dresden.de    }
27312047Schristian.menard@tu-dresden.de
27412047Schristian.menard@tu-dresden.de    Tick ticks = sendAtomic(pkt);
27512047Schristian.menard@tu-dresden.de
27612047Schristian.menard@tu-dresden.de    // send an atomic request to gem5
27712047Schristian.menard@tu-dresden.de    panic_if(pkt->needsResponse() && !pkt->isResponse(),
27812047Schristian.menard@tu-dresden.de             "Packet sending failed!\n");
27912047Schristian.menard@tu-dresden.de
28012047Schristian.menard@tu-dresden.de    // one tick is a pico second
28112047Schristian.menard@tu-dresden.de    auto delay =
28212047Schristian.menard@tu-dresden.de      sc_core::sc_time((double)(ticks / SimClock::Int::ps), sc_core::SC_PS);
28312047Schristian.menard@tu-dresden.de
28412047Schristian.menard@tu-dresden.de    // update time
28512047Schristian.menard@tu-dresden.de    t += delay;
28612047Schristian.menard@tu-dresden.de
28713744Sgabeblack@google.com    if (extension == nullptr)
28812047Schristian.menard@tu-dresden.de        destroyPacket(pkt);
28912047Schristian.menard@tu-dresden.de
29012047Schristian.menard@tu-dresden.de    trans.set_response_status(tlm::TLM_OK_RESPONSE);
29112047Schristian.menard@tu-dresden.de}
29212047Schristian.menard@tu-dresden.de
29312047Schristian.menard@tu-dresden.deunsigned int
29412047Schristian.menard@tu-dresden.deSCMasterPort::transport_dbg(tlm::tlm_generic_payload& trans)
29512047Schristian.menard@tu-dresden.de{
29612047Schristian.menard@tu-dresden.de    Gem5Extension* extension = nullptr;
29712047Schristian.menard@tu-dresden.de    trans.get_extension(extension);
29812047Schristian.menard@tu-dresden.de
29912047Schristian.menard@tu-dresden.de    // If there is an extension, this transaction was initiated by the gem5
30012047Schristian.menard@tu-dresden.de    // world and we can pipe through the original packet.
30112047Schristian.menard@tu-dresden.de    if (extension != nullptr) {
30212047Schristian.menard@tu-dresden.de        extension->setPipeThrough();
30312047Schristian.menard@tu-dresden.de        sendFunctional(extension->getPacket());
30412047Schristian.menard@tu-dresden.de    } else {
30512047Schristian.menard@tu-dresden.de        auto pkt = generatePacket(trans);
30612047Schristian.menard@tu-dresden.de        sendFunctional(pkt);
30712047Schristian.menard@tu-dresden.de        destroyPacket(pkt);
30812047Schristian.menard@tu-dresden.de    }
30912047Schristian.menard@tu-dresden.de
31012047Schristian.menard@tu-dresden.de    return trans.get_data_length();
31112047Schristian.menard@tu-dresden.de}
31212047Schristian.menard@tu-dresden.de
31312047Schristian.menard@tu-dresden.debool
31412047Schristian.menard@tu-dresden.deSCMasterPort::get_direct_mem_ptr(tlm::tlm_generic_payload& trans,
31512047Schristian.menard@tu-dresden.de                               tlm::tlm_dmi& dmi_data)
31612047Schristian.menard@tu-dresden.de{
31712047Schristian.menard@tu-dresden.de    return false;
31812047Schristian.menard@tu-dresden.de}
31912047Schristian.menard@tu-dresden.de
32012047Schristian.menard@tu-dresden.debool
32112047Schristian.menard@tu-dresden.deSCMasterPort::recvTimingResp(PacketPtr pkt)
32212047Schristian.menard@tu-dresden.de{
32312047Schristian.menard@tu-dresden.de    // exclusion rule
32412047Schristian.menard@tu-dresden.de    // We need to Wait for END_RESP before sending next BEGIN_RESP
32512047Schristian.menard@tu-dresden.de    if (responseInProgress) {
32612047Schristian.menard@tu-dresden.de        sc_assert(!needToSendRetry);
32712047Schristian.menard@tu-dresden.de        needToSendRetry = true;
32812047Schristian.menard@tu-dresden.de        return false;
32912047Schristian.menard@tu-dresden.de    }
33012047Schristian.menard@tu-dresden.de
33112047Schristian.menard@tu-dresden.de    sc_assert(pkt->isResponse());
33212047Schristian.menard@tu-dresden.de
33312047Schristian.menard@tu-dresden.de    /*
33412047Schristian.menard@tu-dresden.de     * Pay for annotated transport delays.
33512047Schristian.menard@tu-dresden.de     *
33612047Schristian.menard@tu-dresden.de     * See recvTimingReq in sc_slave_port.cc for a detailed description.
33712047Schristian.menard@tu-dresden.de     */
33812047Schristian.menard@tu-dresden.de    auto delay = sc_core::sc_time::from_value(pkt->payloadDelay);
33912047Schristian.menard@tu-dresden.de    // reset the delays
34012047Schristian.menard@tu-dresden.de    pkt->payloadDelay = 0;
34112047Schristian.menard@tu-dresden.de    pkt->headerDelay = 0;
34212047Schristian.menard@tu-dresden.de
34312047Schristian.menard@tu-dresden.de    auto tlmSenderState = dynamic_cast<TlmSenderState*>(pkt->popSenderState());
34412047Schristian.menard@tu-dresden.de    sc_assert(tlmSenderState != nullptr);
34512047Schristian.menard@tu-dresden.de
34612047Schristian.menard@tu-dresden.de    auto& trans = tlmSenderState->trans;
34712047Schristian.menard@tu-dresden.de
34812047Schristian.menard@tu-dresden.de    Gem5Extension* extension = nullptr;
34912047Schristian.menard@tu-dresden.de    trans.get_extension(extension);
35012047Schristian.menard@tu-dresden.de
35112047Schristian.menard@tu-dresden.de    // clean up
35212047Schristian.menard@tu-dresden.de    delete tlmSenderState;
35312047Schristian.menard@tu-dresden.de
35412047Schristian.menard@tu-dresden.de    // If there is an extension the packet was piped through and we must not
35512047Schristian.menard@tu-dresden.de    // delete it. The packet travels back with the transaction.
35612047Schristian.menard@tu-dresden.de    if (extension == nullptr)
35712047Schristian.menard@tu-dresden.de        destroyPacket(pkt);
35812047Schristian.menard@tu-dresden.de    else
35912047Schristian.menard@tu-dresden.de        sc_assert(extension->isPipeThrough());
36012047Schristian.menard@tu-dresden.de
36112047Schristian.menard@tu-dresden.de    sendBeginResp(trans, delay);
36212047Schristian.menard@tu-dresden.de    trans.release();
36312047Schristian.menard@tu-dresden.de
36412047Schristian.menard@tu-dresden.de    return true;
36512047Schristian.menard@tu-dresden.de}
36612047Schristian.menard@tu-dresden.de
36712047Schristian.menard@tu-dresden.devoid
36812047Schristian.menard@tu-dresden.deSCMasterPort::sendBeginResp(tlm::tlm_generic_payload& trans,
36912047Schristian.menard@tu-dresden.de                            sc_core::sc_time& delay)
37012047Schristian.menard@tu-dresden.de{
37112047Schristian.menard@tu-dresden.de    tlm::tlm_phase phase = tlm::BEGIN_RESP;
37212047Schristian.menard@tu-dresden.de
37312047Schristian.menard@tu-dresden.de    trans.set_response_status(tlm::TLM_OK_RESPONSE);
37412047Schristian.menard@tu-dresden.de
37512047Schristian.menard@tu-dresden.de    auto status = transactor->socket->nb_transport_bw(trans, phase, delay);
37612047Schristian.menard@tu-dresden.de
37712047Schristian.menard@tu-dresden.de    if (status == tlm::TLM_COMPLETED ||
37812047Schristian.menard@tu-dresden.de        status == tlm::TLM_UPDATED && phase == tlm::END_RESP) {
37912047Schristian.menard@tu-dresden.de        // transaction completed -> no need to wait for tlm::END_RESP
38012047Schristian.menard@tu-dresden.de        responseInProgress = false;
38112047Schristian.menard@tu-dresden.de    } else if (status == tlm::TLM_ACCEPTED) {
38212047Schristian.menard@tu-dresden.de        // we need to wait for tlm::END_RESP
38312047Schristian.menard@tu-dresden.de        responseInProgress = true;
38412047Schristian.menard@tu-dresden.de    } else {
38512047Schristian.menard@tu-dresden.de        panic("Unexpected status after sending BEGIN_RESP");
38612047Schristian.menard@tu-dresden.de    }
38712047Schristian.menard@tu-dresden.de}
38812047Schristian.menard@tu-dresden.de
38912047Schristian.menard@tu-dresden.devoid
39012047Schristian.menard@tu-dresden.deSCMasterPort::recvReqRetry()
39112047Schristian.menard@tu-dresden.de{
39212047Schristian.menard@tu-dresden.de    sc_assert(waitForRetry);
39312047Schristian.menard@tu-dresden.de    sc_assert(pendingRequest != nullptr);
39412047Schristian.menard@tu-dresden.de    sc_assert(pendingPacket != nullptr);
39512047Schristian.menard@tu-dresden.de
39612047Schristian.menard@tu-dresden.de    if (sendTimingReq(pendingPacket)) {
39712047Schristian.menard@tu-dresden.de        waitForRetry = false;
39812047Schristian.menard@tu-dresden.de        pendingPacket = nullptr;
39912047Schristian.menard@tu-dresden.de
40012047Schristian.menard@tu-dresden.de        auto& trans = *pendingRequest;
40112047Schristian.menard@tu-dresden.de        sendEndReq(trans);
40212047Schristian.menard@tu-dresden.de        trans.release();
40312047Schristian.menard@tu-dresden.de
40412047Schristian.menard@tu-dresden.de        pendingRequest = nullptr;
40512047Schristian.menard@tu-dresden.de    }
40612047Schristian.menard@tu-dresden.de}
40712047Schristian.menard@tu-dresden.de
40812047Schristian.menard@tu-dresden.devoid
40912047Schristian.menard@tu-dresden.deSCMasterPort::recvRangeChange()
41012047Schristian.menard@tu-dresden.de{
41112047Schristian.menard@tu-dresden.de    SC_REPORT_WARNING("SCMasterPort",
41212047Schristian.menard@tu-dresden.de                      "received address range change but ignored it");
41312047Schristian.menard@tu-dresden.de}
41412047Schristian.menard@tu-dresden.de
41512047Schristian.menard@tu-dresden.deExternalMaster::Port*
41612047Schristian.menard@tu-dresden.deSCMasterPortHandler::getExternalPort(const std::string &name,
41712047Schristian.menard@tu-dresden.de                                     ExternalMaster &owner,
41812047Schristian.menard@tu-dresden.de                                     const std::string &port_data)
41912047Schristian.menard@tu-dresden.de{
42012047Schristian.menard@tu-dresden.de    // Create and register a new SystemC master port
42112047Schristian.menard@tu-dresden.de    auto* port = new SCMasterPort(name, port_data, owner, control);
42212047Schristian.menard@tu-dresden.de
42312047Schristian.menard@tu-dresden.de    control.registerMasterPort(port_data, port);
42412047Schristian.menard@tu-dresden.de
42512047Schristian.menard@tu-dresden.de    return port;
42612047Schristian.menard@tu-dresden.de}
42712047Schristian.menard@tu-dresden.de
42812047Schristian.menard@tu-dresden.de} // namespace Gem5SystemC
429