cpu.hh revision 2354
12315SN/A/* 28733Sgeoffrey.blake@arm.com * Copyright (c) 2006 The Regents of The University of Michigan 38733Sgeoffrey.blake@arm.com * All rights reserved. 48733Sgeoffrey.blake@arm.com * 58733Sgeoffrey.blake@arm.com * Redistribution and use in source and binary forms, with or without 68733Sgeoffrey.blake@arm.com * modification, are permitted provided that the following conditions are 78733Sgeoffrey.blake@arm.com * met: redistributions of source code must retain the above copyright 88733Sgeoffrey.blake@arm.com * notice, this list of conditions and the following disclaimer; 98733Sgeoffrey.blake@arm.com * redistributions in binary form must reproduce the above copyright 108733Sgeoffrey.blake@arm.com * notice, this list of conditions and the following disclaimer in the 118733Sgeoffrey.blake@arm.com * documentation and/or other materials provided with the distribution; 128733Sgeoffrey.blake@arm.com * neither the name of the copyright holders nor the names of its 138733Sgeoffrey.blake@arm.com * contributors may be used to endorse or promote products derived from 142332SN/A * this software without specific prior written permission. 152315SN/A * 162315SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172315SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182315SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192315SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202315SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212315SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222315SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232315SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242315SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252315SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262315SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272315SN/A */ 282315SN/A 292315SN/A#ifndef __CPU_CHECKER_CPU_HH__ 302315SN/A#define __CPU_CHECKER_CPU_HH__ 312315SN/A 322315SN/A#include <list> 332315SN/A#include <queue> 342315SN/A#include <map> 352315SN/A 362315SN/A#include "base/statistics.hh" 372315SN/A#include "config/full_system.hh" 382315SN/A#include "cpu/base.hh" 392689Sktlim@umich.edu#include "cpu/base_dyn_inst.hh" 402689Sktlim@umich.edu#include "cpu/cpu_exec_context.hh" 412315SN/A#include "cpu/pc_event.hh" 422315SN/A#include "cpu/static_inst.hh" 432315SN/A#include "sim/eventq.hh" 442315SN/A 452315SN/A// forward declarations 462315SN/A#if FULL_SYSTEM 478229Snate@binkert.orgclass Processor; 482315SN/Aclass AlphaITB; 492315SN/Aclass AlphaDTB; 502669Sktlim@umich.educlass PhysicalMemory; 512315SN/A 522315SN/Aclass RemoteGDB; 532315SN/Aclass GDBListener; 548229Snate@binkert.org 552683Sktlim@umich.edu#else 562315SN/A 578733Sgeoffrey.blake@arm.comclass Process; 588733Sgeoffrey.blake@arm.com 592315SN/A#endif // FULL_SYSTEM 602315SN/Atemplate <class> 612315SN/Aclass BaseDynInst; 623468Sgblack@eecs.umich.educlass ExecContext; 633468Sgblack@eecs.umich.educlass MemInterface; 646022Sgblack@eecs.umich.educlass Checkpoint; 653468Sgblack@eecs.umich.educlass Sampler; 662315SN/A 672315SN/A/** 682315SN/A * CheckerCPU class. Dynamically verifies instructions as they are 692680Sktlim@umich.edu * completed by making sure that the instruction and its results match 702669Sktlim@umich.edu * the independent execution of the benchmark inside the checker. The 712315SN/A * checker verifies instructions in order, regardless of the order in 722350SN/A * which instructions complete. There are certain results that can 732350SN/A * not be verified, specifically the result of a store conditional or 742350SN/A * the values of uncached accesses. In these cases, and with 752350SN/A * instructions marked as "IsUnverifiable", the checker assumes that 762350SN/A * the value from the main CPU's execution is correct and simply 772350SN/A * copies that value. It provides a CheckerExecContext (see 782350SN/A * checker/exec_context.hh) that provides hooks for updating the 792350SN/A * Checker's state through any ExecContext accesses. This allows the 802350SN/A * checker to be able to correctly verify instructions, even with 812350SN/A * external accesses to the ExecContext that change state. 822680Sktlim@umich.edu */ 832683Sktlim@umich.educlass CheckerCPU : public BaseCPU 842680Sktlim@umich.edu{ 852350SN/A protected: 862680Sktlim@umich.edu typedef TheISA::MachInst MachInst; 872350SN/A typedef TheISA::MiscReg MiscReg; 882315SN/A public: 892315SN/A virtual void init(); 902315SN/A 912315SN/A struct Params : public BaseCPU::Params 922669Sktlim@umich.edu { 932669Sktlim@umich.edu#if FULL_SYSTEM 942315SN/A AlphaITB *itb; 958832SAli.Saidi@ARM.com AlphaDTB *dtb; 968832SAli.Saidi@ARM.com FunctionalMemory *mem; 978832SAli.Saidi@ARM.com#else 982315SN/A Process *process; 992315SN/A#endif 1002315SN/A bool exitOnError; 1012315SN/A bool updateOnError; 1025529Snate@binkert.org }; 1035529Snate@binkert.org 1048733Sgeoffrey.blake@arm.com public: 1052315SN/A CheckerCPU(Params *p); 1062315SN/A virtual ~CheckerCPU(); 1072315SN/A 1088733Sgeoffrey.blake@arm.com void setMemory(FunctionalMemory *mem); 1092679Sktlim@umich.edu 1102315SN/A FunctionalMemory *memPtr; 1112315SN/A 1122315SN/A#if FULL_SYSTEM 1132679Sktlim@umich.edu void setSystem(System *system); 1148887Sgeoffrey.blake@arm.com 1152679Sktlim@umich.edu System *systemPtr; 1168887Sgeoffrey.blake@arm.com#endif 1172679Sktlim@umich.edu public: 1188887Sgeoffrey.blake@arm.com // execution context 1192679Sktlim@umich.edu CPUExecContext *cpuXC; 1208887Sgeoffrey.blake@arm.com 1218887Sgeoffrey.blake@arm.com ExecContext *xcProxy; 1228887Sgeoffrey.blake@arm.com 1238887Sgeoffrey.blake@arm.com AlphaITB *itb; 1248887Sgeoffrey.blake@arm.com AlphaDTB *dtb; 1258887Sgeoffrey.blake@arm.com 1268887Sgeoffrey.blake@arm.com#if FULL_SYSTEM 1278887Sgeoffrey.blake@arm.com Addr dbg_vtophys(Addr addr); 1288887Sgeoffrey.blake@arm.com#endif 1298887Sgeoffrey.blake@arm.com 1308887Sgeoffrey.blake@arm.com union Result { 1318887Sgeoffrey.blake@arm.com uint64_t integer; 1328887Sgeoffrey.blake@arm.com float fp; 1332679Sktlim@umich.edu double dbl; 1342315SN/A }; 1352683Sktlim@umich.edu 1362683Sktlim@umich.edu Result result; 1372315SN/A 1382680Sktlim@umich.edu // current instruction 1392315SN/A MachInst machInst; 1406022Sgblack@eecs.umich.edu 1416022Sgblack@eecs.umich.edu // Refcounted pointer to the one memory request. 1422315SN/A MemReqPtr memReq; 1432315SN/A 1442315SN/A StaticInstPtr curStaticInst; 1452315SN/A 1462315SN/A // number of simulated instructions 1472315SN/A Counter numInst; 1488733Sgeoffrey.blake@arm.com Counter startNumInst; 1498733Sgeoffrey.blake@arm.com 1508733Sgeoffrey.blake@arm.com std::queue<int> miscRegIdxs; 1518733Sgeoffrey.blake@arm.com 1522315SN/A virtual Counter totalInstructions() const 1532315SN/A { 1548733Sgeoffrey.blake@arm.com return numInst - startNumInst; 1558733Sgeoffrey.blake@arm.com } 1568733Sgeoffrey.blake@arm.com 1572315SN/A // number of simulated loads 1582679Sktlim@umich.edu Counter numLoad; 1592679Sktlim@umich.edu Counter startNumLoad; 1602315SN/A 1612315SN/A virtual void serialize(std::ostream &os); 1628733Sgeoffrey.blake@arm.com virtual void unserialize(Checkpoint *cp, const std::string §ion); 1632315SN/A 1642315SN/A template <class T> 1652315SN/A Fault read(Addr addr, T &data, unsigned flags); 1662315SN/A 1672315SN/A template <class T> 1682315SN/A Fault write(T data, Addr addr, unsigned flags, uint64_t *res); 1692315SN/A 1708733Sgeoffrey.blake@arm.com // These functions are only used in CPU models that split 1718733Sgeoffrey.blake@arm.com // effective address computation from the actual memory access. 1728733Sgeoffrey.blake@arm.com void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); } 1738887Sgeoffrey.blake@arm.com Addr getEA() { panic("SimpleCPU::getEA() not implemented\n"); } 1748887Sgeoffrey.blake@arm.com 1758887Sgeoffrey.blake@arm.com void prefetch(Addr addr, unsigned flags) 1768887Sgeoffrey.blake@arm.com { 1778887Sgeoffrey.blake@arm.com // need to do this... 1788887Sgeoffrey.blake@arm.com } 1792315SN/A 1802930Sktlim@umich.edu void writeHint(Addr addr, int size, unsigned flags) 1812315SN/A { 1822315SN/A // need to do this... 1832315SN/A } 1842315SN/A 1852315SN/A Fault copySrcTranslate(Addr src); 1862315SN/A 1872315SN/A Fault copy(Addr dest); 1882315SN/A 1892315SN/A // The register accessor methods provide the index of the 1902315SN/A // instruction's operand (e.g., 0 or 1), not the architectural 1912315SN/A // register index, to simplify the implementation of register 1922315SN/A // renaming. We find the architectural register index by indexing 1935543Ssaidi@eecs.umich.edu // into the instruction's own operand index table. Note that a 1942315SN/A // raw pointer to the StaticInst is provided instead of a 1952315SN/A // ref-counted StaticInstPtr to redice overhead. This is fine as 1962315SN/A // long as these methods don't copy the pointer into any long-term 1972315SN/A // storage (which is pretty hard to imagine they would have reason 1982315SN/A // to do). 1992315SN/A 2002315SN/A uint64_t readIntReg(const StaticInst *si, int idx) 2012315SN/A { 2022315SN/A return cpuXC->readIntReg(si->srcRegIdx(idx)); 2032315SN/A } 2042315SN/A 2052315SN/A float readFloatRegSingle(const StaticInst *si, int idx) 2063735Sstever@eecs.umich.edu { 2072315SN/A int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 2082683Sktlim@umich.edu return cpuXC->readFloatRegSingle(reg_idx); 2092315SN/A } 2102315SN/A 2113735Sstever@eecs.umich.edu double readFloatRegDouble(const StaticInst *si, int idx) 2122315SN/A { 2132315SN/A int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 2142683Sktlim@umich.edu return cpuXC->readFloatRegDouble(reg_idx); 2152315SN/A } 2162315SN/A 2173735Sstever@eecs.umich.edu uint64_t readFloatRegInt(const StaticInst *si, int idx) 2182669Sktlim@umich.edu { 2192669Sktlim@umich.edu int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 2202683Sktlim@umich.edu return cpuXC->readFloatRegInt(reg_idx); 2212315SN/A } 2222315SN/A 2238733Sgeoffrey.blake@arm.com void setIntReg(const StaticInst *si, int idx, uint64_t val) 2248733Sgeoffrey.blake@arm.com { 2258733Sgeoffrey.blake@arm.com cpuXC->setIntReg(si->destRegIdx(idx), val); 2268733Sgeoffrey.blake@arm.com result.integer = val; 2278733Sgeoffrey.blake@arm.com } 2288733Sgeoffrey.blake@arm.com 2298733Sgeoffrey.blake@arm.com void setFloatRegSingle(const StaticInst *si, int idx, float val) 2308733Sgeoffrey.blake@arm.com { 2313735Sstever@eecs.umich.edu int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 2322315SN/A cpuXC->setFloatRegSingle(reg_idx, val); 2332683Sktlim@umich.edu result.fp = val; 2348733Sgeoffrey.blake@arm.com } 2352315SN/A 2362315SN/A void setFloatRegDouble(const StaticInst *si, int idx, double val) 2373735Sstever@eecs.umich.edu { 2382669Sktlim@umich.edu int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 2392669Sktlim@umich.edu cpuXC->setFloatRegDouble(reg_idx, val); 2402683Sktlim@umich.edu result.dbl = val; 2418733Sgeoffrey.blake@arm.com } 2422315SN/A 2432315SN/A void setFloatRegInt(const StaticInst *si, int idx, uint64_t val) 2443735Sstever@eecs.umich.edu { 2453735Sstever@eecs.umich.edu int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 2462315SN/A cpuXC->setFloatRegInt(reg_idx, val); 2472315SN/A result.integer = val; 2482683Sktlim@umich.edu } 2498733Sgeoffrey.blake@arm.com 2502315SN/A uint64_t readPC() { return cpuXC->readPC(); } 2512315SN/A void setNextPC(uint64_t val) { 2528733Sgeoffrey.blake@arm.com cpuXC->setNextPC(val); 2538733Sgeoffrey.blake@arm.com } 2548733Sgeoffrey.blake@arm.com 2558733Sgeoffrey.blake@arm.com MiscReg readMiscReg(int misc_reg) 2568733Sgeoffrey.blake@arm.com { 2572669Sktlim@umich.edu return cpuXC->readMiscReg(misc_reg); 2588733Sgeoffrey.blake@arm.com } 2598733Sgeoffrey.blake@arm.com 2608733Sgeoffrey.blake@arm.com MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) 2618733Sgeoffrey.blake@arm.com { 2628733Sgeoffrey.blake@arm.com return cpuXC->readMiscRegWithEffect(misc_reg, fault); 2638733Sgeoffrey.blake@arm.com } 2648733Sgeoffrey.blake@arm.com 2658733Sgeoffrey.blake@arm.com Fault setMiscReg(int misc_reg, const MiscReg &val) 2668733Sgeoffrey.blake@arm.com { 2678733Sgeoffrey.blake@arm.com result.integer = val; 2688733Sgeoffrey.blake@arm.com miscRegIdxs.push(misc_reg); 2692315SN/A return cpuXC->setMiscReg(misc_reg, val); 2704172Ssaidi@eecs.umich.edu } 2714172Ssaidi@eecs.umich.edu 2724172Ssaidi@eecs.umich.edu Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) 2734172Ssaidi@eecs.umich.edu { 2744172Ssaidi@eecs.umich.edu miscRegIdxs.push(misc_reg); 2752315SN/A return cpuXC->setMiscRegWithEffect(misc_reg, val); 2762315SN/A } 2772683Sktlim@umich.edu 2782315SN/A void recordPCChange(uint64_t val) { changedPC = true; } 2792315SN/A void recordNextPCChange(uint64_t val) { changedNextPC = true; } 2804172Ssaidi@eecs.umich.edu 2812315SN/A bool translateInstReq(MemReqPtr &req); 2824172Ssaidi@eecs.umich.edu void translateDataWriteReq(MemReqPtr &req); 2834172Ssaidi@eecs.umich.edu void translateDataReadReq(MemReqPtr &req); 2842315SN/A 2852315SN/A#if FULL_SYSTEM 2863468Sgblack@eecs.umich.edu Fault hwrei() { return cpuXC->hwrei(); } 2872315SN/A int readIntrFlag() { return cpuXC->readIntrFlag(); } 2882315SN/A void setIntrFlag(int val) { cpuXC->setIntrFlag(val); } 2892683Sktlim@umich.edu bool inPalMode() { return cpuXC->inPalMode(); } 2902315SN/A void ev5_trap(Fault fault) { fault->invoke(xcProxy); } 2912315SN/A bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); } 2928733Sgeoffrey.blake@arm.com#else 2938733Sgeoffrey.blake@arm.com // Assume that the normal CPU's call to syscall was successful. 2948733Sgeoffrey.blake@arm.com // The checker's state would have already been updated by the syscall. 2958733Sgeoffrey.blake@arm.com void syscall() { } 2968733Sgeoffrey.blake@arm.com#endif 2978733Sgeoffrey.blake@arm.com 2988733Sgeoffrey.blake@arm.com virtual void handleError() = 0; 2998733Sgeoffrey.blake@arm.com 3008733Sgeoffrey.blake@arm.com bool checkFlags(MemReqPtr &req); 3018733Sgeoffrey.blake@arm.com 3028733Sgeoffrey.blake@arm.com ExecContext *xcBase() { return xcProxy; } 3038733Sgeoffrey.blake@arm.com CPUExecContext *cpuXCBase() { return cpuXC; } 3048888Sgeoffrey.blake@arm.com 3058888Sgeoffrey.blake@arm.com Result unverifiedResult; 3068888Sgeoffrey.blake@arm.com MemReqPtr unverifiedReq; 3078888Sgeoffrey.blake@arm.com 3088888Sgeoffrey.blake@arm.com bool changedPC; 3098888Sgeoffrey.blake@arm.com bool willChangePC; 3108888Sgeoffrey.blake@arm.com uint64_t newPC; 3118888Sgeoffrey.blake@arm.com bool changedNextPC; 3128888Sgeoffrey.blake@arm.com bool exitOnError; 3138888Sgeoffrey.blake@arm.com bool updateOnError; 3148888Sgeoffrey.blake@arm.com 3158888Sgeoffrey.blake@arm.com InstSeqNum youngestSN; 3168888Sgeoffrey.blake@arm.com}; 3178888Sgeoffrey.blake@arm.com 3188733Sgeoffrey.blake@arm.com/** 3198733Sgeoffrey.blake@arm.com * Templated Checker class. This Checker class is templated on the 3208733Sgeoffrey.blake@arm.com * DynInstPtr of the instruction type that will be verified. Proper 3218733Sgeoffrey.blake@arm.com * template instantiations of the Checker must be placed at the bottom 3228733Sgeoffrey.blake@arm.com * of checker/cpu.cc. 3238733Sgeoffrey.blake@arm.com */ 3248733Sgeoffrey.blake@arm.comtemplate <class DynInstPtr> 3252315SN/Aclass Checker : public CheckerCPU 3265358Sgblack@eecs.umich.edu{ 3275358Sgblack@eecs.umich.edu public: 3285358Sgblack@eecs.umich.edu Checker(Params *p) 3295358Sgblack@eecs.umich.edu : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL) 3305358Sgblack@eecs.umich.edu { } 3315358Sgblack@eecs.umich.edu 3325358Sgblack@eecs.umich.edu void switchOut(Sampler *s); 3335358Sgblack@eecs.umich.edu void takeOverFrom(BaseCPU *oldCPU); 3345358Sgblack@eecs.umich.edu 3355358Sgblack@eecs.umich.edu void tick(DynInstPtr &inst); 3365358Sgblack@eecs.umich.edu 3375358Sgblack@eecs.umich.edu void validateInst(DynInstPtr &inst); 3385358Sgblack@eecs.umich.edu void validateExecution(DynInstPtr &inst); 3395358Sgblack@eecs.umich.edu void validateState(); 3405358Sgblack@eecs.umich.edu 3415358Sgblack@eecs.umich.edu virtual void handleError() 3428733Sgeoffrey.blake@arm.com { 3438733Sgeoffrey.blake@arm.com if (exitOnError) 3448733Sgeoffrey.blake@arm.com panic("Checker found error!"); 3458733Sgeoffrey.blake@arm.com else if (updateOnError) 3468733Sgeoffrey.blake@arm.com updateThisCycle = true; 3478733Sgeoffrey.blake@arm.com } 3488733Sgeoffrey.blake@arm.com 3498733Sgeoffrey.blake@arm.com bool updateThisCycle; 3505702Ssaidi@eecs.umich.edu 3515702Ssaidi@eecs.umich.edu DynInstPtr unverifiedInst; 3528733Sgeoffrey.blake@arm.com 3532315SN/A std::list<DynInstPtr> instList; 3542332SN/A typedef typename std::list<DynInstPtr>::iterator InstListIt; 3552669Sktlim@umich.edu void dumpInsts(); 3562315SN/A}; 3572315SN/A 3582315SN/A#endif // __CPU_CHECKER_CPU_HH__ 3592315SN/A