/*
 * Copyright 2018 Google, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * 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;
 * neither the name of the copyright holders 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
 * OWNER 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: Gabe Black
 */

#ifndef __SYSTEMC_TLM_PORT_WRAPPER_HH__
#define __SYSTEMC_TLM_PORT_WRAPPER_HH__

#include "base/logging.hh"
#include "sim/port.hh"
#include "systemc/ext/tlm_core/2/sockets/sockets.hh"

namespace sc_gem5
{

template <unsigned int BUSWIDTH=32,
          typename TYPES=tlm::tlm_base_protocol_types, int N=1,
          sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
class TlmInitiatorWrapper;

template <unsigned int BUSWIDTH=32,
          typename TYPES=tlm::tlm_base_protocol_types, int N=1,
          sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
class TlmTargetWrapper;

template <unsigned int BUSWIDTH, typename TYPES, int N,
          sc_core::sc_port_policy POL>
class TlmInitiatorWrapper : public ::Port
{
  public:
    typedef tlm::tlm_base_initiator_socket<BUSWIDTH,
            tlm::tlm_fw_transport_if<TYPES>,
            tlm::tlm_bw_transport_if<TYPES>, N, POL>
        InitiatorSocket;
    typedef typename InitiatorSocket::base_target_socket_type TargetSocket;
    typedef TlmTargetWrapper<BUSWIDTH, TYPES, N, POL> TargetWrapper;

    InitiatorSocket &initiator() { return _initiator; }

    TlmInitiatorWrapper(
            InitiatorSocket &i, const std::string &_name, PortID _id) :
        Port(_name, _id), _initiator(i)
    {}

    void
    bind(::Port &peer) override
    {
        auto *target = dynamic_cast<TargetWrapper *>(&peer);
        fatal_if(!target, "Attempt to bind TLM initiator socket %s to "
                "incompatible port %s.", name(), peer.name());

        initiator().bind(target->target());
    }

    void
    unbind() override
    {
        panic("TLM sockets can't be unbound.");
    }

  private:
    InitiatorSocket &_initiator;
};

template <unsigned int BUSWIDTH, typename TYPES, int N,
          sc_core::sc_port_policy POL>
class TlmTargetWrapper : public ::Port
{
  public:
    typedef tlm::tlm_base_target_socket<BUSWIDTH,
            tlm::tlm_fw_transport_if<TYPES>,
            tlm::tlm_bw_transport_if<TYPES>, N, POL>
        TargetSocket;

    TargetSocket &target() { return _target; }

    TlmTargetWrapper(TargetSocket &t, const std::string &_name, PortID _id) :
        Port(_name, _id), _target(t)
    {}

    void
    bind(::Port &peer) override
    {
        // Ignore attempts to bind a target socket. The initiator will
        // handle it.
    }

    void
    unbind() override
    {
        panic("TLM sockets can't be unbound.");
    }

  private:
    TargetSocket &_target;
};

} // namespace sc_gem5

#endif  //__SYSTEMC_TLM_PORT_WRAPPER_HH__
