simple_thread.hh revision 2455
110859Sandreas.sandberg@arm.com/* 211461Sandreas.sandberg@arm.com * Copyright (c) 2001-2006 The Regents of The University of Michigan 310859Sandreas.sandberg@arm.com * All rights reserved. 410859Sandreas.sandberg@arm.com * 510859Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 610859Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 710859Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 810859Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 910859Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1010859Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 1110859Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 1210859Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 1310859Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 1410859Sandreas.sandberg@arm.com * this software without specific prior written permission. 1510859Sandreas.sandberg@arm.com * 1610859Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1710859Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1810859Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1910859Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2010859Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2110859Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2210859Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2310859Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2410859Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2510859Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2610859Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2710859Sandreas.sandberg@arm.com */ 2810859Sandreas.sandberg@arm.com 2910859Sandreas.sandberg@arm.com#ifndef __CPU_CPU_EXEC_CONTEXT_HH__ 3010859Sandreas.sandberg@arm.com#define __CPU_CPU_EXEC_CONTEXT_HH__ 3110859Sandreas.sandberg@arm.com 3210859Sandreas.sandberg@arm.com#include "arch/isa_traits.hh" 3310859Sandreas.sandberg@arm.com#include "config/full_system.hh" 3410859Sandreas.sandberg@arm.com#include "cpu/exec_context.hh" 3510859Sandreas.sandberg@arm.com#include "mem/physical.hh" 3610859Sandreas.sandberg@arm.com#include "mem/request.hh" 3710859Sandreas.sandberg@arm.com#include "sim/byteswap.hh" 3810859Sandreas.sandberg@arm.com#include "sim/eventq.hh" 3910859Sandreas.sandberg@arm.com#include "sim/host.hh" 4010859Sandreas.sandberg@arm.com#include "sim/serialize.hh" 4110859Sandreas.sandberg@arm.com 4210859Sandreas.sandberg@arm.comclass BaseCPU; 4310859Sandreas.sandberg@arm.com 4410859Sandreas.sandberg@arm.com#if FULL_SYSTEM 4510859Sandreas.sandberg@arm.com 4610859Sandreas.sandberg@arm.com#include "sim/system.hh" 4711462Sandreas.sandberg@arm.com#include "arch/tlb.hh" 4811462Sandreas.sandberg@arm.com 4911461Sandreas.sandberg@arm.comclass FunctionProfile; 5011461Sandreas.sandberg@arm.comclass ProfileNode; 5111461Sandreas.sandberg@arm.comclass MemoryController; 5211461Sandreas.sandberg@arm.com 5311461Sandreas.sandberg@arm.com#else // !FULL_SYSTEM 5411461Sandreas.sandberg@arm.com 5511461Sandreas.sandberg@arm.com#include "sim/process.hh" 5611461Sandreas.sandberg@arm.comclass TranslatingPort; 5711461Sandreas.sandberg@arm.com 5811462Sandreas.sandberg@arm.com#endif // FULL_SYSTEM 5911462Sandreas.sandberg@arm.com 6011461Sandreas.sandberg@arm.com// 6111461Sandreas.sandberg@arm.com// The CPUExecContext object represents a functional context for 6211461Sandreas.sandberg@arm.com// instruction execution. It incorporates everything required for 6311461Sandreas.sandberg@arm.com// architecture-level functional simulation of a single thread. 6411461Sandreas.sandberg@arm.com// 6511461Sandreas.sandberg@arm.com 6611461Sandreas.sandberg@arm.comclass CPUExecContext 6711461Sandreas.sandberg@arm.com{ 6811461Sandreas.sandberg@arm.com protected: 6911461Sandreas.sandberg@arm.com typedef TheISA::RegFile RegFile; 7011461Sandreas.sandberg@arm.com typedef TheISA::MachInst MachInst; 7111461Sandreas.sandberg@arm.com typedef TheISA::MiscRegFile MiscRegFile; 7211461Sandreas.sandberg@arm.com typedef TheISA::MiscReg MiscReg; 7311461Sandreas.sandberg@arm.com typedef TheISA::FloatReg FloatReg; 7411461Sandreas.sandberg@arm.com typedef TheISA::FloatRegBits FloatRegBits; 7511461Sandreas.sandberg@arm.com public: 7611461Sandreas.sandberg@arm.com typedef ExecContext::Status Status; 7711461Sandreas.sandberg@arm.com 7811461Sandreas.sandberg@arm.com private: 7911461Sandreas.sandberg@arm.com Status _status; 8011461Sandreas.sandberg@arm.com 8111461Sandreas.sandberg@arm.com public: 8211461Sandreas.sandberg@arm.com Status status() const { return _status; } 8311461Sandreas.sandberg@arm.com 8411461Sandreas.sandberg@arm.com void setStatus(Status newStatus) { _status = newStatus; } 8511461Sandreas.sandberg@arm.com 8611461Sandreas.sandberg@arm.com /// Set the status to Active. Optional delay indicates number of 8711461Sandreas.sandberg@arm.com /// cycles to wait before beginning execution. 8811461Sandreas.sandberg@arm.com void activate(int delay = 1); 8911461Sandreas.sandberg@arm.com 9011461Sandreas.sandberg@arm.com /// Set the status to Suspended. 9111461Sandreas.sandberg@arm.com void suspend(); 9211461Sandreas.sandberg@arm.com 9311461Sandreas.sandberg@arm.com /// Set the status to Unallocated. 9411461Sandreas.sandberg@arm.com void deallocate(); 9511461Sandreas.sandberg@arm.com 9611461Sandreas.sandberg@arm.com /// Set the status to Halted. 9711461Sandreas.sandberg@arm.com void halt(); 9811461Sandreas.sandberg@arm.com 9911461Sandreas.sandberg@arm.com protected: 10011461Sandreas.sandberg@arm.com RegFile regs; // correct-path register context 10111461Sandreas.sandberg@arm.com 10211461Sandreas.sandberg@arm.com public: 10311461Sandreas.sandberg@arm.com // pointer to CPU associated with this context 10411461Sandreas.sandberg@arm.com BaseCPU *cpu; 10511461Sandreas.sandberg@arm.com 10610859Sandreas.sandberg@arm.com ProxyExecContext<CPUExecContext> *proxy; 10710859Sandreas.sandberg@arm.com 10810859Sandreas.sandberg@arm.com // Current instruction 10911462Sandreas.sandberg@arm.com MachInst inst; 11011461Sandreas.sandberg@arm.com 11110859Sandreas.sandberg@arm.com // Index of hardware thread context on the CPU that this represents. 11210859Sandreas.sandberg@arm.com int thread_num; 11310859Sandreas.sandberg@arm.com 11410859Sandreas.sandberg@arm.com // ID of this context w.r.t. the System or Process object to which 11510859Sandreas.sandberg@arm.com // it belongs. For full-system mode, this is the system CPU ID. 11610859Sandreas.sandberg@arm.com int cpu_id; 11710859Sandreas.sandberg@arm.com 11810859Sandreas.sandberg@arm.com Tick lastActivate; 11910905Sandreas.sandberg@arm.com Tick lastSuspend; 12010859Sandreas.sandberg@arm.com 12110859Sandreas.sandberg@arm.com System *system; 12210859Sandreas.sandberg@arm.com 12310859Sandreas.sandberg@arm.com /// Port that syscalls can use to access memory (provides translation step). 12410859Sandreas.sandberg@arm.com TranslatingPort *port; 12510905Sandreas.sandberg@arm.com// Memory *mem; 12610859Sandreas.sandberg@arm.com 12710859Sandreas.sandberg@arm.com#if FULL_SYSTEM 12810859Sandreas.sandberg@arm.com AlphaITB *itb; 12910859Sandreas.sandberg@arm.com AlphaDTB *dtb; 13010859Sandreas.sandberg@arm.com 13110859Sandreas.sandberg@arm.com // the following two fields are redundant, since we can always 13210859Sandreas.sandberg@arm.com // look them up through the system pointer, but we'll leave them 13310859Sandreas.sandberg@arm.com // here for now for convenience 13410859Sandreas.sandberg@arm.com MemoryController *memctrl; 13510859Sandreas.sandberg@arm.com// PhysicalMemory *physmem; 13610859Sandreas.sandberg@arm.com 13710859Sandreas.sandberg@arm.com FunctionProfile *profile; 13810859Sandreas.sandberg@arm.com ProfileNode *profileNode; 13910859Sandreas.sandberg@arm.com Addr profilePC; 14010859Sandreas.sandberg@arm.com void dumpFuncProfile(); 14110859Sandreas.sandberg@arm.com 14210859Sandreas.sandberg@arm.com /** Event for timing out quiesce instruction */ 14310859Sandreas.sandberg@arm.com struct EndQuiesceEvent : public Event 14410859Sandreas.sandberg@arm.com { 14510859Sandreas.sandberg@arm.com /** A pointer to the execution context that is quiesced */ 14611461Sandreas.sandberg@arm.com CPUExecContext *cpuXC; 14710859Sandreas.sandberg@arm.com 14810859Sandreas.sandberg@arm.com EndQuiesceEvent(CPUExecContext *_cpuXC); 14910859Sandreas.sandberg@arm.com 15010859Sandreas.sandberg@arm.com /** Event process to occur at interrupt*/ 15110859Sandreas.sandberg@arm.com virtual void process(); 15210859Sandreas.sandberg@arm.com 15311461Sandreas.sandberg@arm.com /** Event description */ 15410859Sandreas.sandberg@arm.com virtual const char *description(); 15510859Sandreas.sandberg@arm.com }; 15610859Sandreas.sandberg@arm.com EndQuiesceEvent quiesceEvent; 15710859Sandreas.sandberg@arm.com 15810859Sandreas.sandberg@arm.com Event *getQuiesceEvent() { return &quiesceEvent; } 15910859Sandreas.sandberg@arm.com 16011461Sandreas.sandberg@arm.com Tick readLastActivate() { return lastActivate; } 16110859Sandreas.sandberg@arm.com 16210859Sandreas.sandberg@arm.com Tick readLastSuspend() { return lastSuspend; } 16310859Sandreas.sandberg@arm.com 16410859Sandreas.sandberg@arm.com void profileClear(); 16510859Sandreas.sandberg@arm.com 16610859Sandreas.sandberg@arm.com void profileSample(); 16711461Sandreas.sandberg@arm.com 16810859Sandreas.sandberg@arm.com#else 16910859Sandreas.sandberg@arm.com Process *process; 17010859Sandreas.sandberg@arm.com 17110859Sandreas.sandberg@arm.com // Address space ID. Note that this is used for TIMING cache 17210859Sandreas.sandberg@arm.com // simulation only; all functional memory accesses should use 17310859Sandreas.sandberg@arm.com // one of the FunctionalMemory pointers above. 17410859Sandreas.sandberg@arm.com short asid; 17510859Sandreas.sandberg@arm.com 17610859Sandreas.sandberg@arm.com#endif 17710859Sandreas.sandberg@arm.com 17810859Sandreas.sandberg@arm.com /** 17910859Sandreas.sandberg@arm.com * Temporary storage to pass the source address from copy_load to 18010859Sandreas.sandberg@arm.com * copy_store. 18110859Sandreas.sandberg@arm.com * @todo Remove this temporary when we have a better way to do it. 18210859Sandreas.sandberg@arm.com */ 18310859Sandreas.sandberg@arm.com Addr copySrcAddr; 18410859Sandreas.sandberg@arm.com /** 185 * Temp storage for the physical source address of a copy. 186 * @todo Remove this temporary when we have a better way to do it. 187 */ 188 Addr copySrcPhysAddr; 189 190 191 /* 192 * number of executed instructions, for matching with syscall trace 193 * points in EIO files. 194 */ 195 Counter func_exe_inst; 196 197 // 198 // Count failed store conditionals so we can warn of apparent 199 // application deadlock situations. 200 unsigned storeCondFailures; 201 202 // constructor: initialize context from given process structure 203#if FULL_SYSTEM 204 CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_system, 205 AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem); 206#else 207 CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid, Port *mem_port); 208 // Constructor to use XC to pass reg file around. Not used for anything 209 // else. 210 CPUExecContext(RegFile *regFile); 211#endif 212 virtual ~CPUExecContext(); 213 214 virtual void takeOverFrom(ExecContext *oldContext); 215 216 void regStats(const std::string &name); 217 218 void serialize(std::ostream &os); 219 void unserialize(Checkpoint *cp, const std::string §ion); 220 221 TranslatingPort *getMemPort() { return port; } 222 223 BaseCPU *getCpuPtr() { return cpu; } 224 225 ExecContext *getProxy() { return proxy; } 226 227 int getThreadNum() { return thread_num; } 228 229#if FULL_SYSTEM 230 System *getSystemPtr() { return system; } 231 232 PhysicalMemory *getPhysMemPtr() { return physmem; } 233 234 AlphaITB *getITBPtr() { return itb; } 235 236 AlphaDTB *getDTBPtr() { return dtb; } 237 238 int getInstAsid() { return regs.instAsid(); } 239 int getDataAsid() { return regs.dataAsid(); } 240 241 Fault translateInstReq(CpuRequestPtr &req) 242 { 243 return itb->translate(req); 244 } 245 246 Fault translateDataReadReq(CpuRequestPtr &req) 247 { 248 return dtb->translate(req, false); 249 } 250 251 Fault translateDataWriteReq(CpuRequestPtr &req) 252 { 253 return dtb->translate(req, true); 254 } 255 256#else 257 Process *getProcessPtr() { return process; } 258 259 int getInstAsid() { return asid; } 260 int getDataAsid() { return asid; } 261 262 Fault translateInstReq(CpuRequestPtr &req) 263 { 264 return process->pTable->translate(req); 265 } 266 267 Fault translateDataReadReq(CpuRequestPtr &req) 268 { 269 return process->pTable->translate(req); 270 } 271 272 Fault translateDataWriteReq(CpuRequestPtr &req) 273 { 274 return process->pTable->translate(req); 275 } 276 277#endif 278 279/* 280 template <class T> 281 Fault read(CpuRequestPtr &req, T &data) 282 { 283#if FULL_SYSTEM && THE_ISA == ALPHA_ISA 284 if (req->flags & LOCKED) { 285 req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr); 286 req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true); 287 } 288#endif 289 290 Fault error; 291 error = mem->prot_read(req->paddr, data, req->size); 292 data = LittleEndianGuest::gtoh(data); 293 return error; 294 } 295 296 template <class T> 297 Fault write(CpuRequestPtr &req, T &data) 298 { 299#if FULL_SYSTEM && THE_ISA == ALPHA_ISA 300 ExecContext *xc; 301 302 // If this is a store conditional, act appropriately 303 if (req->flags & LOCKED) { 304 xc = req->xc; 305 306 if (req->flags & UNCACHEABLE) { 307 // Don't update result register (see stq_c in isa_desc) 308 req->result = 2; 309 xc->setStCondFailures(0);//Needed? [RGD] 310 } else { 311 bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag); 312 Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag); 313 req->result = lock_flag; 314 if (!lock_flag || 315 ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { 316 xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); 317 xc->setStCondFailures(xc->readStCondFailures() + 1); 318 if (((xc->readStCondFailures()) % 100000) == 0) { 319 std::cerr << "Warning: " 320 << xc->readStCondFailures() 321 << " consecutive store conditional failures " 322 << "on cpu " << req->xc->readCpuId() 323 << std::endl; 324 } 325 return NoFault; 326 } 327 else xc->setStCondFailures(0); 328 } 329 } 330 331 // Need to clear any locked flags on other proccessors for 332 // this address. Only do this for succsful Store Conditionals 333 // and all other stores (WH64?). Unsuccessful Store 334 // Conditionals would have returned above, and wouldn't fall 335 // through. 336 for (int i = 0; i < system->execContexts.size(); i++){ 337 xc = system->execContexts[i]; 338 if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) == 339 (req->paddr & ~0xf)) { 340 xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); 341 } 342 } 343 344#endif 345 return mem->prot_write(req->paddr, (T)htog(data), req->size); 346 } 347*/ 348 virtual bool misspeculating(); 349 350 351 MachInst getInst() { return inst; } 352 353 void setInst(MachInst new_inst) 354 { 355 inst = new_inst; 356 } 357 358 Fault instRead(CpuRequestPtr &req) 359 { 360 panic("instRead not implemented"); 361 // return funcPhysMem->read(req, inst); 362 return NoFault; 363 } 364 365 void setCpuId(int id) { cpu_id = id; } 366 367 int readCpuId() { return cpu_id; } 368 369 void copyArchRegs(ExecContext *xc); 370 371 // 372 // New accessors for new decoder. 373 // 374 uint64_t readIntReg(int reg_idx) 375 { 376 return regs.intRegFile[reg_idx]; 377 } 378 379 FloatReg readFloatReg(int reg_idx, int width) 380 { 381 return regs.floatRegFile.readReg(reg_idx, width); 382 } 383 384 FloatReg readFloatReg(int reg_idx) 385 { 386 return regs.floatRegFile.readReg(reg_idx); 387 } 388 389 FloatRegBits readFloatRegBits(int reg_idx, int width) 390 { 391 return regs.floatRegFile.readRegBits(reg_idx, width); 392 } 393 394 FloatRegBits readFloatRegBits(int reg_idx) 395 { 396 return regs.floatRegFile.readRegBits(reg_idx); 397 } 398 399 void setIntReg(int reg_idx, uint64_t val) 400 { 401 regs.intRegFile[reg_idx] = val; 402 } 403 404 void setFloatReg(int reg_idx, FloatReg val, int width) 405 { 406 regs.floatRegFile.setReg(reg_idx, val, width); 407 } 408 409 void setFloatReg(int reg_idx, FloatReg val) 410 { 411 regs.floatRegFile.setReg(reg_idx, val); 412 } 413 414 void setFloatRegBits(int reg_idx, FloatRegBits val, int width) 415 { 416 regs.floatRegFile.setRegBits(reg_idx, val, width); 417 } 418 419 void setFloatRegBits(int reg_idx, FloatRegBits val) 420 { 421 regs.floatRegFile.setRegBits(reg_idx, val); 422 } 423 424 uint64_t readPC() 425 { 426 return regs.pc; 427 } 428 429 void setPC(uint64_t val) 430 { 431 regs.pc = val; 432 } 433 434 uint64_t readNextPC() 435 { 436 return regs.npc; 437 } 438 439 void setNextPC(uint64_t val) 440 { 441 regs.npc = val; 442 } 443 444 uint64_t readNextNPC() 445 { 446 return regs.nnpc; 447 } 448 449 void setNextNPC(uint64_t val) 450 { 451 regs.nnpc = val; 452 } 453 454 455 MiscReg readMiscReg(int misc_reg) 456 { 457 return regs.miscRegs.readReg(misc_reg); 458 } 459 460 MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) 461 { 462 return regs.miscRegs.readRegWithEffect(misc_reg, fault, proxy); 463 } 464 465 Fault setMiscReg(int misc_reg, const MiscReg &val) 466 { 467 return regs.miscRegs.setReg(misc_reg, val); 468 } 469 470 Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) 471 { 472 return regs.miscRegs.setRegWithEffect(misc_reg, val, proxy); 473 } 474 475 unsigned readStCondFailures() { return storeCondFailures; } 476 477 void setStCondFailures(unsigned sc_failures) 478 { storeCondFailures = sc_failures; } 479 480 void clearArchRegs() { memset(®s, 0, sizeof(regs)); } 481 482#if FULL_SYSTEM 483 int readIntrFlag() { return regs.intrflag; } 484 void setIntrFlag(int val) { regs.intrflag = val; } 485 Fault hwrei(); 486 bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } 487 bool simPalCheck(int palFunc); 488#endif 489 490#if !FULL_SYSTEM 491 TheISA::IntReg getSyscallArg(int i) 492 { 493 return regs.intRegFile[TheISA::ArgumentReg0 + i]; 494 } 495 496 // used to shift args for indirect syscall 497 void setSyscallArg(int i, TheISA::IntReg val) 498 { 499 regs.intRegFile[TheISA::ArgumentReg0 + i] = val; 500 } 501 502 void setSyscallReturn(SyscallReturn return_value) 503 { 504 TheISA::setSyscallReturn(return_value, ®s); 505 } 506 507 void syscall() 508 { 509 process->syscall(proxy); 510 } 511 512 Counter readFuncExeInst() { return func_exe_inst; } 513 514 void setFuncExeInst(Counter new_val) { func_exe_inst = new_val; } 515#endif 516}; 517 518 519// for non-speculative execution context, spec_mode is always false 520inline bool 521CPUExecContext::misspeculating() 522{ 523 return false; 524} 525 526#endif // __CPU_CPU_EXEC_CONTEXT_HH__ 527