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