Earl Ou has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/67232?usp=email )

Change subject: mem: create simple_port classes
......................................................................

mem: create simple_port classes

The simple_port classes convert the Request/ResponsePort from
inherit-base to callback registrations. This help 'composition over
inheritance' that most design pattern follows, which help reducing
code length and increase reusability.

Change-Id: Ia13cc62507ac8425bd7cf143a2e080d041c173f9
---
M src/mem/SConscript
A src/mem/simple_port.cc
A src/mem/simple_port.hh
3 files changed, 302 insertions(+), 0 deletions(-)



diff --git a/src/mem/SConscript b/src/mem/SConscript
index 3bcfc0d..c692e45 100644
--- a/src/mem/SConscript
+++ b/src/mem/SConscript
@@ -91,6 +91,7 @@
 Source('physical.cc')
 Source('shared_memory_server.cc')
 Source('simple_mem.cc')
+Source('simple_port.cc')
 Source('snoop_filter.cc')
 Source('stack_dist_calc.cc')
 Source('sys_bridge.cc')
diff --git a/src/mem/simple_port.cc b/src/mem/simple_port.cc
new file mode 100644
index 0000000..229b2a1
--- /dev/null
+++ b/src/mem/simple_port.cc
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2023 Google, LLC.
+ *
+ * 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.
+ */
+
+#include "mem/simple_port.hh"
+
+namespace gem5
+{
+
+SimpleRequestPort::SimpleRequestPort(const std::string& name,
+                                     SimObject* _owner, PortID id)
+    : RequestPort(name, _owner, id)
+{
+}
+
+void
+SimpleRequestPort::recvRangeChange()
+{
+    if (!recvRangeChangeCb) {
+        RequestPort::recvRangeChange();
+        return;
+    }
+    recvRangeChangeCb();
+}
+
+bool
+SimpleRequestPort::recvTimingResp(PacketPtr packet)
+{
+    panic_if(!recvTimingRespCb, "RecvTimingRespCallback is empty.");
+    return recvTimingRespCb(packet);
+}
+
+void
+SimpleRequestPort::recvReqRetry()
+{
+    panic_if(!recvReqRetryCb, "RecvReqRetryCallback is empty.");
+    recvReqRetryCb();
+}
+
+void
+SimpleRequestPort::setRangeChangeCallback(RecvReqRetryCallback cb)
+{
+    recvRangeChangeCb = std::move(cb);
+}
+
+void
+SimpleRequestPort::setTimingCallbacks(RecvTimingRespCallback resp_cb,
+                                      RecvReqRetryCallback retry_cb)
+{
+    recvTimingRespCb = std::move(resp_cb);
+    recvReqRetryCb = std::move(retry_cb);
+}
+
+SimpleResponsePort::SimpleResponsePort(const std::string& name,
+                                       SimObject* _owner, PortID id)
+    : ResponsePort(name, _owner, id)
+{
+}
+
+AddrRangeList
+SimpleResponsePort::getAddrRanges() const
+{
+    panic_if(!getAddrRangesCb, "GetAddrRangesCallback is empty.");
+    return getAddrRangesCb();
+}
+
+bool
+SimpleResponsePort::recvTimingReq(PacketPtr packet)
+{
+    panic_if(!recvTimingReqCb, "RecvTimingReqCallback is empty.");
+    return recvTimingReqCb(packet);
+}
+
+void
+SimpleResponsePort::recvRespRetry()
+{
+    panic_if(!recvRespRetryCb, "RecvRespRetryCallback is empty.");
+    recvRespRetryCb();
+}
+
+Tick
+SimpleResponsePort::recvAtomic(PacketPtr packet)
+{
+    panic_if(!recvAtomicCb, "RecvAtomicCallback is empty.");
+    return recvAtomicCb(packet);
+}
+
+Tick
+SimpleResponsePort::recvAtomicBackdoor(PacketPtr packet,
+                                       MemBackdoorPtr& backdoor)
+{
+    if (!recvAtomicBackdoorCb) {
+        return ResponsePort::recvAtomicBackdoor(packet, backdoor);
+    }
+    return recvAtomicBackdoorCb(packet, backdoor);
+}
+
+void
+SimpleResponsePort::recvFunctional(PacketPtr packet)
+{
+    panic_if(!recvFunctionalCb, "RecvFunctionalCallback is empty.");
+    recvTimingReqCb(packet);
+}
+
+void
+SimpleResponsePort::recvMemBackdoorReq(const MemBackdoorReq& req,
+                                       MemBackdoorPtr& backdoor)
+{
+    if (!recvMemBackdoorReqCb) {
+        ResponsePort::recvMemBackdoorReq(req, backdoor);
+        return;
+    }
+    recvMemBackdoorReqCb(req, backdoor);
+}
+
+void
+SimpleResponsePort::setGetAddrRangesCallback(GetAddrRangesCallback cb)
+{
+    getAddrRangesCb = std::move(cb);
+}
+
+void
+SimpleResponsePort::setTimingCallbacks(RecvTimingReqCallback timing_cb,
+                                       RecvRespRetryCallback retry_cb)
+{
+    recvTimingReqCb = std::move(timing_cb);
+    recvRespRetryCb = std::move(retry_cb);
+}
+
+void
+SimpleResponsePort::setAtomicCallbacks(RecvAtomicCallback atomic_cb,
+ RecvAtomicBackdoorCallback backdoor_cb)
+{
+    recvAtomicCb = std::move(atomic_cb);
+    recvAtomicBackdoorCb = std::move(backdoor_cb);
+}
+
+void
+SimpleResponsePort::setFunctionalCallbacks(
+    RecvFunctionalCallback func_cb, RecvMemBackdoorReqCallback backdoor_cb)
+{
+    recvFunctionalCb = std::move(func_cb);
+    recvMemBackdoorReqCb = std::move(backdoor_cb);
+}
+
+}  // namespace gem5
diff --git a/src/mem/simple_port.hh b/src/mem/simple_port.hh
new file mode 100644
index 0000000..619f06b
--- /dev/null
+++ b/src/mem/simple_port.hh
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2023 Google, LLC.
+ *
+ * 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.
+ */
+
+#ifndef __MEM_SIMPLE_PORT_HH__
+#define __MEM_SIMPLE_PORT_HH__
+
+#include <functional>
+
+#include "mem/port.hh"
+
+namespace gem5
+{
+
+class SimpleRequestPort : public RequestPort
+{
+  public:
+    using RecvRangeChangeCallback = std::function<void()>;
+    // Timing Protocol
+    using RecvTimingRespCallback = std::function<bool(PacketPtr)>;
+    using RecvReqRetryCallback = std::function<void()>;
+
+    SimpleRequestPort(const std::string& name, SimObject* _owner,
+                      PortID id = InvalidPortID);
+
+    void recvRangeChange() override;
+
+    // TimingRequestProtocol
+    bool recvTimingResp(PacketPtr) override;
+    void recvReqRetry() override;
+
+    void setRangeChangeCallback(RecvReqRetryCallback);
+    void setTimingCallbacks(RecvTimingRespCallback, RecvReqRetryCallback);
+
+  private:
+    RecvRangeChangeCallback recvRangeChangeCb = nullptr;
+    RecvTimingRespCallback recvTimingRespCb = nullptr;
+    RecvReqRetryCallback recvReqRetryCb = nullptr;
+};
+
+class SimpleResponsePort : public ResponsePort
+{
+  public:
+    using GetAddrRangesCallback = std::function<AddrRangeList()>;
+    // Timing Protocol
+    using RecvTimingReqCallback = std::function<bool(PacketPtr)>;
+    // Atomic Protocol
+    using RecvAtomicCallback = std::function<Tick(PacketPtr)>;
+    using RecvAtomicBackdoorCallback =
+        std::function<Tick(PacketPtr, MemBackdoorPtr&)>;
+
+    // Functional Protocol
+    using RecvFunctionalCallback = std::function<void(PacketPtr)>;
+    using RecvMemBackdoorReqCallback =
+        std::function<void(const MemBackdoorReq&, MemBackdoorPtr&)>;
+
+    using RecvRespRetryCallback = std::function<void()>;
+
+    SimpleResponsePort(const std::string& name, SimObject* _owner,
+                       PortID id = InvalidPortID);
+
+    AddrRangeList getAddrRanges() const override;
+
+    // TimingResponseProtocol
+    bool recvTimingReq(PacketPtr) override;
+    void recvRespRetry() override;
+
+    // AtomicResponseProtocol
+    Tick recvAtomic(PacketPtr) override;
+    Tick recvAtomicBackdoor(PacketPtr, MemBackdoorPtr&) override;
+
+    // FunctionalResponseProtocol
+    void recvFunctional(PacketPtr) override;
+ void recvMemBackdoorReq(const MemBackdoorReq&, MemBackdoorPtr&) override;
+
+    void setGetAddrRangesCallback(GetAddrRangesCallback);
+    void setTimingCallbacks(RecvTimingReqCallback, RecvRespRetryCallback);
+    void setAtomicCallbacks(RecvAtomicCallback,
+                            RecvAtomicBackdoorCallback = nullptr);
+    void setFunctionalCallbacks(RecvFunctionalCallback,
+                                RecvMemBackdoorReqCallback = nullptr);
+
+  private:
+    GetAddrRangesCallback getAddrRangesCb = nullptr;
+    RecvTimingReqCallback recvTimingReqCb = nullptr;
+    RecvRespRetryCallback recvRespRetryCb = nullptr;
+    RecvAtomicCallback recvAtomicCb = nullptr;
+    RecvAtomicBackdoorCallback recvAtomicBackdoorCb = nullptr;
+    RecvFunctionalCallback recvFunctionalCb = nullptr;
+    RecvMemBackdoorReqCallback recvMemBackdoorReqCb = nullptr;
+};
+
+}  // namespace gem5
+
+#endif  //__MEM_SIMPLE_PORT_HH__

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67232?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ia13cc62507ac8425bd7cf143a2e080d041c173f9
Gerrit-Change-Number: 67232
Gerrit-PatchSet: 1
Gerrit-Owner: Earl Ou <shunhsin...@google.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org

Reply via email to