cpu.hh revision 2665
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. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Kevin Lim 291689SN/A */ 301689SN/A 311060SN/A//Todo: Add in a lot of the functions that are ISA specific. Also define 321060SN/A//the functions that currently exist within the base cpu class. Define 331060SN/A//everything for the simobject stuff so it can be serialized and 341060SN/A//instantiated, add in debugging statements everywhere. Have CPU schedule 351689SN/A//itself properly. Threads! 361060SN/A// Avoid running stages and advancing queues if idle/stalled. 371060SN/A 381755SN/A#ifndef __CPU_O3_CPU_FULL_CPU_HH__ 391755SN/A#define __CPU_O3_CPU_FULL_CPU_HH__ 401060SN/A 411060SN/A#include <iostream> 421060SN/A#include <list> 431681SN/A#include <vector> 441060SN/A 451060SN/A#include "base/statistics.hh" 461060SN/A#include "base/timebuf.hh" 471858SN/A#include "config/full_system.hh" 481717SN/A#include "cpu/base.hh" 492190SN/A#include "cpu/cpu_exec_context.hh" 501717SN/A#include "cpu/o3/comm.hh" 511717SN/A#include "cpu/o3/cpu_policy.hh" 521060SN/A#include "sim/process.hh" 531060SN/A 542190SN/Aclass ExecContext; 551060SN/Aclass FunctionalMemory; 561060SN/Aclass Process; 571060SN/A 581060SN/Aclass BaseFullCPU : public BaseCPU 591060SN/A{ 601060SN/A //Stuff that's pretty ISA independent will go here. 611060SN/A public: 621464SN/A typedef BaseCPU::Params Params; 631061SN/A 641858SN/A#if FULL_SYSTEM 651061SN/A BaseFullCPU(Params ¶ms); 661061SN/A#else 671061SN/A BaseFullCPU(Params ¶ms); 681060SN/A#endif // FULL_SYSTEM 691681SN/A 701685SN/A protected: 711681SN/A int cpu_id; 721060SN/A}; 731060SN/A 741060SN/Atemplate <class Impl> 751755SN/Aclass FullO3CPU : public BaseFullCPU 761060SN/A{ 771060SN/A public: 781060SN/A //Put typedefs from the Impl here. 791060SN/A typedef typename Impl::CPUPol CPUPolicy; 801060SN/A typedef typename Impl::Params Params; 811061SN/A typedef typename Impl::DynInstPtr DynInstPtr; 821060SN/A 831060SN/A public: 841060SN/A enum Status { 851060SN/A Running, 861060SN/A Idle, 871060SN/A Halted, 881060SN/A Blocked // ? 891060SN/A }; 901060SN/A 911060SN/A Status _status; 921060SN/A 931060SN/A private: 941060SN/A class TickEvent : public Event 951060SN/A { 961060SN/A private: 971755SN/A FullO3CPU<Impl> *cpu; 981060SN/A 991060SN/A public: 1001755SN/A TickEvent(FullO3CPU<Impl> *c); 1011060SN/A void process(); 1021060SN/A const char *description(); 1031060SN/A }; 1041060SN/A 1051060SN/A TickEvent tickEvent; 1061060SN/A 1071060SN/A /// Schedule tick event, regardless of its current state. 1081060SN/A void scheduleTickEvent(int delay) 1091060SN/A { 1101060SN/A if (tickEvent.squashed()) 1111060SN/A tickEvent.reschedule(curTick + delay); 1121060SN/A else if (!tickEvent.scheduled()) 1131060SN/A tickEvent.schedule(curTick + delay); 1141060SN/A } 1151060SN/A 1161060SN/A /// Unschedule tick event, regardless of its current state. 1171060SN/A void unscheduleTickEvent() 1181060SN/A { 1191060SN/A if (tickEvent.scheduled()) 1201060SN/A tickEvent.squash(); 1211060SN/A } 1221060SN/A 1231060SN/A public: 1241755SN/A FullO3CPU(Params ¶ms); 1251755SN/A ~FullO3CPU(); 1261060SN/A 1271684SN/A void fullCPURegStats(); 1281684SN/A 1291684SN/A void tick(); 1301684SN/A 1311060SN/A void init(); 1321060SN/A 1331060SN/A void activateContext(int thread_num, int delay); 1341060SN/A void suspendContext(int thread_num); 1351060SN/A void deallocateContext(int thread_num); 1361060SN/A void haltContext(int thread_num); 1371060SN/A 1381060SN/A void switchOut(); 1391060SN/A void takeOverFrom(BaseCPU *oldCPU); 1401060SN/A 1411060SN/A /** Get the current instruction sequence number, and increment it. */ 1421060SN/A InstSeqNum getAndIncrementInstSeq(); 1431060SN/A 1441858SN/A#if FULL_SYSTEM 1451060SN/A /** Check if this address is a valid instruction address. */ 1461060SN/A bool validInstAddr(Addr addr) { return true; } 1471060SN/A 1481060SN/A /** Check if this address is a valid data address. */ 1491060SN/A bool validDataAddr(Addr addr) { return true; } 1501060SN/A 1511060SN/A /** Get instruction asid. */ 1521681SN/A int getInstAsid() 1532245SN/A { return regFile.miscRegs.getInstAsid(); } 1541060SN/A 1551060SN/A /** Get data asid. */ 1561681SN/A int getDataAsid() 1572245SN/A { return regFile.miscRegs.getDataAsid(); } 1581060SN/A#else 1591060SN/A bool validInstAddr(Addr addr) 1601681SN/A { return thread[0]->validInstAddr(addr); } 1611060SN/A 1621060SN/A bool validDataAddr(Addr addr) 1631681SN/A { return thread[0]->validDataAddr(addr); } 1641060SN/A 1652190SN/A int getInstAsid() { return thread[0]->getInstAsid(); } 1662190SN/A int getDataAsid() { return thread[0]->getDataAsid(); } 1671060SN/A 1681060SN/A#endif 1691060SN/A 1701060SN/A // 1711060SN/A // New accessors for new decoder. 1721060SN/A // 1731060SN/A uint64_t readIntReg(int reg_idx); 1741060SN/A 1752455SN/A FloatReg readFloatReg(int reg_idx); 1761060SN/A 1772455SN/A FloatReg readFloatReg(int reg_idx, int width); 1781060SN/A 1792455SN/A FloatRegBits readFloatRegBits(int reg_idx); 1802455SN/A 1812455SN/A FloatRegBits readFloatRegBits(int reg_idx, int width); 1821060SN/A 1831060SN/A void setIntReg(int reg_idx, uint64_t val); 1841060SN/A 1852455SN/A void setFloatReg(int reg_idx, FloatReg val, int width); 1861060SN/A 1872455SN/A void setFloatReg(int reg_idx, FloatReg val, int width); 1881060SN/A 1892455SN/A void setFloatRegBits(int reg_idx, FloatRegBits val); 1902455SN/A 1912455SN/A void setFloatRegBits(int reg_idx, FloatRegBits val); 1921060SN/A 1931060SN/A uint64_t readPC(); 1941060SN/A 1951060SN/A void setNextPC(uint64_t val); 1961060SN/A 1971060SN/A void setPC(Addr new_PC); 1981060SN/A 1991060SN/A /** Function to add instruction onto the head of the list of the 2001060SN/A * instructions. Used when new instructions are fetched. 2011060SN/A */ 2021061SN/A void addInst(DynInstPtr &inst); 2031060SN/A 2041060SN/A /** Function to tell the CPU that an instruction has completed. */ 2051060SN/A void instDone(); 2061060SN/A 2071060SN/A /** Remove all instructions in back of the given instruction, but leave 2081060SN/A * that instruction in the list. This is useful in a squash, when there 2091060SN/A * are instructions in this list that don't exist in structures such as 2101060SN/A * the ROB. The instruction doesn't have to be the last instruction in 2111060SN/A * the list, but will be once this function completes. 2121060SN/A * @todo: Remove only up until that inst? Squashed inst is most likely 2131060SN/A * valid. 2141060SN/A */ 2151061SN/A void removeBackInst(DynInstPtr &inst); 2161060SN/A 2171060SN/A /** Remove an instruction from the front of the list. It is expected 2181060SN/A * that there are no instructions in front of it (that is, none are older 2191060SN/A * than the instruction being removed). Used when retiring instructions. 2201060SN/A * @todo: Remove the argument to this function, and just have it remove 2211060SN/A * last instruction once it's verified that commit has the same ordering 2221060SN/A * as the instruction list. 2231060SN/A */ 2241061SN/A void removeFrontInst(DynInstPtr &inst); 2251060SN/A 2261060SN/A /** Remove all instructions that are not currently in the ROB. */ 2271060SN/A void removeInstsNotInROB(); 2281060SN/A 2291062SN/A /** Remove all instructions younger than the given sequence number. */ 2301062SN/A void removeInstsUntil(const InstSeqNum &seq_num); 2311062SN/A 2321060SN/A /** Remove all instructions from the list. */ 2331060SN/A void removeAllInsts(); 2341060SN/A 2351060SN/A void dumpInsts(); 2361060SN/A 2371060SN/A /** Basically a wrapper function so that instructions executed at 2381060SN/A * commit can tell the instruction queue that they have completed. 2391060SN/A * Eventually this hack should be removed. 2401060SN/A */ 2411061SN/A void wakeDependents(DynInstPtr &inst); 2421060SN/A 2431060SN/A public: 2441060SN/A /** List of all the instructions in flight. */ 2451061SN/A list<DynInstPtr> instList; 2461060SN/A 2471060SN/A //not sure these should be private. 2481060SN/A protected: 2491060SN/A /** The fetch stage. */ 2501060SN/A typename CPUPolicy::Fetch fetch; 2511060SN/A 2521060SN/A /** The fetch stage's status. */ 2531060SN/A typename CPUPolicy::Fetch::Status fetchStatus; 2541060SN/A 2551060SN/A /** The decode stage. */ 2561060SN/A typename CPUPolicy::Decode decode; 2571060SN/A 2581060SN/A /** The decode stage's status. */ 2591060SN/A typename CPUPolicy::Decode::Status decodeStatus; 2601060SN/A 2611060SN/A /** The dispatch stage. */ 2621060SN/A typename CPUPolicy::Rename rename; 2631060SN/A 2641060SN/A /** The dispatch stage's status. */ 2651060SN/A typename CPUPolicy::Rename::Status renameStatus; 2661060SN/A 2671060SN/A /** The issue/execute/writeback stages. */ 2681060SN/A typename CPUPolicy::IEW iew; 2691060SN/A 2701060SN/A /** The issue/execute/writeback stage's status. */ 2711060SN/A typename CPUPolicy::IEW::Status iewStatus; 2721060SN/A 2731060SN/A /** The commit stage. */ 2741060SN/A typename CPUPolicy::Commit commit; 2751060SN/A 2761060SN/A /** The fetch stage's status. */ 2771060SN/A typename CPUPolicy::Commit::Status commitStatus; 2781060SN/A 2791060SN/A //Might want to just pass these objects in to the constructors of the 2801060SN/A //appropriate stage. regFile is in iew, freeList in dispatch, renameMap 2811060SN/A //in dispatch, and the rob in commit. 2821060SN/A /** The register file. */ 2831060SN/A typename CPUPolicy::RegFile regFile; 2841060SN/A 2851060SN/A /** The free list. */ 2861060SN/A typename CPUPolicy::FreeList freeList; 2871060SN/A 2881060SN/A /** The rename map. */ 2891060SN/A typename CPUPolicy::RenameMap renameMap; 2901060SN/A 2911060SN/A /** The re-order buffer. */ 2921060SN/A typename CPUPolicy::ROB rob; 2931060SN/A 2941060SN/A public: 2951060SN/A /** Typedefs from the Impl to get the structs that each of the 2961060SN/A * time buffers should use. 2971060SN/A */ 2981061SN/A typedef typename CPUPolicy::TimeStruct TimeStruct; 2991060SN/A 3001061SN/A typedef typename CPUPolicy::FetchStruct FetchStruct; 3011060SN/A 3021061SN/A typedef typename CPUPolicy::DecodeStruct DecodeStruct; 3031060SN/A 3041061SN/A typedef typename CPUPolicy::RenameStruct RenameStruct; 3051060SN/A 3061061SN/A typedef typename CPUPolicy::IEWStruct IEWStruct; 3071060SN/A 3081060SN/A /** The main time buffer to do backwards communication. */ 3091060SN/A TimeBuffer<TimeStruct> timeBuffer; 3101060SN/A 3111060SN/A /** The fetch stage's instruction queue. */ 3121060SN/A TimeBuffer<FetchStruct> fetchQueue; 3131060SN/A 3141060SN/A /** The decode stage's instruction queue. */ 3151060SN/A TimeBuffer<DecodeStruct> decodeQueue; 3161060SN/A 3171060SN/A /** The rename stage's instruction queue. */ 3181060SN/A TimeBuffer<RenameStruct> renameQueue; 3191060SN/A 3201060SN/A /** The IEW stage's instruction queue. */ 3211060SN/A TimeBuffer<IEWStruct> iewQueue; 3221060SN/A 3231060SN/A public: 3241060SN/A /** The temporary exec context to support older accessors. */ 3252190SN/A CPUExecContext *cpuXC; 3261060SN/A 3271060SN/A /** Temporary function to get pointer to exec context. */ 3281681SN/A ExecContext *xcBase() 3291681SN/A { 3302190SN/A return thread[0]->getProxy(); 3312190SN/A } 3322190SN/A 3332190SN/A CPUExecContext *cpuXCBase() 3342190SN/A { 3351681SN/A return thread[0]; 3361681SN/A } 3371060SN/A 3381060SN/A InstSeqNum globalSeqNum; 3391060SN/A 3401858SN/A#if FULL_SYSTEM 3411060SN/A System *system; 3421060SN/A 3431060SN/A MemoryController *memCtrl; 3441060SN/A PhysicalMemory *physmem; 3451060SN/A 3461060SN/A AlphaITB *itb; 3471060SN/A AlphaDTB *dtb; 3481060SN/A 3491060SN/A// SWContext *swCtx; 3501060SN/A#endif 3512190SN/A std::vector<CPUExecContext *> thread; 3521060SN/A 3531060SN/A FunctionalMemory *mem; 3541060SN/A 3551060SN/A MemInterface *icacheInterface; 3561060SN/A MemInterface *dcacheInterface; 3571060SN/A 3581060SN/A bool deferRegistration; 3591060SN/A 3601060SN/A Counter numInsts; 3611060SN/A 3621060SN/A Counter funcExeInst; 3631060SN/A}; 3641060SN/A 3651060SN/A#endif 366