cpu.hh (8733:64a7bf8fa56c) cpu.hh (8793:5f25086326ac)
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 *
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
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
50#include "arch/predecoder.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"
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"
59#include "debug/Checker.hh"
60#include "params/CheckerCPU.hh"
61#include "sim/eventq.hh"
62
63// forward declarations
46#include "sim/eventq.hh"
47
48// forward declarations
64#if FULL_SYSTEM
65namespace TheISA
66{
67 class TLB;
68}
49namespace TheISA
50{
51 class TLB;
52}
69class Processor;
70class PhysicalMemory;
71
53
72#else
73
74class Process;
75
76#endif // FULL_SYSTEM
77template <class>
78class BaseDynInst;
54template <class>
55class BaseDynInst;
79class ThreadContext;
80class MemInterface;
56class CheckerCPUParams;
81class Checkpoint;
57class Checkpoint;
58class MemInterface;
59class PhysicalMemory;
60class Process;
61class Processor;
62class ThreadContext;
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
87 * the independent execution of the benchmark inside the checker. The
88 * checker verifies instructions in order, regardless of the order in
89 * which instructions complete. There are certain results that can

--- 15 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
63class Request;
64
65/**
66 * CheckerCPU class. Dynamically verifies instructions as they are
67 * completed by making sure that the instruction and its results match
68 * the independent execution of the benchmark inside the checker. The
69 * checker verifies instructions in order, regardless of the order in
70 * which instructions complete. There are certain results that can

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

86 typedef TheISA::FloatRegBits FloatRegBits;
87 typedef TheISA::MiscReg MiscReg;
88 public:
89 virtual void init();
90
91 public:
92 typedef CheckerCPUParams Params;
93 const Params *params() const
113 { return reinterpret_cast(_params); }
94 { return reinterpret_cast<const Params *>(_params); }
114 CheckerCPU(Params *p);
115 virtual ~CheckerCPU();
116
95 CheckerCPU(Params *p);
96 virtual ~CheckerCPU();
97
117 std::vector<Process*> workload;
98 Process *process;
118
119 void setSystem(System *system);
120
121 System *systemPtr;
122
123 void setIcachePort(Port *icache_port);
124
125 Port *icachePort;

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

138 // Primary thread being run.
139 SimpleThread *thread;
140
141 ThreadContext *tc;
142
143 TheISA::TLB *itb;
144 TheISA::TLB *dtb;
145
99
100 void setSystem(System *system);
101
102 System *systemPtr;
103
104 void setIcachePort(Port *icache_port);
105
106 Port *icachePort;

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

119 // Primary thread being run.
120 SimpleThread *thread;
121
122 ThreadContext *tc;
123
124 TheISA::TLB *itb;
125 TheISA::TLB *dtb;
126
146#if FULL_SYSTEM
147 Addr dbg_vtophys(Addr addr);
127 Addr dbg_vtophys(Addr addr);
148#endif
149
150 union Result {
151 uint64_t integer;
128
129 union Result {
130 uint64_t integer;
131// float fp;
152 double dbl;
132 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; }
157 };
158
133 };
134
159 // ISAs like ARM can have multiple destination registers to check,
160 // keep them all in a std::queue
161 std::queue<Result> result;
135 Result result;
162
163 // current instruction
136
137 // current instruction
164 TheISA::MachInst machInst;
138 MachInst machInst;
165
166 // Pointer to the one memory request.
167 RequestPtr memReq;
168
169 StaticInstPtr curStaticInst;
139
140 // Pointer to the one memory request.
141 RequestPtr memReq;
142
143 StaticInstPtr curStaticInst;
170 StaticInstPtr curMacroStaticInst;
171
172 // number of simulated instructions
173 Counter numInst;
174 Counter startNumInst;
175
176 std::queue<int> miscRegIdxs;
177
144
145 // number of simulated instructions
146 Counter numInst;
147 Counter startNumInst;
148
149 std::queue<int> miscRegIdxs;
150
178 TheISA::TLB* getITBPtr() { return itb; }
179 TheISA::TLB* getDTBPtr() { return dtb; }
180
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
151 virtual Counter totalInstructions() const
152 {
153 return 0;
154 }
155
156 // number of simulated loads
157 Counter numLoad;
158 Counter startNumLoad;
159
160 virtual void serialize(std::ostream &os);
161 virtual void unserialize(Checkpoint *cp, const std::string &section);
162
163 template <class T>
164 Fault read(Addr addr, T &data, unsigned flags);
165
166 template <class T>
167 Fault write(T data, Addr addr, unsigned flags, uint64_t *res);
168
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
169 // These functions are only used in CPU models that split
170 // effective address computation from the actual memory access.
171 void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); }
172 Addr getEA() { panic("SimpleCPU::getEA() not implemented\n"); }
173
174 // The register accessor methods provide the index of the
175 // instruction's operand (e.g., 0 or 1), not the architectural
176 // register index, to simplify the implementation of register

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

194 }
195
196 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
197 {
198 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
199 return thread->readFloatRegBits(reg_idx);
200 }
201
226 template <class T>
227 void setResult(T t)
228 {
229 Result instRes;
230 instRes.set(t);
231 result.push(instRes);
232 }
233
234 void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
235 {
236 thread->setIntReg(si->destRegIdx(idx), val);
202 void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
203 {
204 thread->setIntReg(si->destRegIdx(idx), val);
237 setResult<uint64_t>(val);
205 result.integer = 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);
206 }
207
208 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
209 {
210 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
211 thread->setFloatReg(reg_idx, val);
244 setResult<double>(val);
212 result.dbl = (double)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);
213 }
214
215 void setFloatRegOperandBits(const StaticInst *si, int idx,
216 FloatRegBits val)
217 {
218 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
219 thread->setFloatRegBits(reg_idx, val);
252 setResult<uint64_t>(val);
220 result.integer = val;
253 }
254
221 }
222
255 bool readPredicate() { return thread->readPredicate(); }
256 void setPredicate(bool val)
257 {
258 thread->setPredicate(val);
259 }
223 uint64_t instAddr() { return thread->instAddr(); }
260
224
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 //////////////////////////////////////////
225 uint64_t nextInstAddr() { return thread->nextInstAddr(); }
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 {
226
227 MiscReg readMiscRegNoEffect(int misc_reg)
228 {
229 return thread->readMiscRegNoEffect(misc_reg);
230 }
231
232 MiscReg readMiscReg(int misc_reg)
233 {
234 return thread->readMiscReg(misc_reg);
235 }
236
237 void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
238 {
239 result.integer = val;
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
240 miscRegIdxs.push(misc_reg);
241 return thread->setMiscRegNoEffect(misc_reg, val);
242 }
243
244 void setMiscReg(int misc_reg, const MiscReg &val)
245 {
246 miscRegIdxs.push(misc_reg);
247 return thread->setMiscReg(misc_reg, val);
248 }
249
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 }
250 void recordPCChange(uint64_t val) { changedPC = true; newPC = val; }
251 void recordNextPCChange(uint64_t val) { changedNextPC = true; }
300
252
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
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
253 void demapPage(Addr vaddr, uint64_t asn)
254 {
255 this->itb->demapPage(vaddr, asn);
256 this->dtb->demapPage(vaddr, asn);
257 }
258
259 void demapInstPage(Addr vaddr, uint64_t asn)
260 {
261 this->itb->demapPage(vaddr, asn);
262 }
263
264 void demapDataPage(Addr vaddr, uint64_t asn)
265 {
266 this->dtb->demapPage(vaddr, asn);
267 }
268
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
339#if FULL_SYSTEM
340 Fault hwrei() { return thread->hwrei(); }
341 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
269 Fault hwrei() { return thread->hwrei(); }
270 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
342 void wakeup() { }
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) { }
271 // Assume that the normal CPU's call to syscall was successful.
272 // The checker's state would have already been updated by the syscall.
273 void syscall(uint64_t callnum) { }
347#endif
348
349 void handleError()
350 {
351 if (exitOnError)
352 dumpAndExit();
353 }
354
274
275 void handleError()
276 {
277 if (exitOnError)
278 dumpAndExit();
279 }
280
355 bool checkFlags(Request *unverified_req, Addr vAddr,
356 Addr pAddr, int flags);
281 bool checkFlags(Request *req);
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;
282
283 void dumpAndExit();
284
285 ThreadContext *tcBase() { return tc; }
286 SimpleThread *threadBase() { return thread; }
287
288 Result unverifiedResult;
289 Request *unverifiedReq;
290 uint8_t *unverifiedMemData;
291
292 bool changedPC;
293 bool willChangePC;
369 TheISA::PCState newPCState;
294 uint64_t newPC;
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 */
295 bool changedNextPC;
296 bool exitOnError;
297 bool updateOnError;
298 bool warnOnlyOnLoadError;
299
300 InstSeqNum youngestSN;
301};
302
303/**
304 * Templated Checker class. This Checker class is templated on the
305 * DynInstPtr of the instruction type that will be verified. Proper
306 * template instantiations of the Checker must be placed at the bottom
307 * of checker/cpu.cc.
308 */
384template <class Impl>
309template <class DynInstPtr>
385class Checker : public CheckerCPU
386{
310class Checker : public CheckerCPU
311{
387 private:
388 typedef typename Impl::DynInstPtr DynInstPtr;
389
390 public:
391 Checker(Params *p)
312 public:
313 Checker(Params *p)
392 : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL),
393 predecoder(NULL)
314 : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL)
394 { }
395
396 void switchOut();
397 void takeOverFrom(BaseCPU *oldCPU);
398
315 { }
316
317 void switchOut();
318 void takeOverFrom(BaseCPU *oldCPU);
319
399 void advancePC(Fault fault);
400
401 void verify(DynInstPtr &inst);
402
403 void validateInst(DynInstPtr &inst);
404 void validateExecution(DynInstPtr &inst);
405 void validateState();
406
320 void verify(DynInstPtr &inst);
321
322 void validateInst(DynInstPtr &inst);
323 void validateExecution(DynInstPtr &inst);
324 void validateState();
325
407 void copyResult(DynInstPtr &inst, uint64_t mismatch_val, int start_idx);
408 void handlePendingInt();
326 void copyResult(DynInstPtr &inst);
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;
327
328 private:
329 void handleError(DynInstPtr &inst)
330 {
331 if (exitOnError) {
332 dumpAndExit(inst);
333 } else if (updateOnError) {
334 updateThisCycle = true;
335 }
336 }
337
338 void dumpAndExit(DynInstPtr &inst);
339
340 bool updateThisCycle;
341
342 DynInstPtr unverifiedInst;
425 TheISA::Predecoder predecoder;
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__
343
344 std::list<DynInstPtr> instList;
345 typedef typename std::list<DynInstPtr>::iterator InstListIt;
346 void dumpInsts();
347};
348
349#endif // __CPU_CHECKER_CPU_HH__