thread_context.hh revision 13693:85fa3a41014b
1/*
2 * Copyright (c) 2011-2012, 2016-2018 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_THREAD_CONTEXT_HH__
45#define __CPU_CHECKER_THREAD_CONTEXT_HH__
46
47#include "arch/types.hh"
48#include "config/the_isa.hh"
49#include "cpu/checker/cpu.hh"
50#include "cpu/simple_thread.hh"
51#include "cpu/thread_context.hh"
52#include "debug/Checker.hh"
53
54class EndQuiesceEvent;
55namespace TheISA {
56    namespace Kernel {
57        class Statistics;
58    };
59    class Decoder;
60};
61
62/**
63 * Derived ThreadContext class for use with the Checker.  The template
64 * parameter is the ThreadContext class used by the specific CPU being
65 * verified.  This CheckerThreadContext is then used by the main CPU
66 * in place of its usual ThreadContext class.  It handles updating the
67 * checker's state any time state is updated externally through the
68 * ThreadContext.
69 */
70template <class TC>
71class CheckerThreadContext : public ThreadContext
72{
73  public:
74    CheckerThreadContext(TC *actual_tc,
75                         CheckerCPU *checker_cpu)
76        : actualTC(actual_tc), checkerTC(checker_cpu->thread),
77          checkerCPU(checker_cpu)
78    { }
79
80  private:
81    /** The main CPU's ThreadContext, or class that implements the
82     * ThreadContext interface. */
83    TC *actualTC;
84    /** The checker's own SimpleThread. Will be updated any time
85     * anything uses this ThreadContext to externally update a
86     * thread's state. */
87    SimpleThread *checkerTC;
88    /** Pointer to the checker CPU. */
89    CheckerCPU *checkerCPU;
90
91  public:
92
93    BaseCPU *getCpuPtr() override { return actualTC->getCpuPtr(); }
94
95    uint32_t socketId() const override { return actualTC->socketId(); }
96
97    int cpuId() const override { return actualTC->cpuId(); }
98
99    ContextID contextId() const override { return actualTC->contextId(); }
100
101    void setContextId(ContextID id)override
102    {
103       actualTC->setContextId(id);
104       checkerTC->setContextId(id);
105    }
106
107    /** Returns this thread's ID number. */
108    int threadId() const override { return actualTC->threadId(); }
109    void setThreadId(int id) override
110    {
111        checkerTC->setThreadId(id);
112        actualTC->setThreadId(id);
113    }
114
115    BaseTLB *getITBPtr() override { return actualTC->getITBPtr(); }
116
117    BaseTLB *getDTBPtr() override { return actualTC->getDTBPtr(); }
118
119    CheckerCPU *getCheckerCpuPtr()override
120    {
121        return checkerCPU;
122    }
123
124    TheISA::ISA *getIsaPtr() override { return actualTC->getIsaPtr(); }
125
126    TheISA::Decoder *getDecoderPtr() override {
127        return actualTC->getDecoderPtr();
128    }
129
130    System *getSystemPtr() override { return actualTC->getSystemPtr(); }
131
132    TheISA::Kernel::Statistics *getKernelStats()override
133    { return actualTC->getKernelStats(); }
134
135    Process *getProcessPtr() override { return actualTC->getProcessPtr(); }
136
137    void setProcessPtr(Process *p) override { actualTC->setProcessPtr(p); }
138
139    PortProxy &getPhysProxy() override { return actualTC->getPhysProxy(); }
140
141    FSTranslatingPortProxy &getVirtProxy() override
142    { return actualTC->getVirtProxy(); }
143
144    void initMemProxies(ThreadContext *tc) override
145    { actualTC->initMemProxies(tc); }
146
147    void connectMemPorts(ThreadContext *tc)
148    {
149        actualTC->connectMemPorts(tc);
150    }
151
152    SETranslatingPortProxy &getMemProxy() override {
153        return actualTC->getMemProxy();
154    }
155
156    /** Executes a syscall in SE mode. */
157    void syscall(int64_t callnum, Fault *fault)override
158    { return actualTC->syscall(callnum, fault); }
159
160    Status status() const override { return actualTC->status(); }
161
162    void setStatus(Status new_status) override
163    {
164        actualTC->setStatus(new_status);
165        checkerTC->setStatus(new_status);
166    }
167
168    /// Set the status to Active.
169    void activate() override { actualTC->activate(); }
170
171    /// Set the status to Suspended.
172    void suspend() override{ actualTC->suspend(); }
173
174    /// Set the status to Halted.
175    void halt() override{ actualTC->halt(); }
176
177    void dumpFuncProfile()  override{ actualTC->dumpFuncProfile(); }
178
179    void takeOverFrom(ThreadContext *oldContext) override
180    {
181        actualTC->takeOverFrom(oldContext);
182        checkerTC->copyState(oldContext);
183    }
184
185    void regStats(const std::string &name) override
186    {
187        actualTC->regStats(name);
188        checkerTC->regStats(name);
189    }
190
191    EndQuiesceEvent *getQuiesceEvent() override {
192        return actualTC->getQuiesceEvent();
193    }
194
195    Tick readLastActivate()  override{ return actualTC->readLastActivate(); }
196    Tick readLastSuspend()  override{ return actualTC->readLastSuspend(); }
197
198    void profileClear()  override{ return actualTC->profileClear(); }
199    void profileSample()  override{ return actualTC->profileSample(); }
200
201    // @todo: Do I need this?
202    void copyArchRegs(ThreadContext *tc) override
203    {
204        actualTC->copyArchRegs(tc);
205        checkerTC->copyArchRegs(tc);
206    }
207
208    void clearArchRegs() override
209    {
210        actualTC->clearArchRegs();
211        checkerTC->clearArchRegs();
212    }
213
214    //
215    // New accessors for new decoder.
216    //
217    RegVal readIntReg(int reg_idx) override {
218        return actualTC->readIntReg(reg_idx);
219    }
220
221    RegVal
222    readFloatReg(int reg_idx) override
223    {
224        return actualTC->readFloatReg(reg_idx);
225    }
226
227    const VecRegContainer& readVecReg (const RegId& reg) const override
228    { return actualTC->readVecReg(reg); }
229
230    /**
231     * Read vector register for modification, hierarchical indexing.
232     */
233    VecRegContainer& getWritableVecReg (const RegId& reg) override
234    { return actualTC->getWritableVecReg(reg); }
235
236    /** Vector Register Lane Interfaces. */
237    /** @{ */
238    /** Reads source vector 8bit operand. */
239    ConstVecLane8
240    readVec8BitLaneReg(const RegId& reg) const override
241    { return actualTC->readVec8BitLaneReg(reg); }
242
243    /** Reads source vector 16bit operand. */
244    ConstVecLane16
245    readVec16BitLaneReg(const RegId& reg) const override
246    { return actualTC->readVec16BitLaneReg(reg); }
247
248    /** Reads source vector 32bit operand. */
249    ConstVecLane32
250    readVec32BitLaneReg(const RegId& reg) const override
251    { return actualTC->readVec32BitLaneReg(reg); }
252
253    /** Reads source vector 64bit operand. */
254    ConstVecLane64
255    readVec64BitLaneReg(const RegId& reg) const override
256    { return actualTC->readVec64BitLaneReg(reg); }
257
258    /** Write a lane of the destination vector register. */
259    virtual void setVecLane(const RegId& reg,
260            const LaneData<LaneSize::Byte>& val) override
261    { return actualTC->setVecLane(reg, val); }
262    virtual void setVecLane(const RegId& reg,
263            const LaneData<LaneSize::TwoByte>& val) override
264    { return actualTC->setVecLane(reg, val); }
265    virtual void setVecLane(const RegId& reg,
266            const LaneData<LaneSize::FourByte>& val) override
267    { return actualTC->setVecLane(reg, val); }
268    virtual void setVecLane(const RegId& reg,
269            const LaneData<LaneSize::EightByte>& val) override
270    { return actualTC->setVecLane(reg, val); }
271    /** @} */
272
273    const VecElem& readVecElem(const RegId& reg) const override
274    { return actualTC->readVecElem(reg); }
275
276    const VecPredRegContainer& readVecPredReg(const RegId& reg) const override
277    { return actualTC->readVecPredReg(reg); }
278
279    VecPredRegContainer& getWritableVecPredReg(const RegId& reg) override
280    { return actualTC->getWritableVecPredReg(reg); }
281
282    RegVal readCCReg(int reg_idx) override
283    { return actualTC->readCCReg(reg_idx); }
284
285    void
286    setIntReg(int reg_idx, RegVal val) override
287    {
288        actualTC->setIntReg(reg_idx, val);
289        checkerTC->setIntReg(reg_idx, val);
290    }
291
292    void
293    setFloatReg(int reg_idx, RegVal val) override
294    {
295        actualTC->setFloatReg(reg_idx, val);
296        checkerTC->setFloatReg(reg_idx, val);
297    }
298
299    void
300    setVecReg(const RegId& reg, const VecRegContainer& val) override
301    {
302        actualTC->setVecReg(reg, val);
303        checkerTC->setVecReg(reg, val);
304    }
305
306    void
307    setVecElem(const RegId& reg, const VecElem& val) override
308    {
309        actualTC->setVecElem(reg, val);
310        checkerTC->setVecElem(reg, val);
311    }
312
313    void
314    setVecPredReg(const RegId& reg, const VecPredRegContainer& val) override
315    {
316        actualTC->setVecPredReg(reg, val);
317        checkerTC->setVecPredReg(reg, val);
318    }
319
320    void
321    setCCReg(int reg_idx, RegVal val) override
322    {
323        actualTC->setCCReg(reg_idx, val);
324        checkerTC->setCCReg(reg_idx, val);
325    }
326
327    /** Reads this thread's PC state. */
328    TheISA::PCState pcState() override
329    { return actualTC->pcState(); }
330
331    /** Sets this thread's PC state. */
332    void
333    pcState(const TheISA::PCState &val) override
334    {
335        DPRINTF(Checker, "Changing PC to %s, old PC %s\n",
336                         val, checkerTC->pcState());
337        checkerTC->pcState(val);
338        checkerCPU->recordPCChange(val);
339        return actualTC->pcState(val);
340    }
341
342    void
343    setNPC(Addr val)
344    {
345        checkerTC->setNPC(val);
346        actualTC->setNPC(val);
347    }
348
349    void
350    pcStateNoRecord(const TheISA::PCState &val) override
351    {
352        return actualTC->pcState(val);
353    }
354
355    /** Reads this thread's PC. */
356    Addr instAddr() override
357    { return actualTC->instAddr(); }
358
359    /** Reads this thread's next PC. */
360    Addr nextInstAddr() override
361    { return actualTC->nextInstAddr(); }
362
363    /** Reads this thread's next PC. */
364    MicroPC microPC() override
365    { return actualTC->microPC(); }
366
367    RegVal readMiscRegNoEffect(int misc_reg) const override
368    { return actualTC->readMiscRegNoEffect(misc_reg); }
369
370    RegVal readMiscReg(int misc_reg) override
371    { return actualTC->readMiscReg(misc_reg); }
372
373    void
374    setMiscRegNoEffect(int misc_reg, RegVal val) override
375    {
376        DPRINTF(Checker, "Setting misc reg with no effect: %d to both Checker"
377                         " and O3..\n", misc_reg);
378        checkerTC->setMiscRegNoEffect(misc_reg, val);
379        actualTC->setMiscRegNoEffect(misc_reg, val);
380    }
381
382    void
383    setMiscReg(int misc_reg, RegVal val) override
384    {
385        DPRINTF(Checker, "Setting misc reg with effect: %d to both Checker"
386                         " and O3..\n", misc_reg);
387        checkerTC->setMiscReg(misc_reg, val);
388        actualTC->setMiscReg(misc_reg, val);
389    }
390
391    RegId
392    flattenRegId(const RegId& regId) const override
393    {
394        return actualTC->flattenRegId(regId);
395    }
396
397    unsigned readStCondFailures() override
398    { return actualTC->readStCondFailures(); }
399
400    void
401    setStCondFailures(unsigned sc_failures) override
402    {
403        actualTC->setStCondFailures(sc_failures);
404    }
405
406    Counter readFuncExeInst() override { return actualTC->readFuncExeInst(); }
407
408    RegVal readIntRegFlat(int idx) override {
409        return actualTC->readIntRegFlat(idx);
410    }
411
412    void
413    setIntRegFlat(int idx, RegVal val) override
414    {
415        actualTC->setIntRegFlat(idx, val);
416    }
417
418    RegVal
419    readFloatRegFlat(int idx) override
420    {
421        return actualTC->readFloatRegFlat(idx);
422    }
423
424    void
425    setFloatRegFlat(int idx, RegVal val) override
426    {
427        actualTC->setFloatRegFlat(idx, val);
428    }
429
430    const VecRegContainer &
431    readVecRegFlat(int idx) const override
432    {
433        return actualTC->readVecRegFlat(idx);
434    }
435
436    /**
437     * Read vector register for modification, flat indexing.
438     */
439    VecRegContainer &
440    getWritableVecRegFlat(int idx) override
441    {
442        return actualTC->getWritableVecRegFlat(idx);
443    }
444
445    void setVecRegFlat(int idx, const VecRegContainer& val) override
446    { actualTC->setVecRegFlat(idx, val); }
447
448    const VecElem& readVecElemFlat(const RegIndex& idx,
449                                   const ElemIndex& elem_idx) const override
450    { return actualTC->readVecElemFlat(idx, elem_idx); }
451
452    void setVecElemFlat(const RegIndex& idx,
453                        const ElemIndex& elem_idx, const VecElem& val) override
454    { actualTC->setVecElemFlat(idx, elem_idx, val); }
455
456    const VecPredRegContainer& readVecPredRegFlat(int idx) const override
457    { return actualTC->readVecPredRegFlat(idx); }
458
459    VecPredRegContainer& getWritableVecPredRegFlat(int idx) override
460    { return actualTC->getWritableVecPredRegFlat(idx); }
461
462    void setVecPredRegFlat(int idx, const VecPredRegContainer& val) override
463    { actualTC->setVecPredRegFlat(idx, val); }
464
465    RegVal readCCRegFlat(int idx) override
466    { return actualTC->readCCRegFlat(idx); }
467
468    void setCCRegFlat(int idx, RegVal val) override
469    { actualTC->setCCRegFlat(idx, val); }
470};
471
472#endif // __CPU_CHECKER_EXEC_CONTEXT_HH__
473