cpu.hh revision 11168
112598Snikos.nikoleris@arm.com/*
27090SN/A * Copyright (c) 2011 ARM Limited
37090SN/A * Copyright (c) 2013 Advanced Micro Devices, Inc.
47090SN/A * All rights reserved
57090SN/A *
67090SN/A * The license below extends only to copyright in the software and shall
77090SN/A * not be construed as granting a license to any other intellectual
87090SN/A * property including but not limited to intellectual property relating
97090SN/A * to a hardware implementation of the functionality of the software
107090SN/A * licensed hereunder.  You may use the software subject to the license
117090SN/A * terms below provided that you ensure that this notice is replicated
127090SN/A * unmodified and in its entirety in all distributions of the software,
134486SN/A * modified or unmodified, in source code or in binary form.
144486SN/A *
154486SN/A * Copyright (c) 2006 The Regents of The University of Michigan
164486SN/A * All rights reserved.
174486SN/A *
184486SN/A * Redistribution and use in source and binary forms, with or without
194486SN/A * modification, are permitted provided that the following conditions are
204486SN/A * met: redistributions of source code must retain the above copyright
214486SN/A * notice, this list of conditions and the following disclaimer;
224486SN/A * redistributions in binary form must reproduce the above copyright
234486SN/A * notice, this list of conditions and the following disclaimer in the
244486SN/A * documentation and/or other materials provided with the distribution;
254486SN/A * neither the name of the copyright holders nor the names of its
264486SN/A * contributors may be used to endorse or promote products derived from
274486SN/A * this software without specific prior written permission.
284486SN/A *
294486SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
304486SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
314486SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
324486SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
334486SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
344486SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
354486SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
364486SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
374486SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
384486SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
397584SAli.Saidi@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
407584SAli.Saidi@arm.com *
417754SWilliam.Wang@arm.com * Authors: Kevin Lim
4212472Sglenn.bergmans@arm.com */
434486SN/A
4412472Sglenn.bergmans@arm.com#ifndef __CPU_CHECKER_CPU_HH__
453630SN/A#define __CPU_CHECKER_CPU_HH__
463630SN/A
4712472Sglenn.bergmans@arm.com#include <list>
4813665Sandreas.sandberg@arm.com#include <map>
4913665Sandreas.sandberg@arm.com#include <queue>
5013665Sandreas.sandberg@arm.com
5113665Sandreas.sandberg@arm.com#include "arch/types.hh"
5213665Sandreas.sandberg@arm.com#include "base/statistics.hh"
5313665Sandreas.sandberg@arm.com#include "cpu/base.hh"
5413665Sandreas.sandberg@arm.com#include "cpu/base_dyn_inst.hh"
5513665Sandreas.sandberg@arm.com#include "cpu/exec_context.hh"
5613665Sandreas.sandberg@arm.com#include "cpu/pc_event.hh"
5713665Sandreas.sandberg@arm.com#include "cpu/simple_thread.hh"
5813665Sandreas.sandberg@arm.com#include "cpu/static_inst.hh"
5913665Sandreas.sandberg@arm.com#include "debug/Checker.hh"
6013665Sandreas.sandberg@arm.com#include "params/CheckerCPU.hh"
6113665Sandreas.sandberg@arm.com#include "sim/eventq.hh"
6213665Sandreas.sandberg@arm.com
6313665Sandreas.sandberg@arm.com// forward declarations
6413665Sandreas.sandberg@arm.comnamespace TheISA
6513665Sandreas.sandberg@arm.com{
6613665Sandreas.sandberg@arm.com    class TLB;
6713665Sandreas.sandberg@arm.com}
683630SN/A
6911841Sandreas.sandberg@arm.comtemplate <class>
7011841Sandreas.sandberg@arm.comclass BaseDynInst;
7111841Sandreas.sandberg@arm.comclass ThreadContext;
7211841Sandreas.sandberg@arm.comclass Request;
7313665Sandreas.sandberg@arm.com
7411841Sandreas.sandberg@arm.com/**
7511841Sandreas.sandberg@arm.com * CheckerCPU class.  Dynamically verifies instructions as they are
7611841Sandreas.sandberg@arm.com * completed by making sure that the instruction and its results match
7711841Sandreas.sandberg@arm.com * the independent execution of the benchmark inside the checker.  The
7813505Sgiacomo.travaglini@arm.com * checker verifies instructions in order, regardless of the order in
7911841Sandreas.sandberg@arm.com * which instructions complete.  There are certain results that can
8011841Sandreas.sandberg@arm.com * not be verified, specifically the result of a store conditional or
819806Sstever@gmail.com * the values of uncached accesses.  In these cases, and with
829806Sstever@gmail.com * instructions marked as "IsUnverifiable", the checker assumes that
837584SAli.Saidi@arm.com * the value from the main CPU's execution is correct and simply
849338SAndreas.Sandberg@arm.com * copies that value.  It provides a CheckerThreadContext (see
857584SAli.Saidi@arm.com * checker/thread_context.hh) that provides hooks for updating the
863898SN/A * Checker's state through any ThreadContext accesses.  This allows the
879806Sstever@gmail.com * checker to be able to correctly verify instructions, even with
887950SAli.Saidi@ARM.com * external accesses to the ThreadContext that change state.
897950SAli.Saidi@ARM.com */
909338SAndreas.Sandberg@arm.comclass CheckerCPU : public BaseCPU, public ExecContext
919525SAndreas.Sandberg@ARM.com{
927950SAli.Saidi@ARM.com  protected:
937950SAli.Saidi@ARM.com    typedef TheISA::MachInst MachInst;
947950SAli.Saidi@ARM.com    typedef TheISA::FloatReg FloatReg;
957950SAli.Saidi@ARM.com    typedef TheISA::FloatRegBits FloatRegBits;
967587SAli.Saidi@arm.com    typedef TheISA::MiscReg MiscReg;
977587SAli.Saidi@arm.com
987587SAli.Saidi@arm.com    /** id attached to all issued requests */
999338SAndreas.Sandberg@arm.com    MasterID masterId;
1007753SWilliam.Wang@arm.com  public:
1017753SWilliam.Wang@arm.com    virtual void init();
1029525SAndreas.Sandberg@ARM.com
1037753SWilliam.Wang@arm.com    typedef CheckerCPUParams Params;
1047587SAli.Saidi@arm.com    CheckerCPU(Params *p);
1057587SAli.Saidi@arm.com    virtual ~CheckerCPU();
1068282SAli.Saidi@ARM.com
1078282SAli.Saidi@ARM.com    void setSystem(System *system);
1089338SAndreas.Sandberg@arm.com
1098282SAli.Saidi@ARM.com    void setIcachePort(MasterPort *icache_port);
11011296Sandreas.sandberg@arm.com
11111296Sandreas.sandberg@arm.com    void setDcachePort(MasterPort *dcache_port);
11211296Sandreas.sandberg@arm.com
11311296Sandreas.sandberg@arm.com    MasterPort &getDataPort()
11411296Sandreas.sandberg@arm.com    {
11511296Sandreas.sandberg@arm.com        // the checker does not have ports on its own so return the
11611296Sandreas.sandberg@arm.com        // data port of the actual CPU core
11711296Sandreas.sandberg@arm.com        assert(dcachePort);
11811296Sandreas.sandberg@arm.com        return *dcachePort;
11911296Sandreas.sandberg@arm.com    }
12011296Sandreas.sandberg@arm.com
12111296Sandreas.sandberg@arm.com    MasterPort &getInstPort()
12211296Sandreas.sandberg@arm.com    {
12311296Sandreas.sandberg@arm.com        // the checker does not have ports on its own so return the
12412474Sglenn.bergmans@arm.com        // data port of the actual CPU core
12512474Sglenn.bergmans@arm.com        assert(icachePort);
12612474Sglenn.bergmans@arm.com        return *icachePort;
12712474Sglenn.bergmans@arm.com    }
12812474Sglenn.bergmans@arm.com
12912474Sglenn.bergmans@arm.com  protected:
13012474Sglenn.bergmans@arm.com
13112474Sglenn.bergmans@arm.com    std::vector<Process*> workload;
13212474Sglenn.bergmans@arm.com
13312474Sglenn.bergmans@arm.com    System *systemPtr;
13412474Sglenn.bergmans@arm.com
13512474Sglenn.bergmans@arm.com    MasterPort *icachePort;
13612474Sglenn.bergmans@arm.com    MasterPort *dcachePort;
13712474Sglenn.bergmans@arm.com
13812474Sglenn.bergmans@arm.com    ThreadContext *tc;
13912474Sglenn.bergmans@arm.com
14012474Sglenn.bergmans@arm.com    TheISA::TLB *itb;
14112474Sglenn.bergmans@arm.com    TheISA::TLB *dtb;
14212474Sglenn.bergmans@arm.com
14312474Sglenn.bergmans@arm.com    Addr dbg_vtophys(Addr addr);
14412474Sglenn.bergmans@arm.com
14512474Sglenn.bergmans@arm.com    union Result {
14612474Sglenn.bergmans@arm.com        uint64_t integer;
14712474Sglenn.bergmans@arm.com        double dbl;
14812474Sglenn.bergmans@arm.com        void set(uint64_t i) { integer = i; }
14912474Sglenn.bergmans@arm.com        void set(double d) { dbl = d; }
15012474Sglenn.bergmans@arm.com        void get(uint64_t& i) { i = integer; }
15112474Sglenn.bergmans@arm.com        void get(double& d) { d = dbl; }
15212474Sglenn.bergmans@arm.com    };
15312474Sglenn.bergmans@arm.com
15412474Sglenn.bergmans@arm.com    // ISAs like ARM can have multiple destination registers to check,
15512474Sglenn.bergmans@arm.com    // keep them all in a std::queue
15612474Sglenn.bergmans@arm.com    std::queue<Result> result;
15712474Sglenn.bergmans@arm.com
15812474Sglenn.bergmans@arm.com    // Pointer to the one memory request.
15912474Sglenn.bergmans@arm.com    RequestPtr memReq;
16012474Sglenn.bergmans@arm.com
16112474Sglenn.bergmans@arm.com    StaticInstPtr curStaticInst;
16212474Sglenn.bergmans@arm.com    StaticInstPtr curMacroStaticInst;
16312474Sglenn.bergmans@arm.com
16412474Sglenn.bergmans@arm.com    // number of simulated instructions
16512474Sglenn.bergmans@arm.com    Counter numInst;
16612474Sglenn.bergmans@arm.com    Counter startNumInst;
16712474Sglenn.bergmans@arm.com
16812474Sglenn.bergmans@arm.com    std::queue<int> miscRegIdxs;
16912474Sglenn.bergmans@arm.com
17012474Sglenn.bergmans@arm.com  public:
17112474Sglenn.bergmans@arm.com
17212474Sglenn.bergmans@arm.com    // Primary thread being run.
17312474Sglenn.bergmans@arm.com    SimpleThread *thread;
17412474Sglenn.bergmans@arm.com
17512474Sglenn.bergmans@arm.com    TheISA::TLB* getITBPtr() { return itb; }
17612474Sglenn.bergmans@arm.com    TheISA::TLB* getDTBPtr() { return dtb; }
17712474Sglenn.bergmans@arm.com
17812474Sglenn.bergmans@arm.com    virtual Counter totalInsts() const
17912474Sglenn.bergmans@arm.com    {
18012474Sglenn.bergmans@arm.com        return 0;
18112474Sglenn.bergmans@arm.com    }
18212474Sglenn.bergmans@arm.com
18312474Sglenn.bergmans@arm.com    virtual Counter totalOps() const
18412474Sglenn.bergmans@arm.com    {
18512474Sglenn.bergmans@arm.com        return 0;
18612474Sglenn.bergmans@arm.com    }
18712474Sglenn.bergmans@arm.com
18812474Sglenn.bergmans@arm.com    // number of simulated loads
1897584SAli.Saidi@arm.com    Counter numLoad;
1907584SAli.Saidi@arm.com    Counter startNumLoad;
1919338SAndreas.Sandberg@arm.com
1928524SAli.Saidi@ARM.com    void serialize(CheckpointOut &cp) const override;
1938524SAli.Saidi@ARM.com    void unserialize(CheckpointIn &cp) override;
1948299Schander.sudanthi@arm.com
1957584SAli.Saidi@arm.com    // These functions are only used in CPU models that split
19612472Sglenn.bergmans@arm.com    // effective address computation from the actual memory access.
19712472Sglenn.bergmans@arm.com    void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); }
19812472Sglenn.bergmans@arm.com    Addr getEA() const  { panic("SimpleCPU::getEA() not implemented\n"); }
19912472Sglenn.bergmans@arm.com
20012472Sglenn.bergmans@arm.com    // The register accessor methods provide the index of the
20112472Sglenn.bergmans@arm.com    // instruction's operand (e.g., 0 or 1), not the architectural
20212472Sglenn.bergmans@arm.com    // register index, to simplify the implementation of register
20312472Sglenn.bergmans@arm.com    // renaming.  We find the architectural register index by indexing
20412472Sglenn.bergmans@arm.com    // into the instruction's own operand index table.  Note that a
20512472Sglenn.bergmans@arm.com    // raw pointer to the StaticInst is provided instead of a
20612472Sglenn.bergmans@arm.com    // ref-counted StaticInstPtr to redice overhead.  This is fine as
20712472Sglenn.bergmans@arm.com    // long as these methods don't copy the pointer into any long-term
20811011SAndreas.Sandberg@ARM.com    // storage (which is pretty hard to imagine they would have reason
20911011SAndreas.Sandberg@ARM.com    // to do).
21011011SAndreas.Sandberg@ARM.com
21111011SAndreas.Sandberg@ARM.com    IntReg readIntRegOperand(const StaticInst *si, int idx)
21211011SAndreas.Sandberg@ARM.com    {
21311011SAndreas.Sandberg@ARM.com        return thread->readIntReg(si->srcRegIdx(idx));
21411011SAndreas.Sandberg@ARM.com    }
21511011SAndreas.Sandberg@ARM.com
21611011SAndreas.Sandberg@ARM.com    FloatReg readFloatRegOperand(const StaticInst *si, int idx)
21711011SAndreas.Sandberg@ARM.com    {
21811011SAndreas.Sandberg@ARM.com        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
21911011SAndreas.Sandberg@ARM.com        return thread->readFloatReg(reg_idx);
22011011SAndreas.Sandberg@ARM.com    }
22111011SAndreas.Sandberg@ARM.com
22211011SAndreas.Sandberg@ARM.com    FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
22311011SAndreas.Sandberg@ARM.com    {
22411011SAndreas.Sandberg@ARM.com        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
22511011SAndreas.Sandberg@ARM.com        return thread->readFloatRegBits(reg_idx);
22611011SAndreas.Sandberg@ARM.com    }
22711011SAndreas.Sandberg@ARM.com
22811011SAndreas.Sandberg@ARM.com    CCReg readCCRegOperand(const StaticInst *si, int idx)
22911011SAndreas.Sandberg@ARM.com    {
23012472Sglenn.bergmans@arm.com        int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
23112472Sglenn.bergmans@arm.com        return thread->readCCReg(reg_idx);
23212472Sglenn.bergmans@arm.com    }
23312472Sglenn.bergmans@arm.com
23412472Sglenn.bergmans@arm.com    template <class T>
23512472Sglenn.bergmans@arm.com    void setResult(T t)
23612472Sglenn.bergmans@arm.com    {
23712472Sglenn.bergmans@arm.com        Result instRes;
23812472Sglenn.bergmans@arm.com        instRes.set(t);
23912472Sglenn.bergmans@arm.com        result.push(instRes);
24012472Sglenn.bergmans@arm.com    }
24112472Sglenn.bergmans@arm.com
24212472Sglenn.bergmans@arm.com    void setIntRegOperand(const StaticInst *si, int idx, IntReg val)
24312472Sglenn.bergmans@arm.com    {
24411421Sdavid.guillen@arm.com        thread->setIntReg(si->destRegIdx(idx), val);
24511421Sdavid.guillen@arm.com        setResult<uint64_t>(val);
24611421Sdavid.guillen@arm.com    }
24711421Sdavid.guillen@arm.com
24811421Sdavid.guillen@arm.com    void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
24911421Sdavid.guillen@arm.com    {
25011421Sdavid.guillen@arm.com        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
25111421Sdavid.guillen@arm.com        thread->setFloatReg(reg_idx, val);
25211421Sdavid.guillen@arm.com        setResult<double>(val);
25311421Sdavid.guillen@arm.com    }
25411421Sdavid.guillen@arm.com
25511421Sdavid.guillen@arm.com    void setFloatRegOperandBits(const StaticInst *si, int idx,
25611421Sdavid.guillen@arm.com                                FloatRegBits val)
25711421Sdavid.guillen@arm.com    {
25811421Sdavid.guillen@arm.com        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
25911421Sdavid.guillen@arm.com        thread->setFloatRegBits(reg_idx, val);
26011236Sandreas.sandberg@arm.com        setResult<uint64_t>(val);
26111236Sandreas.sandberg@arm.com    }
26211236Sandreas.sandberg@arm.com
26311236Sandreas.sandberg@arm.com    void setCCRegOperand(const StaticInst *si, int idx, CCReg val)
26411236Sandreas.sandberg@arm.com    {
26511236Sandreas.sandberg@arm.com        int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
26611236Sandreas.sandberg@arm.com        thread->setCCReg(reg_idx, val);
26711236Sandreas.sandberg@arm.com        setResult<uint64_t>(val);
26811236Sandreas.sandberg@arm.com    }
26911011SAndreas.Sandberg@ARM.com
27011011SAndreas.Sandberg@ARM.com    bool readPredicate() { return thread->readPredicate(); }
27111421Sdavid.guillen@arm.com    void setPredicate(bool val)
27211421Sdavid.guillen@arm.com    {
27311421Sdavid.guillen@arm.com        thread->setPredicate(val);
27411236Sandreas.sandberg@arm.com    }
27511236Sandreas.sandberg@arm.com
27611236Sandreas.sandberg@arm.com    TheISA::PCState pcState() const { return thread->pcState(); }
27711236Sandreas.sandberg@arm.com    void pcState(const TheISA::PCState &val)
27811236Sandreas.sandberg@arm.com    {
27911421Sdavid.guillen@arm.com        DPRINTF(Checker, "Changing PC to %s, old PC %s.\n",
28011421Sdavid.guillen@arm.com                         val, thread->pcState());
28111421Sdavid.guillen@arm.com        thread->pcState(val);
28212472Sglenn.bergmans@arm.com    }
28312472Sglenn.bergmans@arm.com    Addr instAddr() { return thread->instAddr(); }
28412472Sglenn.bergmans@arm.com    Addr nextInstAddr() { return thread->nextInstAddr(); }
28512472Sglenn.bergmans@arm.com    MicroPC microPC() { return thread->microPC(); }
28612472Sglenn.bergmans@arm.com    //////////////////////////////////////////
28712472Sglenn.bergmans@arm.com
28812472Sglenn.bergmans@arm.com    MiscReg readMiscRegNoEffect(int misc_reg) const
28912472Sglenn.bergmans@arm.com    {
29012472Sglenn.bergmans@arm.com        return thread->readMiscRegNoEffect(misc_reg);
29112472Sglenn.bergmans@arm.com    }
29212472Sglenn.bergmans@arm.com
29312472Sglenn.bergmans@arm.com    MiscReg readMiscReg(int misc_reg)
29412472Sglenn.bergmans@arm.com    {
29512472Sglenn.bergmans@arm.com        return thread->readMiscReg(misc_reg);
29611236Sandreas.sandberg@arm.com    }
29711236Sandreas.sandberg@arm.com
29811236Sandreas.sandberg@arm.com    void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
29911236Sandreas.sandberg@arm.com    {
30011236Sandreas.sandberg@arm.com        DPRINTF(Checker, "Setting misc reg %d with no effect to check later\n", misc_reg);
30111236Sandreas.sandberg@arm.com        miscRegIdxs.push(misc_reg);
30211236Sandreas.sandberg@arm.com        return thread->setMiscRegNoEffect(misc_reg, val);
30311236Sandreas.sandberg@arm.com    }
30411236Sandreas.sandberg@arm.com
30511011SAndreas.Sandberg@ARM.com    void setMiscReg(int misc_reg, const MiscReg &val)
30611011SAndreas.Sandberg@ARM.com    {
30711236Sandreas.sandberg@arm.com        DPRINTF(Checker, "Setting misc reg %d with effect to check later\n", misc_reg);
30811236Sandreas.sandberg@arm.com        miscRegIdxs.push(misc_reg);
30911236Sandreas.sandberg@arm.com        return thread->setMiscReg(misc_reg, val);
31011236Sandreas.sandberg@arm.com    }
31111236Sandreas.sandberg@arm.com
31211236Sandreas.sandberg@arm.com    MiscReg readMiscRegOperand(const StaticInst *si, int idx)
31311236Sandreas.sandberg@arm.com    {
31411011SAndreas.Sandberg@ARM.com        int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base;
31512472Sglenn.bergmans@arm.com        return thread->readMiscReg(reg_idx);
31612472Sglenn.bergmans@arm.com    }
31712472Sglenn.bergmans@arm.com
31812472Sglenn.bergmans@arm.com    void setMiscRegOperand(
31912472Sglenn.bergmans@arm.com            const StaticInst *si, int idx, const MiscReg &val)
32012472Sglenn.bergmans@arm.com    {
32112472Sglenn.bergmans@arm.com        int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
32212472Sglenn.bergmans@arm.com        return this->setMiscReg(reg_idx, val);
32312472Sglenn.bergmans@arm.com    }
32412472Sglenn.bergmans@arm.com
32512472Sglenn.bergmans@arm.com#if THE_ISA == MIPS_ISA
32612472Sglenn.bergmans@arm.com    MiscReg readRegOtherThread(int misc_reg, ThreadID tid)
32712472Sglenn.bergmans@arm.com    {
3289806Sstever@gmail.com        panic("MIPS MT not defined for CheckerCPU.\n");
3297584SAli.Saidi@arm.com        return 0;
3309338SAndreas.Sandberg@arm.com    }
3317584SAli.Saidi@arm.com
3327584SAli.Saidi@arm.com    void setRegOtherThread(int misc_reg, MiscReg val, ThreadID tid)
3337584SAli.Saidi@arm.com    {
3347584SAli.Saidi@arm.com        panic("MIPS MT not defined for CheckerCPU.\n");
3357584SAli.Saidi@arm.com    }
3369338SAndreas.Sandberg@arm.com#endif
3379525SAndreas.Sandberg@ARM.com
3387584SAli.Saidi@arm.com    /////////////////////////////////////////
3397584SAli.Saidi@arm.com
3407584SAli.Saidi@arm.com    void recordPCChange(const TheISA::PCState &val)
3417584SAli.Saidi@arm.com    {
34212472Sglenn.bergmans@arm.com       changedPC = true;
34312472Sglenn.bergmans@arm.com       newPCState = val;
34412472Sglenn.bergmans@arm.com    }
34512472Sglenn.bergmans@arm.com
34612472Sglenn.bergmans@arm.com    void demapPage(Addr vaddr, uint64_t asn)
34712472Sglenn.bergmans@arm.com    {
34812472Sglenn.bergmans@arm.com        this->itb->demapPage(vaddr, asn);
34912472Sglenn.bergmans@arm.com        this->dtb->demapPage(vaddr, asn);
35012472Sglenn.bergmans@arm.com    }
35112472Sglenn.bergmans@arm.com
35212472Sglenn.bergmans@arm.com    // monitor/mwait funtions
35312472Sglenn.bergmans@arm.com    virtual void armMonitor(Addr address) { BaseCPU::armMonitor(0, address); }
35412472Sglenn.bergmans@arm.com    bool mwait(PacketPtr pkt) { return BaseCPU::mwait(0, pkt); }
35512472Sglenn.bergmans@arm.com    void mwaitAtomic(ThreadContext *tc)
3569806Sstever@gmail.com    { return BaseCPU::mwaitAtomic(0, tc, thread->dtb); }
3577584SAli.Saidi@arm.com    AddressMonitor *getAddrMonitor() { return BaseCPU::getCpuAddrMonitor(0); }
3589338SAndreas.Sandberg@arm.com
3599525SAndreas.Sandberg@ARM.com    void demapInstPage(Addr vaddr, uint64_t asn)
3607584SAli.Saidi@arm.com    {
3617584SAli.Saidi@arm.com        this->itb->demapPage(vaddr, asn);
3627584SAli.Saidi@arm.com    }
3637584SAli.Saidi@arm.com
3647584SAli.Saidi@arm.com    void demapDataPage(Addr vaddr, uint64_t asn)
3657584SAli.Saidi@arm.com    {
36612077Sgedare@rtems.org        this->dtb->demapPage(vaddr, asn);
36712077Sgedare@rtems.org    }
36812077Sgedare@rtems.org
36912077Sgedare@rtems.org    Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags);
37012077Sgedare@rtems.org    Fault writeMem(uint8_t *data, unsigned size,
37112077Sgedare@rtems.org                   Addr addr, unsigned flags, uint64_t *res);
3728512Sgeoffrey.blake@arm.com
3738512Sgeoffrey.blake@arm.com    unsigned int readStCondFailures() const {
3749338SAndreas.Sandberg@arm.com        return thread->readStCondFailures();
37513106Sgiacomo.travaglini@arm.com    }
37613106Sgiacomo.travaglini@arm.com
3778512Sgeoffrey.blake@arm.com    void setStCondFailures(unsigned int sc_failures)
37812467SCurtis.Dunham@arm.com    {}
37910037SARM gem5 Developers    /////////////////////////////////////////////////////
38010037SARM gem5 Developers
38111668Sandreas.sandberg@arm.com    Fault hwrei() { return thread->hwrei(); }
38212975Sgiacomo.travaglini@arm.com    bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
38312975Sgiacomo.travaglini@arm.com    void wakeup(ThreadID tid) override { }
38412975Sgiacomo.travaglini@arm.com    // Assume that the normal CPU's call to syscall was successful.
38512975Sgiacomo.travaglini@arm.com    // The checker's state would have already been updated by the syscall.
38610037SARM gem5 Developers    void syscall(int64_t callnum) { }
38712472Sglenn.bergmans@arm.com
38812472Sglenn.bergmans@arm.com    void handleError()
38912472Sglenn.bergmans@arm.com    {
39012472Sglenn.bergmans@arm.com        if (exitOnError)
39112472Sglenn.bergmans@arm.com            dumpAndExit();
39212472Sglenn.bergmans@arm.com    }
39312733Sandreas.sandberg@arm.com
39412975Sgiacomo.travaglini@arm.com    bool checkFlags(Request *unverified_req, Addr vAddr,
39512975Sgiacomo.travaglini@arm.com                    Addr pAddr, int flags);
39612975Sgiacomo.travaglini@arm.com
39712975Sgiacomo.travaglini@arm.com    void dumpAndExit();
39812733Sandreas.sandberg@arm.com
39912472Sglenn.bergmans@arm.com    ThreadContext *tcBase() { return tc; }
40012472Sglenn.bergmans@arm.com    SimpleThread *threadBase() { return thread; }
40112472Sglenn.bergmans@arm.com
40212472Sglenn.bergmans@arm.com    Result unverifiedResult;
40312472Sglenn.bergmans@arm.com    Request *unverifiedReq;
40410847Sandreas.sandberg@arm.com    uint8_t *unverifiedMemData;
40510847Sandreas.sandberg@arm.com
40610847Sandreas.sandberg@arm.com    bool changedPC;
40710847Sandreas.sandberg@arm.com    bool willChangePC;
40810847Sandreas.sandberg@arm.com    TheISA::PCState newPCState;
40910847Sandreas.sandberg@arm.com    bool exitOnError;
41012975Sgiacomo.travaglini@arm.com    bool updateOnError;
41112975Sgiacomo.travaglini@arm.com    bool warnOnlyOnLoadError;
41210847Sandreas.sandberg@arm.com
4138870SAli.Saidi@ARM.com    InstSeqNum youngestSN;
4148870SAli.Saidi@ARM.com};
4159338SAndreas.Sandberg@arm.com
4168870SAli.Saidi@ARM.com/**
4178870SAli.Saidi@ARM.com * Templated Checker class.  This Checker class is templated on the
4188870SAli.Saidi@ARM.com * DynInstPtr of the instruction type that will be verified.  Proper
41912472Sglenn.bergmans@arm.com * template instantiations of the Checker must be placed at the bottom
42012472Sglenn.bergmans@arm.com * of checker/cpu.cc.
42112472Sglenn.bergmans@arm.com */
42212472Sglenn.bergmans@arm.comtemplate <class Impl>
42312472Sglenn.bergmans@arm.comclass Checker : public CheckerCPU
42412472Sglenn.bergmans@arm.com{
42512472Sglenn.bergmans@arm.com  private:
42612472Sglenn.bergmans@arm.com    typedef typename Impl::DynInstPtr DynInstPtr;
42712472Sglenn.bergmans@arm.com
42812472Sglenn.bergmans@arm.com  public:
4297950SAli.Saidi@ARM.com    Checker(Params *p)
4307754SWilliam.Wang@arm.com        : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL)
4319338SAndreas.Sandberg@arm.com    { }
4327754SWilliam.Wang@arm.com
4337754SWilliam.Wang@arm.com    void switchOut();
43412659Sandreas.sandberg@arm.com    void takeOverFrom(BaseCPU *oldCPU);
43512659Sandreas.sandberg@arm.com
43612472Sglenn.bergmans@arm.com    void advancePC(const Fault &fault);
43712472Sglenn.bergmans@arm.com
43812472Sglenn.bergmans@arm.com    void verify(DynInstPtr &inst);
43912472Sglenn.bergmans@arm.com
44012472Sglenn.bergmans@arm.com    void validateInst(DynInstPtr &inst);
44112472Sglenn.bergmans@arm.com    void validateExecution(DynInstPtr &inst);
44212472Sglenn.bergmans@arm.com    void validateState();
44312472Sglenn.bergmans@arm.com
44412472Sglenn.bergmans@arm.com    void copyResult(DynInstPtr &inst, uint64_t mismatch_val, int start_idx);
44512472Sglenn.bergmans@arm.com    void handlePendingInt();
4467753SWilliam.Wang@arm.com
4477753SWilliam.Wang@arm.com  private:
4489338SAndreas.Sandberg@arm.com    void handleError(DynInstPtr &inst)
4499394Sandreas.hansson@arm.com    {
4509330Schander.sudanthi@arm.com        if (exitOnError) {
4517753SWilliam.Wang@arm.com            dumpAndExit(inst);
4529939Sdam.sunwoo@arm.com        } else if (updateOnError) {
4539939Sdam.sunwoo@arm.com            updateThisCycle = true;
4549646SChris.Emmons@arm.com        }
4559646SChris.Emmons@arm.com    }
4569646SChris.Emmons@arm.com
4579646SChris.Emmons@arm.com    void dumpAndExit(DynInstPtr &inst);
4589646SChris.Emmons@arm.com
4599646SChris.Emmons@arm.com    bool updateThisCycle;
46011237Sandreas.sandberg@arm.com
46110840Sandreas.sandberg@arm.com    DynInstPtr unverifiedInst;
46211090Sandreas.sandberg@arm.com
46311090Sandreas.sandberg@arm.com    std::list<DynInstPtr> instList;
46412232Sgiacomo.travaglini@arm.com    typedef typename std::list<DynInstPtr>::iterator InstListIt;
46512232Sgiacomo.travaglini@arm.com    void dumpInsts();
46612232Sgiacomo.travaglini@arm.com};
46712232Sgiacomo.travaglini@arm.com
4689646SChris.Emmons@arm.com#endif // __CPU_CHECKER_CPU_HH__
46911090Sandreas.sandberg@arm.com