base.hh revision 4181:6edaeff44647
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
57#else
58
59class Process;
60
61#endif // FULL_SYSTEM
62
63class RemoteGDB;
64class GDBListener;
65
66class ThreadContext;
67class Checkpoint;
68
69namespace Trace {
70    class InstRecord;
71}
72
73
74class BaseSimpleCPU : public BaseCPU
75{
76  protected:
77    typedef TheISA::MiscReg MiscReg;
78    typedef TheISA::FloatReg FloatReg;
79    typedef TheISA::FloatRegBits FloatRegBits;
80
81  protected:
82    Trace::InstRecord *traceData;
83
84  public:
85    void post_interrupt(int int_num, int index);
86
87    void zero_fill_64(Addr addr) {
88      static int warned = 0;
89      if (!warned) {
90        warn ("WH64 is not implemented");
91        warned = 1;
92      }
93    };
94
95  public:
96    struct Params : public BaseCPU::Params
97    {
98#if FULL_SYSTEM
99        TheISA::ITB *itb;
100        TheISA::DTB *dtb;
101#else
102        Process *process;
103#endif
104    };
105    BaseSimpleCPU(Params *params);
106    virtual ~BaseSimpleCPU();
107
108  public:
109    /** SimpleThread object, provides all the architectural state. */
110    SimpleThread *thread;
111
112    /** ThreadContext object, provides an interface for external
113     * objects to modify this thread's state.
114     */
115    ThreadContext *tc;
116
117#if FULL_SYSTEM
118    Addr dbg_vtophys(Addr addr);
119
120    bool interval_stats;
121#endif
122
123    // current instruction
124    TheISA::MachInst inst;
125
126    // current extended machine instruction
127    TheISA::ExtMachInst extMachInst;
128
129    // Static data storage
130    TheISA::LargestRead dataReg;
131
132    StaticInstPtr curStaticInst;
133    StaticInstPtr curMacroStaticInst;
134
135    void checkForInterrupts();
136    Fault setupFetchRequest(Request *req);
137    void preExecute();
138    void postExecute();
139    void advancePC(Fault fault);
140
141    virtual void deallocateContext(int thread_num);
142    virtual void haltContext(int thread_num);
143
144    // statistics
145    virtual void regStats();
146    virtual void resetStats();
147
148    // number of simulated instructions
149    Counter numInst;
150    Counter startNumInst;
151    Stats::Scalar<> numInsts;
152
153    virtual Counter totalInstructions() const
154    {
155        return numInst - startNumInst;
156    }
157
158    // number of simulated memory references
159    Stats::Scalar<> numMemRefs;
160
161    // number of simulated loads
162    Counter numLoad;
163    Counter startNumLoad;
164
165    // number of idle cycles
166    Stats::Average<> notIdleFraction;
167    Stats::Formula idleFraction;
168
169    // number of cycles stalled for I-cache responses
170    Stats::Scalar<> icacheStallCycles;
171    Counter lastIcacheStall;
172
173    // number of cycles stalled for I-cache retries
174    Stats::Scalar<> icacheRetryCycles;
175    Counter lastIcacheRetry;
176
177    // number of cycles stalled for D-cache responses
178    Stats::Scalar<> dcacheStallCycles;
179    Counter lastDcacheStall;
180
181    // number of cycles stalled for D-cache retries
182    Stats::Scalar<> dcacheRetryCycles;
183    Counter lastDcacheRetry;
184
185    virtual void serialize(std::ostream &os);
186    virtual void unserialize(Checkpoint *cp, const std::string &section);
187
188    // These functions are only used in CPU models that split
189    // effective address computation from the actual memory access.
190    void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); }
191    Addr getEA() 	{ panic("BaseSimpleCPU::getEA() not implemented\n");
192        M5_DUMMY_RETURN}
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 readIntRegOperand(const StaticInst *si, int idx)
220    {
221        return thread->readIntReg(si->srcRegIdx(idx));
222    }
223
224    FloatReg readFloatRegOperand(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 readFloatRegOperand(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 readFloatRegOperandBits(const StaticInst *si, int idx,
237                                         int width)
238    {
239        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
240        return thread->readFloatRegBits(reg_idx, width);
241    }
242
243    FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
244    {
245        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
246        return thread->readFloatRegBits(reg_idx);
247    }
248
249    void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
250    {
251        thread->setIntReg(si->destRegIdx(idx), val);
252    }
253
254    void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val,
255                            int width)
256    {
257        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
258        thread->setFloatReg(reg_idx, val, width);
259    }
260
261    void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
262    {
263        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
264        thread->setFloatReg(reg_idx, val);
265    }
266
267    void setFloatRegOperandBits(const StaticInst *si, int idx,
268                                FloatRegBits val, int width)
269    {
270        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
271        thread->setFloatRegBits(reg_idx, val, width);
272    }
273
274    void setFloatRegOperandBits(const StaticInst *si, int idx,
275                                FloatRegBits val)
276    {
277        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
278        thread->setFloatRegBits(reg_idx, val);
279    }
280
281    uint64_t readPC() { return thread->readPC(); }
282    uint64_t readNextPC() { return thread->readNextPC(); }
283    uint64_t readNextNPC() { return thread->readNextNPC(); }
284
285    void setPC(uint64_t val) { thread->setPC(val); }
286    void setNextPC(uint64_t val) { thread->setNextPC(val); }
287    void setNextNPC(uint64_t val) { thread->setNextNPC(val); }
288
289    MiscReg readMiscRegNoEffect(int misc_reg)
290    {
291        return thread->readMiscRegNoEffect(misc_reg);
292    }
293
294    MiscReg readMiscReg(int misc_reg)
295    {
296        return thread->readMiscReg(misc_reg);
297    }
298
299    void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
300    {
301        return thread->setMiscRegNoEffect(misc_reg, val);
302    }
303
304    void setMiscReg(int misc_reg, const MiscReg &val)
305    {
306        return thread->setMiscReg(misc_reg, val);
307    }
308
309    MiscReg readMiscRegOperand(const StaticInst *si, int idx)
310    {
311        int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
312        return thread->readMiscRegNoEffect(reg_idx);
313    }
314
315    MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx)
316    {
317        int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
318        return thread->readMiscReg(reg_idx);
319    }
320
321    void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val)
322    {
323        int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
324        return thread->setMiscRegNoEffect(reg_idx, val);
325    }
326
327    void setMiscRegOperandWithEffect(
328            const StaticInst *si, int idx, const MiscReg &val)
329    {
330        int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
331        return thread->setMiscReg(reg_idx, val);
332    }
333
334    unsigned readStCondFailures() {
335        return thread->readStCondFailures();
336    }
337
338    void setStCondFailures(unsigned sc_failures) {
339        thread->setStCondFailures(sc_failures);
340    }
341
342#if FULL_SYSTEM
343    Fault hwrei() { return thread->hwrei(); }
344    void ev5_trap(Fault fault) { fault->invoke(tc); }
345    bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
346#else
347    void syscall(int64_t callnum) { thread->syscall(callnum); }
348#endif
349
350    bool misspeculating() { return thread->misspeculating(); }
351    ThreadContext *tcBase() { return tc; }
352};
353
354#endif // __CPU_SIMPLE_BASE_HH__
355