base.hh revision 5348
13804SN/A/* 29235Sandreas.hansson@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 39235Sandreas.hansson@arm.com * All rights reserved. 49235Sandreas.hansson@arm.com * 59235Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 69235Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 79235Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 89235Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 99235Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 109235Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 119235Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 129235Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 139235Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 143804SN/A * this software without specific prior written permission. 153804SN/A * 163804SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173804SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183804SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193804SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203804SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213804SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223804SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233804SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243804SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253804SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263804SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273804SN/A * 283804SN/A * Authors: Steve Reinhardt 293804SN/A * Dave Greene 303804SN/A * Nathan Binkert 313804SN/A */ 323804SN/A 333804SN/A#ifndef __CPU_SIMPLE_BASE_HH__ 343804SN/A#define __CPU_SIMPLE_BASE_HH__ 353804SN/A 363804SN/A#include "arch/predecoder.hh" 373804SN/A#include "base/statistics.hh" 383804SN/A#include "config/full_system.hh" 393804SN/A#include "cpu/base.hh" 403804SN/A#include "cpu/simple_thread.hh" 419235Sandreas.hansson@arm.com#include "cpu/pc_event.hh" 423804SN/A#include "cpu/static_inst.hh" 433804SN/A#include "mem/packet.hh" 449235Sandreas.hansson@arm.com#include "mem/port.hh" 459235Sandreas.hansson@arm.com#include "mem/request.hh" 463804SN/A#include "sim/eventq.hh" 478229SN/A#include "sim/system.hh" 488902SN/A 498229SN/A// forward declarations 509235Sandreas.hansson@arm.com#if FULL_SYSTEM 513804SN/Aclass Processor; 528918SN/Anamespace TheISA 539235Sandreas.hansson@arm.com{ 549235Sandreas.hansson@arm.com class ITB; 559235Sandreas.hansson@arm.com class DTB; 568918SN/A} 579235Sandreas.hansson@arm.comclass MemObject; 589235Sandreas.hansson@arm.com 593804SN/A#else 603804SN/A 619235Sandreas.hansson@arm.comclass Process; 623804SN/A 633804SN/A#endif // FULL_SYSTEM 643804SN/A 653804SN/Aclass RemoteGDB; 668918SN/Aclass GDBListener; 673804SN/A 688918SN/Anamespace TheISA 699235Sandreas.hansson@arm.com{ 708918SN/A class Predecoder; 718918SN/A} 728918SN/Aclass ThreadContext; 738918SN/Aclass Checkpoint; 748918SN/A 758918SN/Anamespace Trace { 768918SN/A class InstRecord; 778918SN/A} 788918SN/A 798918SN/A 808918SN/Aclass BaseSimpleCPU : public BaseCPU 818918SN/A{ 828918SN/A protected: 838918SN/A typedef TheISA::MiscReg MiscReg; 848918SN/A typedef TheISA::FloatReg FloatReg; 858918SN/A typedef TheISA::FloatRegBits FloatRegBits; 868918SN/A 878918SN/A protected: 888918SN/A Trace::InstRecord *traceData; 898918SN/A 908918SN/A inline void checkPcEventQueue() { 918918SN/A Addr oldpc; 929235Sandreas.hansson@arm.com do { 933804SN/A oldpc = thread->readPC(); 943804SN/A system->pcEventQueue.service(tc); 953804SN/A } while (oldpc != thread->readPC()); 963804SN/A } 973804SN/A 983832SN/A public: 993832SN/A void post_interrupt(int int_num, int index); 1003832SN/A 1013832SN/A void zero_fill_64(Addr addr) { 1023832SN/A static int warned = 0; 1033832SN/A if (!warned) { 1043832SN/A warn ("WH64 is not implemented"); 1053804SN/A warned = 1; 1068918SN/A } 1073804SN/A }; 1083804SN/A 1093804SN/A public: 1103804SN/A struct Params : public BaseCPU::Params 1113804SN/A { 1123804SN/A TheISA::ITB *itb; 1133804SN/A TheISA::DTB *dtb; 1148918SN/A#if !FULL_SYSTEM 1159235Sandreas.hansson@arm.com Process *process; 1168918SN/A#endif 1178918SN/A }; 1188918SN/A BaseSimpleCPU(Params *params); 1198918SN/A virtual ~BaseSimpleCPU(); 1208918SN/A 1219235Sandreas.hansson@arm.com public: 1225609SN/A /** SimpleThread object, provides all the architectural state. */ 1235609SN/A SimpleThread *thread; 1245609SN/A 1255609SN/A /** ThreadContext object, provides an interface for external 1265608SN/A * objects to modify this thread's state. 1279235Sandreas.hansson@arm.com */ 1283804SN/A ThreadContext *tc; 1293804SN/A protected: 1303804SN/A int cpuId; 1313804SN/A 1323804SN/A public: 1333804SN/A 1343804SN/A#if FULL_SYSTEM 1353804SN/A Addr dbg_vtophys(Addr addr); 1365608SN/A 1379235Sandreas.hansson@arm.com bool interval_stats; 1383804SN/A#endif 1393804SN/A 1403804SN/A // current instruction 1413804SN/A TheISA::MachInst inst; 1428902SN/A 1433804SN/A // The predecoder 1443804SN/A TheISA::Predecoder predecoder; 1459235Sandreas.hansson@arm.com 1469235Sandreas.hansson@arm.com StaticInstPtr curStaticInst; 1473804SN/A StaticInstPtr curMacroStaticInst; 1483804SN/A 1493804SN/A //This is the offset from the current pc that fetch should be performed at 1503804SN/A Addr fetchOffset; 1515608SN/A //This flag says to stay at the current pc. This is useful for 1525608SN/A //instructions which go beyond MachInst boundaries. 1533804SN/A bool stayAtPC; 1543804SN/A 1553804SN/A void checkForInterrupts(); 1563804SN/A Fault setupFetchRequest(Request *req); 1575608SN/A void preExecute(); 1585608SN/A void postExecute(); 1593804SN/A void advancePC(Fault fault); 1603804SN/A 1613804SN/A virtual void deallocateContext(int thread_num); 1623804SN/A virtual void haltContext(int thread_num); 1635608SN/A 1645608SN/A // statistics 1653804SN/A virtual void regStats(); 1663804SN/A virtual void resetStats(); 1673804SN/A 1683804SN/A // number of simulated instructions 1698918SN/A Counter numInst; 1708918SN/A Counter startNumInst; 1718918SN/A Stats::Scalar<> numInsts; 1728918SN/A 1738918SN/A void countInst() 1748918SN/A { 1755608SN/A numInst++; 1765608SN/A numInsts++; 1773804SN/A 1783804SN/A thread->funcExeInst++; 1793804SN/A } 1803804SN/A 1818918SN/A virtual Counter totalInstructions() const 1828918SN/A { 1838918SN/A return numInst - startNumInst; 1848918SN/A } 1858918SN/A 1868918SN/A // Mask to align PCs to MachInst sized boundaries 1875608SN/A static const Addr PCMask = ~((Addr)sizeof(TheISA::MachInst) - 1); 1885608SN/A 1893804SN/A // number of simulated memory references 1903804SN/A Stats::Scalar<> numMemRefs; 1913804SN/A 1923804SN/A // number of simulated loads 1939235Sandreas.hansson@arm.com Counter numLoad; 1948918SN/A Counter startNumLoad; 1953804SN/A 1963804SN/A // number of idle cycles 1973804SN/A Stats::Average<> notIdleFraction; 1983804SN/A Stats::Formula idleFraction; 1995608SN/A 2008918SN/A // number of cycles stalled for I-cache responses 2013804SN/A Stats::Scalar<> icacheStallCycles; 2023804SN/A Counter lastIcacheStall; 2033804SN/A 2043804SN/A // number of cycles stalled for I-cache retries 2053804SN/A Stats::Scalar<> icacheRetryCycles; 2069235Sandreas.hansson@arm.com Counter lastIcacheRetry; 207 208 // number of cycles stalled for D-cache responses 209 Stats::Scalar<> dcacheStallCycles; 210 Counter lastDcacheStall; 211 212 // number of cycles stalled for D-cache retries 213 Stats::Scalar<> dcacheRetryCycles; 214 Counter lastDcacheRetry; 215 216 virtual void serialize(std::ostream &os); 217 virtual void unserialize(Checkpoint *cp, const std::string §ion); 218 219 // These functions are only used in CPU models that split 220 // effective address computation from the actual memory access. 221 void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); } 222 Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n"); 223 M5_DUMMY_RETURN} 224 225 void prefetch(Addr addr, unsigned flags) 226 { 227 // need to do this... 228 } 229 230 void writeHint(Addr addr, int size, unsigned flags) 231 { 232 // need to do this... 233 } 234 235 236 Fault copySrcTranslate(Addr src); 237 238 Fault copy(Addr dest); 239 240 // The register accessor methods provide the index of the 241 // instruction's operand (e.g., 0 or 1), not the architectural 242 // register index, to simplify the implementation of register 243 // renaming. We find the architectural register index by indexing 244 // into the instruction's own operand index table. Note that a 245 // raw pointer to the StaticInst is provided instead of a 246 // ref-counted StaticInstPtr to redice overhead. This is fine as 247 // long as these methods don't copy the pointer into any long-term 248 // storage (which is pretty hard to imagine they would have reason 249 // to do). 250 251 uint64_t readIntRegOperand(const StaticInst *si, int idx) 252 { 253 return thread->readIntReg(si->srcRegIdx(idx)); 254 } 255 256 FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width) 257 { 258 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 259 return thread->readFloatReg(reg_idx, width); 260 } 261 262 FloatReg readFloatRegOperand(const StaticInst *si, int idx) 263 { 264 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 265 return thread->readFloatReg(reg_idx); 266 } 267 268 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx, 269 int width) 270 { 271 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 272 return thread->readFloatRegBits(reg_idx, width); 273 } 274 275 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) 276 { 277 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 278 return thread->readFloatRegBits(reg_idx); 279 } 280 281 void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) 282 { 283 thread->setIntReg(si->destRegIdx(idx), val); 284 } 285 286 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, 287 int width) 288 { 289 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 290 thread->setFloatReg(reg_idx, val, width); 291 } 292 293 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) 294 { 295 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 296 thread->setFloatReg(reg_idx, val); 297 } 298 299 void setFloatRegOperandBits(const StaticInst *si, int idx, 300 FloatRegBits val, int width) 301 { 302 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 303 thread->setFloatRegBits(reg_idx, val, width); 304 } 305 306 void setFloatRegOperandBits(const StaticInst *si, int idx, 307 FloatRegBits val) 308 { 309 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 310 thread->setFloatRegBits(reg_idx, val); 311 } 312 313 uint64_t readPC() { return thread->readPC(); } 314 uint64_t readMicroPC() { return thread->readMicroPC(); } 315 uint64_t readNextPC() { return thread->readNextPC(); } 316 uint64_t readNextMicroPC() { return thread->readNextMicroPC(); } 317 uint64_t readNextNPC() { return thread->readNextNPC(); } 318 319 void setPC(uint64_t val) { thread->setPC(val); } 320 void setMicroPC(uint64_t val) { thread->setMicroPC(val); } 321 void setNextPC(uint64_t val) { thread->setNextPC(val); } 322 void setNextMicroPC(uint64_t val) { thread->setNextMicroPC(val); } 323 void setNextNPC(uint64_t val) { thread->setNextNPC(val); } 324 325 MiscReg readMiscRegNoEffect(int misc_reg) 326 { 327 return thread->readMiscRegNoEffect(misc_reg); 328 } 329 330 MiscReg readMiscReg(int misc_reg) 331 { 332 return thread->readMiscReg(misc_reg); 333 } 334 335 void setMiscRegNoEffect(int misc_reg, const MiscReg &val) 336 { 337 return thread->setMiscRegNoEffect(misc_reg, val); 338 } 339 340 void setMiscReg(int misc_reg, const MiscReg &val) 341 { 342 return thread->setMiscReg(misc_reg, val); 343 } 344 345 MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx) 346 { 347 int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 348 return thread->readMiscRegNoEffect(reg_idx); 349 } 350 351 MiscReg readMiscRegOperand(const StaticInst *si, int idx) 352 { 353 int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 354 return thread->readMiscReg(reg_idx); 355 } 356 357 void setMiscRegOperandNoEffect(const StaticInst *si, int idx, const MiscReg &val) 358 { 359 int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 360 return thread->setMiscRegNoEffect(reg_idx, val); 361 } 362 363 void setMiscRegOperand( 364 const StaticInst *si, int idx, const MiscReg &val) 365 { 366 int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 367 return thread->setMiscReg(reg_idx, val); 368 } 369 370 unsigned readStCondFailures() { 371 return thread->readStCondFailures(); 372 } 373 374 void setStCondFailures(unsigned sc_failures) { 375 thread->setStCondFailures(sc_failures); 376 } 377 378 MiscReg readRegOtherThread(int regIdx, int tid = -1) 379 { 380 panic("Simple CPU models do not support multithreaded " 381 "register access.\n"); 382 } 383 384 void setRegOtherThread(int regIdx, const MiscReg &val, int tid = -1) 385 { 386 panic("Simple CPU models do not support multithreaded " 387 "register access.\n"); 388 } 389 390 //Fault CacheOp(uint8_t Op, Addr EA); 391 392#if FULL_SYSTEM 393 Fault hwrei() { return thread->hwrei(); } 394 void ev5_trap(Fault fault) { fault->invoke(tc); } 395 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } 396#else 397 void syscall(int64_t callnum) { thread->syscall(callnum); } 398#endif 399 400 bool misspeculating() { return thread->misspeculating(); } 401 ThreadContext *tcBase() { return tc; } 402}; 403 404#endif // __CPU_SIMPLE_BASE_HH__ 405