diff --git a/src/systemc/tlm_bridge/SConscript b/src/systemc/tlm_bridge/SConscript
index 6d91436..df56fdf 100644
--- a/src/systemc/tlm_bridge/SConscript
+++ b/src/systemc/tlm_bridge/SConscript
@@ -30,6 +30,11 @@
 if not env['USE_SYSTEMC']:
     Return()
 
+SimObject('TlmBridge.py')
+
+Source('gem5_to_tlm.cc')
+Source('tlm_to_gem5.cc')
+
 Source('master_transactor.cc')
 Source('sc_ext.cc')
 Source('sc_master_port.cc')
diff --git a/src/systemc/tlm_bridge/TlmBridge.py b/src/systemc/tlm_bridge/TlmBridge.py
new file mode 100644
index 0000000..d2dff86
--- /dev/null
+++ b/src/systemc/tlm_bridge/TlmBridge.py
@@ -0,0 +1,52 @@
+# Copyright 2019 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
+
+from m5.objects.SystemC import SystemC_ScModule
+from m5.params import *
+from m5.proxy import *
+
+class Gem5ToTlmBridge(SystemC_ScModule):
+    type = 'Gem5ToTlmBridge'
+    cxx_class = 'sc_gem5::Gem5ToTlmBridge'
+    cxx_header = 'systemc/tlm_bridge/gem5_to_tlm.hh'
+
+    system = Param.System(Parent.any, "system")
+
+    gem5 = SlavePort('gem5 slave port')
+    tlm = MasterPort('TLM initiator socket')
+    addr_ranges = VectorParam.AddrRange([],
+            'Addresses served by this port\'s TLM side')
+
+class TlmToGem5Bridge(SystemC_ScModule):
+    type = 'TlmToGem5Bridge'
+    cxx_class = 'sc_gem5::TlmToGem5Bridge'
+    cxx_header = 'systemc/tlm_bridge/tlm_to_gem5.hh'
+
+    system = Param.System(Parent.any, "system")
+
+    gem5 = MasterPort('gem5 master port')
+    tlm = SlavePort('TLM target socket')
diff --git a/src/systemc/tlm_bridge/gem5_to_tlm.cc b/src/systemc/tlm_bridge/gem5_to_tlm.cc
new file mode 100644
index 0000000..06ed2ab
--- /dev/null
+++ b/src/systemc/tlm_bridge/gem5_to_tlm.cc
@@ -0,0 +1,422 @@
+/*
+ * Copyright 2019 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.
+ *
+ * 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: Gabe Black
+ *          Matthias Jung
+ *          Abdul Mutaal Ahmad
+ *          Christian Menard
+ */
+
+#include "systemc/tlm_bridge/gem5_to_tlm.hh"
+
+#include "sim/system.hh"
+#include "systemc/tlm_bridge/sc_ext.hh"
+#include "systemc/tlm_bridge/sc_mm.hh"
+
+namespace sc_gem5
+{
+
+/**
+ * Instantiate a tlm memory manager that takes care about all the
+ * tlm transactions in the system.
+ */
+Gem5SystemC::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("Gem5ToTlmBridge", "No R/W packet");
+    }
+}
+
+void
+Gem5ToTlmBridge::pec(Gem5SystemC::PayloadEvent<Gem5ToTlmBridge> *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 = nullptr;
+
+        // Did another request arrive while blocked, schedule a retry.
+        if (needToSendRequestRetry) {
+            needToSendRequestRetry = false;
+            bsp.sendRetryReq();
+        }
+    }
+    if (phase == tlm::BEGIN_RESP) {
+        auto &extension = Gem5SystemC::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 = !bsp.sendTimingResp(packet);
+            }
+        } else if (packet->needsResponse()) {
+            packet->makeResponse();
+            need_retry = !bsp.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;
+                socket->nb_transport_fw(trans, fw_phase, delay);
+                // Release the transaction with all the extensions.
+                trans.release();
+            }
+        }
+    }
+    delete pe;
+}
+
+// Similar to TLM's blocking transport (LT)
+Tick
+Gem5ToTlmBridge::recvAtomic(PacketPtr packet)
+{
+    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.
+    auto *extension = new Gem5SystemC::Gem5Extension(packet);
+    trans->set_auto_extension(extension);
+
+    // Execute b_transport:
+    if (packet->cmd == MemCmd::SwapReq) {
+        SC_REPORT_FATAL("Gem5ToTlmBridge", "SwapReq not supported");
+    } else if (packet->isRead()) {
+        socket->b_transport(*trans, delay);
+    } else if (packet->isInvalidate()) {
+        // do nothing
+    } else if (packet->isWrite()) {
+        socket->b_transport(*trans, delay);
+    } else {
+        SC_REPORT_FATAL("Gem5ToTlmBridge", "Typo of request not supported");
+    }
+
+    if (packet->needsResponse()) {
+        packet->makeResponse();
+    }
+
+    trans->release();
+
+    return delay.value();
+}
+
+void
+Gem5ToTlmBridge::recvFunctionalSnoop(PacketPtr packet)
+{
+    // Snooping should be implemented with tlm_dbg_transport.
+    SC_REPORT_FATAL("Gem5ToTlmBridge",
+            "unimplemented func.: recvFunctionalSnoop");
+}
+
+// Similar to TLM's non-blocking transport (AT).
+bool
+Gem5ToTlmBridge::recvTimingReq(PacketPtr packet)
+{
+    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.
+    auto *extension = new Gem5SystemC::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 in 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 = 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);
+
+        auto *pe = new Gem5SystemC::PayloadEvent<Gem5ToTlmBridge>(
+                *this, &Gem5ToTlmBridge::pec, "PEQ");
+        Tick nextEventTick = curTick() + delay.value();
+        system->wakeupEventQueue(nextEventTick);
+        system->schedule(pe, nextEventTick);
+    } else if (status == tlm::TLM_COMPLETED) {
+        // Transaction is over nothing has do be done.
+        sc_assert(phase == tlm::END_RESP);
+        trans->release();
+    }
+
+    return true;
+}
+
+bool
+Gem5ToTlmBridge::recvTimingSnoopResp(PacketPtr packet)
+{
+    // Snooping should be implemented with tlm_dbg_transport.
+    SC_REPORT_FATAL("Gem5ToTlmBridge",
+            "unimplemented func.: recvTimingSnoopResp");
+    return false;
+}
+
+bool
+Gem5ToTlmBridge::tryTiming(PacketPtr packet)
+{
+    panic("tryTiming(PacketPtr) isn't implemented.");
+}
+
+void
+Gem5ToTlmBridge::recvRespRetry()
+{
+    /* Retry a response */
+    sc_assert(blockingResponse);
+
+    tlm::tlm_generic_payload *trans = blockingResponse;
+    blockingResponse = nullptr;
+    PacketPtr packet =
+        Gem5SystemC::Gem5Extension::getExtension(trans).getPacket();
+
+    bool need_retry = !bsp.sendTimingResp(packet);
+
+    sc_assert(!need_retry);
+
+    sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
+    tlm::tlm_phase phase = tlm::END_RESP;
+    socket->nb_transport_fw(*trans, phase, delay);
+    // Release transaction with all the extensions
+    trans->release();
+}
+
+// Similar to TLM's debug transport.
+void
+Gem5ToTlmBridge::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.
+    auto *extension = new Gem5SystemC::Gem5Extension(packet);
+    trans->set_auto_extension(extension);
+
+    /* Execute Debug Transport: */
+    unsigned int bytes = socket->transport_dbg(*trans);
+    if (bytes != trans->get_data_length()) {
+        SC_REPORT_FATAL("Gem5ToTlmBridge",
+                "debug transport was not completed");
+    }
+
+    trans->release();
+}
+
+tlm::tlm_sync_enum
+Gem5ToTlmBridge::nb_transport_bw(tlm::tlm_generic_payload &trans,
+    tlm::tlm_phase &phase, sc_core::sc_time &delay)
+{
+    auto *pe = new Gem5SystemC::PayloadEvent<Gem5ToTlmBridge>(
+            *this, &Gem5ToTlmBridge::pec, "PE");
+    Tick nextEventTick = curTick() + delay.value();
+    system->wakeupEventQueue(nextEventTick);
+    system->schedule(pe, nextEventTick);
+    return tlm::TLM_ACCEPTED;
+}
+
+Gem5ToTlmBridge::Gem5ToTlmBridge(
+        Params *params, const sc_core::sc_module_name &mn) :
+    sc_core::sc_module(mn), bsp(std::string(name()) + ".gem5", *this),
+    socket("tlm_socket"),
+    wrapper(socket, std::string(name()) + ".tlm", InvalidPortID),
+    system(params->system), blockingRequest(nullptr),
+    needToSendRequestRetry(false), blockingResponse(nullptr),
+    addrRanges(params->addr_ranges.begin(), params->addr_ranges.end())
+{
+}
+
+::Port &
+Gem5ToTlmBridge::gem5_getPort(const std::string &if_name, int idx)
+{
+    if (if_name == "gem5")
+        return bsp;
+    else if (if_name == "tlm")
+        return wrapper;
+
+    return sc_core::sc_module::gem5_getPort(if_name, idx);
+}
+
+void
+Gem5ToTlmBridge::before_end_of_elaboration()
+{
+    bsp.sendRangeChange();
+
+    socket.register_nb_transport_bw(this, &Gem5ToTlmBridge::nb_transport_bw);
+    sc_core::sc_module::before_end_of_elaboration();
+}
+
+} // namespace sc_gem5
+
+sc_gem5::Gem5ToTlmBridge *
+Gem5ToTlmBridgeParams::create()
+{
+    return new sc_gem5::Gem5ToTlmBridge(
+            this, sc_core::sc_module_name(name.c_str()));
+}
diff --git a/src/systemc/tlm_bridge/gem5_to_tlm.hh b/src/systemc/tlm_bridge/gem5_to_tlm.hh
new file mode 100644
index 0000000..02deb6a
--- /dev/null
+++ b/src/systemc/tlm_bridge/gem5_to_tlm.hh
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2019 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.
+ *
+ * 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: Gabe Black
+ *          Matthias Jung
+ *          Christian Menard
+ */
+
+#ifndef __SYSTEMC_TLM_BRIDGE_GEM5_TO_TLM_HH__
+#define __SYSTEMC_TLM_BRIDGE_GEM5_TO_TLM_HH__
+
+#include <string>
+
+#include "mem/port.hh"
+#include "params/Gem5ToTlmBridge.hh"
+#include "sim/system.hh"
+#include "systemc/ext/core/sc_module.hh"
+#include "systemc/ext/core/sc_module_name.hh"
+#include "systemc/ext/tlm_core/2/generic_payload/gp.hh"
+#include "systemc/ext/tlm_utils/simple_initiator_socket.h"
+#include "systemc/tlm_bridge/sc_peq.hh"
+#include "systemc/tlm_port_wrapper.hh"
+
+namespace sc_gem5
+{
+
+class Gem5ToTlmBridge : public sc_core::sc_module
+{
+  private:
+    class BridgeSlavePort : public SlavePort
+    {
+      protected:
+        Gem5ToTlmBridge &bridge;
+
+        AddrRangeList
+        getAddrRanges() const override
+        {
+            return bridge.getAddrRanges();
+        }
+        Tick
+        recvAtomic(PacketPtr pkt) override
+        {
+            return bridge.recvAtomic(pkt);
+        }
+        void
+        recvFunctional(PacketPtr pkt) override
+        {
+            return bridge.recvFunctional(pkt);
+        }
+        bool
+        recvTimingReq(PacketPtr pkt) override
+        {
+            return bridge.recvTimingReq(pkt);
+        }
+        bool
+        tryTiming(PacketPtr pkt) override
+        {
+            return bridge.tryTiming(pkt);
+        }
+        bool
+        recvTimingSnoopResp(PacketPtr pkt) override
+        {
+            return bridge.recvTimingSnoopResp(pkt);
+        }
+        void recvRespRetry() override { bridge.recvRespRetry(); }
+
+      public:
+        BridgeSlavePort(const std::string &name_, Gem5ToTlmBridge &bridge_) :
+            SlavePort(name_, nullptr), bridge(bridge_)
+        {}
+    };
+
+    BridgeSlavePort bsp;
+    tlm_utils::simple_initiator_socket<Gem5ToTlmBridge, 64> socket;
+    sc_gem5::TlmInitiatorWrapper<64> wrapper;
+
+    System *system;
+
+    /**
+     * A transaction after BEGIN_REQ has been sent but before END_REQ, which
+     * is blocking the request channel (Exlusion Rule, see IEEE1666)
+     */
+    tlm::tlm_generic_payload *blockingRequest;
+
+    /**
+     * Did another gem5 request arrive while currently blocked?
+     * This variable is needed when a retry should happen
+     */
+    bool needToSendRequestRetry;
+
+    /**
+     * A response which has been asked to retry by gem5 and so is blocking
+     * the response channel
+     */
+    tlm::tlm_generic_payload *blockingResponse;
+
+    AddrRangeList addrRanges;
+
+  protected:
+    void pec(Gem5SystemC::PayloadEvent<Gem5ToTlmBridge> *pe,
+             tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase);
+
+    // The gem5 port interface.
+    Tick recvAtomic(PacketPtr packet);
+    void recvFunctional(PacketPtr packet);
+    bool recvTimingReq(PacketPtr packet);
+    bool tryTiming(PacketPtr packet);
+    bool recvTimingSnoopResp(PacketPtr packet);
+    void recvRespRetry();
+    void recvFunctionalSnoop(PacketPtr packet);
+    AddrRangeList getAddrRanges() const { return addrRanges; }
+
+    // The TLM initiator interface.
+    tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &trans,
+                                       tlm::tlm_phase &phase,
+                                       sc_core::sc_time &t);
+
+  public:
+    ::Port &gem5_getPort(const std::string &if_name, int idx=-1) override;
+
+    typedef Gem5ToTlmBridgeParams Params;
+    Gem5ToTlmBridge(Params *p, const sc_core::sc_module_name &mn);
+
+    tlm_utils::simple_initiator_socket<Gem5ToTlmBridge, 64> &
+    getSocket()
+    {
+        return socket;
+    }
+
+    void before_end_of_elaboration() override;
+};
+
+} // namespace sc_gem5
+
+#endif // __SYSTEMC_TLM_BRIDGE_GEM5_TO_TLM_HH__
diff --git a/src/systemc/tlm_bridge/tlm_to_gem5.cc b/src/systemc/tlm_bridge/tlm_to_gem5.cc
new file mode 100644
index 0000000..9e70490
--- /dev/null
+++ b/src/systemc/tlm_bridge/tlm_to_gem5.cc
@@ -0,0 +1,442 @@
+/*
+ * Copyright 2019 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.
+ *
+ * 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: Gabe Black
+ *          Christian Menard
+ */
+
+#include "systemc/tlm_bridge/tlm_to_gem5.hh"
+
+#include "sim/system.hh"
+#include "systemc/ext/core/sc_module_name.hh"
+
+namespace sc_gem5
+{
+
+void
+TlmToGem5Bridge::sendEndReq(tlm::tlm_generic_payload &trans)
+{
+    tlm::tlm_phase phase = tlm::END_REQ;
+    auto delay = sc_core::SC_ZERO_TIME;
+
+    auto status = socket->nb_transport_bw(trans, phase, delay);
+    panic_if(status != tlm::TLM_ACCEPTED,
+             "Unexpected status after sending END_REQ");
+}
+
+void
+TlmToGem5Bridge::sendBeginResp(tlm::tlm_generic_payload &trans,
+                               sc_core::sc_time &delay)
+{
+    tlm::tlm_phase phase = tlm::BEGIN_RESP;
+
+    trans.set_response_status(tlm::TLM_OK_RESPONSE);
+
+    auto status = socket->nb_transport_bw(trans, phase, delay);
+
+    if (status == tlm::TLM_COMPLETED ||
+        (status == tlm::TLM_UPDATED && phase == tlm::END_RESP)) {
+        // transaction completed -> no need to wait for tlm::END_RESP
+        responseInProgress = false;
+    } else if (status == tlm::TLM_ACCEPTED) {
+        // we need to wait for tlm::END_RESP
+        responseInProgress = true;
+    } else {
+        panic("Unexpected status after sending BEGIN_RESP");
+    }
+}
+
+void
+TlmToGem5Bridge::handleBeginReq(tlm::tlm_generic_payload &trans)
+{
+    sc_assert(!waitForRetry);
+    sc_assert(pendingRequest == nullptr);
+    sc_assert(pendingPacket == nullptr);
+
+    trans.acquire();
+
+    PacketPtr pkt = nullptr;
+
+    Gem5SystemC::Gem5Extension *extension = nullptr;
+    trans.get_extension(extension);
+
+    // If there is an extension, this transaction was initiated by the gem5
+    // world and we can pipe through the original packet. Otherwise, we
+    // generate a new packet based on the transaction.
+    if (extension != nullptr) {
+        extension->setPipeThrough();
+        pkt = extension->getPacket();
+    } else {
+        pkt = generatePacket(trans);
+    }
+
+    auto tlmSenderState = new TlmSenderState(trans);
+    pkt->pushSenderState(tlmSenderState);
+
+    if (bmp.sendTimingReq(pkt)) { // port is free -> send END_REQ immediately
+        sendEndReq(trans);
+        trans.release();
+    } else { // port is blocked -> wait for retry before sending END_REQ
+        waitForRetry = true;
+        pendingRequest = &trans;
+        pendingPacket = pkt;
+    }
+}
+
+void
+TlmToGem5Bridge::handleEndResp(tlm::tlm_generic_payload &trans)
+{
+    sc_assert(responseInProgress);
+
+    responseInProgress = false;
+
+    checkTransaction(trans);
+
+    if (needToSendRetry) {
+        bmp.sendRetryResp();
+        needToSendRetry = false;
+    }
+}
+
+PacketPtr
+TlmToGem5Bridge::generatePacket(tlm::tlm_generic_payload &trans)
+{
+    MemCmd cmd;
+
+    switch (trans.get_command()) {
+        case tlm::TLM_READ_COMMAND:
+            cmd = MemCmd::ReadReq;
+            break;
+        case tlm::TLM_WRITE_COMMAND:
+            cmd = MemCmd::WriteReq;
+            break;
+        case tlm::TLM_IGNORE_COMMAND:
+            return nullptr;
+        default:
+            SC_REPORT_FATAL("TlmToGem5Bridge",
+                            "received transaction with unsupported command");
+    }
+
+    Request::Flags flags;
+    auto req = std::make_shared<Request>(
+        trans.get_address(), trans.get_data_length(), flags, masterId);
+
+    /*
+     * Allocate a new Packet. The packet will be deleted when it returns from
+     * the gem5 world as a response.
+     */
+    auto pkt = new Packet(req, cmd);
+    pkt->dataStatic(trans.get_data_ptr());
+
+    return pkt;
+}
+
+void
+TlmToGem5Bridge::destroyPacket(PacketPtr pkt)
+{
+    delete pkt;
+}
+
+void
+TlmToGem5Bridge::checkTransaction(tlm::tlm_generic_payload &trans)
+{
+    if (trans.is_response_error()) {
+        std::stringstream ss;
+        ss << "Transaction returned with error, response status = "
+           << trans.get_response_string();
+        SC_REPORT_ERROR("TLM-2", ss.str().c_str());
+    }
+}
+
+void
+TlmToGem5Bridge::peq_cb(tlm::tlm_generic_payload &trans,
+                        const tlm::tlm_phase &phase)
+{
+    switch (phase) {
+        case tlm::BEGIN_REQ:
+            handleBeginReq(trans);
+            break;
+        case tlm::END_RESP:
+            handleEndResp(trans);
+            break;
+        default:
+            panic("unimplemented phase in callback");
+    }
+}
+
+tlm::tlm_sync_enum
+TlmToGem5Bridge::nb_transport_fw(
+        tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase,
+        sc_core::sc_time &delay)
+{
+    unsigned len = trans.get_data_length();
+    unsigned char *byteEnable = trans.get_byte_enable_ptr();
+    unsigned width = trans.get_streaming_width();
+
+    // check the transaction attributes for unsupported features ...
+    if (byteEnable != 0) {
+        trans.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE);
+        return tlm::TLM_COMPLETED;
+    }
+    if (width < len) { // is this a burst request?
+        trans.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE);
+        return tlm::TLM_COMPLETED;
+    }
+
+    // ... and queue the valid transaction
+    trans.acquire();
+    peq.notify(trans, phase, delay);
+    return tlm::TLM_ACCEPTED;
+}
+
+void
+TlmToGem5Bridge::b_transport(tlm::tlm_generic_payload &trans,
+                             sc_core::sc_time &t)
+{
+    Gem5SystemC::Gem5Extension *extension = nullptr;
+    trans.get_extension(extension);
+
+    PacketPtr pkt = nullptr;
+
+    // If there is an extension, this transaction was initiated by the gem5
+    // world and we can pipe through the original packet.
+    if (extension != nullptr) {
+        extension->setPipeThrough();
+        pkt = extension->getPacket();
+    } else {
+        pkt = generatePacket(trans);
+    }
+
+    Tick ticks = bmp.sendAtomic(pkt);
+
+    // send an atomic request to gem5
+    panic_if(pkt->needsResponse() && !pkt->isResponse(),
+             "Packet sending failed!\n");
+
+    auto delay =
+      sc_core::sc_time((double)(ticks / SimClock::Int::ps), sc_core::SC_PS);
+
+    // update time
+    t += delay;
+
+    if (extension == nullptr)
+        destroyPacket(pkt);
+
+    trans.set_response_status(tlm::TLM_OK_RESPONSE);
+}
+
+unsigned int
+TlmToGem5Bridge::transport_dbg(tlm::tlm_generic_payload &trans)
+{
+    Gem5SystemC::Gem5Extension *extension = nullptr;
+    trans.get_extension(extension);
+
+    // If there is an extension, this transaction was initiated by the gem5
+    // world and we can pipe through the original packet.
+    if (extension != nullptr) {
+        extension->setPipeThrough();
+        bmp.sendFunctional(extension->getPacket());
+    } else {
+        auto pkt = generatePacket(trans);
+        if (pkt) {
+            bmp.sendFunctional(pkt);
+            destroyPacket(pkt);
+        }
+    }
+
+    return trans.get_data_length();
+}
+
+bool
+TlmToGem5Bridge::get_direct_mem_ptr(tlm::tlm_generic_payload &trans,
+                                    tlm::tlm_dmi &dmi_data)
+{
+    return false;
+}
+
+bool
+TlmToGem5Bridge::recvTimingResp(PacketPtr pkt)
+{
+    // exclusion rule
+    // We need to Wait for END_RESP before sending next BEGIN_RESP
+    if (responseInProgress) {
+        sc_assert(!needToSendRetry);
+        needToSendRetry = true;
+        return false;
+    }
+
+    sc_assert(pkt->isResponse());
+
+    /*
+     * Pay for annotated transport delays.
+     *
+     * See recvTimingReq in sc_slave_port.cc for a detailed description.
+     */
+    auto delay = sc_core::sc_time::from_value(pkt->payloadDelay);
+    // reset the delays
+    pkt->payloadDelay = 0;
+    pkt->headerDelay = 0;
+
+    auto tlmSenderState = dynamic_cast<TlmSenderState*>(pkt->popSenderState());
+    sc_assert(tlmSenderState != nullptr);
+
+    auto &trans = tlmSenderState->trans;
+
+    Gem5SystemC::Gem5Extension *extension = nullptr;
+    trans.get_extension(extension);
+
+    // clean up
+    delete tlmSenderState;
+
+    // If there is an extension the packet was piped through and we must not
+    // delete it. The packet travels back with the transaction.
+    if (extension == nullptr)
+        destroyPacket(pkt);
+    else
+        sc_assert(extension->isPipeThrough());
+
+    sendBeginResp(trans, delay);
+    trans.release();
+
+    return true;
+}
+
+void
+TlmToGem5Bridge::recvReqRetry()
+{
+    sc_assert(waitForRetry);
+    sc_assert(pendingRequest != nullptr);
+    sc_assert(pendingPacket != nullptr);
+
+    if (bmp.sendTimingReq(pendingPacket)) {
+        waitForRetry = false;
+        pendingPacket = nullptr;
+
+        auto &trans = *pendingRequest;
+        sendEndReq(trans);
+        trans.release();
+
+        pendingRequest = nullptr;
+    }
+}
+
+void
+TlmToGem5Bridge::recvRangeChange()
+{
+    SC_REPORT_WARNING("TlmToGem5Bridge",
+                      "received address range change but ignored it");
+}
+
+::Port &
+TlmToGem5Bridge::gem5_getPort(const std::string &if_name, int idx)
+{
+    if (if_name == "gem5")
+        return bmp;
+    else if (if_name == "tlm")
+        return wrapper;
+
+    return sc_core::sc_module::gem5_getPort(if_name, idx);
+}
+
+TlmToGem5Bridge::TlmToGem5Bridge(
+        Params *params, const sc_core::sc_module_name &mn) :
+    sc_core::sc_module(mn), peq(this, &TlmToGem5Bridge::peq_cb),
+    waitForRetry(false), pendingRequest(nullptr), pendingPacket(nullptr),
+    needToSendRetry(false), responseInProgress(false),
+    bmp(std::string(name()) + "master", *this), socket("tlm_socket"),
+    wrapper(socket, std::string(name()) + ".tlm", InvalidPortID),
+    system(params->system),
+    masterId(params->system->getGlobalMasterId(
+                std::string("[systemc].") + name()))
+{
+}
+
+void
+TlmToGem5Bridge::before_end_of_elaboration()
+{
+    /*
+     * Register the TLM non-blocking interface when using gem5 Timing mode and
+     * the TLM blocking interface when using the gem5 Atomic mode.
+     * Then the magic (TM) in simple_target_socket automatically transforms
+     * non-blocking in blocking transactions and vice versa.
+     *
+     * NOTE: The mode may change during execution.
+     */
+    if (system->isTimingMode()) {
+        SC_REPORT_INFO("TlmToGem5Bridge", "register non-blocking interface");
+        socket.register_nb_transport_fw(
+                this, &TlmToGem5Bridge::nb_transport_fw);
+    } else if (system->isAtomicMode()) {
+        SC_REPORT_INFO("TlmToGem5Bridge", "register blocking interface");
+        socket.register_b_transport(
+                this, &TlmToGem5Bridge::b_transport);
+    } else {
+        panic("gem5 operates neither in Timing nor in Atomic mode");
+    }
+
+    socket.register_transport_dbg(this, &TlmToGem5Bridge::transport_dbg);
+
+    sc_core::sc_module::before_end_of_elaboration();
+}
+
+} // namespace sc_gem5
+
+sc_gem5::TlmToGem5Bridge *
+TlmToGem5BridgeParams::create()
+{
+    return new sc_gem5::TlmToGem5Bridge(
+            this, sc_core::sc_module_name(name.c_str()));
+}
diff --git a/src/systemc/tlm_bridge/tlm_to_gem5.hh b/src/systemc/tlm_bridge/tlm_to_gem5.hh
new file mode 100644
index 0000000..1d6fa13
--- /dev/null
+++ b/src/systemc/tlm_bridge/tlm_to_gem5.hh
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2019 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.
+ *
+ * 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: Gabe Black
+ *          Christian Menard
+ */
+
+#ifndef __SYSTEMC_TLM_BRIDGE_TLM_TO_GEM5_HH__
+#define __SYSTEMC_TLM_BRIDGE_TLM_TO_GEM5_HH__
+
+#include "mem/port.hh"
+#include "params/TlmToGem5Bridge.hh"
+#include "systemc/ext/core/sc_module.hh"
+#include "systemc/ext/core/sc_module_name.hh"
+#include "systemc/ext/tlm_core/2/generic_payload/gp.hh"
+#include "systemc/ext/tlm_utils/peq_with_cb_and_phase.h"
+#include "systemc/ext/tlm_utils/simple_target_socket.h"
+#include "systemc/tlm_bridge/sc_ext.hh"
+#include "systemc/tlm_port_wrapper.hh"
+
+namespace sc_gem5
+{
+
+class TlmToGem5Bridge : public sc_core::sc_module
+{
+  private:
+    struct TlmSenderState : public Packet::SenderState
+    {
+        tlm::tlm_generic_payload &trans;
+        TlmSenderState(tlm::tlm_generic_payload &trans) : trans(trans) {}
+    };
+
+    class BridgeMasterPort : public MasterPort
+    {
+      protected:
+        TlmToGem5Bridge &bridge;
+
+        bool
+        recvTimingResp(PacketPtr pkt) override
+        {
+            return bridge.recvTimingResp(pkt);
+        }
+        void recvReqRetry() override { bridge.recvReqRetry(); }
+        void recvRangeChange() override { bridge.recvRangeChange(); }
+
+      public:
+        BridgeMasterPort(const std::string &name_, TlmToGem5Bridge &bridge_) :
+            MasterPort(name_, nullptr), bridge(bridge_)
+        {}
+    };
+
+    tlm_utils::peq_with_cb_and_phase<TlmToGem5Bridge> peq;
+
+    bool waitForRetry;
+    tlm::tlm_generic_payload *pendingRequest;
+    PacketPtr pendingPacket;
+
+    bool needToSendRetry;
+
+    bool responseInProgress;
+
+    BridgeMasterPort bmp;
+    tlm_utils::simple_target_socket<TlmToGem5Bridge, 64> socket;
+    sc_gem5::TlmTargetWrapper<64> wrapper;
+
+    System *system;
+
+    void sendEndReq(tlm::tlm_generic_payload &trans);
+    void sendBeginResp(tlm::tlm_generic_payload &trans,
+                       sc_core::sc_time &delay);
+
+    void handleBeginReq(tlm::tlm_generic_payload &trans);
+    void handleEndResp(tlm::tlm_generic_payload &trans);
+
+    PacketPtr generatePacket(tlm::tlm_generic_payload &trans);
+    void destroyPacket(PacketPtr pkt);
+
+    void checkTransaction(tlm::tlm_generic_payload &trans);
+
+  protected:
+    // payload event call back
+    void peq_cb(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase);
+
+    // The TLM target interface
+    tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans,
+                                       tlm::tlm_phase &phase,
+                                       sc_core::sc_time &t);
+    void b_transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &t);
+    unsigned int transport_dbg(tlm::tlm_generic_payload &trans);
+    bool get_direct_mem_ptr(tlm::tlm_generic_payload &trans,
+                            tlm::tlm_dmi &dmi_data);
+
+    // Gem5 port interface.
+    bool recvTimingResp(PacketPtr pkt);
+    void recvReqRetry();
+    void recvRangeChange();
+
+  public:
+    ::Port &gem5_getPort(const std::string &if_name, int idx=-1) override;
+
+    typedef TlmToGem5BridgeParams Params;
+    TlmToGem5Bridge(Params *p, const sc_core::sc_module_name &mn);
+
+    tlm_utils::simple_target_socket<TlmToGem5Bridge, 64> &
+    getSocket()
+    {
+        return socket;
+    }
+
+    void before_end_of_elaboration() override;
+
+    const MasterID masterId;
+};
+
+} // namespace sc_gem5
+
+#endif // __SYSTEMC_TLM_BRIDGE_TLM_TO_GEM5_HH__
