gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cpu.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011,2013 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  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  * Authors: Kevin Lim
41  * Geoffrey Blake
42  */
43 
44 #include "cpu/checker/cpu.hh"
45 
46 #include <list>
47 #include <string>
48 
49 #include "arch/generic/tlb.hh"
50 #include "arch/kernel_stats.hh"
51 #include "arch/vtophys.hh"
52 #include "cpu/base.hh"
53 #include "cpu/simple_thread.hh"
54 #include "cpu/static_inst.hh"
55 #include "cpu/thread_context.hh"
56 #include "params/CheckerCPU.hh"
57 #include "sim/full_system.hh"
58 
59 using namespace std;
60 using namespace TheISA;
61 
62 void
64 {
65  masterId = systemPtr->getMasterId(name());
66 }
67 
69  : BaseCPU(p, true), systemPtr(NULL), icachePort(NULL), dcachePort(NULL),
70  tc(NULL), thread(NULL)
71 {
72  memReq = NULL;
73  curStaticInst = NULL;
74  curMacroStaticInst = NULL;
75 
76  numInst = 0;
77  startNumInst = 0;
78  numLoad = 0;
79  startNumLoad = 0;
80  youngestSN = 0;
81 
82  changedPC = willChangePC = false;
83 
84  exitOnError = p->exitOnError;
85  warnOnlyOnLoadError = p->warnOnlyOnLoadError;
86  itb = p->itb;
87  dtb = p->dtb;
88  workload = p->workload;
89 
90  updateOnError = true;
91 }
92 
94 {
95 }
96 
97 void
99 {
100  const Params *p(dynamic_cast<const Params *>(_params));
101 
102  systemPtr = system;
103 
104  if (FullSystem) {
105  thread = new SimpleThread(this, 0, systemPtr, itb, dtb,
106  p->isa[0], false);
107  } else {
108  thread = new SimpleThread(this, 0, systemPtr,
109  workload.size() ? workload[0] : NULL,
110  itb, dtb, p->isa[0]);
111  }
112 
113  tc = thread->getTC();
114  threadContexts.push_back(tc);
115  thread->kernelStats = NULL;
116  // Thread should never be null after this
117  assert(thread != NULL);
118 }
119 
120 void
122 {
123  icachePort = icache_port;
124 }
125 
126 void
128 {
129  dcachePort = dcache_port;
130 }
131 
132 void
133 CheckerCPU::serialize(ostream &os) const
134 {
135 }
136 
137 void
139 {
140 }
141 
142 Fault
143 CheckerCPU::readMem(Addr addr, uint8_t *data, unsigned size,
144  Request::Flags flags)
145 {
146  Fault fault = NoFault;
147  int fullSize = size;
148  Addr secondAddr = roundDown(addr + size - 1, cacheLineSize());
149  bool checked_flags = false;
150  bool flags_match = true;
151  Addr pAddr = 0x0;
152 
153 
154  if (secondAddr > addr)
155  size = secondAddr - addr;
156 
157  // Need to account for multiple accesses like the Atomic and TimingSimple
158  while (1) {
159  memReq = new Request(0, addr, size, flags, masterId,
160  thread->pcState().instAddr(), tc->contextId());
161 
162  // translate to physical address
163  fault = dtb->translateFunctional(memReq, tc, BaseTLB::Read);
164 
165  if (!checked_flags && fault == NoFault && unverifiedReq) {
166  flags_match = checkFlags(unverifiedReq, memReq->getVaddr(),
167  memReq->getPaddr(), memReq->getFlags());
168  pAddr = memReq->getPaddr();
169  checked_flags = true;
170  }
171 
172  // Now do the access
173  if (fault == NoFault &&
176 
177  pkt->dataStatic(data);
178 
179  if (!(memReq->isUncacheable() || memReq->isMmappedIpr())) {
180  // Access memory to see if we have the same data
182  } else {
183  // Assume the data is correct if it's an uncached access
184  memcpy(data, unverifiedMemData, size);
185  }
186 
187  delete memReq;
188  memReq = NULL;
189  delete pkt;
190  }
191 
192  if (fault != NoFault) {
193  if (memReq->isPrefetch()) {
194  fault = NoFault;
195  }
196  delete memReq;
197  memReq = NULL;
198  break;
199  }
200 
201  if (memReq != NULL) {
202  delete memReq;
203  }
204 
205  //If we don't need to access a second cache line, stop now.
206  if (secondAddr <= addr)
207  {
208  break;
209  }
210 
211  // Setup for accessing next cache line
212  data += size;
214  size = addr + fullSize - secondAddr;
215  addr = secondAddr;
216  }
217 
218  if (!flags_match) {
219  warn("%lli: Flags do not match CPU:%#x %#x %#x Checker:%#x %#x %#x\n",
221  unverifiedReq->getFlags(), addr, pAddr, flags);
222  handleError();
223  }
224 
225  return fault;
226 }
227 
228 Fault
229 CheckerCPU::writeMem(uint8_t *data, unsigned size,
230  Addr addr, Request::Flags flags, uint64_t *res)
231 {
232  Fault fault = NoFault;
233  bool checked_flags = false;
234  bool flags_match = true;
235  Addr pAddr = 0x0;
236  static uint8_t zero_data[64] = {};
237 
238  int fullSize = size;
239 
240  Addr secondAddr = roundDown(addr + size - 1, cacheLineSize());
241 
242  if (secondAddr > addr)
243  size = secondAddr - addr;
244 
245  // Need to account for a multiple access like Atomic and Timing CPUs
246  while (1) {
247  memReq = new Request(0, addr, size, flags, masterId,
248  thread->pcState().instAddr(), tc->contextId());
249 
250  // translate to physical address
251  fault = dtb->translateFunctional(memReq, tc, BaseTLB::Write);
252 
253  if (!checked_flags && fault == NoFault && unverifiedReq) {
254  flags_match = checkFlags(unverifiedReq, memReq->getVaddr(),
255  memReq->getPaddr(), memReq->getFlags());
256  pAddr = memReq->getPaddr();
257  checked_flags = true;
258  }
259 
260  /*
261  * We don't actually check memory for the store because there
262  * is no guarantee it has left the lsq yet, and therefore we
263  * can't verify the memory on stores without lsq snooping
264  * enabled. This is left as future work for the Checker: LSQ snooping
265  * and memory validation after stores have committed.
266  */
267  bool was_prefetch = memReq->isPrefetch();
268 
269  delete memReq;
270 
271  //If we don't need to access a second cache line, stop now.
272  if (fault != NoFault || secondAddr <= addr)
273  {
274  if (fault != NoFault && was_prefetch) {
275  fault = NoFault;
276  }
277  break;
278  }
279 
280  //Update size and access address
281  size = addr + fullSize - secondAddr;
282  //And access the right address.
283  addr = secondAddr;
284  }
285 
286  if (!flags_match) {
287  warn("%lli: Flags do not match CPU:%#x %#x Checker:%#x %#x %#x\n",
289  unverifiedReq->getFlags(), addr, pAddr, flags);
290  handleError();
291  }
292 
293  // Assume the result was the same as the one passed in. This checker
294  // doesn't check if the SC should succeed or fail, it just checks the
295  // value.
296  if (unverifiedReq && res && unverifiedReq->extraDataValid())
297  *res = unverifiedReq->getExtraData();
298 
299  // Entire purpose here is to make sure we are getting the
300  // same data to send to the mem system as the CPU did.
301  // Cannot check this is actually what went to memory because
302  // there stores can be in ld/st queue or coherent operations
303  // overwriting values.
304  bool extraData = false;
305  if (unverifiedReq) {
306  extraData = unverifiedReq->extraDataValid() ?
307  unverifiedReq->getExtraData() : true;
308  }
309 
310  // If the request is to ZERO a cache block, there is no data to check
311  // against, but it's all zero. We need something to compare to, so use a
312  // const set of zeros.
313  if (flags & Request::CACHE_BLOCK_ZERO) {
314  assert(!data);
315  assert(sizeof(zero_data) <= fullSize);
316  data = zero_data;
317  }
318 
320  memcmp(data, unverifiedMemData, fullSize) && extraData) {
321  warn("%lli: Store value does not match value sent to memory! "
322  "data: %#x inst_data: %#x", curTick(), data,
324  handleError();
325  }
326 
327  return fault;
328 }
329 
330 Addr
332 {
333  return vtophys(tc, addr);
334 }
335 
339 bool
340 CheckerCPU::checkFlags(Request *unverified_req, Addr vAddr,
341  Addr pAddr, int flags)
342 {
343  Addr unverifiedVAddr = unverified_req->getVaddr();
344  Addr unverifiedPAddr = unverified_req->getPaddr();
345  int unverifiedFlags = unverified_req->getFlags();
346 
347  if (unverifiedVAddr != vAddr ||
348  unverifiedPAddr != pAddr ||
349  unverifiedFlags != flags) {
350  return false;
351  }
352 
353  return true;
354 }
355 
356 void
358 {
359  warn("%lli: Checker PC:%s",
360  curTick(), thread->pcState());
361  panic("Checker found an error!");
362 }
Fault writeMem(uint8_t *data, unsigned size, Addr addr, Request::Flags flags, uint64_t *res) override
Definition: cpu.cc:229
A MasterPort is a specialisation of a BaseMasterPort, which implements the default protocol for the t...
Definition: port.hh:167
bool isUncacheable() const
Accessor functions for flags.
Definition: request.hh:767
decltype(nullptr) constexpr NoFault
Definition: types.hh:189
const std::string & name()
Definition: trace.cc:49
bool changedPC
Definition: cpu.hh:416
#define panic(...)
Definition: misc.hh:153
TheISA::TLB * dtb
Definition: cpu.hh:142
uint64_t getExtraData() const
Accessor function for store conditional return value.
Definition: request.hh:672
ip6_addr_t addr
Definition: inet.hh:335
bool isMmappedIpr() const
Definition: request.hh:776
bool isSet() const
Definition: flags.hh:62
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:146
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
This is a write that is targeted and zeroing an entire cache block.
Definition: request.hh:134
System * systemPtr
Definition: cpu.hh:134
Definition: system.hh:83
bool isPrefetch() const
Definition: request.hh:770
bool willChangePC
Definition: cpu.hh:417
StaticInstPtr curMacroStaticInst
Definition: cpu.hh:163
void setDcachePort(MasterPort *dcache_port)
Definition: cpu.cc:127
Bitfield< 17 > os
Definition: misc.hh:804
bool updateOnError
Definition: cpu.hh:420
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
Definition: packet.hh:909
const char data[]
Definition: circlebuf.cc:43
bool checkFlags(Request *unverified_req, Addr vAddr, Addr pAddr, int flags)
Checks if the flags set by the Checker and Checkee match.
Definition: cpu.cc:340
#define warn(...)
Definition: misc.hh:219
TheISA::TLB * itb
Definition: cpu.hh:141
Request * unverifiedReq
Definition: cpu.hh:413
system
Definition: isa.cc:226
Tick curTick()
The current simulated tick.
Definition: core.hh:47
ThreadContext * tc
Definition: cpu.hh:139
MasterID masterId
id attached to all issued requests
Definition: cpu.hh:100
Addr getPaddr() const
Definition: request.hh:519
uint8_t * unverifiedMemData
Definition: cpu.hh:414
bool exitOnError
Definition: cpu.hh:419
T roundDown(const T &val, const U &align)
Definition: intmath.hh:213
Counter startNumInst
Definition: cpu.hh:167
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
ThreadContext * getTC()
Returns the pointer to this SimpleThread's ThreadContext.
bool extraDataValid() const
Accessor function to check if sc result is valid.
Definition: request.hh:665
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
SimpleThread * thread
Definition: cpu.hh:174
Addr dbg_vtophys(Addr addr)
Definition: cpu.cc:331
void serialize(CheckpointOut &cp) const override
Definition: cpu.cc:133
TheISA::PCState pcState()
Flags getFlags()
Accessor for flags.
Definition: request.hh:584
CheckerCPUParams Params
Definition: cpu.hh:104
TheISA::Kernel::Statistics * kernelStats
Counter startNumLoad
Definition: cpu.hh:191
void setIcachePort(MasterPort *icache_port)
Definition: cpu.cc:121
int size()
Definition: pagetable.hh:146
Counter numInst
Definition: cpu.hh:166
Addr vtophys(Addr vaddr)
Definition: vtophys.cc:75
The request should not cause a memory access.
Definition: request.hh:137
MasterPort * icachePort
Definition: cpu.hh:136
std::vector< Process * > workload
Definition: cpu.hh:132
void setSystem(System *system)
Definition: cpu.cc:98
Addr getVaddr() const
Definition: request.hh:616
virtual int contextId() const =0
virtual ~CheckerCPU()
Definition: cpu.cc:93
bool warnOnlyOnLoadError
Definition: cpu.hh:421
static PacketPtr createRead(const RequestPtr req)
Constructor-like methods that return Packets based on Request objects.
Definition: packet.hh:809
Counter numLoad
Definition: cpu.hh:190
RequestPtr memReq
Definition: cpu.hh:160
void init() override
Definition: cpu.cc:63
CheckerCPU(Params *p)
Definition: cpu.cc:68
Bitfield< 0 > p
StaticInstPtr curStaticInst
Definition: cpu.hh:162
std::shared_ptr< FaultBase > Fault
Definition: types.hh:184
InstSeqNum youngestSN
Definition: cpu.hh:423
Fault readMem(Addr addr, uint8_t *data, unsigned size, Request::Flags flags) override
Definition: cpu.cc:143
void unserialize(CheckpointIn &cp) override
Definition: cpu.cc:138
MasterPort * dcachePort
Definition: cpu.hh:137
void dumpAndExit()
Definition: cpu.cc:357
void sendFunctional(PacketPtr pkt)
Send a functional request packet, where the data is instantly updated everywhere in the memory system...
Definition: port.cc:173
void handleError()
Definition: cpu.hh:398

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