SST  11.1.0
StructuralSimulationToolkit
simpleMem.h
1 // -*- mode: c++ -*-
2 // Copyright 2009-2021 NTESS. Under the terms
3 // of Contract DE-NA0003525 with NTESS, the U.S.
4 // Government retains certain rights in this software.
5 //
6 // Copyright (c) 2009-2021, NTESS
7 // All rights reserved.
8 //
9 // This file is part of the SST software package. For license
10 // information, see the LICENSE file in the top level directory of the
11 // distribution.
12 //
13 
14 #ifndef SST_CORE_INTERFACES_SIMPLEMEM_H
15 #define SST_CORE_INTERFACES_SIMPLEMEM_H
16 
17 #include "sst/core/link.h"
18 #include "sst/core/params.h"
19 #include "sst/core/sst_types.h"
20 #include "sst/core/ssthandler.h"
21 #include "sst/core/subcomponent.h"
22 #include "sst/core/warnmacros.h"
23 
24 #include <atomic>
25 #include <map>
26 #include <string>
27 #include <utility>
28 
29 namespace SST {
30 
31 class Component;
32 class Event;
33 
34 namespace Interfaces {
35 
36 /**
37  * Simplified, generic interface to Memory models
38  */
39 class SimpleMem : public SubComponent
40 {
41 public:
42  class Request; // Needed for HandlerBase definition
43  /**
44  Base handler for request handling.
45  */
47 
48  /**
49  Used to create handlers for request handling. The callback
50  function is expected to be in the form of:
51 
52  void func(Request* event)
53 
54  In which case, the class is created with:
55 
56  new SimpleMem::Handler<classname>(this, &classname::function_name)
57 
58  Or, to add static data, the callback function is:
59 
60  void func(Request* event, dataT data)
61 
62  and the class is created with:
63 
64  new SimpleMem::Handler<classname, dataT>(this, &classname::function_name, data)
65  */
66  template <typename classT, typename dataT = void>
68 
69  SST_ELI_REGISTER_SUBCOMPONENT_API(SST::Interfaces::SimpleMem,TimeConverter*,HandlerBase*)
70  /** All Addresses can be 64-bit */
71  typedef uint64_t Addr;
72 
73  /**
74  * Represents both memory requests and responses.
75  */
76  class Request
77  {
78  public:
79  typedef uint64_t id_t; /*!< Request ID type */
80  typedef uint32_t flags_t; /*!< Flag type */
81 
82  /**
83  * Commands and responses possible with a Request object
84  */
85  typedef enum {
86  Read, /*!< Issue a Read from Memory */
87  Write, /*!< Issue a Write to Memory */
88  ReadResp, /*!< Response from Memory to a Read */
89  WriteResp, /*!< Response from Memory to a Write */
90  FlushLine, /*!< Cache flush request - writeback specified line throughout memory system */
91  FlushLineInv, /*!< Cache flush request - writeback and invalidate specified line throughout memory system */
92  FlushLineResp, /*!< Response to FlushLine; flag F_FLUSH_SUCCESS indicates success or failure */
93  Inv, /*!< Notification of L1 cache invalidation to core */
94  TxBegin, /*!< Start a new transaction */
95  TxEnd, /*!< End the current lowest transaction */
96  TxResp,
97  TxAbort,
98  TxCommit,
99  CustomCmd /*!< Custom memory command: Must also set custCmd opcode */
100  } Command;
101 
102  /**
103  * Flags to specify conditions on a Request
104  */
105  typedef enum {
106  F_NONCACHEABLE = 1 << 1, /*!< This request should not be cached */
107  F_LOCKED = 1 << 2, /*!< This request should be locked. A LOCKED read should be soon followed by a LOCKED
108  write (to unlock) */
109  F_LLSC = 1 << 3,
110  F_LLSC_RESP = 1 << 4,
111  F_FLUSH_SUCCESS =
112  1 << 5, /*!< This flag is set if the flush was successful. Flush may fail due to LOCKED lines */
113  F_TRANSACTION = 1 << 6
114  } Flags;
115 
116  /** Type of the payload or data */
117  typedef std::vector<uint8_t> dataVec;
118 
119  Command cmd; /*!< Command to issue */
120  std::vector<Addr> addrs; /*!< Target address(es) */
121  Addr addr; /*!< Target address - DEPRECATED but included for backward compatibility, defaults to addrs[0] */
122  size_t size; /*!< Size of this request or response */
123  dataVec data; /*!< Payload data (for Write, or ReadResp) */
124  flags_t flags; /*!< Flags associated with this request or response */
125  flags_t
126  memFlags; /*!< Memory flags - ignored by caches except to be passed through with request to main memory */
127  id_t id; /*!< Unique ID to identify responses with requests */
128  Addr instrPtr; /*!< Instruction pointer associated with the operation */
129  Addr virtualAddr; /*!< Virtual address associated with the operation */
130  uint32_t custOpc; /*!< Custom command opcode for CustomdCmd type commands */
131 
132  /** Constructor */
133  Request(Command cmd, Addr addr, size_t size, dataVec& data, flags_t flags = 0, flags_t memFlags = 0) :
134  cmd(cmd),
135  addr(addr),
136  size(size),
137  data(data),
138  flags(flags),
139  memFlags(memFlags),
140  instrPtr(0),
141  virtualAddr(0),
142  custOpc(0xFFFF)
143  {
144  addrs.push_back(addr);
145  id = main_id++;
146  }
147 
148  /** Constructor */
149  Request(Command cmd, Addr addr, size_t size, flags_t flags = 0, flags_t memFlags = 0) :
150  cmd(cmd),
151  addr(addr),
152  size(size),
153  flags(flags),
154  memFlags(memFlags),
155  instrPtr(0),
156  virtualAddr(0),
157  custOpc(0xFFFF)
158  {
159  addrs.push_back(addr);
160  id = main_id++;
161  }
162 
163  /** Constructor */
165  Command cmd, Addr addr, size_t size, dataVec& data, uint32_t Opc, flags_t flags = 0, flags_t memFlags = 0) :
166  cmd(cmd),
167  addr(addr),
168  size(size),
169  data(data),
170  flags(flags),
171  memFlags(memFlags),
172  instrPtr(0),
173  virtualAddr(0),
174  custOpc(Opc)
175  {
176  addrs.push_back(addr);
177  id = main_id++;
178  }
179 
180  /** Constructor */
181  Request(Command cmd, Addr addr, size_t size, uint32_t Opc, flags_t flags = 0, flags_t memFlags = 0) :
182  cmd(cmd),
183  addr(addr),
184  size(size),
185  flags(flags),
186  memFlags(memFlags),
187  instrPtr(0),
188  virtualAddr(0),
189  custOpc(Opc)
190  {
191  addrs.push_back(addr);
192  id = main_id++;
193  }
194 
195  void addAddress(Addr addr) { addrs.push_back(addr); }
196 
197  /**
198  * @param[in] data_in
199  * @brief Set the contents of the payload / data field.
200  */
201  void setPayload(const std::vector<uint8_t>& data_in) { data = data_in; }
202 
203  /**
204  * @param[in] data_in
205  * @brief Set the contents of the payload / data field.
206  */
207  void setPayload(uint8_t* data_in, size_t len)
208  {
209  data.resize(len);
210  for ( size_t i = 0; i < len; i++ ) {
211  data[i] = data_in[i];
212  }
213  }
214 
215  /**
216  * @param[in] newVA
217  * @brief Set the virtual address associated with the operation
218  */
219  void setVirtualAddress(const Addr newVA) { virtualAddr = newVA; }
220 
221  /**
222  * @returns the virtual address associated with the operation
223  */
224  uint64_t getVirtualAddress() { return (uint64_t)virtualAddr; }
225 
226  /**
227  * @param[in] newIP
228  * @brief Sets the instruction pointer associated with the operation
229  */
230  void setInstructionPointer(const Addr newIP) { instrPtr = newIP; }
231 
232  /**
233  * @returns the instruction pointer associated with the operation
234  */
235  Addr getInstructionPointer() { return instrPtr; }
236 
237  /**
238  * @brief Clears the flags associated with the operation
239  */
240  void clearFlags(void) { flags = 0; }
241 
242  /**
243  * @param[in] inValue Should be one of the flags beginning with F_ in simpleMem
244  */
245  void setFlags(flags_t inValue) { flags = flags | inValue; }
246 
247  /**
248  * @returns the flags associated with the operation
249  */
250  flags_t getFlags(void) { return flags; }
251 
252  /**
253  * @brief Clears the memory flags associated with the operation
254  */
255  void clearMemFlags(void) { memFlags = 0; }
256 
257  /**
258  * @param[in] inValue Should be one of the flags beginning with F_ in simpleMem
259  */
260  void setMemFlags(flags_t inValue) { memFlags = memFlags | inValue; }
261 
262  /**
263  * @returns the memory flags associated with the operation
264  */
265  flags_t getMemFlags(void) { return memFlags; }
266 
267  /**
268  * @returns the custom opcode for custom request types
269  */
270  uint32_t getCustomOpc(void) { return custOpc; }
271 
272  private:
273  static std::atomic<id_t> main_id;
274  };
275 
276  /** Constructor, designed to be used via 'loadUserSubComponent and loadAnonymousSubComponent'. */
277  SimpleMem(SST::ComponentId_t id, Params& UNUSED(params)) : SubComponent(id) {}
278 
279  /** Second half of building the interface.
280  * Initialize with link name name, and handler, if any
281  * @return true if the link was able to be configured.
282  */
283  virtual bool initialize(const std::string& linkName, HandlerBase* handler = nullptr) = 0;
284 
285  /**
286  * Sends a memory-based request during the init() phase
287  */
288  virtual void sendInitData(Request* req) = 0;
289 
290  /**
291  * Sends a generic Event during the init() phase
292  * (Mostly acts as a passthrough)
293  * @see SST::Link::sendInitData()
294  */
295  virtual void sendInitData(SST::Event* ev) { getLink()->sendInitData(ev); }
296 
297  /**
298  * Receive any data during the init() phase.
299  * @see SST::Link::recvInitData()
300  */
301  virtual SST::Event* recvInitData() { return getLink()->recvInitData(); }
302 
303  /**
304  * Returns a handle to the underlying SST::Link
305  */
306  virtual SST::Link* getLink(void) const = 0;
307 
308  /**
309  * Send a Request to the other side of the link.
310  */
311  virtual void sendRequest(Request* req) = 0;
312 
313  /**
314  * Receive a Request response from the side of the link.
315  *
316  * Use this method for polling-based applications.
317  * Register a handler for push-based notification of responses.
318  *
319  * @return nullptr if nothing is available.
320  * @return Pointer to a Request response (that should be deleted)
321  */
322  virtual Request* recvResponse(void) = 0;
323 
324  /**
325  * Get cache/memory line size from the memory system
326  *
327  * The memory system should provide this and it should be
328  * valid after the init() phase is complete, so processors
329  * can call this function during setup().
330  *
331  * For backward compatibiity, the function returns 0 by default.
332  * Eventually, interfaces will be required to implement this
333  * function.
334  *
335  * @return 0 if the interface does not provide this capability
336  * @return line size of the memory system
337  */
338  virtual Addr getLineSize() { return 0; }
339 };
340 
341 } // namespace Interfaces
342 } // namespace SST
343 
344 #endif // SST_CORE_INTERFACES_SIMPLEMEM_H
virtual SST::Event * recvInitData()
Receive any data during the init() phase.
Definition: simpleMem.h:301
size_t size
Definition: simpleMem.h:122
uint32_t flags_t
Definition: simpleMem.h:80
Request(Command cmd, Addr addr, size_t size, uint32_t Opc, flags_t flags=0, flags_t memFlags=0)
Constructor.
Definition: simpleMem.h:181
Addr getInstructionPointer()
Definition: simpleMem.h:235
Definition: ssthandler.h:100
Command
Commands and responses possible with a Request object.
Definition: simpleMem.h:85
Represents both memory requests and responses.
Definition: simpleMem.h:76
virtual void sendRequest(Request *req)=0
Send a Request to the other side of the link.
std::vector< Addr > addrs
Definition: simpleMem.h:120
virtual SST::Link * getLink(void) const =0
Returns a handle to the underlying SST::Link.
Event Handler class with user-data argument.
Definition: ssthandler.h:115
A class to convert between a component&#39;s view of time and the core&#39;s view of time.
Definition: timeConverter.h:26
uint64_t getVirtualAddress()
Definition: simpleMem.h:224
Command cmd
Definition: simpleMem.h:119
dataVec data
Definition: simpleMem.h:123
void setFlags(flags_t inValue)
Definition: simpleMem.h:245
std::vector< uint8_t > dataVec
Type of the payload or data.
Definition: simpleMem.h:117
Request(Command cmd, Addr addr, size_t size, dataVec &data, uint32_t Opc, flags_t flags=0, flags_t memFlags=0)
Constructor.
Definition: simpleMem.h:164
void setInstructionPointer(const Addr newIP)
Sets the instruction pointer associated with the operation.
Definition: simpleMem.h:230
void setPayload(const std::vector< uint8_t > &data_in)
Set the contents of the payload / data field.
Definition: simpleMem.h:201
virtual void sendInitData(Request *req)=0
Sends a memory-based request during the init() phase.
flags_t flags
Definition: simpleMem.h:124
virtual bool initialize(const std::string &linkName, HandlerBase *handler=nullptr)=0
Second half of building the interface.
Simplified, generic interface to Memory models.
Definition: simpleMem.h:39
flags_t getMemFlags(void)
Definition: simpleMem.h:265
void clearFlags(void)
Clears the flags associated with the operation.
Definition: simpleMem.h:240
Addr instrPtr
Definition: simpleMem.h:128
Request(Command cmd, Addr addr, size_t size, dataVec &data, flags_t flags=0, flags_t memFlags=0)
Constructor.
Definition: simpleMem.h:133
virtual Addr getLineSize()
Get cache/memory line size from the memory system.
Definition: simpleMem.h:338
Addr virtualAddr
Definition: simpleMem.h:129
flags_t getFlags(void)
Definition: simpleMem.h:250
virtual void sendInitData(SST::Event *ev)
Sends a generic Event during the init() phase (Mostly acts as a passthrough)
Definition: simpleMem.h:295
void setMemFlags(flags_t inValue)
Definition: simpleMem.h:260
Parameter store.
Definition: params.h:43
uint64_t Addr
All Addresses can be 64-bit.
Definition: simpleMem.h:71
void setVirtualAddress(const Addr newVA)
Set the virtual address associated with the operation.
Definition: simpleMem.h:219
uint32_t getCustomOpc(void)
Definition: simpleMem.h:270
void setPayload(uint8_t *data_in, size_t len)
Set the contents of the payload / data field.
Definition: simpleMem.h:207
Base class for Events - Items sent across links to communicate between components.
Definition: event.h:31
SimpleMem(SST::ComponentId_t id, Params &UNUSED(params))
Constructor, designed to be used via &#39;loadUserSubComponent and loadAnonymousSubComponent&#39;.
Definition: simpleMem.h:277
uint32_t custOpc
Definition: simpleMem.h:130
Addr addr
Definition: simpleMem.h:121
SubComponent is a class loadable through the factory which allows dynamic functionality to be added t...
Definition: subcomponent.h:28
uint64_t id_t
Definition: simpleMem.h:79
id_t id
Definition: simpleMem.h:127
virtual Request * recvResponse(void)=0
Receive a Request response from the side of the link.
SSTHandlerBase< void, Request *, false > HandlerBase
Base handler for request handling.
Definition: simpleMem.h:46
void clearMemFlags(void)
Clears the memory flags associated with the operation.
Definition: simpleMem.h:255
Request(Command cmd, Addr addr, size_t size, flags_t flags=0, flags_t memFlags=0)
Constructor.
Definition: simpleMem.h:149
flags_t memFlags
Definition: simpleMem.h:126