cpu.hh revision 13557
12315SN/A/*
212107SRekai.GonzalezAlberquilla@arm.com * Copyright (c) 2011, 2016 ARM Limited
39920Syasuko.eckert@amd.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
48733Sgeoffrey.blake@arm.com * All rights reserved
58733Sgeoffrey.blake@arm.com *
68733Sgeoffrey.blake@arm.com * The license below extends only to copyright in the software and shall
78733Sgeoffrey.blake@arm.com * not be construed as granting a license to any other intellectual
88733Sgeoffrey.blake@arm.com * property including but not limited to intellectual property relating
98733Sgeoffrey.blake@arm.com * to a hardware implementation of the functionality of the software
108733Sgeoffrey.blake@arm.com * licensed hereunder.  You may use the software subject to the license
118733Sgeoffrey.blake@arm.com * terms below provided that you ensure that this notice is replicated
128733Sgeoffrey.blake@arm.com * unmodified and in its entirety in all distributions of the software,
138733Sgeoffrey.blake@arm.com * modified or unmodified, in source code or in binary form.
148733Sgeoffrey.blake@arm.com *
152332SN/A * Copyright (c) 2006 The Regents of The University of Michigan
162315SN/A * All rights reserved.
172315SN/A *
182315SN/A * Redistribution and use in source and binary forms, with or without
192315SN/A * modification, are permitted provided that the following conditions are
202315SN/A * met: redistributions of source code must retain the above copyright
212315SN/A * notice, this list of conditions and the following disclaimer;
222315SN/A * redistributions in binary form must reproduce the above copyright
232315SN/A * notice, this list of conditions and the following disclaimer in the
242315SN/A * documentation and/or other materials provided with the distribution;
252315SN/A * neither the name of the copyright holders nor the names of its
262315SN/A * contributors may be used to endorse or promote products derived from
272315SN/A * this software without specific prior written permission.
282315SN/A *
292315SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302315SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
312315SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
322315SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
332315SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342315SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
352315SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
362315SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
372315SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382315SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
392315SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402689Sktlim@umich.edu *
412689Sktlim@umich.edu * Authors: Kevin Lim
422315SN/A */
432315SN/A
442315SN/A#ifndef __CPU_CHECKER_CPU_HH__
452315SN/A#define __CPU_CHECKER_CPU_HH__
462315SN/A
472315SN/A#include <list>
488229Snate@binkert.org#include <map>
492315SN/A#include <queue>
502315SN/A
512669Sktlim@umich.edu#include "arch/types.hh"
522315SN/A#include "base/statistics.hh"
532315SN/A#include "cpu/base.hh"
542315SN/A#include "cpu/base_dyn_inst.hh"
5510319SAndreas.Sandberg@ARM.com#include "cpu/exec_context.hh"
5612107SRekai.GonzalezAlberquilla@arm.com#include "cpu/inst_res.hh"
578229Snate@binkert.org#include "cpu/pc_event.hh"
582683Sktlim@umich.edu#include "cpu/simple_thread.hh"
592315SN/A#include "cpu/static_inst.hh"
608733Sgeoffrey.blake@arm.com#include "debug/Checker.hh"
6111608Snikos.nikoleris@arm.com#include "mem/request.hh"
628733Sgeoffrey.blake@arm.com#include "params/CheckerCPU.hh"
632315SN/A#include "sim/eventq.hh"
642315SN/A
6512406Sgabeblack@google.comclass BaseTLB;
662315SN/Atemplate <class>
672315SN/Aclass BaseDynInst;
682680Sktlim@umich.educlass ThreadContext;
692669Sktlim@umich.educlass Request;
702315SN/A
712350SN/A/**
722350SN/A * CheckerCPU class.  Dynamically verifies instructions as they are
732350SN/A * completed by making sure that the instruction and its results match
742350SN/A * the independent execution of the benchmark inside the checker.  The
752350SN/A * checker verifies instructions in order, regardless of the order in
762350SN/A * which instructions complete.  There are certain results that can
772350SN/A * not be verified, specifically the result of a store conditional or
782350SN/A * the values of uncached accesses.  In these cases, and with
792350SN/A * instructions marked as "IsUnverifiable", the checker assumes that
802350SN/A * the value from the main CPU's execution is correct and simply
812680Sktlim@umich.edu * copies that value.  It provides a CheckerThreadContext (see
822683Sktlim@umich.edu * checker/thread_context.hh) that provides hooks for updating the
832680Sktlim@umich.edu * Checker's state through any ThreadContext accesses.  This allows the
842350SN/A * checker to be able to correctly verify instructions, even with
852680Sktlim@umich.edu * external accesses to the ThreadContext that change state.
862350SN/A */
8710319SAndreas.Sandberg@ARM.comclass CheckerCPU : public BaseCPU, public ExecContext
882315SN/A{
892315SN/A  protected:
902315SN/A    typedef TheISA::MachInst MachInst;
9112109SRekai.GonzalezAlberquilla@arm.com    using VecRegContainer = TheISA::VecRegContainer;
928832SAli.Saidi@ARM.com
938832SAli.Saidi@ARM.com    /** id attached to all issued requests */
948832SAli.Saidi@ARM.com    MasterID masterId;
952315SN/A  public:
9611169Sandreas.hansson@arm.com    void init() override;
972315SN/A
985529Snate@binkert.org    typedef CheckerCPUParams Params;
992315SN/A    CheckerCPU(Params *p);
1002315SN/A    virtual ~CheckerCPU();
1012315SN/A
1022315SN/A    void setSystem(System *system);
1032315SN/A
1049608Sandreas.hansson@arm.com    void setIcachePort(MasterPort *icache_port);
1052679Sktlim@umich.edu
1069608Sandreas.hansson@arm.com    void setDcachePort(MasterPort *dcache_port);
1072679Sktlim@umich.edu
10811169Sandreas.hansson@arm.com    MasterPort &getDataPort() override
1098887Sgeoffrey.blake@arm.com    {
1109176Sandreas.hansson@arm.com        // the checker does not have ports on its own so return the
1119176Sandreas.hansson@arm.com        // data port of the actual CPU core
1129176Sandreas.hansson@arm.com        assert(dcachePort);
1138887Sgeoffrey.blake@arm.com        return *dcachePort;
1148887Sgeoffrey.blake@arm.com    }
1158887Sgeoffrey.blake@arm.com
11611169Sandreas.hansson@arm.com    MasterPort &getInstPort() override
1178887Sgeoffrey.blake@arm.com    {
1189176Sandreas.hansson@arm.com        // the checker does not have ports on its own so return the
1199176Sandreas.hansson@arm.com        // data port of the actual CPU core
1209176Sandreas.hansson@arm.com        assert(icachePort);
1218887Sgeoffrey.blake@arm.com        return *icachePort;
1228887Sgeoffrey.blake@arm.com    }
1232679Sktlim@umich.edu
1249176Sandreas.hansson@arm.com  protected:
1259176Sandreas.hansson@arm.com
1269176Sandreas.hansson@arm.com    std::vector<Process*> workload;
1279176Sandreas.hansson@arm.com
1289176Sandreas.hansson@arm.com    System *systemPtr;
1299176Sandreas.hansson@arm.com
1309608Sandreas.hansson@arm.com    MasterPort *icachePort;
1319608Sandreas.hansson@arm.com    MasterPort *dcachePort;
1322315SN/A
1332680Sktlim@umich.edu    ThreadContext *tc;
1342315SN/A
13512406Sgabeblack@google.com    BaseTLB *itb;
13612406Sgabeblack@google.com    BaseTLB *dtb;
1372315SN/A
1382315SN/A    Addr dbg_vtophys(Addr addr);
1392315SN/A
1408733Sgeoffrey.blake@arm.com    // ISAs like ARM can have multiple destination registers to check,
1418733Sgeoffrey.blake@arm.com    // keep them all in a std::queue
14212107SRekai.GonzalezAlberquilla@arm.com    std::queue<InstResult> result;
1432315SN/A
1442315SN/A    StaticInstPtr curStaticInst;
1458733Sgeoffrey.blake@arm.com    StaticInstPtr curMacroStaticInst;
1462315SN/A
1472315SN/A    // number of simulated instructions
1482315SN/A    Counter numInst;
1492315SN/A    Counter startNumInst;
1502315SN/A
1512315SN/A    std::queue<int> miscRegIdxs;
1522315SN/A
1539176Sandreas.hansson@arm.com  public:
1549176Sandreas.hansson@arm.com
1559176Sandreas.hansson@arm.com    // Primary thread being run.
1569176Sandreas.hansson@arm.com    SimpleThread *thread;
1579176Sandreas.hansson@arm.com
15812406Sgabeblack@google.com    BaseTLB* getITBPtr() { return itb; }
15912406Sgabeblack@google.com    BaseTLB* getDTBPtr() { return dtb; }
1608733Sgeoffrey.blake@arm.com
16111169Sandreas.hansson@arm.com    virtual Counter totalInsts() const override
1628887Sgeoffrey.blake@arm.com    {
1638887Sgeoffrey.blake@arm.com        return 0;
1648887Sgeoffrey.blake@arm.com    }
1658887Sgeoffrey.blake@arm.com
16611169Sandreas.hansson@arm.com    virtual Counter totalOps() const override
1672315SN/A    {
1682930Sktlim@umich.edu        return 0;
1692315SN/A    }
1702315SN/A
1712315SN/A    // number of simulated loads
1722315SN/A    Counter numLoad;
1732315SN/A    Counter startNumLoad;
1742315SN/A
17511168Sandreas.hansson@arm.com    void serialize(CheckpointOut &cp) const override;
17611168Sandreas.hansson@arm.com    void unserialize(CheckpointIn &cp) override;
1772315SN/A
1782315SN/A    // The register accessor methods provide the index of the
1792315SN/A    // instruction's operand (e.g., 0 or 1), not the architectural
1802315SN/A    // register index, to simplify the implementation of register
1812315SN/A    // renaming.  We find the architectural register index by indexing
1822315SN/A    // into the instruction's own operand index table.  Note that a
1832315SN/A    // raw pointer to the StaticInst is provided instead of a
1842315SN/A    // ref-counted StaticInstPtr to redice overhead.  This is fine as
1852315SN/A    // long as these methods don't copy the pointer into any long-term
1862315SN/A    // storage (which is pretty hard to imagine they would have reason
1872315SN/A    // to do).
1882315SN/A
18913557Sgabeblack@google.com    RegVal
19013557Sgabeblack@google.com    readIntRegOperand(const StaticInst *si, int idx) override
1912315SN/A    {
19212106SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->srcRegIdx(idx);
19312106SRekai.GonzalezAlberquilla@arm.com        assert(reg.isIntReg());
19412106SRekai.GonzalezAlberquilla@arm.com        return thread->readIntReg(reg.index());
1952315SN/A    }
1962315SN/A
19713557Sgabeblack@google.com    RegVal
19813557Sgabeblack@google.com    readFloatRegOperandBits(const StaticInst *si, int idx) override
1992669Sktlim@umich.edu    {
20012106SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->srcRegIdx(idx);
20112106SRekai.GonzalezAlberquilla@arm.com        assert(reg.isFloatReg());
20212106SRekai.GonzalezAlberquilla@arm.com        return thread->readFloatRegBits(reg.index());
2032315SN/A    }
2042315SN/A
20512109SRekai.GonzalezAlberquilla@arm.com    /**
20612109SRekai.GonzalezAlberquilla@arm.com     * Read source vector register operand.
20712109SRekai.GonzalezAlberquilla@arm.com     */
20813557Sgabeblack@google.com    const VecRegContainer &
20913557Sgabeblack@google.com    readVecRegOperand(const StaticInst *si, int idx) const override
21012109SRekai.GonzalezAlberquilla@arm.com    {
21112109SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->srcRegIdx(idx);
21212109SRekai.GonzalezAlberquilla@arm.com        assert(reg.isVecReg());
21312109SRekai.GonzalezAlberquilla@arm.com        return thread->readVecReg(reg);
21412109SRekai.GonzalezAlberquilla@arm.com    }
21512109SRekai.GonzalezAlberquilla@arm.com
21612109SRekai.GonzalezAlberquilla@arm.com    /**
21712109SRekai.GonzalezAlberquilla@arm.com     * Read destination vector register operand for modification.
21812109SRekai.GonzalezAlberquilla@arm.com     */
21913557Sgabeblack@google.com    VecRegContainer &
22013557Sgabeblack@google.com    getWritableVecRegOperand(const StaticInst *si, int idx) override
22112109SRekai.GonzalezAlberquilla@arm.com    {
22212109SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->destRegIdx(idx);
22312109SRekai.GonzalezAlberquilla@arm.com        assert(reg.isVecReg());
22412109SRekai.GonzalezAlberquilla@arm.com        return thread->getWritableVecReg(reg);
22512109SRekai.GonzalezAlberquilla@arm.com    }
22612109SRekai.GonzalezAlberquilla@arm.com
22712109SRekai.GonzalezAlberquilla@arm.com    /** Vector Register Lane Interfaces. */
22812109SRekai.GonzalezAlberquilla@arm.com    /** @{ */
22912109SRekai.GonzalezAlberquilla@arm.com    /** Reads source vector 8bit operand. */
23012109SRekai.GonzalezAlberquilla@arm.com    virtual ConstVecLane8
23113557Sgabeblack@google.com    readVec8BitLaneOperand(const StaticInst *si, int idx) const override
23212109SRekai.GonzalezAlberquilla@arm.com    {
23312109SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->destRegIdx(idx);
23412109SRekai.GonzalezAlberquilla@arm.com        assert(reg.isVecReg());
23512109SRekai.GonzalezAlberquilla@arm.com        return thread->readVec8BitLaneReg(reg);
23612109SRekai.GonzalezAlberquilla@arm.com    }
23712109SRekai.GonzalezAlberquilla@arm.com
23812109SRekai.GonzalezAlberquilla@arm.com    /** Reads source vector 16bit operand. */
23912109SRekai.GonzalezAlberquilla@arm.com    virtual ConstVecLane16
24013557Sgabeblack@google.com    readVec16BitLaneOperand(const StaticInst *si, int idx) const override
24112109SRekai.GonzalezAlberquilla@arm.com    {
24212109SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->destRegIdx(idx);
24312109SRekai.GonzalezAlberquilla@arm.com        assert(reg.isVecReg());
24412109SRekai.GonzalezAlberquilla@arm.com        return thread->readVec16BitLaneReg(reg);
24512109SRekai.GonzalezAlberquilla@arm.com    }
24612109SRekai.GonzalezAlberquilla@arm.com
24712109SRekai.GonzalezAlberquilla@arm.com    /** Reads source vector 32bit operand. */
24812109SRekai.GonzalezAlberquilla@arm.com    virtual ConstVecLane32
24913557Sgabeblack@google.com    readVec32BitLaneOperand(const StaticInst *si, int idx) const override
25012109SRekai.GonzalezAlberquilla@arm.com    {
25112109SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->destRegIdx(idx);
25212109SRekai.GonzalezAlberquilla@arm.com        assert(reg.isVecReg());
25312109SRekai.GonzalezAlberquilla@arm.com        return thread->readVec32BitLaneReg(reg);
25412109SRekai.GonzalezAlberquilla@arm.com    }
25512109SRekai.GonzalezAlberquilla@arm.com
25612109SRekai.GonzalezAlberquilla@arm.com    /** Reads source vector 64bit operand. */
25712109SRekai.GonzalezAlberquilla@arm.com    virtual ConstVecLane64
25813557Sgabeblack@google.com    readVec64BitLaneOperand(const StaticInst *si, int idx) const override
25912109SRekai.GonzalezAlberquilla@arm.com    {
26012109SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->destRegIdx(idx);
26112109SRekai.GonzalezAlberquilla@arm.com        assert(reg.isVecReg());
26212109SRekai.GonzalezAlberquilla@arm.com        return thread->readVec64BitLaneReg(reg);
26312109SRekai.GonzalezAlberquilla@arm.com    }
26412109SRekai.GonzalezAlberquilla@arm.com
26512109SRekai.GonzalezAlberquilla@arm.com    /** Write a lane of the destination vector operand. */
26612109SRekai.GonzalezAlberquilla@arm.com    template <typename LD>
26712109SRekai.GonzalezAlberquilla@arm.com    void
26812109SRekai.GonzalezAlberquilla@arm.com    setVecLaneOperandT(const StaticInst *si, int idx, const LD& val)
26912109SRekai.GonzalezAlberquilla@arm.com    {
27012109SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->destRegIdx(idx);
27112109SRekai.GonzalezAlberquilla@arm.com        assert(reg.isVecReg());
27212109SRekai.GonzalezAlberquilla@arm.com        return thread->setVecLane(reg, val);
27312109SRekai.GonzalezAlberquilla@arm.com    }
27412109SRekai.GonzalezAlberquilla@arm.com    virtual void
27512109SRekai.GonzalezAlberquilla@arm.com    setVecLaneOperand(const StaticInst *si, int idx,
27612109SRekai.GonzalezAlberquilla@arm.com            const LaneData<LaneSize::Byte>& val) override
27712109SRekai.GonzalezAlberquilla@arm.com    {
27812109SRekai.GonzalezAlberquilla@arm.com        setVecLaneOperandT(si, idx, val);
27912109SRekai.GonzalezAlberquilla@arm.com    }
28012109SRekai.GonzalezAlberquilla@arm.com    virtual void
28112109SRekai.GonzalezAlberquilla@arm.com    setVecLaneOperand(const StaticInst *si, int idx,
28212109SRekai.GonzalezAlberquilla@arm.com            const LaneData<LaneSize::TwoByte>& val) override
28312109SRekai.GonzalezAlberquilla@arm.com    {
28412109SRekai.GonzalezAlberquilla@arm.com        setVecLaneOperandT(si, idx, val);
28512109SRekai.GonzalezAlberquilla@arm.com    }
28612109SRekai.GonzalezAlberquilla@arm.com    virtual void
28712109SRekai.GonzalezAlberquilla@arm.com    setVecLaneOperand(const StaticInst *si, int idx,
28812109SRekai.GonzalezAlberquilla@arm.com            const LaneData<LaneSize::FourByte>& val) override
28912109SRekai.GonzalezAlberquilla@arm.com    {
29012109SRekai.GonzalezAlberquilla@arm.com        setVecLaneOperandT(si, idx, val);
29112109SRekai.GonzalezAlberquilla@arm.com    }
29212109SRekai.GonzalezAlberquilla@arm.com    virtual void
29312109SRekai.GonzalezAlberquilla@arm.com    setVecLaneOperand(const StaticInst *si, int idx,
29412109SRekai.GonzalezAlberquilla@arm.com            const LaneData<LaneSize::EightByte>& val) override
29512109SRekai.GonzalezAlberquilla@arm.com    {
29612109SRekai.GonzalezAlberquilla@arm.com        setVecLaneOperandT(si, idx, val);
29712109SRekai.GonzalezAlberquilla@arm.com    }
29812109SRekai.GonzalezAlberquilla@arm.com    /** @} */
29912109SRekai.GonzalezAlberquilla@arm.com
30013557Sgabeblack@google.com    VecElem
30113557Sgabeblack@google.com    readVecElemOperand(const StaticInst *si, int idx) const override
30212109SRekai.GonzalezAlberquilla@arm.com    {
30312109SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->srcRegIdx(idx);
30412109SRekai.GonzalezAlberquilla@arm.com        return thread->readVecElem(reg);
30512109SRekai.GonzalezAlberquilla@arm.com    }
30612109SRekai.GonzalezAlberquilla@arm.com
30713557Sgabeblack@google.com    CCReg
30813557Sgabeblack@google.com    readCCRegOperand(const StaticInst *si, int idx) override
3099920Syasuko.eckert@amd.com    {
31012106SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->srcRegIdx(idx);
31112106SRekai.GonzalezAlberquilla@arm.com        assert(reg.isCCReg());
31212106SRekai.GonzalezAlberquilla@arm.com        return thread->readCCReg(reg.index());
3139920Syasuko.eckert@amd.com    }
3149920Syasuko.eckert@amd.com
31512107SRekai.GonzalezAlberquilla@arm.com    template<typename T>
31613557Sgabeblack@google.com    void
31713557Sgabeblack@google.com    setScalarResult(T&& t)
3188733Sgeoffrey.blake@arm.com    {
31912107SRekai.GonzalezAlberquilla@arm.com        result.push(InstResult(std::forward<T>(t),
32013557Sgabeblack@google.com                               InstResult::ResultType::Scalar));
3218733Sgeoffrey.blake@arm.com    }
3228733Sgeoffrey.blake@arm.com
32312109SRekai.GonzalezAlberquilla@arm.com    template<typename T>
32413557Sgabeblack@google.com    void
32513557Sgabeblack@google.com    setVecResult(T&& t)
32612109SRekai.GonzalezAlberquilla@arm.com    {
32712109SRekai.GonzalezAlberquilla@arm.com        result.push(InstResult(std::forward<T>(t),
32813557Sgabeblack@google.com                               InstResult::ResultType::VecReg));
32912109SRekai.GonzalezAlberquilla@arm.com    }
33012109SRekai.GonzalezAlberquilla@arm.com
33112109SRekai.GonzalezAlberquilla@arm.com    template<typename T>
33213557Sgabeblack@google.com    void
33313557Sgabeblack@google.com    setVecElemResult(T&& t)
33412109SRekai.GonzalezAlberquilla@arm.com    {
33512109SRekai.GonzalezAlberquilla@arm.com        result.push(InstResult(std::forward<T>(t),
33613557Sgabeblack@google.com                               InstResult::ResultType::VecElem));
33712109SRekai.GonzalezAlberquilla@arm.com    }
33812109SRekai.GonzalezAlberquilla@arm.com
33913557Sgabeblack@google.com    void
34013557Sgabeblack@google.com    setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
3412315SN/A    {
34212106SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->destRegIdx(idx);
34312106SRekai.GonzalezAlberquilla@arm.com        assert(reg.isIntReg());
34412106SRekai.GonzalezAlberquilla@arm.com        thread->setIntReg(reg.index(), val);
34512107SRekai.GonzalezAlberquilla@arm.com        setScalarResult(val);
3462315SN/A    }
3472315SN/A
34813557Sgabeblack@google.com    void
34913557Sgabeblack@google.com    setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
3502315SN/A    {
35112106SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->destRegIdx(idx);
35212106SRekai.GonzalezAlberquilla@arm.com        assert(reg.isFloatReg());
35312106SRekai.GonzalezAlberquilla@arm.com        thread->setFloatRegBits(reg.index(), val);
35412107SRekai.GonzalezAlberquilla@arm.com        setScalarResult(val);
3552315SN/A    }
3562315SN/A
35713557Sgabeblack@google.com    void
35813557Sgabeblack@google.com    setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
3599920Syasuko.eckert@amd.com    {
36012106SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->destRegIdx(idx);
36112106SRekai.GonzalezAlberquilla@arm.com        assert(reg.isCCReg());
36212106SRekai.GonzalezAlberquilla@arm.com        thread->setCCReg(reg.index(), val);
36312107SRekai.GonzalezAlberquilla@arm.com        setScalarResult((uint64_t)val);
3649920Syasuko.eckert@amd.com    }
3659920Syasuko.eckert@amd.com
36613557Sgabeblack@google.com    void
36713557Sgabeblack@google.com    setVecRegOperand(const StaticInst *si, int idx,
36813557Sgabeblack@google.com                     const VecRegContainer& val) override
36912109SRekai.GonzalezAlberquilla@arm.com    {
37012109SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->destRegIdx(idx);
37112109SRekai.GonzalezAlberquilla@arm.com        assert(reg.isVecReg());
37212109SRekai.GonzalezAlberquilla@arm.com        thread->setVecReg(reg, val);
37312109SRekai.GonzalezAlberquilla@arm.com        setVecResult(val);
37412109SRekai.GonzalezAlberquilla@arm.com    }
37512109SRekai.GonzalezAlberquilla@arm.com
37613557Sgabeblack@google.com    void
37713557Sgabeblack@google.com    setVecElemOperand(const StaticInst *si, int idx,
37813557Sgabeblack@google.com                      const VecElem val) override
37912109SRekai.GonzalezAlberquilla@arm.com    {
38012109SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->destRegIdx(idx);
38112109SRekai.GonzalezAlberquilla@arm.com        assert(reg.isVecElem());
38212109SRekai.GonzalezAlberquilla@arm.com        thread->setVecElem(reg, val);
38312109SRekai.GonzalezAlberquilla@arm.com        setVecElemResult(val);
38412109SRekai.GonzalezAlberquilla@arm.com    }
38512109SRekai.GonzalezAlberquilla@arm.com
38613429Srekai.gonzalezalberquilla@arm.com    bool readPredicate() const override { return thread->readPredicate(); }
38713429Srekai.gonzalezalberquilla@arm.com
38813557Sgabeblack@google.com    void
38913557Sgabeblack@google.com    setPredicate(bool val) override
3908733Sgeoffrey.blake@arm.com    {
3918733Sgeoffrey.blake@arm.com        thread->setPredicate(val);
3928733Sgeoffrey.blake@arm.com    }
3932669Sktlim@umich.edu
39411169Sandreas.hansson@arm.com    TheISA::PCState pcState() const override { return thread->pcState(); }
39513557Sgabeblack@google.com    void
39613557Sgabeblack@google.com    pcState(const TheISA::PCState &val) override
3978733Sgeoffrey.blake@arm.com    {
3988733Sgeoffrey.blake@arm.com        DPRINTF(Checker, "Changing PC to %s, old PC %s.\n",
3998733Sgeoffrey.blake@arm.com                         val, thread->pcState());
4008733Sgeoffrey.blake@arm.com        thread->pcState(val);
4018733Sgeoffrey.blake@arm.com    }
4028733Sgeoffrey.blake@arm.com    Addr instAddr() { return thread->instAddr(); }
4038733Sgeoffrey.blake@arm.com    Addr nextInstAddr() { return thread->nextInstAddr(); }
4048733Sgeoffrey.blake@arm.com    MicroPC microPC() { return thread->microPC(); }
4058733Sgeoffrey.blake@arm.com    //////////////////////////////////////////
4062315SN/A
40713557Sgabeblack@google.com    RegVal
40813557Sgabeblack@google.com    readMiscRegNoEffect(int misc_reg) const
4094172Ssaidi@eecs.umich.edu    {
4104172Ssaidi@eecs.umich.edu        return thread->readMiscRegNoEffect(misc_reg);
4114172Ssaidi@eecs.umich.edu    }
4124172Ssaidi@eecs.umich.edu
41313557Sgabeblack@google.com    RegVal
41413557Sgabeblack@google.com    readMiscReg(int misc_reg) override
4152315SN/A    {
4162683Sktlim@umich.edu        return thread->readMiscReg(misc_reg);
4172315SN/A    }
4182315SN/A
41913557Sgabeblack@google.com    void
42013557Sgabeblack@google.com    setMiscRegNoEffect(int misc_reg, const RegVal &val)
4212315SN/A    {
42213557Sgabeblack@google.com        DPRINTF(Checker, "Setting misc reg %d with no effect to check later\n",
42313557Sgabeblack@google.com                misc_reg);
4244172Ssaidi@eecs.umich.edu        miscRegIdxs.push(misc_reg);
4254172Ssaidi@eecs.umich.edu        return thread->setMiscRegNoEffect(misc_reg, val);
4262315SN/A    }
4272315SN/A
42813557Sgabeblack@google.com    void
42913557Sgabeblack@google.com    setMiscReg(int misc_reg, const RegVal &val) override
4302315SN/A    {
43113557Sgabeblack@google.com        DPRINTF(Checker, "Setting misc reg %d with effect to check later\n",
43213557Sgabeblack@google.com                misc_reg);
4332315SN/A        miscRegIdxs.push(misc_reg);
4342683Sktlim@umich.edu        return thread->setMiscReg(misc_reg, val);
4352315SN/A    }
4362315SN/A
43713557Sgabeblack@google.com    RegVal
43813557Sgabeblack@google.com    readMiscRegOperand(const StaticInst *si, int idx) override
4398733Sgeoffrey.blake@arm.com    {
44012106SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->srcRegIdx(idx);
44112106SRekai.GonzalezAlberquilla@arm.com        assert(reg.isMiscReg());
44212106SRekai.GonzalezAlberquilla@arm.com        return thread->readMiscReg(reg.index());
4438733Sgeoffrey.blake@arm.com    }
4448733Sgeoffrey.blake@arm.com
44513557Sgabeblack@google.com    void
44613557Sgabeblack@google.com    setMiscRegOperand(const StaticInst *si, int idx,
44713557Sgabeblack@google.com                      const RegVal &val) override
4488733Sgeoffrey.blake@arm.com    {
44912106SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = si->destRegIdx(idx);
45012106SRekai.GonzalezAlberquilla@arm.com        assert(reg.isMiscReg());
45112106SRekai.GonzalezAlberquilla@arm.com        return this->setMiscReg(reg.index(), val);
4528733Sgeoffrey.blake@arm.com    }
4538888Sgeoffrey.blake@arm.com
4548888Sgeoffrey.blake@arm.com#if THE_ISA == MIPS_ISA
45513557Sgabeblack@google.com    RegVal
45613557Sgabeblack@google.com    readRegOtherThread(const RegId &misc_reg, ThreadID tid) override
4578888Sgeoffrey.blake@arm.com    {
4588888Sgeoffrey.blake@arm.com        panic("MIPS MT not defined for CheckerCPU.\n");
4598888Sgeoffrey.blake@arm.com        return 0;
4608888Sgeoffrey.blake@arm.com    }
4618888Sgeoffrey.blake@arm.com
46213557Sgabeblack@google.com    void
46313557Sgabeblack@google.com    setRegOtherThread(const RegId& misc_reg, RegVal val, ThreadID tid) override
4648888Sgeoffrey.blake@arm.com    {
4658888Sgeoffrey.blake@arm.com        panic("MIPS MT not defined for CheckerCPU.\n");
4668888Sgeoffrey.blake@arm.com    }
4678888Sgeoffrey.blake@arm.com#endif
4688888Sgeoffrey.blake@arm.com
4698733Sgeoffrey.blake@arm.com    /////////////////////////////////////////
4708733Sgeoffrey.blake@arm.com
47113557Sgabeblack@google.com    void
47213557Sgabeblack@google.com    recordPCChange(const TheISA::PCState &val)
4738733Sgeoffrey.blake@arm.com    {
4748733Sgeoffrey.blake@arm.com       changedPC = true;
4758733Sgeoffrey.blake@arm.com       newPCState = val;
4768733Sgeoffrey.blake@arm.com    }
4772315SN/A
47813557Sgabeblack@google.com    void
47913557Sgabeblack@google.com    demapPage(Addr vaddr, uint64_t asn) override
4805358Sgblack@eecs.umich.edu    {
4815358Sgblack@eecs.umich.edu        this->itb->demapPage(vaddr, asn);
4825358Sgblack@eecs.umich.edu        this->dtb->demapPage(vaddr, asn);
4835358Sgblack@eecs.umich.edu    }
4845358Sgblack@eecs.umich.edu
48510529Smorr@cs.wisc.edu    // monitor/mwait funtions
48613557Sgabeblack@google.com    void armMonitor(Addr address) override { BaseCPU::armMonitor(0, address); }
48711169Sandreas.hansson@arm.com    bool mwait(PacketPtr pkt) override { return BaseCPU::mwait(0, pkt); }
48811169Sandreas.hansson@arm.com    void mwaitAtomic(ThreadContext *tc) override
48911148Smitch.hayenga@arm.com    { return BaseCPU::mwaitAtomic(0, tc, thread->dtb); }
49011169Sandreas.hansson@arm.com    AddressMonitor *getAddrMonitor() override
49111169Sandreas.hansson@arm.com    { return BaseCPU::getCpuAddrMonitor(0); }
49210529Smorr@cs.wisc.edu
49313557Sgabeblack@google.com    void
49413557Sgabeblack@google.com    demapInstPage(Addr vaddr, uint64_t asn)
4955358Sgblack@eecs.umich.edu    {
4965358Sgblack@eecs.umich.edu        this->itb->demapPage(vaddr, asn);
4975358Sgblack@eecs.umich.edu    }
4985358Sgblack@eecs.umich.edu
49913557Sgabeblack@google.com    void
50013557Sgabeblack@google.com    demapDataPage(Addr vaddr, uint64_t asn)
5015358Sgblack@eecs.umich.edu    {
5025358Sgblack@eecs.umich.edu        this->dtb->demapPage(vaddr, asn);
5035358Sgblack@eecs.umich.edu    }
5045358Sgblack@eecs.umich.edu
50511169Sandreas.hansson@arm.com    Fault readMem(Addr addr, uint8_t *data, unsigned size,
50611608Snikos.nikoleris@arm.com                  Request::Flags flags) override;
50711608Snikos.nikoleris@arm.com    Fault writeMem(uint8_t *data, unsigned size, Addr addr,
50811608Snikos.nikoleris@arm.com                   Request::Flags flags, uint64_t *res) override;
5098733Sgeoffrey.blake@arm.com
51013557Sgabeblack@google.com    unsigned int
51113557Sgabeblack@google.com    readStCondFailures() const override {
51210319SAndreas.Sandberg@ARM.com        return thread->readStCondFailures();
51310319SAndreas.Sandberg@ARM.com    }
51410319SAndreas.Sandberg@ARM.com
51513557Sgabeblack@google.com    void setStCondFailures(unsigned int sc_failures) override {}
5168733Sgeoffrey.blake@arm.com    /////////////////////////////////////////////////////
5178733Sgeoffrey.blake@arm.com
51811169Sandreas.hansson@arm.com    Fault hwrei() override { return thread->hwrei(); }
51911169Sandreas.hansson@arm.com    bool simPalCheck(int palFunc) override
52011169Sandreas.hansson@arm.com    { return thread->simPalCheck(palFunc); }
52111168Sandreas.hansson@arm.com    void wakeup(ThreadID tid) override { }
5222315SN/A    // Assume that the normal CPU's call to syscall was successful.
5232332SN/A    // The checker's state would have already been updated by the syscall.
52411877Sbrandon.potter@amd.com    void syscall(int64_t callnum, Fault *fault) override { }
5252315SN/A
52613557Sgabeblack@google.com    void
52713557Sgabeblack@google.com    handleError()
5282315SN/A    {
5292315SN/A        if (exitOnError)
5302732Sktlim@umich.edu            dumpAndExit();
5312315SN/A    }
5322732Sktlim@umich.edu
53312749Sgiacomo.travaglini@arm.com    bool checkFlags(const RequestPtr &unverified_req, Addr vAddr,
5348733Sgeoffrey.blake@arm.com                    Addr pAddr, int flags);
5352315SN/A
5362732Sktlim@umich.edu    void dumpAndExit();
5372732Sktlim@umich.edu
53811169Sandreas.hansson@arm.com    ThreadContext *tcBase() override { return tc; }
5392683Sktlim@umich.edu    SimpleThread *threadBase() { return thread; }
5402315SN/A
54112107SRekai.GonzalezAlberquilla@arm.com    InstResult unverifiedResult;
54212748Sgiacomo.travaglini@arm.com    RequestPtr unverifiedReq;
5432679Sktlim@umich.edu    uint8_t *unverifiedMemData;
5442315SN/A
5452315SN/A    bool changedPC;
5462315SN/A    bool willChangePC;
5478733Sgeoffrey.blake@arm.com    TheISA::PCState newPCState;
5482315SN/A    bool exitOnError;
5492354SN/A    bool updateOnError;
5502732Sktlim@umich.edu    bool warnOnlyOnLoadError;
5512315SN/A
5522315SN/A    InstSeqNum youngestSN;
5532315SN/A};
5542315SN/A
5552350SN/A/**
5562350SN/A * Templated Checker class.  This Checker class is templated on the
5572350SN/A * DynInstPtr of the instruction type that will be verified.  Proper
5582350SN/A * template instantiations of the Checker must be placed at the bottom
5592350SN/A * of checker/cpu.cc.
5602350SN/A */
5618733Sgeoffrey.blake@arm.comtemplate <class Impl>
5622315SN/Aclass Checker : public CheckerCPU
5632315SN/A{
5648733Sgeoffrey.blake@arm.com  private:
5658733Sgeoffrey.blake@arm.com    typedef typename Impl::DynInstPtr DynInstPtr;
5668733Sgeoffrey.blake@arm.com
5672315SN/A  public:
5682315SN/A    Checker(Params *p)
5699023Sgblack@eecs.umich.edu        : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL)
5702315SN/A    { }
5712315SN/A
5722840Sktlim@umich.edu    void switchOut();
5732315SN/A    void takeOverFrom(BaseCPU *oldCPU);
5742315SN/A
57510379Sandreas.hansson@arm.com    void advancePC(const Fault &fault);
5768733Sgeoffrey.blake@arm.com
57713429Srekai.gonzalezalberquilla@arm.com    void verify(const DynInstPtr &inst);
5782315SN/A
57913429Srekai.gonzalezalberquilla@arm.com    void validateInst(const DynInstPtr &inst);
58013429Srekai.gonzalezalberquilla@arm.com    void validateExecution(const DynInstPtr &inst);
5812315SN/A    void validateState();
5822315SN/A
58313429Srekai.gonzalezalberquilla@arm.com    void copyResult(const DynInstPtr &inst, const InstResult& mismatch_val,
58412107SRekai.GonzalezAlberquilla@arm.com                    int start_idx);
5858733Sgeoffrey.blake@arm.com    void handlePendingInt();
5862732Sktlim@umich.edu
5872732Sktlim@umich.edu  private:
58813429Srekai.gonzalezalberquilla@arm.com    void handleError(const DynInstPtr &inst)
5892732Sktlim@umich.edu    {
5902360SN/A        if (exitOnError) {
5912732Sktlim@umich.edu            dumpAndExit(inst);
5922360SN/A        } else if (updateOnError) {
5932354SN/A            updateThisCycle = true;
5942360SN/A        }
5952732Sktlim@umich.edu    }
5962732Sktlim@umich.edu
59713429Srekai.gonzalezalberquilla@arm.com    void dumpAndExit(const DynInstPtr &inst);
5982732Sktlim@umich.edu
5992354SN/A    bool updateThisCycle;
6002354SN/A
6012354SN/A    DynInstPtr unverifiedInst;
6022354SN/A
6032315SN/A    std::list<DynInstPtr> instList;
6042315SN/A    typedef typename std::list<DynInstPtr>::iterator InstListIt;
6052315SN/A    void dumpInsts();
6062315SN/A};
6072315SN/A
6082315SN/A#endif // __CPU_CHECKER_CPU_HH__
609