cpu.hh revision 2632
11689SN/A/* 21689SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 31689SN/A * All rights reserved. 41689SN/A * 51689SN/A * Redistribution and use in source and binary forms, with or without 61689SN/A * modification, are permitted provided that the following conditions are 71689SN/A * met: redistributions of source code must retain the above copyright 81689SN/A * notice, this list of conditions and the following disclaimer; 91689SN/A * redistributions in binary form must reproduce the above copyright 101689SN/A * notice, this list of conditions and the following disclaimer in the 111689SN/A * documentation and/or other materials provided with the distribution; 121689SN/A * neither the name of the copyright holders nor the names of its 131689SN/A * contributors may be used to endorse or promote products derived from 141689SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271689SN/A */ 281689SN/A 291060SN/A//Todo: Add in a lot of the functions that are ISA specific. Also define 301060SN/A//the functions that currently exist within the base cpu class. Define 311060SN/A//everything for the simobject stuff so it can be serialized and 321060SN/A//instantiated, add in debugging statements everywhere. Have CPU schedule 331689SN/A//itself properly. Threads! 341060SN/A// Avoid running stages and advancing queues if idle/stalled. 351060SN/A 361755SN/A#ifndef __CPU_O3_CPU_FULL_CPU_HH__ 371755SN/A#define __CPU_O3_CPU_FULL_CPU_HH__ 381060SN/A 391060SN/A#include <iostream> 401060SN/A#include <list> 411681SN/A#include <vector> 421060SN/A 431060SN/A#include "base/statistics.hh" 441060SN/A#include "base/timebuf.hh" 451858SN/A#include "config/full_system.hh" 461717SN/A#include "cpu/base.hh" 472190SN/A#include "cpu/cpu_exec_context.hh" 481717SN/A#include "cpu/o3/comm.hh" 491717SN/A#include "cpu/o3/cpu_policy.hh" 501060SN/A#include "sim/process.hh" 511060SN/A 522190SN/Aclass ExecContext; 531060SN/Aclass FunctionalMemory; 541060SN/Aclass Process; 551060SN/A 561060SN/Aclass BaseFullCPU : public BaseCPU 571060SN/A{ 581060SN/A //Stuff that's pretty ISA independent will go here. 591060SN/A public: 601464SN/A typedef BaseCPU::Params Params; 611061SN/A 621858SN/A#if FULL_SYSTEM 631061SN/A BaseFullCPU(Params ¶ms); 641061SN/A#else 651061SN/A BaseFullCPU(Params ¶ms); 661060SN/A#endif // FULL_SYSTEM 671681SN/A 681685SN/A protected: 691681SN/A int cpu_id; 701060SN/A}; 711060SN/A 721060SN/Atemplate <class Impl> 731755SN/Aclass FullO3CPU : public BaseFullCPU 741060SN/A{ 751060SN/A public: 761060SN/A //Put typedefs from the Impl here. 771060SN/A typedef typename Impl::CPUPol CPUPolicy; 781060SN/A typedef typename Impl::Params Params; 791061SN/A typedef typename Impl::DynInstPtr DynInstPtr; 801060SN/A 811060SN/A public: 821060SN/A enum Status { 831060SN/A Running, 841060SN/A Idle, 851060SN/A Halted, 861060SN/A Blocked // ? 871060SN/A }; 881060SN/A 891060SN/A Status _status; 901060SN/A 911060SN/A private: 921060SN/A class TickEvent : public Event 931060SN/A { 941060SN/A private: 951755SN/A FullO3CPU<Impl> *cpu; 961060SN/A 971060SN/A public: 981755SN/A TickEvent(FullO3CPU<Impl> *c); 991060SN/A void process(); 1001060SN/A const char *description(); 1011060SN/A }; 1021060SN/A 1031060SN/A TickEvent tickEvent; 1041060SN/A 1051060SN/A /// Schedule tick event, regardless of its current state. 1061060SN/A void scheduleTickEvent(int delay) 1071060SN/A { 1081060SN/A if (tickEvent.squashed()) 1091060SN/A tickEvent.reschedule(curTick + delay); 1101060SN/A else if (!tickEvent.scheduled()) 1111060SN/A tickEvent.schedule(curTick + delay); 1121060SN/A } 1131060SN/A 1141060SN/A /// Unschedule tick event, regardless of its current state. 1151060SN/A void unscheduleTickEvent() 1161060SN/A { 1171060SN/A if (tickEvent.scheduled()) 1181060SN/A tickEvent.squash(); 1191060SN/A } 1201060SN/A 1211060SN/A public: 1221755SN/A FullO3CPU(Params ¶ms); 1231755SN/A ~FullO3CPU(); 1241060SN/A 1251684SN/A void fullCPURegStats(); 1261684SN/A 1271684SN/A void tick(); 1281684SN/A 1291060SN/A void init(); 1301060SN/A 1311060SN/A void activateContext(int thread_num, int delay); 1321060SN/A void suspendContext(int thread_num); 1331060SN/A void deallocateContext(int thread_num); 1341060SN/A void haltContext(int thread_num); 1351060SN/A 1361060SN/A void switchOut(); 1371060SN/A void takeOverFrom(BaseCPU *oldCPU); 1381060SN/A 1391060SN/A /** Get the current instruction sequence number, and increment it. */ 1401060SN/A InstSeqNum getAndIncrementInstSeq(); 1411060SN/A 1421858SN/A#if FULL_SYSTEM 1431060SN/A /** Check if this address is a valid instruction address. */ 1441060SN/A bool validInstAddr(Addr addr) { return true; } 1451060SN/A 1461060SN/A /** Check if this address is a valid data address. */ 1471060SN/A bool validDataAddr(Addr addr) { return true; } 1481060SN/A 1491060SN/A /** Get instruction asid. */ 1501681SN/A int getInstAsid() 1512245SN/A { return regFile.miscRegs.getInstAsid(); } 1521060SN/A 1531060SN/A /** Get data asid. */ 1541681SN/A int getDataAsid() 1552245SN/A { return regFile.miscRegs.getDataAsid(); } 1561060SN/A#else 1571060SN/A bool validInstAddr(Addr addr) 1581681SN/A { return thread[0]->validInstAddr(addr); } 1591060SN/A 1601060SN/A bool validDataAddr(Addr addr) 1611681SN/A { return thread[0]->validDataAddr(addr); } 1621060SN/A 1632190SN/A int getInstAsid() { return thread[0]->getInstAsid(); } 1642190SN/A int getDataAsid() { return thread[0]->getDataAsid(); } 1651060SN/A 1661060SN/A#endif 1671060SN/A 1681060SN/A // 1691060SN/A // New accessors for new decoder. 1701060SN/A // 1711060SN/A uint64_t readIntReg(int reg_idx); 1721060SN/A 1732455SN/A FloatReg readFloatReg(int reg_idx); 1741060SN/A 1752455SN/A FloatReg readFloatReg(int reg_idx, int width); 1761060SN/A 1772455SN/A FloatRegBits readFloatRegBits(int reg_idx); 1782455SN/A 1792455SN/A FloatRegBits readFloatRegBits(int reg_idx, int width); 1801060SN/A 1811060SN/A void setIntReg(int reg_idx, uint64_t val); 1821060SN/A 1832455SN/A void setFloatReg(int reg_idx, FloatReg val, int width); 1841060SN/A 1852455SN/A void setFloatReg(int reg_idx, FloatReg val, int width); 1861060SN/A 1872455SN/A void setFloatRegBits(int reg_idx, FloatRegBits val); 1882455SN/A 1892455SN/A void setFloatRegBits(int reg_idx, FloatRegBits val); 1901060SN/A 1911060SN/A uint64_t readPC(); 1921060SN/A 1931060SN/A void setNextPC(uint64_t val); 1941060SN/A 1951060SN/A void setPC(Addr new_PC); 1961060SN/A 1971060SN/A /** Function to add instruction onto the head of the list of the 1981060SN/A * instructions. Used when new instructions are fetched. 1991060SN/A */ 2001061SN/A void addInst(DynInstPtr &inst); 2011060SN/A 2021060SN/A /** Function to tell the CPU that an instruction has completed. */ 2031060SN/A void instDone(); 2041060SN/A 2051060SN/A /** Remove all instructions in back of the given instruction, but leave 2061060SN/A * that instruction in the list. This is useful in a squash, when there 2071060SN/A * are instructions in this list that don't exist in structures such as 2081060SN/A * the ROB. The instruction doesn't have to be the last instruction in 2091060SN/A * the list, but will be once this function completes. 2101060SN/A * @todo: Remove only up until that inst? Squashed inst is most likely 2111060SN/A * valid. 2121060SN/A */ 2131061SN/A void removeBackInst(DynInstPtr &inst); 2141060SN/A 2151060SN/A /** Remove an instruction from the front of the list. It is expected 2161060SN/A * that there are no instructions in front of it (that is, none are older 2171060SN/A * than the instruction being removed). Used when retiring instructions. 2181060SN/A * @todo: Remove the argument to this function, and just have it remove 2191060SN/A * last instruction once it's verified that commit has the same ordering 2201060SN/A * as the instruction list. 2211060SN/A */ 2221061SN/A void removeFrontInst(DynInstPtr &inst); 2231060SN/A 2241060SN/A /** Remove all instructions that are not currently in the ROB. */ 2251060SN/A void removeInstsNotInROB(); 2261060SN/A 2271062SN/A /** Remove all instructions younger than the given sequence number. */ 2281062SN/A void removeInstsUntil(const InstSeqNum &seq_num); 2291062SN/A 2301060SN/A /** Remove all instructions from the list. */ 2311060SN/A void removeAllInsts(); 2321060SN/A 2331060SN/A void dumpInsts(); 2341060SN/A 2351060SN/A /** Basically a wrapper function so that instructions executed at 2361060SN/A * commit can tell the instruction queue that they have completed. 2371060SN/A * Eventually this hack should be removed. 2381060SN/A */ 2391061SN/A void wakeDependents(DynInstPtr &inst); 2401060SN/A 2411060SN/A public: 2421060SN/A /** List of all the instructions in flight. */ 2431061SN/A list<DynInstPtr> instList; 2441060SN/A 2451060SN/A //not sure these should be private. 2461060SN/A protected: 2471060SN/A /** The fetch stage. */ 2481060SN/A typename CPUPolicy::Fetch fetch; 2491060SN/A 2501060SN/A /** The fetch stage's status. */ 2511060SN/A typename CPUPolicy::Fetch::Status fetchStatus; 2521060SN/A 2531060SN/A /** The decode stage. */ 2541060SN/A typename CPUPolicy::Decode decode; 2551060SN/A 2561060SN/A /** The decode stage's status. */ 2571060SN/A typename CPUPolicy::Decode::Status decodeStatus; 2581060SN/A 2591060SN/A /** The dispatch stage. */ 2601060SN/A typename CPUPolicy::Rename rename; 2611060SN/A 2621060SN/A /** The dispatch stage's status. */ 2631060SN/A typename CPUPolicy::Rename::Status renameStatus; 2641060SN/A 2651060SN/A /** The issue/execute/writeback stages. */ 2661060SN/A typename CPUPolicy::IEW iew; 2671060SN/A 2681060SN/A /** The issue/execute/writeback stage's status. */ 2691060SN/A typename CPUPolicy::IEW::Status iewStatus; 2701060SN/A 2711060SN/A /** The commit stage. */ 2721060SN/A typename CPUPolicy::Commit commit; 2731060SN/A 2741060SN/A /** The fetch stage's status. */ 2751060SN/A typename CPUPolicy::Commit::Status commitStatus; 2761060SN/A 2771060SN/A //Might want to just pass these objects in to the constructors of the 2781060SN/A //appropriate stage. regFile is in iew, freeList in dispatch, renameMap 2791060SN/A //in dispatch, and the rob in commit. 2801060SN/A /** The register file. */ 2811060SN/A typename CPUPolicy::RegFile regFile; 2821060SN/A 2831060SN/A /** The free list. */ 2841060SN/A typename CPUPolicy::FreeList freeList; 2851060SN/A 2861060SN/A /** The rename map. */ 2871060SN/A typename CPUPolicy::RenameMap renameMap; 2881060SN/A 2891060SN/A /** The re-order buffer. */ 2901060SN/A typename CPUPolicy::ROB rob; 2911060SN/A 2921060SN/A public: 2931060SN/A /** Typedefs from the Impl to get the structs that each of the 2941060SN/A * time buffers should use. 2951060SN/A */ 2961061SN/A typedef typename CPUPolicy::TimeStruct TimeStruct; 2971060SN/A 2981061SN/A typedef typename CPUPolicy::FetchStruct FetchStruct; 2991060SN/A 3001061SN/A typedef typename CPUPolicy::DecodeStruct DecodeStruct; 3011060SN/A 3021061SN/A typedef typename CPUPolicy::RenameStruct RenameStruct; 3031060SN/A 3041061SN/A typedef typename CPUPolicy::IEWStruct IEWStruct; 3051060SN/A 3061060SN/A /** The main time buffer to do backwards communication. */ 3071060SN/A TimeBuffer<TimeStruct> timeBuffer; 3081060SN/A 3091060SN/A /** The fetch stage's instruction queue. */ 3101060SN/A TimeBuffer<FetchStruct> fetchQueue; 3111060SN/A 3121060SN/A /** The decode stage's instruction queue. */ 3131060SN/A TimeBuffer<DecodeStruct> decodeQueue; 3141060SN/A 3151060SN/A /** The rename stage's instruction queue. */ 3161060SN/A TimeBuffer<RenameStruct> renameQueue; 3171060SN/A 3181060SN/A /** The IEW stage's instruction queue. */ 3191060SN/A TimeBuffer<IEWStruct> iewQueue; 3201060SN/A 3211060SN/A public: 3221060SN/A /** The temporary exec context to support older accessors. */ 3232190SN/A CPUExecContext *cpuXC; 3241060SN/A 3251060SN/A /** Temporary function to get pointer to exec context. */ 3261681SN/A ExecContext *xcBase() 3271681SN/A { 3282190SN/A return thread[0]->getProxy(); 3292190SN/A } 3302190SN/A 3312190SN/A CPUExecContext *cpuXCBase() 3322190SN/A { 3331681SN/A return thread[0]; 3341681SN/A } 3351060SN/A 3361060SN/A InstSeqNum globalSeqNum; 3371060SN/A 3381858SN/A#if FULL_SYSTEM 3391060SN/A System *system; 3401060SN/A 3411060SN/A MemoryController *memCtrl; 3421060SN/A PhysicalMemory *physmem; 3431060SN/A 3441060SN/A AlphaITB *itb; 3451060SN/A AlphaDTB *dtb; 3461060SN/A 3471060SN/A// SWContext *swCtx; 3481060SN/A#endif 3492190SN/A std::vector<CPUExecContext *> thread; 3501060SN/A 3511060SN/A FunctionalMemory *mem; 3521060SN/A 3531060SN/A MemInterface *icacheInterface; 3541060SN/A MemInterface *dcacheInterface; 3551060SN/A 3561060SN/A bool deferRegistration; 3571060SN/A 3581060SN/A Counter numInsts; 3591060SN/A 3601060SN/A Counter funcExeInst; 3611060SN/A}; 3621060SN/A 3631060SN/A#endif 364