cpu.hh (8229:78bf55f23338) cpu.hh (8733:64a7bf8fa56c)
1/*
1/*
2 * Copyright (c) 2011 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 *
2 * Copyright (c) 2006 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

--- 20 unchanged lines hidden (view full) ---

30
31#ifndef __CPU_CHECKER_CPU_HH__
32#define __CPU_CHECKER_CPU_HH__
33
34#include <list>
35#include <map>
36#include <queue>
37
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

--- 20 unchanged lines hidden (view full) ---

42
43#ifndef __CPU_CHECKER_CPU_HH__
44#define __CPU_CHECKER_CPU_HH__
45
46#include <list>
47#include <map>
48#include <queue>
49
50#include "arch/predecoder.hh"
38#include "arch/types.hh"
39#include "base/statistics.hh"
40#include "config/full_system.hh"
41#include "cpu/base.hh"
42#include "cpu/base_dyn_inst.hh"
43#include "cpu/pc_event.hh"
44#include "cpu/simple_thread.hh"
45#include "cpu/static_inst.hh"
51#include "arch/types.hh"
52#include "base/statistics.hh"
53#include "config/full_system.hh"
54#include "cpu/base.hh"
55#include "cpu/base_dyn_inst.hh"
56#include "cpu/pc_event.hh"
57#include "cpu/simple_thread.hh"
58#include "cpu/static_inst.hh"
59#include "debug/Checker.hh"
60#include "params/CheckerCPU.hh"
46#include "sim/eventq.hh"
47
48// forward declarations
49#if FULL_SYSTEM
50namespace TheISA
51{
52 class TLB;
53}
54class Processor;
55class PhysicalMemory;
56
57#else
58
59class Process;
60
61#endif // FULL_SYSTEM
62template <class>
63class BaseDynInst;
61#include "sim/eventq.hh"
62
63// forward declarations
64#if FULL_SYSTEM
65namespace TheISA
66{
67 class TLB;
68}
69class Processor;
70class PhysicalMemory;
71
72#else
73
74class Process;
75
76#endif // FULL_SYSTEM
77template <class>
78class BaseDynInst;
64class CheckerCPUParams;
65class ThreadContext;
66class MemInterface;
67class Checkpoint;
68class Request;
69
70/**
71 * CheckerCPU class. Dynamically verifies instructions as they are
72 * completed by making sure that the instruction and its results match

--- 18 unchanged lines hidden (view full) ---

91 typedef TheISA::FloatRegBits FloatRegBits;
92 typedef TheISA::MiscReg MiscReg;
93 public:
94 virtual void init();
95
96 public:
97 typedef CheckerCPUParams Params;
98 const Params *params() const
79class ThreadContext;
80class MemInterface;
81class Checkpoint;
82class Request;
83
84/**
85 * CheckerCPU class. Dynamically verifies instructions as they are
86 * completed by making sure that the instruction and its results match

--- 18 unchanged lines hidden (view full) ---

105 typedef TheISA::FloatRegBits FloatRegBits;
106 typedef TheISA::MiscReg MiscReg;
107 public:
108 virtual void init();
109
110 public:
111 typedef CheckerCPUParams Params;
112 const Params *params() const
99 { return reinterpret_cast<const Params *>(_params); }
113 { return reinterpret_cast(_params); }
100 CheckerCPU(Params *p);
101 virtual ~CheckerCPU();
102
114 CheckerCPU(Params *p);
115 virtual ~CheckerCPU();
116
103 Process *process;
117 std::vector<Process*> workload;
104
105 void setSystem(System *system);
106
107 System *systemPtr;
108
109 void setIcachePort(Port *icache_port);
110
111 Port *icachePort;

--- 18 unchanged lines hidden (view full) ---

130 TheISA::TLB *dtb;
131
132#if FULL_SYSTEM
133 Addr dbg_vtophys(Addr addr);
134#endif
135
136 union Result {
137 uint64_t integer;
118
119 void setSystem(System *system);
120
121 System *systemPtr;
122
123 void setIcachePort(Port *icache_port);
124
125 Port *icachePort;

--- 18 unchanged lines hidden (view full) ---

144 TheISA::TLB *dtb;
145
146#if FULL_SYSTEM
147 Addr dbg_vtophys(Addr addr);
148#endif
149
150 union Result {
151 uint64_t integer;
138// float fp;
139 double dbl;
152 double dbl;
153 void set(uint64_t i) { integer = i; }
154 void set(double d) { dbl = d; }
155 void get(uint64_t& i) { i = integer; }
156 void get(double& d) { d = dbl; }
140 };
141
157 };
158
142 Result result;
159 // ISAs like ARM can have multiple destination registers to check,
160 // keep them all in a std::queue
161 std::queue<Result> result;
143
144 // current instruction
162
163 // current instruction
145 MachInst machInst;
164 TheISA::MachInst machInst;
146
147 // Pointer to the one memory request.
148 RequestPtr memReq;
149
150 StaticInstPtr curStaticInst;
165
166 // Pointer to the one memory request.
167 RequestPtr memReq;
168
169 StaticInstPtr curStaticInst;
170 StaticInstPtr curMacroStaticInst;
151
152 // number of simulated instructions
153 Counter numInst;
154 Counter startNumInst;
155
156 std::queue<int> miscRegIdxs;
157
171
172 // number of simulated instructions
173 Counter numInst;
174 Counter startNumInst;
175
176 std::queue<int> miscRegIdxs;
177
178 TheISA::TLB* getITBPtr() { return itb; }
179 TheISA::TLB* getDTBPtr() { return dtb; }
180
158 virtual Counter totalInstructions() const
159 {
160 return 0;
161 }
162
163 // number of simulated loads
164 Counter numLoad;
165 Counter startNumLoad;
166
167 virtual void serialize(std::ostream &os);
168 virtual void unserialize(Checkpoint *cp, const std::string &section);
169
181 virtual Counter totalInstructions() const
182 {
183 return 0;
184 }
185
186 // number of simulated loads
187 Counter numLoad;
188 Counter startNumLoad;
189
190 virtual void serialize(std::ostream &os);
191 virtual void unserialize(Checkpoint *cp, const std::string &section);
192
170 template <class T>
171 Fault read(Addr addr, T &data, unsigned flags);
172
173 template <class T>
174 Fault write(T data, Addr addr, unsigned flags, uint64_t *res);
175
176 // These functions are only used in CPU models that split
177 // effective address computation from the actual memory access.
178 void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); }
179 Addr getEA() { panic("SimpleCPU::getEA() not implemented\n"); }
180
181 // The register accessor methods provide the index of the
182 // instruction's operand (e.g., 0 or 1), not the architectural
183 // register index, to simplify the implementation of register

--- 17 unchanged lines hidden (view full) ---

201 }
202
203 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
204 {
205 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
206 return thread->readFloatRegBits(reg_idx);
207 }
208
193 // These functions are only used in CPU models that split
194 // effective address computation from the actual memory access.
195 void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); }
196 Addr getEA() { panic("SimpleCPU::getEA() not implemented\n"); }
197
198 // The register accessor methods provide the index of the
199 // instruction's operand (e.g., 0 or 1), not the architectural
200 // register index, to simplify the implementation of register

--- 17 unchanged lines hidden (view full) ---

218 }
219
220 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
221 {
222 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
223 return thread->readFloatRegBits(reg_idx);
224 }
225
226 template <class T>
227 void setResult(T t)
228 {
229 Result instRes;
230 instRes.set(t);
231 result.push(instRes);
232 }
233
209 void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
210 {
211 thread->setIntReg(si->destRegIdx(idx), val);
234 void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
235 {
236 thread->setIntReg(si->destRegIdx(idx), val);
212 result.integer = val;
237 setResult<uint64_t>(val);
213 }
214
215 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
216 {
217 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
218 thread->setFloatReg(reg_idx, val);
238 }
239
240 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
241 {
242 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
243 thread->setFloatReg(reg_idx, val);
219 result.dbl = (double)val;
244 setResult<double>(val);
220 }
221
222 void setFloatRegOperandBits(const StaticInst *si, int idx,
223 FloatRegBits val)
224 {
225 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
226 thread->setFloatRegBits(reg_idx, val);
245 }
246
247 void setFloatRegOperandBits(const StaticInst *si, int idx,
248 FloatRegBits val)
249 {
250 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
251 thread->setFloatRegBits(reg_idx, val);
227 result.integer = val;
252 setResult<uint64_t>(val);
228 }
229
253 }
254
230 uint64_t instAddr() { return thread->instAddr(); }
255 bool readPredicate() { return thread->readPredicate(); }
256 void setPredicate(bool val)
257 {
258 thread->setPredicate(val);
259 }
231
260
232 uint64_t nextInstAddr() { return thread->nextInstAddr(); }
261 TheISA::PCState pcState() { return thread->pcState(); }
262 void pcState(const TheISA::PCState &val)
263 {
264 DPRINTF(Checker, "Changing PC to %s, old PC %s.\n",
265 val, thread->pcState());
266 thread->pcState(val);
267 }
268 Addr instAddr() { return thread->instAddr(); }
269 Addr nextInstAddr() { return thread->nextInstAddr(); }
270 MicroPC microPC() { return thread->microPC(); }
271 //////////////////////////////////////////
233
234 MiscReg readMiscRegNoEffect(int misc_reg)
235 {
236 return thread->readMiscRegNoEffect(misc_reg);
237 }
238
239 MiscReg readMiscReg(int misc_reg)
240 {
241 return thread->readMiscReg(misc_reg);
242 }
243
244 void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
245 {
272
273 MiscReg readMiscRegNoEffect(int misc_reg)
274 {
275 return thread->readMiscRegNoEffect(misc_reg);
276 }
277
278 MiscReg readMiscReg(int misc_reg)
279 {
280 return thread->readMiscReg(misc_reg);
281 }
282
283 void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
284 {
246 result.integer = val;
247 miscRegIdxs.push(misc_reg);
248 return thread->setMiscRegNoEffect(misc_reg, val);
249 }
250
251 void setMiscReg(int misc_reg, const MiscReg &val)
252 {
253 miscRegIdxs.push(misc_reg);
254 return thread->setMiscReg(misc_reg, val);
255 }
256
285 miscRegIdxs.push(misc_reg);
286 return thread->setMiscRegNoEffect(misc_reg, val);
287 }
288
289 void setMiscReg(int misc_reg, const MiscReg &val)
290 {
291 miscRegIdxs.push(misc_reg);
292 return thread->setMiscReg(misc_reg, val);
293 }
294
257 void recordPCChange(uint64_t val) { changedPC = true; newPC = val; }
258 void recordNextPCChange(uint64_t val) { changedNextPC = true; }
295 MiscReg readMiscRegOperand(const StaticInst *si, int idx)
296 {
297 int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
298 return thread->readMiscReg(reg_idx);
299 }
259
300
301 void setMiscRegOperand(
302 const StaticInst *si, int idx, const MiscReg &val)
303 {
304 int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
305 return thread->setMiscReg(reg_idx, val);
306 }
307 /////////////////////////////////////////
308
309 void recordPCChange(const TheISA::PCState &val)
310 {
311 changedPC = true;
312 newPCState = val;
313 }
314
260 void demapPage(Addr vaddr, uint64_t asn)
261 {
262 this->itb->demapPage(vaddr, asn);
263 this->dtb->demapPage(vaddr, asn);
264 }
265
266 void demapInstPage(Addr vaddr, uint64_t asn)
267 {
268 this->itb->demapPage(vaddr, asn);
269 }
270
271 void demapDataPage(Addr vaddr, uint64_t asn)
272 {
273 this->dtb->demapPage(vaddr, asn);
274 }
275
315 void demapPage(Addr vaddr, uint64_t asn)
316 {
317 this->itb->demapPage(vaddr, asn);
318 this->dtb->demapPage(vaddr, asn);
319 }
320
321 void demapInstPage(Addr vaddr, uint64_t asn)
322 {
323 this->itb->demapPage(vaddr, asn);
324 }
325
326 void demapDataPage(Addr vaddr, uint64_t asn)
327 {
328 this->dtb->demapPage(vaddr, asn);
329 }
330
331 Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags);
332 Fault writeMem(uint8_t *data, unsigned size,
333 Addr addr, unsigned flags, uint64_t *res);
334
335 void setStCondFailures(unsigned sc_failures)
336 {}
337 /////////////////////////////////////////////////////
338
276#if FULL_SYSTEM
277 Fault hwrei() { return thread->hwrei(); }
278 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
339#if FULL_SYSTEM
340 Fault hwrei() { return thread->hwrei(); }
341 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
342 void wakeup() { }
279#else
280 // Assume that the normal CPU's call to syscall was successful.
281 // The checker's state would have already been updated by the syscall.
282 void syscall(uint64_t callnum) { }
283#endif
284
285 void handleError()
286 {
287 if (exitOnError)
288 dumpAndExit();
289 }
290
343#else
344 // Assume that the normal CPU's call to syscall was successful.
345 // The checker's state would have already been updated by the syscall.
346 void syscall(uint64_t callnum) { }
347#endif
348
349 void handleError()
350 {
351 if (exitOnError)
352 dumpAndExit();
353 }
354
291 bool checkFlags(Request *req);
355 bool checkFlags(Request *unverified_req, Addr vAddr,
356 Addr pAddr, int flags);
292
293 void dumpAndExit();
294
295 ThreadContext *tcBase() { return tc; }
296 SimpleThread *threadBase() { return thread; }
297
298 Result unverifiedResult;
299 Request *unverifiedReq;
300 uint8_t *unverifiedMemData;
301
302 bool changedPC;
303 bool willChangePC;
357
358 void dumpAndExit();
359
360 ThreadContext *tcBase() { return tc; }
361 SimpleThread *threadBase() { return thread; }
362
363 Result unverifiedResult;
364 Request *unverifiedReq;
365 uint8_t *unverifiedMemData;
366
367 bool changedPC;
368 bool willChangePC;
304 uint64_t newPC;
369 TheISA::PCState newPCState;
305 bool changedNextPC;
306 bool exitOnError;
307 bool updateOnError;
308 bool warnOnlyOnLoadError;
309
310 InstSeqNum youngestSN;
311};
312
313/**
314 * Templated Checker class. This Checker class is templated on the
315 * DynInstPtr of the instruction type that will be verified. Proper
316 * template instantiations of the Checker must be placed at the bottom
317 * of checker/cpu.cc.
318 */
370 bool changedNextPC;
371 bool exitOnError;
372 bool updateOnError;
373 bool warnOnlyOnLoadError;
374
375 InstSeqNum youngestSN;
376};
377
378/**
379 * Templated Checker class. This Checker class is templated on the
380 * DynInstPtr of the instruction type that will be verified. Proper
381 * template instantiations of the Checker must be placed at the bottom
382 * of checker/cpu.cc.
383 */
319template <class DynInstPtr>
384template <class Impl>
320class Checker : public CheckerCPU
321{
385class Checker : public CheckerCPU
386{
387 private:
388 typedef typename Impl::DynInstPtr DynInstPtr;
389
322 public:
323 Checker(Params *p)
390 public:
391 Checker(Params *p)
324 : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL)
392 : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL),
393 predecoder(NULL)
325 { }
326
327 void switchOut();
328 void takeOverFrom(BaseCPU *oldCPU);
329
394 { }
395
396 void switchOut();
397 void takeOverFrom(BaseCPU *oldCPU);
398
399 void advancePC(Fault fault);
400
330 void verify(DynInstPtr &inst);
331
332 void validateInst(DynInstPtr &inst);
333 void validateExecution(DynInstPtr &inst);
334 void validateState();
335
401 void verify(DynInstPtr &inst);
402
403 void validateInst(DynInstPtr &inst);
404 void validateExecution(DynInstPtr &inst);
405 void validateState();
406
336 void copyResult(DynInstPtr &inst);
407 void copyResult(DynInstPtr &inst, uint64_t mismatch_val, int start_idx);
408 void handlePendingInt();
337
338 private:
339 void handleError(DynInstPtr &inst)
340 {
341 if (exitOnError) {
342 dumpAndExit(inst);
343 } else if (updateOnError) {
344 updateThisCycle = true;
345 }
346 }
347
348 void dumpAndExit(DynInstPtr &inst);
349
350 bool updateThisCycle;
351
352 DynInstPtr unverifiedInst;
409
410 private:
411 void handleError(DynInstPtr &inst)
412 {
413 if (exitOnError) {
414 dumpAndExit(inst);
415 } else if (updateOnError) {
416 updateThisCycle = true;
417 }
418 }
419
420 void dumpAndExit(DynInstPtr &inst);
421
422 bool updateThisCycle;
423
424 DynInstPtr unverifiedInst;
425 TheISA::Predecoder predecoder;
353
354 std::list<DynInstPtr> instList;
355 typedef typename std::list<DynInstPtr>::iterator InstListIt;
356 void dumpInsts();
357};
358
359#endif // __CPU_CHECKER_CPU_HH__
426
427 std::list<DynInstPtr> instList;
428 typedef typename std::list<DynInstPtr>::iterator InstListIt;
429 void dumpInsts();
430};
431
432#endif // __CPU_CHECKER_CPU_HH__