gem5  v22.1.0.0
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 
26 namespace tlm
27 {
28 
29 template class tlm_array<tlm_extension_base *>;
30 
31 //---------------------------------------------------------------------------
32 // Classes for the extension mechanism
33 //---------------------------------------------------------------------------
34 
35 namespace
36 {
37 
38 class 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 
80 tlm_extension_registry *tlm_extension_registry::instance_ = NULL;
81 
82 } // anonymous namespace
83 
84 unsigned int
86 {
88 }
89 
90 unsigned int
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 
116 void
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.
125 void
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) {
145  std::memcpy(m_byte_enable, other.m_byte_enable, m_byte_enable_length);
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.
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 
179 void
181  const tlm_generic_payload &other, bool use_byte_enable_on_read)
182 {
183  // Copy back extensions that are present on the original.
184  update_extensions_from(other);
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 
231 void
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.
250 void
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 
274 std::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());
306  return tmp;
307 }
308 
311  unsigned int index, tlm_extension_base *ext)
312 {
313  sc_assert(index < m_extensions.size());
316  if (!tmp)
317  m_extensions.insert_in_cache(&m_extensions[index]);
318  sc_assert(m_mm != 0);
319  return tmp;
320 }
321 
324 {
325  sc_assert(index < m_extensions.size());
326  return m_extensions[index];
327 }
328 
329 void
331 {
332  sc_assert(index < m_extensions.size());
333  m_extensions[index] = static_cast<tlm_extension_base *>(0);
334 }
335 
336 void
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 
348 void
350 {
352 }
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
bool is_read() const
Definition: gp.hh:176
void release_extension()
Definition: gp.hh:401
void free_all_extensions()
Definition: gp.cc:251
T * set_extension(T *ext)
Definition: gp.hh:340
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
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
T * set_auto_extension(T *ext)
Definition: gp.hh:353
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
T * get_extension() const
Definition: gp.hh:367
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
std::string get_response_string() const
Definition: gp.cc:275
void clear_extension()
Definition: gp.hh:386
static ispex_registry * instance_
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 22 > u
Definition: misc_types.hh:359
Bitfield< 12 > ext
Definition: misc_types.hh:434
Bitfield< 30, 0 > index
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 Wed Dec 21 2022 10:22:50 for gem5 by doxygen 1.9.1