gem5  v22.1.0.0
proxy_ptr.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004-2005 The Regents of The University of Michigan
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef __SIM_PROXY_PTR_HH__
30 #define __SIM_PROXY_PTR_HH__
31 
32 #include <cstdint>
33 #include <memory>
34 #include <type_traits>
35 
36 #include "base/logging.hh"
37 #include "base/types.hh"
38 #include "sim/guest_abi.hh"
39 
40 namespace gem5
41 {
42 
43 template <typename Proxy>
45 {
46  private:
47  std::shared_ptr<Proxy> proxy;
48 
50  size_t size;
51  std::unique_ptr<uint8_t[]> data;
52 
53  bool dirty = false;
54 
55  void markClean() { dirty = false; }
56 
57  public:
58 
59  std::shared_ptr<Proxy> getProxy() const { return proxy; }
60 
61  void markDirty() { dirty = true; }
62  bool isDirty() { return dirty; }
63 
64  template <typename T>
65  T &
66  as()
67  {
68  assert(sizeof(T) <= size);
69  markDirty();
70  return *reinterpret_cast<T *>(data.get());
71  }
72 
73  template <typename T>
74  const T &
75  asConst() const
76  {
77  assert(sizeof(T) <= size);
78  return *reinterpret_cast<T *>(data.get());
79  }
80 
81  void
82  flush(bool force=false)
83  {
84  if (force || isDirty()) {
85  proxy->writeBlob(ptr, data.get(), size);
86  markClean();
87  }
88  }
89 
90  void
91  load()
92  {
93  panic_if(isDirty(), "Overwriting dirty ProxyPtr.");
94  proxy->readBlob(ptr, data.get(), size);
95  }
96 
97  Addr addr() const { return ptr; }
98 
99  ProxyPtrBuffer(std::shared_ptr<Proxy> _proxy, Addr _ptr, size_t _size) :
100  proxy(_proxy), ptr(_ptr), size(_size), data(new uint8_t[_size])
101  {
102  load();
103  }
104 
106 };
107 
108 template <typename T, typename Proxy>
110 {
111  protected:
112  std::shared_ptr<Proxy> proxy;
113  std::shared_ptr<ProxyPtrBuffer<Proxy>> buffer;
114 
115  template <typename O, typename P>
116  friend class ProxyPtr;
117 
118  void nullCheck() const { panic_if(!buffer, "Accessing null ProxyPtr."); }
119 
120  void
122  {
123  if (ptr)
124  buffer.reset(new ProxyPtrBuffer<Proxy>(proxy, ptr, sizeof(T)));
125  else
126  buffer.reset((ProxyPtrBuffer<Proxy> *)nullptr);
127  }
128 
129  ConstProxyPtr(Addr _ptr, std::shared_ptr<Proxy> _proxy) : proxy(_proxy)
130  {
131  setAddr(_ptr);
132  }
133 
135 
136  public:
137  using Type = T;
138 
139  template <typename ...Args,
140  typename std::enable_if_t<std::is_constructible_v<
141  Proxy, Args&&...>, int> = 0>
142  explicit ConstProxyPtr(Addr _ptr, Args&&... args) :
143  proxy(std::make_shared<Proxy>(args...))
144  {
145  setAddr(_ptr);
146  }
147  template <typename ...Args,
148  typename std::enable_if_t<std::is_constructible_v<
149  Proxy, Args&&...>, int> = 0>
150  explicit ConstProxyPtr(Args&&... args) :
151  proxy(std::make_shared<Proxy>(args...))
152  {
153  setAddr(0);
154  }
155 
156  template <typename O, typename Enabled=
157  typename std::enable_if_t<std::is_assignable_v<T *, O *>>>
159  proxy(other.proxy), buffer(other.buffer)
160  {}
161 
162  ConstProxyPtr(const CPP &other) :
163  proxy(other.proxy), buffer(other.buffer)
164  {}
165 
166  void
168  {
169  nullCheck();
170  buffer->load();
171  }
172 
173  Addr addr() const { return buffer ? buffer->addr() : 0; }
174  operator bool() const { return (bool)buffer; }
175 
176  template <typename A>
177  typename std::enable_if_t<std::is_integral_v<A>, CPP>
178  operator + (A a) const
179  {
180  return CPP(addr() + a * sizeof(T), proxy);
181  }
182 
183  template <typename A>
184  typename std::enable_if_t<std::is_integral_v<A>, CPP>
185  operator - (A a) const
186  {
187  return CPP(addr() - a * sizeof(T), proxy);
188  }
189 
190  ptrdiff_t
191  operator - (const CPP &other) const
192  {
193  return (addr() - other.addr()) / sizeof(T);
194  }
195 
196  CPP &
197  operator = (const CPP &other)
198  {
199  proxy = other.proxy;
200  buffer = other.buffer;
201  return *this;
202  }
203 
204  CPP &
206  {
207  setAddr(a);
208  return *this;
209  }
210 
211  operator const T *() const
212  {
213  return buffer ? &buffer->template asConst<T>() : nullptr;
214  }
215 
216  const T &
217  operator *() const
218  {
219  nullCheck();
220  return buffer->template asConst<T>();
221  }
222  const T *
223  operator ->() const
224  {
225  nullCheck();
226  return &buffer->template asConst<T>();
227  }
228 };
229 
230 template <typename T, typename Proxy, typename A>
231 typename std::enable_if_t<std::is_integral_v<A>, ConstProxyPtr<T, Proxy>>
233 {
234  return other + a;
235 }
236 
237 template <typename T, typename Proxy>
238 class ProxyPtr : public ConstProxyPtr<T, Proxy>
239 {
240  protected:
243 
244  ProxyPtr(Addr _ptr, std::shared_ptr<Proxy> _proxy) : CPP(_ptr, _proxy) {}
245 
246  public:
247  template <typename ...Args,
248  typename std::enable_if_t<std::is_constructible_v<
249  Proxy, Args&&...>, int> = 0>
250  explicit ProxyPtr(Addr _ptr, Args&&... args) : CPP(_ptr, args...) {}
251  template <typename ...Args,
252  typename std::enable_if_t<std::is_constructible_v<
253  Proxy, Args&&...>, int> = 0>
254  explicit ProxyPtr(Args&&... args) : CPP(0, args...) {}
255 
256  template <typename O, typename Enabled=
257  typename std::enable_if_t<std::is_assignable_v<T *, O *> &&
258  !std::is_same_v<O, void>>>
259  ProxyPtr(const ProxyPtr<O, Proxy> &other) : CPP(other) {}
260 
261  ProxyPtr(const PP &other) : CPP(other) {}
262  operator bool() const { return (bool)this->buffer; }
263 
264  void
265  flush(bool force=false)
266  {
267  this->nullCheck();
268  this->buffer->flush(force);
269  }
270 
271  template <typename A>
272  typename std::enable_if_t<std::is_integral_v<A>, PP>
273  operator + (A a) const
274  {
275  return PP(this->addr() + a * sizeof(T), this->proxy);
276  }
277 
278  template <typename A>
279  typename std::enable_if_t<std::is_integral_v<A>, PP>
280  operator - (A a) const
281  {
282  return PP(this->addr() - a * sizeof(T), this->proxy);
283  }
284 
285  ptrdiff_t
286  operator - (const PP &other) const
287  {
288  return (this->addr() - other.addr()) / sizeof(T);
289  }
290 
291  PP &
292  operator = (const PP &other)
293  {
294  this->proxy = other.proxy;
295  this->buffer = other.buffer;
296  return *this;
297  }
298 
299  PP &
301  {
302  this->setAddr(a);
303  return *this;
304  }
305 
306  using CPP::operator const T *;
307  operator T *() const
308  {
309  return this->buffer ? &this->buffer->template as<T>() : nullptr;
310  }
311 
312  using CPP::operator *;
313  T &
314  operator *() const
315  {
316  this->nullCheck();
317  return this->buffer->template as<T>();
318  }
319 
320  using CPP::operator ->;
321  T *
322  operator ->() const
323  {
324  this->nullCheck();
325  return &this->buffer->template as<T>();
326  }
327 };
328 
329 template <typename Proxy>
330 class ProxyPtr<void, Proxy>
331 {
332  protected:
334 
335  public:
336  ProxyPtr(Addr new_addr, ...) : _addr(new_addr) {}
337 
338  template <typename T>
339  ProxyPtr(const ProxyPtr<T, Proxy> &other) : _addr(other.addr()) {}
340 
342  operator = (Addr new_addr)
343  {
344  _addr = new_addr;
345  return *this;
346  }
347 
348  operator Addr() const { return _addr; }
349 
350  Addr addr() const { return _addr; }
351 };
352 
353 template <typename T, typename Proxy, typename A>
354 typename std::enable_if_t<std::is_integral_v<A>, ProxyPtr<T, Proxy>>
356 {
357  return other + a;
358 }
359 
360 GEM5_DEPRECATED_NAMESPACE(GuestABI, guest_abi);
361 namespace guest_abi
362 {
363 
364 template <typename ABI, typename T, typename Proxy>
365 struct Argument<ABI, ProxyPtr<T, Proxy>>
366 {
367  static ProxyPtr<T, Proxy>
368  get(ThreadContext *tc, typename ABI::State &state)
369  {
370  return ProxyPtr<T, Proxy>(
372  }
373 };
374 
375 template <typename ABI, typename T, typename Proxy>
376 struct Argument<ABI, ConstProxyPtr<T, Proxy>>
377 {
379  get(ThreadContext *tc, typename ABI::State &state)
380  {
383  }
384 };
385 
386 } // namespace guest_abi
387 
388 template <typename T, typename Proxy>
389 std::ostream &
390 operator << (std::ostream &os, const ConstProxyPtr<T, Proxy> &vptr)
391 {
392  ccprintf(os, "%#x", vptr.addr());
393  return os;
394 }
395 
396 class SETranslatingPortProxy;
397 
398 template <typename T>
400 template <typename T=void>
402 
403 } // namespace gem5
404 
405 #endif // __SIM_PROXY_PTR_HH__
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
std::shared_ptr< ProxyPtrBuffer< Proxy > > buffer
Definition: proxy_ptr.hh:113
ConstProxyPtr< T, Proxy > CPP
Definition: proxy_ptr.hh:134
std::enable_if_t< std::is_integral_v< A >, CPP > operator-(A a) const
Definition: proxy_ptr.hh:185
ConstProxyPtr(Addr _ptr, Args &&... args)
Definition: proxy_ptr.hh:142
CPP & operator=(const CPP &other)
Definition: proxy_ptr.hh:197
const T * operator->() const
Definition: proxy_ptr.hh:223
ConstProxyPtr(Args &&... args)
Definition: proxy_ptr.hh:150
void nullCheck() const
Definition: proxy_ptr.hh:118
std::enable_if_t< std::is_integral_v< A >, CPP > operator+(A a) const
Definition: proxy_ptr.hh:178
ConstProxyPtr(Addr _ptr, std::shared_ptr< Proxy > _proxy)
Definition: proxy_ptr.hh:129
std::shared_ptr< Proxy > proxy
Definition: proxy_ptr.hh:112
Addr addr() const
Definition: proxy_ptr.hh:173
const T & operator*() const
Definition: proxy_ptr.hh:217
void setAddr(Addr ptr)
Definition: proxy_ptr.hh:121
ConstProxyPtr(const CPP &other)
Definition: proxy_ptr.hh:162
ConstProxyPtr(const ConstProxyPtr< O, Proxy > &other)
Definition: proxy_ptr.hh:158
const T & asConst() const
Definition: proxy_ptr.hh:75
Addr addr() const
Definition: proxy_ptr.hh:97
std::shared_ptr< Proxy > getProxy() const
Definition: proxy_ptr.hh:59
std::unique_ptr< uint8_t[]> data
Definition: proxy_ptr.hh:51
ProxyPtrBuffer(std::shared_ptr< Proxy > _proxy, Addr _ptr, size_t _size)
Definition: proxy_ptr.hh:99
std::shared_ptr< Proxy > proxy
Definition: proxy_ptr.hh:47
void flush(bool force=false)
Definition: proxy_ptr.hh:82
ProxyPtr(Addr new_addr,...)
Definition: proxy_ptr.hh:336
ProxyPtr(const ProxyPtr< T, Proxy > &other)
Definition: proxy_ptr.hh:339
T & operator*() const
Definition: proxy_ptr.hh:314
ProxyPtr(Addr _ptr, std::shared_ptr< Proxy > _proxy)
Definition: proxy_ptr.hh:244
void flush(bool force=false)
Definition: proxy_ptr.hh:265
ProxyPtr< T, Proxy > PP
Definition: proxy_ptr.hh:242
ProxyPtr(const ProxyPtr< O, Proxy > &other)
Definition: proxy_ptr.hh:259
std::enable_if_t< std::is_integral_v< A >, PP > operator-(A a) const
Definition: proxy_ptr.hh:280
ProxyPtr(const PP &other)
Definition: proxy_ptr.hh:261
std::enable_if_t< std::is_integral_v< A >, PP > operator+(A a) const
Definition: proxy_ptr.hh:273
ProxyPtr(Addr _ptr, Args &&... args)
Definition: proxy_ptr.hh:250
PP & operator=(const PP &other)
Definition: proxy_ptr.hh:292
ProxyPtr(Args &&... args)
Definition: proxy_ptr.hh:254
T * operator->() const
Definition: proxy_ptr.hh:322
ThreadContext is the external interface to all thread state for anything outside of the CPU.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:204
atomic_var_t state
Definition: helpers.cc:188
Bitfield< 8 > a
Definition: misc_types.hh:66
Bitfield< 17 > os
Definition: misc.hh:810
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
std::ostream & operator<<(std::ostream &os, const ArmSemihosting::InPlaceArg &ipa)
void ccprintf(cp::Print &print)
Definition: cprintf.hh:130
GEM5_DEPRECATED_NAMESPACE(GuestABI, guest_abi)
Time operator+(const Time &l, const Time &r)
Definition: time.hh:247
Overload hash function for BasicBlockRange type.
Definition: misc.hh:2826
static ConstProxyPtr< T, Proxy > get(ThreadContext *tc, typename ABI::State &state)
Definition: proxy_ptr.hh:379
static ProxyPtr< T, Proxy > get(ThreadContext *tc, typename ABI::State &state)
Definition: proxy_ptr.hh:368

Generated on Wed Dec 21 2022 10:22:40 for gem5 by doxygen 1.9.1