base.cc revision 5529:9ae69b9cd7fd
16019Shines@cs.fsu.edu/* 210037SARM gem5 Developers * Copyright (c) 2002-2005 The Regents of The University of Michigan 37093Sgblack@eecs.umich.edu * All rights reserved. 47093Sgblack@eecs.umich.edu * 57093Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 67093Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 77093Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 87093Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 97093Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 107093Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 117093Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 127093Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137093Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 146019Shines@cs.fsu.edu * this software without specific prior written permission. 156019Shines@cs.fsu.edu * 166019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276019Shines@cs.fsu.edu * 286019Shines@cs.fsu.edu * Authors: Steve Reinhardt 296019Shines@cs.fsu.edu */ 306019Shines@cs.fsu.edu 316019Shines@cs.fsu.edu#include "arch/utility.hh" 326019Shines@cs.fsu.edu#include "arch/faults.hh" 336019Shines@cs.fsu.edu#include "base/cprintf.hh" 346019Shines@cs.fsu.edu#include "base/inifile.hh" 356019Shines@cs.fsu.edu#include "base/loader/symtab.hh" 366019Shines@cs.fsu.edu#include "base/misc.hh" 376019Shines@cs.fsu.edu#include "base/pollevent.hh" 386019Shines@cs.fsu.edu#include "base/range.hh" 396019Shines@cs.fsu.edu#include "base/stats/events.hh" 407399SAli.Saidi@ARM.com#include "base/trace.hh" 417399SAli.Saidi@ARM.com#include "cpu/base.hh" 426019Shines@cs.fsu.edu#include "cpu/exetrace.hh" 436019Shines@cs.fsu.edu#include "cpu/profile.hh" 446019Shines@cs.fsu.edu#include "cpu/simple/base.hh" 4510873Sandreas.sandberg@arm.com#include "cpu/simple_thread.hh" 4610873Sandreas.sandberg@arm.com#include "cpu/smt.hh" 4710474Sandreas.hansson@arm.com#include "cpu/static_inst.hh" 486019Shines@cs.fsu.edu#include "cpu/thread_context.hh" 496019Shines@cs.fsu.edu#include "mem/packet.hh" 506019Shines@cs.fsu.edu#include "sim/byteswap.hh" 516116Snate@binkert.org#include "sim/debug.hh" 526019Shines@cs.fsu.edu#include "sim/host.hh" 538782Sgblack@eecs.umich.edu#include "sim/sim_events.hh" 548756Sgblack@eecs.umich.edu#include "sim/sim_object.hh" 5510037SARM gem5 Developers#include "sim/stats.hh" 5610037SARM gem5 Developers#include "sim/system.hh" 576019Shines@cs.fsu.edu 586019Shines@cs.fsu.edu#if FULL_SYSTEM 596019Shines@cs.fsu.edu#include "arch/kernel_stats.hh" 606019Shines@cs.fsu.edu#include "arch/stacktrace.hh" 6110024Sdam.sunwoo@arm.com#include "arch/tlb.hh" 626019Shines@cs.fsu.edu#include "arch/vtophys.hh" 638232Snate@binkert.org#include "base/remote_gdb.hh" 648232Snate@binkert.org#else // !FULL_SYSTEM 658232Snate@binkert.org#include "mem/mem_object.hh" 666116Snate@binkert.org#endif // FULL_SYSTEM 676116Snate@binkert.org 688756Sgblack@eecs.umich.edu#include "params/BaseSimpleCPU.hh" 696019Shines@cs.fsu.edu 706019Shines@cs.fsu.eduusing namespace std; 716019Shines@cs.fsu.eduusing namespace TheISA; 726019Shines@cs.fsu.edu 736019Shines@cs.fsu.eduBaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p) 7410037SARM gem5 Developers : BaseCPU(p), traceData(NULL), thread(NULL), predecoder(NULL) 7510037SARM gem5 Developers{ 7610418Sandreas.hansson@arm.com#if FULL_SYSTEM 7710418Sandreas.hansson@arm.com thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb); 7810822Sandreas.hansson@arm.com#else 7910537Sandreas.hansson@arm.com thread = new SimpleThread(this, /* thread_num */ 0, p->workload[0], 8010537Sandreas.hansson@arm.com p->itb, p->dtb, /* asid */ 0); 8110418Sandreas.hansson@arm.com#endif // !FULL_SYSTEM 826019Shines@cs.fsu.edu 8310037SARM gem5 Developers thread->setStatus(ThreadContext::Unallocated); 847399SAli.Saidi@ARM.com 8510037SARM gem5 Developers tc = thread->getTC(); 8610037SARM gem5 Developers 8710037SARM gem5 Developers numInst = 0; 8810037SARM gem5 Developers startNumInst = 0; 896019Shines@cs.fsu.edu numLoad = 0; 906019Shines@cs.fsu.edu startNumLoad = 0; 916019Shines@cs.fsu.edu lastIcacheStall = 0; 926019Shines@cs.fsu.edu lastDcacheStall = 0; 9310037SARM gem5 Developers 9410037SARM gem5 Developers threadContexts.push_back(tc); 9510037SARM gem5 Developers 9610037SARM gem5 Developers 9710037SARM gem5 Developers fetchOffset = 0; 9810037SARM gem5 Developers stayAtPC = false; 9910037SARM gem5 Developers} 10010037SARM gem5 Developers 10110037SARM gem5 DevelopersBaseSimpleCPU::~BaseSimpleCPU() 10210037SARM gem5 Developers{ 10310037SARM gem5 Developers} 10410717Sandreas.hansson@arm.com 10510037SARM gem5 Developersvoid 10610037SARM gem5 DevelopersBaseSimpleCPU::deallocateContext(int thread_num) 10710717Sandreas.hansson@arm.com{ 1086019Shines@cs.fsu.edu // for now, these are equivalent 1096019Shines@cs.fsu.edu suspendContext(thread_num); 1107694SAli.Saidi@ARM.com} 1117694SAli.Saidi@ARM.com 1127694SAli.Saidi@ARM.com 11310037SARM gem5 Developersvoid 11410037SARM gem5 DevelopersBaseSimpleCPU::haltContext(int thread_num) 11510037SARM gem5 Developers{ 11610037SARM gem5 Developers // for now, these are equivalent 11710037SARM gem5 Developers suspendContext(thread_num); 11810037SARM gem5 Developers} 11910037SARM gem5 Developers 12010037SARM gem5 Developers 12110037SARM gem5 Developersvoid 1227694SAli.Saidi@ARM.comBaseSimpleCPU::regStats() 1237694SAli.Saidi@ARM.com{ 1247694SAli.Saidi@ARM.com using namespace Stats; 1257694SAli.Saidi@ARM.com 1267694SAli.Saidi@ARM.com BaseCPU::regStats(); 1277694SAli.Saidi@ARM.com 1289738Sandreas@sandberg.pp.se numInsts 1299738Sandreas@sandberg.pp.se .name(name() + ".num_insts") 1309738Sandreas@sandberg.pp.se .desc("Number of instructions executed") 1319738Sandreas@sandberg.pp.se ; 1329738Sandreas@sandberg.pp.se 1339738Sandreas@sandberg.pp.se numMemRefs 1347404SAli.Saidi@ARM.com .name(name() + ".num_refs") 13510037SARM gem5 Developers .desc("Number of memory references") 13610037SARM gem5 Developers ; 1376019Shines@cs.fsu.edu 1387404SAli.Saidi@ARM.com notIdleFraction 1397404SAli.Saidi@ARM.com .name(name() + ".not_idle_fraction") 1407404SAli.Saidi@ARM.com .desc("Percentage of non-idle cycles") 14110037SARM gem5 Developers ; 1427404SAli.Saidi@ARM.com 1437404SAli.Saidi@ARM.com idleFraction 14410037SARM gem5 Developers .name(name() + ".idle_fraction") 14510037SARM gem5 Developers .desc("Percentage of idle cycles") 14610037SARM gem5 Developers ; 14710037SARM gem5 Developers 14810037SARM gem5 Developers icacheStallCycles 1499535Smrinmoy.ghosh@arm.com .name(name() + ".icache_stall_cycles") 1507697SAli.Saidi@ARM.com .desc("ICache total stall cycles") 1517697SAli.Saidi@ARM.com .prereq(icacheStallCycles) 15210037SARM gem5 Developers ; 1537697SAli.Saidi@ARM.com 1547697SAli.Saidi@ARM.com dcacheStallCycles 1557697SAli.Saidi@ARM.com .name(name() + ".dcache_stall_cycles") 1567697SAli.Saidi@ARM.com .desc("DCache total stall cycles") 1577697SAli.Saidi@ARM.com .prereq(dcacheStallCycles) 1587404SAli.Saidi@ARM.com ; 1597404SAli.Saidi@ARM.com 16010037SARM gem5 Developers icacheRetryCycles 1617404SAli.Saidi@ARM.com .name(name() + ".icache_retry_cycles") 1627404SAli.Saidi@ARM.com .desc("ICache total retry cycles") 16310037SARM gem5 Developers .prereq(icacheRetryCycles) 16410037SARM gem5 Developers ; 16510037SARM gem5 Developers 16610037SARM gem5 Developers dcacheRetryCycles 16710037SARM gem5 Developers .name(name() + ".dcache_retry_cycles") 16810037SARM gem5 Developers .desc("DCache total retry cycles") 16910037SARM gem5 Developers .prereq(dcacheRetryCycles) 17010037SARM gem5 Developers ; 17110367SAndrew.Bardsley@arm.com 17210037SARM gem5 Developers idleFraction = constant(1.0) - notIdleFraction; 1737404SAli.Saidi@ARM.com} 1746019Shines@cs.fsu.edu 1756019Shines@cs.fsu.eduvoid 1766019Shines@cs.fsu.eduBaseSimpleCPU::resetStats() 1776019Shines@cs.fsu.edu{ 1787404SAli.Saidi@ARM.com// startNumInst = numInst; 1796019Shines@cs.fsu.edu notIdleFraction = (_status != Idle); 1807404SAli.Saidi@ARM.com} 18110037SARM gem5 Developers 18210037SARM gem5 Developersvoid 18310037SARM gem5 DevelopersBaseSimpleCPU::serialize(ostream &os) 18410037SARM gem5 Developers{ 18510037SARM gem5 Developers SERIALIZE_ENUM(_status); 18610037SARM gem5 Developers BaseCPU::serialize(os); 1877404SAli.Saidi@ARM.com// SERIALIZE_SCALAR(inst); 18810037SARM gem5 Developers nameOut(os, csprintf("%s.xc.0", name())); 18910037SARM gem5 Developers thread->serialize(os); 19010037SARM gem5 Developers} 1917697SAli.Saidi@ARM.com 19210037SARM gem5 Developersvoid 19310037SARM gem5 DevelopersBaseSimpleCPU::unserialize(Checkpoint *cp, const string §ion) 19410037SARM gem5 Developers{ 19510037SARM gem5 Developers UNSERIALIZE_ENUM(_status); 1967404SAli.Saidi@ARM.com BaseCPU::unserialize(cp, section); 1977697SAli.Saidi@ARM.com// UNSERIALIZE_SCALAR(inst); 1987404SAli.Saidi@ARM.com thread->unserialize(cp, csprintf("%s.xc.0", section)); 19910037SARM gem5 Developers} 20010037SARM gem5 Developers 2017697SAli.Saidi@ARM.comvoid 2027734SAli.Saidi@ARM.comchange_thread_state(int thread_number, int activate, int priority) 2037734SAli.Saidi@ARM.com{ 20410463SAndreas.Sandberg@ARM.com} 2056019Shines@cs.fsu.edu 2066019Shines@cs.fsu.eduFault 2076019Shines@cs.fsu.eduBaseSimpleCPU::copySrcTranslate(Addr src) 20810037SARM gem5 Developers{ 2097404SAli.Saidi@ARM.com#if 0 2107404SAli.Saidi@ARM.com static bool no_warn = true; 2117404SAli.Saidi@ARM.com int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 2127404SAli.Saidi@ARM.com // Only support block sizes of 64 atm. 2137404SAli.Saidi@ARM.com assert(blk_size == 64); 21410037SARM gem5 Developers int offset = src & (blk_size - 1); 21510037SARM gem5 Developers 21610037SARM gem5 Developers // Make sure block doesn't span page 21710037SARM gem5 Developers if (no_warn && 2187404SAli.Saidi@ARM.com (src & PageMask) != ((src + blk_size) & PageMask) && 2197404SAli.Saidi@ARM.com (src >> 40) != 0xfffffc) { 2207404SAli.Saidi@ARM.com warn("Copied block source spans pages %x.", src); 2217404SAli.Saidi@ARM.com no_warn = false; 22210037SARM gem5 Developers } 2236019Shines@cs.fsu.edu 22410037SARM gem5 Developers memReq->reset(src & ~(blk_size - 1), blk_size); 22510037SARM gem5 Developers 2267404SAli.Saidi@ARM.com // translate to physical address 2277404SAli.Saidi@ARM.com Fault fault = thread->translateDataReadReq(req); 2287404SAli.Saidi@ARM.com 22910037SARM gem5 Developers if (fault == NoFault) { 23010037SARM gem5 Developers thread->copySrcAddr = src; 23110037SARM gem5 Developers thread->copySrcPhysAddr = memReq->paddr + offset; 23210037SARM gem5 Developers } else { 23310037SARM gem5 Developers assert(!fault->isAlignmentFault()); 23410037SARM gem5 Developers 23510037SARM gem5 Developers thread->copySrcAddr = 0; 23610037SARM gem5 Developers thread->copySrcPhysAddr = 0; 23710037SARM gem5 Developers } 23810037SARM gem5 Developers return fault; 2397404SAli.Saidi@ARM.com#else 2407404SAli.Saidi@ARM.com return NoFault; 24110037SARM gem5 Developers#endif 24210037SARM gem5 Developers} 24310037SARM gem5 Developers 24410037SARM gem5 DevelopersFault 24510037SARM gem5 DevelopersBaseSimpleCPU::copy(Addr dest) 24610037SARM gem5 Developers{ 24710037SARM gem5 Developers#if 0 24810037SARM gem5 Developers static bool no_warn = true; 24910037SARM gem5 Developers int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 25010037SARM gem5 Developers // Only support block sizes of 64 atm. 25110037SARM gem5 Developers assert(blk_size == 64); 25210037SARM gem5 Developers uint8_t data[blk_size]; 25310037SARM gem5 Developers //assert(thread->copySrcAddr); 25410037SARM gem5 Developers int offset = dest & (blk_size - 1); 25510037SARM gem5 Developers 25610037SARM gem5 Developers // Make sure block doesn't span page 25710037SARM gem5 Developers if (no_warn && 25810037SARM gem5 Developers (dest & PageMask) != ((dest + blk_size) & PageMask) && 25910037SARM gem5 Developers (dest >> 40) != 0xfffffc) { 26010037SARM gem5 Developers no_warn = false; 26110037SARM gem5 Developers warn("Copied block destination spans pages %x. ", dest); 26210037SARM gem5 Developers } 26310037SARM gem5 Developers 26410037SARM gem5 Developers memReq->reset(dest & ~(blk_size -1), blk_size); 26510037SARM gem5 Developers // translate to physical address 26610037SARM gem5 Developers Fault fault = thread->translateDataWriteReq(req); 26710037SARM gem5 Developers 2687734SAli.Saidi@ARM.com if (fault == NoFault) { 2697734SAli.Saidi@ARM.com Addr dest_addr = memReq->paddr + offset; 27010037SARM gem5 Developers // Need to read straight from memory since we have more than 8 bytes. 27110037SARM gem5 Developers memReq->paddr = thread->copySrcPhysAddr; 27210037SARM gem5 Developers thread->mem->read(memReq, data); 27310037SARM gem5 Developers memReq->paddr = dest_addr; 27410037SARM gem5 Developers thread->mem->write(memReq, data); 2756019Shines@cs.fsu.edu if (dcacheInterface) { 2766019Shines@cs.fsu.edu memReq->cmd = Copy; 2777404SAli.Saidi@ARM.com memReq->completionEvent = NULL; 27810037SARM gem5 Developers memReq->paddr = thread->copySrcPhysAddr; 2797404SAli.Saidi@ARM.com memReq->dest = dest_addr; 28010037SARM gem5 Developers memReq->size = 64; 28110037SARM gem5 Developers memReq->time = curTick; 28210037SARM gem5 Developers memReq->flags &= ~INST_READ; 28310037SARM gem5 Developers dcacheInterface->access(memReq); 2847734SAli.Saidi@ARM.com } 2857404SAli.Saidi@ARM.com } 2867404SAli.Saidi@ARM.com else 2877404SAli.Saidi@ARM.com assert(!fault->isAlignmentFault()); 28810037SARM gem5 Developers 2897404SAli.Saidi@ARM.com return fault; 29010037SARM gem5 Developers#else 29110037SARM gem5 Developers panic("copy not implemented"); 2927404SAli.Saidi@ARM.com return NoFault; 29310037SARM gem5 Developers#endif 2947404SAli.Saidi@ARM.com} 2957404SAli.Saidi@ARM.com 2967404SAli.Saidi@ARM.com#if FULL_SYSTEM 2977404SAli.Saidi@ARM.comAddr 29810037SARM gem5 DevelopersBaseSimpleCPU::dbg_vtophys(Addr addr) 29910037SARM gem5 Developers{ 30010037SARM gem5 Developers return vtophys(tc, addr); 30110037SARM gem5 Developers} 3027404SAli.Saidi@ARM.com#endif // FULL_SYSTEM 30310037SARM gem5 Developers 3047734SAli.Saidi@ARM.com#if FULL_SYSTEM 3057404SAli.Saidi@ARM.comvoid 30610037SARM gem5 DevelopersBaseSimpleCPU::post_interrupt(int int_num, int index) 3077404SAli.Saidi@ARM.com{ 3087734SAli.Saidi@ARM.com BaseCPU::post_interrupt(int_num, index); 3097404SAli.Saidi@ARM.com 3107404SAli.Saidi@ARM.com if (thread->status() == ThreadContext::Suspended) { 3117404SAli.Saidi@ARM.com DPRINTF(Quiesce,"Suspended Processor awoke\n"); 31210037SARM gem5 Developers thread->activate(); 3137404SAli.Saidi@ARM.com } 31410037SARM gem5 Developers} 31510037SARM gem5 Developers#endif // FULL_SYSTEM 31610037SARM gem5 Developers 31710037SARM gem5 Developersvoid 31810037SARM gem5 DevelopersBaseSimpleCPU::checkForInterrupts() 3197404SAli.Saidi@ARM.com{ 32010037SARM gem5 Developers#if FULL_SYSTEM 32110037SARM gem5 Developers if (check_interrupts(tc)) { 32210037SARM gem5 Developers Fault interrupt = interrupts.getInterrupt(tc); 32310037SARM gem5 Developers 3247404SAli.Saidi@ARM.com if (interrupt != NoFault) { 32510037SARM gem5 Developers interrupts.updateIntrInfo(tc); 32610037SARM gem5 Developers interrupt->invoke(tc); 32710037SARM gem5 Developers } 32810037SARM gem5 Developers } 32910037SARM gem5 Developers#endif 33010037SARM gem5 Developers} 33110037SARM gem5 Developers 3327404SAli.Saidi@ARM.com 3337734SAli.Saidi@ARM.comFault 3347404SAli.Saidi@ARM.comBaseSimpleCPU::setupFetchRequest(Request *req) 33510037SARM gem5 Developers{ 33610037SARM gem5 Developers Addr threadPC = thread->readPC(); 3377404SAli.Saidi@ARM.com 33810037SARM gem5 Developers // set up memory request for instruction fetch 33910037SARM gem5 Developers#if ISA_HAS_DELAY_SLOT 34010037SARM gem5 Developers DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",threadPC, 34110037SARM gem5 Developers thread->readNextPC(),thread->readNextNPC()); 34210037SARM gem5 Developers#else 34310037SARM gem5 Developers DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p\n",threadPC, 34410037SARM gem5 Developers thread->readNextPC()); 34510037SARM gem5 Developers#endif 34610037SARM gem5 Developers 34710037SARM gem5 Developers Addr fetchPC = (threadPC & PCMask) + fetchOffset; 34810037SARM gem5 Developers req->setVirt(0, fetchPC, sizeof(MachInst), 0, threadPC); 34910037SARM gem5 Developers 35010037SARM gem5 Developers Fault fault = thread->translateInstReq(req); 35110037SARM gem5 Developers 3527404SAli.Saidi@ARM.com return fault; 3537404SAli.Saidi@ARM.com} 3546019Shines@cs.fsu.edu 3559439SAndreas.Sandberg@ARM.com 3569439SAndreas.Sandberg@ARM.comvoid 3579439SAndreas.Sandberg@ARM.comBaseSimpleCPU::preExecute() 3589439SAndreas.Sandberg@ARM.com{ 3599439SAndreas.Sandberg@ARM.com // maintain $r0 semantics 3609439SAndreas.Sandberg@ARM.com thread->setIntReg(ZeroReg, 0); 3619439SAndreas.Sandberg@ARM.com#if THE_ISA == ALPHA_ISA 3629439SAndreas.Sandberg@ARM.com thread->setFloatReg(ZeroReg, 0.0); 36310194SGeoffrey.Blake@arm.com#endif // ALPHA_ISA 36410194SGeoffrey.Blake@arm.com 36510194SGeoffrey.Blake@arm.com // check for instruction-count-based events 36610194SGeoffrey.Blake@arm.com comInstEventQueue[0]->serviceEvents(numInst); 36710194SGeoffrey.Blake@arm.com 36810194SGeoffrey.Blake@arm.com // decode the instruction 36910194SGeoffrey.Blake@arm.com inst = gtoh(inst); 37010194SGeoffrey.Blake@arm.com 37110194SGeoffrey.Blake@arm.com //If we're not in the middle of a macro instruction 37210194SGeoffrey.Blake@arm.com if (!curMacroStaticInst) { 37310194SGeoffrey.Blake@arm.com 37410194SGeoffrey.Blake@arm.com StaticInstPtr instPtr = NULL; 37510194SGeoffrey.Blake@arm.com 37610194SGeoffrey.Blake@arm.com //Predecode, ie bundle up an ExtMachInst 37710194SGeoffrey.Blake@arm.com //This should go away once the constructor can be set up properly 37810194SGeoffrey.Blake@arm.com predecoder.setTC(thread->getTC()); 37910194SGeoffrey.Blake@arm.com //If more fetch data is needed, pass it in. 38010194SGeoffrey.Blake@arm.com Addr fetchPC = (thread->readPC() & PCMask) + fetchOffset; 38110194SGeoffrey.Blake@arm.com //if(predecoder.needMoreBytes()) 38210194SGeoffrey.Blake@arm.com predecoder.moreBytes(thread->readPC(), fetchPC, inst); 38310194SGeoffrey.Blake@arm.com //else 38410194SGeoffrey.Blake@arm.com // predecoder.process(); 38510194SGeoffrey.Blake@arm.com 3866019Shines@cs.fsu.edu //If an instruction is ready, decode it. Otherwise, we'll have to 3876019Shines@cs.fsu.edu //fetch beyond the MachInst at the current pc. 3887733SAli.Saidi@ARM.com if (predecoder.extMachInstReady()) { 3897733SAli.Saidi@ARM.com#if THE_ISA == X86_ISA 3907733SAli.Saidi@ARM.com thread->setNextPC(thread->readPC() + predecoder.getInstSize()); 39110037SARM gem5 Developers#endif // X86_ISA 39210037SARM gem5 Developers stayAtPC = false; 39310037SARM gem5 Developers instPtr = StaticInst::decode(predecoder.getExtMachInst(), 3948353SAli.Saidi@ARM.com thread->readPC()); 3958353SAli.Saidi@ARM.com } else { 3968353SAli.Saidi@ARM.com stayAtPC = true; 3977733SAli.Saidi@ARM.com fetchOffset += sizeof(MachInst); 3987733SAli.Saidi@ARM.com } 3997733SAli.Saidi@ARM.com 4007733SAli.Saidi@ARM.com //If we decoded an instruction and it's microcoded, start pulling 4016019Shines@cs.fsu.edu //out micro ops 4026019Shines@cs.fsu.edu if (instPtr && instPtr->isMacroop()) { 4036019Shines@cs.fsu.edu curMacroStaticInst = instPtr; 4046019Shines@cs.fsu.edu curStaticInst = curMacroStaticInst-> 4056019Shines@cs.fsu.edu fetchMicroop(thread->readMicroPC()); 4067733SAli.Saidi@ARM.com } else { 4076019Shines@cs.fsu.edu curStaticInst = instPtr; 4087733SAli.Saidi@ARM.com } 40910037SARM gem5 Developers } else { 41010037SARM gem5 Developers //Read the next micro op from the macro op 41110037SARM gem5 Developers curStaticInst = curMacroStaticInst-> 41210037SARM gem5 Developers fetchMicroop(thread->readMicroPC()); 4138353SAli.Saidi@ARM.com } 4148353SAli.Saidi@ARM.com 4158353SAli.Saidi@ARM.com //If we decoded an instruction this "tick", record information about it. 4167733SAli.Saidi@ARM.com if(curStaticInst) 4177733SAli.Saidi@ARM.com { 4186019Shines@cs.fsu.edu#if TRACING_ON 4196019Shines@cs.fsu.edu traceData = tracer->getInstRecord(curTick, tc, curStaticInst, 4206019Shines@cs.fsu.edu thread->readPC()); 4216019Shines@cs.fsu.edu 4226019Shines@cs.fsu.edu DPRINTF(Decode,"Decode: Decoded %s instruction: 0x%x\n", 4237734SAli.Saidi@ARM.com curStaticInst->getName(), curStaticInst->machInst); 4247734SAli.Saidi@ARM.com#endif // TRACING_ON 4257734SAli.Saidi@ARM.com 4267734SAli.Saidi@ARM.com#if FULL_SYSTEM 4277734SAli.Saidi@ARM.com thread->setInst(inst); 4287734SAli.Saidi@ARM.com#endif // FULL_SYSTEM 4297734SAli.Saidi@ARM.com } 4307734SAli.Saidi@ARM.com} 4317734SAli.Saidi@ARM.com 4327734SAli.Saidi@ARM.comvoid 4337734SAli.Saidi@ARM.comBaseSimpleCPU::postExecute() 4347734SAli.Saidi@ARM.com{ 4357734SAli.Saidi@ARM.com#if FULL_SYSTEM 4367734SAli.Saidi@ARM.com if (thread->profile && curStaticInst) { 4377734SAli.Saidi@ARM.com bool usermode = TheISA::inUserMode(tc); 4387734SAli.Saidi@ARM.com thread->profilePC = usermode ? 1 : thread->readPC(); 4396019Shines@cs.fsu.edu ProfileNode *node = thread->profile->consume(tc, curStaticInst); 4406019Shines@cs.fsu.edu if (node) 4416019Shines@cs.fsu.edu thread->profileNode = node; 4426019Shines@cs.fsu.edu } 4437734SAli.Saidi@ARM.com#endif 4446019Shines@cs.fsu.edu 4456019Shines@cs.fsu.edu if (curStaticInst->isMemRef()) { 4466019Shines@cs.fsu.edu numMemRefs++; 4476019Shines@cs.fsu.edu } 4487734SAli.Saidi@ARM.com 4496019Shines@cs.fsu.edu if (curStaticInst->isLoad()) { 4506019Shines@cs.fsu.edu ++numLoad; 4516019Shines@cs.fsu.edu comLoadEventQueue[0]->serviceEvents(numLoad); 4526019Shines@cs.fsu.edu } 4537734SAli.Saidi@ARM.com 4546019Shines@cs.fsu.edu traceFunctions(thread->readPC()); 4556019Shines@cs.fsu.edu 4566019Shines@cs.fsu.edu if (traceData) { 4576019Shines@cs.fsu.edu traceData->dump(); 4587734SAli.Saidi@ARM.com delete traceData; 4596019Shines@cs.fsu.edu traceData = NULL; 4606019Shines@cs.fsu.edu } 4616019Shines@cs.fsu.edu} 4626019Shines@cs.fsu.edu 4637734SAli.Saidi@ARM.com 4646019Shines@cs.fsu.eduvoid 4656019Shines@cs.fsu.eduBaseSimpleCPU::advancePC(Fault fault) 4666019Shines@cs.fsu.edu{ 4676019Shines@cs.fsu.edu //Since we're moving to a new pc, zero out the offset 4686019Shines@cs.fsu.edu fetchOffset = 0; 4696019Shines@cs.fsu.edu if (fault != NoFault) { 4706019Shines@cs.fsu.edu curMacroStaticInst = StaticInst::nullStaticInstPtr; 4716019Shines@cs.fsu.edu predecoder.reset(); 4726019Shines@cs.fsu.edu thread->setMicroPC(0); 4736019Shines@cs.fsu.edu thread->setNextMicroPC(1); 4746019Shines@cs.fsu.edu fault->invoke(tc); 4756019Shines@cs.fsu.edu } else { 4766019Shines@cs.fsu.edu //If we're at the last micro op for this instruction 4776019Shines@cs.fsu.edu if (curStaticInst && curStaticInst->isLastMicroop()) { 4786019Shines@cs.fsu.edu //We should be working with a macro op 4796019Shines@cs.fsu.edu assert(curMacroStaticInst); 4806019Shines@cs.fsu.edu //Close out this macro op, and clean up the 4816019Shines@cs.fsu.edu //microcode state 4826019Shines@cs.fsu.edu curMacroStaticInst = StaticInst::nullStaticInstPtr; 4837734SAli.Saidi@ARM.com thread->setMicroPC(0); 4847734SAli.Saidi@ARM.com thread->setNextMicroPC(1); 4857734SAli.Saidi@ARM.com } 4867734SAli.Saidi@ARM.com //If we're still in a macro op 4877734SAli.Saidi@ARM.com if (curMacroStaticInst) { 4887734SAli.Saidi@ARM.com //Advance the micro pc 4897734SAli.Saidi@ARM.com thread->setMicroPC(thread->readNextMicroPC()); 4907734SAli.Saidi@ARM.com //Advance the "next" micro pc. Note that there are no delay 4917734SAli.Saidi@ARM.com //slots, and micro ops are "word" addressed. 4927734SAli.Saidi@ARM.com thread->setNextMicroPC(thread->readNextMicroPC() + 1); 4937734SAli.Saidi@ARM.com } else { 4947734SAli.Saidi@ARM.com // go to the next instruction 4957734SAli.Saidi@ARM.com thread->setPC(thread->readNextPC()); 4967734SAli.Saidi@ARM.com thread->setNextPC(thread->readNextNPC()); 4977734SAli.Saidi@ARM.com thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst)); 4987734SAli.Saidi@ARM.com assert(thread->readNextPC() != thread->readNextNPC()); 4997734SAli.Saidi@ARM.com } 5007734SAli.Saidi@ARM.com } 5017734SAli.Saidi@ARM.com} 5027734SAli.Saidi@ARM.com 5037734SAli.Saidi@ARM.com/*Fault 5047734SAli.Saidi@ARM.comBaseSimpleCPU::CacheOp(uint8_t Op, Addr EffAddr) 5057734SAli.Saidi@ARM.com{ 5067734SAli.Saidi@ARM.com // translate to physical address 5077734SAli.Saidi@ARM.com Fault fault = NoFault; 5087734SAli.Saidi@ARM.com int CacheID = Op & 0x3; // Lower 3 bits identify Cache 5097734SAli.Saidi@ARM.com int CacheOP = Op >> 2; // Upper 3 bits identify Cache Operation 5107734SAli.Saidi@ARM.com if(CacheID > 1) 5117734SAli.Saidi@ARM.com { 5127734SAli.Saidi@ARM.com warn("CacheOps not implemented for secondary/tertiary caches\n"); 5137734SAli.Saidi@ARM.com } 5147734SAli.Saidi@ARM.com else 5157734SAli.Saidi@ARM.com { 5167734SAli.Saidi@ARM.com switch(CacheOP) 5177734SAli.Saidi@ARM.com { // Fill Packet Type 5187734SAli.Saidi@ARM.com case 0: warn("Invalidate Cache Op\n"); 5197734SAli.Saidi@ARM.com break; 5207734SAli.Saidi@ARM.com case 1: warn("Index Load Tag Cache Op\n"); 5217734SAli.Saidi@ARM.com break; 5227734SAli.Saidi@ARM.com case 2: warn("Index Store Tag Cache Op\n"); 5237734SAli.Saidi@ARM.com break; 5247734SAli.Saidi@ARM.com case 4: warn("Hit Invalidate Cache Op\n"); 5257734SAli.Saidi@ARM.com break; 5267734SAli.Saidi@ARM.com case 5: warn("Fill/Hit Writeback Invalidate Cache Op\n"); 5277734SAli.Saidi@ARM.com break; 5287734SAli.Saidi@ARM.com case 6: warn("Hit Writeback\n"); 5297734SAli.Saidi@ARM.com break; 5307734SAli.Saidi@ARM.com case 7: warn("Fetch & Lock Cache Op\n"); 5317734SAli.Saidi@ARM.com break; 5327734SAli.Saidi@ARM.com default: warn("Unimplemented Cache Op\n"); 5337734SAli.Saidi@ARM.com } 5346019Shines@cs.fsu.edu } 5356019Shines@cs.fsu.edu return fault; 53610463SAndreas.Sandberg@ARM.com}*/ 53710463SAndreas.Sandberg@ARM.com