simple_thread.hh revision 2521
110428Sandreas.hansson@arm.com/* 210428Sandreas.hansson@arm.com * Copyright (c) 2001-2006 The Regents of The University of Michigan 310428Sandreas.hansson@arm.com * All rights reserved. 410428Sandreas.hansson@arm.com * 510428Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 610428Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 710428Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 810428Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 910428Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 1010428Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 1110428Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 1210428Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 1310428Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 1410428Sandreas.hansson@arm.com * this software without specific prior written permission. 1510428Sandreas.hansson@arm.com * 1610428Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1710428Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1810428Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1910428Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2010428Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2110428Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2210428Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2310428Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2410428Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2510428Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2610428Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2710428Sandreas.hansson@arm.com */ 2810428Sandreas.hansson@arm.com 2910428Sandreas.hansson@arm.com#ifndef __CPU_CPU_EXEC_CONTEXT_HH__ 3010428Sandreas.hansson@arm.com#define __CPU_CPU_EXEC_CONTEXT_HH__ 3110428Sandreas.hansson@arm.com 3210428Sandreas.hansson@arm.com#include "arch/isa_traits.hh" 3310428Sandreas.hansson@arm.com#include "config/full_system.hh" 3410428Sandreas.hansson@arm.com#include "cpu/exec_context.hh" 3510428Sandreas.hansson@arm.com#include "mem/physical.hh" 3610428Sandreas.hansson@arm.com#include "mem/request.hh" 3710428Sandreas.hansson@arm.com#include "sim/byteswap.hh" 3810428Sandreas.hansson@arm.com#include "sim/eventq.hh" 3910428Sandreas.hansson@arm.com#include "sim/host.hh" 4010428Sandreas.hansson@arm.com#include "sim/serialize.hh" 4110428Sandreas.hansson@arm.com 4210428Sandreas.hansson@arm.comclass BaseCPU; 4310428Sandreas.hansson@arm.com 4410428Sandreas.hansson@arm.com#if FULL_SYSTEM 4510428Sandreas.hansson@arm.com 4610428Sandreas.hansson@arm.com#include "sim/system.hh" 4710428Sandreas.hansson@arm.com#include "arch/tlb.hh" 4810428Sandreas.hansson@arm.com 4910428Sandreas.hansson@arm.comclass FunctionProfile; 5010428Sandreas.hansson@arm.comclass ProfileNode; 5110428Sandreas.hansson@arm.comclass FunctionalPort; 5210428Sandreas.hansson@arm.comclass PhysicalPort; 5310428Sandreas.hansson@arm.com 5410428Sandreas.hansson@arm.com 5510428Sandreas.hansson@arm.com#else // !FULL_SYSTEM 5612266Sradhika.jagtap@arm.com 5712266Sradhika.jagtap@arm.com#include "sim/process.hh" 5812266Sradhika.jagtap@arm.com#include "mem/page_table.hh" 5912266Sradhika.jagtap@arm.comclass TranslatingPort; 6012266Sradhika.jagtap@arm.com 6112266Sradhika.jagtap@arm.com 6212266Sradhika.jagtap@arm.com#endif // FULL_SYSTEM 6312266Sradhika.jagtap@arm.com 6412266Sradhika.jagtap@arm.com// 6512266Sradhika.jagtap@arm.com// The CPUExecContext object represents a functional context for 6612266Sradhika.jagtap@arm.com// instruction execution. It incorporates everything required for 6712266Sradhika.jagtap@arm.com// architecture-level functional simulation of a single thread. 6812266Sradhika.jagtap@arm.com// 6912266Sradhika.jagtap@arm.com 7010428Sandreas.hansson@arm.comclass CPUExecContext 7110428Sandreas.hansson@arm.com{ 7210428Sandreas.hansson@arm.com protected: 7310428Sandreas.hansson@arm.com typedef TheISA::RegFile RegFile; 7410428Sandreas.hansson@arm.com typedef TheISA::MachInst MachInst; 7510428Sandreas.hansson@arm.com typedef TheISA::MiscRegFile MiscRegFile; 7610428Sandreas.hansson@arm.com typedef TheISA::MiscReg MiscReg; 7710428Sandreas.hansson@arm.com typedef TheISA::FloatReg FloatReg; 7812266Sradhika.jagtap@arm.com typedef TheISA::FloatRegBits FloatRegBits; 7912266Sradhika.jagtap@arm.com public: 8012266Sradhika.jagtap@arm.com typedef ExecContext::Status Status; 8112266Sradhika.jagtap@arm.com 8212266Sradhika.jagtap@arm.com private: 8312266Sradhika.jagtap@arm.com Status _status; 8412266Sradhika.jagtap@arm.com 8512266Sradhika.jagtap@arm.com public: 8612266Sradhika.jagtap@arm.com Status status() const { return _status; } 8712266Sradhika.jagtap@arm.com 8812266Sradhika.jagtap@arm.com void setStatus(Status newStatus) { _status = newStatus; } 8912266Sradhika.jagtap@arm.com 9012266Sradhika.jagtap@arm.com /// Set the status to Active. Optional delay indicates number of 9112266Sradhika.jagtap@arm.com /// cycles to wait before beginning execution. 9212266Sradhika.jagtap@arm.com void activate(int delay = 1); 9310428Sandreas.hansson@arm.com 9410428Sandreas.hansson@arm.com /// Set the status to Suspended. 9511555Sjungma@eit.uni-kl.de void suspend(); 9610428Sandreas.hansson@arm.com 9710428Sandreas.hansson@arm.com /// Set the status to Unallocated. 9811555Sjungma@eit.uni-kl.de void deallocate(); 9910428Sandreas.hansson@arm.com 10010428Sandreas.hansson@arm.com /// Set the status to Halted. 10110428Sandreas.hansson@arm.com void halt(); 10211555Sjungma@eit.uni-kl.de 10310428Sandreas.hansson@arm.com protected: 10410428Sandreas.hansson@arm.com RegFile regs; // correct-path register context 10510428Sandreas.hansson@arm.com 10610428Sandreas.hansson@arm.com public: 10710428Sandreas.hansson@arm.com // pointer to CPU associated with this context 10810428Sandreas.hansson@arm.com BaseCPU *cpu; 10910428Sandreas.hansson@arm.com 11010428Sandreas.hansson@arm.com ProxyExecContext<CPUExecContext> *proxy; 11110428Sandreas.hansson@arm.com 11210428Sandreas.hansson@arm.com // Current instruction 11310428Sandreas.hansson@arm.com MachInst inst; 11410428Sandreas.hansson@arm.com 11510428Sandreas.hansson@arm.com // Index of hardware thread context on the CPU that this represents. 11610428Sandreas.hansson@arm.com int thread_num; 11711555Sjungma@eit.uni-kl.de 11810428Sandreas.hansson@arm.com // ID of this context w.r.t. the System or Process object to which 11910428Sandreas.hansson@arm.com // it belongs. For full-system mode, this is the system CPU ID. 12010428Sandreas.hansson@arm.com int cpu_id; 12110428Sandreas.hansson@arm.com 12210428Sandreas.hansson@arm.com Tick lastActivate; 12310428Sandreas.hansson@arm.com Tick lastSuspend; 12410428Sandreas.hansson@arm.com 12511555Sjungma@eit.uni-kl.de System *system; 12610428Sandreas.hansson@arm.com 12710428Sandreas.hansson@arm.com 12810428Sandreas.hansson@arm.com#if FULL_SYSTEM 12910428Sandreas.hansson@arm.com AlphaITB *itb; 13010428Sandreas.hansson@arm.com AlphaDTB *dtb; 13110428Sandreas.hansson@arm.com 13210428Sandreas.hansson@arm.com /** A functional port outgoing only for functional accesses to physical 13310428Sandreas.hansson@arm.com * addresses.*/ 13410428Sandreas.hansson@arm.com FunctionalPort *physPort; 13510428Sandreas.hansson@arm.com 13610428Sandreas.hansson@arm.com /** A functional port, outgoing only, for functional accesse to virtual 13710428Sandreas.hansson@arm.com * addresses. That doen't require execution context information */ 13810428Sandreas.hansson@arm.com VirtualPort *virtPort; 13910428Sandreas.hansson@arm.com 14010428Sandreas.hansson@arm.com FunctionProfile *profile; 14112266Sradhika.jagtap@arm.com ProfileNode *profileNode; 14210428Sandreas.hansson@arm.com Addr profilePC; 14310428Sandreas.hansson@arm.com void dumpFuncProfile(); 14410428Sandreas.hansson@arm.com 14511555Sjungma@eit.uni-kl.de /** Event for timing out quiesce instruction */ 14611555Sjungma@eit.uni-kl.de struct EndQuiesceEvent : public Event 14711555Sjungma@eit.uni-kl.de { 14811555Sjungma@eit.uni-kl.de /** A pointer to the execution context that is quiesced */ 14911555Sjungma@eit.uni-kl.de CPUExecContext *cpuXC; 15012266Sradhika.jagtap@arm.com 15111555Sjungma@eit.uni-kl.de EndQuiesceEvent(CPUExecContext *_cpuXC); 15211555Sjungma@eit.uni-kl.de 15311555Sjungma@eit.uni-kl.de /** Event process to occur at interrupt*/ 15411555Sjungma@eit.uni-kl.de virtual void process(); 15511555Sjungma@eit.uni-kl.de 15611555Sjungma@eit.uni-kl.de /** Event description */ 15711555Sjungma@eit.uni-kl.de virtual const char *description(); 15811555Sjungma@eit.uni-kl.de }; 15911555Sjungma@eit.uni-kl.de EndQuiesceEvent quiesceEvent; 16011555Sjungma@eit.uni-kl.de 16111555Sjungma@eit.uni-kl.de Event *getQuiesceEvent() { return &quiesceEvent; } 16211555Sjungma@eit.uni-kl.de 16311555Sjungma@eit.uni-kl.de Tick readLastActivate() { return lastActivate; } 16411555Sjungma@eit.uni-kl.de 16510428Sandreas.hansson@arm.com Tick readLastSuspend() { return lastSuspend; } 16610428Sandreas.hansson@arm.com 16710428Sandreas.hansson@arm.com void profileClear(); 16810428Sandreas.hansson@arm.com 16910428Sandreas.hansson@arm.com void profileSample(); 17011555Sjungma@eit.uni-kl.de 17110428Sandreas.hansson@arm.com#else 17210428Sandreas.hansson@arm.com /// Port that syscalls can use to access memory (provides translation step). 17310428Sandreas.hansson@arm.com TranslatingPort *port; 17410428Sandreas.hansson@arm.com 17510428Sandreas.hansson@arm.com Process *process; 17610428Sandreas.hansson@arm.com 17710428Sandreas.hansson@arm.com // Address space ID. Note that this is used for TIMING cache 17810428Sandreas.hansson@arm.com // simulation only; all functional memory accesses should use 17910428Sandreas.hansson@arm.com // one of the FunctionalMemory pointers above. 18010428Sandreas.hansson@arm.com short asid; 18110490Sandreas.hansson@arm.com 18210428Sandreas.hansson@arm.com#endif 18310428Sandreas.hansson@arm.com 18410428Sandreas.hansson@arm.com /** 18510428Sandreas.hansson@arm.com * Temporary storage to pass the source address from copy_load to 18610428Sandreas.hansson@arm.com * copy_store. 18711555Sjungma@eit.uni-kl.de * @todo Remove this temporary when we have a better way to do it. 18810428Sandreas.hansson@arm.com */ 18910428Sandreas.hansson@arm.com Addr copySrcAddr; 19010428Sandreas.hansson@arm.com /** 191 * Temp storage for the physical source address of a copy. 192 * @todo Remove this temporary when we have a better way to do it. 193 */ 194 Addr copySrcPhysAddr; 195 196 197 /* 198 * number of executed instructions, for matching with syscall trace 199 * points in EIO files. 200 */ 201 Counter func_exe_inst; 202 203 // 204 // Count failed store conditionals so we can warn of apparent 205 // application deadlock situations. 206 unsigned storeCondFailures; 207 208 // constructor: initialize context from given process structure 209#if FULL_SYSTEM 210 CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_system, 211 AlphaITB *_itb, AlphaDTB *_dtb); 212#else 213 CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid, 214 MemObject *memobj); 215 // Constructor to use XC to pass reg file around. Not used for anything 216 // else. 217 CPUExecContext(RegFile *regFile); 218#endif 219 virtual ~CPUExecContext(); 220 221 virtual void takeOverFrom(ExecContext *oldContext); 222 223 void regStats(const std::string &name); 224 225 void serialize(std::ostream &os); 226 void unserialize(Checkpoint *cp, const std::string §ion); 227 228 BaseCPU *getCpuPtr() { return cpu; } 229 230 ExecContext *getProxy() { return proxy; } 231 232 int getThreadNum() { return thread_num; } 233 234#if FULL_SYSTEM 235 System *getSystemPtr() { return system; } 236 237 AlphaITB *getITBPtr() { return itb; } 238 239 AlphaDTB *getDTBPtr() { return dtb; } 240 241 int getInstAsid() { return regs.instAsid(); } 242 int getDataAsid() { return regs.dataAsid(); } 243 244 Fault translateInstReq(CpuRequestPtr &req) 245 { 246 return itb->translate(req, proxy); 247 } 248 249 Fault translateDataReadReq(CpuRequestPtr &req) 250 { 251 return dtb->translate(req, proxy, false); 252 } 253 254 Fault translateDataWriteReq(CpuRequestPtr &req) 255 { 256 return dtb->translate(req, proxy, true); 257 } 258 259 FunctionalPort *getPhysPort() { return physPort; } 260 261 /** Return a virtual port. If no exec context is specified then a static 262 * port is returned. Otherwise a port is created and returned. It must be 263 * deleted by deleteVirtPort(). */ 264 VirtualPort *getVirtPort(ExecContext *xc); 265 266 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