base.cc revision 4156
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 311308Santhony.gutierrez@amd.com * All rights reserved. 411308Santhony.gutierrez@amd.com * 511308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without 611308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are 711308Santhony.gutierrez@amd.com * met: redistributions of source code must retain the above copyright 811308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer; 911308Santhony.gutierrez@amd.com * redistributions in binary form must reproduce the above copyright 1011308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer in the 1111308Santhony.gutierrez@amd.com * documentation and/or other materials provided with the distribution; 1211308Santhony.gutierrez@amd.com * neither the name of the copyright holders nor the names of its 1311308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from 1411308Santhony.gutierrez@amd.com * this software without specific prior written permission. 1511308Santhony.gutierrez@amd.com * 1611308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711308Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811308Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011308Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611308Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711308Santhony.gutierrez@amd.com * 2811308Santhony.gutierrez@amd.com * Authors: Steve Reinhardt 2911308Santhony.gutierrez@amd.com */ 3011308Santhony.gutierrez@amd.com 3111308Santhony.gutierrez@amd.com#include "arch/utility.hh" 3211308Santhony.gutierrez@amd.com#include "arch/faults.hh" 3311308Santhony.gutierrez@amd.com#include "base/cprintf.hh" 3411308Santhony.gutierrez@amd.com#include "base/inifile.hh" 3511308Santhony.gutierrez@amd.com#include "base/loader/symtab.hh" 3611308Santhony.gutierrez@amd.com#include "base/misc.hh" 3711308Santhony.gutierrez@amd.com#include "base/pollevent.hh" 3811308Santhony.gutierrez@amd.com#include "base/range.hh" 3911308Santhony.gutierrez@amd.com#include "base/stats/events.hh" 4011308Santhony.gutierrez@amd.com#include "base/trace.hh" 4111308Santhony.gutierrez@amd.com#include "cpu/base.hh" 4211308Santhony.gutierrez@amd.com#include "cpu/exetrace.hh" 4311308Santhony.gutierrez@amd.com#include "cpu/profile.hh" 4411308Santhony.gutierrez@amd.com#include "cpu/simple/base.hh" 4511308Santhony.gutierrez@amd.com#include "cpu/simple_thread.hh" 4611308Santhony.gutierrez@amd.com#include "cpu/smt.hh" 4711308Santhony.gutierrez@amd.com#include "cpu/static_inst.hh" 4811308Santhony.gutierrez@amd.com#include "cpu/thread_context.hh" 4911308Santhony.gutierrez@amd.com#include "mem/packet.hh" 5011308Santhony.gutierrez@amd.com#include "sim/builder.hh" 5111308Santhony.gutierrez@amd.com#include "sim/byteswap.hh" 5211308Santhony.gutierrez@amd.com#include "sim/debug.hh" 5311308Santhony.gutierrez@amd.com#include "sim/host.hh" 5411308Santhony.gutierrez@amd.com#include "sim/sim_events.hh" 5511308Santhony.gutierrez@amd.com#include "sim/sim_object.hh" 5611308Santhony.gutierrez@amd.com#include "sim/stats.hh" 5711308Santhony.gutierrez@amd.com#include "sim/system.hh" 5811308Santhony.gutierrez@amd.com 5911308Santhony.gutierrez@amd.com#if FULL_SYSTEM 6011308Santhony.gutierrez@amd.com#include "arch/kernel_stats.hh" 6111308Santhony.gutierrez@amd.com#include "arch/stacktrace.hh" 6211308Santhony.gutierrez@amd.com#include "arch/tlb.hh" 6311308Santhony.gutierrez@amd.com#include "arch/vtophys.hh" 6411308Santhony.gutierrez@amd.com#include "base/remote_gdb.hh" 6511308Santhony.gutierrez@amd.com#else // !FULL_SYSTEM 6611308Santhony.gutierrez@amd.com#include "mem/mem_object.hh" 6711308Santhony.gutierrez@amd.com#endif // FULL_SYSTEM 6811308Santhony.gutierrez@amd.com 6911308Santhony.gutierrez@amd.comusing namespace std; 7011308Santhony.gutierrez@amd.comusing namespace TheISA; 7111308Santhony.gutierrez@amd.com 7211308Santhony.gutierrez@amd.comBaseSimpleCPU::BaseSimpleCPU(Params *p) 7311308Santhony.gutierrez@amd.com : BaseCPU(p), thread(NULL) 7411308Santhony.gutierrez@amd.com{ 7511308Santhony.gutierrez@amd.com#if FULL_SYSTEM 7611308Santhony.gutierrez@amd.com thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb); 7711308Santhony.gutierrez@amd.com#else 7811308Santhony.gutierrez@amd.com thread = new SimpleThread(this, /* thread_num */ 0, p->process, 7911308Santhony.gutierrez@amd.com /* asid */ 0); 8011308Santhony.gutierrez@amd.com#endif // !FULL_SYSTEM 8111308Santhony.gutierrez@amd.com 8211308Santhony.gutierrez@amd.com thread->setStatus(ThreadContext::Suspended); 8311308Santhony.gutierrez@amd.com 8411308Santhony.gutierrez@amd.com tc = thread->getTC(); 8511308Santhony.gutierrez@amd.com 8611308Santhony.gutierrez@amd.com numInst = 0; 8711308Santhony.gutierrez@amd.com startNumInst = 0; 8811308Santhony.gutierrez@amd.com numLoad = 0; 8911308Santhony.gutierrez@amd.com startNumLoad = 0; 9011308Santhony.gutierrez@amd.com lastIcacheStall = 0; 9111308Santhony.gutierrez@amd.com lastDcacheStall = 0; 9211308Santhony.gutierrez@amd.com 9311308Santhony.gutierrez@amd.com threadContexts.push_back(tc); 9411308Santhony.gutierrez@amd.com} 9511308Santhony.gutierrez@amd.com 9611308Santhony.gutierrez@amd.comBaseSimpleCPU::~BaseSimpleCPU() 9711308Santhony.gutierrez@amd.com{ 9811308Santhony.gutierrez@amd.com} 9911308Santhony.gutierrez@amd.com 10011308Santhony.gutierrez@amd.comvoid 10111308Santhony.gutierrez@amd.comBaseSimpleCPU::deallocateContext(int thread_num) 10211308Santhony.gutierrez@amd.com{ 10311308Santhony.gutierrez@amd.com // for now, these are equivalent 10411308Santhony.gutierrez@amd.com suspendContext(thread_num); 10511308Santhony.gutierrez@amd.com} 10611308Santhony.gutierrez@amd.com 10711308Santhony.gutierrez@amd.com 10811308Santhony.gutierrez@amd.comvoid 10911308Santhony.gutierrez@amd.comBaseSimpleCPU::haltContext(int thread_num) 11011308Santhony.gutierrez@amd.com{ 11111308Santhony.gutierrez@amd.com // for now, these are equivalent 11211308Santhony.gutierrez@amd.com suspendContext(thread_num); 11311308Santhony.gutierrez@amd.com} 11411308Santhony.gutierrez@amd.com 11511308Santhony.gutierrez@amd.com 11611308Santhony.gutierrez@amd.comvoid 11711308Santhony.gutierrez@amd.comBaseSimpleCPU::regStats() 11811308Santhony.gutierrez@amd.com{ 11911308Santhony.gutierrez@amd.com using namespace Stats; 12011308Santhony.gutierrez@amd.com 12111308Santhony.gutierrez@amd.com BaseCPU::regStats(); 12211308Santhony.gutierrez@amd.com 12311308Santhony.gutierrez@amd.com numInsts 12411308Santhony.gutierrez@amd.com .name(name() + ".num_insts") 12511308Santhony.gutierrez@amd.com .desc("Number of instructions executed") 12611308Santhony.gutierrez@amd.com ; 12711308Santhony.gutierrez@amd.com 12811308Santhony.gutierrez@amd.com numMemRefs 12911308Santhony.gutierrez@amd.com .name(name() + ".num_refs") 13011308Santhony.gutierrez@amd.com .desc("Number of memory references") 13111308Santhony.gutierrez@amd.com ; 13211308Santhony.gutierrez@amd.com 13311308Santhony.gutierrez@amd.com notIdleFraction 13411308Santhony.gutierrez@amd.com .name(name() + ".not_idle_fraction") 13511308Santhony.gutierrez@amd.com .desc("Percentage of non-idle cycles") 13611308Santhony.gutierrez@amd.com ; 13711308Santhony.gutierrez@amd.com 13811308Santhony.gutierrez@amd.com idleFraction 13911308Santhony.gutierrez@amd.com .name(name() + ".idle_fraction") 14011308Santhony.gutierrez@amd.com .desc("Percentage of idle cycles") 14111308Santhony.gutierrez@amd.com ; 14211308Santhony.gutierrez@amd.com 14311308Santhony.gutierrez@amd.com icacheStallCycles 14411308Santhony.gutierrez@amd.com .name(name() + ".icache_stall_cycles") 14511308Santhony.gutierrez@amd.com .desc("ICache total stall cycles") 14611308Santhony.gutierrez@amd.com .prereq(icacheStallCycles) 14711308Santhony.gutierrez@amd.com ; 14811308Santhony.gutierrez@amd.com 14911308Santhony.gutierrez@amd.com dcacheStallCycles 15011308Santhony.gutierrez@amd.com .name(name() + ".dcache_stall_cycles") 15111308Santhony.gutierrez@amd.com .desc("DCache total stall cycles") 15211308Santhony.gutierrez@amd.com .prereq(dcacheStallCycles) 15311308Santhony.gutierrez@amd.com ; 15411308Santhony.gutierrez@amd.com 15511308Santhony.gutierrez@amd.com icacheRetryCycles 15611308Santhony.gutierrez@amd.com .name(name() + ".icache_retry_cycles") 15711308Santhony.gutierrez@amd.com .desc("ICache total retry cycles") 15811308Santhony.gutierrez@amd.com .prereq(icacheRetryCycles) 15911308Santhony.gutierrez@amd.com ; 16011308Santhony.gutierrez@amd.com 16111308Santhony.gutierrez@amd.com dcacheRetryCycles 16211308Santhony.gutierrez@amd.com .name(name() + ".dcache_retry_cycles") 16311308Santhony.gutierrez@amd.com .desc("DCache total retry cycles") 16411308Santhony.gutierrez@amd.com .prereq(dcacheRetryCycles) 16511308Santhony.gutierrez@amd.com ; 16611308Santhony.gutierrez@amd.com 16711308Santhony.gutierrez@amd.com idleFraction = constant(1.0) - notIdleFraction; 16811308Santhony.gutierrez@amd.com} 16911308Santhony.gutierrez@amd.com 17011308Santhony.gutierrez@amd.comvoid 17111308Santhony.gutierrez@amd.comBaseSimpleCPU::resetStats() 17211308Santhony.gutierrez@amd.com{ 17311308Santhony.gutierrez@amd.com// startNumInst = numInst; 17411308Santhony.gutierrez@amd.com // notIdleFraction = (_status != Idle); 17511308Santhony.gutierrez@amd.com} 17611308Santhony.gutierrez@amd.com 17711308Santhony.gutierrez@amd.comvoid 17811308Santhony.gutierrez@amd.comBaseSimpleCPU::serialize(ostream &os) 17911308Santhony.gutierrez@amd.com{ 18011308Santhony.gutierrez@amd.com BaseCPU::serialize(os); 18111308Santhony.gutierrez@amd.com// SERIALIZE_SCALAR(inst); 18211308Santhony.gutierrez@amd.com nameOut(os, csprintf("%s.xc.0", name())); 18311308Santhony.gutierrez@amd.com thread->serialize(os); 18411308Santhony.gutierrez@amd.com} 18511308Santhony.gutierrez@amd.com 18611308Santhony.gutierrez@amd.comvoid 18711308Santhony.gutierrez@amd.comBaseSimpleCPU::unserialize(Checkpoint *cp, const string §ion) 18811308Santhony.gutierrez@amd.com{ 18911308Santhony.gutierrez@amd.com BaseCPU::unserialize(cp, section); 19011308Santhony.gutierrez@amd.com// UNSERIALIZE_SCALAR(inst); 19111308Santhony.gutierrez@amd.com thread->unserialize(cp, csprintf("%s.xc.0", section)); 19211308Santhony.gutierrez@amd.com} 19311308Santhony.gutierrez@amd.com 19411308Santhony.gutierrez@amd.comvoid 19511308Santhony.gutierrez@amd.comchange_thread_state(int thread_number, int activate, int priority) 19611308Santhony.gutierrez@amd.com{ 19711308Santhony.gutierrez@amd.com} 19811308Santhony.gutierrez@amd.com 19911308Santhony.gutierrez@amd.comFault 20011308Santhony.gutierrez@amd.comBaseSimpleCPU::copySrcTranslate(Addr src) 20111308Santhony.gutierrez@amd.com{ 20211308Santhony.gutierrez@amd.com#if 0 20311308Santhony.gutierrez@amd.com static bool no_warn = true; 20411308Santhony.gutierrez@amd.com int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 20511308Santhony.gutierrez@amd.com // Only support block sizes of 64 atm. 20611308Santhony.gutierrez@amd.com assert(blk_size == 64); 20711308Santhony.gutierrez@amd.com int offset = src & (blk_size - 1); 20811308Santhony.gutierrez@amd.com 20911308Santhony.gutierrez@amd.com // Make sure block doesn't span page 21011308Santhony.gutierrez@amd.com if (no_warn && 21111308Santhony.gutierrez@amd.com (src & PageMask) != ((src + blk_size) & PageMask) && 21211308Santhony.gutierrez@amd.com (src >> 40) != 0xfffffc) { 21311308Santhony.gutierrez@amd.com warn("Copied block source spans pages %x.", src); 21411308Santhony.gutierrez@amd.com no_warn = false; 21511308Santhony.gutierrez@amd.com } 21611308Santhony.gutierrez@amd.com 21711308Santhony.gutierrez@amd.com memReq->reset(src & ~(blk_size - 1), blk_size); 21811308Santhony.gutierrez@amd.com 21911308Santhony.gutierrez@amd.com // translate to physical address 22011308Santhony.gutierrez@amd.com Fault fault = thread->translateDataReadReq(req); 22111308Santhony.gutierrez@amd.com 22211308Santhony.gutierrez@amd.com if (fault == NoFault) { 22311308Santhony.gutierrez@amd.com thread->copySrcAddr = src; 22411308Santhony.gutierrez@amd.com thread->copySrcPhysAddr = memReq->paddr + offset; 22511308Santhony.gutierrez@amd.com } else { 22611308Santhony.gutierrez@amd.com assert(!fault->isAlignmentFault()); 22711308Santhony.gutierrez@amd.com 22811308Santhony.gutierrez@amd.com thread->copySrcAddr = 0; 22911308Santhony.gutierrez@amd.com thread->copySrcPhysAddr = 0; 23011308Santhony.gutierrez@amd.com } 23111308Santhony.gutierrez@amd.com return fault; 23211308Santhony.gutierrez@amd.com#else 23311308Santhony.gutierrez@amd.com return NoFault; 23411308Santhony.gutierrez@amd.com#endif 23511308Santhony.gutierrez@amd.com} 23611308Santhony.gutierrez@amd.com 23711308Santhony.gutierrez@amd.comFault 23811308Santhony.gutierrez@amd.comBaseSimpleCPU::copy(Addr dest) 23911308Santhony.gutierrez@amd.com{ 24011308Santhony.gutierrez@amd.com#if 0 24111308Santhony.gutierrez@amd.com static bool no_warn = true; 24211308Santhony.gutierrez@amd.com int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 24311308Santhony.gutierrez@amd.com // Only support block sizes of 64 atm. 24411308Santhony.gutierrez@amd.com assert(blk_size == 64); 24511308Santhony.gutierrez@amd.com uint8_t data[blk_size]; 24611308Santhony.gutierrez@amd.com //assert(thread->copySrcAddr); 24711308Santhony.gutierrez@amd.com int offset = dest & (blk_size - 1); 24811308Santhony.gutierrez@amd.com 24911308Santhony.gutierrez@amd.com // Make sure block doesn't span page 25011308Santhony.gutierrez@amd.com if (no_warn && 25111308Santhony.gutierrez@amd.com (dest & PageMask) != ((dest + blk_size) & PageMask) && 25211308Santhony.gutierrez@amd.com (dest >> 40) != 0xfffffc) { 25311308Santhony.gutierrez@amd.com no_warn = false; 25411308Santhony.gutierrez@amd.com warn("Copied block destination spans pages %x. ", dest); 25511308Santhony.gutierrez@amd.com } 25611308Santhony.gutierrez@amd.com 25711308Santhony.gutierrez@amd.com memReq->reset(dest & ~(blk_size -1), blk_size); 25811308Santhony.gutierrez@amd.com // translate to physical address 25911308Santhony.gutierrez@amd.com Fault fault = thread->translateDataWriteReq(req); 26011308Santhony.gutierrez@amd.com 26111308Santhony.gutierrez@amd.com if (fault == NoFault) { 26211308Santhony.gutierrez@amd.com Addr dest_addr = memReq->paddr + offset; 26311308Santhony.gutierrez@amd.com // Need to read straight from memory since we have more than 8 bytes. 26411308Santhony.gutierrez@amd.com memReq->paddr = thread->copySrcPhysAddr; 26511308Santhony.gutierrez@amd.com thread->mem->read(memReq, data); 26611308Santhony.gutierrez@amd.com memReq->paddr = dest_addr; 26711308Santhony.gutierrez@amd.com thread->mem->write(memReq, data); 26811308Santhony.gutierrez@amd.com if (dcacheInterface) { 26911308Santhony.gutierrez@amd.com memReq->cmd = Copy; 27011308Santhony.gutierrez@amd.com memReq->completionEvent = NULL; 27111308Santhony.gutierrez@amd.com memReq->paddr = thread->copySrcPhysAddr; 27211308Santhony.gutierrez@amd.com memReq->dest = dest_addr; 27311308Santhony.gutierrez@amd.com memReq->size = 64; 27411308Santhony.gutierrez@amd.com memReq->time = curTick; 27511308Santhony.gutierrez@amd.com memReq->flags &= ~INST_READ; 27611308Santhony.gutierrez@amd.com dcacheInterface->access(memReq); 27711308Santhony.gutierrez@amd.com } 27811308Santhony.gutierrez@amd.com } 27911308Santhony.gutierrez@amd.com else 28011308Santhony.gutierrez@amd.com assert(!fault->isAlignmentFault()); 28111308Santhony.gutierrez@amd.com 28211308Santhony.gutierrez@amd.com return fault; 28311308Santhony.gutierrez@amd.com#else 28411308Santhony.gutierrez@amd.com panic("copy not implemented"); 28511308Santhony.gutierrez@amd.com return NoFault; 28611308Santhony.gutierrez@amd.com#endif 28711308Santhony.gutierrez@amd.com} 28811308Santhony.gutierrez@amd.com 28911308Santhony.gutierrez@amd.com#if FULL_SYSTEM 29011308Santhony.gutierrez@amd.comAddr 29111308Santhony.gutierrez@amd.comBaseSimpleCPU::dbg_vtophys(Addr addr) 29211308Santhony.gutierrez@amd.com{ 29311308Santhony.gutierrez@amd.com return vtophys(tc, addr); 29411308Santhony.gutierrez@amd.com} 29511308Santhony.gutierrez@amd.com#endif // FULL_SYSTEM 29611308Santhony.gutierrez@amd.com 29711308Santhony.gutierrez@amd.com#if FULL_SYSTEM 29811308Santhony.gutierrez@amd.comvoid 29911308Santhony.gutierrez@amd.comBaseSimpleCPU::post_interrupt(int int_num, int index) 30011308Santhony.gutierrez@amd.com{ 30111308Santhony.gutierrez@amd.com BaseCPU::post_interrupt(int_num, index); 30211308Santhony.gutierrez@amd.com 30311308Santhony.gutierrez@amd.com if (thread->status() == ThreadContext::Suspended) { 30411308Santhony.gutierrez@amd.com DPRINTF(IPI,"Suspended Processor awoke\n"); 30511308Santhony.gutierrez@amd.com thread->activate(); 30611308Santhony.gutierrez@amd.com } 30711308Santhony.gutierrez@amd.com} 30811308Santhony.gutierrez@amd.com#endif // FULL_SYSTEM 30911308Santhony.gutierrez@amd.com 31011308Santhony.gutierrez@amd.comvoid 31111308Santhony.gutierrez@amd.comBaseSimpleCPU::checkForInterrupts() 31211308Santhony.gutierrez@amd.com{ 31311308Santhony.gutierrez@amd.com#if FULL_SYSTEM 31411308Santhony.gutierrez@amd.com if (check_interrupts(tc)) { 31511308Santhony.gutierrez@amd.com Fault interrupt = interrupts.getInterrupt(tc); 31611308Santhony.gutierrez@amd.com 31711308Santhony.gutierrez@amd.com if (interrupt != NoFault) { 31811308Santhony.gutierrez@amd.com interrupts.updateIntrInfo(tc); 31911308Santhony.gutierrez@amd.com interrupt->invoke(tc); 32011308Santhony.gutierrez@amd.com } 32111308Santhony.gutierrez@amd.com } 32211308Santhony.gutierrez@amd.com#endif 32311308Santhony.gutierrez@amd.com} 32411308Santhony.gutierrez@amd.com 32511308Santhony.gutierrez@amd.com 32611308Santhony.gutierrez@amd.comFault 32711308Santhony.gutierrez@amd.comBaseSimpleCPU::setupFetchRequest(Request *req) 32811308Santhony.gutierrez@amd.com{ 32911308Santhony.gutierrez@amd.com // set up memory request for instruction fetch 33011308Santhony.gutierrez@amd.com#if ISA_HAS_DELAY_SLOT 33111308Santhony.gutierrez@amd.com DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",thread->readPC(), 33211308Santhony.gutierrez@amd.com thread->readNextPC(),thread->readNextNPC()); 33311308Santhony.gutierrez@amd.com#else 33411308Santhony.gutierrez@amd.com DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p",thread->readPC(), 33511308Santhony.gutierrez@amd.com thread->readNextPC()); 33611308Santhony.gutierrez@amd.com#endif 33711308Santhony.gutierrez@amd.com 33811308Santhony.gutierrez@amd.com req->setVirt(0, thread->readPC() & ~3, sizeof(MachInst), 33911308Santhony.gutierrez@amd.com (FULL_SYSTEM && (thread->readPC() & 1)) ? PHYSICAL : 0, 34011308Santhony.gutierrez@amd.com thread->readPC()); 34111308Santhony.gutierrez@amd.com 34211308Santhony.gutierrez@amd.com Fault fault = thread->translateInstReq(req); 34311308Santhony.gutierrez@amd.com 34411308Santhony.gutierrez@amd.com return fault; 34511308Santhony.gutierrez@amd.com} 34611955Sgabeblack@google.com 34711308Santhony.gutierrez@amd.com 34811308Santhony.gutierrez@amd.comvoid 34911308Santhony.gutierrez@amd.comBaseSimpleCPU::preExecute() 35011308Santhony.gutierrez@amd.com{ 35111308Santhony.gutierrez@amd.com // maintain $r0 semantics 35211308Santhony.gutierrez@amd.com thread->setIntReg(ZeroReg, 0); 35311308Santhony.gutierrez@amd.com#if THE_ISA == ALPHA_ISA 35411308Santhony.gutierrez@amd.com thread->setFloatReg(ZeroReg, 0.0); 35511308Santhony.gutierrez@amd.com#endif // ALPHA_ISA 35611308Santhony.gutierrez@amd.com 35711308Santhony.gutierrez@amd.com // keep an instruction count 35811308Santhony.gutierrez@amd.com numInst++; 35911308Santhony.gutierrez@amd.com numInsts++; 36011308Santhony.gutierrez@amd.com 36111308Santhony.gutierrez@amd.com thread->funcExeInst++; 36211308Santhony.gutierrez@amd.com 36311308Santhony.gutierrez@amd.com // check for instruction-count-based events 36411308Santhony.gutierrez@amd.com comInstEventQueue[0]->serviceEvents(numInst); 36511308Santhony.gutierrez@amd.com 36611308Santhony.gutierrez@amd.com // decode the instruction 36711308Santhony.gutierrez@amd.com inst = gtoh(inst); 36811308Santhony.gutierrez@amd.com //If we're not in the middle of a macro instruction 36911308Santhony.gutierrez@amd.com if (!curMacroStaticInst) { 37011308Santhony.gutierrez@amd.com#if THE_ISA == ALPHA_ISA 37111308Santhony.gutierrez@amd.com StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->readPC())); 37211308Santhony.gutierrez@amd.com#elif THE_ISA == SPARC_ISA 37311308Santhony.gutierrez@amd.com StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC())); 37411308Santhony.gutierrez@amd.com#elif THE_ISA == X86_ISA 37511308Santhony.gutierrez@amd.com StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC())); 37611308Santhony.gutierrez@amd.com#elif THE_ISA == MIPS_ISA 37711308Santhony.gutierrez@amd.com //Mips doesn't do anything in it's MakeExtMI function right now, 37811308Santhony.gutierrez@amd.com //so it won't be called. 37911308Santhony.gutierrez@amd.com StaticInstPtr instPtr = StaticInst::decode(inst); 38011308Santhony.gutierrez@amd.com#endif 38111308Santhony.gutierrez@amd.com if (instPtr->isMacroOp()) { 38211308Santhony.gutierrez@amd.com curMacroStaticInst = instPtr; 38311308Santhony.gutierrez@amd.com curStaticInst = curMacroStaticInst-> 38411308Santhony.gutierrez@amd.com fetchMicroOp(thread->readMicroPC()); 38511308Santhony.gutierrez@amd.com } else { 38611308Santhony.gutierrez@amd.com curStaticInst = instPtr; 38711308Santhony.gutierrez@amd.com } 38811308Santhony.gutierrez@amd.com } else { 38911308Santhony.gutierrez@amd.com //Read the next micro op from the macro op 39011308Santhony.gutierrez@amd.com curStaticInst = curMacroStaticInst-> 39111308Santhony.gutierrez@amd.com fetchMicroOp(thread->readMicroPC()); 39211308Santhony.gutierrez@amd.com } 39311308Santhony.gutierrez@amd.com 39411308Santhony.gutierrez@amd.com 39511308Santhony.gutierrez@amd.com traceData = Trace::getInstRecord(curTick, tc, curStaticInst, 39611308Santhony.gutierrez@amd.com thread->readPC()); 39711308Santhony.gutierrez@amd.com 39811308Santhony.gutierrez@amd.com DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n", 39911308Santhony.gutierrez@amd.com curStaticInst->getName(), curStaticInst->getOpcode(), 40011308Santhony.gutierrez@amd.com curStaticInst->machInst); 40111308Santhony.gutierrez@amd.com 40211308Santhony.gutierrez@amd.com#if FULL_SYSTEM 40311308Santhony.gutierrez@amd.com thread->setInst(inst); 40411308Santhony.gutierrez@amd.com#endif // FULL_SYSTEM 40511308Santhony.gutierrez@amd.com} 40611308Santhony.gutierrez@amd.com 40711308Santhony.gutierrez@amd.comvoid 40811308Santhony.gutierrez@amd.comBaseSimpleCPU::postExecute() 40911308Santhony.gutierrez@amd.com{ 41011308Santhony.gutierrez@amd.com#if FULL_SYSTEM 41111308Santhony.gutierrez@amd.com if (thread->profile) { 41211308Santhony.gutierrez@amd.com bool usermode = TheISA::inUserMode(tc); 41311308Santhony.gutierrez@amd.com thread->profilePC = usermode ? 1 : thread->readPC(); 41411308Santhony.gutierrez@amd.com ProfileNode *node = thread->profile->consume(tc, inst); 41511308Santhony.gutierrez@amd.com if (node) 41611308Santhony.gutierrez@amd.com thread->profileNode = node; 41711308Santhony.gutierrez@amd.com } 41811308Santhony.gutierrez@amd.com#endif 41911308Santhony.gutierrez@amd.com 42011308Santhony.gutierrez@amd.com if (curStaticInst->isMemRef()) { 42111308Santhony.gutierrez@amd.com numMemRefs++; 42211308Santhony.gutierrez@amd.com } 42311308Santhony.gutierrez@amd.com 42411308Santhony.gutierrez@amd.com if (curStaticInst->isLoad()) { 42511308Santhony.gutierrez@amd.com ++numLoad; 42611308Santhony.gutierrez@amd.com comLoadEventQueue[0]->serviceEvents(numLoad); 42711308Santhony.gutierrez@amd.com } 42811308Santhony.gutierrez@amd.com 42911308Santhony.gutierrez@amd.com traceFunctions(thread->readPC()); 43011308Santhony.gutierrez@amd.com 43111308Santhony.gutierrez@amd.com if (traceData) { 43211308Santhony.gutierrez@amd.com traceData->dump(); 43311308Santhony.gutierrez@amd.com delete traceData; 43411308Santhony.gutierrez@amd.com traceData = NULL; 43511308Santhony.gutierrez@amd.com } 43611308Santhony.gutierrez@amd.com} 43711308Santhony.gutierrez@amd.com 43811308Santhony.gutierrez@amd.com 43911308Santhony.gutierrez@amd.comvoid 44011308Santhony.gutierrez@amd.comBaseSimpleCPU::advancePC(Fault fault) 44111308Santhony.gutierrez@amd.com{ 44211308Santhony.gutierrez@amd.com if (fault != NoFault) { 44311308Santhony.gutierrez@amd.com curMacroStaticInst = StaticInst::nullStaticInstPtr; 44411308Santhony.gutierrez@amd.com fault->invoke(tc); 44511308Santhony.gutierrez@amd.com thread->setMicroPC(0); 44611308Santhony.gutierrez@amd.com thread->setNextMicroPC(1); 44711308Santhony.gutierrez@amd.com } else { 44811308Santhony.gutierrez@amd.com //If we're at the last micro op for this instruction 44911308Santhony.gutierrez@amd.com if (curStaticInst->isLastMicroOp()) { 45011308Santhony.gutierrez@amd.com //We should be working with a macro op 45111308Santhony.gutierrez@amd.com assert(curMacroStaticInst); 45211308Santhony.gutierrez@amd.com //Close out this macro op, and clean up the 45311308Santhony.gutierrez@amd.com //microcode state 45411308Santhony.gutierrez@amd.com curMacroStaticInst = StaticInst::nullStaticInstPtr; 45511308Santhony.gutierrez@amd.com thread->setMicroPC(0); 45611308Santhony.gutierrez@amd.com thread->setNextMicroPC(1); 45711308Santhony.gutierrez@amd.com } 45811308Santhony.gutierrez@amd.com //If we're still in a macro op 45911308Santhony.gutierrez@amd.com if (curMacroStaticInst) { 46011308Santhony.gutierrez@amd.com //Advance the micro pc 46111308Santhony.gutierrez@amd.com thread->setMicroPC(thread->readNextMicroPC()); 46211308Santhony.gutierrez@amd.com //Advance the "next" micro pc. Note that there are no delay 46311308Santhony.gutierrez@amd.com //slots, and micro ops are "word" addressed. 46411308Santhony.gutierrez@amd.com thread->setNextMicroPC(thread->readNextMicroPC() + 1); 46511308Santhony.gutierrez@amd.com } else { 46611308Santhony.gutierrez@amd.com // go to the next instruction 46711308Santhony.gutierrez@amd.com thread->setPC(thread->readNextPC()); 46811308Santhony.gutierrez@amd.com#if ISA_HAS_DELAY_SLOT 46911308Santhony.gutierrez@amd.com thread->setNextPC(thread->readNextNPC()); 47011308Santhony.gutierrez@amd.com thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst)); 47111308Santhony.gutierrez@amd.com assert(thread->readNextPC() != thread->readNextNPC()); 47211308Santhony.gutierrez@amd.com#else 47311308Santhony.gutierrez@amd.com thread->setNextPC(thread->readNextPC() + sizeof(MachInst)); 47411308Santhony.gutierrez@amd.com#endif 47511308Santhony.gutierrez@amd.com } 47611308Santhony.gutierrez@amd.com } 47711308Santhony.gutierrez@amd.com 47811308Santhony.gutierrez@amd.com#if FULL_SYSTEM 47911308Santhony.gutierrez@amd.com Addr oldpc; 48011308Santhony.gutierrez@amd.com do { 48111308Santhony.gutierrez@amd.com oldpc = thread->readPC(); 48211308Santhony.gutierrez@amd.com system->pcEventQueue.service(tc); 48311308Santhony.gutierrez@amd.com } while (oldpc != thread->readPC()); 48411308Santhony.gutierrez@amd.com#endif 48511308Santhony.gutierrez@amd.com} 48611308Santhony.gutierrez@amd.com 48711308Santhony.gutierrez@amd.com