base.hh revision 7445:dfd04ffc1773
112837Sgabeblack@google.com/*
212837Sgabeblack@google.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
312837Sgabeblack@google.com * All rights reserved.
412837Sgabeblack@google.com *
512837Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
612837Sgabeblack@google.com * modification, are permitted provided that the following conditions are
712837Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
812837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
912837Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1012837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1112837Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1212837Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1312837Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1412837Sgabeblack@google.com * this software without specific prior written permission.
1512837Sgabeblack@google.com *
1612837Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712837Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812837Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912837Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012837Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112837Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212837Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312837Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412837Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512837Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612837Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712837Sgabeblack@google.com *
2812837Sgabeblack@google.com * Authors: Steve Reinhardt
2912837Sgabeblack@google.com *          Dave Greene
3012837Sgabeblack@google.com *          Nathan Binkert
3112954Sgabeblack@google.com */
3213140Sgabeblack@google.com
3313324Sgabeblack@google.com#ifndef __CPU_SIMPLE_BASE_HH__
3413238Sgabeblack@google.com#define __CPU_SIMPLE_BASE_HH__
3512837Sgabeblack@google.com
3612837Sgabeblack@google.com#include "arch/predecoder.hh"
3713140Sgabeblack@google.com#include "base/statistics.hh"
3813140Sgabeblack@google.com#include "config/full_system.hh"
3913140Sgabeblack@google.com#include "config/the_isa.hh"
4013140Sgabeblack@google.com#include "cpu/base.hh"
4113140Sgabeblack@google.com#include "cpu/simple_thread.hh"
4213140Sgabeblack@google.com#include "cpu/pc_event.hh"
4313140Sgabeblack@google.com#include "cpu/static_inst.hh"
4412837Sgabeblack@google.com#include "mem/packet.hh"
4512837Sgabeblack@google.com#include "mem/port.hh"
4612837Sgabeblack@google.com#include "mem/request.hh"
4713238Sgabeblack@google.com#include "sim/eventq.hh"
4813238Sgabeblack@google.com#include "sim/system.hh"
4913238Sgabeblack@google.com
5013324Sgabeblack@google.com// forward declarations
5113283Sgabeblack@google.com#if FULL_SYSTEM
5213283Sgabeblack@google.comclass Processor;
5313324Sgabeblack@google.comnamespace TheISA
5413238Sgabeblack@google.com{
5513283Sgabeblack@google.com    class ITB;
5613238Sgabeblack@google.com    class DTB;
5712837Sgabeblack@google.com}
5812954Sgabeblack@google.comclass MemObject;
5913238Sgabeblack@google.com
6013238Sgabeblack@google.com#else
6113238Sgabeblack@google.com
6213324Sgabeblack@google.comclass Process;
6313283Sgabeblack@google.com
6413283Sgabeblack@google.com#endif // FULL_SYSTEM
6513324Sgabeblack@google.com
6613238Sgabeblack@google.comnamespace TheISA
6713283Sgabeblack@google.com{
6813238Sgabeblack@google.com    class Predecoder;
6912837Sgabeblack@google.com}
7012954Sgabeblack@google.comclass ThreadContext;
7112837Sgabeblack@google.comclass Checkpoint;
7212837Sgabeblack@google.com
7312837Sgabeblack@google.comnamespace Trace {
7412837Sgabeblack@google.com    class InstRecord;
7512954Sgabeblack@google.com}
7612837Sgabeblack@google.com
7712837Sgabeblack@google.comclass BaseSimpleCPUParams;
7812837Sgabeblack@google.com
7912837Sgabeblack@google.com
8012837Sgabeblack@google.comclass BaseSimpleCPU : public BaseCPU
8112954Sgabeblack@google.com{
8212837Sgabeblack@google.com  protected:
8312837Sgabeblack@google.com    typedef TheISA::MiscReg MiscReg;
8412837Sgabeblack@google.com    typedef TheISA::FloatReg FloatReg;
8512837Sgabeblack@google.com    typedef TheISA::FloatRegBits FloatRegBits;
8612837Sgabeblack@google.com
8712954Sgabeblack@google.com  protected:
8812837Sgabeblack@google.com    Trace::InstRecord *traceData;
8912837Sgabeblack@google.com
9012837Sgabeblack@google.com    inline void checkPcEventQueue() {
9112954Sgabeblack@google.com        Addr oldpc;
9212837Sgabeblack@google.com        do {
9312954Sgabeblack@google.com            oldpc = thread->readPC();
9412837Sgabeblack@google.com            system->pcEventQueue.service(tc);
9512837Sgabeblack@google.com        } while (oldpc != thread->readPC());
9612837Sgabeblack@google.com    }
9712954Sgabeblack@google.com
9812837Sgabeblack@google.com  public:
9912954Sgabeblack@google.com    void wakeup();
10012837Sgabeblack@google.com
10112837Sgabeblack@google.com    void zero_fill_64(Addr addr) {
10212837Sgabeblack@google.com      static int warned = 0;
10312954Sgabeblack@google.com      if (!warned) {
10412837Sgabeblack@google.com        warn ("WH64 is not implemented");
10512954Sgabeblack@google.com        warned = 1;
10612837Sgabeblack@google.com      }
10712837Sgabeblack@google.com    };
10812837Sgabeblack@google.com
10912954Sgabeblack@google.com  public:
11012837Sgabeblack@google.com    BaseSimpleCPU(BaseSimpleCPUParams *params);
11112954Sgabeblack@google.com    virtual ~BaseSimpleCPU();
11212837Sgabeblack@google.com
11312837Sgabeblack@google.com  public:
11412837Sgabeblack@google.com    /** SimpleThread object, provides all the architectural state. */
11512954Sgabeblack@google.com    SimpleThread *thread;
11612837Sgabeblack@google.com
11712954Sgabeblack@google.com    /** ThreadContext object, provides an interface for external
11812837Sgabeblack@google.com     * objects to modify this thread's state.
11912837Sgabeblack@google.com     */
12012837Sgabeblack@google.com    ThreadContext *tc;
12112954Sgabeblack@google.com  protected:
12212837Sgabeblack@google.com
12312954Sgabeblack@google.com    enum Status {
12412837Sgabeblack@google.com        Idle,
12512837Sgabeblack@google.com        Running,
12612837Sgabeblack@google.com        ITBWaitResponse,
12712954Sgabeblack@google.com        IcacheRetry,
12812837Sgabeblack@google.com        IcacheWaitResponse,
12912954Sgabeblack@google.com        IcacheWaitSwitch,
13012837Sgabeblack@google.com        DTBWaitResponse,
13112837Sgabeblack@google.com        DcacheRetry,
13212837Sgabeblack@google.com        DcacheWaitResponse,
13312954Sgabeblack@google.com        DcacheWaitSwitch,
13412837Sgabeblack@google.com        SwitchedOut
13512954Sgabeblack@google.com    };
13612837Sgabeblack@google.com
13712837Sgabeblack@google.com    Status _status;
13812837Sgabeblack@google.com
13912954Sgabeblack@google.com  public:
14012954Sgabeblack@google.com
14112837Sgabeblack@google.com#if FULL_SYSTEM
14212954Sgabeblack@google.com    Addr dbg_vtophys(Addr addr);
14312837Sgabeblack@google.com
14412837Sgabeblack@google.com    bool interval_stats;
14512837Sgabeblack@google.com#endif
14612954Sgabeblack@google.com
14712837Sgabeblack@google.com    // current instruction
14812954Sgabeblack@google.com    TheISA::MachInst inst;
14912837Sgabeblack@google.com
15012837Sgabeblack@google.com    // The predecoder
15112837Sgabeblack@google.com    TheISA::Predecoder predecoder;
15212954Sgabeblack@google.com
15312954Sgabeblack@google.com    StaticInstPtr curStaticInst;
15412837Sgabeblack@google.com    StaticInstPtr curMacroStaticInst;
15512954Sgabeblack@google.com
15612837Sgabeblack@google.com    //This is the offset from the current pc that fetch should be performed at
15712837Sgabeblack@google.com    Addr fetchOffset;
15812929Sgabeblack@google.com    //This flag says to stay at the current pc. This is useful for
15912929Sgabeblack@google.com    //instructions which go beyond MachInst boundaries.
16012929Sgabeblack@google.com    bool stayAtPC;
16113189Sgabeblack@google.com
16212929Sgabeblack@google.com    void checkForInterrupts();
16312929Sgabeblack@google.com    void setupFetchRequest(Request *req);
16412837Sgabeblack@google.com    void preExecute();
16512837Sgabeblack@google.com    void postExecute();
16612837Sgabeblack@google.com    void advancePC(Fault fault);
16712954Sgabeblack@google.com
16812837Sgabeblack@google.com    virtual void deallocateContext(int thread_num);
16912837Sgabeblack@google.com    virtual void haltContext(int thread_num);
17012837Sgabeblack@google.com
17112954Sgabeblack@google.com    // statistics
17212837Sgabeblack@google.com    virtual void regStats();
17312954Sgabeblack@google.com    virtual void resetStats();
17412837Sgabeblack@google.com
17512837Sgabeblack@google.com    // number of simulated instructions
17612837Sgabeblack@google.com    Counter numInst;
17712954Sgabeblack@google.com    Counter startNumInst;
17812837Sgabeblack@google.com    Stats::Scalar numInsts;
17912954Sgabeblack@google.com
18012837Sgabeblack@google.com    void countInst()
18112837Sgabeblack@google.com    {
18212837Sgabeblack@google.com        numInst++;
18312954Sgabeblack@google.com        numInsts++;
18412837Sgabeblack@google.com
18512954Sgabeblack@google.com        thread->funcExeInst++;
18612837Sgabeblack@google.com    }
18712837Sgabeblack@google.com
18812837Sgabeblack@google.com    virtual Counter totalInstructions() const
18912954Sgabeblack@google.com    {
19012837Sgabeblack@google.com        return numInst - startNumInst;
19112954Sgabeblack@google.com    }
19212837Sgabeblack@google.com
19312837Sgabeblack@google.com    // Mask to align PCs to MachInst sized boundaries
19412837Sgabeblack@google.com    static const Addr PCMask = ~((Addr)sizeof(TheISA::MachInst) - 1);
19512954Sgabeblack@google.com
19612837Sgabeblack@google.com    // number of simulated memory references
19712954Sgabeblack@google.com    Stats::Scalar numMemRefs;
19812837Sgabeblack@google.com
19912837Sgabeblack@google.com    // number of simulated loads
20012837Sgabeblack@google.com    Counter numLoad;
20112954Sgabeblack@google.com    Counter startNumLoad;
20212837Sgabeblack@google.com
20312954Sgabeblack@google.com    // number of idle cycles
20412837Sgabeblack@google.com    Stats::Average notIdleFraction;
20512837Sgabeblack@google.com    Stats::Formula idleFraction;
20612837Sgabeblack@google.com
20712954Sgabeblack@google.com    // number of cycles stalled for I-cache responses
20812837Sgabeblack@google.com    Stats::Scalar icacheStallCycles;
20912954Sgabeblack@google.com    Counter lastIcacheStall;
21012837Sgabeblack@google.com
21112837Sgabeblack@google.com    // number of cycles stalled for I-cache retries
21212837Sgabeblack@google.com    Stats::Scalar icacheRetryCycles;
21312954Sgabeblack@google.com    Counter lastIcacheRetry;
21412837Sgabeblack@google.com
21512954Sgabeblack@google.com    // number of cycles stalled for D-cache responses
21612837Sgabeblack@google.com    Stats::Scalar dcacheStallCycles;
21712837Sgabeblack@google.com    Counter lastDcacheStall;
21812837Sgabeblack@google.com
21912954Sgabeblack@google.com    // number of cycles stalled for D-cache retries
22012837Sgabeblack@google.com    Stats::Scalar dcacheRetryCycles;
22112954Sgabeblack@google.com    Counter lastDcacheRetry;
22212837Sgabeblack@google.com
22312837Sgabeblack@google.com    virtual void serialize(std::ostream &os);
22412837Sgabeblack@google.com    virtual void unserialize(Checkpoint *cp, const std::string &section);
22512954Sgabeblack@google.com
22612837Sgabeblack@google.com    // These functions are only used in CPU models that split
22712954Sgabeblack@google.com    // effective address computation from the actual memory access.
22812837Sgabeblack@google.com    void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); }
22912837Sgabeblack@google.com    Addr getEA()        { panic("BaseSimpleCPU::getEA() not implemented\n");
23012837Sgabeblack@google.com        M5_DUMMY_RETURN}
23112954Sgabeblack@google.com
23212837Sgabeblack@google.com    void prefetch(Addr addr, unsigned flags);
23312954Sgabeblack@google.com    void writeHint(Addr addr, int size, unsigned flags);
23412837Sgabeblack@google.com
23512837Sgabeblack@google.com    Fault copySrcTranslate(Addr src);
23612837Sgabeblack@google.com
23712954Sgabeblack@google.com    Fault copy(Addr dest);
23812837Sgabeblack@google.com
23912954Sgabeblack@google.com    // The register accessor methods provide the index of the
24012837Sgabeblack@google.com    // instruction's operand (e.g., 0 or 1), not the architectural
24112837Sgabeblack@google.com    // register index, to simplify the implementation of register
24212837Sgabeblack@google.com    // renaming.  We find the architectural register index by indexing
243    // into the instruction's own operand index table.  Note that a
244    // raw pointer to the StaticInst is provided instead of a
245    // ref-counted StaticInstPtr to redice overhead.  This is fine as
246    // long as these methods don't copy the pointer into any long-term
247    // storage (which is pretty hard to imagine they would have reason
248    // to do).
249
250    uint64_t readIntRegOperand(const StaticInst *si, int idx)
251    {
252        return thread->readIntReg(si->srcRegIdx(idx));
253    }
254
255    FloatReg readFloatRegOperand(const StaticInst *si, int idx)
256    {
257        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
258        return thread->readFloatReg(reg_idx);
259    }
260
261    FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
262    {
263        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
264        return thread->readFloatRegBits(reg_idx);
265    }
266
267    void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
268    {
269        thread->setIntReg(si->destRegIdx(idx), val);
270    }
271
272    void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
273    {
274        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
275        thread->setFloatReg(reg_idx, val);
276    }
277
278    void setFloatRegOperandBits(const StaticInst *si, int idx,
279                                FloatRegBits val)
280    {
281        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
282        thread->setFloatRegBits(reg_idx, val);
283    }
284
285    uint64_t readPC() { return thread->readPC(); }
286    uint64_t readMicroPC() { return thread->readMicroPC(); }
287    uint64_t readNextPC() { return thread->readNextPC(); }
288    uint64_t readNextMicroPC() { return thread->readNextMicroPC(); }
289    uint64_t readNextNPC() { return thread->readNextNPC(); }
290
291    void setPC(uint64_t val) { thread->setPC(val); }
292    void setMicroPC(uint64_t val) { thread->setMicroPC(val); }
293    void setNextPC(uint64_t val) { thread->setNextPC(val); }
294    void setNextMicroPC(uint64_t val) { thread->setNextMicroPC(val); }
295    void setNextNPC(uint64_t val) { thread->setNextNPC(val); }
296
297    MiscReg readMiscRegNoEffect(int misc_reg)
298    {
299        return thread->readMiscRegNoEffect(misc_reg);
300    }
301
302    MiscReg readMiscReg(int misc_reg)
303    {
304        return thread->readMiscReg(misc_reg);
305    }
306
307    void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
308    {
309        return thread->setMiscRegNoEffect(misc_reg, val);
310    }
311
312    void setMiscReg(int misc_reg, const MiscReg &val)
313    {
314        return thread->setMiscReg(misc_reg, val);
315    }
316
317    MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
318    {
319        int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
320        return thread->readMiscRegNoEffect(reg_idx);
321    }
322
323    MiscReg readMiscRegOperand(const StaticInst *si, int idx)
324    {
325        int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
326        return thread->readMiscReg(reg_idx);
327    }
328
329    void setMiscRegOperandNoEffect(const StaticInst *si, int idx, const MiscReg &val)
330    {
331        int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
332        return thread->setMiscRegNoEffect(reg_idx, val);
333    }
334
335    void setMiscRegOperand(
336            const StaticInst *si, int idx, const MiscReg &val)
337    {
338        int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
339        return thread->setMiscReg(reg_idx, val);
340    }
341
342    void demapPage(Addr vaddr, uint64_t asn)
343    {
344        thread->demapPage(vaddr, asn);
345    }
346
347    void demapInstPage(Addr vaddr, uint64_t asn)
348    {
349        thread->demapInstPage(vaddr, asn);
350    }
351
352    void demapDataPage(Addr vaddr, uint64_t asn)
353    {
354        thread->demapDataPage(vaddr, asn);
355    }
356
357    unsigned readStCondFailures() {
358        return thread->readStCondFailures();
359    }
360
361    void setStCondFailures(unsigned sc_failures) {
362        thread->setStCondFailures(sc_failures);
363    }
364
365     MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID)
366     {
367        panic("Simple CPU models do not support multithreaded "
368              "register access.\n");
369     }
370
371     void setRegOtherThread(int regIdx, const MiscReg &val,
372                            ThreadID tid = InvalidThreadID)
373     {
374        panic("Simple CPU models do not support multithreaded "
375              "register access.\n");
376     }
377
378    //Fault CacheOp(uint8_t Op, Addr EA);
379
380#if FULL_SYSTEM
381    Fault hwrei() { return thread->hwrei(); }
382    void ev5_trap(Fault fault) { fault->invoke(tc); }
383    bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
384#else
385    void syscall(int64_t callnum) { thread->syscall(callnum); }
386#endif
387
388    bool misspeculating() { return thread->misspeculating(); }
389    ThreadContext *tcBase() { return tc; }
390};
391
392#endif // __CPU_SIMPLE_BASE_HH__
393