/*
 * Copyright (c) 2015, University of Kaiserslautern
 * Copyright (c) 2016, Dresden University of Technology (TU Dresden)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Matthias Jung
 *          Abdul Mutaal Ahmad
 *          Christian Menard
 */

#include "systemc/tlm_bridge/sc_slave_port.hh"

#include "systemc/tlm_bridge/sc_ext.hh"
#include "systemc/tlm_bridge/sc_mm.hh"
#include "systemc/tlm_bridge/slave_transactor.hh"

namespace Gem5SystemC
{

/**
 * Instantiate a tlm memory manager that takes care about all the
 * tlm transactions in the system
 */
MemoryManager mm;

/**
 * Convert a gem5 packet to a TLM payload by copying all the relevant
 * information to a previously allocated tlm payload
 */
void
packet2payload(PacketPtr packet, tlm::tlm_generic_payload &trans)
{
    trans.set_address(packet->getAddr());

    /* Check if this transaction was allocated by mm */
    sc_assert(trans.has_mm());

    unsigned int size = packet->getSize();
    unsigned char *data = packet->getPtr<unsigned char>();

    trans.set_data_length(size);
    trans.set_streaming_width(size);
    trans.set_data_ptr(data);

    if (packet->isRead()) {
        trans.set_command(tlm::TLM_READ_COMMAND);
    }
    else if (packet->isInvalidate()) {
        /* Do nothing */
    } else if (packet->isWrite()) {
        trans.set_command(tlm::TLM_WRITE_COMMAND);
    } else {
        SC_REPORT_FATAL("SCSlavePort", "No R/W packet");
    }
}

/**
 * Similar to TLM's blocking transport (LT)
 */
Tick
SCSlavePort::recvAtomic(PacketPtr packet)
{
    CAUGHT_UP;
    SC_REPORT_INFO("SCSlavePort", "recvAtomic hasn't been tested much");

    panic_if(packet->cacheResponding(), "Should not see packets where cache "
             "is responding");

    panic_if(!(packet->isRead() || packet->isWrite()),
             "Should only see read and writes at TLM memory\n");


    sc_core::sc_time delay = sc_core::SC_ZERO_TIME;


    /* Prepare the transaction */
    tlm::tlm_generic_payload *trans = mm.allocate();
    trans->acquire();
    packet2payload(packet, *trans);

    /* Attach the packet pointer to the TLM transaction to keep track */
    Gem5Extension *extension = new Gem5Extension(packet);
    trans->set_auto_extension(extension);

    /* Execute b_transport: */
    if (packet->cmd == MemCmd::SwapReq) {
        SC_REPORT_FATAL("SCSlavePort", "SwapReq not supported");
    } else if (packet->isRead()) {
        transactor->socket->b_transport(*trans, delay);
    } else if (packet->isInvalidate()) {
        // do nothing
    } else if (packet->isWrite()) {
        transactor->socket->b_transport(*trans, delay);
    } else {
        SC_REPORT_FATAL("SCSlavePort", "Typo of request not supported");
    }

    if (packet->needsResponse()) {
        packet->makeResponse();
    }

    trans->release();

    return delay.value();
}

/**
 * Similar to TLM's debug transport
 */
void
SCSlavePort::recvFunctional(PacketPtr packet)
{
    /* Prepare the transaction */
    tlm::tlm_generic_payload *trans = mm.allocate();
    trans->acquire();
    packet2payload(packet, *trans);

    /* Attach the packet pointer to the TLM transaction to keep track */
    Gem5Extension *extension = new Gem5Extension(packet);
    trans->set_auto_extension(extension);

    /* Execute Debug Transport: */
    unsigned int bytes = transactor->socket->transport_dbg(*trans);
    if (bytes != trans->get_data_length()) {
        SC_REPORT_FATAL("SCSlavePort","debug transport was not completed");
    }

    trans->release();
}

bool
SCSlavePort::recvTimingSnoopResp(PacketPtr packet)
{
    /* Snooping should be implemented with tlm_dbg_transport */
    SC_REPORT_FATAL("SCSlavePort","unimplemented func.: recvTimingSnoopResp");
    return false;
}

void
SCSlavePort::recvFunctionalSnoop(PacketPtr packet)
{
    /* Snooping should be implemented with tlm_dbg_transport */
    SC_REPORT_FATAL("SCSlavePort","unimplemented func.: recvFunctionalSnoop");
}

/**
 *  Similar to TLM's non-blocking transport (AT)
 */
bool
SCSlavePort::recvTimingReq(PacketPtr packet)
{
    CAUGHT_UP;

    panic_if(packet->cacheResponding(), "Should not see packets where cache "
             "is responding");

    panic_if(!(packet->isRead() || packet->isWrite()),
             "Should only see read and writes at TLM memory\n");


    /* We should never get a second request after noting that a retry is
     * required */
    sc_assert(!needToSendRequestRetry);

    /* Remember if a request comes in while we're blocked so that a retry
     * can be sent to gem5 */
    if (blockingRequest) {
        needToSendRequestRetry = true;
        return false;
    }

    /*  NOTE: normal tlm is blocking here. But in our case we return false
     *  and tell gem5 when a retry can be done. This is the main difference
     *  in the protocol:
     *  if (requestInProgress)
     *  {
     *      wait(endRequestEvent);
     *  }
     *  requestInProgress = trans;
    */

    /* Prepare the transaction */
    tlm::tlm_generic_payload *trans = mm.allocate();
    trans->acquire();
    packet2payload(packet, *trans);

    /* Attach the packet pointer to the TLM transaction to keep track */
    Gem5Extension *extension = new Gem5Extension(packet);
    trans->set_auto_extension(extension);

    /*
     * Pay for annotated transport delays.
     *
     * The header delay marks the point in time, when the packet first is seen
     * by the transactor. This is the point int time, when the transactor needs
     * to send the BEGIN_REQ to the SystemC world.
     *
     * NOTE: We drop the payload delay here. Normally, the receiver would be
     *       responsible for handling the payload delay. In this case, however,
     *       the receiver is a SystemC module and has no notion of the gem5
     *       transport protocol and we cannot simply forward the
     *       payload delay to the receiving module. Instead, we expect the
     *       receiving SystemC module to model the payload delay by deferring
     *       the END_REQ. This could lead to incorrect delays, if the XBar
     *       payload delay is longer than the time the receiver needs to accept
     *       the request (time between BEGIN_REQ and END_REQ).
     *
     * TODO: We could detect the case described above by remembering the
     *       payload delay and comparing it to the time between BEGIN_REQ and
     *       END_REQ. Then, a warning should be printed.
     */
    auto delay = sc_core::sc_time::from_value(packet->payloadDelay);
    // reset the delays
    packet->payloadDelay = 0;
    packet->headerDelay = 0;

    /* Starting TLM non-blocking sequence (AT) Refer to IEEE1666-2011 SystemC
     * Standard Page 507 for a visualisation of the procedure */
    tlm::tlm_phase phase = tlm::BEGIN_REQ;
    tlm::tlm_sync_enum status;
    status = transactor->socket->nb_transport_fw(*trans, phase, delay);
    /* Check returned value: */
    if (status == tlm::TLM_ACCEPTED) {
        sc_assert(phase == tlm::BEGIN_REQ);
        /* Accepted but is now blocking until END_REQ (exclusion rule)*/
        blockingRequest = trans;
    } else if (status == tlm::TLM_UPDATED) {
        /* The Timing annotation must be honored: */
        sc_assert(phase == tlm::END_REQ || phase == tlm::BEGIN_RESP);

        PayloadEvent<SCSlavePort> * pe;
        pe = new PayloadEvent<SCSlavePort>(*this,
            &SCSlavePort::pec, "PEQ");
        pe->notify(*trans, phase, delay);
    } else if (status == tlm::TLM_COMPLETED) {
        /* Transaction is over nothing has do be done. */
        sc_assert(phase == tlm::END_RESP);
        trans->release();
    }

    return true;
}

void
SCSlavePort::pec(
    PayloadEvent<SCSlavePort> *pe,
    tlm::tlm_generic_payload &trans,
    const tlm::tlm_phase &phase)
{
    sc_core::sc_time delay;

    if (phase == tlm::END_REQ ||
            (&trans == blockingRequest && phase == tlm::BEGIN_RESP)) {
        sc_assert(&trans == blockingRequest);
        blockingRequest = NULL;

        /* Did another request arrive while blocked, schedule a retry */
        if (needToSendRequestRetry) {
            needToSendRequestRetry = false;
            sendRetryReq();
        }
    }
    if (phase == tlm::BEGIN_RESP) {
        CAUGHT_UP;

        auto& extension = Gem5Extension::getExtension(trans);
        auto packet = extension.getPacket();

        sc_assert(!blockingResponse);

        bool need_retry = false;

        /*
         * If the packet was piped through and needs a response, we don't need
         * to touch the packet and can forward it directly as a response.
         * Otherwise, we need to make a response and send the transformed
         * packet.
         */
        if (extension.isPipeThrough()) {
            if (packet->isResponse()) {
                need_retry = !sendTimingResp(packet);
            }
        } else if (packet->needsResponse()) {
            packet->makeResponse();
            need_retry = !sendTimingResp(packet);
        }

        if (need_retry) {
            blockingResponse = &trans;
        } else {
            if (phase == tlm::BEGIN_RESP) {
                /* Send END_RESP and we're finished: */
                tlm::tlm_phase fw_phase = tlm::END_RESP;
                sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
                transactor->socket->nb_transport_fw(trans, fw_phase, delay);
                /* Release the transaction with all the extensions */
                trans.release();
            }
        }
    }
    delete pe;
}

void
SCSlavePort::recvRespRetry()
{
    CAUGHT_UP;

    /* Retry a response */
    sc_assert(blockingResponse);

    tlm::tlm_generic_payload *trans = blockingResponse;
    blockingResponse = NULL;
    PacketPtr packet = Gem5Extension::getExtension(trans).getPacket();

    bool need_retry = !sendTimingResp(packet);

    sc_assert(!need_retry);

    sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
    tlm::tlm_phase phase = tlm::END_RESP;
    transactor->socket->nb_transport_fw(*trans, phase, delay);
    // Release transaction with all the extensions
    trans->release();
}

tlm::tlm_sync_enum
SCSlavePort::nb_transport_bw(tlm::tlm_generic_payload &trans,
    tlm::tlm_phase &phase,
    sc_core::sc_time &delay)
{
    PayloadEvent<SCSlavePort> *pe;
    pe = new PayloadEvent<SCSlavePort>(*this, &SCSlavePort::pec, "PE");
    pe->notify(trans, phase, delay);
    return tlm::TLM_ACCEPTED;
}

SCSlavePort::SCSlavePort(const std::string &name_,
    const std::string &systemc_name,
    ExternalSlave &owner_) :
    ExternalSlave::Port(name_, owner_),
    blockingRequest(NULL),
    needToSendRequestRetry(false),
    blockingResponse(NULL),
    transactor(nullptr)
{
}

void
SCSlavePort::bindToTransactor(Gem5SlaveTransactor *transactor)
{
    sc_assert(this->transactor == nullptr);

    this->transactor = transactor;

    transactor->socket.register_nb_transport_bw(this,
                                                &SCSlavePort::nb_transport_bw);
}

ExternalSlave::Port *
SCSlavePortHandler::getExternalPort(const std::string &name,
                                    ExternalSlave &owner,
                                    const std::string &port_data)
{
    // Create and register a new SystemC slave port
    auto *port = new SCSlavePort(name, port_data, owner);

    //control.registerSlavePort(port_data, port);

    return port;
}

} // namespace Gem5SystemC
