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