Skip to content

Commit 6531ba3

Browse files
author
Mahmoud Kamel
committed
addrtr: update the addrtr model to use mapped_base_addr parameter
- instead of using offset CCI parameter, a mapped_base_addr CCI parameter is used to translate the module base address to the mapped_base_addr, the transport functions and the test bench are adjusted to accomodate the change. Signed-off-by: Mahmoud Kamel <[email protected]>
1 parent 846249f commit 6531ba3

File tree

3 files changed

+136
-57
lines changed

3 files changed

+136
-57
lines changed

systemc-components/addrtr/include/addrtr.h

Lines changed: 112 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/*
2-
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
3-
* Author: GreenSocs 2022
2+
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
43
*
54
* SPDX-License-Identifier: BSD-3-Clause
65
*/
@@ -16,6 +15,7 @@
1615
#include <tlm_utils/simple_initiator_socket.h>
1716
#include <tlm_utils/simple_target_socket.h>
1817
#include <cci_configuration>
18+
#include <scp/report.h>
1919

2020
#include <libgsutils.h>
2121
#include <module_factory_registery.h>
@@ -27,72 +27,143 @@
2727
* @brief A Addrtr component that can add addrtr to a virtual platform project to manage the various
2828
* transactions
2929
*
30-
* @details This component models a addrtr. It has a single multi-target socket so any other
30+
* @details This component models a addrtr. It has a single target socket so another
3131
* component with an initiator socket can connect to this component. It behaves as follows:
32-
* - Manages exclusive accesses, adding this addrtr as a 'hop' in the exclusive access extension
33-
* (see GreenSocs/libgsutils).
34-
* - Manages connections to multiple initiators and targets with the method `add_initiator` and
35-
* `add_target`.
36-
* - Allows to manage read and write transactions with `b_transport` and `transport_dbg` methods.
37-
* - Supports passing through DMI requests with the method `get_direct_mem_ptr`.
38-
* - Handles invalidation of multiple DMI pointers with the method `invalidate_direct_mem_ptr`
39-
* which passes the invalidate back to *all* initiators.
40-
* - It checks for each transaction if the address is valid or not and returns an error if the
41-
* address is invalid with the method `decode_address`.
32+
* translate the target_socket address to the mapped_base_addr (CCI parameter) and reinitiate the transaction
33+
* using the initiator_socket.
4234
*/
4335

4436
class addrtr : public sc_core::sc_module
4537
{
4638
private:
47-
sc_dt::uint64 addr_fw(sc_dt::uint64 addr) { return addr + offset; }
48-
sc_dt::uint64 addr_bw(sc_dt::uint64 addr) { return addr - offset; }
49-
void translate_fw(tlm::tlm_generic_payload& trans) { trans.set_address(addr_fw(trans.get_address())); }
50-
void translate_bw(tlm::tlm_generic_payload& trans) { trans.set_address(addr_bw(trans.get_address())); }
39+
SCP_LOGGER();
40+
41+
sc_dt::uint64 addr_fw(sc_dt::uint64 addr)
42+
{
43+
auto offset = addr - m_base_addr;
44+
return p_mapped_base_addr.get_value() + offset;
45+
}
46+
47+
sc_dt::uint64 addr_bw(sc_dt::uint64 addr)
48+
{
49+
auto offset = addr - p_mapped_base_addr.get_value();
50+
return m_base_addr + offset;
51+
}
52+
53+
uint64_t map_txn_addr(tlm::tlm_generic_payload& trans)
54+
{
55+
uint64_t addr = trans.get_address();
56+
uint64_t len = trans.get_data_length();
57+
uint64_t mapped_addr = addr;
58+
if ((addr >= m_base_addr) && ((addr + len - 1) < (m_base_addr + m_mapping_size))) {
59+
mapped_addr = addr_fw(addr);
60+
trans.set_address(mapped_addr);
61+
} else {
62+
SCP_FATAL(()) << "The txn [addr: 0x" << std::hex << addr << "] len: 0x" << std::hex << len
63+
<< ", doesn't belong to the target_socket base address: 0x" << std::hex << m_base_addr
64+
<< " size: 0x" << std::hex << m_mapping_size;
65+
}
66+
return mapped_addr;
67+
}
68+
69+
void map_dmi_start_end_addr(uint64_t& start_addr, uint64_t& end_addr)
70+
{
71+
if (start_addr < p_mapped_base_addr.get_value()) {
72+
start_addr = m_base_addr;
73+
} else if ((start_addr >= p_mapped_base_addr.get_value()) &&
74+
(start_addr < (p_mapped_base_addr.get_value() + m_mapping_size))) {
75+
start_addr = addr_bw(start_addr);
76+
} else {
77+
SCP_FATAL(()) << "DMI granted start address 0x" << std::hex << start_addr
78+
<< " is bigger than the mapped area 0x" << std::hex << p_mapped_base_addr.get_value()
79+
<< " size: 0x" << std::hex << m_mapping_size;
80+
}
81+
if (end_addr >= (p_mapped_base_addr.get_value() + m_mapping_size)) {
82+
end_addr = m_base_addr + m_mapping_size;
83+
} else if ((end_addr > start_addr) && (end_addr < (p_mapped_base_addr.get_value() + m_mapping_size))) {
84+
end_addr = addr_bw(end_addr);
85+
} else {
86+
SCP_FATAL(()) << "DMI granted end address 0x" << std::hex << start_addr
87+
<< " is smaller than the mapped area 0x" << std::hex << p_mapped_base_addr.get_value()
88+
<< " size: 0x" << std::hex << m_mapping_size;
89+
}
90+
}
5191

5292
void b_transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay)
5393
{
54-
translate_fw(trans);
55-
back_socket->b_transport(trans, delay);
56-
translate_bw(trans);
94+
uint64_t orig_addr = trans.get_address();
95+
uint64_t mapped_addr = map_txn_addr(trans);
96+
SCP_DEBUG(()) << "b_transport to addr: 0x" << std::hex << orig_addr << " will be mapped to addr: 0x" << std::hex
97+
<< mapped_addr;
98+
initiator_socket->b_transport(trans, delay);
99+
trans.set_address(orig_addr);
57100
}
58101

59102
unsigned int transport_dbg(tlm::tlm_generic_payload& trans)
60103
{
61-
sc_dt::uint64 addr = trans.get_address();
62-
63-
translate_fw(trans);
64-
unsigned int r = back_socket->transport_dbg(trans);
65-
translate_bw(trans);
66-
return r;
104+
uint64_t orig_addr = trans.get_address();
105+
uint64_t mapped_addr = map_txn_addr(trans);
106+
SCP_DEBUG(()) << "transport_dbg to addr: 0x" << std::hex << orig_addr << " will be mapped to addr: 0x"
107+
<< std::hex << mapped_addr;
108+
unsigned int ret = initiator_socket->transport_dbg(trans);
109+
trans.set_address(orig_addr);
110+
return ret;
67111
}
68112

69113
bool get_direct_mem_ptr(tlm::tlm_generic_payload& trans, tlm::tlm_dmi& dmi_data)
70114
{
71-
sc_dt::uint64 addr = trans.get_address();
72-
73-
translate_fw(trans);
74-
bool r = back_socket->get_direct_mem_ptr(trans, dmi_data);
75-
translate_bw(trans);
76-
return r;
115+
uint64_t orig_addr = trans.get_address();
116+
uint64_t mapped_addr = map_txn_addr(trans);
117+
bool ret = initiator_socket->get_direct_mem_ptr(trans, dmi_data);
118+
trans.set_address(orig_addr);
119+
if (ret) {
120+
uint64_t start_addr = dmi_data.get_start_address();
121+
uint64_t end_addr = dmi_data.get_end_address();
122+
map_dmi_start_end_addr(start_addr, end_addr);
123+
dmi_data.set_start_address(start_addr);
124+
dmi_data.set_end_address(end_addr);
125+
SCP_DEBUG(()) << "DMI was granted to range 0x" << std::hex << start_addr << " - 0x" << std::hex << end_addr;
126+
}
127+
return ret;
77128
}
78129

79130
void invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end)
80131
{
81-
front_socket->invalidate_direct_mem_ptr(addr_bw(start), addr_bw(end));
132+
uint64_t start_addr = start;
133+
uint64_t end_addr = end;
134+
map_dmi_start_end_addr(start_addr, end_addr);
135+
SCP_DEBUG(()) << "invalidate_direct_mem_ptr request to range 0x" << std::hex << start_addr << " - 0x"
136+
<< std::hex << end_addr;
137+
target_socket->invalidate_direct_mem_ptr(start_addr, end_addr);
82138
}
83139

140+
private:
141+
cci::cci_broker_handle m_broker;
142+
uint64_t m_base_addr;
143+
uint64_t m_mapping_size;
144+
84145
public:
85-
tlm_utils::simple_target_socket<addrtr, DEFAULT_TLM_BUSWIDTH> front_socket;
86-
tlm_utils::simple_initiator_socket<addrtr, DEFAULT_TLM_BUSWIDTH> back_socket;
87-
cci::cci_param<uint64_t> offset;
146+
tlm_utils::simple_target_socket<addrtr, DEFAULT_TLM_BUSWIDTH> target_socket;
147+
tlm_utils::simple_initiator_socket<addrtr, DEFAULT_TLM_BUSWIDTH> initiator_socket;
148+
cci::cci_param<uint64_t> p_mapped_base_addr;
88149

150+
public:
89151
explicit addrtr(const sc_core::sc_module_name& nm)
90-
: sc_core::sc_module(nm), back_socket("initiator"), front_socket("target"), offset("offset", 0)
152+
: sc_core::sc_module(nm)
153+
, m_broker(cci::cci_get_broker())
154+
, initiator_socket("initiator_socket")
155+
, target_socket("target_socket")
156+
, p_mapped_base_addr("mapped_base_addr", 0, "base adress for mapping")
91157
{
92-
front_socket.register_b_transport(this, &addrtr::b_transport);
93-
front_socket.register_transport_dbg(this, &addrtr::transport_dbg);
94-
front_socket.register_get_direct_mem_ptr(this, &addrtr::get_direct_mem_ptr);
95-
back_socket.register_invalidate_direct_mem_ptr(this, &addrtr::invalidate_direct_mem_ptr);
158+
SCP_TRACE(())("addrtr constructor");
159+
target_socket.register_b_transport(this, &addrtr::b_transport);
160+
target_socket.register_transport_dbg(this, &addrtr::transport_dbg);
161+
target_socket.register_get_direct_mem_ptr(this, &addrtr::get_direct_mem_ptr);
162+
initiator_socket.register_invalidate_direct_mem_ptr(this, &addrtr::invalidate_direct_mem_ptr);
163+
m_base_addr = gs::cci_get<uint64_t>(m_broker,
164+
std::string(sc_core::sc_module::name()) + ".target_socket.address");
165+
m_mapping_size = gs::cci_get<uint64_t>(m_broker,
166+
std::string(sc_core::sc_module::name()) + ".target_socket.size");
96167
}
97168

98169
addrtr() = delete;

tests/base-components/addrtr/addrtr-bench.h

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/*
2-
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
3-
* Author: GreenSocs 2022
2+
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
43
*
54
* SPDX-License-Identifier: BSD-3-Clause
65
*/
@@ -21,6 +20,7 @@
2120

2221
class AddrtrTestBench : public TestBench
2322
{
23+
public:
2424
static constexpr size_t TARGET_MMIO_SIZE = 1024;
2525

2626
class TargetTesterDMIinv : public TargetTester
@@ -43,7 +43,7 @@ class AddrtrTestBench : public TestBench
4343
TargetTesterDMIinv m_target;
4444

4545
uint64_t sent_addr;
46-
uint64_t offset = 0xDEAD;
46+
uint64_t offset = 0xDEADULL;
4747

4848
/* Initiator callback */
4949
void invalidate_direct_mem_ptr(uint64_t start_range, uint64_t end_range)
@@ -66,9 +66,9 @@ class AddrtrTestBench : public TestBench
6666
}
6767

6868
protected:
69-
void do_txn(int id, uint64_t addr, bool dbg)
69+
void do_txn(uint64_t addr, bool dbg)
7070
{
71-
uint64_t data = 0x42;
71+
uint64_t data = 0x42ULL;
7272
TlmGenericPayload txn;
7373
sent_addr = addr;
7474
if (!dbg) {
@@ -78,9 +78,9 @@ class AddrtrTestBench : public TestBench
7878
}
7979
}
8080

81-
void do_dmi(int id, uint64_t addr)
81+
void do_dmi(uint64_t addr)
8282
{
83-
uint64_t data = 0x42;
83+
uint64_t data = 0x42ULL;
8484
TlmGenericPayload txn;
8585
sent_addr = addr;
8686
m_initiator.do_dmi_request(addr);
@@ -90,14 +90,13 @@ class AddrtrTestBench : public TestBench
9090
public:
9191
AddrtrTestBench(const sc_core::sc_module_name& n)
9292
: TestBench(n)
93-
, m_addrtr("exclusive-addrtr")
93+
, m_addrtr("exclusive_addrtr")
9494
, m_initiator("initiator-tester")
9595
, m_target("target-tester", TARGET_MMIO_SIZE)
9696
{
9797
using namespace std::placeholders;
9898

99-
offset = 10;
100-
m_addrtr.offset = offset;
99+
offset = 0x10ULL;
101100

102101
m_initiator.register_invalidate_direct_mem_ptr(
103102
std::bind(&AddrtrTestBench::invalidate_direct_mem_ptr, this, _1, _2));
@@ -106,8 +105,8 @@ class AddrtrTestBench : public TestBench
106105
m_target.register_debug_write_cb(std::bind(&AddrtrTestBench::target_access, this, _1, _2, _3));
107106
m_target.register_get_direct_mem_ptr_cb(std::bind(&AddrtrTestBench::get_direct_mem_ptr, this, _1, _2));
108107

109-
m_addrtr.front_socket.bind(m_initiator.socket);
110-
m_addrtr.back_socket.bind(m_target.socket);
108+
m_addrtr.target_socket.bind(m_initiator.socket);
109+
m_addrtr.initiator_socket.bind(m_target.socket);
111110
}
112111

113112
virtual ~AddrtrTestBench() {}

tests/base-components/addrtr/addrtr-tests.cc

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,21 @@
1414
* Regular load and stores. Check that the monitor does not introduce bugs when
1515
* no exclusive transaction are in use.
1616
*/
17-
TEST_BENCH(AddrtrTestBench, simlpletxn) { do_txn(0, 100, 0); }
18-
TEST_BENCH(AddrtrTestBench, dbgtxn) { do_txn(1, 100, 1); }
19-
TEST_BENCH(AddrtrTestBench, dmiinv) { do_dmi(2, 100); }
17+
TEST_BENCH(AddrtrTestBench, Tester)
18+
{
19+
do_txn(0x100ULL, 0);
20+
do_txn(0x100ULL, 1);
21+
do_dmi(0x100ULL);
22+
}
23+
2024
int sc_main(int argc, char* argv[])
2125
{
22-
auto m_broker = new gs::ConfigurableBroker();
26+
gs::ConfigurableBroker m_broker({
27+
{ "log_level", cci::cci_value(5) },
28+
{ "Tester.exclusive_addrtr.target_socket.address", cci::cci_value(0x100ULL) },
29+
{ "Tester.exclusive_addrtr.target_socket.size", cci::cci_value(AddrtrTestBench::TARGET_MMIO_SIZE) },
30+
{ "Tester.exclusive_addrtr.mapped_base_addr", cci::cci_value(0x110ULL) },
31+
});
2332

2433
::testing::InitGoogleTest(&argc, argv);
2534
return RUN_ALL_TESTS();

0 commit comments

Comments
 (0)