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