cpu.hh revision 13953
17753SWilliam.Wang@arm.com/* 210839Sandreas.sandberg@arm.com * Copyright (c) 2011, 2016-2018 ARM Limited 37753SWilliam.Wang@arm.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 47753SWilliam.Wang@arm.com * All rights reserved 57753SWilliam.Wang@arm.com * 67753SWilliam.Wang@arm.com * The license below extends only to copyright in the software and shall 77753SWilliam.Wang@arm.com * not be construed as granting a license to any other intellectual 87753SWilliam.Wang@arm.com * property including but not limited to intellectual property relating 97753SWilliam.Wang@arm.com * to a hardware implementation of the functionality of the software 107753SWilliam.Wang@arm.com * licensed hereunder. You may use the software subject to the license 117753SWilliam.Wang@arm.com * terms below provided that you ensure that this notice is replicated 127753SWilliam.Wang@arm.com * unmodified and in its entirety in all distributions of the software, 137753SWilliam.Wang@arm.com * modified or unmodified, in source code or in binary form. 147753SWilliam.Wang@arm.com * 157753SWilliam.Wang@arm.com * Copyright (c) 2006 The Regents of The University of Michigan 167753SWilliam.Wang@arm.com * All rights reserved. 177753SWilliam.Wang@arm.com * 187753SWilliam.Wang@arm.com * Redistribution and use in source and binary forms, with or without 197753SWilliam.Wang@arm.com * modification, are permitted provided that the following conditions are 207753SWilliam.Wang@arm.com * met: redistributions of source code must retain the above copyright 217753SWilliam.Wang@arm.com * notice, this list of conditions and the following disclaimer; 227753SWilliam.Wang@arm.com * redistributions in binary form must reproduce the above copyright 237753SWilliam.Wang@arm.com * notice, this list of conditions and the following disclaimer in the 247753SWilliam.Wang@arm.com * documentation and/or other materials provided with the distribution; 257753SWilliam.Wang@arm.com * neither the name of the copyright holders nor the names of its 267753SWilliam.Wang@arm.com * contributors may be used to endorse or promote products derived from 277753SWilliam.Wang@arm.com * this software without specific prior written permission. 287753SWilliam.Wang@arm.com * 297753SWilliam.Wang@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 307753SWilliam.Wang@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 317753SWilliam.Wang@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 327753SWilliam.Wang@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 337753SWilliam.Wang@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 347753SWilliam.Wang@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 357753SWilliam.Wang@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 367753SWilliam.Wang@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 377753SWilliam.Wang@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 387950SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 397753SWilliam.Wang@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 407753SWilliam.Wang@arm.com * 4111793Sbrandon.potter@amd.com * Authors: Kevin Lim 4211793Sbrandon.potter@amd.com */ 437950SAli.Saidi@ARM.com 447753SWilliam.Wang@arm.com#ifndef __CPU_CHECKER_CPU_HH__ 4511793Sbrandon.potter@amd.com#define __CPU_CHECKER_CPU_HH__ 468245Snate@binkert.org 478245Snate@binkert.org#include <list> 487753SWilliam.Wang@arm.com#include <map> 499525SAndreas.Sandberg@ARM.com#include <queue> 507753SWilliam.Wang@arm.com 517753SWilliam.Wang@arm.com#include "arch/types.hh" 529525SAndreas.Sandberg@ARM.com#include "base/statistics.hh" 537753SWilliam.Wang@arm.com#include "cpu/base.hh" 548737Skoansin.tan@gmail.com#include "cpu/base_dyn_inst.hh" 558737Skoansin.tan@gmail.com#include "cpu/exec_context.hh" 568737Skoansin.tan@gmail.com#include "cpu/inst_res.hh" 578737Skoansin.tan@gmail.com#include "cpu/pc_event.hh" 587753SWilliam.Wang@arm.com#include "cpu/simple_thread.hh" 597753SWilliam.Wang@arm.com#include "cpu/static_inst.hh" 607753SWilliam.Wang@arm.com#include "debug/Checker.hh" 617753SWilliam.Wang@arm.com#include "mem/request.hh" 627950SAli.Saidi@ARM.com#include "params/CheckerCPU.hh" 637753SWilliam.Wang@arm.com#include "sim/eventq.hh" 647753SWilliam.Wang@arm.com 659157Sandreas.hansson@arm.comclass BaseTLB; 6610839Sandreas.sandberg@arm.comtemplate <class> 6710839Sandreas.sandberg@arm.comclass BaseDynInst; 6810839Sandreas.sandberg@arm.comclass ThreadContext; 699530SChris.Emmons@arm.comclass Request; 707950SAli.Saidi@ARM.com 7112086Sspwilson2@wisc.edu/** 7212086Sspwilson2@wisc.edu * CheckerCPU class. Dynamically verifies instructions as they are 7312086Sspwilson2@wisc.edu * completed by making sure that the instruction and its results match 749395SAndreas.Sandberg@ARM.com * the independent execution of the benchmark inside the checker. The 759395SAndreas.Sandberg@ARM.com * checker verifies instructions in order, regardless of the order in 7612086Sspwilson2@wisc.edu * which instructions complete. There are certain results that can 7712086Sspwilson2@wisc.edu * not be verified, specifically the result of a store conditional or 787753SWilliam.Wang@arm.com * the values of uncached accesses. In these cases, and with 797753SWilliam.Wang@arm.com * instructions marked as "IsUnverifiable", the checker assumes that 807753SWilliam.Wang@arm.com * the value from the main CPU's execution is correct and simply 818737Skoansin.tan@gmail.com * copies that value. It provides a CheckerThreadContext (see 827950SAli.Saidi@ARM.com * checker/thread_context.hh) that provides hooks for updating the 837753SWilliam.Wang@arm.com * Checker's state through any ThreadContext accesses. This allows the 847753SWilliam.Wang@arm.com * checker to be able to correctly verify instructions, even with 858737Skoansin.tan@gmail.com * external accesses to the ThreadContext that change state. 867950SAli.Saidi@ARM.com */ 879395SAndreas.Sandberg@ARM.comclass CheckerCPU : public BaseCPU, public ExecContext 889395SAndreas.Sandberg@ARM.com{ 899395SAndreas.Sandberg@ARM.com protected: 909330Schander.sudanthi@arm.com typedef TheISA::MachInst MachInst; 9110839Sandreas.sandberg@arm.com using VecRegContainer = TheISA::VecRegContainer; 927753SWilliam.Wang@arm.com 937753SWilliam.Wang@arm.com /** id attached to all issued requests */ 949086Sandreas.hansson@arm.com MasterID masterId; 959086Sandreas.hansson@arm.com public: 969086Sandreas.hansson@arm.com void init() override; 979086Sandreas.hansson@arm.com 989086Sandreas.hansson@arm.com typedef CheckerCPUParams Params; 997753SWilliam.Wang@arm.com CheckerCPU(Params *p); 1007753SWilliam.Wang@arm.com virtual ~CheckerCPU(); 1017753SWilliam.Wang@arm.com 1027753SWilliam.Wang@arm.com void setSystem(System *system); 1037753SWilliam.Wang@arm.com 1047753SWilliam.Wang@arm.com void setIcachePort(MasterPort *icache_port); 1057753SWilliam.Wang@arm.com 1067753SWilliam.Wang@arm.com void setDcachePort(MasterPort *dcache_port); 1077753SWilliam.Wang@arm.com 1087950SAli.Saidi@ARM.com MasterPort &getDataPort() override 1097950SAli.Saidi@ARM.com { 1107753SWilliam.Wang@arm.com // the checker does not have ports on its own so return the 1117950SAli.Saidi@ARM.com // data port of the actual CPU core 1127753SWilliam.Wang@arm.com assert(dcachePort); 1137950SAli.Saidi@ARM.com return *dcachePort; 1147753SWilliam.Wang@arm.com } 1157950SAli.Saidi@ARM.com 1167950SAli.Saidi@ARM.com MasterPort &getInstPort() override 1177950SAli.Saidi@ARM.com { 1187950SAli.Saidi@ARM.com // the checker does not have ports on its own so return the 1197950SAli.Saidi@ARM.com // data port of the actual CPU core 1207950SAli.Saidi@ARM.com assert(icachePort); 1217950SAli.Saidi@ARM.com return *icachePort; 1227950SAli.Saidi@ARM.com } 1237950SAli.Saidi@ARM.com 1247950SAli.Saidi@ARM.com protected: 1257950SAli.Saidi@ARM.com 1267950SAli.Saidi@ARM.com std::vector<Process*> workload; 1277950SAli.Saidi@ARM.com 1287950SAli.Saidi@ARM.com System *systemPtr; 1297950SAli.Saidi@ARM.com 1307950SAli.Saidi@ARM.com MasterPort *icachePort; 1317950SAli.Saidi@ARM.com MasterPort *dcachePort; 1327950SAli.Saidi@ARM.com 1337950SAli.Saidi@ARM.com ThreadContext *tc; 1347950SAli.Saidi@ARM.com 1357950SAli.Saidi@ARM.com BaseTLB *itb; 1367950SAli.Saidi@ARM.com BaseTLB *dtb; 1377950SAli.Saidi@ARM.com 1387950SAli.Saidi@ARM.com Addr dbg_vtophys(Addr addr); 1397950SAli.Saidi@ARM.com 1407950SAli.Saidi@ARM.com // ISAs like ARM can have multiple destination registers to check, 1417950SAli.Saidi@ARM.com // keep them all in a std::queue 1427950SAli.Saidi@ARM.com std::queue<InstResult> result; 1437950SAli.Saidi@ARM.com 1447950SAli.Saidi@ARM.com StaticInstPtr curStaticInst; 1457950SAli.Saidi@ARM.com StaticInstPtr curMacroStaticInst; 1467950SAli.Saidi@ARM.com 1477950SAli.Saidi@ARM.com // number of simulated instructions 1487950SAli.Saidi@ARM.com Counter numInst; 1497950SAli.Saidi@ARM.com Counter startNumInst; 1507950SAli.Saidi@ARM.com 1517950SAli.Saidi@ARM.com std::queue<int> miscRegIdxs; 1527950SAli.Saidi@ARM.com 1537950SAli.Saidi@ARM.com public: 1547950SAli.Saidi@ARM.com 1557950SAli.Saidi@ARM.com // Primary thread being run. 1567950SAli.Saidi@ARM.com SimpleThread *thread; 1577950SAli.Saidi@ARM.com 1587950SAli.Saidi@ARM.com BaseTLB* getITBPtr() { return itb; } 1597950SAli.Saidi@ARM.com BaseTLB* getDTBPtr() { return dtb; } 1607950SAli.Saidi@ARM.com 1617950SAli.Saidi@ARM.com virtual Counter totalInsts() const override 1627950SAli.Saidi@ARM.com { 1637950SAli.Saidi@ARM.com return 0; 1647950SAli.Saidi@ARM.com } 1657950SAli.Saidi@ARM.com 1667950SAli.Saidi@ARM.com virtual Counter totalOps() const override 1677950SAli.Saidi@ARM.com { 1687950SAli.Saidi@ARM.com return 0; 1697950SAli.Saidi@ARM.com } 1707950SAli.Saidi@ARM.com 1717950SAli.Saidi@ARM.com // number of simulated loads 1727950SAli.Saidi@ARM.com Counter numLoad; 1737950SAli.Saidi@ARM.com Counter startNumLoad; 1747950SAli.Saidi@ARM.com 1757950SAli.Saidi@ARM.com void serialize(CheckpointOut &cp) const override; 1767950SAli.Saidi@ARM.com void unserialize(CheckpointIn &cp) override; 1777950SAli.Saidi@ARM.com 1787950SAli.Saidi@ARM.com // The register accessor methods provide the index of the 1797950SAli.Saidi@ARM.com // instruction's operand (e.g., 0 or 1), not the architectural 1807950SAli.Saidi@ARM.com // register index, to simplify the implementation of register 1817950SAli.Saidi@ARM.com // renaming. We find the architectural register index by indexing 1827950SAli.Saidi@ARM.com // into the instruction's own operand index table. Note that a 1837950SAli.Saidi@ARM.com // raw pointer to the StaticInst is provided instead of a 1847950SAli.Saidi@ARM.com // ref-counted StaticInstPtr to redice overhead. This is fine as 1857950SAli.Saidi@ARM.com // long as these methods don't copy the pointer into any long-term 1869806Sstever@gmail.com // storage (which is pretty hard to imagine they would have reason 1877950SAli.Saidi@ARM.com // to do). 18813230Sgabeblack@google.com 1897753SWilliam.Wang@arm.com RegVal 1907950SAli.Saidi@ARM.com readIntRegOperand(const StaticInst *si, int idx) override 1917950SAli.Saidi@ARM.com { 1927950SAli.Saidi@ARM.com const RegId& reg = si->srcRegIdx(idx); 1937950SAli.Saidi@ARM.com assert(reg.isIntReg()); 1947950SAli.Saidi@ARM.com return thread->readIntReg(reg.index()); 1957753SWilliam.Wang@arm.com } 1967950SAli.Saidi@ARM.com 1977950SAli.Saidi@ARM.com RegVal 1987950SAli.Saidi@ARM.com readFloatRegOperandBits(const StaticInst *si, int idx) override 1997950SAli.Saidi@ARM.com { 2007950SAli.Saidi@ARM.com const RegId& reg = si->srcRegIdx(idx); 2017753SWilliam.Wang@arm.com assert(reg.isFloatReg()); 2027950SAli.Saidi@ARM.com return thread->readFloatReg(reg.index()); 20310367SAndrew.Bardsley@arm.com } 20410367SAndrew.Bardsley@arm.com 2057753SWilliam.Wang@arm.com /** 2067753SWilliam.Wang@arm.com * Read source vector register operand. 2077753SWilliam.Wang@arm.com */ 2087753SWilliam.Wang@arm.com const VecRegContainer & 2097753SWilliam.Wang@arm.com readVecRegOperand(const StaticInst *si, int idx) const override 2107753SWilliam.Wang@arm.com { 21113230Sgabeblack@google.com const RegId& reg = si->srcRegIdx(idx); 2127753SWilliam.Wang@arm.com assert(reg.isVecReg()); 2137753SWilliam.Wang@arm.com return thread->readVecReg(reg); 21413230Sgabeblack@google.com } 2157753SWilliam.Wang@arm.com 2167753SWilliam.Wang@arm.com /** 21713230Sgabeblack@google.com * Read destination vector register operand for modification. 2187753SWilliam.Wang@arm.com */ 2197753SWilliam.Wang@arm.com VecRegContainer & 2207753SWilliam.Wang@arm.com getWritableVecRegOperand(const StaticInst *si, int idx) override 2217753SWilliam.Wang@arm.com { 2227753SWilliam.Wang@arm.com const RegId& reg = si->destRegIdx(idx); 2237753SWilliam.Wang@arm.com assert(reg.isVecReg()); 2247753SWilliam.Wang@arm.com return thread->getWritableVecReg(reg); 2257753SWilliam.Wang@arm.com } 2267753SWilliam.Wang@arm.com 2277753SWilliam.Wang@arm.com /** Vector Register Lane Interfaces. */ 2287753SWilliam.Wang@arm.com /** @{ */ 2297753SWilliam.Wang@arm.com /** Reads source vector 8bit operand. */ 2307753SWilliam.Wang@arm.com virtual ConstVecLane8 2317753SWilliam.Wang@arm.com readVec8BitLaneOperand(const StaticInst *si, int idx) const override 2327753SWilliam.Wang@arm.com { 2337753SWilliam.Wang@arm.com const RegId& reg = si->destRegIdx(idx); 2347753SWilliam.Wang@arm.com assert(reg.isVecReg()); 2357753SWilliam.Wang@arm.com return thread->readVec8BitLaneReg(reg); 2367753SWilliam.Wang@arm.com } 2377753SWilliam.Wang@arm.com 2387753SWilliam.Wang@arm.com /** Reads source vector 16bit operand. */ 23913230Sgabeblack@google.com virtual ConstVecLane16 2407753SWilliam.Wang@arm.com readVec16BitLaneOperand(const StaticInst *si, int idx) const override 2417753SWilliam.Wang@arm.com { 24213230Sgabeblack@google.com const RegId& reg = si->destRegIdx(idx); 2437753SWilliam.Wang@arm.com assert(reg.isVecReg()); 2447753SWilliam.Wang@arm.com return thread->readVec16BitLaneReg(reg); 24513230Sgabeblack@google.com } 2467753SWilliam.Wang@arm.com 2477753SWilliam.Wang@arm.com /** Reads source vector 32bit operand. */ 2487753SWilliam.Wang@arm.com virtual ConstVecLane32 2497753SWilliam.Wang@arm.com readVec32BitLaneOperand(const StaticInst *si, int idx) const override 2507753SWilliam.Wang@arm.com { 2517753SWilliam.Wang@arm.com const RegId& reg = si->destRegIdx(idx); 2527950SAli.Saidi@ARM.com assert(reg.isVecReg()); 2537950SAli.Saidi@ARM.com return thread->readVec32BitLaneReg(reg); 2547753SWilliam.Wang@arm.com } 2557950SAli.Saidi@ARM.com 2567753SWilliam.Wang@arm.com /** Reads source vector 64bit operand. */ 2577950SAli.Saidi@ARM.com virtual ConstVecLane64 25813230Sgabeblack@google.com readVec64BitLaneOperand(const StaticInst *si, int idx) const override 2597753SWilliam.Wang@arm.com { 2607950SAli.Saidi@ARM.com const RegId& reg = si->destRegIdx(idx); 2617950SAli.Saidi@ARM.com assert(reg.isVecReg()); 2627950SAli.Saidi@ARM.com return thread->readVec64BitLaneReg(reg); 2637950SAli.Saidi@ARM.com } 2647950SAli.Saidi@ARM.com 2657950SAli.Saidi@ARM.com /** Write a lane of the destination vector operand. */ 2667950SAli.Saidi@ARM.com template <typename LD> 2677950SAli.Saidi@ARM.com void 2687950SAli.Saidi@ARM.com setVecLaneOperandT(const StaticInst *si, int idx, const LD& val) 2697950SAli.Saidi@ARM.com { 2707950SAli.Saidi@ARM.com const RegId& reg = si->destRegIdx(idx); 2717950SAli.Saidi@ARM.com assert(reg.isVecReg()); 2727950SAli.Saidi@ARM.com return thread->setVecLane(reg, val); 2737950SAli.Saidi@ARM.com } 2747950SAli.Saidi@ARM.com virtual void 2757950SAli.Saidi@ARM.com setVecLaneOperand(const StaticInst *si, int idx, 2767950SAli.Saidi@ARM.com const LaneData<LaneSize::Byte>& val) override 2777950SAli.Saidi@ARM.com { 2787950SAli.Saidi@ARM.com setVecLaneOperandT(si, idx, val); 2797950SAli.Saidi@ARM.com } 2807950SAli.Saidi@ARM.com virtual void 2817950SAli.Saidi@ARM.com setVecLaneOperand(const StaticInst *si, int idx, 2828508SAli.Saidi@ARM.com const LaneData<LaneSize::TwoByte>& val) override 2837950SAli.Saidi@ARM.com { 2847950SAli.Saidi@ARM.com setVecLaneOperandT(si, idx, val); 2857950SAli.Saidi@ARM.com } 2867950SAli.Saidi@ARM.com virtual void 2877950SAli.Saidi@ARM.com setVecLaneOperand(const StaticInst *si, int idx, 2887950SAli.Saidi@ARM.com const LaneData<LaneSize::FourByte>& val) override 2897950SAli.Saidi@ARM.com { 2907753SWilliam.Wang@arm.com setVecLaneOperandT(si, idx, val); 2917950SAli.Saidi@ARM.com } 2927950SAli.Saidi@ARM.com virtual void 2937950SAli.Saidi@ARM.com setVecLaneOperand(const StaticInst *si, int idx, 2947950SAli.Saidi@ARM.com const LaneData<LaneSize::EightByte>& val) override 2957950SAli.Saidi@ARM.com { 2967950SAli.Saidi@ARM.com setVecLaneOperandT(si, idx, val); 2977950SAli.Saidi@ARM.com } 2987950SAli.Saidi@ARM.com /** @} */ 2997950SAli.Saidi@ARM.com 3007950SAli.Saidi@ARM.com VecElem 3017950SAli.Saidi@ARM.com readVecElemOperand(const StaticInst *si, int idx) const override 3027950SAli.Saidi@ARM.com { 3037950SAli.Saidi@ARM.com const RegId& reg = si->srcRegIdx(idx); 3047950SAli.Saidi@ARM.com return thread->readVecElem(reg); 3057950SAli.Saidi@ARM.com } 3067950SAli.Saidi@ARM.com 3077950SAli.Saidi@ARM.com const VecPredRegContainer& 3087950SAli.Saidi@ARM.com readVecPredRegOperand(const StaticInst *si, int idx) const override 3097950SAli.Saidi@ARM.com { 3107950SAli.Saidi@ARM.com const RegId& reg = si->srcRegIdx(idx); 3117950SAli.Saidi@ARM.com assert(reg.isVecPredReg()); 3127950SAli.Saidi@ARM.com return thread->readVecPredReg(reg); 3137950SAli.Saidi@ARM.com } 3147950SAli.Saidi@ARM.com 3157950SAli.Saidi@ARM.com VecPredRegContainer& 3167950SAli.Saidi@ARM.com getWritableVecPredRegOperand(const StaticInst *si, int idx) override 3177950SAli.Saidi@ARM.com { 3187950SAli.Saidi@ARM.com const RegId& reg = si->destRegIdx(idx); 3197950SAli.Saidi@ARM.com assert(reg.isVecPredReg()); 3207950SAli.Saidi@ARM.com return thread->getWritableVecPredReg(reg); 3217950SAli.Saidi@ARM.com } 3227950SAli.Saidi@ARM.com 3237950SAli.Saidi@ARM.com RegVal 3247950SAli.Saidi@ARM.com readCCRegOperand(const StaticInst *si, int idx) override 3257950SAli.Saidi@ARM.com { 3267950SAli.Saidi@ARM.com const RegId& reg = si->srcRegIdx(idx); 3277950SAli.Saidi@ARM.com assert(reg.isCCReg()); 3287950SAli.Saidi@ARM.com return thread->readCCReg(reg.index()); 3297950SAli.Saidi@ARM.com } 3307950SAli.Saidi@ARM.com 3317950SAli.Saidi@ARM.com template<typename T> 3327950SAli.Saidi@ARM.com void 3337950SAli.Saidi@ARM.com setScalarResult(T&& t) 3347950SAli.Saidi@ARM.com { 3357950SAli.Saidi@ARM.com result.push(InstResult(std::forward<T>(t), 3367950SAli.Saidi@ARM.com InstResult::ResultType::Scalar)); 3377950SAli.Saidi@ARM.com } 3387950SAli.Saidi@ARM.com 3397950SAli.Saidi@ARM.com template<typename T> 3407950SAli.Saidi@ARM.com void 3417950SAli.Saidi@ARM.com setVecResult(T&& t) 3427950SAli.Saidi@ARM.com { 3437950SAli.Saidi@ARM.com result.push(InstResult(std::forward<T>(t), 3447950SAli.Saidi@ARM.com InstResult::ResultType::VecReg)); 3457950SAli.Saidi@ARM.com } 3467950SAli.Saidi@ARM.com 3477950SAli.Saidi@ARM.com template<typename T> 3487950SAli.Saidi@ARM.com void 3497950SAli.Saidi@ARM.com setVecElemResult(T&& t) 3507950SAli.Saidi@ARM.com { 3517950SAli.Saidi@ARM.com result.push(InstResult(std::forward<T>(t), 3527950SAli.Saidi@ARM.com InstResult::ResultType::VecElem)); 3537950SAli.Saidi@ARM.com } 3547950SAli.Saidi@ARM.com 3557950SAli.Saidi@ARM.com template<typename T> 3567950SAli.Saidi@ARM.com void 3577950SAli.Saidi@ARM.com setVecPredResult(T&& t) 3587950SAli.Saidi@ARM.com { 3597950SAli.Saidi@ARM.com result.push(InstResult(std::forward<T>(t), 3607950SAli.Saidi@ARM.com InstResult::ResultType::VecPredReg)); 3617950SAli.Saidi@ARM.com } 3627950SAli.Saidi@ARM.com 3637950SAli.Saidi@ARM.com void 3647950SAli.Saidi@ARM.com setIntRegOperand(const StaticInst *si, int idx, RegVal val) override 3657950SAli.Saidi@ARM.com { 3667950SAli.Saidi@ARM.com const RegId& reg = si->destRegIdx(idx); 3677950SAli.Saidi@ARM.com assert(reg.isIntReg()); 3687753SWilliam.Wang@arm.com thread->setIntReg(reg.index(), val); 3697950SAli.Saidi@ARM.com setScalarResult(val); 3707950SAli.Saidi@ARM.com } 3717950SAli.Saidi@ARM.com 3727950SAli.Saidi@ARM.com void 3737950SAli.Saidi@ARM.com setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override 3747753SWilliam.Wang@arm.com { 3757950SAli.Saidi@ARM.com const RegId& reg = si->destRegIdx(idx); 37610367SAndrew.Bardsley@arm.com assert(reg.isFloatReg()); 37710367SAndrew.Bardsley@arm.com thread->setFloatReg(reg.index(), val); 3787753SWilliam.Wang@arm.com setScalarResult(val); 3797753SWilliam.Wang@arm.com } 3807753SWilliam.Wang@arm.com 3817753SWilliam.Wang@arm.com void 3827753SWilliam.Wang@arm.com setCCRegOperand(const StaticInst *si, int idx, RegVal val) override 3837753SWilliam.Wang@arm.com { 3847753SWilliam.Wang@arm.com const RegId& reg = si->destRegIdx(idx); 3857753SWilliam.Wang@arm.com assert(reg.isCCReg()); 38610839Sandreas.sandberg@arm.com thread->setCCReg(reg.index(), val); 38710839Sandreas.sandberg@arm.com setScalarResult((uint64_t)val); 38810839Sandreas.sandberg@arm.com } 38910839Sandreas.sandberg@arm.com 39010839Sandreas.sandberg@arm.com void 39110839Sandreas.sandberg@arm.com setVecRegOperand(const StaticInst *si, int idx, 39210839Sandreas.sandberg@arm.com const VecRegContainer& val) override 39310839Sandreas.sandberg@arm.com { 39410839Sandreas.sandberg@arm.com const RegId& reg = si->destRegIdx(idx); 39510839Sandreas.sandberg@arm.com assert(reg.isVecReg()); 39610839Sandreas.sandberg@arm.com thread->setVecReg(reg, val); 39710839Sandreas.sandberg@arm.com setVecResult(val); 39810839Sandreas.sandberg@arm.com } 39910839Sandreas.sandberg@arm.com 40010839Sandreas.sandberg@arm.com void 40110839Sandreas.sandberg@arm.com setVecElemOperand(const StaticInst *si, int idx, 40210839Sandreas.sandberg@arm.com const VecElem val) override 40310839Sandreas.sandberg@arm.com { 40410839Sandreas.sandberg@arm.com const RegId& reg = si->destRegIdx(idx); 40510839Sandreas.sandberg@arm.com assert(reg.isVecElem()); 40610839Sandreas.sandberg@arm.com thread->setVecElem(reg, val); 40710839Sandreas.sandberg@arm.com setVecElemResult(val); 40810839Sandreas.sandberg@arm.com } 40910839Sandreas.sandberg@arm.com 41010839Sandreas.sandberg@arm.com void setVecPredRegOperand(const StaticInst *si, int idx, 41110839Sandreas.sandberg@arm.com const VecPredRegContainer& val) override 41210839Sandreas.sandberg@arm.com { 41310839Sandreas.sandberg@arm.com const RegId& reg = si->destRegIdx(idx); 41410839Sandreas.sandberg@arm.com assert(reg.isVecPredReg()); 41510839Sandreas.sandberg@arm.com thread->setVecPredReg(reg, val); 41610839Sandreas.sandberg@arm.com setVecPredResult(val); 41710839Sandreas.sandberg@arm.com } 41810839Sandreas.sandberg@arm.com 41910839Sandreas.sandberg@arm.com bool readPredicate() const override { return thread->readPredicate(); } 42010839Sandreas.sandberg@arm.com 42110839Sandreas.sandberg@arm.com void 42210839Sandreas.sandberg@arm.com setPredicate(bool val) override 42310839Sandreas.sandberg@arm.com { 42410839Sandreas.sandberg@arm.com thread->setPredicate(val); 42510839Sandreas.sandberg@arm.com } 42610839Sandreas.sandberg@arm.com 42710839Sandreas.sandberg@arm.com bool 4287753SWilliam.Wang@arm.com readMemAccPredicate() const override 4297950SAli.Saidi@ARM.com { 4307950SAli.Saidi@ARM.com return thread->readMemAccPredicate(); 43110839Sandreas.sandberg@arm.com } 43210839Sandreas.sandberg@arm.com 43310839Sandreas.sandberg@arm.com void 43410839Sandreas.sandberg@arm.com setMemAccPredicate(bool val) override 43510839Sandreas.sandberg@arm.com { 4367950SAli.Saidi@ARM.com thread->setMemAccPredicate(val); 43710839Sandreas.sandberg@arm.com } 43810839Sandreas.sandberg@arm.com 4397950SAli.Saidi@ARM.com TheISA::PCState pcState() const override { return thread->pcState(); } 44010839Sandreas.sandberg@arm.com void 44110839Sandreas.sandberg@arm.com pcState(const TheISA::PCState &val) override 44210839Sandreas.sandberg@arm.com { 44310839Sandreas.sandberg@arm.com DPRINTF(Checker, "Changing PC to %s, old PC %s.\n", 44410839Sandreas.sandberg@arm.com val, thread->pcState()); 44510839Sandreas.sandberg@arm.com thread->pcState(val); 4467950SAli.Saidi@ARM.com } 4477950SAli.Saidi@ARM.com Addr instAddr() { return thread->instAddr(); } 4487950SAli.Saidi@ARM.com Addr nextInstAddr() { return thread->nextInstAddr(); } 4497950SAli.Saidi@ARM.com MicroPC microPC() { return thread->microPC(); } 4507950SAli.Saidi@ARM.com ////////////////////////////////////////// 4517950SAli.Saidi@ARM.com 4527950SAli.Saidi@ARM.com RegVal 4537950SAli.Saidi@ARM.com readMiscRegNoEffect(int misc_reg) const 4547950SAli.Saidi@ARM.com { 4557950SAli.Saidi@ARM.com return thread->readMiscRegNoEffect(misc_reg); 4567950SAli.Saidi@ARM.com } 4577753SWilliam.Wang@arm.com 4587753SWilliam.Wang@arm.com RegVal 4597753SWilliam.Wang@arm.com readMiscReg(int misc_reg) override 4607950SAli.Saidi@ARM.com { 4617950SAli.Saidi@ARM.com return thread->readMiscReg(misc_reg); 4627753SWilliam.Wang@arm.com } 4637950SAli.Saidi@ARM.com 4647950SAli.Saidi@ARM.com void 4657950SAli.Saidi@ARM.com setMiscRegNoEffect(int misc_reg, RegVal val) 4667950SAli.Saidi@ARM.com { 4679648Sdam.sunwoo@arm.com DPRINTF(Checker, "Setting misc reg %d with no effect to check later\n", 4687950SAli.Saidi@ARM.com misc_reg); 4697753SWilliam.Wang@arm.com miscRegIdxs.push(misc_reg); 4709394Sandreas.hansson@arm.com return thread->setMiscRegNoEffect(misc_reg, val); 4717950SAli.Saidi@ARM.com } 4727950SAli.Saidi@ARM.com 4737950SAli.Saidi@ARM.com void 4747950SAli.Saidi@ARM.com setMiscReg(int misc_reg, RegVal val) override 4757950SAli.Saidi@ARM.com { 4767753SWilliam.Wang@arm.com DPRINTF(Checker, "Setting misc reg %d with effect to check later\n", 4777753SWilliam.Wang@arm.com misc_reg); 4787753SWilliam.Wang@arm.com miscRegIdxs.push(misc_reg); 4797753SWilliam.Wang@arm.com return thread->setMiscReg(misc_reg, val); 4807753SWilliam.Wang@arm.com } 4817753SWilliam.Wang@arm.com 4827753SWilliam.Wang@arm.com RegVal 4837753SWilliam.Wang@arm.com readMiscRegOperand(const StaticInst *si, int idx) override 4847753SWilliam.Wang@arm.com { 4857753SWilliam.Wang@arm.com const RegId& reg = si->srcRegIdx(idx); 4867950SAli.Saidi@ARM.com assert(reg.isMiscReg()); 4879395SAndreas.Sandberg@ARM.com return thread->readMiscReg(reg.index()); 4889395SAndreas.Sandberg@ARM.com } 4899395SAndreas.Sandberg@ARM.com 4909395SAndreas.Sandberg@ARM.com void 4917950SAli.Saidi@ARM.com setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override 4927950SAli.Saidi@ARM.com { 4937950SAli.Saidi@ARM.com const RegId& reg = si->destRegIdx(idx); 4947950SAli.Saidi@ARM.com assert(reg.isMiscReg()); 4957950SAli.Saidi@ARM.com return this->setMiscReg(reg.index(), val); 4968851Sandreas.hansson@arm.com } 4979395SAndreas.Sandberg@ARM.com 4988851Sandreas.hansson@arm.com ///////////////////////////////////////// 4997753SWilliam.Wang@arm.com 5007753SWilliam.Wang@arm.com void 5017753SWilliam.Wang@arm.com recordPCChange(const TheISA::PCState &val) 5027753SWilliam.Wang@arm.com { 5037753SWilliam.Wang@arm.com changedPC = true; 5047753SWilliam.Wang@arm.com newPCState = val; 5057753SWilliam.Wang@arm.com } 5069394Sandreas.hansson@arm.com 5079394Sandreas.hansson@arm.com void 5089394Sandreas.hansson@arm.com demapPage(Addr vaddr, uint64_t asn) override 5097753SWilliam.Wang@arm.com { 5107753SWilliam.Wang@arm.com this->itb->demapPage(vaddr, asn); 5117753SWilliam.Wang@arm.com this->dtb->demapPage(vaddr, asn); 5127753SWilliam.Wang@arm.com } 5139394Sandreas.hansson@arm.com 5149394Sandreas.hansson@arm.com // monitor/mwait funtions 5157823Ssteve.reinhardt@amd.com void armMonitor(Addr address) override { BaseCPU::armMonitor(0, address); } 5167950SAli.Saidi@ARM.com bool mwait(PacketPtr pkt) override { return BaseCPU::mwait(0, pkt); } 5177950SAli.Saidi@ARM.com void mwaitAtomic(ThreadContext *tc) override 5189648Sdam.sunwoo@arm.com { return BaseCPU::mwaitAtomic(0, tc, thread->dtb); } 5197950SAli.Saidi@ARM.com AddressMonitor *getAddrMonitor() override 5207753SWilliam.Wang@arm.com { return BaseCPU::getCpuAddrMonitor(0); } 5217753SWilliam.Wang@arm.com 52210839Sandreas.sandberg@arm.com void 5239330Schander.sudanthi@arm.com demapInstPage(Addr vaddr, uint64_t asn) 5249330Schander.sudanthi@arm.com { 5257753SWilliam.Wang@arm.com this->itb->demapPage(vaddr, asn); 5269939Sdam.sunwoo@arm.com } 5279939Sdam.sunwoo@arm.com 5287950SAli.Saidi@ARM.com void 5299939Sdam.sunwoo@arm.com demapDataPage(Addr vaddr, uint64_t asn) 53011359Sandreas@sandberg.pp.se { 53111359Sandreas@sandberg.pp.se this->dtb->demapPage(vaddr, asn); 5329530SChris.Emmons@arm.com } 5339939Sdam.sunwoo@arm.com 53411359Sandreas@sandberg.pp.se Fault readMem(Addr addr, uint8_t *data, unsigned size, 53511359Sandreas@sandberg.pp.se Request::Flags flags) override; 5369939Sdam.sunwoo@arm.com 5377753SWilliam.Wang@arm.com Fault writeMem(uint8_t *data, unsigned size, Addr addr, 5389179Sandreas.hansson@arm.com Request::Flags flags, uint64_t *res) override; 5399179Sandreas.hansson@arm.com 5409394Sandreas.hansson@arm.com Fault amoMem(Addr addr, uint8_t* data, unsigned size, 5417950SAli.Saidi@ARM.com Request::Flags flags, AtomicOpFunctor *amo_op) override 5429394Sandreas.hansson@arm.com { 5439394Sandreas.hansson@arm.com panic("AMO is not supported yet in CPU checker\n"); 5449394Sandreas.hansson@arm.com } 5457753SWilliam.Wang@arm.com 5467753SWilliam.Wang@arm.com unsigned int 5477753SWilliam.Wang@arm.com readStCondFailures() const override { 5487753SWilliam.Wang@arm.com return thread->readStCondFailures(); 5497753SWilliam.Wang@arm.com } 5507753SWilliam.Wang@arm.com 5519648Sdam.sunwoo@arm.com void setStCondFailures(unsigned int sc_failures) override {} 5527950SAli.Saidi@ARM.com ///////////////////////////////////////////////////// 5537753SWilliam.Wang@arm.com 5547753SWilliam.Wang@arm.com void wakeup(ThreadID tid) override { } 55510905Sandreas.sandberg@arm.com // Assume that the normal CPU's call to syscall was successful. 5567753SWilliam.Wang@arm.com // The checker's state would have already been updated by the syscall. 5577753SWilliam.Wang@arm.com void syscall(int64_t callnum, Fault *fault) override { } 5587753SWilliam.Wang@arm.com 5597753SWilliam.Wang@arm.com void 5607753SWilliam.Wang@arm.com handleError() 5617753SWilliam.Wang@arm.com { 5627753SWilliam.Wang@arm.com if (exitOnError) 5637753SWilliam.Wang@arm.com dumpAndExit(); 5647753SWilliam.Wang@arm.com } 5657753SWilliam.Wang@arm.com 5667753SWilliam.Wang@arm.com bool checkFlags(const RequestPtr &unverified_req, Addr vAddr, 5677753SWilliam.Wang@arm.com Addr pAddr, int flags); 5687753SWilliam.Wang@arm.com 5697753SWilliam.Wang@arm.com void dumpAndExit(); 5707753SWilliam.Wang@arm.com 5717753SWilliam.Wang@arm.com ThreadContext *tcBase() override { return tc; } 5727753SWilliam.Wang@arm.com SimpleThread *threadBase() { return thread; } 5737753SWilliam.Wang@arm.com 5747753SWilliam.Wang@arm.com InstResult unverifiedResult; 5757753SWilliam.Wang@arm.com RequestPtr unverifiedReq; 5767753SWilliam.Wang@arm.com uint8_t *unverifiedMemData; 5777753SWilliam.Wang@arm.com 5787753SWilliam.Wang@arm.com bool changedPC; 5797753SWilliam.Wang@arm.com bool willChangePC; 5807753SWilliam.Wang@arm.com TheISA::PCState newPCState; 5817753SWilliam.Wang@arm.com bool exitOnError; 5827753SWilliam.Wang@arm.com bool updateOnError; 5837753SWilliam.Wang@arm.com bool warnOnlyOnLoadError; 5847753SWilliam.Wang@arm.com 5857753SWilliam.Wang@arm.com InstSeqNum youngestSN; 5867753SWilliam.Wang@arm.com}; 5877753SWilliam.Wang@arm.com 5887753SWilliam.Wang@arm.com/** 5897753SWilliam.Wang@arm.com * Templated Checker class. This Checker class is templated on the 5907753SWilliam.Wang@arm.com * DynInstPtr of the instruction type that will be verified. Proper 5917753SWilliam.Wang@arm.com * template instantiations of the Checker must be placed at the bottom 5927753SWilliam.Wang@arm.com * of checker/cpu.cc. 5937753SWilliam.Wang@arm.com */ 5947753SWilliam.Wang@arm.comtemplate <class Impl> 5957753SWilliam.Wang@arm.comclass Checker : public CheckerCPU 5967753SWilliam.Wang@arm.com{ 5977753SWilliam.Wang@arm.com private: 5987753SWilliam.Wang@arm.com typedef typename Impl::DynInstPtr DynInstPtr; 5997753SWilliam.Wang@arm.com 6007753SWilliam.Wang@arm.com public: 6017753SWilliam.Wang@arm.com Checker(Params *p) 6027753SWilliam.Wang@arm.com : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL) 6037753SWilliam.Wang@arm.com { } 6047753SWilliam.Wang@arm.com 6057753SWilliam.Wang@arm.com void switchOut(); 6067753SWilliam.Wang@arm.com void takeOverFrom(BaseCPU *oldCPU); 6077753SWilliam.Wang@arm.com 6087753SWilliam.Wang@arm.com void advancePC(const Fault &fault); 6097753SWilliam.Wang@arm.com 6107950SAli.Saidi@ARM.com void verify(const DynInstPtr &inst); 6117753SWilliam.Wang@arm.com 6129415SChander.Sudanthi@arm.com void validateInst(const DynInstPtr &inst); 6137753SWilliam.Wang@arm.com void validateExecution(const DynInstPtr &inst); 6147753SWilliam.Wang@arm.com void validateState(); 6157753SWilliam.Wang@arm.com 6167753SWilliam.Wang@arm.com void copyResult(const DynInstPtr &inst, const InstResult& mismatch_val, 6177753SWilliam.Wang@arm.com int start_idx); 6187753SWilliam.Wang@arm.com void handlePendingInt(); 6198062SAli.Saidi@ARM.com 6208062SAli.Saidi@ARM.com private: 6218062SAli.Saidi@ARM.com void handleError(const DynInstPtr &inst) 6228062SAli.Saidi@ARM.com { 6238062SAli.Saidi@ARM.com if (exitOnError) { 6248062SAli.Saidi@ARM.com dumpAndExit(inst); 6258062SAli.Saidi@ARM.com } else if (updateOnError) { 6268062SAli.Saidi@ARM.com updateThisCycle = true; 6278062SAli.Saidi@ARM.com } 6288062SAli.Saidi@ARM.com } 6298062SAli.Saidi@ARM.com 6308062SAli.Saidi@ARM.com void dumpAndExit(const DynInstPtr &inst); 6318062SAli.Saidi@ARM.com 6328062SAli.Saidi@ARM.com bool updateThisCycle; 6338062SAli.Saidi@ARM.com 6348062SAli.Saidi@ARM.com DynInstPtr unverifiedInst; 6358062SAli.Saidi@ARM.com 6368062SAli.Saidi@ARM.com std::list<DynInstPtr> instList; 6378062SAli.Saidi@ARM.com typedef typename std::list<DynInstPtr>::iterator InstListIt; 6389395SAndreas.Sandberg@ARM.com void dumpInsts(); 6399395SAndreas.Sandberg@ARM.com}; 6408062SAli.Saidi@ARM.com 64110905Sandreas.sandberg@arm.com#endif // __CPU_CHECKER_CPU_HH__ 6427753SWilliam.Wang@arm.com