thread_context.hh revision 2683:d6b72bb2ed97
1/*
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
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef __CPU_CHECKER_THREAD_CONTEXT_HH__
30#define __CPU_CHECKER_THREAD_CONTEXT_HH__
31
32#include "cpu/checker/cpu.hh"
33#include "cpu/simple_thread.hh"
34#include "cpu/thread_context.hh"
35
36class EndQuiesceEvent;
37namespace Kernel {
38    class Statistics;
39};
40
41/**
42 * Derived ThreadContext class for use with the Checker.  The template
43 * parameter is the ThreadContext class used by the specific CPU being
44 * verified.  This CheckerThreadContext is then used by the main CPU
45 * in place of its usual ThreadContext class.  It handles updating the
46 * checker's state any time state is updated externally through the
47 * ThreadContext.
48 */
49template <class TC>
50class CheckerThreadContext : public ThreadContext
51{
52  public:
53    CheckerThreadContext(TC *actual_tc,
54                         CheckerCPU *checker_cpu)
55        : actualTC(actual_tc), checkerTC(checker_cpu->thread),
56          checkerCPU(checker_cpu)
57    { }
58
59  private:
60    /** The main CPU's ThreadContext, or class that implements the
61     * ThreadContext interface. */
62    TC *actualTC;
63    /** The checker's own SimpleThread. Will be updated any time
64     * anything uses this ThreadContext to externally update a
65     * thread's state. */
66    SimpleThread *checkerTC;
67    /** Pointer to the checker CPU. */
68    CheckerCPU *checkerCPU;
69
70  public:
71
72    BaseCPU *getCpuPtr() { return actualTC->getCpuPtr(); }
73
74    void setCpuId(int id)
75    {
76        actualTC->setCpuId(id);
77        checkerTC->setCpuId(id);
78    }
79
80    int readCpuId() { return actualTC->readCpuId(); }
81
82    TranslatingPort *getMemPort() { return actualTC->getMemPort(); }
83
84#if FULL_SYSTEM
85    System *getSystemPtr() { return actualTC->getSystemPtr(); }
86
87    PhysicalMemory *getPhysMemPtr() { return actualTC->getPhysMemPtr(); }
88
89    AlphaITB *getITBPtr() { return actualTC->getITBPtr(); }
90
91    AlphaDTB *getDTBPtr() { return actualTC->getDTBPtr(); }
92
93    Kernel::Statistics *getKernelStats() { return actualTC->getKernelStats(); }
94#else
95    Process *getProcessPtr() { return actualTC->getProcessPtr(); }
96#endif
97
98    Status status() const { return actualTC->status(); }
99
100    void setStatus(Status new_status)
101    {
102        actualTC->setStatus(new_status);
103        checkerTC->setStatus(new_status);
104    }
105
106    /// Set the status to Active.  Optional delay indicates number of
107    /// cycles to wait before beginning execution.
108    void activate(int delay = 1) { actualTC->activate(delay); }
109
110    /// Set the status to Suspended.
111    void suspend() { actualTC->suspend(); }
112
113    /// Set the status to Unallocated.
114    void deallocate() { actualTC->deallocate(); }
115
116    /// Set the status to Halted.
117    void halt() { actualTC->halt(); }
118
119#if FULL_SYSTEM
120    void dumpFuncProfile() { actualTC->dumpFuncProfile(); }
121#endif
122
123    void takeOverFrom(ThreadContext *oldContext)
124    {
125        actualTC->takeOverFrom(oldContext);
126        checkerTC->takeOverFrom(oldContext);
127    }
128
129    void regStats(const std::string &name) { actualTC->regStats(name); }
130
131    void serialize(std::ostream &os) { actualTC->serialize(os); }
132    void unserialize(Checkpoint *cp, const std::string &section)
133    { actualTC->unserialize(cp, section); }
134
135#if FULL_SYSTEM
136    EndQuiesceEvent *getQuiesceEvent() { return actualTC->getQuiesceEvent(); }
137
138    Tick readLastActivate() { return actualTC->readLastActivate(); }
139    Tick readLastSuspend() { return actualTC->readLastSuspend(); }
140
141    void profileClear() { return actualTC->profileClear(); }
142    void profileSample() { return actualTC->profileSample(); }
143#endif
144
145    int getThreadNum() { return actualTC->getThreadNum(); }
146
147    // @todo: Do I need this?
148    MachInst getInst() { return actualTC->getInst(); }
149
150    // @todo: Do I need this?
151    void copyArchRegs(ThreadContext *tc)
152    {
153        actualTC->copyArchRegs(tc);
154        checkerTC->copyArchRegs(tc);
155    }
156
157    void clearArchRegs()
158    {
159        actualTC->clearArchRegs();
160        checkerTC->clearArchRegs();
161    }
162
163    //
164    // New accessors for new decoder.
165    //
166    uint64_t readIntReg(int reg_idx)
167    { return actualTC->readIntReg(reg_idx); }
168
169    FloatReg readFloatReg(int reg_idx, int width)
170    { return actualTC->readFloatReg(reg_idx, width); }
171
172    FloatReg readFloatReg(int reg_idx)
173    { return actualTC->readFloatReg(reg_idx); }
174
175    FloatRegBits readFloatRegBits(int reg_idx, int width)
176    { return actualTC->readFloatRegBits(reg_idx, width); }
177
178    FloatRegBits readFloatRegBits(int reg_idx)
179    { return actualTC->readFloatRegBits(reg_idx); }
180
181    void setIntReg(int reg_idx, uint64_t val)
182    {
183        actualTC->setIntReg(reg_idx, val);
184        checkerTC->setIntReg(reg_idx, val);
185    }
186
187    void setFloatReg(int reg_idx, FloatReg val, int width)
188    {
189        actualTC->setFloatReg(reg_idx, val, width);
190        checkerTC->setFloatReg(reg_idx, val, width);
191    }
192
193    void setFloatReg(int reg_idx, FloatReg val)
194    {
195        actualTC->setFloatReg(reg_idx, val);
196        checkerTC->setFloatReg(reg_idx, val);
197    }
198
199    void setFloatRegBits(int reg_idx, FloatRegBits val, int width)
200    {
201        actualTC->setFloatRegBits(reg_idx, val, width);
202        checkerTC->setFloatRegBits(reg_idx, val, width);
203    }
204
205    void setFloatRegBits(int reg_idx, FloatRegBits val)
206    {
207        actualTC->setFloatRegBits(reg_idx, val);
208        checkerTC->setFloatRegBits(reg_idx, val);
209    }
210
211    uint64_t readPC() { return actualTC->readPC(); }
212
213    void setPC(uint64_t val)
214    {
215        actualTC->setPC(val);
216        checkerTC->setPC(val);
217        checkerCPU->recordPCChange(val);
218    }
219
220    uint64_t readNextPC() { return actualTC->readNextPC(); }
221
222    void setNextPC(uint64_t val)
223    {
224        actualTC->setNextPC(val);
225        checkerTC->setNextPC(val);
226        checkerCPU->recordNextPCChange(val);
227    }
228
229    uint64_t readNextNPC() { return actualTC->readNextNPC(); }
230
231    void setNextNPC(uint64_t val)
232    {
233        actualTC->setNextNPC(val);
234        checkerTC->setNextNPC(val);
235        checkerCPU->recordNextPCChange(val);
236    }
237
238    MiscReg readMiscReg(int misc_reg)
239    { return actualTC->readMiscReg(misc_reg); }
240
241    MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
242    { return actualTC->readMiscRegWithEffect(misc_reg, fault); }
243
244    Fault setMiscReg(int misc_reg, const MiscReg &val)
245    {
246        checkerTC->setMiscReg(misc_reg, val);
247        return actualTC->setMiscReg(misc_reg, val);
248    }
249
250    Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
251    {
252        checkerTC->setMiscRegWithEffect(misc_reg, val);
253        return actualTC->setMiscRegWithEffect(misc_reg, val);
254    }
255
256    unsigned readStCondFailures()
257    { return actualTC->readStCondFailures(); }
258
259    void setStCondFailures(unsigned sc_failures)
260    {
261        checkerTC->setStCondFailures(sc_failures);
262        actualTC->setStCondFailures(sc_failures);
263    }
264#if FULL_SYSTEM
265    bool inPalMode() { return actualTC->inPalMode(); }
266#endif
267
268    // @todo: Fix this!
269    bool misspeculating() { return actualTC->misspeculating(); }
270
271#if !FULL_SYSTEM
272    IntReg getSyscallArg(int i) { return actualTC->getSyscallArg(i); }
273
274    // used to shift args for indirect syscall
275    void setSyscallArg(int i, IntReg val)
276    {
277        checkerTC->setSyscallArg(i, val);
278        actualTC->setSyscallArg(i, val);
279    }
280
281    void setSyscallReturn(SyscallReturn return_value)
282    {
283        checkerTC->setSyscallReturn(return_value);
284        actualTC->setSyscallReturn(return_value);
285    }
286
287    Counter readFuncExeInst() { return actualTC->readFuncExeInst(); }
288#endif
289    void changeRegFileContext(RegFile::ContextParam param,
290            RegFile::ContextVal val)
291    {
292        actualTC->changeRegFileContext(param, val);
293        checkerTC->changeRegFileContext(param, val);
294    }
295};
296
297#endif // __CPU_CHECKER_EXEC_CONTEXT_HH__
298