aboutsummaryrefslogtreecommitdiff
path: root/test/lt_bus.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/lt_bus.cc')
-rw-r--r--test/lt_bus.cc66
1 files changed, 52 insertions, 14 deletions
diff --git a/test/lt_bus.cc b/test/lt_bus.cc
index ffbad9d..4f7fcf7 100644
--- a/test/lt_bus.cc
+++ b/test/lt_bus.cc
@@ -7,7 +7,6 @@
#include <tlm_utils/simple_target_socket.h>
#include <sstream>
-#include "gmock/gmock.h"
using testing::_;
@@ -28,11 +27,13 @@ struct [[nodiscard]] phantom {
namespace tag {
struct addr;
struct len;
+struct lock;
} // namespace tag
} // namespace detail
using addr_t = detail::phantom<detail::tag::addr, sc_dt::uint64>;
using len_t = detail::phantom<detail::tag::len, u32>;
+using lock_t = detail::phantom<detail::tag::len, bool>;
// -- TLM TARGET MOCK ----------------------------------------------------------
@@ -75,10 +76,15 @@ struct initiator : public sc_core::sc_module {
MOCK_METHOD(void, invalidate_direct_mem_ptr, (sc_dt::uint64, sc_dt::uint64));
- bool transport(addr_t a, len_t l) {
+ bool transport(addr_t a, len_t l, lock_t lk = lock_t{false}) {
tlm::tlm_generic_payload tx;
setup_tx(tx, a, l);
+ // Set bus lock extension (will be owned by gp).
+ auto* bl = new bus_lock;
+ bl->is_lock = lk.cast();
+ tx.set_extension(bl);
+
sc_core::sc_time t;
p_sock->b_transport(tx, t);
// Check bus restored correct original address.
@@ -130,21 +136,14 @@ struct initiator : public sc_core::sc_module {
static std::string tx_to_str(const tlm::tlm_generic_payload& tx) {
std::ostringstream oss;
// Only print values we are interested in in the tests.
- oss << "tx.addr=0x" << std::hex << tx.get_address() << std::dec << ',';
- oss << "tx.len=" << tx.get_data_length();
+ oss << "tx.addr=0x" << std::hex << tx.get_address() << std::dec;
+ oss << ",tx.len=" << tx.get_data_length();
+ if (const bus_lock* ext = tx.get_extension<bus_lock>()) {
+ oss << ",tx.is_lock=" << ext->is_lock;
+ }
return oss.str();
};
-MATCHER_P(gp_addr,
- /* arg0 */ arg_addr,
- /* desc */ [](addr_t a) {
- tlm::tlm_generic_payload tx;
- tx.set_address(a.cast());
- return tx_to_str(tx);
- }(arg_addr /* ign negation arg */)) {
- return arg.get_address() == arg_addr.cast();
-}
-
// Custom generic payload (gp) address and length matcher.
MATCHER_P2(gp_addr_len,
/* arg0 */ arg_addr,
@@ -159,6 +158,26 @@ MATCHER_P2(gp_addr_len,
arg.get_data_length() == arg_len.cast();
}
+// Custom generic payload (gp) address, length and lock matcher.
+MATCHER_P3(gp_addr_len_lock,
+ /* arg0 */ arg_addr,
+ /* arg1 */ arg_len,
+ /* arg2 */ arg_lock,
+ /* desc */ [](addr_t a, len_t l, lock_t lk) {
+ tlm::tlm_generic_payload tx;
+ tx.set_address(a.cast());
+ tx.set_data_length(l.cast());
+ auto* ext = new bus_lock;
+ ext->is_lock = lk.cast();
+ tx.set_extension(ext);
+ return tx_to_str(tx);
+ }(arg_addr, arg_len, arg_lock /* ign negation arg */)) {
+ const auto* ext = arg.template get_extension<bus_lock>();
+ return arg.get_address() == arg_addr.cast() &&
+ arg.get_data_length() == arg_len.cast() && ext &&
+ ext->is_lock == arg_lock.cast();
+}
+
// Define operator<< for tlm generic payloads in the tlm namespace. Used
// by gtest/gmock when printing payload objects.
// It is not a good practice to add functions to non-owned namespaced but for
@@ -335,3 +354,22 @@ TEST_F(bus_test, invalidate_dmi) {
EXPECT_CALL(i2, invalidate_direct_mem_ptr(0xa80, 0xaff));
t2.inv_dmi(0x80, 0x101);
}
+
+TEST_F(bus_test, fwd_lock) {
+ bus.attach_target(t1.p_sock, 0x400, 0x7ff);
+
+ testing::InSequence seq;
+
+ // Unlocked access.
+ EXPECT_CALL(
+ t1,
+ b_transport(gp_addr_len_lock(addr_t(0x0), len_t(1), lock_t(false)), _));
+ ASSERT_TRUE(i1.transport(addr_t(0x400), len_t(1), lock_t(false)));
+
+ // Locked access -> invalidates DMI pointer.
+ EXPECT_CALL(i1, invalidate_direct_mem_ptr(0x0, -1ull));
+ EXPECT_CALL(
+ t1,
+ b_transport(gp_addr_len_lock(addr_t(0x100), len_t(1), lock_t(true)), _));
+ ASSERT_TRUE(i1.transport(addr_t(0x500), len_t(1), lock_t(true)));
+}