cpu.hh revision 12106
12381SN/A/*
22592SN/A * Copyright (c) 2011 ARM Limited
32381SN/A * Copyright (c) 2013 Advanced Micro Devices, Inc.
42381SN/A * All rights reserved
52381SN/A *
62381SN/A * The license below extends only to copyright in the software and shall
72381SN/A * not be construed as granting a license to any other intellectual
82381SN/A * property including but not limited to intellectual property relating
92381SN/A * to a hardware implementation of the functionality of the software
102381SN/A * licensed hereunder.  You may use the software subject to the license
112381SN/A * terms below provided that you ensure that this notice is replicated
122381SN/A * unmodified and in its entirety in all distributions of the software,
132381SN/A * modified or unmodified, in source code or in binary form.
142381SN/A *
152381SN/A * Copyright (c) 2006 The Regents of The University of Michigan
162381SN/A * All rights reserved.
172381SN/A *
182381SN/A * Redistribution and use in source and binary forms, with or without
192381SN/A * modification, are permitted provided that the following conditions are
202381SN/A * met: redistributions of source code must retain the above copyright
212381SN/A * notice, this list of conditions and the following disclaimer;
222381SN/A * redistributions in binary form must reproduce the above copyright
232381SN/A * notice, this list of conditions and the following disclaimer in the
242381SN/A * documentation and/or other materials provided with the distribution;
252381SN/A * neither the name of the copyright holders nor the names of its
262381SN/A * contributors may be used to endorse or promote products derived from
272665Ssaidi@eecs.umich.edu * this software without specific prior written permission.
282665Ssaidi@eecs.umich.edu *
292665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302665Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
312381SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
322381SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
332381SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342381SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
352662Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
362381SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
372381SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382381SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
392381SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402381SN/A *
413348Sbinkertn@umich.edu * Authors: Kevin Lim
423348Sbinkertn@umich.edu */
433348Sbinkertn@umich.edu
442392SN/A#ifndef __CPU_CHECKER_CPU_HH__
452980Sgblack@eecs.umich.edu#define __CPU_CHECKER_CPU_HH__
462394SN/A
472394SN/A#include <list>
482394SN/A#include <map>
492394SN/A#include <queue>
502394SN/A
512812Srdreslin@umich.edu#include "arch/types.hh"
522812Srdreslin@umich.edu#include "base/statistics.hh"
532812Srdreslin@umich.edu#include "cpu/base.hh"
542812Srdreslin@umich.edu#include "cpu/base_dyn_inst.hh"
552812Srdreslin@umich.edu#include "cpu/exec_context.hh"
562812Srdreslin@umich.edu#include "cpu/pc_event.hh"
572813Srdreslin@umich.edu#include "cpu/simple_thread.hh"
582813Srdreslin@umich.edu#include "cpu/static_inst.hh"
592813Srdreslin@umich.edu#include "debug/Checker.hh"
603074Srdreslin@umich.edu#include "mem/request.hh"
612382SN/A#include "params/CheckerCPU.hh"
623208Srdreslin@umich.edu#include "sim/eventq.hh"
633214Srdreslin@umich.edu
642381SN/A// forward declarations
652662Sstever@eecs.umich.edunamespace TheISA
662662Sstever@eecs.umich.edu{
672662Sstever@eecs.umich.edu    class TLB;
682662Sstever@eecs.umich.edu}
692662Sstever@eecs.umich.edu
702381SN/Atemplate <class>
712641Sstever@eecs.umich.educlass BaseDynInst;
722381SN/Aclass ThreadContext;
732813Srdreslin@umich.educlass Request;
742813Srdreslin@umich.edu
752813Srdreslin@umich.edu/**
762813Srdreslin@umich.edu * CheckerCPU class.  Dynamically verifies instructions as they are
772566SN/A * completed by making sure that the instruction and its results match
782662Sstever@eecs.umich.edu * the independent execution of the benchmark inside the checker.  The
792662Sstever@eecs.umich.edu * checker verifies instructions in order, regardless of the order in
802662Sstever@eecs.umich.edu * which instructions complete.  There are certain results that can
812662Sstever@eecs.umich.edu * not be verified, specifically the result of a store conditional or
822662Sstever@eecs.umich.edu * the values of uncached accesses.  In these cases, and with
832566SN/A * instructions marked as "IsUnverifiable", the checker assumes that
842566SN/A * the value from the main CPU's execution is correct and simply
852566SN/A * copies that value.  It provides a CheckerThreadContext (see
862662Sstever@eecs.umich.edu * checker/thread_context.hh) that provides hooks for updating the
872662Sstever@eecs.umich.edu * Checker's state through any ThreadContext accesses.  This allows the
882566SN/A * checker to be able to correctly verify instructions, even with
892662Sstever@eecs.umich.edu * external accesses to the ThreadContext that change state.
902662Sstever@eecs.umich.edu */
912566SN/Aclass CheckerCPU : public BaseCPU, public ExecContext
922662Sstever@eecs.umich.edu{
932662Sstever@eecs.umich.edu  protected:
942566SN/A    typedef TheISA::MachInst MachInst;
952566SN/A    typedef TheISA::FloatReg FloatReg;
962662Sstever@eecs.umich.edu    typedef TheISA::FloatRegBits FloatRegBits;
972662Sstever@eecs.umich.edu    typedef TheISA::MiscReg MiscReg;
982381SN/A
992381SN/A    /** id attached to all issued requests */
1002662Sstever@eecs.umich.edu    MasterID masterId;
1012381SN/A  public:
1022381SN/A    void init() override;
1032662Sstever@eecs.umich.edu
1042662Sstever@eecs.umich.edu    typedef CheckerCPUParams Params;
1052662Sstever@eecs.umich.edu    CheckerCPU(Params *p);
1062662Sstever@eecs.umich.edu    virtual ~CheckerCPU();
1072381SN/A
1082381SN/A    void setSystem(System *system);
1092662Sstever@eecs.umich.edu
1102662Sstever@eecs.umich.edu    void setIcachePort(MasterPort *icache_port);
1112662Sstever@eecs.umich.edu
1122662Sstever@eecs.umich.edu    void setDcachePort(MasterPort *dcache_port);
1132662Sstever@eecs.umich.edu
1142641Sstever@eecs.umich.edu    MasterPort &getDataPort() override
1152641Sstever@eecs.umich.edu    {
1162663Sstever@eecs.umich.edu        // the checker does not have ports on its own so return the
1172663Sstever@eecs.umich.edu        // data port of the actual CPU core
1182662Sstever@eecs.umich.edu        assert(dcachePort);
1192641Sstever@eecs.umich.edu        return *dcachePort;
1202813Srdreslin@umich.edu    }
1212641Sstever@eecs.umich.edu
1222641Sstever@eecs.umich.edu    MasterPort &getInstPort() override
1232641Sstever@eecs.umich.edu    {
1242811Srdreslin@umich.edu        // the checker does not have ports on its own so return the
1252811Srdreslin@umich.edu        // data port of the actual CPU core
1262811Srdreslin@umich.edu        assert(icachePort);
1273218Sgblack@eecs.umich.edu        return *icachePort;
1283218Sgblack@eecs.umich.edu    }
1293218Sgblack@eecs.umich.edu
1303218Sgblack@eecs.umich.edu  protected:
1313218Sgblack@eecs.umich.edu
1323218Sgblack@eecs.umich.edu    std::vector<Process*> workload;
1332662Sstever@eecs.umich.edu
1342662Sstever@eecs.umich.edu    System *systemPtr;
1352623SN/A
1362623SN/A    MasterPort *icachePort;
1372662Sstever@eecs.umich.edu    MasterPort *dcachePort;
1382641Sstever@eecs.umich.edu
1392641Sstever@eecs.umich.edu    ThreadContext *tc;
1402662Sstever@eecs.umich.edu
1412662Sstever@eecs.umich.edu    TheISA::TLB *itb;
1422662Sstever@eecs.umich.edu    TheISA::TLB *dtb;
1432641Sstever@eecs.umich.edu
1442641Sstever@eecs.umich.edu    Addr dbg_vtophys(Addr addr);
1452641Sstever@eecs.umich.edu
1462641Sstever@eecs.umich.edu    union Result {
1472641Sstever@eecs.umich.edu        uint64_t integer;
1482662Sstever@eecs.umich.edu        double dbl;
1492662Sstever@eecs.umich.edu        void set(uint64_t i) { integer = i; }
1502662Sstever@eecs.umich.edu        void set(double d) { dbl = d; }
1512662Sstever@eecs.umich.edu        void get(uint64_t& i) { i = integer; }
1522641Sstever@eecs.umich.edu        void get(double& d) { d = dbl; }
1532662Sstever@eecs.umich.edu    };
1542662Sstever@eecs.umich.edu
1552662Sstever@eecs.umich.edu    // ISAs like ARM can have multiple destination registers to check,
1562662Sstever@eecs.umich.edu    // keep them all in a std::queue
1572662Sstever@eecs.umich.edu    std::queue<Result> result;
1582662Sstever@eecs.umich.edu
1592662Sstever@eecs.umich.edu    // Pointer to the one memory request.
1602641Sstever@eecs.umich.edu    RequestPtr memReq;
1612641Sstever@eecs.umich.edu
1622641Sstever@eecs.umich.edu    StaticInstPtr curStaticInst;
1632641Sstever@eecs.umich.edu    StaticInstPtr curMacroStaticInst;
1642641Sstever@eecs.umich.edu
1652662Sstever@eecs.umich.edu    // number of simulated instructions
1662662Sstever@eecs.umich.edu    Counter numInst;
1672662Sstever@eecs.umich.edu    Counter startNumInst;
1682641Sstever@eecs.umich.edu
1692641Sstever@eecs.umich.edu    std::queue<int> miscRegIdxs;
1702641Sstever@eecs.umich.edu
1713158Sgblack@eecs.umich.edu  public:
1723158Sgblack@eecs.umich.edu
1732641Sstever@eecs.umich.edu    // Primary thread being run.
1742641Sstever@eecs.umich.edu    SimpleThread *thread;
1753260Ssaidi@eecs.umich.edu
1763260Ssaidi@eecs.umich.edu    TheISA::TLB* getITBPtr() { return itb; }
1773260Ssaidi@eecs.umich.edu    TheISA::TLB* getDTBPtr() { return dtb; }
1783260Ssaidi@eecs.umich.edu
1793260Ssaidi@eecs.umich.edu    virtual Counter totalInsts() const override
1803260Ssaidi@eecs.umich.edu    {
1813260Ssaidi@eecs.umich.edu        return 0;
1822811Srdreslin@umich.edu    }
1833156Sgblack@eecs.umich.edu
1843214Srdreslin@umich.edu    virtual Counter totalOps() const override
1853260Ssaidi@eecs.umich.edu    {
1862641Sstever@eecs.umich.edu        return 0;
1872641Sstever@eecs.umich.edu    }
1882641Sstever@eecs.umich.edu
1892641Sstever@eecs.umich.edu    // number of simulated loads
1902641Sstever@eecs.umich.edu    Counter numLoad;
1912641Sstever@eecs.umich.edu    Counter startNumLoad;
1922813Srdreslin@umich.edu
1933260Ssaidi@eecs.umich.edu    void serialize(CheckpointOut &cp) const override;
1943260Ssaidi@eecs.umich.edu    void unserialize(CheckpointIn &cp) override;
1953260Ssaidi@eecs.umich.edu
1963260Ssaidi@eecs.umich.edu    // These functions are only used in CPU models that split
1973260Ssaidi@eecs.umich.edu    // effective address computation from the actual memory access.
1983158Sgblack@eecs.umich.edu    void setEA(Addr EA) override
1992811Srdreslin@umich.edu    { panic("CheckerCPU::setEA() not implemented\n"); }
2002811Srdreslin@umich.edu    Addr getEA() const  override
2013156Sgblack@eecs.umich.edu    { panic("CheckerCPU::getEA() not implemented\n"); }
2023158Sgblack@eecs.umich.edu
2033156Sgblack@eecs.umich.edu    // The register accessor methods provide the index of the
2043260Ssaidi@eecs.umich.edu    // instruction's operand (e.g., 0 or 1), not the architectural
2052812Srdreslin@umich.edu    // register index, to simplify the implementation of register
2063293Srdreslin@umich.edu    // renaming.  We find the architectural register index by indexing
2073293Srdreslin@umich.edu    // into the instruction's own operand index table.  Note that a
2083335Srdreslin@umich.edu    // raw pointer to the StaticInst is provided instead of a
2093335Srdreslin@umich.edu    // ref-counted StaticInstPtr to redice overhead.  This is fine as
2103207Srdreslin@umich.edu    // long as these methods don't copy the pointer into any long-term
2112855Srdreslin@umich.edu    // storage (which is pretty hard to imagine they would have reason
2123156Sgblack@eecs.umich.edu    // to do).
2133158Sgblack@eecs.umich.edu
2142641Sstever@eecs.umich.edu    IntReg readIntRegOperand(const StaticInst *si, int idx) override
2152641Sstever@eecs.umich.edu    {
2162662Sstever@eecs.umich.edu        const RegId& reg = si->srcRegIdx(idx);
2172662Sstever@eecs.umich.edu        assert(reg.isIntReg());
2182641Sstever@eecs.umich.edu        return thread->readIntReg(reg.index());
2192381SN/A    }
2202811Srdreslin@umich.edu
2212811Srdreslin@umich.edu    FloatReg readFloatRegOperand(const StaticInst *si, int idx) override
2222811Srdreslin@umich.edu    {
2232811Srdreslin@umich.edu        const RegId& reg = si->srcRegIdx(idx);
2242811Srdreslin@umich.edu        assert(reg.isFloatReg());
2252811Srdreslin@umich.edu        return thread->readFloatReg(reg.index());
2262662Sstever@eecs.umich.edu    }
2272381SN/A
2282381SN/A    FloatRegBits readFloatRegOperandBits(const StaticInst *si,
2293260Ssaidi@eecs.umich.edu                                         int idx) override
2303260Ssaidi@eecs.umich.edu    {
2313260Ssaidi@eecs.umich.edu        const RegId& reg = si->srcRegIdx(idx);
2323260Ssaidi@eecs.umich.edu        assert(reg.isFloatReg());
2333260Ssaidi@eecs.umich.edu        return thread->readFloatRegBits(reg.index());
2343260Ssaidi@eecs.umich.edu    }
2353260Ssaidi@eecs.umich.edu
2362812Srdreslin@umich.edu    CCReg readCCRegOperand(const StaticInst *si, int idx) override
2373260Ssaidi@eecs.umich.edu    {
2383260Ssaidi@eecs.umich.edu        const RegId& reg = si->srcRegIdx(idx);
2393260Ssaidi@eecs.umich.edu        assert(reg.isCCReg());
2402814Srdreslin@umich.edu        return thread->readCCReg(reg.index());
2413039Sstever@eecs.umich.edu    }
2422641Sstever@eecs.umich.edu
2432662Sstever@eecs.umich.edu    template <class T>
2442641Sstever@eecs.umich.edu    void setResult(T t)
2452641Sstever@eecs.umich.edu    {
2462641Sstever@eecs.umich.edu        Result instRes;
2472641Sstever@eecs.umich.edu        instRes.set(t);
2482685Ssaidi@eecs.umich.edu        result.push(instRes);
2492641Sstever@eecs.umich.edu    }
2502641Sstever@eecs.umich.edu
2512641Sstever@eecs.umich.edu    void setIntRegOperand(const StaticInst *si, int idx,
2522662Sstever@eecs.umich.edu                          IntReg val) override
2532641Sstever@eecs.umich.edu    {
2542381SN/A        const RegId& reg = si->destRegIdx(idx);
2552381SN/A        assert(reg.isIntReg());
2562641Sstever@eecs.umich.edu        thread->setIntReg(reg.index(), val);
2572641Sstever@eecs.umich.edu        setResult<uint64_t>(val);
2582381SN/A    }
2592381SN/A
2602381SN/A    void setFloatRegOperand(const StaticInst *si, int idx,
2612381SN/A                            FloatReg val) override
2622641Sstever@eecs.umich.edu    {
2632549SN/A        const RegId& reg = si->destRegIdx(idx);
2642663Sstever@eecs.umich.edu        assert(reg.isFloatReg());
2652663Sstever@eecs.umich.edu        thread->setFloatReg(reg.index(), val);
2662883Srdreslin@umich.edu        setResult<double>(val);
2672813Srdreslin@umich.edu    }
2682813Srdreslin@umich.edu
2692813Srdreslin@umich.edu    void setFloatRegOperandBits(const StaticInst *si, int idx,
2702641Sstever@eecs.umich.edu                                FloatRegBits val) override
2712662Sstever@eecs.umich.edu    {
2722662Sstever@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
2732662Sstever@eecs.umich.edu        assert(reg.isFloatReg());
2742662Sstever@eecs.umich.edu        thread->setFloatRegBits(reg.index(), val);
2752641Sstever@eecs.umich.edu        setResult<uint64_t>(val);
2762566SN/A    }
2772641Sstever@eecs.umich.edu
2782663Sstever@eecs.umich.edu    void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
2792814Srdreslin@umich.edu    {
2802641Sstever@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
2812662Sstever@eecs.umich.edu        assert(reg.isCCReg());
2822641Sstever@eecs.umich.edu        thread->setCCReg(reg.index(), val);
2832813Srdreslin@umich.edu        setResult<uint64_t>(val);
2843018Srdreslin@umich.edu    }
2852813Srdreslin@umich.edu
2862813Srdreslin@umich.edu    bool readPredicate() override { return thread->readPredicate(); }
2872813Srdreslin@umich.edu    void setPredicate(bool val) override
2882813Srdreslin@umich.edu    {
2892813Srdreslin@umich.edu        thread->setPredicate(val);
2902813Srdreslin@umich.edu    }
2912813Srdreslin@umich.edu
2922813Srdreslin@umich.edu    TheISA::PCState pcState() const override { return thread->pcState(); }
2932814Srdreslin@umich.edu    void pcState(const TheISA::PCState &val) override
2942814Srdreslin@umich.edu    {
2952813Srdreslin@umich.edu        DPRINTF(Checker, "Changing PC to %s, old PC %s.\n",
2962813Srdreslin@umich.edu                         val, thread->pcState());
2972813Srdreslin@umich.edu        thread->pcState(val);
2982813Srdreslin@umich.edu    }
2993018Srdreslin@umich.edu    Addr instAddr() { return thread->instAddr(); }
3002641Sstever@eecs.umich.edu    Addr nextInstAddr() { return thread->nextInstAddr(); }
3012549SN/A    MicroPC microPC() { return thread->microPC(); }
3022662Sstever@eecs.umich.edu    //////////////////////////////////////////
3032566SN/A
3042566SN/A    MiscReg readMiscRegNoEffect(int misc_reg) const
3052566SN/A    {
3062662Sstever@eecs.umich.edu        return thread->readMiscRegNoEffect(misc_reg);
3072662Sstever@eecs.umich.edu    }
3082662Sstever@eecs.umich.edu
3092662Sstever@eecs.umich.edu    MiscReg readMiscReg(int misc_reg) override
3102662Sstever@eecs.umich.edu    {
3112662Sstever@eecs.umich.edu        return thread->readMiscReg(misc_reg);
3122662Sstever@eecs.umich.edu    }
3132663Sstever@eecs.umich.edu
3142663Sstever@eecs.umich.edu    void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
3153018Srdreslin@umich.edu    {
3162663Sstever@eecs.umich.edu        DPRINTF(Checker, "Setting misc reg %d with no effect to check later\n", misc_reg);
3172662Sstever@eecs.umich.edu        miscRegIdxs.push(misc_reg);
3182662Sstever@eecs.umich.edu        return thread->setMiscRegNoEffect(misc_reg, val);
3192662Sstever@eecs.umich.edu    }
3202662Sstever@eecs.umich.edu
3212662Sstever@eecs.umich.edu    void setMiscReg(int misc_reg, const MiscReg &val) override
3222662Sstever@eecs.umich.edu    {
3232662Sstever@eecs.umich.edu        DPRINTF(Checker, "Setting misc reg %d with effect to check later\n", misc_reg);
3242566SN/A        miscRegIdxs.push(misc_reg);
3252662Sstever@eecs.umich.edu        return thread->setMiscReg(misc_reg, val);
3262662Sstever@eecs.umich.edu    }
3272662Sstever@eecs.umich.edu
3282662Sstever@eecs.umich.edu    MiscReg readMiscRegOperand(const StaticInst *si, int idx) override
3293135Srdreslin@umich.edu    {
3302662Sstever@eecs.umich.edu        const RegId& reg = si->srcRegIdx(idx);
3312662Sstever@eecs.umich.edu        assert(reg.isMiscReg());
3322662Sstever@eecs.umich.edu        return thread->readMiscReg(reg.index());
3332855Srdreslin@umich.edu    }
3342662Sstever@eecs.umich.edu
3352855Srdreslin@umich.edu    void setMiscRegOperand(const StaticInst *si, int idx,
3362662Sstever@eecs.umich.edu                           const MiscReg &val) override
3373216Srdreslin@umich.edu    {
3383216Srdreslin@umich.edu        const RegId& reg = si->destRegIdx(idx);
3393217Srdreslin@umich.edu        assert(reg.isMiscReg());
3403217Srdreslin@umich.edu        return this->setMiscReg(reg.index(), val);
3412662Sstever@eecs.umich.edu    }
3422662Sstever@eecs.umich.edu
3432662Sstever@eecs.umich.edu#if THE_ISA == MIPS_ISA
3442641Sstever@eecs.umich.edu    MiscReg readRegOtherThread(const RegId& misc_reg, ThreadID tid) override
3452641Sstever@eecs.umich.edu    {
3463348Sbinkertn@umich.edu        panic("MIPS MT not defined for CheckerCPU.\n");
3473348Sbinkertn@umich.edu        return 0;
3483348Sbinkertn@umich.edu    }
3493135Srdreslin@umich.edu
3503348Sbinkertn@umich.edu    void setRegOtherThread(const RegId& misc_reg, MiscReg val,
3513348Sbinkertn@umich.edu                               ThreadID tid) override
3523135Srdreslin@umich.edu    {
3533135Srdreslin@umich.edu        panic("MIPS MT not defined for CheckerCPU.\n");
3543135Srdreslin@umich.edu    }
3553135Srdreslin@umich.edu#endif
3563135Srdreslin@umich.edu
3573261Srdreslin@umich.edu    /////////////////////////////////////////
3583261Srdreslin@umich.edu
3593261Srdreslin@umich.edu    void recordPCChange(const TheISA::PCState &val)
3603261Srdreslin@umich.edu    {
3613135Srdreslin@umich.edu       changedPC = true;
3623135Srdreslin@umich.edu       newPCState = val;
3633135Srdreslin@umich.edu    }
3643348Sbinkertn@umich.edu
3653348Sbinkertn@umich.edu    void demapPage(Addr vaddr, uint64_t asn) override
3663348Sbinkertn@umich.edu    {
3673348Sbinkertn@umich.edu        this->itb->demapPage(vaddr, asn);
3683348Sbinkertn@umich.edu        this->dtb->demapPage(vaddr, asn);
3693348Sbinkertn@umich.edu    }
3703348Sbinkertn@umich.edu
3713348Sbinkertn@umich.edu    // monitor/mwait funtions
3722685Ssaidi@eecs.umich.edu    void armMonitor(Addr address) override
3732685Ssaidi@eecs.umich.edu    { BaseCPU::armMonitor(0, address); }
3742685Ssaidi@eecs.umich.edu    bool mwait(PacketPtr pkt) override { return BaseCPU::mwait(0, pkt); }
3752685Ssaidi@eecs.umich.edu    void mwaitAtomic(ThreadContext *tc) override
3762685Ssaidi@eecs.umich.edu    { return BaseCPU::mwaitAtomic(0, tc, thread->dtb); }
3772685Ssaidi@eecs.umich.edu    AddressMonitor *getAddrMonitor() override
3783348Sbinkertn@umich.edu    { return BaseCPU::getCpuAddrMonitor(0); }
3793348Sbinkertn@umich.edu
3803348Sbinkertn@umich.edu    void demapInstPage(Addr vaddr, uint64_t asn)
3812566SN/A    {
3822566SN/A        this->itb->demapPage(vaddr, asn);
3833348Sbinkertn@umich.edu    }
3843348Sbinkertn@umich.edu
3853348Sbinkertn@umich.edu    void demapDataPage(Addr vaddr, uint64_t asn)
3863348Sbinkertn@umich.edu    {
3873348Sbinkertn@umich.edu        this->dtb->demapPage(vaddr, asn);
3883348Sbinkertn@umich.edu    }
3893348Sbinkertn@umich.edu
3903348Sbinkertn@umich.edu    Fault readMem(Addr addr, uint8_t *data, unsigned size,
3912566SN/A                  Request::Flags flags) override;
3923348Sbinkertn@umich.edu    Fault writeMem(uint8_t *data, unsigned size, Addr addr,
3933348Sbinkertn@umich.edu                   Request::Flags flags, uint64_t *res) override;
3943348Sbinkertn@umich.edu
3953348Sbinkertn@umich.edu    unsigned int readStCondFailures() const override {
3962566SN/A        return thread->readStCondFailures();
3973348Sbinkertn@umich.edu    }
3983348Sbinkertn@umich.edu
3993348Sbinkertn@umich.edu    void setStCondFailures(unsigned int sc_failures) override
4003348Sbinkertn@umich.edu    {}
4013348Sbinkertn@umich.edu    /////////////////////////////////////////////////////
4023348Sbinkertn@umich.edu
4033348Sbinkertn@umich.edu    Fault hwrei() override { return thread->hwrei(); }
4043348Sbinkertn@umich.edu    bool simPalCheck(int palFunc) override
4053348Sbinkertn@umich.edu    { return thread->simPalCheck(palFunc); }
4063348Sbinkertn@umich.edu    void wakeup(ThreadID tid) override { }
4073348Sbinkertn@umich.edu    // Assume that the normal CPU's call to syscall was successful.
4083348Sbinkertn@umich.edu    // The checker's state would have already been updated by the syscall.
4093348Sbinkertn@umich.edu    void syscall(int64_t callnum, Fault *fault) override { }
4103348Sbinkertn@umich.edu
4113348Sbinkertn@umich.edu    void handleError()
4123348Sbinkertn@umich.edu    {
4133348Sbinkertn@umich.edu        if (exitOnError)
4143348Sbinkertn@umich.edu            dumpAndExit();
4153348Sbinkertn@umich.edu    }
4163348Sbinkertn@umich.edu
4173348Sbinkertn@umich.edu    bool checkFlags(Request *unverified_req, Addr vAddr,
4183348Sbinkertn@umich.edu                    Addr pAddr, int flags);
4193348Sbinkertn@umich.edu
4203348Sbinkertn@umich.edu    void dumpAndExit();
4213348Sbinkertn@umich.edu
4223348Sbinkertn@umich.edu    ThreadContext *tcBase() override { return tc; }
4233348Sbinkertn@umich.edu    SimpleThread *threadBase() { return thread; }
4243348Sbinkertn@umich.edu
4253348Sbinkertn@umich.edu    Result unverifiedResult;
4263348Sbinkertn@umich.edu    Request *unverifiedReq;
4273348Sbinkertn@umich.edu    uint8_t *unverifiedMemData;
4282566SN/A
4292566SN/A    bool changedPC;
4302566SN/A    bool willChangePC;
4312592SN/A    TheISA::PCState newPCState;
4322566SN/A    bool exitOnError;
4332566SN/A    bool updateOnError;
4342566SN/A    bool warnOnlyOnLoadError;
4352592SN/A
4362566SN/A    InstSeqNum youngestSN;
4373348Sbinkertn@umich.edu};
4383348Sbinkertn@umich.edu
4393348Sbinkertn@umich.edu/**
4403348Sbinkertn@umich.edu * Templated Checker class.  This Checker class is templated on the
4412592SN/A * DynInstPtr of the instruction type that will be verified.  Proper
4422566SN/A * template instantiations of the Checker must be placed at the bottom
4432566SN/A * of checker/cpu.cc.
4442592SN/A */
4452568SN/Atemplate <class Impl>
4462568SN/Aclass Checker : public CheckerCPU
4472592SN/A{
4482381SN/A  private:
4492381SN/A    typedef typename Impl::DynInstPtr DynInstPtr;
4503260Ssaidi@eecs.umich.edu
4513260Ssaidi@eecs.umich.edu  public:
4523260Ssaidi@eecs.umich.edu    Checker(Params *p)
4533260Ssaidi@eecs.umich.edu        : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL)
4543260Ssaidi@eecs.umich.edu    { }
4553260Ssaidi@eecs.umich.edu
4562630SN/A    void switchOut();
4573260Ssaidi@eecs.umich.edu    void takeOverFrom(BaseCPU *oldCPU);
4583260Ssaidi@eecs.umich.edu
4593260Ssaidi@eecs.umich.edu    void advancePC(const Fault &fault);
4602381SN/A
461    void verify(DynInstPtr &inst);
462
463    void validateInst(DynInstPtr &inst);
464    void validateExecution(DynInstPtr &inst);
465    void validateState();
466
467    void copyResult(DynInstPtr &inst, uint64_t mismatch_val, int start_idx);
468    void handlePendingInt();
469
470  private:
471    void handleError(DynInstPtr &inst)
472    {
473        if (exitOnError) {
474            dumpAndExit(inst);
475        } else if (updateOnError) {
476            updateThisCycle = true;
477        }
478    }
479
480    void dumpAndExit(DynInstPtr &inst);
481
482    bool updateThisCycle;
483
484    DynInstPtr unverifiedInst;
485
486    std::list<DynInstPtr> instList;
487    typedef typename std::list<DynInstPtr>::iterator InstListIt;
488    void dumpInsts();
489};
490
491#endif // __CPU_CHECKER_CPU_HH__
492