gem5 v24.0.0.0
Loading...
Searching...
No Matches
gp.cc
Go to the documentation of this file.
1/*****************************************************************************
2
3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4 more contributor license agreements. See the NOTICE file distributed
5 with this work for additional information regarding copyright ownership.
6 Accellera licenses this file to you under the Apache License, Version 2.0
7 (the "License"); you may not use this file except in compliance with the
8 License. You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15 implied. See the License for the specific language governing
16 permissions and limitations under the License.
17
18 *****************************************************************************/
19
20#include <cstring> // std::memcpy et.al.
21#include <map>
22#include <typeindex>
23
25
26namespace tlm
27{
28
29template class tlm_array<tlm_extension_base *>;
30
31//---------------------------------------------------------------------------
32// Classes for the extension mechanism
33//---------------------------------------------------------------------------
34
35namespace
36{
37
38class tlm_extension_registry
39{
40 typedef unsigned int key_type;
41 typedef std::map<std::type_index, key_type> type_map;
42 public:
43 static tlm_extension_registry &
44 instance()
45 {
46 if (!instance_) {
47 // Don't cleanup registry.
48 instance_ = new tlm_extension_registry();
49 }
50 return *instance_;
51 }
52
53 unsigned int
54 register_extension(std::type_index type)
55 {
56 type_map::const_iterator it = ids_.find(type);
57
58 if (it == ids_.end()) {
59 // New extension - generate/store ID.
60 type_map::value_type v(type, static_cast<key_type>(ids_.size()));
61 ids_.insert(v);
62 return v.second;
63 }
64 return it->second;
65 }
66
67 static unsigned int
69 {
70 return (instance_) ? instance().ids_.size() : 0;
71 }
72
73 private:
74 static tlm_extension_registry *instance_;
75 type_map ids_;
76 tlm_extension_registry() {}
77
78};
79
80tlm_extension_registry *tlm_extension_registry::instance_ = NULL;
81
82} // anonymous namespace
83
84unsigned int
86{
87 return tlm_extension_registry::max_num_extensions();
88}
89
90unsigned int
91tlm_extension_base::register_extension(const std::type_info &type)
92{
93 return tlm_extension_registry::instance().register_extension(type);
94}
95
96//---------------------------------------------------------------------------
97// The generic payload class:
98//---------------------------------------------------------------------------
99
101 m_command(TLM_IGNORE_COMMAND), m_data(0), m_length(0),
102 m_response_status(TLM_INCOMPLETE_RESPONSE), m_dmi(false), m_byte_enable(0),
103 m_byte_enable_length(0), m_streaming_width(0),
104 m_gp_option(TLM_MIN_PAYLOAD), m_extensions(max_num_extensions()), m_mm(0),
105 m_ref_count(0)
106{}
107
109 m_command(TLM_IGNORE_COMMAND), m_data(0), m_length(0),
110 m_response_status(TLM_INCOMPLETE_RESPONSE), m_dmi(false), m_byte_enable(0),
111 m_byte_enable_length(0), m_streaming_width(0),
112 m_gp_option(TLM_MIN_PAYLOAD), m_extensions(max_num_extensions()), m_mm(mm),
113 m_ref_count(0)
114{}
115
116void
118{
119 // Should the other members be reset too?
121 m_extensions.free_entire_cache();
122};
123
124// Non-virtual deep-copying of the object.
125void
127{
128 m_command = other.get_command();
129 m_address = other.get_address();
130 m_length = other.get_data_length();
134 m_gp_option = other.get_gp_option();
135 m_dmi = other.is_dmi_allowed();
136
137 // Deep copy data.
138 // There must be enough space in the target transaction!
139 if (m_data && other.m_data) {
140 std::memcpy(m_data, other.m_data, m_length);
141 }
142 // Deep copy byte enables.
143 // There must be enough space in the target transaction!
144 if (m_byte_enable && other.m_byte_enable) {
146 }
147 // Deep copy extensions (sticky and non-sticky).
148 if (m_extensions.size() < other.m_extensions.size()) {
149 m_extensions.expand(other.m_extensions.size());
150 }
151 for (unsigned int i = 0; i < other.m_extensions.size(); i++) {
152 if (other.m_extensions[i]) {
153 // Original has extension i.
154 if (!m_extensions[i]) {
155 // We don't: clone.
156 tlm_extension_base *ext = other.m_extensions[i]->clone();
157 if (ext) { // Extension may not be clonable.
158 if (has_mm()) {
159 // mm can take care of removing cloned extensions.
160 set_auto_extension(i, ext);
161 } else {
162 // no mm, user will call free_all_extensions().
163 set_extension(i, ext);
164 }
165 }
166 } else {
167 // We already have such extension. Copy original over it.
168 m_extensions[i]->copy_from(*other.m_extensions[i]);
169 }
170 }
171 }
172}
173
174// To update the state of the original generic payload from a deep copy.
175// Assumes that "other" was created from the original by calling
176// deep_copy_from. Argument use_byte_enable_on_read determines whether to use
177// or ignores byte enables when copying back the data array on a read command.
178
179void
181 const tlm_generic_payload &other, bool use_byte_enable_on_read)
182{
183 // Copy back extensions that are present on the original.
185
186 // Copy back the response status and DMI hint attributes.
188 m_dmi = other.is_dmi_allowed();
189
190 // Copy back the data array for a read command only deep_copy_from allowed
191 // null pointers, and so will we.
192 // We assume the arrays are the same size.
193 // We test for equal pointers in case the original and the copy share the
194 // same array.
195
196 if (is_read() && m_data && other.m_data && m_data != other.m_data) {
197 if (m_byte_enable && use_byte_enable_on_read) {
198 if (m_byte_enable_length == 8 && m_length % 8 == 0) {
199 // Optimized implementation copies 64-bit words by masking.
200 for (unsigned int i = 0; i < m_length; i += 8) {
201 typedef sc_dt::uint64 *u;
202 *reinterpret_cast<u>(&m_data[i]) &=
203 ~*reinterpret_cast<u>(m_byte_enable);
204 *reinterpret_cast<u>(&m_data[i]) |=
205 *reinterpret_cast<u>(&other.m_data[i]) &
206 *reinterpret_cast<u>(m_byte_enable);
207 }
208 } else if (m_byte_enable_length == 4 && m_length % 4 == 0) {
209 // Optimized implementation copies 32-bit words by masking.
210 for (unsigned int i = 0; i < m_length; i += 4) {
211 typedef unsigned int *u;
212 *reinterpret_cast<u>(&m_data[i]) &=
213 ~*reinterpret_cast<u>(m_byte_enable);
214 *reinterpret_cast<u>(&m_data[i]) |=
215 *reinterpret_cast<u>(&other.m_data[i]) &
216 *reinterpret_cast<u>(m_byte_enable);
217 }
218 } else {
219 // Unoptimized implementation.
220 for (unsigned int i = 0; i < m_length; i++) {
222 m_data[i] = other.m_data[i];
223 }
224 }
225 } else {
226 std::memcpy(m_data, other.m_data, m_length);
227 }
228 }
229}
230
231void
233{
234 // Deep copy extensions that are already present.
235 sc_assert(m_extensions.size() <= other.m_extensions.size());
236 for (unsigned int i = 0; i < m_extensions.size(); i++) {
237 if (other.m_extensions[i]) {
238 // Original has extension i.
239 if (m_extensions[i]) {
240 // We have it too. Copy.
241 m_extensions[i]->copy_from(*other.m_extensions[i]);
242 }
243 }
244 }
245}
246
247// Free all extensions. Useful when reusing a cloned transaction that doesn't
248// have memory manager. Normal and sticky extensions are freed and extension
249// array cleared.
250void
252{
253 m_extensions.free_entire_cache();
254 for (unsigned int i = 0; i < m_extensions.size(); i++) {
255 if (m_extensions[i]) {
256 m_extensions[i]->free();
257 m_extensions[i] = 0;
258 }
259 }
260}
261
263{
264 for (unsigned int i = 0; i < m_extensions.size(); i++) {
265 if (m_extensions[i])
266 m_extensions[i]->free();
267 }
268}
269
270//----------------
271// API (including setters & getters)
272//---------------
273
274std::string
276{
277 switch (m_response_status) {
278 case TLM_OK_RESPONSE:
279 return "TLM_OK_RESPONSE";
281 return "TLM_INCOMPLETE_RESPONSE";
283 return "TLM_GENERIC_ERROR_RESPONSE";
285 return "TLM_ADDRESS_ERROR_RESPONSE";
287 return "TLM_COMMAND_ERROR_RESPONSE";
289 return "TLM_BURST_ERROR_RESPONSE";
291 return "TLM_BYTE_ENABLE_ERROR_RESPONSE";
292 }
293 return "TLM_UNKNOWN_RESPONSE";
294}
295
296/* --------------------------------------------------------------------- */
297/* Dynamic extension mechanism: */
298/* --------------------------------------------------------------------- */
299
302{
303 sc_assert(index < m_extensions.size());
304 tlm_extension_base *tmp = m_extensions[index];
305 m_extensions[index] = ext;
306 return tmp;
307}
308
311 unsigned int index, tlm_extension_base *ext)
312{
313 sc_assert(index < m_extensions.size());
314 tlm_extension_base *tmp = m_extensions[index];
315 m_extensions[index] = ext;
316 if (!tmp)
317 m_extensions.insert_in_cache(&m_extensions[index]);
318 sc_assert(m_mm != 0);
319 return tmp;
320}
321
323tlm_generic_payload::get_extension(unsigned int index) const
324{
325 sc_assert(index < m_extensions.size());
326 return m_extensions[index];
327}
328
329void
331{
332 sc_assert(index < m_extensions.size());
333 m_extensions[index] = static_cast<tlm_extension_base *>(0);
334}
335
336void
338{
339 sc_assert(index < m_extensions.size());
340 if (m_mm) {
341 m_extensions.insert_in_cache(&m_extensions[index]);
342 } else {
343 m_extensions[index]->free();
344 m_extensions[index] = static_cast<tlm_extension_base *>(nullptr);
345 }
346}
347
348void
353
354} // namespace tlm
Definition mm.h:9
static unsigned int register_extension(const std::type_info &)
Definition gp.cc:91
tlm_command m_command
Definition gp.hh:290
void update_extensions_from(const tlm_generic_payload &other)
Definition gp.cc:232
void resize_extensions()
Definition gp.cc:349
T * set_auto_extension(T *ext)
Definition gp.hh:353
bool is_read() const
Definition gp.hh:176
void release_extension()
Definition gp.hh:401
void free_all_extensions()
Definition gp.cc:251
tlm_array< tlm_extension_base * > m_extensions
Definition gp.hh:421
tlm_gp_option get_gp_option() const
Definition gp.hh:250
void deep_copy_from(const tlm_generic_payload &other)
Definition gp.cc:126
tlm_mm_interface * m_mm
Definition gp.hh:422
T * get_extension() const
Definition gp.hh:367
unsigned int m_streaming_width
Definition gp.hh:297
void update_original_from(const tlm_generic_payload &other, bool use_byte_enable_on_read=true)
Definition gp.cc:180
tlm_response_status m_response_status
Definition gp.hh:293
sc_dt::uint64 get_address() const
Definition gp.hh:184
unsigned int get_byte_enable_length() const
Definition gp.hh:226
tlm_response_status get_response_status() const
Definition gp.hh:199
unsigned char * m_byte_enable
Definition gp.hh:295
bool is_dmi_allowed() const
Definition gp.hh:244
sc_dt::uint64 m_address
Definition gp.hh:289
unsigned char * m_data
Definition gp.hh:291
bool has_mm() const
Definition gp.hh:140
unsigned int get_streaming_width() const
Definition gp.hh:211
unsigned int m_byte_enable_length
Definition gp.hh:296
unsigned int get_data_length() const
Definition gp.hh:192
tlm_command get_command() const
Definition gp.hh:180
unsigned int m_length
Definition gp.hh:292
virtual ~tlm_generic_payload()
Definition gp.cc:262
tlm_gp_option m_gp_option
Definition gp.hh:298
T * set_extension(T *ext)
Definition gp.hh:340
std::string get_response_string() const
Definition gp.cc:275
static ispex_registry * instance_
Bitfield< 0 > v
Definition pagetable.hh:65
uint64_t uint64
Definition sc_nbdefs.hh:172
@ TLM_MIN_PAYLOAD
Definition gp.hh:102
@ TLM_IGNORE_COMMAND
Definition gp.hh:86
@ TLM_ADDRESS_ERROR_RESPONSE
Definition gp.hh:94
@ TLM_OK_RESPONSE
Definition gp.hh:91
@ TLM_BURST_ERROR_RESPONSE
Definition gp.hh:96
@ TLM_BYTE_ENABLE_ERROR_RESPONSE
Definition gp.hh:97
@ TLM_GENERIC_ERROR_RESPONSE
Definition gp.hh:93
@ TLM_COMMAND_ERROR_RESPONSE
Definition gp.hh:95
@ TLM_INCOMPLETE_RESPONSE
Definition gp.hh:92
unsigned int max_num_extensions()
Definition gp.cc:85
#define sc_assert(expr)

Generated on Tue Jun 18 2024 16:24:07 for gem5 by doxygen 1.11.0