cpu.hh (12749:223c83ed9979) cpu.hh (13429:a1e199fd8122)
1/*
2 * Copyright (c) 2011, 2016 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2006 The Regents of The University of Michigan
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: Kevin Lim
42 */
43
44#ifndef __CPU_CHECKER_CPU_HH__
45#define __CPU_CHECKER_CPU_HH__
46
47#include <list>
48#include <map>
49#include <queue>
50
51#include "arch/types.hh"
52#include "base/statistics.hh"
53#include "cpu/base.hh"
54#include "cpu/base_dyn_inst.hh"
55#include "cpu/exec_context.hh"
56#include "cpu/inst_res.hh"
57#include "cpu/pc_event.hh"
58#include "cpu/simple_thread.hh"
59#include "cpu/static_inst.hh"
60#include "debug/Checker.hh"
61#include "mem/request.hh"
62#include "params/CheckerCPU.hh"
63#include "sim/eventq.hh"
64
65class BaseTLB;
66template <class>
67class BaseDynInst;
68class ThreadContext;
69class Request;
70
71/**
72 * CheckerCPU class. Dynamically verifies instructions as they are
73 * completed by making sure that the instruction and its results match
74 * the independent execution of the benchmark inside the checker. The
75 * checker verifies instructions in order, regardless of the order in
76 * which instructions complete. There are certain results that can
77 * not be verified, specifically the result of a store conditional or
78 * the values of uncached accesses. In these cases, and with
79 * instructions marked as "IsUnverifiable", the checker assumes that
80 * the value from the main CPU's execution is correct and simply
81 * copies that value. It provides a CheckerThreadContext (see
82 * checker/thread_context.hh) that provides hooks for updating the
83 * Checker's state through any ThreadContext accesses. This allows the
84 * checker to be able to correctly verify instructions, even with
85 * external accesses to the ThreadContext that change state.
86 */
87class CheckerCPU : public BaseCPU, public ExecContext
88{
89 protected:
90 typedef TheISA::MachInst MachInst;
91 typedef TheISA::FloatReg FloatReg;
92 typedef TheISA::FloatRegBits FloatRegBits;
93 typedef TheISA::MiscReg MiscReg;
94 using VecRegContainer = TheISA::VecRegContainer;
95
96 /** id attached to all issued requests */
97 MasterID masterId;
98 public:
99 void init() override;
100
101 typedef CheckerCPUParams Params;
102 CheckerCPU(Params *p);
103 virtual ~CheckerCPU();
104
105 void setSystem(System *system);
106
107 void setIcachePort(MasterPort *icache_port);
108
109 void setDcachePort(MasterPort *dcache_port);
110
111 MasterPort &getDataPort() override
112 {
113 // the checker does not have ports on its own so return the
114 // data port of the actual CPU core
115 assert(dcachePort);
116 return *dcachePort;
117 }
118
119 MasterPort &getInstPort() override
120 {
121 // the checker does not have ports on its own so return the
122 // data port of the actual CPU core
123 assert(icachePort);
124 return *icachePort;
125 }
126
127 protected:
128
129 std::vector<Process*> workload;
130
131 System *systemPtr;
132
133 MasterPort *icachePort;
134 MasterPort *dcachePort;
135
136 ThreadContext *tc;
137
138 BaseTLB *itb;
139 BaseTLB *dtb;
140
141 Addr dbg_vtophys(Addr addr);
142
143 // ISAs like ARM can have multiple destination registers to check,
144 // keep them all in a std::queue
145 std::queue<InstResult> result;
146
147 StaticInstPtr curStaticInst;
148 StaticInstPtr curMacroStaticInst;
149
150 // number of simulated instructions
151 Counter numInst;
152 Counter startNumInst;
153
154 std::queue<int> miscRegIdxs;
155
156 public:
157
158 // Primary thread being run.
159 SimpleThread *thread;
160
161 BaseTLB* getITBPtr() { return itb; }
162 BaseTLB* getDTBPtr() { return dtb; }
163
164 virtual Counter totalInsts() const override
165 {
166 return 0;
167 }
168
169 virtual Counter totalOps() const override
170 {
171 return 0;
172 }
173
174 // number of simulated loads
175 Counter numLoad;
176 Counter startNumLoad;
177
178 void serialize(CheckpointOut &cp) const override;
179 void unserialize(CheckpointIn &cp) override;
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
184 // renaming. We find the architectural register index by indexing
185 // into the instruction's own operand index table. Note that a
186 // raw pointer to the StaticInst is provided instead of a
187 // ref-counted StaticInstPtr to redice overhead. This is fine as
188 // long as these methods don't copy the pointer into any long-term
189 // storage (which is pretty hard to imagine they would have reason
190 // to do).
191
192 IntReg readIntRegOperand(const StaticInst *si, int idx) override
193 {
194 const RegId& reg = si->srcRegIdx(idx);
195 assert(reg.isIntReg());
196 return thread->readIntReg(reg.index());
197 }
198
199 FloatReg readFloatRegOperand(const StaticInst *si, int idx) override
200 {
201 const RegId& reg = si->srcRegIdx(idx);
202 assert(reg.isFloatReg());
203 return thread->readFloatReg(reg.index());
204 }
205
206 FloatRegBits readFloatRegOperandBits(const StaticInst *si,
207 int idx) override
208 {
209 const RegId& reg = si->srcRegIdx(idx);
210 assert(reg.isFloatReg());
211 return thread->readFloatRegBits(reg.index());
212 }
213
214 /**
215 * Read source vector register operand.
216 */
217 const VecRegContainer& readVecRegOperand(const StaticInst *si,
218 int idx) const override
219 {
220 const RegId& reg = si->srcRegIdx(idx);
221 assert(reg.isVecReg());
222 return thread->readVecReg(reg);
223 }
224
225 /**
226 * Read destination vector register operand for modification.
227 */
228 VecRegContainer& getWritableVecRegOperand(const StaticInst *si,
229 int idx) override
230 {
231 const RegId& reg = si->destRegIdx(idx);
232 assert(reg.isVecReg());
233 return thread->getWritableVecReg(reg);
234 }
235
236 /** Vector Register Lane Interfaces. */
237 /** @{ */
238 /** Reads source vector 8bit operand. */
239 virtual ConstVecLane8
240 readVec8BitLaneOperand(const StaticInst *si, int idx) const
241 override
242 {
243 const RegId& reg = si->destRegIdx(idx);
244 assert(reg.isVecReg());
245 return thread->readVec8BitLaneReg(reg);
246 }
247
248 /** Reads source vector 16bit operand. */
249 virtual ConstVecLane16
250 readVec16BitLaneOperand(const StaticInst *si, int idx) const
251 override
252 {
253 const RegId& reg = si->destRegIdx(idx);
254 assert(reg.isVecReg());
255 return thread->readVec16BitLaneReg(reg);
256 }
257
258 /** Reads source vector 32bit operand. */
259 virtual ConstVecLane32
260 readVec32BitLaneOperand(const StaticInst *si, int idx) const
261 override
262 {
263 const RegId& reg = si->destRegIdx(idx);
264 assert(reg.isVecReg());
265 return thread->readVec32BitLaneReg(reg);
266 }
267
268 /** Reads source vector 64bit operand. */
269 virtual ConstVecLane64
270 readVec64BitLaneOperand(const StaticInst *si, int idx) const
271 override
272 {
273 const RegId& reg = si->destRegIdx(idx);
274 assert(reg.isVecReg());
275 return thread->readVec64BitLaneReg(reg);
276 }
277
278 /** Write a lane of the destination vector operand. */
279 template <typename LD>
280 void
281 setVecLaneOperandT(const StaticInst *si, int idx, const LD& val)
282 {
283 const RegId& reg = si->destRegIdx(idx);
284 assert(reg.isVecReg());
285 return thread->setVecLane(reg, val);
286 }
287 virtual void
288 setVecLaneOperand(const StaticInst *si, int idx,
289 const LaneData<LaneSize::Byte>& val) override
290 {
291 setVecLaneOperandT(si, idx, val);
292 }
293 virtual void
294 setVecLaneOperand(const StaticInst *si, int idx,
295 const LaneData<LaneSize::TwoByte>& val) override
296 {
297 setVecLaneOperandT(si, idx, val);
298 }
299 virtual void
300 setVecLaneOperand(const StaticInst *si, int idx,
301 const LaneData<LaneSize::FourByte>& val) override
302 {
303 setVecLaneOperandT(si, idx, val);
304 }
305 virtual void
306 setVecLaneOperand(const StaticInst *si, int idx,
307 const LaneData<LaneSize::EightByte>& val) override
308 {
309 setVecLaneOperandT(si, idx, val);
310 }
311 /** @} */
312
313 VecElem readVecElemOperand(const StaticInst *si, int idx) const override
314 {
315 const RegId& reg = si->srcRegIdx(idx);
316 return thread->readVecElem(reg);
317 }
318
319 CCReg readCCRegOperand(const StaticInst *si, int idx) override
320 {
321 const RegId& reg = si->srcRegIdx(idx);
322 assert(reg.isCCReg());
323 return thread->readCCReg(reg.index());
324 }
325
326 template<typename T>
327 void setScalarResult(T&& t)
328 {
329 result.push(InstResult(std::forward<T>(t),
330 InstResult::ResultType::Scalar));
331 }
332
333 template<typename T>
334 void setVecResult(T&& t)
335 {
336 result.push(InstResult(std::forward<T>(t),
337 InstResult::ResultType::VecReg));
338 }
339
340 template<typename T>
341 void setVecElemResult(T&& t)
342 {
343 result.push(InstResult(std::forward<T>(t),
344 InstResult::ResultType::VecElem));
345 }
346
347 void setIntRegOperand(const StaticInst *si, int idx,
348 IntReg val) override
349 {
350 const RegId& reg = si->destRegIdx(idx);
351 assert(reg.isIntReg());
352 thread->setIntReg(reg.index(), val);
353 setScalarResult(val);
354 }
355
356 void setFloatRegOperand(const StaticInst *si, int idx,
357 FloatReg val) override
358 {
359 const RegId& reg = si->destRegIdx(idx);
360 assert(reg.isFloatReg());
361 thread->setFloatReg(reg.index(), val);
362 setScalarResult(val);
363 }
364
365 void setFloatRegOperandBits(const StaticInst *si, int idx,
366 FloatRegBits val) override
367 {
368 const RegId& reg = si->destRegIdx(idx);
369 assert(reg.isFloatReg());
370 thread->setFloatRegBits(reg.index(), val);
371 setScalarResult(val);
372 }
373
374 void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
375 {
376 const RegId& reg = si->destRegIdx(idx);
377 assert(reg.isCCReg());
378 thread->setCCReg(reg.index(), val);
379 setScalarResult((uint64_t)val);
380 }
381
382 void setVecRegOperand(const StaticInst *si, int idx,
383 const VecRegContainer& val) override
384 {
385 const RegId& reg = si->destRegIdx(idx);
386 assert(reg.isVecReg());
387 thread->setVecReg(reg, val);
388 setVecResult(val);
389 }
390
391 void setVecElemOperand(const StaticInst *si, int idx,
392 const VecElem val) override
393 {
394 const RegId& reg = si->destRegIdx(idx);
395 assert(reg.isVecElem());
396 thread->setVecElem(reg, val);
397 setVecElemResult(val);
398 }
399
1/*
2 * Copyright (c) 2011, 2016 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2006 The Regents of The University of Michigan
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: Kevin Lim
42 */
43
44#ifndef __CPU_CHECKER_CPU_HH__
45#define __CPU_CHECKER_CPU_HH__
46
47#include <list>
48#include <map>
49#include <queue>
50
51#include "arch/types.hh"
52#include "base/statistics.hh"
53#include "cpu/base.hh"
54#include "cpu/base_dyn_inst.hh"
55#include "cpu/exec_context.hh"
56#include "cpu/inst_res.hh"
57#include "cpu/pc_event.hh"
58#include "cpu/simple_thread.hh"
59#include "cpu/static_inst.hh"
60#include "debug/Checker.hh"
61#include "mem/request.hh"
62#include "params/CheckerCPU.hh"
63#include "sim/eventq.hh"
64
65class BaseTLB;
66template <class>
67class BaseDynInst;
68class ThreadContext;
69class Request;
70
71/**
72 * CheckerCPU class. Dynamically verifies instructions as they are
73 * completed by making sure that the instruction and its results match
74 * the independent execution of the benchmark inside the checker. The
75 * checker verifies instructions in order, regardless of the order in
76 * which instructions complete. There are certain results that can
77 * not be verified, specifically the result of a store conditional or
78 * the values of uncached accesses. In these cases, and with
79 * instructions marked as "IsUnverifiable", the checker assumes that
80 * the value from the main CPU's execution is correct and simply
81 * copies that value. It provides a CheckerThreadContext (see
82 * checker/thread_context.hh) that provides hooks for updating the
83 * Checker's state through any ThreadContext accesses. This allows the
84 * checker to be able to correctly verify instructions, even with
85 * external accesses to the ThreadContext that change state.
86 */
87class CheckerCPU : public BaseCPU, public ExecContext
88{
89 protected:
90 typedef TheISA::MachInst MachInst;
91 typedef TheISA::FloatReg FloatReg;
92 typedef TheISA::FloatRegBits FloatRegBits;
93 typedef TheISA::MiscReg MiscReg;
94 using VecRegContainer = TheISA::VecRegContainer;
95
96 /** id attached to all issued requests */
97 MasterID masterId;
98 public:
99 void init() override;
100
101 typedef CheckerCPUParams Params;
102 CheckerCPU(Params *p);
103 virtual ~CheckerCPU();
104
105 void setSystem(System *system);
106
107 void setIcachePort(MasterPort *icache_port);
108
109 void setDcachePort(MasterPort *dcache_port);
110
111 MasterPort &getDataPort() override
112 {
113 // the checker does not have ports on its own so return the
114 // data port of the actual CPU core
115 assert(dcachePort);
116 return *dcachePort;
117 }
118
119 MasterPort &getInstPort() override
120 {
121 // the checker does not have ports on its own so return the
122 // data port of the actual CPU core
123 assert(icachePort);
124 return *icachePort;
125 }
126
127 protected:
128
129 std::vector<Process*> workload;
130
131 System *systemPtr;
132
133 MasterPort *icachePort;
134 MasterPort *dcachePort;
135
136 ThreadContext *tc;
137
138 BaseTLB *itb;
139 BaseTLB *dtb;
140
141 Addr dbg_vtophys(Addr addr);
142
143 // ISAs like ARM can have multiple destination registers to check,
144 // keep them all in a std::queue
145 std::queue<InstResult> result;
146
147 StaticInstPtr curStaticInst;
148 StaticInstPtr curMacroStaticInst;
149
150 // number of simulated instructions
151 Counter numInst;
152 Counter startNumInst;
153
154 std::queue<int> miscRegIdxs;
155
156 public:
157
158 // Primary thread being run.
159 SimpleThread *thread;
160
161 BaseTLB* getITBPtr() { return itb; }
162 BaseTLB* getDTBPtr() { return dtb; }
163
164 virtual Counter totalInsts() const override
165 {
166 return 0;
167 }
168
169 virtual Counter totalOps() const override
170 {
171 return 0;
172 }
173
174 // number of simulated loads
175 Counter numLoad;
176 Counter startNumLoad;
177
178 void serialize(CheckpointOut &cp) const override;
179 void unserialize(CheckpointIn &cp) override;
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
184 // renaming. We find the architectural register index by indexing
185 // into the instruction's own operand index table. Note that a
186 // raw pointer to the StaticInst is provided instead of a
187 // ref-counted StaticInstPtr to redice overhead. This is fine as
188 // long as these methods don't copy the pointer into any long-term
189 // storage (which is pretty hard to imagine they would have reason
190 // to do).
191
192 IntReg readIntRegOperand(const StaticInst *si, int idx) override
193 {
194 const RegId& reg = si->srcRegIdx(idx);
195 assert(reg.isIntReg());
196 return thread->readIntReg(reg.index());
197 }
198
199 FloatReg readFloatRegOperand(const StaticInst *si, int idx) override
200 {
201 const RegId& reg = si->srcRegIdx(idx);
202 assert(reg.isFloatReg());
203 return thread->readFloatReg(reg.index());
204 }
205
206 FloatRegBits readFloatRegOperandBits(const StaticInst *si,
207 int idx) override
208 {
209 const RegId& reg = si->srcRegIdx(idx);
210 assert(reg.isFloatReg());
211 return thread->readFloatRegBits(reg.index());
212 }
213
214 /**
215 * Read source vector register operand.
216 */
217 const VecRegContainer& readVecRegOperand(const StaticInst *si,
218 int idx) const override
219 {
220 const RegId& reg = si->srcRegIdx(idx);
221 assert(reg.isVecReg());
222 return thread->readVecReg(reg);
223 }
224
225 /**
226 * Read destination vector register operand for modification.
227 */
228 VecRegContainer& getWritableVecRegOperand(const StaticInst *si,
229 int idx) override
230 {
231 const RegId& reg = si->destRegIdx(idx);
232 assert(reg.isVecReg());
233 return thread->getWritableVecReg(reg);
234 }
235
236 /** Vector Register Lane Interfaces. */
237 /** @{ */
238 /** Reads source vector 8bit operand. */
239 virtual ConstVecLane8
240 readVec8BitLaneOperand(const StaticInst *si, int idx) const
241 override
242 {
243 const RegId& reg = si->destRegIdx(idx);
244 assert(reg.isVecReg());
245 return thread->readVec8BitLaneReg(reg);
246 }
247
248 /** Reads source vector 16bit operand. */
249 virtual ConstVecLane16
250 readVec16BitLaneOperand(const StaticInst *si, int idx) const
251 override
252 {
253 const RegId& reg = si->destRegIdx(idx);
254 assert(reg.isVecReg());
255 return thread->readVec16BitLaneReg(reg);
256 }
257
258 /** Reads source vector 32bit operand. */
259 virtual ConstVecLane32
260 readVec32BitLaneOperand(const StaticInst *si, int idx) const
261 override
262 {
263 const RegId& reg = si->destRegIdx(idx);
264 assert(reg.isVecReg());
265 return thread->readVec32BitLaneReg(reg);
266 }
267
268 /** Reads source vector 64bit operand. */
269 virtual ConstVecLane64
270 readVec64BitLaneOperand(const StaticInst *si, int idx) const
271 override
272 {
273 const RegId& reg = si->destRegIdx(idx);
274 assert(reg.isVecReg());
275 return thread->readVec64BitLaneReg(reg);
276 }
277
278 /** Write a lane of the destination vector operand. */
279 template <typename LD>
280 void
281 setVecLaneOperandT(const StaticInst *si, int idx, const LD& val)
282 {
283 const RegId& reg = si->destRegIdx(idx);
284 assert(reg.isVecReg());
285 return thread->setVecLane(reg, val);
286 }
287 virtual void
288 setVecLaneOperand(const StaticInst *si, int idx,
289 const LaneData<LaneSize::Byte>& val) override
290 {
291 setVecLaneOperandT(si, idx, val);
292 }
293 virtual void
294 setVecLaneOperand(const StaticInst *si, int idx,
295 const LaneData<LaneSize::TwoByte>& val) override
296 {
297 setVecLaneOperandT(si, idx, val);
298 }
299 virtual void
300 setVecLaneOperand(const StaticInst *si, int idx,
301 const LaneData<LaneSize::FourByte>& val) override
302 {
303 setVecLaneOperandT(si, idx, val);
304 }
305 virtual void
306 setVecLaneOperand(const StaticInst *si, int idx,
307 const LaneData<LaneSize::EightByte>& val) override
308 {
309 setVecLaneOperandT(si, idx, val);
310 }
311 /** @} */
312
313 VecElem readVecElemOperand(const StaticInst *si, int idx) const override
314 {
315 const RegId& reg = si->srcRegIdx(idx);
316 return thread->readVecElem(reg);
317 }
318
319 CCReg readCCRegOperand(const StaticInst *si, int idx) override
320 {
321 const RegId& reg = si->srcRegIdx(idx);
322 assert(reg.isCCReg());
323 return thread->readCCReg(reg.index());
324 }
325
326 template<typename T>
327 void setScalarResult(T&& t)
328 {
329 result.push(InstResult(std::forward<T>(t),
330 InstResult::ResultType::Scalar));
331 }
332
333 template<typename T>
334 void setVecResult(T&& t)
335 {
336 result.push(InstResult(std::forward<T>(t),
337 InstResult::ResultType::VecReg));
338 }
339
340 template<typename T>
341 void setVecElemResult(T&& t)
342 {
343 result.push(InstResult(std::forward<T>(t),
344 InstResult::ResultType::VecElem));
345 }
346
347 void setIntRegOperand(const StaticInst *si, int idx,
348 IntReg val) override
349 {
350 const RegId& reg = si->destRegIdx(idx);
351 assert(reg.isIntReg());
352 thread->setIntReg(reg.index(), val);
353 setScalarResult(val);
354 }
355
356 void setFloatRegOperand(const StaticInst *si, int idx,
357 FloatReg val) override
358 {
359 const RegId& reg = si->destRegIdx(idx);
360 assert(reg.isFloatReg());
361 thread->setFloatReg(reg.index(), val);
362 setScalarResult(val);
363 }
364
365 void setFloatRegOperandBits(const StaticInst *si, int idx,
366 FloatRegBits val) override
367 {
368 const RegId& reg = si->destRegIdx(idx);
369 assert(reg.isFloatReg());
370 thread->setFloatRegBits(reg.index(), val);
371 setScalarResult(val);
372 }
373
374 void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
375 {
376 const RegId& reg = si->destRegIdx(idx);
377 assert(reg.isCCReg());
378 thread->setCCReg(reg.index(), val);
379 setScalarResult((uint64_t)val);
380 }
381
382 void setVecRegOperand(const StaticInst *si, int idx,
383 const VecRegContainer& val) override
384 {
385 const RegId& reg = si->destRegIdx(idx);
386 assert(reg.isVecReg());
387 thread->setVecReg(reg, val);
388 setVecResult(val);
389 }
390
391 void setVecElemOperand(const StaticInst *si, int idx,
392 const VecElem val) override
393 {
394 const RegId& reg = si->destRegIdx(idx);
395 assert(reg.isVecElem());
396 thread->setVecElem(reg, val);
397 setVecElemResult(val);
398 }
399
400 bool readPredicate() override { return thread->readPredicate(); }
400 bool readPredicate() const override { return thread->readPredicate(); }
401
401 void setPredicate(bool val) override
402 {
403 thread->setPredicate(val);
404 }
405
406 TheISA::PCState pcState() const override { return thread->pcState(); }
407 void pcState(const TheISA::PCState &val) override
408 {
409 DPRINTF(Checker, "Changing PC to %s, old PC %s.\n",
410 val, thread->pcState());
411 thread->pcState(val);
412 }
413 Addr instAddr() { return thread->instAddr(); }
414 Addr nextInstAddr() { return thread->nextInstAddr(); }
415 MicroPC microPC() { return thread->microPC(); }
416 //////////////////////////////////////////
417
418 MiscReg readMiscRegNoEffect(int misc_reg) const
419 {
420 return thread->readMiscRegNoEffect(misc_reg);
421 }
422
423 MiscReg readMiscReg(int misc_reg) override
424 {
425 return thread->readMiscReg(misc_reg);
426 }
427
428 void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
429 {
430 DPRINTF(Checker, "Setting misc reg %d with no effect to check later\n", misc_reg);
431 miscRegIdxs.push(misc_reg);
432 return thread->setMiscRegNoEffect(misc_reg, val);
433 }
434
435 void setMiscReg(int misc_reg, const MiscReg &val) override
436 {
437 DPRINTF(Checker, "Setting misc reg %d with effect to check later\n", misc_reg);
438 miscRegIdxs.push(misc_reg);
439 return thread->setMiscReg(misc_reg, val);
440 }
441
442 MiscReg readMiscRegOperand(const StaticInst *si, int idx) override
443 {
444 const RegId& reg = si->srcRegIdx(idx);
445 assert(reg.isMiscReg());
446 return thread->readMiscReg(reg.index());
447 }
448
449 void setMiscRegOperand(const StaticInst *si, int idx,
450 const MiscReg &val) override
451 {
452 const RegId& reg = si->destRegIdx(idx);
453 assert(reg.isMiscReg());
454 return this->setMiscReg(reg.index(), val);
455 }
456
457#if THE_ISA == MIPS_ISA
458 MiscReg readRegOtherThread(const RegId& misc_reg, ThreadID tid) override
459 {
460 panic("MIPS MT not defined for CheckerCPU.\n");
461 return 0;
462 }
463
464 void setRegOtherThread(const RegId& misc_reg, MiscReg val,
465 ThreadID tid) override
466 {
467 panic("MIPS MT not defined for CheckerCPU.\n");
468 }
469#endif
470
471 /////////////////////////////////////////
472
473 void recordPCChange(const TheISA::PCState &val)
474 {
475 changedPC = true;
476 newPCState = val;
477 }
478
479 void demapPage(Addr vaddr, uint64_t asn) override
480 {
481 this->itb->demapPage(vaddr, asn);
482 this->dtb->demapPage(vaddr, asn);
483 }
484
485 // monitor/mwait funtions
486 void armMonitor(Addr address) override
487 { BaseCPU::armMonitor(0, address); }
488 bool mwait(PacketPtr pkt) override { return BaseCPU::mwait(0, pkt); }
489 void mwaitAtomic(ThreadContext *tc) override
490 { return BaseCPU::mwaitAtomic(0, tc, thread->dtb); }
491 AddressMonitor *getAddrMonitor() override
492 { return BaseCPU::getCpuAddrMonitor(0); }
493
494 void demapInstPage(Addr vaddr, uint64_t asn)
495 {
496 this->itb->demapPage(vaddr, asn);
497 }
498
499 void demapDataPage(Addr vaddr, uint64_t asn)
500 {
501 this->dtb->demapPage(vaddr, asn);
502 }
503
504 Fault readMem(Addr addr, uint8_t *data, unsigned size,
505 Request::Flags flags) override;
506 Fault writeMem(uint8_t *data, unsigned size, Addr addr,
507 Request::Flags flags, uint64_t *res) override;
508
509 unsigned int readStCondFailures() const override {
510 return thread->readStCondFailures();
511 }
512
513 void setStCondFailures(unsigned int sc_failures) override
514 {}
515 /////////////////////////////////////////////////////
516
517 Fault hwrei() override { return thread->hwrei(); }
518 bool simPalCheck(int palFunc) override
519 { return thread->simPalCheck(palFunc); }
520 void wakeup(ThreadID tid) override { }
521 // Assume that the normal CPU's call to syscall was successful.
522 // The checker's state would have already been updated by the syscall.
523 void syscall(int64_t callnum, Fault *fault) override { }
524
525 void handleError()
526 {
527 if (exitOnError)
528 dumpAndExit();
529 }
530
531 bool checkFlags(const RequestPtr &unverified_req, Addr vAddr,
532 Addr pAddr, int flags);
533
534 void dumpAndExit();
535
536 ThreadContext *tcBase() override { return tc; }
537 SimpleThread *threadBase() { return thread; }
538
539 InstResult unverifiedResult;
540 RequestPtr unverifiedReq;
541 uint8_t *unverifiedMemData;
542
543 bool changedPC;
544 bool willChangePC;
545 TheISA::PCState newPCState;
546 bool exitOnError;
547 bool updateOnError;
548 bool warnOnlyOnLoadError;
549
550 InstSeqNum youngestSN;
551};
552
553/**
554 * Templated Checker class. This Checker class is templated on the
555 * DynInstPtr of the instruction type that will be verified. Proper
556 * template instantiations of the Checker must be placed at the bottom
557 * of checker/cpu.cc.
558 */
559template <class Impl>
560class Checker : public CheckerCPU
561{
562 private:
563 typedef typename Impl::DynInstPtr DynInstPtr;
564
565 public:
566 Checker(Params *p)
567 : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL)
568 { }
569
570 void switchOut();
571 void takeOverFrom(BaseCPU *oldCPU);
572
573 void advancePC(const Fault &fault);
574
402 void setPredicate(bool val) override
403 {
404 thread->setPredicate(val);
405 }
406
407 TheISA::PCState pcState() const override { return thread->pcState(); }
408 void pcState(const TheISA::PCState &val) override
409 {
410 DPRINTF(Checker, "Changing PC to %s, old PC %s.\n",
411 val, thread->pcState());
412 thread->pcState(val);
413 }
414 Addr instAddr() { return thread->instAddr(); }
415 Addr nextInstAddr() { return thread->nextInstAddr(); }
416 MicroPC microPC() { return thread->microPC(); }
417 //////////////////////////////////////////
418
419 MiscReg readMiscRegNoEffect(int misc_reg) const
420 {
421 return thread->readMiscRegNoEffect(misc_reg);
422 }
423
424 MiscReg readMiscReg(int misc_reg) override
425 {
426 return thread->readMiscReg(misc_reg);
427 }
428
429 void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
430 {
431 DPRINTF(Checker, "Setting misc reg %d with no effect to check later\n", misc_reg);
432 miscRegIdxs.push(misc_reg);
433 return thread->setMiscRegNoEffect(misc_reg, val);
434 }
435
436 void setMiscReg(int misc_reg, const MiscReg &val) override
437 {
438 DPRINTF(Checker, "Setting misc reg %d with effect to check later\n", misc_reg);
439 miscRegIdxs.push(misc_reg);
440 return thread->setMiscReg(misc_reg, val);
441 }
442
443 MiscReg readMiscRegOperand(const StaticInst *si, int idx) override
444 {
445 const RegId& reg = si->srcRegIdx(idx);
446 assert(reg.isMiscReg());
447 return thread->readMiscReg(reg.index());
448 }
449
450 void setMiscRegOperand(const StaticInst *si, int idx,
451 const MiscReg &val) override
452 {
453 const RegId& reg = si->destRegIdx(idx);
454 assert(reg.isMiscReg());
455 return this->setMiscReg(reg.index(), val);
456 }
457
458#if THE_ISA == MIPS_ISA
459 MiscReg readRegOtherThread(const RegId& misc_reg, ThreadID tid) override
460 {
461 panic("MIPS MT not defined for CheckerCPU.\n");
462 return 0;
463 }
464
465 void setRegOtherThread(const RegId& misc_reg, MiscReg val,
466 ThreadID tid) override
467 {
468 panic("MIPS MT not defined for CheckerCPU.\n");
469 }
470#endif
471
472 /////////////////////////////////////////
473
474 void recordPCChange(const TheISA::PCState &val)
475 {
476 changedPC = true;
477 newPCState = val;
478 }
479
480 void demapPage(Addr vaddr, uint64_t asn) override
481 {
482 this->itb->demapPage(vaddr, asn);
483 this->dtb->demapPage(vaddr, asn);
484 }
485
486 // monitor/mwait funtions
487 void armMonitor(Addr address) override
488 { BaseCPU::armMonitor(0, address); }
489 bool mwait(PacketPtr pkt) override { return BaseCPU::mwait(0, pkt); }
490 void mwaitAtomic(ThreadContext *tc) override
491 { return BaseCPU::mwaitAtomic(0, tc, thread->dtb); }
492 AddressMonitor *getAddrMonitor() override
493 { return BaseCPU::getCpuAddrMonitor(0); }
494
495 void demapInstPage(Addr vaddr, uint64_t asn)
496 {
497 this->itb->demapPage(vaddr, asn);
498 }
499
500 void demapDataPage(Addr vaddr, uint64_t asn)
501 {
502 this->dtb->demapPage(vaddr, asn);
503 }
504
505 Fault readMem(Addr addr, uint8_t *data, unsigned size,
506 Request::Flags flags) override;
507 Fault writeMem(uint8_t *data, unsigned size, Addr addr,
508 Request::Flags flags, uint64_t *res) override;
509
510 unsigned int readStCondFailures() const override {
511 return thread->readStCondFailures();
512 }
513
514 void setStCondFailures(unsigned int sc_failures) override
515 {}
516 /////////////////////////////////////////////////////
517
518 Fault hwrei() override { return thread->hwrei(); }
519 bool simPalCheck(int palFunc) override
520 { return thread->simPalCheck(palFunc); }
521 void wakeup(ThreadID tid) override { }
522 // Assume that the normal CPU's call to syscall was successful.
523 // The checker's state would have already been updated by the syscall.
524 void syscall(int64_t callnum, Fault *fault) override { }
525
526 void handleError()
527 {
528 if (exitOnError)
529 dumpAndExit();
530 }
531
532 bool checkFlags(const RequestPtr &unverified_req, Addr vAddr,
533 Addr pAddr, int flags);
534
535 void dumpAndExit();
536
537 ThreadContext *tcBase() override { return tc; }
538 SimpleThread *threadBase() { return thread; }
539
540 InstResult unverifiedResult;
541 RequestPtr unverifiedReq;
542 uint8_t *unverifiedMemData;
543
544 bool changedPC;
545 bool willChangePC;
546 TheISA::PCState newPCState;
547 bool exitOnError;
548 bool updateOnError;
549 bool warnOnlyOnLoadError;
550
551 InstSeqNum youngestSN;
552};
553
554/**
555 * Templated Checker class. This Checker class is templated on the
556 * DynInstPtr of the instruction type that will be verified. Proper
557 * template instantiations of the Checker must be placed at the bottom
558 * of checker/cpu.cc.
559 */
560template <class Impl>
561class Checker : public CheckerCPU
562{
563 private:
564 typedef typename Impl::DynInstPtr DynInstPtr;
565
566 public:
567 Checker(Params *p)
568 : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL)
569 { }
570
571 void switchOut();
572 void takeOverFrom(BaseCPU *oldCPU);
573
574 void advancePC(const Fault &fault);
575
575 void verify(DynInstPtr &inst);
576 void verify(const DynInstPtr &inst);
576
577
577 void validateInst(DynInstPtr &inst);
578 void validateExecution(DynInstPtr &inst);
578 void validateInst(const DynInstPtr &inst);
579 void validateExecution(const DynInstPtr &inst);
579 void validateState();
580
580 void validateState();
581
581 void copyResult(DynInstPtr &inst, const InstResult& mismatch_val,
582 void copyResult(const DynInstPtr &inst, const InstResult& mismatch_val,
582 int start_idx);
583 void handlePendingInt();
584
585 private:
583 int start_idx);
584 void handlePendingInt();
585
586 private:
586 void handleError(DynInstPtr &inst)
587 void handleError(const DynInstPtr &inst)
587 {
588 if (exitOnError) {
589 dumpAndExit(inst);
590 } else if (updateOnError) {
591 updateThisCycle = true;
592 }
593 }
594
588 {
589 if (exitOnError) {
590 dumpAndExit(inst);
591 } else if (updateOnError) {
592 updateThisCycle = true;
593 }
594 }
595
595 void dumpAndExit(DynInstPtr &inst);
596 void dumpAndExit(const DynInstPtr &inst);
596
597 bool updateThisCycle;
598
599 DynInstPtr unverifiedInst;
600
601 std::list<DynInstPtr> instList;
602 typedef typename std::list<DynInstPtr>::iterator InstListIt;
603 void dumpInsts();
604};
605
606#endif // __CPU_CHECKER_CPU_HH__
597
598 bool updateThisCycle;
599
600 DynInstPtr unverifiedInst;
601
602 std::list<DynInstPtr> instList;
603 typedef typename std::list<DynInstPtr>::iterator InstListIt;
604 void dumpInsts();
605};
606
607#endif // __CPU_CHECKER_CPU_HH__