gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
packet.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2016 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2006 The Regents of The University of Michigan
15  * Copyright (c) 2010,2015 Advanced Micro Devices, Inc.
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions are
20  * met: redistributions of source code must retain the above copyright
21  * notice, this list of conditions and the following disclaimer;
22  * redistributions in binary form must reproduce the above copyright
23  * notice, this list of conditions and the following disclaimer in the
24  * documentation and/or other materials provided with the distribution;
25  * neither the name of the copyright holders nor the names of its
26  * contributors may be used to endorse or promote products derived from
27  * this software without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  *
41  * Authors: Ali Saidi
42  * Steve Reinhardt
43  */
44 
51 #include "mem/packet.hh"
52 
53 #include <cstring>
54 #include <iostream>
55 
56 #include "base/cprintf.hh"
57 #include "base/misc.hh"
58 #include "base/trace.hh"
59 
60 using namespace std;
61 
62 // The one downside to bitsets is that static initializers can get ugly.
63 #define SET1(a1) (1 << (a1))
64 #define SET2(a1, a2) (SET1(a1) | SET1(a2))
65 #define SET3(a1, a2, a3) (SET2(a1, a2) | SET1(a3))
66 #define SET4(a1, a2, a3, a4) (SET3(a1, a2, a3) | SET1(a4))
67 #define SET5(a1, a2, a3, a4, a5) (SET4(a1, a2, a3, a4) | SET1(a5))
68 #define SET6(a1, a2, a3, a4, a5, a6) (SET5(a1, a2, a3, a4, a5) | SET1(a6))
69 #define SET7(a1, a2, a3, a4, a5, a6, a7) (SET6(a1, a2, a3, a4, a5, a6) | \
70  SET1(a7))
71 
74 {
75  /* InvalidCmd */
76  { 0, InvalidCmd, "InvalidCmd" },
77  /* ReadReq - Read issued by a non-caching agent such as a CPU or
78  * device, with no restrictions on alignment. */
79  { SET3(IsRead, IsRequest, NeedsResponse), ReadResp, "ReadReq" },
80  /* ReadResp */
81  { SET3(IsRead, IsResponse, HasData), InvalidCmd, "ReadResp" },
82  /* ReadRespWithInvalidate */
83  { SET4(IsRead, IsResponse, HasData, IsInvalidate),
84  InvalidCmd, "ReadRespWithInvalidate" },
85  /* WriteReq */
86  { SET5(IsWrite, NeedsWritable, IsRequest, NeedsResponse, HasData),
87  WriteResp, "WriteReq" },
88  /* WriteResp */
89  { SET2(IsWrite, IsResponse), InvalidCmd, "WriteResp" },
90  /* WritebackDirty */
91  { SET5(IsWrite, IsRequest, IsEviction, HasData, FromCache),
92  InvalidCmd, "WritebackDirty" },
93  /* WritebackClean - This allows the upstream cache to writeback a
94  * line to the downstream cache without it being considered
95  * dirty. */
96  { SET5(IsWrite, IsRequest, IsEviction, HasData, FromCache),
97  InvalidCmd, "WritebackClean" },
98  /* CleanEvict */
99  { SET3(IsRequest, IsEviction, FromCache), InvalidCmd, "CleanEvict" },
100  /* SoftPFReq */
101  { SET4(IsRead, IsRequest, IsSWPrefetch, NeedsResponse),
102  SoftPFResp, "SoftPFReq" },
103  /* HardPFReq */
104  { SET5(IsRead, IsRequest, IsHWPrefetch, NeedsResponse, FromCache),
105  HardPFResp, "HardPFReq" },
106  /* SoftPFResp */
107  { SET4(IsRead, IsResponse, IsSWPrefetch, HasData),
108  InvalidCmd, "SoftPFResp" },
109  /* HardPFResp */
110  { SET4(IsRead, IsResponse, IsHWPrefetch, HasData),
111  InvalidCmd, "HardPFResp" },
112  /* WriteLineReq */
113  { SET5(IsWrite, NeedsWritable, IsRequest, NeedsResponse, HasData),
114  WriteResp, "WriteLineReq" },
115  /* UpgradeReq */
116  { SET6(IsInvalidate, NeedsWritable, IsUpgrade, IsRequest, NeedsResponse,
117  FromCache),
118  UpgradeResp, "UpgradeReq" },
119  /* SCUpgradeReq: response could be UpgradeResp or UpgradeFailResp */
120  { SET7(IsInvalidate, NeedsWritable, IsUpgrade, IsLlsc,
121  IsRequest, NeedsResponse, FromCache),
122  UpgradeResp, "SCUpgradeReq" },
123  /* UpgradeResp */
124  { SET2(IsUpgrade, IsResponse),
125  InvalidCmd, "UpgradeResp" },
126  /* SCUpgradeFailReq: generates UpgradeFailResp but still gets the data */
127  { SET7(IsRead, NeedsWritable, IsInvalidate,
128  IsLlsc, IsRequest, NeedsResponse, FromCache),
129  UpgradeFailResp, "SCUpgradeFailReq" },
130  /* UpgradeFailResp - Behaves like a ReadExReq, but notifies an SC
131  * that it has failed, acquires line as Dirty*/
132  { SET3(IsRead, IsResponse, HasData),
133  InvalidCmd, "UpgradeFailResp" },
134  /* ReadExReq - Read issues by a cache, always cache-line aligned,
135  * and the response is guaranteed to be writeable (exclusive or
136  * even modified) */
137  { SET6(IsRead, NeedsWritable, IsInvalidate, IsRequest, NeedsResponse,
138  FromCache),
139  ReadExResp, "ReadExReq" },
140  /* ReadExResp - Response matching a read exclusive, as we check
141  * the need for exclusive also on responses */
142  { SET3(IsRead, IsResponse, HasData),
143  InvalidCmd, "ReadExResp" },
144  /* ReadCleanReq - Read issued by a cache, always cache-line
145  * aligned, and the response is guaranteed to not contain dirty data
146  * (exclusive or shared).*/
147  { SET4(IsRead, IsRequest, NeedsResponse, FromCache),
148  ReadResp, "ReadCleanReq" },
149  /* ReadSharedReq - Read issued by a cache, always cache-line
150  * aligned, response is shared, possibly exclusive, owned or even
151  * modified. */
152  { SET4(IsRead, IsRequest, NeedsResponse, FromCache),
153  ReadResp, "ReadSharedReq" },
154  /* LoadLockedReq: note that we use plain ReadResp as response, so that
155  * we can also use ReadRespWithInvalidate when needed */
156  { SET4(IsRead, IsLlsc, IsRequest, NeedsResponse),
157  ReadResp, "LoadLockedReq" },
158  /* StoreCondReq */
159  { SET6(IsWrite, NeedsWritable, IsLlsc,
160  IsRequest, NeedsResponse, HasData),
161  StoreCondResp, "StoreCondReq" },
162  /* StoreCondFailReq: generates failing StoreCondResp */
163  { SET6(IsWrite, NeedsWritable, IsLlsc,
164  IsRequest, NeedsResponse, HasData),
165  StoreCondResp, "StoreCondFailReq" },
166  /* StoreCondResp */
167  { SET3(IsWrite, IsLlsc, IsResponse),
168  InvalidCmd, "StoreCondResp" },
169  /* SwapReq -- for Swap ldstub type operations */
170  { SET6(IsRead, IsWrite, NeedsWritable, IsRequest, HasData, NeedsResponse),
171  SwapResp, "SwapReq" },
172  /* SwapResp -- for Swap ldstub type operations */
173  { SET4(IsRead, IsWrite, IsResponse, HasData),
174  InvalidCmd, "SwapResp" },
175  /* IntReq -- for interrupts */
176  { SET4(IsWrite, IsRequest, NeedsResponse, HasData),
177  MessageResp, "MessageReq" },
178  /* IntResp -- for interrupts */
179  { SET2(IsWrite, IsResponse), InvalidCmd, "MessageResp" },
180  /* MemFenceReq -- for synchronization requests */
181  {SET2(IsRequest, NeedsResponse), MemFenceResp, "MemFenceReq"},
182  /* MemFenceResp -- for synchronization responses */
183  {SET1(IsResponse), InvalidCmd, "MemFenceResp"},
184  /* InvalidDestError -- packet dest field invalid */
185  { SET2(IsResponse, IsError), InvalidCmd, "InvalidDestError" },
186  /* BadAddressError -- memory address invalid */
187  { SET2(IsResponse, IsError), InvalidCmd, "BadAddressError" },
188  /* FunctionalReadError */
189  { SET3(IsRead, IsResponse, IsError), InvalidCmd, "FunctionalReadError" },
190  /* FunctionalWriteError */
191  { SET3(IsWrite, IsResponse, IsError), InvalidCmd, "FunctionalWriteError" },
192  /* PrintReq */
193  { SET2(IsRequest, IsPrint), InvalidCmd, "PrintReq" },
194  /* Flush Request */
195  { SET3(IsRequest, IsFlush, NeedsWritable), InvalidCmd, "FlushReq" },
196  /* Invalidation Request */
197  { SET5(IsInvalidate, IsRequest, NeedsWritable, NeedsResponse, FromCache),
198  InvalidateResp, "InvalidateReq" },
199  /* Invalidation Response */
200  { SET2(IsInvalidate, IsResponse),
201  InvalidCmd, "InvalidateResp" }
202 };
203 
204 bool
205 Packet::checkFunctional(Printable *obj, Addr addr, bool is_secure, int size,
206  uint8_t *_data)
207 {
208  Addr func_start = getAddr();
209  Addr func_end = getAddr() + getSize() - 1;
210  Addr val_start = addr;
211  Addr val_end = val_start + size - 1;
212 
213  if (is_secure != _isSecure || func_start > val_end ||
214  val_start > func_end) {
215  // no intersection
216  return false;
217  }
218 
219  // check print first since it doesn't require data
220  if (isPrint()) {
221  assert(!_data);
222  safe_cast<PrintReqState*>(senderState)->printObj(obj);
223  return false;
224  }
225 
226  // we allow the caller to pass NULL to signify the other packet
227  // has no data
228  if (!_data) {
229  return false;
230  }
231 
232  // offset of functional request into supplied value (could be
233  // negative if partial overlap)
234  int offset = func_start - val_start;
235 
236  if (isRead()) {
237  if (func_start >= val_start && func_end <= val_end) {
238  memcpy(getPtr<uint8_t>(), _data + offset, getSize());
239  if (bytesValid.empty())
240  bytesValid.resize(getSize(), true);
241  // complete overlap, and as the current packet is a read
242  // we are done
243  return true;
244  } else {
245  // Offsets and sizes to copy in case of partial overlap
246  int func_offset;
247  int val_offset;
248  int overlap_size;
249 
250  // calculate offsets and copy sizes for the two byte arrays
251  if (val_start < func_start && val_end <= func_end) {
252  // the one we are checking against starts before and
253  // ends before or the same
254  val_offset = func_start - val_start;
255  func_offset = 0;
256  overlap_size = val_end - func_start;
257  } else if (val_start >= func_start && val_end > func_end) {
258  // the one we are checking against starts after or the
259  // same, and ends after
260  val_offset = 0;
261  func_offset = val_start - func_start;
262  overlap_size = func_end - val_start;
263  } else if (val_start >= func_start && val_end <= func_end) {
264  // the one we are checking against is completely
265  // subsumed in the current packet, possibly starting
266  // and ending at the same address
267  val_offset = 0;
268  func_offset = val_start - func_start;
269  overlap_size = size;
270  } else if (val_start < func_start && val_end > func_end) {
271  // the current packet is completely subsumed in the
272  // one we are checking against
273  val_offset = func_start - val_start;
274  func_offset = 0;
275  overlap_size = func_end - func_start;
276  } else {
277  panic("Missed a case for checkFunctional with "
278  " %s 0x%x size %d, against 0x%x size %d\n",
279  cmdString(), getAddr(), getSize(), addr, size);
280  }
281 
282  // copy partial data into the packet's data array
283  uint8_t *dest = getPtr<uint8_t>() + func_offset;
284  uint8_t *src = _data + val_offset;
285  memcpy(dest, src, overlap_size);
286 
287  // initialise the tracking of valid bytes if we have not
288  // used it already
289  if (bytesValid.empty())
290  bytesValid.resize(getSize(), false);
291 
292  // track if we are done filling the functional access
293  bool all_bytes_valid = true;
294 
295  int i = 0;
296 
297  // check up to func_offset
298  for (; all_bytes_valid && i < func_offset; ++i)
299  all_bytes_valid &= bytesValid[i];
300 
301  // update the valid bytes
302  for (i = func_offset; i < func_offset + overlap_size; ++i)
303  bytesValid[i] = true;
304 
305  // check the bit after the update we just made
306  for (; all_bytes_valid && i < getSize(); ++i)
307  all_bytes_valid &= bytesValid[i];
308 
309  return all_bytes_valid;
310  }
311  } else if (isWrite()) {
312  if (offset >= 0) {
313  memcpy(_data + offset, getConstPtr<uint8_t>(),
314  (min(func_end, val_end) - func_start) + 1);
315  } else {
316  // val_start > func_start
317  memcpy(_data, getConstPtr<uint8_t>() - offset,
318  (min(func_end, val_end) - val_start) + 1);
319  }
320  } else {
321  panic("Don't know how to handle command %s\n", cmdString());
322  }
323 
324  // keep going with request by default
325  return false;
326 }
327 
328 void
330 {
331  assert(sender_state != NULL);
332  sender_state->predecessor = senderState;
333  senderState = sender_state;
334 }
335 
338 {
339  assert(senderState != NULL);
340  SenderState *sender_state = senderState;
341  senderState = sender_state->predecessor;
342  sender_state->predecessor = NULL;
343  return sender_state;
344 }
345 
346 void
347 Packet::print(ostream &o, const int verbosity, const string &prefix) const
348 {
349  ccprintf(o, "%s%s [%x:%x]%s%s%s%s", prefix, cmdString(),
350  getAddr(), getAddr() + getSize() - 1,
351  req->isSecure() ? " (s)" : "",
352  req->isInstFetch() ? " IF" : "",
353  req->isUncacheable() ? " UC" : "",
354  isExpressSnoop() ? " ES" : "");
355 }
356 
357 std::string
358 Packet::print() const {
359  ostringstream str;
360  print(str);
361  return str.str();
362 }
363 
364 Packet::PrintReqState::PrintReqState(ostream &_os, int _verbosity)
365  : curPrefixPtr(new string("")), os(_os), verbosity(_verbosity)
366 {
367  labelStack.push_back(LabelStackEntry("", curPrefixPtr));
368 }
369 
371 {
372  labelStack.pop_back();
373  assert(labelStack.empty());
374  delete curPrefixPtr;
375 }
376 
378 LabelStackEntry::LabelStackEntry(const string &_label, string *_prefix)
379  : label(_label), prefix(_prefix), labelPrinted(false)
380 {
381 }
382 
383 void
384 Packet::PrintReqState::pushLabel(const string &lbl, const string &prefix)
385 {
386  labelStack.push_back(LabelStackEntry(lbl, curPrefixPtr));
387  curPrefixPtr = new string(*curPrefixPtr);
388  *curPrefixPtr += prefix;
389 }
390 
391 void
393 {
394  delete curPrefixPtr;
395  curPrefixPtr = labelStack.back().prefix;
396  labelStack.pop_back();
397  assert(!labelStack.empty());
398 }
399 
400 void
402 {
403  if (!labelStack.back().labelPrinted) {
404  LabelStack::iterator i = labelStack.begin();
405  LabelStack::iterator end = labelStack.end();
406  while (i != end) {
407  if (!i->labelPrinted) {
408  ccprintf(os, "%s%s\n", *(i->prefix), i->label);
409  i->labelPrinted = true;
410  }
411  i++;
412  }
413  }
414 }
415 
416 
417 void
419 {
420  printLabels();
421  obj->print(os, verbosity, curPrefix());
422 }
void ccprintf(cp::Print &print)
Definition: cprintf.hh:130
Bitfield< 7 > i
Definition: miscregs.hh:1378
#define panic(...)
Definition: misc.hh:153
Object used to maintain state of a PrintReq.
Definition: packet.hh:388
LabelStackEntry(const std::string &_label, std::string *_prefix)
Definition: packet.cc:378
std::string print() const
A no-args wrapper of print(std::ostream...) meant to be invoked from DPRINTFs avoiding string overhea...
Definition: packet.cc:358
LabelStack labelStack
Definition: packet.hh:403
ip6_addr_t addr
Definition: inet.hh:335
#define SET4(a1, a2, a3, a4)
Definition: packet.cc:66
Bitfield< 23, 0 > offset
Definition: types.hh:149
static const CommandInfo commandInfo[]
Array to map Command enum to associated info.
Definition: packet.hh:174
const std::string & curPrefix()
Returns the current line prefix.
Definition: packet.hh:417
void popLabel()
Pop a label off the label stack.
Definition: packet.cc:392
PrintReqState(std::ostream &os, int verbosity=0)
Definition: packet.cc:364
Bitfield< 17 > os
Definition: misc.hh:804
#define SET7(a1, a2, a3, a4, a5, a6, a7)
Definition: packet.cc:69
std::ostream & os
Definition: packet.hh:408
#define SET3(a1, a2, a3)
Definition: packet.cc:65
Structure that defines attributes and other data associated with a Command.
Definition: packet.hh:162
#define SET1(a1)
Definition: packet.cc:63
An entry in the label stack.
Definition: packet.hh:394
#define SET2(a1, a2)
Definition: packet.cc:64
SenderState * predecessor
Definition: packet.hh:379
void printLabels()
Print all of the pending unprinted labels on the stack.
Definition: packet.cc:401
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
T safe_cast(U ptr)
Definition: cast.hh:61
std::string * curPrefixPtr
Definition: packet.hh:405
Abstract base class for objects which support being printed to a stream for debugging.
Definition: printable.hh:44
A virtual base opaque structure used to hold state associated with the packet (e.g., an MSHR), specific to a MemObject that sees the packet.
Definition: packet.hh:377
bool checkFunctional(PacketPtr other)
Check a functional request against a memory value stored in another packet (i.e.
Definition: packet.hh:1115
void pushLabel(const std::string &lbl, const std::string &prefix=" ")
Push a label onto the label stack, and prepend the given prefix string onto the current prefix...
Definition: packet.cc:384
int size()
Definition: pagetable.hh:146
Declaration of the Packet class.
#define SET6(a1, a2, a3, a4, a5, a6)
Definition: packet.cc:68
#define SET5(a1, a2, a3, a4, a5)
Definition: packet.cc:67
virtual void print(std::ostream &os, int verbosity=0, const std::string &prefix="") const =0
void pushSenderState(SenderState *sender_state)
Push a new sender state to the packet and make the current sender state the predecessor of the new on...
Definition: packet.cc:329
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
Definition: packet.cc:337
void printObj(Printable *obj)
Print a Printable object to os, because it matched the address on a PrintReq.
Definition: packet.cc:418

Generated on Fri Jun 9 2017 13:03:49 for gem5 by doxygen 1.8.6