base.hh revision 5348
13804SN/A/*
29235Sandreas.hansson@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
39235Sandreas.hansson@arm.com * All rights reserved.
49235Sandreas.hansson@arm.com *
59235Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
69235Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
79235Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
89235Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
99235Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
109235Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
119235Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
129235Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
139235Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
143804SN/A * this software without specific prior written permission.
153804SN/A *
163804SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173804SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183804SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193804SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203804SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213804SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223804SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233804SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243804SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253804SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263804SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273804SN/A *
283804SN/A * Authors: Steve Reinhardt
293804SN/A *          Dave Greene
303804SN/A *          Nathan Binkert
313804SN/A */
323804SN/A
333804SN/A#ifndef __CPU_SIMPLE_BASE_HH__
343804SN/A#define __CPU_SIMPLE_BASE_HH__
353804SN/A
363804SN/A#include "arch/predecoder.hh"
373804SN/A#include "base/statistics.hh"
383804SN/A#include "config/full_system.hh"
393804SN/A#include "cpu/base.hh"
403804SN/A#include "cpu/simple_thread.hh"
419235Sandreas.hansson@arm.com#include "cpu/pc_event.hh"
423804SN/A#include "cpu/static_inst.hh"
433804SN/A#include "mem/packet.hh"
449235Sandreas.hansson@arm.com#include "mem/port.hh"
459235Sandreas.hansson@arm.com#include "mem/request.hh"
463804SN/A#include "sim/eventq.hh"
478229SN/A#include "sim/system.hh"
488902SN/A
498229SN/A// forward declarations
509235Sandreas.hansson@arm.com#if FULL_SYSTEM
513804SN/Aclass Processor;
528918SN/Anamespace TheISA
539235Sandreas.hansson@arm.com{
549235Sandreas.hansson@arm.com    class ITB;
559235Sandreas.hansson@arm.com    class DTB;
568918SN/A}
579235Sandreas.hansson@arm.comclass MemObject;
589235Sandreas.hansson@arm.com
593804SN/A#else
603804SN/A
619235Sandreas.hansson@arm.comclass Process;
623804SN/A
633804SN/A#endif // FULL_SYSTEM
643804SN/A
653804SN/Aclass RemoteGDB;
668918SN/Aclass GDBListener;
673804SN/A
688918SN/Anamespace TheISA
699235Sandreas.hansson@arm.com{
708918SN/A    class Predecoder;
718918SN/A}
728918SN/Aclass ThreadContext;
738918SN/Aclass Checkpoint;
748918SN/A
758918SN/Anamespace Trace {
768918SN/A    class InstRecord;
778918SN/A}
788918SN/A
798918SN/A
808918SN/Aclass BaseSimpleCPU : public BaseCPU
818918SN/A{
828918SN/A  protected:
838918SN/A    typedef TheISA::MiscReg MiscReg;
848918SN/A    typedef TheISA::FloatReg FloatReg;
858918SN/A    typedef TheISA::FloatRegBits FloatRegBits;
868918SN/A
878918SN/A  protected:
888918SN/A    Trace::InstRecord *traceData;
898918SN/A
908918SN/A    inline void checkPcEventQueue() {
918918SN/A        Addr oldpc;
929235Sandreas.hansson@arm.com        do {
933804SN/A            oldpc = thread->readPC();
943804SN/A            system->pcEventQueue.service(tc);
953804SN/A        } while (oldpc != thread->readPC());
963804SN/A    }
973804SN/A
983832SN/A  public:
993832SN/A    void post_interrupt(int int_num, int index);
1003832SN/A
1013832SN/A    void zero_fill_64(Addr addr) {
1023832SN/A      static int warned = 0;
1033832SN/A      if (!warned) {
1043832SN/A        warn ("WH64 is not implemented");
1053804SN/A        warned = 1;
1068918SN/A      }
1073804SN/A    };
1083804SN/A
1093804SN/A  public:
1103804SN/A    struct Params : public BaseCPU::Params
1113804SN/A    {
1123804SN/A        TheISA::ITB *itb;
1133804SN/A        TheISA::DTB *dtb;
1148918SN/A#if !FULL_SYSTEM
1159235Sandreas.hansson@arm.com        Process *process;
1168918SN/A#endif
1178918SN/A    };
1188918SN/A    BaseSimpleCPU(Params *params);
1198918SN/A    virtual ~BaseSimpleCPU();
1208918SN/A
1219235Sandreas.hansson@arm.com  public:
1225609SN/A    /** SimpleThread object, provides all the architectural state. */
1235609SN/A    SimpleThread *thread;
1245609SN/A
1255609SN/A    /** ThreadContext object, provides an interface for external
1265608SN/A     * objects to modify this thread's state.
1279235Sandreas.hansson@arm.com     */
1283804SN/A    ThreadContext *tc;
1293804SN/A  protected:
1303804SN/A    int cpuId;
1313804SN/A
1323804SN/A  public:
1333804SN/A
1343804SN/A#if FULL_SYSTEM
1353804SN/A    Addr dbg_vtophys(Addr addr);
1365608SN/A
1379235Sandreas.hansson@arm.com    bool interval_stats;
1383804SN/A#endif
1393804SN/A
1403804SN/A    // current instruction
1413804SN/A    TheISA::MachInst inst;
1428902SN/A
1433804SN/A    // The predecoder
1443804SN/A    TheISA::Predecoder predecoder;
1459235Sandreas.hansson@arm.com
1469235Sandreas.hansson@arm.com    StaticInstPtr curStaticInst;
1473804SN/A    StaticInstPtr curMacroStaticInst;
1483804SN/A
1493804SN/A    //This is the offset from the current pc that fetch should be performed at
1503804SN/A    Addr fetchOffset;
1515608SN/A    //This flag says to stay at the current pc. This is useful for
1525608SN/A    //instructions which go beyond MachInst boundaries.
1533804SN/A    bool stayAtPC;
1543804SN/A
1553804SN/A    void checkForInterrupts();
1563804SN/A    Fault setupFetchRequest(Request *req);
1575608SN/A    void preExecute();
1585608SN/A    void postExecute();
1593804SN/A    void advancePC(Fault fault);
1603804SN/A
1613804SN/A    virtual void deallocateContext(int thread_num);
1623804SN/A    virtual void haltContext(int thread_num);
1635608SN/A
1645608SN/A    // statistics
1653804SN/A    virtual void regStats();
1663804SN/A    virtual void resetStats();
1673804SN/A
1683804SN/A    // number of simulated instructions
1698918SN/A    Counter numInst;
1708918SN/A    Counter startNumInst;
1718918SN/A    Stats::Scalar<> numInsts;
1728918SN/A
1738918SN/A    void countInst()
1748918SN/A    {
1755608SN/A        numInst++;
1765608SN/A        numInsts++;
1773804SN/A
1783804SN/A        thread->funcExeInst++;
1793804SN/A    }
1803804SN/A
1818918SN/A    virtual Counter totalInstructions() const
1828918SN/A    {
1838918SN/A        return numInst - startNumInst;
1848918SN/A    }
1858918SN/A
1868918SN/A    // Mask to align PCs to MachInst sized boundaries
1875608SN/A    static const Addr PCMask = ~((Addr)sizeof(TheISA::MachInst) - 1);
1885608SN/A
1893804SN/A    // number of simulated memory references
1903804SN/A    Stats::Scalar<> numMemRefs;
1913804SN/A
1923804SN/A    // number of simulated loads
1939235Sandreas.hansson@arm.com    Counter numLoad;
1948918SN/A    Counter startNumLoad;
1953804SN/A
1963804SN/A    // number of idle cycles
1973804SN/A    Stats::Average<> notIdleFraction;
1983804SN/A    Stats::Formula idleFraction;
1995608SN/A
2008918SN/A    // number of cycles stalled for I-cache responses
2013804SN/A    Stats::Scalar<> icacheStallCycles;
2023804SN/A    Counter lastIcacheStall;
2033804SN/A
2043804SN/A    // number of cycles stalled for I-cache retries
2053804SN/A    Stats::Scalar<> icacheRetryCycles;
2069235Sandreas.hansson@arm.com    Counter lastIcacheRetry;
207
208    // number of cycles stalled for D-cache responses
209    Stats::Scalar<> dcacheStallCycles;
210    Counter lastDcacheStall;
211
212    // number of cycles stalled for D-cache retries
213    Stats::Scalar<> dcacheRetryCycles;
214    Counter lastDcacheRetry;
215
216    virtual void serialize(std::ostream &os);
217    virtual void unserialize(Checkpoint *cp, const std::string &section);
218
219    // These functions are only used in CPU models that split
220    // effective address computation from the actual memory access.
221    void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); }
222    Addr getEA() 	{ panic("BaseSimpleCPU::getEA() not implemented\n");
223        M5_DUMMY_RETURN}
224
225    void prefetch(Addr addr, unsigned flags)
226    {
227        // need to do this...
228    }
229
230    void writeHint(Addr addr, int size, unsigned flags)
231    {
232        // need to do this...
233    }
234
235
236    Fault copySrcTranslate(Addr src);
237
238    Fault copy(Addr dest);
239
240    // The register accessor methods provide the index of the
241    // instruction's operand (e.g., 0 or 1), not the architectural
242    // register index, to simplify the implementation of register
243    // renaming.  We find the architectural register index by indexing
244    // into the instruction's own operand index table.  Note that a
245    // raw pointer to the StaticInst is provided instead of a
246    // ref-counted StaticInstPtr to redice overhead.  This is fine as
247    // long as these methods don't copy the pointer into any long-term
248    // storage (which is pretty hard to imagine they would have reason
249    // to do).
250
251    uint64_t readIntRegOperand(const StaticInst *si, int idx)
252    {
253        return thread->readIntReg(si->srcRegIdx(idx));
254    }
255
256    FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width)
257    {
258        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
259        return thread->readFloatReg(reg_idx, width);
260    }
261
262    FloatReg readFloatRegOperand(const StaticInst *si, int idx)
263    {
264        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
265        return thread->readFloatReg(reg_idx);
266    }
267
268    FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx,
269                                         int width)
270    {
271        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
272        return thread->readFloatRegBits(reg_idx, width);
273    }
274
275    FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
276    {
277        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
278        return thread->readFloatRegBits(reg_idx);
279    }
280
281    void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
282    {
283        thread->setIntReg(si->destRegIdx(idx), val);
284    }
285
286    void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val,
287                            int width)
288    {
289        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
290        thread->setFloatReg(reg_idx, val, width);
291    }
292
293    void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
294    {
295        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
296        thread->setFloatReg(reg_idx, val);
297    }
298
299    void setFloatRegOperandBits(const StaticInst *si, int idx,
300                                FloatRegBits val, int width)
301    {
302        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
303        thread->setFloatRegBits(reg_idx, val, width);
304    }
305
306    void setFloatRegOperandBits(const StaticInst *si, int idx,
307                                FloatRegBits val)
308    {
309        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
310        thread->setFloatRegBits(reg_idx, val);
311    }
312
313    uint64_t readPC() { return thread->readPC(); }
314    uint64_t readMicroPC() { return thread->readMicroPC(); }
315    uint64_t readNextPC() { return thread->readNextPC(); }
316    uint64_t readNextMicroPC() { return thread->readNextMicroPC(); }
317    uint64_t readNextNPC() { return thread->readNextNPC(); }
318
319    void setPC(uint64_t val) { thread->setPC(val); }
320    void setMicroPC(uint64_t val) { thread->setMicroPC(val); }
321    void setNextPC(uint64_t val) { thread->setNextPC(val); }
322    void setNextMicroPC(uint64_t val) { thread->setNextMicroPC(val); }
323    void setNextNPC(uint64_t val) { thread->setNextNPC(val); }
324
325    MiscReg readMiscRegNoEffect(int misc_reg)
326    {
327        return thread->readMiscRegNoEffect(misc_reg);
328    }
329
330    MiscReg readMiscReg(int misc_reg)
331    {
332        return thread->readMiscReg(misc_reg);
333    }
334
335    void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
336    {
337        return thread->setMiscRegNoEffect(misc_reg, val);
338    }
339
340    void setMiscReg(int misc_reg, const MiscReg &val)
341    {
342        return thread->setMiscReg(misc_reg, val);
343    }
344
345    MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
346    {
347        int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
348        return thread->readMiscRegNoEffect(reg_idx);
349    }
350
351    MiscReg readMiscRegOperand(const StaticInst *si, int idx)
352    {
353        int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
354        return thread->readMiscReg(reg_idx);
355    }
356
357    void setMiscRegOperandNoEffect(const StaticInst *si, int idx, const MiscReg &val)
358    {
359        int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
360        return thread->setMiscRegNoEffect(reg_idx, val);
361    }
362
363    void setMiscRegOperand(
364            const StaticInst *si, int idx, const MiscReg &val)
365    {
366        int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
367        return thread->setMiscReg(reg_idx, val);
368    }
369
370    unsigned readStCondFailures() {
371        return thread->readStCondFailures();
372    }
373
374    void setStCondFailures(unsigned sc_failures) {
375        thread->setStCondFailures(sc_failures);
376    }
377
378     MiscReg readRegOtherThread(int regIdx, int tid = -1)
379     {
380        panic("Simple CPU models do not support multithreaded "
381              "register access.\n");
382     }
383
384     void setRegOtherThread(int regIdx, const MiscReg &val, int tid = -1)
385     {
386        panic("Simple CPU models do not support multithreaded "
387              "register access.\n");
388     }
389
390    //Fault CacheOp(uint8_t Op, Addr EA);
391
392#if FULL_SYSTEM
393    Fault hwrei() { return thread->hwrei(); }
394    void ev5_trap(Fault fault) { fault->invoke(tc); }
395    bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
396#else
397    void syscall(int64_t callnum) { thread->syscall(callnum); }
398#endif
399
400    bool misspeculating() { return thread->misspeculating(); }
401    ThreadContext *tcBase() { return tc; }
402};
403
404#endif // __CPU_SIMPLE_BASE_HH__
405