From 291364e1b408d29236034854b7ed30f080e5b6c9 Mon Sep 17 00:00:00 2001 From: Johannes Stoelp Date: Wed, 1 Nov 2023 18:41:44 +0100 Subject: lt_bus: add initial support for global bus locking --- test/lt_bus.cc | 66 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 14 deletions(-) (limited to 'test/lt_bus.cc') 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 #include -#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; using len_t = detail::phantom; +using lock_t = detail::phantom; // -- 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()) { + 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(); + 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))); +} -- cgit v1.2.3