gem5  v20.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
91 tlm_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 
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();
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.
187  m_response_status = other.get_response_status();
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
232 tlm_generic_payload::update_extensions_from(const tlm_generic_payload &other)
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 
300 tlm_extension_base *
301 tlm_generic_payload::set_extension(unsigned int index, tlm_extension_base *ext)
302 {
303  sc_assert(index < m_extensions.size());
304  tlm_extension_base *tmp = m_extensions[index];
306  return tmp;
307 }
308 
309 tlm_extension_base *
311  unsigned int index, tlm_extension_base *ext)
312 {
313  sc_assert(index < m_extensions.size());
314  tlm_extension_base *tmp = m_extensions[index];
316  if (!tmp)
317  m_extensions.insert_in_cache(&m_extensions[index]);
319  return tmp;
320 }
321 
323 tlm_generic_payload::get_extension(unsigned int index) const
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
tlm::tlm_generic_payload::get_byte_enable_length
unsigned int get_byte_enable_length() const
Definition: gp.hh:243
tlm::tlm_extension_base::register_extension
static unsigned int register_extension(const std::type_info &)
Definition: gp.cc:108
tlm::tlm_generic_payload::m_mm
tlm_mm_interface * m_mm
Definition: gp.hh:439
tlm::tlm_generic_payload::release_extension
void release_extension()
Definition: gp.hh:418
tlm::TLM_INCOMPLETE_RESPONSE
@ TLM_INCOMPLETE_RESPONSE
Definition: gp.hh:109
MipsISA::index
Bitfield< 30, 0 > index
Definition: pra_constants.hh:44
tlm::tlm_generic_payload::resize_extensions
void resize_extensions()
Definition: gp.cc:366
tlm::tlm_generic_payload::update_extensions_from
void update_extensions_from(const tlm_generic_payload &other)
Definition: gp.cc:249
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
tlm::tlm_generic_payload::tlm_generic_payload
tlm_generic_payload()
Definition: gp.cc:117
tlm::tlm_generic_payload::get_streaming_width
unsigned int get_streaming_width() const
Definition: gp.hh:228
tlm::tlm_generic_payload::m_address
sc_dt::uint64 m_address
Definition: gp.hh:306
tlm::TLM_GENERIC_ERROR_RESPONSE
@ TLM_GENERIC_ERROR_RESPONSE
Definition: gp.hh:110
type
uint8_t type
Definition: inet.hh:421
tlm::TLM_OK_RESPONSE
@ TLM_OK_RESPONSE
Definition: gp.hh:108
tlm::tlm_generic_payload::m_byte_enable_length
unsigned int m_byte_enable_length
Definition: gp.hh:313
tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE
@ TLM_BYTE_ENABLE_ERROR_RESPONSE
Definition: gp.hh:114
tlm::tlm_generic_payload::m_response_status
tlm_response_status m_response_status
Definition: gp.hh:310
tlm::tlm_generic_payload::is_dmi_allowed
bool is_dmi_allowed() const
Definition: gp.hh:261
tlm::tlm_generic_payload::m_length
unsigned int m_length
Definition: gp.hh:309
sc_assert
#define sc_assert(expr)
Definition: sc_report_handler.hh:135
tlm::tlm_generic_payload::free_all_extensions
void free_all_extensions()
Definition: gp.cc:268
tlm::tlm_generic_payload::m_gp_option
tlm_gp_option m_gp_option
Definition: gp.hh:315
tlm::tlm_generic_payload::get_response_string
std::string get_response_string() const
Definition: gp.cc:292
tlm::tlm_generic_payload::reset
void reset()
Definition: gp.cc:134
tlm::tlm_generic_payload::m_streaming_width
unsigned int m_streaming_width
Definition: gp.hh:314
tlm::tlm_generic_payload::m_command
tlm_command m_command
Definition: gp.hh:307
tlm::TLM_BURST_ERROR_RESPONSE
@ TLM_BURST_ERROR_RESPONSE
Definition: gp.hh:113
tlm::tlm_generic_payload::m_dmi
bool m_dmi
Definition: gp.hh:311
tlm::tlm_generic_payload::get_command
tlm_command get_command() const
Definition: gp.hh:197
tlm::tlm_generic_payload::clear_extension
void clear_extension()
Definition: gp.hh:403
tlm::tlm_generic_payload::get_response_status
tlm_response_status get_response_status() const
Definition: gp.hh:216
tlm::tlm_extension_base
Definition: gp.hh:65
tlm::tlm_generic_payload::get_data_length
unsigned int get_data_length() const
Definition: gp.hh:209
sc_dt::uint64
uint64_t uint64
Definition: sc_nbdefs.hh:206
tlm::TLM_MIN_PAYLOAD
@ TLM_MIN_PAYLOAD
Definition: gp.hh:119
ArmISA::ext
Bitfield< 12 > ext
Definition: miscregs_types.hh:422
tlm::tlm_generic_payload::m_byte_enable
unsigned char * m_byte_enable
Definition: gp.hh:312
tlm::tlm_generic_payload::deep_copy_from
void deep_copy_from(const tlm_generic_payload &other)
Definition: gp.cc:143
mm
Definition: mm.h:8
tlm
Definition: analysis_fifo.hh:27
tlm::TLM_IGNORE_COMMAND
@ TLM_IGNORE_COMMAND
Definition: gp.hh:103
ArmISA::u
Bitfield< 22 > u
Definition: miscregs_types.hh:348
tlm::max_num_extensions
unsigned int max_num_extensions()
Definition: gp.cc:102
ids_
type_map ids_
Definition: instance_specific_extensions.cc:77
tlm::tlm_generic_payload::get_extension
T * get_extension() const
Definition: gp.hh:384
tlm::TLM_COMMAND_ERROR_RESPONSE
@ TLM_COMMAND_ERROR_RESPONSE
Definition: gp.hh:112
tlm::tlm_generic_payload
Definition: gp.hh:133
tlm::tlm_generic_payload::m_data
unsigned char * m_data
Definition: gp.hh:308
tlm::tlm_generic_payload::update_original_from
void update_original_from(const tlm_generic_payload &other, bool use_byte_enable_on_read=true)
Definition: gp.cc:197
tlm::tlm_generic_payload::has_mm
bool has_mm() const
Definition: gp.hh:157
tlm::tlm_generic_payload::set_extension
T * set_extension(T *ext)
Definition: gp.hh:357
tlm::tlm_generic_payload::set_auto_extension
T * set_auto_extension(T *ext)
Definition: gp.hh:370
tlm::tlm_generic_payload::get_gp_option
tlm_gp_option get_gp_option() const
Definition: gp.hh:267
instance_
static ispex_registry * instance_
Definition: instance_specific_extensions.cc:76
tlm::TLM_ADDRESS_ERROR_RESPONSE
@ TLM_ADDRESS_ERROR_RESPONSE
Definition: gp.hh:111
tlm::tlm_mm_interface
Definition: gp.hh:50
tlm::tlm_generic_payload::m_extensions
tlm_array< tlm_extension_base * > m_extensions
Definition: gp.hh:438
tlm::tlm_generic_payload::get_address
sc_dt::uint64 get_address() const
Definition: gp.hh:201
ArmISA::v
Bitfield< 28 > v
Definition: miscregs_types.hh:51
tlm::tlm_generic_payload::~tlm_generic_payload
virtual ~tlm_generic_payload()
Definition: gp.cc:279
tlm::tlm_generic_payload::is_read
bool is_read() const
Definition: gp.hh:193
gp.hh

Generated on Wed Sep 30 2020 14:02:18 for gem5 by doxygen 1.8.17