quic/qbox
Loading...
Searching...
No Matches
addrtr.h
1/*
2 * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _GREENSOCS_BASE_COMPONENTS_ADDRTR_H
8#define _GREENSOCS_BASE_COMPONENTS_ADDRTR_H
9
10#include <cinttypes>
11#include <vector>
12
13#include <systemc>
14#include <tlm>
15#include <tlm_utils/simple_initiator_socket.h>
16#include <tlm_utils/simple_target_socket.h>
17#include <cci_configuration>
18#include <scp/report.h>
19
20#include <libgsutils.h>
21#include <module_factory_registery.h>
22#include <tlm_sockets_buswidth.h>
23
36class addrtr : public sc_core::sc_module
37{
38private:
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();
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 }
91
92 void b_transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay)
93 {
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);
100 }
101
102 unsigned int transport_dbg(tlm::tlm_generic_payload& trans)
103 {
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;
111 }
112
113 bool get_direct_mem_ptr(tlm::tlm_generic_payload& trans, tlm::tlm_dmi& dmi_data)
114 {
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;
128 }
129
130 void invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end)
131 {
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);
138 }
139
140private:
141 cci::cci_broker_handle m_broker;
142 uint64_t m_base_addr;
143 uint64_t m_mapping_size;
144
145public:
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;
149
150public:
151 explicit addrtr(const sc_core::sc_module_name& nm)
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")
157 {
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");
167 }
168
169 addrtr() = delete;
170
171 addrtr(const addrtr&) = delete;
172
173 virtual ~addrtr() {}
174};
175
176extern "C" void module_register();
177
178#endif
Definition target.h:160
Definition addrtr.h:37