base.hh revision 3468
1/*
2 * Copyright (c) 2002-2005 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: Steve Reinhardt
29 *          Dave Greene
30 *          Nathan Binkert
31 */
32
33#ifndef __CPU_SIMPLE_BASE_HH__
34#define __CPU_SIMPLE_BASE_HH__
35
36#include "base/statistics.hh"
37#include "config/full_system.hh"
38#include "cpu/base.hh"
39#include "cpu/simple_thread.hh"
40#include "cpu/pc_event.hh"
41#include "cpu/static_inst.hh"
42#include "mem/packet.hh"
43#include "mem/port.hh"
44#include "mem/request.hh"
45#include "sim/eventq.hh"
46
47// forward declarations
48#if FULL_SYSTEM
49class Processor;
50namespace TheISA
51{
52    class ITB;
53    class DTB;
54}
55class MemObject;
56
57class RemoteGDB;
58class GDBListener;
59
60#else
61
62class Process;
63
64#endif // FULL_SYSTEM
65
66class ThreadContext;
67class Checkpoint;
68
69namespace Trace {
70    class InstRecord;
71}
72
73
74class BaseSimpleCPU : public BaseCPU
75{
76  protected:
77    typedef TheISA::MachInst MachInst;
78    typedef TheISA::MiscReg MiscReg;
79    typedef TheISA::FloatReg FloatReg;
80    typedef TheISA::FloatRegBits FloatRegBits;
81
82    MemObject *mem;
83
84  protected:
85    Trace::InstRecord *traceData;
86
87  public:
88    void post_interrupt(int int_num, int index);
89
90    void zero_fill_64(Addr addr) {
91      static int warned = 0;
92      if (!warned) {
93        warn ("WH64 is not implemented");
94        warned = 1;
95      }
96    };
97
98  public:
99    struct Params : public BaseCPU::Params
100    {
101        MemObject *mem;
102#if FULL_SYSTEM
103        TheISA::ITB *itb;
104        TheISA::DTB *dtb;
105#else
106        Process *process;
107#endif
108    };
109    BaseSimpleCPU(Params *params);
110    virtual ~BaseSimpleCPU();
111
112  public:
113    /** SimpleThread object, provides all the architectural state. */
114    SimpleThread *thread;
115
116    /** ThreadContext object, provides an interface for external
117     * objects to modify this thread's state.
118     */
119    ThreadContext *tc;
120
121#if FULL_SYSTEM
122    Addr dbg_vtophys(Addr addr);
123
124    bool interval_stats;
125#endif
126
127    // current instruction
128    MachInst inst;
129
130    // Static data storage
131    TheISA::IntReg dataReg;
132
133    StaticInstPtr curStaticInst;
134    StaticInstPtr curMacroStaticInst;
135
136    void checkForInterrupts();
137    Fault setupFetchRequest(Request *req);
138    void preExecute();
139    void postExecute();
140    void advancePC(Fault fault);
141
142    virtual void deallocateContext(int thread_num);
143    virtual void haltContext(int thread_num);
144
145    // statistics
146    virtual void regStats();
147    virtual void resetStats();
148
149    // number of simulated instructions
150    Counter numInst;
151    Counter startNumInst;
152    Stats::Scalar<> numInsts;
153
154    virtual Counter totalInstructions() const
155    {
156        return numInst - startNumInst;
157    }
158
159    // number of simulated memory references
160    Stats::Scalar<> numMemRefs;
161
162    // number of simulated loads
163    Counter numLoad;
164    Counter startNumLoad;
165
166    // number of idle cycles
167    Stats::Average<> notIdleFraction;
168    Stats::Formula idleFraction;
169
170    // number of cycles stalled for I-cache responses
171    Stats::Scalar<> icacheStallCycles;
172    Counter lastIcacheStall;
173
174    // number of cycles stalled for I-cache retries
175    Stats::Scalar<> icacheRetryCycles;
176    Counter lastIcacheRetry;
177
178    // number of cycles stalled for D-cache responses
179    Stats::Scalar<> dcacheStallCycles;
180    Counter lastDcacheStall;
181
182    // number of cycles stalled for D-cache retries
183    Stats::Scalar<> dcacheRetryCycles;
184    Counter lastDcacheRetry;
185
186    virtual void serialize(std::ostream &os);
187    virtual void unserialize(Checkpoint *cp, const std::string &section);
188
189    // These functions are only used in CPU models that split
190    // effective address computation from the actual memory access.
191    void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); }
192    Addr getEA() 	{ panic("BaseSimpleCPU::getEA() not implemented\n"); }
193
194    void prefetch(Addr addr, unsigned flags)
195    {
196        // need to do this...
197    }
198
199    void writeHint(Addr addr, int size, unsigned flags)
200    {
201        // need to do this...
202    }
203
204    Fault copySrcTranslate(Addr src);
205
206    Fault copy(Addr dest);
207
208    // The register accessor methods provide the index of the
209    // instruction's operand (e.g., 0 or 1), not the architectural
210    // register index, to simplify the implementation of register
211    // renaming.  We find the architectural register index by indexing
212    // into the instruction's own operand index table.  Note that a
213    // raw pointer to the StaticInst is provided instead of a
214    // ref-counted StaticInstPtr to redice overhead.  This is fine as
215    // long as these methods don't copy the pointer into any long-term
216    // storage (which is pretty hard to imagine they would have reason
217    // to do).
218
219    uint64_t readIntReg(const StaticInst *si, int idx)
220    {
221        return thread->readIntReg(si->srcRegIdx(idx));
222    }
223
224    FloatReg readFloatReg(const StaticInst *si, int idx, int width)
225    {
226        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
227        return thread->readFloatReg(reg_idx, width);
228    }
229
230    FloatReg readFloatReg(const StaticInst *si, int idx)
231    {
232        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
233        return thread->readFloatReg(reg_idx);
234    }
235
236    FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width)
237    {
238        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
239        return thread->readFloatRegBits(reg_idx, width);
240    }
241
242    FloatRegBits readFloatRegBits(const StaticInst *si, int idx)
243    {
244        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
245        return thread->readFloatRegBits(reg_idx);
246    }
247
248    void setIntReg(const StaticInst *si, int idx, uint64_t val)
249    {
250        thread->setIntReg(si->destRegIdx(idx), val);
251    }
252
253    void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width)
254    {
255        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
256        thread->setFloatReg(reg_idx, val, width);
257    }
258
259    void setFloatReg(const StaticInst *si, int idx, FloatReg val)
260    {
261        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
262        thread->setFloatReg(reg_idx, val);
263    }
264
265    void setFloatRegBits(const StaticInst *si, int idx,
266                         FloatRegBits val, int width)
267    {
268        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
269        thread->setFloatRegBits(reg_idx, val, width);
270    }
271
272    void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val)
273    {
274        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
275        thread->setFloatRegBits(reg_idx, val);
276    }
277
278    uint64_t readPC() { return thread->readPC(); }
279    uint64_t readNextPC() { return thread->readNextPC(); }
280    uint64_t readNextNPC() { return thread->readNextNPC(); }
281
282    void setPC(uint64_t val) { thread->setPC(val); }
283    void setNextPC(uint64_t val) { thread->setNextPC(val); }
284    void setNextNPC(uint64_t val) { thread->setNextNPC(val); }
285
286    MiscReg readMiscReg(int misc_reg)
287    {
288        return thread->readMiscReg(misc_reg);
289    }
290
291    MiscReg readMiscRegWithEffect(int misc_reg)
292    {
293        return thread->readMiscRegWithEffect(misc_reg);
294    }
295
296    void setMiscReg(int misc_reg, const MiscReg &val)
297    {
298        return thread->setMiscReg(misc_reg, val);
299    }
300
301    void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
302    {
303        return thread->setMiscRegWithEffect(misc_reg, val);
304    }
305
306#if FULL_SYSTEM
307    Fault hwrei() { return thread->hwrei(); }
308    bool inPalMode() { return thread->inPalMode(); }
309    void ev5_trap(Fault fault) { fault->invoke(tc); }
310    bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
311#else
312    void syscall(int64_t callnum) { thread->syscall(callnum); }
313#endif
314
315    bool misspeculating() { return thread->misspeculating(); }
316    ThreadContext *tcBase() { return tc; }
317};
318
319#endif // __CPU_SIMPLE_BASE_HH__
320