base.cc revision 2935:d1223a6c9156
12929Sktlim@umich.edu/* 22929Sktlim@umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan 32932Sktlim@umich.edu * All rights reserved. 42929Sktlim@umich.edu * 52929Sktlim@umich.edu * Redistribution and use in source and binary forms, with or without 62929Sktlim@umich.edu * modification, are permitted provided that the following conditions are 72929Sktlim@umich.edu * met: redistributions of source code must retain the above copyright 82929Sktlim@umich.edu * notice, this list of conditions and the following disclaimer; 92929Sktlim@umich.edu * redistributions in binary form must reproduce the above copyright 102929Sktlim@umich.edu * notice, this list of conditions and the following disclaimer in the 112929Sktlim@umich.edu * documentation and/or other materials provided with the distribution; 122929Sktlim@umich.edu * neither the name of the copyright holders nor the names of its 132929Sktlim@umich.edu * contributors may be used to endorse or promote products derived from 142929Sktlim@umich.edu * this software without specific prior written permission. 152929Sktlim@umich.edu * 162929Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172929Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182929Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192929Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202929Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212929Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222929Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232929Sktlim@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242929Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252929Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262929Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272929Sktlim@umich.edu * 282932Sktlim@umich.edu * Authors: Steve Reinhardt 292932Sktlim@umich.edu */ 302932Sktlim@umich.edu 312929Sktlim@umich.edu#include "arch/utility.hh" 326007Ssteve.reinhardt@amd.com#include "base/cprintf.hh" 332929Sktlim@umich.edu#include "base/inifile.hh" 342929Sktlim@umich.edu#include "base/loader/symtab.hh" 352929Sktlim@umich.edu#include "base/misc.hh" 362929Sktlim@umich.edu#include "base/pollevent.hh" 372929Sktlim@umich.edu#include "base/range.hh" 382929Sktlim@umich.edu#include "base/stats/events.hh" 392929Sktlim@umich.edu#include "base/trace.hh" 402929Sktlim@umich.edu#include "cpu/base.hh" 412929Sktlim@umich.edu#include "cpu/exetrace.hh" 422929Sktlim@umich.edu#include "cpu/profile.hh" 432929Sktlim@umich.edu#include "cpu/simple/base.hh" 442929Sktlim@umich.edu#include "cpu/simple_thread.hh" 452929Sktlim@umich.edu#include "cpu/smt.hh" 462929Sktlim@umich.edu#include "cpu/static_inst.hh" 476007Ssteve.reinhardt@amd.com#include "cpu/thread_context.hh" 486007Ssteve.reinhardt@amd.com#include "kern/kernel_stats.hh" 496007Ssteve.reinhardt@amd.com#include "mem/packet_impl.hh" 506007Ssteve.reinhardt@amd.com#include "sim/builder.hh" 516007Ssteve.reinhardt@amd.com#include "sim/byteswap.hh" 526007Ssteve.reinhardt@amd.com#include "sim/debug.hh" 536007Ssteve.reinhardt@amd.com#include "sim/host.hh" 546007Ssteve.reinhardt@amd.com#include "sim/sim_events.hh" 556007Ssteve.reinhardt@amd.com#include "sim/sim_object.hh" 566007Ssteve.reinhardt@amd.com#include "sim/stats.hh" 576007Ssteve.reinhardt@amd.com#include "sim/system.hh" 586007Ssteve.reinhardt@amd.com 596007Ssteve.reinhardt@amd.com#if FULL_SYSTEM 606007Ssteve.reinhardt@amd.com#include "base/remote_gdb.hh" 616007Ssteve.reinhardt@amd.com#include "arch/tlb.hh" 626007Ssteve.reinhardt@amd.com#include "arch/stacktrace.hh" 636007Ssteve.reinhardt@amd.com#include "arch/vtophys.hh" 646007Ssteve.reinhardt@amd.com#else // !FULL_SYSTEM 656007Ssteve.reinhardt@amd.com#include "mem/mem_object.hh" 666007Ssteve.reinhardt@amd.com#endif // FULL_SYSTEM 676007Ssteve.reinhardt@amd.com 686007Ssteve.reinhardt@amd.comusing namespace std; 696007Ssteve.reinhardt@amd.comusing namespace TheISA; 706007Ssteve.reinhardt@amd.com 716007Ssteve.reinhardt@amd.comBaseSimpleCPU::BaseSimpleCPU(Params *p) 726007Ssteve.reinhardt@amd.com : BaseCPU(p), mem(p->mem), thread(NULL) 736007Ssteve.reinhardt@amd.com{ 746007Ssteve.reinhardt@amd.com#if FULL_SYSTEM 756007Ssteve.reinhardt@amd.com thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb); 762929Sktlim@umich.edu#else 772929Sktlim@umich.edu thread = new SimpleThread(this, /* thread_num */ 0, p->process, 782929Sktlim@umich.edu /* asid */ 0, mem); 796007Ssteve.reinhardt@amd.com#endif // !FULL_SYSTEM 806007Ssteve.reinhardt@amd.com 816007Ssteve.reinhardt@amd.com thread->setStatus(ThreadContext::Suspended); 826007Ssteve.reinhardt@amd.com 836007Ssteve.reinhardt@amd.com tc = thread->getTC(); 846007Ssteve.reinhardt@amd.com 852929Sktlim@umich.edu numInst = 0; 862929Sktlim@umich.edu startNumInst = 0; 872929Sktlim@umich.edu numLoad = 0; 882929Sktlim@umich.edu startNumLoad = 0; 892929Sktlim@umich.edu lastIcacheStall = 0; 906011Ssteve.reinhardt@amd.com lastDcacheStall = 0; 916007Ssteve.reinhardt@amd.com 926007Ssteve.reinhardt@amd.com threadContexts.push_back(tc); 936007Ssteve.reinhardt@amd.com} 946007Ssteve.reinhardt@amd.com 956007Ssteve.reinhardt@amd.comBaseSimpleCPU::~BaseSimpleCPU() 966007Ssteve.reinhardt@amd.com{ 976007Ssteve.reinhardt@amd.com} 986007Ssteve.reinhardt@amd.com 996007Ssteve.reinhardt@amd.comvoid 1006007Ssteve.reinhardt@amd.comBaseSimpleCPU::deallocateContext(int thread_num) 1016007Ssteve.reinhardt@amd.com{ 1026007Ssteve.reinhardt@amd.com // for now, these are equivalent 1036007Ssteve.reinhardt@amd.com suspendContext(thread_num); 1046007Ssteve.reinhardt@amd.com} 1056011Ssteve.reinhardt@amd.com 1066007Ssteve.reinhardt@amd.com 1076007Ssteve.reinhardt@amd.comvoid 1086007Ssteve.reinhardt@amd.comBaseSimpleCPU::haltContext(int thread_num) 1096007Ssteve.reinhardt@amd.com{ 1106007Ssteve.reinhardt@amd.com // for now, these are equivalent 1117685Ssteve.reinhardt@amd.com suspendContext(thread_num); 1126007Ssteve.reinhardt@amd.com} 1136011Ssteve.reinhardt@amd.com 1146007Ssteve.reinhardt@amd.com 1156007Ssteve.reinhardt@amd.comvoid 1166007Ssteve.reinhardt@amd.comBaseSimpleCPU::regStats() 1176007Ssteve.reinhardt@amd.com{ 1186007Ssteve.reinhardt@amd.com using namespace Stats; 1196007Ssteve.reinhardt@amd.com 1206007Ssteve.reinhardt@amd.com BaseCPU::regStats(); 1216011Ssteve.reinhardt@amd.com 1226007Ssteve.reinhardt@amd.com numInsts 1236007Ssteve.reinhardt@amd.com .name(name() + ".num_insts") 1246007Ssteve.reinhardt@amd.com .desc("Number of instructions executed") 1256007Ssteve.reinhardt@amd.com ; 1266007Ssteve.reinhardt@amd.com 1276008Ssteve.reinhardt@amd.com numMemRefs 1286007Ssteve.reinhardt@amd.com .name(name() + ".num_refs") 1296008Ssteve.reinhardt@amd.com .desc("Number of memory references") 1306008Ssteve.reinhardt@amd.com ; 1316008Ssteve.reinhardt@amd.com 1326008Ssteve.reinhardt@amd.com notIdleFraction 1336008Ssteve.reinhardt@amd.com .name(name() + ".not_idle_fraction") 1346008Ssteve.reinhardt@amd.com .desc("Percentage of non-idle cycles") 1356008Ssteve.reinhardt@amd.com ; 1366007Ssteve.reinhardt@amd.com 1376007Ssteve.reinhardt@amd.com idleFraction 1386007Ssteve.reinhardt@amd.com .name(name() + ".idle_fraction") 1396007Ssteve.reinhardt@amd.com .desc("Percentage of idle cycles") 1406007Ssteve.reinhardt@amd.com ; 1412929Sktlim@umich.edu 1422929Sktlim@umich.edu icacheStallCycles 1432929Sktlim@umich.edu .name(name() + ".icache_stall_cycles") 1442929Sktlim@umich.edu .desc("ICache total stall cycles") 1456007Ssteve.reinhardt@amd.com .prereq(icacheStallCycles) 1466007Ssteve.reinhardt@amd.com ; 1472929Sktlim@umich.edu 1482929Sktlim@umich.edu dcacheStallCycles 1492929Sktlim@umich.edu .name(name() + ".dcache_stall_cycles") 1502929Sktlim@umich.edu .desc("DCache total stall cycles") 1516007Ssteve.reinhardt@amd.com .prereq(dcacheStallCycles) 1526007Ssteve.reinhardt@amd.com ; 1532929Sktlim@umich.edu 1542929Sktlim@umich.edu icacheRetryCycles 1556007Ssteve.reinhardt@amd.com .name(name() + ".icache_retry_cycles") 1562929Sktlim@umich.edu .desc("ICache total retry cycles") 1572929Sktlim@umich.edu .prereq(icacheRetryCycles) 1582929Sktlim@umich.edu ; 1592929Sktlim@umich.edu 1602929Sktlim@umich.edu dcacheRetryCycles 1612929Sktlim@umich.edu .name(name() + ".dcache_retry_cycles") 1622929Sktlim@umich.edu .desc("DCache total retry cycles") 1634937Sstever@gmail.com .prereq(dcacheRetryCycles) 1644937Sstever@gmail.com ; 1654937Sstever@gmail.com 1664937Sstever@gmail.com idleFraction = constant(1.0) - notIdleFraction; 1674937Sstever@gmail.com} 1684937Sstever@gmail.com 1694937Sstever@gmail.comvoid 1704937Sstever@gmail.comBaseSimpleCPU::resetStats() 1714937Sstever@gmail.com{ 1725773Snate@binkert.org startNumInst = numInst; 1734937Sstever@gmail.com // notIdleFraction = (_status != Idle); 1744937Sstever@gmail.com} 1754937Sstever@gmail.com 1762929Sktlim@umich.eduvoid 1772929Sktlim@umich.eduBaseSimpleCPU::serialize(ostream &os) 1782929Sktlim@umich.edu{ 1795773Snate@binkert.org BaseCPU::serialize(os); 1802929Sktlim@umich.edu// SERIALIZE_SCALAR(inst); 1812929Sktlim@umich.edu nameOut(os, csprintf("%s.xc.0", name())); 1822929Sktlim@umich.edu thread->serialize(os); 1832929Sktlim@umich.edu} 1842929Sktlim@umich.edu 1852929Sktlim@umich.eduvoid 1864937Sstever@gmail.comBaseSimpleCPU::unserialize(Checkpoint *cp, const string §ion) 1874937Sstever@gmail.com{ 1884937Sstever@gmail.com BaseCPU::unserialize(cp, section); 1894937Sstever@gmail.com// UNSERIALIZE_SCALAR(inst); 1904937Sstever@gmail.com thread->unserialize(cp, csprintf("%s.xc.0", section)); 1914937Sstever@gmail.com} 1924937Sstever@gmail.com 1934937Sstever@gmail.comvoid 1944937Sstever@gmail.comchange_thread_state(int thread_number, int activate, int priority) 1954937Sstever@gmail.com{ 1964937Sstever@gmail.com} 1974937Sstever@gmail.com 1984937Sstever@gmail.comFault 1994937Sstever@gmail.comBaseSimpleCPU::copySrcTranslate(Addr src) 2004937Sstever@gmail.com{ 2012929Sktlim@umich.edu#if 0 2022929Sktlim@umich.edu static bool no_warn = true; 2032929Sktlim@umich.edu int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 2042929Sktlim@umich.edu // Only support block sizes of 64 atm. 2052929Sktlim@umich.edu assert(blk_size == 64); 2062929Sktlim@umich.edu int offset = src & (blk_size - 1); 2072929Sktlim@umich.edu 2086011Ssteve.reinhardt@amd.com // Make sure block doesn't span page 2092929Sktlim@umich.edu if (no_warn && 2102929Sktlim@umich.edu (src & PageMask) != ((src + blk_size) & PageMask) && 2112929Sktlim@umich.edu (src >> 40) != 0xfffffc) { 2122929Sktlim@umich.edu warn("Copied block source spans pages %x.", src); 2132929Sktlim@umich.edu no_warn = false; 2142929Sktlim@umich.edu } 2152929Sktlim@umich.edu 2162929Sktlim@umich.edu memReq->reset(src & ~(blk_size - 1), blk_size); 2172997Sstever@eecs.umich.edu 2182997Sstever@eecs.umich.edu // translate to physical address 2192929Sktlim@umich.edu Fault fault = thread->translateDataReadReq(req); 2202997Sstever@eecs.umich.edu 2212997Sstever@eecs.umich.edu if (fault == NoFault) { 2222929Sktlim@umich.edu thread->copySrcAddr = src; 2232997Sstever@eecs.umich.edu thread->copySrcPhysAddr = memReq->paddr + offset; 2242997Sstever@eecs.umich.edu } else { 2252997Sstever@eecs.umich.edu assert(!fault->isAlignmentFault()); 2262929Sktlim@umich.edu 2272997Sstever@eecs.umich.edu thread->copySrcAddr = 0; 2282997Sstever@eecs.umich.edu thread->copySrcPhysAddr = 0; 2292997Sstever@eecs.umich.edu } 2302997Sstever@eecs.umich.edu return fault; 2315773Snate@binkert.org#else 2325773Snate@binkert.org return NoFault; 2332997Sstever@eecs.umich.edu#endif 2342997Sstever@eecs.umich.edu} 2356007Ssteve.reinhardt@amd.com 2366007Ssteve.reinhardt@amd.comFault 2372997Sstever@eecs.umich.eduBaseSimpleCPU::copy(Addr dest) 2382929Sktlim@umich.edu{ 2392997Sstever@eecs.umich.edu#if 0 2402997Sstever@eecs.umich.edu static bool no_warn = true; 2412997Sstever@eecs.umich.edu int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 2422997Sstever@eecs.umich.edu // Only support block sizes of 64 atm. 2432997Sstever@eecs.umich.edu assert(blk_size == 64); 2442997Sstever@eecs.umich.edu uint8_t data[blk_size]; 2452997Sstever@eecs.umich.edu //assert(thread->copySrcAddr); 2462929Sktlim@umich.edu int offset = dest & (blk_size - 1); 2472997Sstever@eecs.umich.edu 2482929Sktlim@umich.edu // Make sure block doesn't span page 2492929Sktlim@umich.edu if (no_warn && 2503005Sstever@eecs.umich.edu (dest & PageMask) != ((dest + blk_size) & PageMask) && 2513005Sstever@eecs.umich.edu (dest >> 40) != 0xfffffc) { 2523005Sstever@eecs.umich.edu no_warn = false; 2533005Sstever@eecs.umich.edu warn("Copied block destination spans pages %x. ", dest); 2546025Snate@binkert.org } 2556025Snate@binkert.org 2566025Snate@binkert.org memReq->reset(dest & ~(blk_size -1), blk_size); 2576025Snate@binkert.org // translate to physical address 2586025Snate@binkert.org Fault fault = thread->translateDataWriteReq(req); 2596025Snate@binkert.org 2604130Ssaidi@eecs.umich.edu if (fault == NoFault) { 2614130Ssaidi@eecs.umich.edu Addr dest_addr = memReq->paddr + offset; 2624130Ssaidi@eecs.umich.edu // Need to read straight from memory since we have more than 8 bytes. 2633691Shsul@eecs.umich.edu memReq->paddr = thread->copySrcPhysAddr; 2643005Sstever@eecs.umich.edu thread->mem->read(memReq, data); 2655721Shsul@eecs.umich.edu memReq->paddr = dest_addr; 2666194Sksewell@umich.edu thread->mem->write(memReq, data); 2676928SBrad.Beckmann@amd.com if (dcacheInterface) { 2683005Sstever@eecs.umich.edu memReq->cmd = Copy; 2696168Snate@binkert.org memReq->completionEvent = NULL; 2706928SBrad.Beckmann@amd.com memReq->paddr = thread->copySrcPhysAddr; 2716928SBrad.Beckmann@amd.com memReq->dest = dest_addr; 2726928SBrad.Beckmann@amd.com memReq->size = 64; 2736928SBrad.Beckmann@amd.com memReq->time = curTick; 2746928SBrad.Beckmann@amd.com memReq->flags &= ~INST_READ; 2756928SBrad.Beckmann@amd.com dcacheInterface->access(memReq); 2766928SBrad.Beckmann@amd.com } 2776928SBrad.Beckmann@amd.com } 2786928SBrad.Beckmann@amd.com else 2796928SBrad.Beckmann@amd.com assert(!fault->isAlignmentFault()); 2806928SBrad.Beckmann@amd.com 2816928SBrad.Beckmann@amd.com return fault; 2826928SBrad.Beckmann@amd.com#else 2836928SBrad.Beckmann@amd.com panic("copy not implemented"); 2846166Ssteve.reinhardt@amd.com return NoFault; 2852929Sktlim@umich.edu#endif 2862929Sktlim@umich.edu} 2873005Sstever@eecs.umich.edu 2882997Sstever@eecs.umich.edu#if FULL_SYSTEM 2892997Sstever@eecs.umich.eduAddr 2906293Ssteve.reinhardt@amd.comBaseSimpleCPU::dbg_vtophys(Addr addr) 2916293Ssteve.reinhardt@amd.com{ 2922929Sktlim@umich.edu return vtophys(tc, addr); 293} 294#endif // FULL_SYSTEM 295 296#if FULL_SYSTEM 297void 298BaseSimpleCPU::post_interrupt(int int_num, int index) 299{ 300 BaseCPU::post_interrupt(int_num, index); 301 302 if (thread->status() == ThreadContext::Suspended) { 303 DPRINTF(IPI,"Suspended Processor awoke\n"); 304 thread->activate(); 305 } 306} 307#endif // FULL_SYSTEM 308 309void 310BaseSimpleCPU::checkForInterrupts() 311{ 312#if FULL_SYSTEM 313 if (checkInterrupts && check_interrupts() && !thread->inPalMode()) { 314 int ipl = 0; 315 int summary = 0; 316 checkInterrupts = false; 317 318 if (thread->readMiscReg(IPR_SIRR)) { 319 for (int i = INTLEVEL_SOFTWARE_MIN; 320 i < INTLEVEL_SOFTWARE_MAX; i++) { 321 if (thread->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { 322 // See table 4-19 of 21164 hardware reference 323 ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; 324 summary |= (ULL(1) << i); 325 } 326 } 327 } 328 329 uint64_t interrupts = thread->cpu->intr_status(); 330 for (int i = INTLEVEL_EXTERNAL_MIN; 331 i < INTLEVEL_EXTERNAL_MAX; i++) { 332 if (interrupts & (ULL(1) << i)) { 333 // See table 4-19 of 21164 hardware reference 334 ipl = i; 335 summary |= (ULL(1) << i); 336 } 337 } 338 339 if (thread->readMiscReg(IPR_ASTRR)) 340 panic("asynchronous traps not implemented\n"); 341 342 if (ipl && ipl > thread->readMiscReg(IPR_IPLR)) { 343 thread->setMiscReg(IPR_ISR, summary); 344 thread->setMiscReg(IPR_INTID, ipl); 345 346 Fault(new InterruptFault)->invoke(tc); 347 348 DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", 349 thread->readMiscReg(IPR_IPLR), ipl, summary); 350 } 351 } 352#endif 353} 354 355 356Fault 357BaseSimpleCPU::setupFetchRequest(Request *req) 358{ 359 // set up memory request for instruction fetch 360#if THE_ISA == ALPHA_ISA 361 DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p",thread->readPC(), 362 thread->readNextPC()); 363#else 364 DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",thread->readPC(), 365 thread->readNextPC(),thread->readNextNPC()); 366#endif 367 368 req->setVirt(0, thread->readPC() & ~3, sizeof(MachInst), 369 (FULL_SYSTEM && (thread->readPC() & 1)) ? PHYSICAL : 0, 370 thread->readPC()); 371 372 Fault fault = thread->translateInstReq(req); 373 374 return fault; 375} 376 377 378void 379BaseSimpleCPU::preExecute() 380{ 381 // maintain $r0 semantics 382 thread->setIntReg(ZeroReg, 0); 383#if THE_ISA == ALPHA_ISA 384 thread->setFloatReg(ZeroReg, 0.0); 385#endif // ALPHA_ISA 386 387 // keep an instruction count 388 numInst++; 389 numInsts++; 390 391 thread->funcExeInst++; 392 393 // check for instruction-count-based events 394 comInstEventQueue[0]->serviceEvents(numInst); 395 396 // decode the instruction 397 inst = gtoh(inst); 398 curStaticInst = StaticInst::decode(makeExtMI(inst, thread->readPC())); 399 400 traceData = Trace::getInstRecord(curTick, tc, this, curStaticInst, 401 thread->readPC()); 402 403 DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n", 404 curStaticInst->getName(), curStaticInst->getOpcode(), 405 curStaticInst->machInst); 406 407#if FULL_SYSTEM 408 thread->setInst(inst); 409#endif // FULL_SYSTEM 410} 411 412void 413BaseSimpleCPU::postExecute() 414{ 415#if FULL_SYSTEM 416 if (thread->profile) { 417 bool usermode = 418 (thread->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; 419 thread->profilePC = usermode ? 1 : thread->readPC(); 420 ProfileNode *node = thread->profile->consume(tc, inst); 421 if (node) 422 thread->profileNode = node; 423 } 424#endif 425 426 if (curStaticInst->isMemRef()) { 427 numMemRefs++; 428 } 429 430 if (curStaticInst->isLoad()) { 431 ++numLoad; 432 comLoadEventQueue[0]->serviceEvents(numLoad); 433 } 434 435 traceFunctions(thread->readPC()); 436 437 if (traceData) { 438 traceData->finalize(); 439 } 440} 441 442 443void 444BaseSimpleCPU::advancePC(Fault fault) 445{ 446 if (fault != NoFault) { 447 fault->invoke(tc); 448 } 449 else { 450 // go to the next instruction 451 thread->setPC(thread->readNextPC()); 452#if THE_ISA == ALPHA_ISA 453 thread->setNextPC(thread->readNextPC() + sizeof(MachInst)); 454#else 455 thread->setNextPC(thread->readNextNPC()); 456 thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst)); 457 assert(thread->readNextPC() != thread->readNextNPC()); 458#endif 459 460 } 461 462#if FULL_SYSTEM 463 Addr oldpc; 464 do { 465 oldpc = thread->readPC(); 466 system->pcEventQueue.service(tc); 467 } while (oldpc != thread->readPC()); 468#endif 469} 470 471