simple_thread.hh revision 2521
12686Sksewell@umich.edu/* 25254Sksewell@umich.edu * Copyright (c) 2001-2006 The Regents of The University of Michigan 35254Sksewell@umich.edu * All rights reserved. 42686Sksewell@umich.edu * 55254Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 65254Sksewell@umich.edu * modification, are permitted provided that the following conditions are 75254Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 85254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 95254Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 105254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 115254Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 125254Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 135254Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 145254Sksewell@umich.edu * this software without specific prior written permission. 152686Sksewell@umich.edu * 165254Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175254Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185254Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195254Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205254Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215254Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225254Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235254Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245254Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255254Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265254Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272706Sksewell@umich.edu */ 285254Sksewell@umich.edu 292686Sksewell@umich.edu#ifndef __CPU_CPU_EXEC_CONTEXT_HH__ 302686Sksewell@umich.edu#define __CPU_CPU_EXEC_CONTEXT_HH__ 314661Sksewell@umich.edu 322686Sksewell@umich.edu#include "arch/isa_traits.hh" 334661Sksewell@umich.edu#include "config/full_system.hh" 344661Sksewell@umich.edu#include "cpu/exec_context.hh" 354661Sksewell@umich.edu#include "mem/physical.hh" 364661Sksewell@umich.edu#include "mem/request.hh" 374661Sksewell@umich.edu#include "sim/byteswap.hh" 382980Sgblack@eecs.umich.edu#include "sim/eventq.hh" 392686Sksewell@umich.edu#include "sim/host.hh" 405222Sksewell@umich.edu#include "sim/serialize.hh" 415222Sksewell@umich.edu 425222Sksewell@umich.educlass BaseCPU; 435222Sksewell@umich.edu 445222Sksewell@umich.edu#if FULL_SYSTEM 455222Sksewell@umich.edu 462686Sksewell@umich.edu#include "sim/system.hh" 474661Sksewell@umich.edu#include "arch/tlb.hh" 482686Sksewell@umich.edu 495222Sksewell@umich.educlass FunctionProfile; 505222Sksewell@umich.educlass ProfileNode; 512686Sksewell@umich.educlass FunctionalPort; 525222Sksewell@umich.educlass PhysicalPort; 535222Sksewell@umich.edu 545222Sksewell@umich.edu 555222Sksewell@umich.edu#else // !FULL_SYSTEM 565222Sksewell@umich.edu 575222Sksewell@umich.edu#include "sim/process.hh" 585222Sksewell@umich.edu#include "mem/page_table.hh" 595222Sksewell@umich.educlass TranslatingPort; 605222Sksewell@umich.edu 615222Sksewell@umich.edu 625222Sksewell@umich.edu#endif // FULL_SYSTEM 635222Sksewell@umich.edu 645222Sksewell@umich.edu// 655222Sksewell@umich.edu// The CPUExecContext object represents a functional context for 665222Sksewell@umich.edu// instruction execution. It incorporates everything required for 675222Sksewell@umich.edu// architecture-level functional simulation of a single thread. 685222Sksewell@umich.edu// 695222Sksewell@umich.edu 705222Sksewell@umich.educlass CPUExecContext 715222Sksewell@umich.edu{ 725222Sksewell@umich.edu protected: 735222Sksewell@umich.edu typedef TheISA::RegFile RegFile; 745222Sksewell@umich.edu typedef TheISA::MachInst MachInst; 755222Sksewell@umich.edu typedef TheISA::MiscRegFile MiscRegFile; 762686Sksewell@umich.edu typedef TheISA::MiscReg MiscReg; 772686Sksewell@umich.edu typedef TheISA::FloatReg FloatReg; 782686Sksewell@umich.edu typedef TheISA::FloatRegBits FloatRegBits; 792686Sksewell@umich.edu public: 802686Sksewell@umich.edu typedef ExecContext::Status Status; 812686Sksewell@umich.edu 822686Sksewell@umich.edu private: 832686Sksewell@umich.edu Status _status; 842686Sksewell@umich.edu 852686Sksewell@umich.edu public: 862686Sksewell@umich.edu Status status() const { return _status; } 872686Sksewell@umich.edu 882686Sksewell@umich.edu void setStatus(Status newStatus) { _status = newStatus; } 892686Sksewell@umich.edu 902686Sksewell@umich.edu /// Set the status to Active. Optional delay indicates number of 912686Sksewell@umich.edu /// cycles to wait before beginning execution. 922686Sksewell@umich.edu void activate(int delay = 1); 932686Sksewell@umich.edu 942686Sksewell@umich.edu /// Set the status to Suspended. 952686Sksewell@umich.edu void suspend(); 962686Sksewell@umich.edu 972686Sksewell@umich.edu /// Set the status to Unallocated. 982686Sksewell@umich.edu void deallocate(); 992686Sksewell@umich.edu 1002686Sksewell@umich.edu /// Set the status to Halted. 1012686Sksewell@umich.edu void halt(); 1022686Sksewell@umich.edu 1032686Sksewell@umich.edu protected: 1042686Sksewell@umich.edu RegFile regs; // correct-path register context 1052686Sksewell@umich.edu 1062686Sksewell@umich.edu public: 1072686Sksewell@umich.edu // pointer to CPU associated with this context 1082686Sksewell@umich.edu BaseCPU *cpu; 1092686Sksewell@umich.edu 1102686Sksewell@umich.edu ProxyExecContext<CPUExecContext> *proxy; 1112686Sksewell@umich.edu 1122686Sksewell@umich.edu // Current instruction 1132686Sksewell@umich.edu MachInst inst; 1142686Sksewell@umich.edu 1152686Sksewell@umich.edu // Index of hardware thread context on the CPU that this represents. 1162686Sksewell@umich.edu int thread_num; 1172686Sksewell@umich.edu 1182686Sksewell@umich.edu // ID of this context w.r.t. the System or Process object to which 1195222Sksewell@umich.edu // it belongs. For full-system mode, this is the system CPU ID. 1202686Sksewell@umich.edu int cpu_id; 1212686Sksewell@umich.edu 1222686Sksewell@umich.edu Tick lastActivate; 1232686Sksewell@umich.edu Tick lastSuspend; 1242686Sksewell@umich.edu 1252686Sksewell@umich.edu System *system; 1262686Sksewell@umich.edu 1272686Sksewell@umich.edu 1282686Sksewell@umich.edu#if FULL_SYSTEM 1292686Sksewell@umich.edu AlphaITB *itb; 1305222Sksewell@umich.edu AlphaDTB *dtb; 1312686Sksewell@umich.edu 1322686Sksewell@umich.edu /** A functional port outgoing only for functional accesses to physical 1332686Sksewell@umich.edu * addresses.*/ 1342686Sksewell@umich.edu FunctionalPort *physPort; 1352686Sksewell@umich.edu 1362686Sksewell@umich.edu /** A functional port, outgoing only, for functional accesse to virtual 1375222Sksewell@umich.edu * addresses. That doen't require execution context information */ 1382686Sksewell@umich.edu VirtualPort *virtPort; 1392686Sksewell@umich.edu 1402686Sksewell@umich.edu FunctionProfile *profile; 1412686Sksewell@umich.edu ProfileNode *profileNode; 1422686Sksewell@umich.edu Addr profilePC; 1432686Sksewell@umich.edu void dumpFuncProfile(); 1442686Sksewell@umich.edu 1455222Sksewell@umich.edu /** Event for timing out quiesce instruction */ 1462686Sksewell@umich.edu struct EndQuiesceEvent : public Event 1472686Sksewell@umich.edu { 1482686Sksewell@umich.edu /** A pointer to the execution context that is quiesced */ 1492686Sksewell@umich.edu CPUExecContext *cpuXC; 1502686Sksewell@umich.edu 1512686Sksewell@umich.edu EndQuiesceEvent(CPUExecContext *_cpuXC); 1522686Sksewell@umich.edu 1532686Sksewell@umich.edu /** Event process to occur at interrupt*/ 1542686Sksewell@umich.edu virtual void process(); 1552686Sksewell@umich.edu 1562686Sksewell@umich.edu /** Event description */ 1575222Sksewell@umich.edu virtual const char *description(); 1582686Sksewell@umich.edu }; 1592686Sksewell@umich.edu EndQuiesceEvent quiesceEvent; 1602686Sksewell@umich.edu 1612686Sksewell@umich.edu Event *getQuiesceEvent() { return &quiesceEvent; } 1622686Sksewell@umich.edu 1632686Sksewell@umich.edu Tick readLastActivate() { return lastActivate; } 1642686Sksewell@umich.edu 1652686Sksewell@umich.edu Tick readLastSuspend() { return lastSuspend; } 1662686Sksewell@umich.edu 1672686Sksewell@umich.edu void profileClear(); 1682686Sksewell@umich.edu 1692686Sksewell@umich.edu void profileSample(); 1702686Sksewell@umich.edu 1715222Sksewell@umich.edu#else 1722686Sksewell@umich.edu /// Port that syscalls can use to access memory (provides translation step). 1732686Sksewell@umich.edu TranslatingPort *port; 1742686Sksewell@umich.edu 1752686Sksewell@umich.edu Process *process; 1762686Sksewell@umich.edu 1772686Sksewell@umich.edu // Address space ID. Note that this is used for TIMING cache 1782686Sksewell@umich.edu // simulation only; all functional memory accesses should use 1792686Sksewell@umich.edu // one of the FunctionalMemory pointers above. 1802686Sksewell@umich.edu short asid; 1812686Sksewell@umich.edu 1822686Sksewell@umich.edu#endif 1832686Sksewell@umich.edu 1842686Sksewell@umich.edu /** 1852686Sksewell@umich.edu * Temporary storage to pass the source address from copy_load to 1862686Sksewell@umich.edu * copy_store. 1872686Sksewell@umich.edu * @todo Remove this temporary when we have a better way to do it. 1882686Sksewell@umich.edu */ 1892686Sksewell@umich.edu Addr copySrcAddr; 1902686Sksewell@umich.edu /** 1912686Sksewell@umich.edu * Temp storage for the physical source address of a copy. 1922686Sksewell@umich.edu * @todo Remove this temporary when we have a better way to do it. 1932686Sksewell@umich.edu */ 1945222Sksewell@umich.edu Addr copySrcPhysAddr; 1952686Sksewell@umich.edu 1962686Sksewell@umich.edu 1972686Sksewell@umich.edu /* 1982686Sksewell@umich.edu * number of executed instructions, for matching with syscall trace 1992686Sksewell@umich.edu * points in EIO files. 2002686Sksewell@umich.edu */ 2012686Sksewell@umich.edu Counter func_exe_inst; 2022686Sksewell@umich.edu 2032686Sksewell@umich.edu // 2042686Sksewell@umich.edu // Count failed store conditionals so we can warn of apparent 2052686Sksewell@umich.edu // application deadlock situations. 2062686Sksewell@umich.edu unsigned storeCondFailures; 2072686Sksewell@umich.edu 2082686Sksewell@umich.edu // constructor: initialize context from given process structure 2092686Sksewell@umich.edu#if FULL_SYSTEM 2102686Sksewell@umich.edu CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_system, 2112686Sksewell@umich.edu AlphaITB *_itb, AlphaDTB *_dtb); 2122686Sksewell@umich.edu#else 2132686Sksewell@umich.edu CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid, 2142686Sksewell@umich.edu MemObject *memobj); 2152686Sksewell@umich.edu // Constructor to use XC to pass reg file around. Not used for anything 2165222Sksewell@umich.edu // else. 2172686Sksewell@umich.edu CPUExecContext(RegFile *regFile); 2182686Sksewell@umich.edu#endif 2192686Sksewell@umich.edu virtual ~CPUExecContext(); 2202686Sksewell@umich.edu 2212686Sksewell@umich.edu virtual void takeOverFrom(ExecContext *oldContext); 2222686Sksewell@umich.edu 2232686Sksewell@umich.edu void regStats(const std::string &name); 2242686Sksewell@umich.edu 2252686Sksewell@umich.edu void serialize(std::ostream &os); 2262686Sksewell@umich.edu void unserialize(Checkpoint *cp, const std::string §ion); 2272686Sksewell@umich.edu 2282686Sksewell@umich.edu BaseCPU *getCpuPtr() { return cpu; } 2292686Sksewell@umich.edu 2302686Sksewell@umich.edu ExecContext *getProxy() { return proxy; } 2312686Sksewell@umich.edu 2322686Sksewell@umich.edu int getThreadNum() { return thread_num; } 2332686Sksewell@umich.edu 2342686Sksewell@umich.edu#if FULL_SYSTEM 2352686Sksewell@umich.edu System *getSystemPtr() { return system; } 2364661Sksewell@umich.edu 2374661Sksewell@umich.edu AlphaITB *getITBPtr() { return itb; } 2385222Sksewell@umich.edu 2394661Sksewell@umich.edu AlphaDTB *getDTBPtr() { return dtb; } 2405222Sksewell@umich.edu 2414661Sksewell@umich.edu int getInstAsid() { return regs.instAsid(); } 2425222Sksewell@umich.edu int getDataAsid() { return regs.dataAsid(); } 2435222Sksewell@umich.edu 2445222Sksewell@umich.edu Fault translateInstReq(CpuRequestPtr &req) 2455222Sksewell@umich.edu { 2465222Sksewell@umich.edu return itb->translate(req, proxy); 2475222Sksewell@umich.edu } 2485222Sksewell@umich.edu 2495222Sksewell@umich.edu Fault translateDataReadReq(CpuRequestPtr &req) 2505222Sksewell@umich.edu { 2515222Sksewell@umich.edu return dtb->translate(req, proxy, false); 2525222Sksewell@umich.edu } 2535222Sksewell@umich.edu 2545222Sksewell@umich.edu Fault translateDataWriteReq(CpuRequestPtr &req) 2555222Sksewell@umich.edu { 2565222Sksewell@umich.edu return dtb->translate(req, proxy, true); 2575222Sksewell@umich.edu } 2585222Sksewell@umich.edu 2595222Sksewell@umich.edu FunctionalPort *getPhysPort() { return physPort; } 2605222Sksewell@umich.edu 2615222Sksewell@umich.edu /** Return a virtual port. If no exec context is specified then a static 2625222Sksewell@umich.edu * port is returned. Otherwise a port is created and returned. It must be 2635222Sksewell@umich.edu * deleted by deleteVirtPort(). */ 2645222Sksewell@umich.edu VirtualPort *getVirtPort(ExecContext *xc); 2655222Sksewell@umich.edu 2665222Sksewell@umich.edu void delVirtPort(VirtualPort *vp); 267 268#else 269 TranslatingPort *getMemPort() { return port; } 270 271 Process *getProcessPtr() { return process; } 272 273 int getInstAsid() { return asid; } 274 int getDataAsid() { return asid; } 275 276 Fault translateInstReq(CpuRequestPtr &req) 277 { 278 return process->pTable->translate(req); 279 } 280 281 Fault translateDataReadReq(CpuRequestPtr &req) 282 { 283 return process->pTable->translate(req); 284 } 285 286 Fault translateDataWriteReq(CpuRequestPtr &req) 287 { 288 return process->pTable->translate(req); 289 } 290 291#endif 292 293/* 294 template <class T> 295 Fault read(CpuRequestPtr &req, T &data) 296 { 297#if FULL_SYSTEM && THE_ISA == ALPHA_ISA 298 if (req->flags & LOCKED) { 299 req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr); 300 req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true); 301 } 302#endif 303 304 Fault error; 305 error = mem->prot_read(req->paddr, data, req->size); 306 data = LittleEndianGuest::gtoh(data); 307 return error; 308 } 309 310 template <class T> 311 Fault write(CpuRequestPtr &req, T &data) 312 { 313#if FULL_SYSTEM && THE_ISA == ALPHA_ISA 314 ExecContext *xc; 315 316 // If this is a store conditional, act appropriately 317 if (req->flags & LOCKED) { 318 xc = req->xc; 319 320 if (req->flags & UNCACHEABLE) { 321 // Don't update result register (see stq_c in isa_desc) 322 req->result = 2; 323 xc->setStCondFailures(0);//Needed? [RGD] 324 } else { 325 bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag); 326 Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag); 327 req->result = lock_flag; 328 if (!lock_flag || 329 ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { 330 xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); 331 xc->setStCondFailures(xc->readStCondFailures() + 1); 332 if (((xc->readStCondFailures()) % 100000) == 0) { 333 std::cerr << "Warning: " 334 << xc->readStCondFailures() 335 << " consecutive store conditional failures " 336 << "on cpu " << req->xc->readCpuId() 337 << std::endl; 338 } 339 return NoFault; 340 } 341 else xc->setStCondFailures(0); 342 } 343 } 344 345 // Need to clear any locked flags on other proccessors for 346 // this address. Only do this for succsful Store Conditionals 347 // and all other stores (WH64?). Unsuccessful Store 348 // Conditionals would have returned above, and wouldn't fall 349 // through. 350 for (int i = 0; i < system->execContexts.size(); i++){ 351 xc = system->execContexts[i]; 352 if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) == 353 (req->paddr & ~0xf)) { 354 xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); 355 } 356 } 357 358#endif 359 return mem->prot_write(req->paddr, (T)htog(data), req->size); 360 } 361*/ 362 virtual bool misspeculating(); 363 364 365 MachInst getInst() { return inst; } 366 367 void setInst(MachInst new_inst) 368 { 369 inst = new_inst; 370 } 371 372 Fault instRead(CpuRequestPtr &req) 373 { 374 panic("instRead not implemented"); 375 // return funcPhysMem->read(req, inst); 376 return NoFault; 377 } 378 379 void setCpuId(int id) { cpu_id = id; } 380 381 int readCpuId() { return cpu_id; } 382 383 void copyArchRegs(ExecContext *xc); 384 385 // 386 // New accessors for new decoder. 387 // 388 uint64_t readIntReg(int reg_idx) 389 { 390 return regs.intRegFile[reg_idx]; 391 } 392 393 FloatReg readFloatReg(int reg_idx, int width) 394 { 395 return regs.floatRegFile.readReg(reg_idx, width); 396 } 397 398 FloatReg readFloatReg(int reg_idx) 399 { 400 return regs.floatRegFile.readReg(reg_idx); 401 } 402 403 FloatRegBits readFloatRegBits(int reg_idx, int width) 404 { 405 return regs.floatRegFile.readRegBits(reg_idx, width); 406 } 407 408 FloatRegBits readFloatRegBits(int reg_idx) 409 { 410 return regs.floatRegFile.readRegBits(reg_idx); 411 } 412 413 void setIntReg(int reg_idx, uint64_t val) 414 { 415 regs.intRegFile[reg_idx] = val; 416 } 417 418 void setFloatReg(int reg_idx, FloatReg val, int width) 419 { 420 regs.floatRegFile.setReg(reg_idx, val, width); 421 } 422 423 void setFloatReg(int reg_idx, FloatReg val) 424 { 425 regs.floatRegFile.setReg(reg_idx, val); 426 } 427 428 void setFloatRegBits(int reg_idx, FloatRegBits val, int width) 429 { 430 regs.floatRegFile.setRegBits(reg_idx, val, width); 431 } 432 433 void setFloatRegBits(int reg_idx, FloatRegBits val) 434 { 435 regs.floatRegFile.setRegBits(reg_idx, val); 436 } 437 438 uint64_t readPC() 439 { 440 return regs.pc; 441 } 442 443 void setPC(uint64_t val) 444 { 445 regs.pc = val; 446 } 447 448 uint64_t readNextPC() 449 { 450 return regs.npc; 451 } 452 453 void setNextPC(uint64_t val) 454 { 455 regs.npc = val; 456 } 457 458 uint64_t readNextNPC() 459 { 460 return regs.nnpc; 461 } 462 463 void setNextNPC(uint64_t val) 464 { 465 regs.nnpc = val; 466 } 467 468 469 MiscReg readMiscReg(int misc_reg) 470 { 471 return regs.miscRegs.readReg(misc_reg); 472 } 473 474 MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) 475 { 476 return regs.miscRegs.readRegWithEffect(misc_reg, fault, proxy); 477 } 478 479 Fault setMiscReg(int misc_reg, const MiscReg &val) 480 { 481 return regs.miscRegs.setReg(misc_reg, val); 482 } 483 484 Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) 485 { 486 return regs.miscRegs.setRegWithEffect(misc_reg, val, proxy); 487 } 488 489 unsigned readStCondFailures() { return storeCondFailures; } 490 491 void setStCondFailures(unsigned sc_failures) 492 { storeCondFailures = sc_failures; } 493 494 void clearArchRegs() { memset(®s, 0, sizeof(regs)); } 495 496#if FULL_SYSTEM 497 int readIntrFlag() { return regs.intrflag; } 498 void setIntrFlag(int val) { regs.intrflag = val; } 499 Fault hwrei(); 500 bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } 501 bool simPalCheck(int palFunc); 502#endif 503 504#if !FULL_SYSTEM 505 TheISA::IntReg getSyscallArg(int i) 506 { 507 return regs.intRegFile[TheISA::ArgumentReg0 + i]; 508 } 509 510 // used to shift args for indirect syscall 511 void setSyscallArg(int i, TheISA::IntReg val) 512 { 513 regs.intRegFile[TheISA::ArgumentReg0 + i] = val; 514 } 515 516 void setSyscallReturn(SyscallReturn return_value) 517 { 518 TheISA::setSyscallReturn(return_value, ®s); 519 } 520 521 void syscall() 522 { 523 process->syscall(proxy); 524 } 525 526 Counter readFuncExeInst() { return func_exe_inst; } 527 528 void setFuncExeInst(Counter new_val) { func_exe_inst = new_val; } 529#endif 530}; 531 532 533// for non-speculative execution context, spec_mode is always false 534inline bool 535CPUExecContext::misspeculating() 536{ 537 return false; 538} 539 540#endif // __CPU_CPU_EXEC_CONTEXT_HH__ 541