base.hh revision 2420
12889Sbinkertn@umich.edu/* 22889Sbinkertn@umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan 32889Sbinkertn@umich.edu * All rights reserved. 42889Sbinkertn@umich.edu * 52889Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without 62889Sbinkertn@umich.edu * modification, are permitted provided that the following conditions are 72889Sbinkertn@umich.edu * met: redistributions of source code must retain the above copyright 82889Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer; 92889Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright 102889Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the 112889Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution; 122889Sbinkertn@umich.edu * neither the name of the copyright holders nor the names of its 132889Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from 142889Sbinkertn@umich.edu * this software without specific prior written permission. 152889Sbinkertn@umich.edu * 162889Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172889Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182889Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192889Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202889Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212889Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222889Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232889Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242889Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252889Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262889Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272889Sbinkertn@umich.edu */ 282889Sbinkertn@umich.edu 294850Snate@binkert.org#ifndef __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__ 304850Snate@binkert.org#define __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__ 314850Snate@binkert.org 324850Snate@binkert.org#include "base/statistics.hh" 334850Snate@binkert.org#include "config/full_system.hh" 344850Snate@binkert.org#include "cpu/base.hh" 355467Snate@binkert.org#include "cpu/exec_context.hh" 365471Snate@binkert.org#include "cpu/pc_event.hh" 375470Snate@binkert.org#include "cpu/sampler/sampler.hh" 382889Sbinkertn@umich.edu#include "cpu/static_inst.hh" 392889Sbinkertn@umich.edu#include "mem/packet.hh" 402889Sbinkertn@umich.edu#include "mem/port.hh" 415470Snate@binkert.org#include "mem/request.hh" 425470Snate@binkert.org#include "sim/eventq.hh" 435470Snate@binkert.org 445470Snate@binkert.org// forward declarations 455470Snate@binkert.org#if FULL_SYSTEM 465470Snate@binkert.orgclass Processor; 475470Snate@binkert.orgclass AlphaITB; 482889Sbinkertn@umich.educlass AlphaDTB; 495470Snate@binkert.orgclass Memory; 505470Snate@binkert.org 515470Snate@binkert.orgclass RemoteGDB; 525470Snate@binkert.orgclass GDBListener; 535470Snate@binkert.org 542889Sbinkertn@umich.edu#else 552889Sbinkertn@umich.edu 562889Sbinkertn@umich.educlass Process; 572889Sbinkertn@umich.edu 584850Snate@binkert.org#endif // FULL_SYSTEM 594850Snate@binkert.org 602889Sbinkertn@umich.educlass MemInterface; 612889Sbinkertn@umich.educlass Checkpoint; 622889Sbinkertn@umich.edu 632889Sbinkertn@umich.edunamespace Trace { 642889Sbinkertn@umich.edu class InstRecord; 652889Sbinkertn@umich.edu} 662889Sbinkertn@umich.edu 672889Sbinkertn@umich.edu 685773Snate@binkert.org// Set exactly one of these symbols to 1 to set the memory access 692889Sbinkertn@umich.edu// model. Probably should make these template parameters, or even 705524Sstever@gmail.com// just fork the CPU models. 715524Sstever@gmail.com// 725524Sstever@gmail.com#define SIMPLE_CPU_MEM_TIMING 0 735524Sstever@gmail.com#define SIMPLE_CPU_MEM_ATOMIC 0 745524Sstever@gmail.com#define SIMPLE_CPU_MEM_IMMEDIATE 1 755524Sstever@gmail.com 765524Sstever@gmail.com 775524Sstever@gmail.comclass SimpleCPU : public BaseCPU 782889Sbinkertn@umich.edu{ 792889Sbinkertn@umich.edu class CpuPort : public Port 802899Sbinkertn@umich.edu { 812899Sbinkertn@umich.edu 822889Sbinkertn@umich.edu SimpleCPU *cpu; 832889Sbinkertn@umich.edu 842889Sbinkertn@umich.edu public: 852889Sbinkertn@umich.edu 862889Sbinkertn@umich.edu CpuPort(SimpleCPU *_cpu) 872889Sbinkertn@umich.edu : cpu(_cpu) 882889Sbinkertn@umich.edu { } 892889Sbinkertn@umich.edu 902889Sbinkertn@umich.edu protected: 915773Snate@binkert.org 922889Sbinkertn@umich.edu virtual bool recvTiming(Packet &pkt); 932889Sbinkertn@umich.edu 945773Snate@binkert.org virtual Tick recvAtomic(Packet &pkt); 955773Snate@binkert.org 965773Snate@binkert.org virtual void recvFunctional(Packet &pkt); 975773Snate@binkert.org 985773Snate@binkert.org virtual void recvStatusChange(Status status); 992889Sbinkertn@umich.edu 1002889Sbinkertn@umich.edu virtual Packet *recvRetry(); 1012889Sbinkertn@umich.edu }; 1022889Sbinkertn@umich.edu 1035512SMichael.Adler@intel.com CpuPort icachePort; 1045512SMichael.Adler@intel.com CpuPort dcachePort; 1052889Sbinkertn@umich.edu 1062889Sbinkertn@umich.edu public: 1072889Sbinkertn@umich.edu // main simulation loop (one cycle) 1084053Sbinkertn@umich.edu void tick(); 1094053Sbinkertn@umich.edu 1102889Sbinkertn@umich.edu private: 1114053Sbinkertn@umich.edu struct TickEvent : public Event 1124044Sbinkertn@umich.edu { 1134044Sbinkertn@umich.edu SimpleCPU *cpu; 1142889Sbinkertn@umich.edu int width; 1152889Sbinkertn@umich.edu 1162889Sbinkertn@umich.edu TickEvent(SimpleCPU *c, int w); 1172889Sbinkertn@umich.edu void process(); 1182889Sbinkertn@umich.edu const char *description(); 1195473Snate@binkert.org }; 1205473Snate@binkert.org 1215473Snate@binkert.org TickEvent tickEvent; 1225473Snate@binkert.org 1235473Snate@binkert.org /// Schedule tick event, regardless of its current state. 1242889Sbinkertn@umich.edu void scheduleTickEvent(int numCycles) 1255801Snate@binkert.org { 1265801Snate@binkert.org if (tickEvent.squashed()) 1275801Snate@binkert.org tickEvent.reschedule(curTick + cycles(numCycles)); 1284167Sbinkertn@umich.edu else if (!tickEvent.scheduled()) 1294042Sbinkertn@umich.edu tickEvent.schedule(curTick + cycles(numCycles)); 1305801Snate@binkert.org } 1315799Snate@binkert.org 1325799Snate@binkert.org /// Unschedule tick event, regardless of its current state. 1335799Snate@binkert.org void unscheduleTickEvent() 1345799Snate@binkert.org { 1355799Snate@binkert.org if (tickEvent.scheduled()) 1365799Snate@binkert.org tickEvent.squash(); 1375802Snate@binkert.org } 1382889Sbinkertn@umich.edu 1395472Snate@binkert.org private: 1405472Snate@binkert.org Trace::InstRecord *traceData; 1415472Snate@binkert.org 1425472Snate@binkert.org public: 1435472Snate@binkert.org // 1445472Snate@binkert.org enum Status { 1455472Snate@binkert.org Running, 1465470Snate@binkert.org Idle, 1472889Sbinkertn@umich.edu IcacheRetry, 1485524Sstever@gmail.com IcacheWaitResponse, 1495524Sstever@gmail.com IcacheAccessComplete, 1505524Sstever@gmail.com DcacheRetry, 1515524Sstever@gmail.com DcacheWaitResponse, 1525524Sstever@gmail.com DcacheWaitSwitch, 1535524Sstever@gmail.com SwitchedOut 1545524Sstever@gmail.com }; 1555524Sstever@gmail.com 1565524Sstever@gmail.com private: 1575524Sstever@gmail.com Status _status; 1585524Sstever@gmail.com 1595524Sstever@gmail.com public: 1605524Sstever@gmail.com void post_interrupt(int int_num, int index); 1615524Sstever@gmail.com 1625524Sstever@gmail.com void zero_fill_64(Addr addr) { 1635524Sstever@gmail.com static int warned = 0; 1645524Sstever@gmail.com if (!warned) { 1655524Sstever@gmail.com warn ("WH64 is not implemented"); 1665524Sstever@gmail.com warned = 1; 1675524Sstever@gmail.com } 1685524Sstever@gmail.com }; 1695524Sstever@gmail.com 1705524Sstever@gmail.com public: 1715524Sstever@gmail.com struct Params : public BaseCPU::Params 1725524Sstever@gmail.com { 1735524Sstever@gmail.com int width; 1745524Sstever@gmail.com#if FULL_SYSTEM 1752889Sbinkertn@umich.edu AlphaITB *itb; 1764850Snate@binkert.org AlphaDTB *dtb; 1774850Snate@binkert.org#else 1784850Snate@binkert.org Memory *mem; 1794850Snate@binkert.org Process *process; 1804850Snate@binkert.org#endif 1815801Snate@binkert.org }; 1825824Ssaidi@eecs.umich.edu SimpleCPU(Params *params); 1834850Snate@binkert.org virtual ~SimpleCPU(); 1845801Snate@binkert.org 1854850Snate@binkert.org public: 1864850Snate@binkert.org // execution context 1875801Snate@binkert.org ExecContext *xc; 1884850Snate@binkert.org 1894850Snate@binkert.org void switchOut(Sampler *s); 1904850Snate@binkert.org void takeOverFrom(BaseCPU *oldCPU); 1912889Sbinkertn@umich.edu 1922889Sbinkertn@umich.edu#if FULL_SYSTEM 1932889Sbinkertn@umich.edu Addr dbg_vtophys(Addr addr); 1942889Sbinkertn@umich.edu 1952889Sbinkertn@umich.edu bool interval_stats; 1962889Sbinkertn@umich.edu#endif 1972889Sbinkertn@umich.edu 1982889Sbinkertn@umich.edu // current instruction 1992889Sbinkertn@umich.edu MachInst inst; 2002889Sbinkertn@umich.edu 2012889Sbinkertn@umich.edu#if SIMPLE_CPU_MEM_TIMING 2022889Sbinkertn@umich.edu Packet *retry_pkt; 2032889Sbinkertn@umich.edu#elif SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE 2042889Sbinkertn@umich.edu CpuRequest *ifetch_req; 2052889Sbinkertn@umich.edu Packet *ifetch_pkt; 2062889Sbinkertn@umich.edu CpuRequest *data_read_req; 2072889Sbinkertn@umich.edu Packet *data_read_pkt; 2082889Sbinkertn@umich.edu CpuRequest *data_write_req; 2092889Sbinkertn@umich.edu Packet *data_write_pkt; 2102889Sbinkertn@umich.edu#endif 2112889Sbinkertn@umich.edu 2122889Sbinkertn@umich.edu // Pointer to the sampler that is telling us to switchover. 2132889Sbinkertn@umich.edu // Used to signal the completion of the pipe drain and schedule 2142889Sbinkertn@umich.edu // the next switchover 2152889Sbinkertn@umich.edu Sampler *sampler; 2162889Sbinkertn@umich.edu 2174053Sbinkertn@umich.edu StaticInstPtr<TheISA> curStaticInst; 2184053Sbinkertn@umich.edu 2195799Snate@binkert.org Status status() const { return _status; } 2205799Snate@binkert.org 2214053Sbinkertn@umich.edu virtual void activateContext(int thread_num, int delay); 2225473Snate@binkert.org virtual void suspendContext(int thread_num); 2235473Snate@binkert.org virtual void deallocateContext(int thread_num); 2245473Snate@binkert.org virtual void haltContext(int thread_num); 2255473Snate@binkert.org 2265473Snate@binkert.org // statistics 2275473Snate@binkert.org virtual void regStats(); 2285473Snate@binkert.org virtual void resetStats(); 2295473Snate@binkert.org 2305473Snate@binkert.org // number of simulated instructions 2315473Snate@binkert.org Counter numInst; 2325473Snate@binkert.org Counter startNumInst; 2335473Snate@binkert.org Stats::Scalar<> numInsts; 2345473Snate@binkert.org 2355473Snate@binkert.org virtual Counter totalInstructions() const 2365473Snate@binkert.org { 2375473Snate@binkert.org return numInst - startNumInst; 2385473Snate@binkert.org } 2395473Snate@binkert.org 2405473Snate@binkert.org // number of simulated memory references 2415473Snate@binkert.org Stats::Scalar<> numMemRefs; 2425473Snate@binkert.org 2432889Sbinkertn@umich.edu // number of simulated loads 2442889Sbinkertn@umich.edu Counter numLoad; 2452889Sbinkertn@umich.edu Counter startNumLoad; 2465470Snate@binkert.org 2475470Snate@binkert.org // number of idle cycles 2485470Snate@binkert.org Stats::Average<> notIdleFraction; 2495470Snate@binkert.org Stats::Formula idleFraction; 2505470Snate@binkert.org 2512889Sbinkertn@umich.edu // number of cycles stalled for I-cache responses 2522889Sbinkertn@umich.edu Stats::Scalar<> icacheStallCycles; 2532889Sbinkertn@umich.edu Counter lastIcacheStall; 2542889Sbinkertn@umich.edu 2555801Snate@binkert.org // number of cycles stalled for I-cache retries 2565801Snate@binkert.org Stats::Scalar<> icacheRetryCycles; 2575824Ssaidi@eecs.umich.edu Counter lastIcacheRetry; 2585456Ssaidi@eecs.umich.edu 2595528Sstever@gmail.com // number of cycles stalled for D-cache responses 2605528Sstever@gmail.com Stats::Scalar<> dcacheStallCycles; 2615528Sstever@gmail.com Counter lastDcacheStall; 2622967Sktlim@umich.edu 2632967Sktlim@umich.edu // number of cycles stalled for D-cache retries 2642967Sktlim@umich.edu Stats::Scalar<> dcacheRetryCycles; 2652967Sktlim@umich.edu Counter lastDcacheRetry; 2662889Sbinkertn@umich.edu 2672889Sbinkertn@umich.edu void sendIcacheRequest(Packet *pkt); 2682889Sbinkertn@umich.edu void sendDcacheRequest(Packet *pkt); 2692922Sktlim@umich.edu void processResponse(Packet &response); 2702922Sktlim@umich.edu 2714053Sbinkertn@umich.edu Packet * processRetry(); 2725470Snate@binkert.org void recvStatusChange(Port::Status status) {} 2732889Sbinkertn@umich.edu 2742889Sbinkertn@umich.edu virtual void serialize(std::ostream &os); 2755801Snate@binkert.org virtual void unserialize(Checkpoint *cp, const std::string §ion); 2762889Sbinkertn@umich.edu 2772889Sbinkertn@umich.edu template <class T> 2782889Sbinkertn@umich.edu Fault read(Addr addr, T &data, unsigned flags); 2792889Sbinkertn@umich.edu 2802889Sbinkertn@umich.edu template <class T> 2815801Snate@binkert.org Fault write(T data, Addr addr, unsigned flags, uint64_t *res); 2822889Sbinkertn@umich.edu 2832889Sbinkertn@umich.edu // These functions are only used in CPU models that split 2845801Snate@binkert.org // effective address computation from the actual memory access. 2853645Sbinkertn@umich.edu void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); } 2865801Snate@binkert.org Addr getEA() { panic("SimpleCPU::getEA() not implemented\n"); } 2872889Sbinkertn@umich.edu 2885586Snate@binkert.org void prefetch(Addr addr, unsigned flags) 2895799Snate@binkert.org { 2904053Sbinkertn@umich.edu // need to do this... 2915586Snate@binkert.org } 2925586Snate@binkert.org 2935586Snate@binkert.org void writeHint(Addr addr, int size, unsigned flags) 2945586Snate@binkert.org { 2955586Snate@binkert.org // need to do this... 2965586Snate@binkert.org } 2975586Snate@binkert.org 2985799Snate@binkert.org Fault copySrcTranslate(Addr src); 2995586Snate@binkert.org 3005586Snate@binkert.org Fault copy(Addr dest); 3014053Sbinkertn@umich.edu 3025586Snate@binkert.org // The register accessor methods provide the index of the 3035586Snate@binkert.org // instruction's operand (e.g., 0 or 1), not the architectural 3045586Snate@binkert.org // register index, to simplify the implementation of register 3055586Snate@binkert.org // renaming. We find the architectural register index by indexing 3064042Sbinkertn@umich.edu // into the instruction's own operand index table. Note that a 3075586Snate@binkert.org // raw pointer to the StaticInst is provided instead of a 3085799Snate@binkert.org // ref-counted StaticInstPtr to redice overhead. This is fine as 3095586Snate@binkert.org // long as these methods don't copy the pointer into any long-term 3105586Snate@binkert.org // storage (which is pretty hard to imagine they would have reason 3115799Snate@binkert.org // to do). 3124053Sbinkertn@umich.edu 3134074Sbinkertn@umich.edu uint64_t readIntReg(const StaticInst<TheISA> *si, int idx) 3145799Snate@binkert.org { 3155950Ssaidi@eecs.umich.edu return xc->readIntReg(si->srcRegIdx(idx)); 3165606Snate@binkert.org } 3174074Sbinkertn@umich.edu 3185799Snate@binkert.org float readFloatRegSingle(const StaticInst<TheISA> *si, int idx) 3194042Sbinkertn@umich.edu { 3205799Snate@binkert.org int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 3214042Sbinkertn@umich.edu return xc->readFloatRegSingle(reg_idx); 3224042Sbinkertn@umich.edu } 3235799Snate@binkert.org 3245799Snate@binkert.org double readFloatRegDouble(const StaticInst<TheISA> *si, int idx) 3252889Sbinkertn@umich.edu { 3262889Sbinkertn@umich.edu int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 3272889Sbinkertn@umich.edu return xc->readFloatRegDouble(reg_idx); 3282891Sbinkertn@umich.edu } 3295604Snate@binkert.org 3305604Snate@binkert.org uint64_t readFloatRegInt(const StaticInst<TheISA> *si, int idx) 3315604Snate@binkert.org { 3325604Snate@binkert.org int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 3333887Sbinkertn@umich.edu return xc->readFloatRegInt(reg_idx); 3342899Sbinkertn@umich.edu } 3352899Sbinkertn@umich.edu 3362899Sbinkertn@umich.edu void setIntReg(const StaticInst<TheISA> *si, int idx, uint64_t val) 3374042Sbinkertn@umich.edu { 3382899Sbinkertn@umich.edu xc->setIntReg(si->destRegIdx(idx), val); 3392899Sbinkertn@umich.edu } 3402899Sbinkertn@umich.edu 3412899Sbinkertn@umich.edu void setFloatRegSingle(const StaticInst<TheISA> *si, int idx, float val) 3425604Snate@binkert.org { 3435604Snate@binkert.org int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 3445604Snate@binkert.org xc->setFloatRegSingle(reg_idx, val); 3455604Snate@binkert.org } 3465604Snate@binkert.org 3475604Snate@binkert.org void setFloatRegDouble(const StaticInst<TheISA> *si, int idx, double val) 3485604Snate@binkert.org { 3495604Snate@binkert.org int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 3505604Snate@binkert.org xc->setFloatRegDouble(reg_idx, val); 3515604Snate@binkert.org } 3525604Snate@binkert.org 3535604Snate@binkert.org void setFloatRegInt(const StaticInst<TheISA> *si, int idx, uint64_t val) 3545604Snate@binkert.org { 3555604Snate@binkert.org int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 3565604Snate@binkert.org xc->setFloatRegInt(reg_idx, val); 3575604Snate@binkert.org } 3582899Sbinkertn@umich.edu 3595604Snate@binkert.org uint64_t readPC() { return xc->readPC(); } 3602889Sbinkertn@umich.edu void setNextPC(uint64_t val) { xc->setNextPC(val); } 3612889Sbinkertn@umich.edu 3622889Sbinkertn@umich.edu uint64_t readUniq() { return xc->readUniq(); } 3632889Sbinkertn@umich.edu void setUniq(uint64_t val) { xc->setUniq(val); } 3642889Sbinkertn@umich.edu 3652889Sbinkertn@umich.edu uint64_t readFpcr() { return xc->readFpcr(); } 3662889Sbinkertn@umich.edu void setFpcr(uint64_t val) { xc->setFpcr(val); } 3672889Sbinkertn@umich.edu 3682889Sbinkertn@umich.edu#if FULL_SYSTEM 3695586Snate@binkert.org uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); } 3705586Snate@binkert.org Fault setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); } 3715586Snate@binkert.org Fault hwrei() { return xc->hwrei(); } 3725586Snate@binkert.org int readIntrFlag() { return xc->readIntrFlag(); } 3735586Snate@binkert.org void setIntrFlag(int val) { xc->setIntrFlag(val); } 3745586Snate@binkert.org bool inPalMode() { return xc->inPalMode(); } 3755586Snate@binkert.org void ev5_trap(Fault fault) { xc->ev5_trap(fault); } 3765586Snate@binkert.org bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } 3772889Sbinkertn@umich.edu#else 3782889Sbinkertn@umich.edu void syscall() { xc->syscall(); } 3792889Sbinkertn@umich.edu#endif 3802889Sbinkertn@umich.edu 3812889Sbinkertn@umich.edu bool misspeculating() { return xc->misspeculating(); } 3822889Sbinkertn@umich.edu ExecContext *xcBase() { return xc; } 3832889Sbinkertn@umich.edu}; 384 385#endif // __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__ 386