simple_thread.hh revision 2330
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/mem_req.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 EndQuiesceEvent;
46class Event;
47class FunctionalMemory;
48class PhysicalMemory;
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::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    virtual FunctionalMemory *getMemPtr() = 0;
95
96#if FULL_SYSTEM
97    virtual System *getSystemPtr() = 0;
98
99    virtual PhysicalMemory *getPhysMemPtr() = 0;
100
101    virtual AlphaITB *getITBPtr() = 0;
102
103    virtual AlphaDTB * getDTBPtr() = 0;
104
105    virtual Kernel::Statistics *getKernelStats() = 0;
106#else
107    virtual Process *getProcessPtr() = 0;
108#endif
109
110    virtual Status status() const = 0;
111
112    virtual void setStatus(Status new_status) = 0;
113
114    /// Set the status to Active.  Optional delay indicates number of
115    /// cycles to wait before beginning execution.
116    virtual void activate(int delay = 1) = 0;
117
118    /// Set the status to Suspended.
119    virtual void suspend() = 0;
120
121    /// Set the status to Unallocated.
122    virtual void deallocate() = 0;
123
124    /// Set the status to Halted.
125    virtual void halt() = 0;
126
127#if FULL_SYSTEM
128    virtual void dumpFuncProfile() = 0;
129#endif
130
131    virtual void takeOverFrom(ExecContext *old_context) = 0;
132
133    virtual void regStats(const std::string &name) = 0;
134
135    virtual void serialize(std::ostream &os) = 0;
136    virtual void unserialize(Checkpoint *cp, const std::string &section) = 0;
137
138#if FULL_SYSTEM
139    virtual EndQuiesceEvent *getQuiesceEvent() = 0;
140
141    // Not necessarily the best location for these...
142    // Having an extra function just to read these is obnoxious
143    virtual Tick readLastActivate() = 0;
144    virtual Tick readLastSuspend() = 0;
145
146    virtual void profileClear() = 0;
147    virtual void profileSample() = 0;
148#endif
149
150    virtual int getThreadNum() = 0;
151
152    // Also somewhat obnoxious.  Really only used for the TLB fault.
153    // However, may be quite useful in SPARC.
154    virtual TheISA::MachInst getInst() = 0;
155
156    virtual void copyArchRegs(ExecContext *xc) = 0;
157
158    virtual void clearArchRegs() = 0;
159
160    //
161    // New accessors for new decoder.
162    //
163    virtual uint64_t readIntReg(int reg_idx) = 0;
164
165    virtual float readFloatRegSingle(int reg_idx) = 0;
166
167    virtual double readFloatRegDouble(int reg_idx) = 0;
168
169    virtual uint64_t readFloatRegInt(int reg_idx) = 0;
170
171    virtual void setIntReg(int reg_idx, uint64_t val) = 0;
172
173    virtual void setFloatRegSingle(int reg_idx, float val) = 0;
174
175    virtual void setFloatRegDouble(int reg_idx, double val) = 0;
176
177    virtual void setFloatRegInt(int reg_idx, uint64_t val) = 0;
178
179    virtual uint64_t readPC() = 0;
180
181    virtual void setPC(uint64_t val) = 0;
182
183    virtual uint64_t readNextPC() = 0;
184
185    virtual void setNextPC(uint64_t val) = 0;
186
187    virtual MiscReg readMiscReg(int misc_reg) = 0;
188
189    virtual MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) = 0;
190
191    virtual Fault setMiscReg(int misc_reg, const MiscReg &val) = 0;
192
193    virtual Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) = 0;
194
195    // Also not necessarily the best location for these two.  Hopefully will go
196    // away once we decide upon where st cond failures goes.
197    virtual unsigned readStCondFailures() = 0;
198
199    virtual void setStCondFailures(unsigned sc_failures) = 0;
200
201#if FULL_SYSTEM
202    virtual bool inPalMode() = 0;
203#endif
204
205    // Only really makes sense for old CPU model.  Still could be useful though.
206    virtual bool misspeculating() = 0;
207
208#if !FULL_SYSTEM
209    virtual IntReg getSyscallArg(int i) = 0;
210
211    // used to shift args for indirect syscall
212    virtual void setSyscallArg(int i, IntReg val) = 0;
213
214    virtual void setSyscallReturn(SyscallReturn return_value) = 0;
215
216//    virtual void syscall() = 0;
217
218    // Same with st cond failures.
219    virtual Counter readFuncExeInst() = 0;
220#endif
221};
222
223template <class XC>
224class ProxyExecContext : public ExecContext
225{
226  public:
227    ProxyExecContext(XC *actual_xc)
228    { actualXC = actual_xc; }
229
230  private:
231    XC *actualXC;
232
233  public:
234
235    BaseCPU *getCpuPtr() { return actualXC->getCpuPtr(); }
236
237    void setCpuId(int id) { actualXC->setCpuId(id); }
238
239    int readCpuId() { return actualXC->readCpuId(); }
240
241    FunctionalMemory *getMemPtr() { return actualXC->getMemPtr(); }
242
243#if FULL_SYSTEM
244    System *getSystemPtr() { return actualXC->getSystemPtr(); }
245
246    PhysicalMemory *getPhysMemPtr() { return actualXC->getPhysMemPtr(); }
247
248    AlphaITB *getITBPtr() { return actualXC->getITBPtr(); }
249
250    AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); }
251
252    Kernel::Statistics *getKernelStats() { return actualXC->getKernelStats(); }
253#else
254    Process *getProcessPtr() { return actualXC->getProcessPtr(); }
255#endif
256
257    Status status() const { return actualXC->status(); }
258
259    void setStatus(Status new_status) { actualXC->setStatus(new_status); }
260
261    /// Set the status to Active.  Optional delay indicates number of
262    /// cycles to wait before beginning execution.
263    void activate(int delay = 1) { actualXC->activate(delay); }
264
265    /// Set the status to Suspended.
266    void suspend() { actualXC->suspend(); }
267
268    /// Set the status to Unallocated.
269    void deallocate() { actualXC->deallocate(); }
270
271    /// Set the status to Halted.
272    void halt() { actualXC->halt(); }
273
274#if FULL_SYSTEM
275    void dumpFuncProfile() { actualXC->dumpFuncProfile(); }
276#endif
277
278    void takeOverFrom(ExecContext *oldContext)
279    { actualXC->takeOverFrom(oldContext); }
280
281    void regStats(const std::string &name) { actualXC->regStats(name); }
282
283    void serialize(std::ostream &os) { actualXC->serialize(os); }
284    void unserialize(Checkpoint *cp, const std::string &section)
285    { actualXC->unserialize(cp, section); }
286
287#if FULL_SYSTEM
288    EndQuiesceEvent *getQuiesceEvent() { return actualXC->getQuiesceEvent(); }
289
290    Tick readLastActivate() { return actualXC->readLastActivate(); }
291    Tick readLastSuspend() { return actualXC->readLastSuspend(); }
292
293    void profileClear() { return actualXC->profileClear(); }
294    void profileSample() { return actualXC->profileSample(); }
295#endif
296
297    int getThreadNum() { return actualXC->getThreadNum(); }
298
299    // @todo: Do I need this?
300    MachInst getInst() { return actualXC->getInst(); }
301
302    // @todo: Do I need this?
303    void copyArchRegs(ExecContext *xc) { actualXC->copyArchRegs(xc); }
304
305    void clearArchRegs() { actualXC->clearArchRegs(); }
306
307    //
308    // New accessors for new decoder.
309    //
310    uint64_t readIntReg(int reg_idx)
311    { return actualXC->readIntReg(reg_idx); }
312
313    float readFloatRegSingle(int reg_idx)
314    { return actualXC->readFloatRegSingle(reg_idx); }
315
316    double readFloatRegDouble(int reg_idx)
317    { return actualXC->readFloatRegDouble(reg_idx); }
318
319    uint64_t readFloatRegInt(int reg_idx)
320    { return actualXC->readFloatRegInt(reg_idx); }
321
322    void setIntReg(int reg_idx, uint64_t val)
323    { actualXC->setIntReg(reg_idx, val); }
324
325    void setFloatRegSingle(int reg_idx, float val)
326    { actualXC->setFloatRegSingle(reg_idx, val); }
327
328    void setFloatRegDouble(int reg_idx, double val)
329    { actualXC->setFloatRegDouble(reg_idx, val); }
330
331    void setFloatRegInt(int reg_idx, uint64_t val)
332    { actualXC->setFloatRegInt(reg_idx, val); }
333
334    uint64_t readPC() { return actualXC->readPC(); }
335
336    void setPC(uint64_t val) { actualXC->setPC(val); }
337
338    uint64_t readNextPC() { return actualXC->readNextPC(); }
339
340    void setNextPC(uint64_t val) { actualXC->setNextPC(val); }
341
342    MiscReg readMiscReg(int misc_reg)
343    { return actualXC->readMiscReg(misc_reg); }
344
345    MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
346    { return actualXC->readMiscRegWithEffect(misc_reg, fault); }
347
348    Fault setMiscReg(int misc_reg, const MiscReg &val)
349    { return actualXC->setMiscReg(misc_reg, val); }
350
351    Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
352    { return actualXC->setMiscRegWithEffect(misc_reg, val); }
353
354    unsigned readStCondFailures()
355    { return actualXC->readStCondFailures(); }
356
357    void setStCondFailures(unsigned sc_failures)
358    { actualXC->setStCondFailures(sc_failures); }
359#if FULL_SYSTEM
360    bool inPalMode() { return actualXC->inPalMode(); }
361#endif
362
363    // @todo: Fix this!
364    bool misspeculating() { return actualXC->misspeculating(); }
365
366#if !FULL_SYSTEM
367    IntReg getSyscallArg(int i) { return actualXC->getSyscallArg(i); }
368
369    // used to shift args for indirect syscall
370    void setSyscallArg(int i, IntReg val)
371    { actualXC->setSyscallArg(i, val); }
372
373    void setSyscallReturn(SyscallReturn return_value)
374    { actualXC->setSyscallReturn(return_value); }
375
376//    void syscall() { actualXC->syscall(); }
377
378    Counter readFuncExeInst() { return actualXC->readFuncExeInst(); }
379#endif
380};
381
382#endif
383