thread_context.hh revision 2654
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_EXEC_CONTEXT_HH__
30#define __CPU_EXEC_CONTEXT_HH__
31
32#include "config/full_system.hh"
33#include "mem/request.hh"
34#include "sim/faults.hh"
35#include "sim/host.hh"
36#include "sim/serialize.hh"
37#include "sim/byteswap.hh"
38
39// @todo: Figure out a more architecture independent way to obtain the ITB and
40// DTB pointers.
41class AlphaDTB;
42class AlphaITB;
43class BaseCPU;
44class EndQuiesceEvent;
45class Event;
46class TranslatingPort;
47class FunctionalPort;
48class VirtualPort;
49class Process;
50class System;
51namespace Kernel {
52    class Statistics;
53};
54
55class ExecContext
56{
57  protected:
58    typedef TheISA::RegFile RegFile;
59    typedef TheISA::MachInst MachInst;
60    typedef TheISA::IntReg IntReg;
61    typedef TheISA::FloatReg FloatReg;
62    typedef TheISA::FloatRegBits FloatRegBits;
63    typedef TheISA::MiscRegFile MiscRegFile;
64    typedef TheISA::MiscReg MiscReg;
65  public:
66    enum Status
67    {
68        /// Initialized but not running yet.  All CPUs start in
69        /// this state, but most transition to Active on cycle 1.
70        /// In MP or SMT systems, non-primary contexts will stay
71        /// in this state until a thread is assigned to them.
72        Unallocated,
73
74        /// Running.  Instructions should be executed only when
75        /// the context is in this state.
76        Active,
77
78        /// Temporarily inactive.  Entered while waiting for
79        /// synchronization, etc.
80        Suspended,
81
82        /// Permanently shut down.  Entered when target executes
83        /// m5exit pseudo-instruction.  When all contexts enter
84        /// this state, the simulation will terminate.
85        Halted
86    };
87
88    virtual ~ExecContext() { };
89
90    virtual BaseCPU *getCpuPtr() = 0;
91
92    virtual void setCpuId(int id) = 0;
93
94    virtual int readCpuId() = 0;
95
96#if FULL_SYSTEM
97    virtual System *getSystemPtr() = 0;
98
99    virtual AlphaITB *getITBPtr() = 0;
100
101    virtual AlphaDTB * getDTBPtr() = 0;
102
103    virtual Kernel::Statistics *getKernelStats() = 0;
104
105    virtual FunctionalPort *getPhysPort() = 0;
106
107    virtual VirtualPort *getVirtPort(ExecContext *xc = NULL) = 0;
108
109    virtual void delVirtPort(VirtualPort *vp) = 0;
110#else
111    virtual TranslatingPort *getMemPort() = 0;
112
113    virtual Process *getProcessPtr() = 0;
114#endif
115
116    virtual Status status() const = 0;
117
118    virtual void setStatus(Status new_status) = 0;
119
120    /// Set the status to Active.  Optional delay indicates number of
121    /// cycles to wait before beginning execution.
122    virtual void activate(int delay = 1) = 0;
123
124    /// Set the status to Suspended.
125    virtual void suspend() = 0;
126
127    /// Set the status to Unallocated.
128    virtual void deallocate() = 0;
129
130    /// Set the status to Halted.
131    virtual void halt() = 0;
132
133#if FULL_SYSTEM
134    virtual void dumpFuncProfile() = 0;
135#endif
136
137    virtual void takeOverFrom(ExecContext *old_context) = 0;
138
139    virtual void regStats(const std::string &name) = 0;
140
141    virtual void serialize(std::ostream &os) = 0;
142    virtual void unserialize(Checkpoint *cp, const std::string &section) = 0;
143
144#if FULL_SYSTEM
145    virtual EndQuiesceEvent *getQuiesceEvent() = 0;
146
147    // Not necessarily the best location for these...
148    // Having an extra function just to read these is obnoxious
149    virtual Tick readLastActivate() = 0;
150    virtual Tick readLastSuspend() = 0;
151
152    virtual void profileClear() = 0;
153    virtual void profileSample() = 0;
154#endif
155
156    virtual int getThreadNum() = 0;
157
158    // Also somewhat obnoxious.  Really only used for the TLB fault.
159    // However, may be quite useful in SPARC.
160    virtual TheISA::MachInst getInst() = 0;
161
162    virtual void copyArchRegs(ExecContext *xc) = 0;
163
164    virtual void clearArchRegs() = 0;
165
166    //
167    // New accessors for new decoder.
168    //
169    virtual uint64_t readIntReg(int reg_idx) = 0;
170
171    virtual FloatReg readFloatReg(int reg_idx, int width) = 0;
172
173    virtual FloatReg readFloatReg(int reg_idx) = 0;
174
175    virtual FloatRegBits readFloatRegBits(int reg_idx, int width) = 0;
176
177    virtual FloatRegBits readFloatRegBits(int reg_idx) = 0;
178
179    virtual void setIntReg(int reg_idx, uint64_t val) = 0;
180
181    virtual void setFloatReg(int reg_idx, FloatReg val, int width) = 0;
182
183    virtual void setFloatReg(int reg_idx, FloatReg val) = 0;
184
185    virtual void setFloatRegBits(int reg_idx, FloatRegBits val) = 0;
186
187    virtual void setFloatRegBits(int reg_idx, FloatRegBits val, int width) = 0;
188
189    virtual uint64_t readPC() = 0;
190
191    virtual void setPC(uint64_t val) = 0;
192
193    virtual uint64_t readNextPC() = 0;
194
195    virtual void setNextPC(uint64_t val) = 0;
196
197    virtual uint64_t readNextNPC() = 0;
198
199    virtual void setNextNPC(uint64_t val) = 0;
200
201    virtual MiscReg readMiscReg(int misc_reg) = 0;
202
203    virtual MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) = 0;
204
205    virtual Fault setMiscReg(int misc_reg, const MiscReg &val) = 0;
206
207    virtual Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) = 0;
208
209    // Also not necessarily the best location for these two.  Hopefully will go
210    // away once we decide upon where st cond failures goes.
211    virtual unsigned readStCondFailures() = 0;
212
213    virtual void setStCondFailures(unsigned sc_failures) = 0;
214
215#if FULL_SYSTEM
216    virtual bool inPalMode() = 0;
217#endif
218
219    // Only really makes sense for old CPU model.  Still could be useful though.
220    virtual bool misspeculating() = 0;
221
222#if !FULL_SYSTEM
223    virtual IntReg getSyscallArg(int i) = 0;
224
225    // used to shift args for indirect syscall
226    virtual void setSyscallArg(int i, IntReg val) = 0;
227
228    virtual void setSyscallReturn(SyscallReturn return_value) = 0;
229
230
231    // Same with st cond failures.
232    virtual Counter readFuncExeInst() = 0;
233#endif
234
235    virtual void changeRegFileContext(RegFile::ContextParam param,
236            RegFile::ContextVal val) = 0;
237};
238
239template <class XC>
240class ProxyExecContext : public ExecContext
241{
242  public:
243    ProxyExecContext(XC *actual_xc)
244    { actualXC = actual_xc; }
245
246  private:
247    XC *actualXC;
248
249  public:
250
251    BaseCPU *getCpuPtr() { return actualXC->getCpuPtr(); }
252
253    void setCpuId(int id) { actualXC->setCpuId(id); }
254
255    int readCpuId() { return actualXC->readCpuId(); }
256
257#if FULL_SYSTEM
258    System *getSystemPtr() { return actualXC->getSystemPtr(); }
259
260    AlphaITB *getITBPtr() { return actualXC->getITBPtr(); }
261
262    AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); }
263
264    Kernel::Statistics *getKernelStats() { return actualXC->getKernelStats(); }
265
266    FunctionalPort *getPhysPort() { return actualXC->getPhysPort(); }
267
268    VirtualPort *getVirtPort(ExecContext *xc = NULL) { return actualXC->getVirtPort(xc); }
269
270    void delVirtPort(VirtualPort *vp) { return actualXC->delVirtPort(vp); }
271#else
272    TranslatingPort *getMemPort() { return actualXC->getMemPort(); }
273
274    Process *getProcessPtr() { return actualXC->getProcessPtr(); }
275#endif
276
277    Status status() const { return actualXC->status(); }
278
279    void setStatus(Status new_status) { actualXC->setStatus(new_status); }
280
281    /// Set the status to Active.  Optional delay indicates number of
282    /// cycles to wait before beginning execution.
283    void activate(int delay = 1) { actualXC->activate(delay); }
284
285    /// Set the status to Suspended.
286    void suspend() { actualXC->suspend(); }
287
288    /// Set the status to Unallocated.
289    void deallocate() { actualXC->deallocate(); }
290
291    /// Set the status to Halted.
292    void halt() { actualXC->halt(); }
293
294#if FULL_SYSTEM
295    void dumpFuncProfile() { actualXC->dumpFuncProfile(); }
296#endif
297
298    void takeOverFrom(ExecContext *oldContext)
299    { actualXC->takeOverFrom(oldContext); }
300
301    void regStats(const std::string &name) { actualXC->regStats(name); }
302
303    void serialize(std::ostream &os) { actualXC->serialize(os); }
304    void unserialize(Checkpoint *cp, const std::string &section)
305    { actualXC->unserialize(cp, section); }
306
307#if FULL_SYSTEM
308    EndQuiesceEvent *getQuiesceEvent() { return actualXC->getQuiesceEvent(); }
309
310    Tick readLastActivate() { return actualXC->readLastActivate(); }
311    Tick readLastSuspend() { return actualXC->readLastSuspend(); }
312
313    void profileClear() { return actualXC->profileClear(); }
314    void profileSample() { return actualXC->profileSample(); }
315#endif
316
317    int getThreadNum() { return actualXC->getThreadNum(); }
318
319    // @todo: Do I need this?
320    MachInst getInst() { return actualXC->getInst(); }
321
322    // @todo: Do I need this?
323    void copyArchRegs(ExecContext *xc) { actualXC->copyArchRegs(xc); }
324
325    void clearArchRegs() { actualXC->clearArchRegs(); }
326
327    //
328    // New accessors for new decoder.
329    //
330    uint64_t readIntReg(int reg_idx)
331    { return actualXC->readIntReg(reg_idx); }
332
333    FloatReg readFloatReg(int reg_idx, int width)
334    { return actualXC->readFloatReg(reg_idx, width); }
335
336    FloatReg readFloatReg(int reg_idx)
337    { return actualXC->readFloatReg(reg_idx); }
338
339    FloatRegBits readFloatRegBits(int reg_idx, int width)
340    { return actualXC->readFloatRegBits(reg_idx, width); }
341
342    FloatRegBits readFloatRegBits(int reg_idx)
343    { return actualXC->readFloatRegBits(reg_idx); }
344
345    void setIntReg(int reg_idx, uint64_t val)
346    { actualXC->setIntReg(reg_idx, val); }
347
348    void setFloatReg(int reg_idx, FloatReg val, int width)
349    { actualXC->setFloatReg(reg_idx, val, width); }
350
351    void setFloatReg(int reg_idx, FloatReg val)
352    { actualXC->setFloatReg(reg_idx, val); }
353
354    void setFloatRegBits(int reg_idx, FloatRegBits val, int width)
355    { actualXC->setFloatRegBits(reg_idx, val, width); }
356
357    void setFloatRegBits(int reg_idx, FloatRegBits val)
358    { actualXC->setFloatRegBits(reg_idx, val); }
359
360    uint64_t readPC() { return actualXC->readPC(); }
361
362    void setPC(uint64_t val) { actualXC->setPC(val); }
363
364    uint64_t readNextPC() { return actualXC->readNextPC(); }
365
366    void setNextPC(uint64_t val) { actualXC->setNextPC(val); }
367
368    uint64_t readNextNPC() { return actualXC->readNextNPC(); }
369
370    void setNextNPC(uint64_t val) { actualXC->setNextNPC(val); }
371
372    MiscReg readMiscReg(int misc_reg)
373    { return actualXC->readMiscReg(misc_reg); }
374
375    MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
376    { return actualXC->readMiscRegWithEffect(misc_reg, fault); }
377
378    Fault setMiscReg(int misc_reg, const MiscReg &val)
379    { return actualXC->setMiscReg(misc_reg, val); }
380
381    Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
382    { return actualXC->setMiscRegWithEffect(misc_reg, val); }
383
384    unsigned readStCondFailures()
385    { return actualXC->readStCondFailures(); }
386
387    void setStCondFailures(unsigned sc_failures)
388    { actualXC->setStCondFailures(sc_failures); }
389#if FULL_SYSTEM
390    bool inPalMode() { return actualXC->inPalMode(); }
391#endif
392
393    // @todo: Fix this!
394    bool misspeculating() { return actualXC->misspeculating(); }
395
396#if !FULL_SYSTEM
397    IntReg getSyscallArg(int i) { return actualXC->getSyscallArg(i); }
398
399    // used to shift args for indirect syscall
400    void setSyscallArg(int i, IntReg val)
401    { actualXC->setSyscallArg(i, val); }
402
403    void setSyscallReturn(SyscallReturn return_value)
404    { actualXC->setSyscallReturn(return_value); }
405
406
407    Counter readFuncExeInst() { return actualXC->readFuncExeInst(); }
408#endif
409
410    void changeRegFileContext(RegFile::ContextParam param,
411            RegFile::ContextVal val)
412    {
413        actualXC->changeRegFileContext(param, val);
414    }
415};
416
417#endif
418