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