diff options
Diffstat (limited to 'src/cpu/simple')
-rw-r--r-- | src/cpu/simple/atomic.cc | 74 | ||||
-rw-r--r-- | src/cpu/simple/atomic.hh | 6 | ||||
-rw-r--r-- | src/cpu/simple/base.cc | 147 | ||||
-rw-r--r-- | src/cpu/simple/base.hh | 77 | ||||
-rw-r--r-- | src/cpu/simple/timing.cc | 64 | ||||
-rw-r--r-- | src/cpu/simple/timing.hh | 6 |
6 files changed, 178 insertions, 196 deletions
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 3cad6e43f..071193f02 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -24,6 +24,8 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Steve Reinhardt */ #include "arch/utility.hh" @@ -68,11 +70,11 @@ AtomicSimpleCPU::init() BaseCPU::init(); #if FULL_SYSTEM - for (int i = 0; i < execContexts.size(); ++i) { - ExecContext *xc = execContexts[i]; + for (int i = 0; i < threadContexts.size(); ++i) { + ThreadContext *tc = threadContexts[i]; // initialize CPU, including PC - TheISA::initCPU(xc, xc->readCpuId()); + TheISA::initCPU(tc, tc->readCpuId()); } #endif } @@ -106,11 +108,10 @@ AtomicSimpleCPU::CpuPort::recvStatusChange(Status status) panic("AtomicSimpleCPU doesn't expect recvStatusChange callback!"); } -Packet * +void AtomicSimpleCPU::CpuPort::recvRetry() { panic("AtomicSimpleCPU doesn't expect recvRetry callback!"); - return NULL; } @@ -121,26 +122,17 @@ AtomicSimpleCPU::AtomicSimpleCPU(Params *p) { _status = Idle; - ifetch_req = new Request(true); - ifetch_req->setAsid(0); - // @todo fix me and get the real cpu iD!!! - ifetch_req->setCpuNum(0); - ifetch_req->setSize(sizeof(MachInst)); + // @todo fix me and get the real cpu id & thread number!!! + ifetch_req = new Request(); ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast); ifetch_pkt->dataStatic(&inst); - data_read_req = new Request(true); - // @todo fix me and get the real cpu iD!!! - data_read_req->setCpuNum(0); - data_read_req->setAsid(0); + data_read_req = new Request(); data_read_pkt = new Packet(data_read_req, Packet::ReadReq, Packet::Broadcast); data_read_pkt->dataStatic(&dataReg); - data_write_req = new Request(true); - // @todo fix me and get the real cpu iD!!! - data_write_req->setCpuNum(0); - data_write_req->setAsid(0); + data_write_req = new Request(); data_write_pkt = new Packet(data_write_req, Packet::WriteReq, Packet::Broadcast); } @@ -187,11 +179,11 @@ AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU) assert(!tickEvent.scheduled()); - // if any of this CPU's ExecContexts are active, mark the CPU as + // if any of this CPU's ThreadContexts are active, mark the CPU as // running and schedule its tick event. - for (int i = 0; i < execContexts.size(); ++i) { - ExecContext *xc = execContexts[i]; - if (xc->status() == ExecContext::Active && _status != Running) { + for (int i = 0; i < threadContexts.size(); ++i) { + ThreadContext *tc = threadContexts[i]; + if (tc->status() == ThreadContext::Active && _status != Running) { _status = Running; tickEvent.schedule(curTick); break; @@ -204,7 +196,7 @@ void AtomicSimpleCPU::activateContext(int thread_num, int delay) { assert(thread_num == 0); - assert(cpuXC); + assert(thread); assert(_status == Idle); assert(!tickEvent.scheduled()); @@ -219,7 +211,7 @@ void AtomicSimpleCPU::suspendContext(int thread_num) { assert(thread_num == 0); - assert(cpuXC); + assert(thread); assert(_status == Running); @@ -237,24 +229,20 @@ template <class T> Fault AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags) { - data_read_req->setVaddr(addr); - data_read_req->setSize(sizeof(T)); - data_read_req->setFlags(flags); - data_read_req->setTime(curTick); + data_read_req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); if (traceData) { traceData->setAddr(addr); } // translate to physical address - Fault fault = cpuXC->translateDataReadReq(data_read_req); + Fault fault = thread->translateDataReadReq(data_read_req); // Now do the access. if (fault == NoFault) { - data_read_pkt->reset(); data_read_pkt->reinitFromRequest(); - dcache_complete = dcachePort.sendAtomic(data_read_pkt); + dcache_latency = dcachePort.sendAtomic(data_read_pkt); dcache_access = true; assert(data_read_pkt->result == Packet::Success); @@ -316,26 +304,22 @@ template <class T> Fault AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) { - data_write_req->setVaddr(addr); - data_write_req->setTime(curTick); - data_write_req->setSize(sizeof(T)); - data_write_req->setFlags(flags); + data_write_req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); if (traceData) { traceData->setAddr(addr); } // translate to physical address - Fault fault = cpuXC->translateDataWriteReq(data_write_req); + Fault fault = thread->translateDataWriteReq(data_write_req); // Now do the access. if (fault == NoFault) { - data_write_pkt->reset(); data = htog(data); - data_write_pkt->dataStatic(&data); data_write_pkt->reinitFromRequest(); + data_write_pkt->dataStatic(&data); - dcache_complete = dcachePort.sendAtomic(data_write_pkt); + dcache_latency = dcachePort.sendAtomic(data_write_pkt); dcache_access = true; assert(data_write_pkt->result == Packet::Success); @@ -411,12 +395,12 @@ AtomicSimpleCPU::tick() checkForInterrupts(); - ifetch_req->resetMin(); - ifetch_pkt->reset(); - Fault fault = setupFetchPacket(ifetch_pkt); + Fault fault = setupFetchRequest(ifetch_req); if (fault == NoFault) { - Tick icache_complete = icachePort.sendAtomic(ifetch_pkt); + ifetch_pkt->reinitFromRequest(); + + Tick icache_latency = icachePort.sendAtomic(ifetch_pkt); // ifetch_req is initialized to read the instruction directly // into the CPU object's inst field. @@ -431,9 +415,9 @@ AtomicSimpleCPU::tick() // cycle time. If not, the next tick event may get // scheduled at a non-integer multiple of the CPU // cycle time. - Tick icache_stall = icache_complete - curTick - cycles(1); + Tick icache_stall = icache_latency - cycles(1); Tick dcache_stall = - dcache_access ? dcache_complete - curTick - cycles(1) : 0; + dcache_access ? dcache_latency - cycles(1) : 0; latency += icache_stall + dcache_stall; } diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh index ab3a3e8ef..7f4956da9 100644 --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -24,6 +24,8 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Steve Reinhardt */ #ifndef __CPU_SIMPLE_ATOMIC_HH__ @@ -98,7 +100,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU virtual void recvStatusChange(Status status); - virtual Packet *recvRetry(); + virtual void recvRetry(); virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) @@ -116,7 +118,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU Packet *data_write_pkt; bool dcache_access; - Tick dcache_complete; + Tick dcache_latency; public: diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 18f170449..d94b0e079 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -24,6 +24,8 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Steve Reinhardt */ #include "arch/utility.hh" @@ -36,18 +38,18 @@ #include "base/stats/events.hh" #include "base/trace.hh" #include "cpu/base.hh" -#include "cpu/cpu_exec_context.hh" -#include "cpu/exec_context.hh" #include "cpu/exetrace.hh" #include "cpu/profile.hh" #include "cpu/sampler/sampler.hh" #include "cpu/simple/base.hh" +#include "cpu/simple_thread.hh" #include "cpu/smt.hh" #include "cpu/static_inst.hh" +#include "cpu/thread_context.hh" #include "kern/kernel_stats.hh" #include "mem/packet_impl.hh" -#include "sim/byteswap.hh" #include "sim/builder.hh" +#include "sim/byteswap.hh" #include "sim/debug.hh" #include "sim/host.hh" #include "sim/sim_events.hh" @@ -68,16 +70,18 @@ using namespace std; using namespace TheISA; BaseSimpleCPU::BaseSimpleCPU(Params *p) - : BaseCPU(p), mem(p->mem), cpuXC(NULL) + : BaseCPU(p), mem(p->mem), thread(NULL) { #if FULL_SYSTEM - cpuXC = new CPUExecContext(this, 0, p->system, p->itb, p->dtb); + thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb); #else - cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process, + thread = new SimpleThread(this, /* thread_num */ 0, p->process, /* asid */ 0, mem); #endif // !FULL_SYSTEM - xcProxy = cpuXC->getProxy(); + thread->setStatus(ThreadContext::Suspended); + + tc = thread->getTC(); numInst = 0; startNumInst = 0; @@ -86,7 +90,7 @@ BaseSimpleCPU::BaseSimpleCPU(Params *p) lastIcacheStall = 0; lastDcacheStall = 0; - execContexts.push_back(xcProxy); + threadContexts.push_back(tc); } BaseSimpleCPU::~BaseSimpleCPU() @@ -176,7 +180,7 @@ BaseSimpleCPU::serialize(ostream &os) BaseCPU::serialize(os); SERIALIZE_SCALAR(inst); nameOut(os, csprintf("%s.xc", name())); - cpuXC->serialize(os); + thread->serialize(os); } void @@ -184,7 +188,7 @@ BaseSimpleCPU::unserialize(Checkpoint *cp, const string §ion) { BaseCPU::unserialize(cp, section); UNSERIALIZE_SCALAR(inst); - cpuXC->unserialize(cp, csprintf("%s.xc", section)); + thread->unserialize(cp, csprintf("%s.xc", section)); } void @@ -213,16 +217,16 @@ BaseSimpleCPU::copySrcTranslate(Addr src) memReq->reset(src & ~(blk_size - 1), blk_size); // translate to physical address - Fault fault = cpuXC->translateDataReadReq(req); + Fault fault = thread->translateDataReadReq(req); if (fault == NoFault) { - cpuXC->copySrcAddr = src; - cpuXC->copySrcPhysAddr = memReq->paddr + offset; + thread->copySrcAddr = src; + thread->copySrcPhysAddr = memReq->paddr + offset; } else { assert(!fault->isAlignmentFault()); - cpuXC->copySrcAddr = 0; - cpuXC->copySrcPhysAddr = 0; + thread->copySrcAddr = 0; + thread->copySrcPhysAddr = 0; } return fault; #else @@ -239,7 +243,7 @@ BaseSimpleCPU::copy(Addr dest) // Only support block sizes of 64 atm. assert(blk_size == 64); uint8_t data[blk_size]; - //assert(cpuXC->copySrcAddr); + //assert(thread->copySrcAddr); int offset = dest & (blk_size - 1); // Make sure block doesn't span page @@ -252,19 +256,19 @@ BaseSimpleCPU::copy(Addr dest) memReq->reset(dest & ~(blk_size -1), blk_size); // translate to physical address - Fault fault = cpuXC->translateDataWriteReq(req); + Fault fault = thread->translateDataWriteReq(req); if (fault == NoFault) { Addr dest_addr = memReq->paddr + offset; // Need to read straight from memory since we have more than 8 bytes. - memReq->paddr = cpuXC->copySrcPhysAddr; - cpuXC->mem->read(memReq, data); + memReq->paddr = thread->copySrcPhysAddr; + thread->mem->read(memReq, data); memReq->paddr = dest_addr; - cpuXC->mem->write(memReq, data); + thread->mem->write(memReq, data); if (dcacheInterface) { memReq->cmd = Copy; memReq->completionEvent = NULL; - memReq->paddr = cpuXC->copySrcPhysAddr; + memReq->paddr = thread->copySrcPhysAddr; memReq->dest = dest_addr; memReq->size = 64; memReq->time = curTick; @@ -286,7 +290,7 @@ BaseSimpleCPU::copy(Addr dest) Addr BaseSimpleCPU::dbg_vtophys(Addr addr) { - return vtophys(xcProxy, addr); + return vtophys(tc, addr); } #endif // FULL_SYSTEM @@ -296,9 +300,9 @@ BaseSimpleCPU::post_interrupt(int int_num, int index) { BaseCPU::post_interrupt(int_num, index); - if (cpuXC->status() == ExecContext::Suspended) { + if (thread->status() == ThreadContext::Suspended) { DPRINTF(IPI,"Suspended Processor awoke\n"); - cpuXC->activate(); + thread->activate(); } } #endif // FULL_SYSTEM @@ -307,15 +311,15 @@ void BaseSimpleCPU::checkForInterrupts() { #if FULL_SYSTEM - if (checkInterrupts && check_interrupts() && !cpuXC->inPalMode()) { + if (checkInterrupts && check_interrupts() && !thread->inPalMode()) { int ipl = 0; int summary = 0; checkInterrupts = false; - if (cpuXC->readMiscReg(IPR_SIRR)) { + if (thread->readMiscReg(IPR_SIRR)) { for (int i = INTLEVEL_SOFTWARE_MIN; i < INTLEVEL_SOFTWARE_MAX; i++) { - if (cpuXC->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { + if (thread->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { // See table 4-19 of 21164 hardware reference ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; summary |= (ULL(1) << i); @@ -323,7 +327,7 @@ BaseSimpleCPU::checkForInterrupts() } } - uint64_t interrupts = cpuXC->cpu->intr_status(); + uint64_t interrupts = thread->cpu->intr_status(); for (int i = INTLEVEL_EXTERNAL_MIN; i < INTLEVEL_EXTERNAL_MAX; i++) { if (interrupts & (ULL(1) << i)) { @@ -333,17 +337,17 @@ BaseSimpleCPU::checkForInterrupts() } } - if (cpuXC->readMiscReg(IPR_ASTRR)) + if (thread->readMiscReg(IPR_ASTRR)) panic("asynchronous traps not implemented\n"); - if (ipl && ipl > cpuXC->readMiscReg(IPR_IPLR)) { - cpuXC->setMiscReg(IPR_ISR, summary); - cpuXC->setMiscReg(IPR_INTID, ipl); + if (ipl && ipl > thread->readMiscReg(IPR_IPLR)) { + thread->setMiscReg(IPR_ISR, summary); + thread->setMiscReg(IPR_INTID, ipl); - Fault(new InterruptFault)->invoke(xcProxy); + Fault(new InterruptFault)->invoke(tc); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - cpuXC->readMiscReg(IPR_IPLR), ipl, summary); + thread->readMiscReg(IPR_IPLR), ipl, summary); } } #endif @@ -351,29 +355,17 @@ BaseSimpleCPU::checkForInterrupts() Fault -BaseSimpleCPU::setupFetchPacket(Packet *ifetch_pkt) +BaseSimpleCPU::setupFetchRequest(Request *req) { - // Try to fetch an instruction - // set up memory request for instruction fetch + DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",thread->readPC(), + thread->readNextPC(),thread->readNextNPC()); - DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",cpuXC->readPC(), - cpuXC->readNextPC(),cpuXC->readNextNPC()); - - Request *ifetch_req = ifetch_pkt->req; - ifetch_req->setVaddr(cpuXC->readPC() & ~3); - ifetch_req->setTime(curTick); -#if FULL_SYSTEM - ifetch_req->setFlags((cpuXC->readPC() & 1) ? PHYSICAL : 0); -#else - ifetch_req->setFlags(0); -#endif - - Fault fault = cpuXC->translateInstReq(ifetch_req); + req->setVirt(0, thread->readPC() & ~3, sizeof(MachInst), + (FULL_SYSTEM && (thread->readPC() & 1)) ? PHYSICAL : 0, + thread->readPC()); - if (fault == NoFault) { - ifetch_pkt->reinitFromRequest(); - } + Fault fault = thread->translateInstReq(req); return fault; } @@ -383,33 +375,33 @@ void BaseSimpleCPU::preExecute() { // maintain $r0 semantics - cpuXC->setIntReg(ZeroReg, 0); + thread->setIntReg(ZeroReg, 0); #if THE_ISA == ALPHA_ISA - cpuXC->setFloatReg(ZeroReg, 0.0); + thread->setFloatReg(ZeroReg, 0.0); #endif // ALPHA_ISA // keep an instruction count numInst++; numInsts++; - cpuXC->func_exe_inst++; + thread->funcExeInst++; // check for instruction-count-based events comInstEventQueue[0]->serviceEvents(numInst); // decode the instruction inst = gtoh(inst); - curStaticInst = StaticInst::decode(makeExtMI(inst, cpuXC->readPC())); + curStaticInst = StaticInst::decode(makeExtMI(inst, thread->readPC())); - traceData = Trace::getInstRecord(curTick, xcProxy, this, curStaticInst, - cpuXC->readPC()); + traceData = Trace::getInstRecord(curTick, tc, this, curStaticInst, + thread->readPC()); DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n", curStaticInst->getName(), curStaticInst->getOpcode(), curStaticInst->machInst); #if FULL_SYSTEM - cpuXC->setInst(inst); + thread->setInst(inst); #endif // FULL_SYSTEM } @@ -417,18 +409,13 @@ void BaseSimpleCPU::postExecute() { #if FULL_SYSTEM - if (system->kernelBinning->fnbin) { - assert(kernelStats); - system->kernelBinning->execute(xcProxy, inst); - } - - if (cpuXC->profile) { + if (thread->profile) { bool usermode = - (cpuXC->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; - cpuXC->profilePC = usermode ? 1 : cpuXC->readPC(); - ProfileNode *node = cpuXC->profile->consume(xcProxy, inst); + (thread->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; + thread->profilePC = usermode ? 1 : thread->readPC(); + ProfileNode *node = thread->profile->consume(tc, inst); if (node) - cpuXC->profileNode = node; + thread->profileNode = node; } #endif @@ -441,7 +428,7 @@ BaseSimpleCPU::postExecute() comLoadEventQueue[0]->serviceEvents(numLoad); } - traceFunctions(cpuXC->readPC()); + traceFunctions(thread->readPC()); if (traceData) { traceData->finalize(); @@ -454,19 +441,19 @@ BaseSimpleCPU::advancePC(Fault fault) { if (fault != NoFault) { #if FULL_SYSTEM - fault->invoke(xcProxy); + fault->invoke(tc); #else // !FULL_SYSTEM - fatal("fault (%s) detected @ PC %08p", fault->name(), cpuXC->readPC()); + fatal("fault (%s) detected @ PC %08p", fault->name(), thread->readPC()); #endif // FULL_SYSTEM } else { // go to the next instruction - cpuXC->setPC(cpuXC->readNextPC()); + thread->setPC(thread->readNextPC()); #if THE_ISA == ALPHA_ISA - cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst)); + thread->setNextPC(thread->readNextPC() + sizeof(MachInst)); #else - cpuXC->setNextPC(cpuXC->readNextNPC()); - cpuXC->setNextNPC(cpuXC->readNextNPC() + sizeof(MachInst)); + thread->setNextPC(thread->readNextNPC()); + thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst)); #endif } @@ -474,9 +461,9 @@ BaseSimpleCPU::advancePC(Fault fault) #if FULL_SYSTEM Addr oldpc; do { - oldpc = cpuXC->readPC(); - system->pcEventQueue.service(xcProxy); - } while (oldpc != cpuXC->readPC()); + oldpc = thread->readPC(); + system->pcEventQueue.service(tc); + } while (oldpc != thread->readPC()); #endif } diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 4c0e6f3c7..39bc86050 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -24,6 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Steve Reinhardt + * Dave Greene + * Nathan Binkert */ #ifndef __CPU_SIMPLE_BASE_HH__ @@ -32,7 +36,7 @@ #include "base/statistics.hh" #include "config/full_system.hh" #include "cpu/base.hh" -#include "cpu/cpu_exec_context.hh" +#include "cpu/simple_thread.hh" #include "cpu/pc_event.hh" #include "cpu/sampler/sampler.hh" #include "cpu/static_inst.hh" @@ -57,7 +61,7 @@ class Process; #endif // FULL_SYSTEM -class ExecContext; +class ThreadContext; class Checkpoint; namespace Trace { @@ -104,10 +108,13 @@ class BaseSimpleCPU : public BaseCPU virtual ~BaseSimpleCPU(); public: - // execution context - CPUExecContext *cpuXC; + /** SimpleThread object, provides all the architectural state. */ + SimpleThread *thread; - ExecContext *xcProxy; + /** ThreadContext object, provides an interface for external + * objects to modify this thread's state. + */ + ThreadContext *tc; #if FULL_SYSTEM Addr dbg_vtophys(Addr addr); @@ -129,7 +136,7 @@ class BaseSimpleCPU : public BaseCPU StaticInstPtr curStaticInst; void checkForInterrupts(); - Fault setupFetchPacket(Packet *ifetch_pkt); + Fault setupFetchRequest(Request *req); void preExecute(); void postExecute(); void advancePC(Fault fault); @@ -213,104 +220,104 @@ class BaseSimpleCPU : public BaseCPU uint64_t readIntReg(const StaticInst *si, int idx) { - return cpuXC->readIntReg(si->srcRegIdx(idx)); + return thread->readIntReg(si->srcRegIdx(idx)); } FloatReg readFloatReg(const StaticInst *si, int idx, int width) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return cpuXC->readFloatReg(reg_idx, width); + return thread->readFloatReg(reg_idx, width); } FloatReg readFloatReg(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return cpuXC->readFloatReg(reg_idx); + return thread->readFloatReg(reg_idx); } FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return cpuXC->readFloatRegBits(reg_idx, width); + return thread->readFloatRegBits(reg_idx, width); } FloatRegBits readFloatRegBits(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return cpuXC->readFloatRegBits(reg_idx); + return thread->readFloatRegBits(reg_idx); } void setIntReg(const StaticInst *si, int idx, uint64_t val) { - cpuXC->setIntReg(si->destRegIdx(idx), val); + thread->setIntReg(si->destRegIdx(idx), val); } void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - cpuXC->setFloatReg(reg_idx, val, width); + thread->setFloatReg(reg_idx, val, width); } void setFloatReg(const StaticInst *si, int idx, FloatReg val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - cpuXC->setFloatReg(reg_idx, val); + thread->setFloatReg(reg_idx, val); } void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val, int width) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - cpuXC->setFloatRegBits(reg_idx, val, width); + thread->setFloatRegBits(reg_idx, val, width); } void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - cpuXC->setFloatRegBits(reg_idx, val); + thread->setFloatRegBits(reg_idx, val); } - uint64_t readPC() { return cpuXC->readPC(); } - uint64_t readNextPC() { return cpuXC->readNextPC(); } - uint64_t readNextNPC() { return cpuXC->readNextNPC(); } + uint64_t readPC() { return thread->readPC(); } + uint64_t readNextPC() { return thread->readNextPC(); } + uint64_t readNextNPC() { return thread->readNextNPC(); } - void setPC(uint64_t val) { cpuXC->setPC(val); } - void setNextPC(uint64_t val) { cpuXC->setNextPC(val); } - void setNextNPC(uint64_t val) { cpuXC->setNextNPC(val); } + void setPC(uint64_t val) { thread->setPC(val); } + void setNextPC(uint64_t val) { thread->setNextPC(val); } + void setNextNPC(uint64_t val) { thread->setNextNPC(val); } MiscReg readMiscReg(int misc_reg) { - return cpuXC->readMiscReg(misc_reg); + return thread->readMiscReg(misc_reg); } MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) { - return cpuXC->readMiscRegWithEffect(misc_reg, fault); + return thread->readMiscRegWithEffect(misc_reg, fault); } Fault setMiscReg(int misc_reg, const MiscReg &val) { - return cpuXC->setMiscReg(misc_reg, val); + return thread->setMiscReg(misc_reg, val); } Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) { - return cpuXC->setMiscRegWithEffect(misc_reg, val); + return thread->setMiscRegWithEffect(misc_reg, val); } #if FULL_SYSTEM - Fault hwrei() { return cpuXC->hwrei(); } - int readIntrFlag() { return cpuXC->readIntrFlag(); } - void setIntrFlag(int val) { cpuXC->setIntrFlag(val); } - bool inPalMode() { return cpuXC->inPalMode(); } - void ev5_trap(Fault fault) { fault->invoke(xcProxy); } - bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); } + Fault hwrei() { return thread->hwrei(); } + int readIntrFlag() { return thread->readIntrFlag(); } + void setIntrFlag(int val) { thread->setIntrFlag(val); } + bool inPalMode() { return thread->inPalMode(); } + void ev5_trap(Fault fault) { fault->invoke(tc); } + bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } #else - void syscall(int64_t callnum) { cpuXC->syscall(callnum); } + void syscall(int64_t callnum) { thread->syscall(callnum); } #endif - bool misspeculating() { return cpuXC->misspeculating(); } - ExecContext *xcBase() { return xcProxy; } + bool misspeculating() { return thread->misspeculating(); } + ThreadContext *tcBase() { return tc; } }; #endif // __CPU_SIMPLE_BASE_HH__ diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 7cdcdafa1..c99db8fbf 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -24,6 +24,8 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Steve Reinhardt */ #include "arch/utility.hh" @@ -50,11 +52,11 @@ TimingSimpleCPU::init() BaseCPU::init(); #if FULL_SYSTEM - for (int i = 0; i < execContexts.size(); ++i) { - ExecContext *xc = execContexts[i]; + for (int i = 0; i < threadContexts.size(); ++i) { + ThreadContext *tc = threadContexts[i]; // initialize CPU, including PC - TheISA::initCPU(xc, xc->readCpuId()); + TheISA::initCPU(tc, tc->readCpuId()); } #endif } @@ -123,11 +125,11 @@ TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU) { BaseCPU::takeOverFrom(oldCPU); - // if any of this CPU's ExecContexts are active, mark the CPU as + // if any of this CPU's ThreadContexts are active, mark the CPU as // running and schedule its tick event. - for (int i = 0; i < execContexts.size(); ++i) { - ExecContext *xc = execContexts[i]; - if (xc->status() == ExecContext::Active && _status != Running) { + for (int i = 0; i < threadContexts.size(); ++i) { + ThreadContext *tc = threadContexts[i]; + if (tc->status() == ThreadContext::Active && _status != Running) { _status = Running; break; } @@ -139,7 +141,7 @@ void TimingSimpleCPU::activateContext(int thread_num, int delay) { assert(thread_num == 0); - assert(cpuXC); + assert(thread); assert(_status == Idle); @@ -156,7 +158,7 @@ void TimingSimpleCPU::suspendContext(int thread_num) { assert(thread_num == 0); - assert(cpuXC); + assert(thread); assert(_status == Running); @@ -172,19 +174,17 @@ template <class T> Fault TimingSimpleCPU::read(Addr addr, T &data, unsigned flags) { - Request *data_read_req = new Request(true); + // need to fill in CPU & thread IDs here + Request *data_read_req = new Request(); - data_read_req->setVaddr(addr); - data_read_req->setSize(sizeof(T)); - data_read_req->setFlags(flags); - data_read_req->setTime(curTick); + data_read_req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); if (traceData) { traceData->setAddr(data_read_req->getVaddr()); } // translate to physical address - Fault fault = cpuXC->translateDataReadReq(data_read_req); + Fault fault = thread->translateDataReadReq(data_read_req); // Now do the access. if (fault == NoFault) { @@ -255,14 +255,12 @@ template <class T> Fault TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) { - Request *data_write_req = new Request(true); - data_write_req->setVaddr(addr); - data_write_req->setTime(curTick); - data_write_req->setSize(sizeof(T)); - data_write_req->setFlags(flags); + // need to fill in CPU & thread IDs here + Request *data_write_req = new Request(); + data_write_req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); // translate to physical address - Fault fault = cpuXC->translateDataWriteReq(data_write_req); + Fault fault = thread->translateDataWriteReq(data_write_req); // Now do the access. if (fault == NoFault) { Packet *data_write_pkt = @@ -340,13 +338,13 @@ TimingSimpleCPU::fetch() { checkForInterrupts(); - Request *ifetch_req = new Request(true); - ifetch_req->setSize(sizeof(MachInst)); + // need to fill in CPU & thread IDs here + Request *ifetch_req = new Request(); + Fault fault = setupFetchRequest(ifetch_req); ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast); ifetch_pkt->dataStatic(&inst); - Fault fault = setupFetchPacket(ifetch_pkt); if (fault == NoFault) { if (!icachePort.sendTiming(ifetch_pkt)) { // Need to wait for retry @@ -419,17 +417,18 @@ TimingSimpleCPU::IcachePort::recvTiming(Packet *pkt) return true; } -Packet * +void TimingSimpleCPU::IcachePort::recvRetry() { // we shouldn't get a retry unless we have a packet that we're // waiting to transmit assert(cpu->ifetch_pkt != NULL); assert(cpu->_status == IcacheRetry); - cpu->_status = IcacheWaitResponse; Packet *tmp = cpu->ifetch_pkt; - cpu->ifetch_pkt = NULL; - return tmp; + if (sendTiming(tmp)) { + cpu->_status = IcacheWaitResponse; + cpu->ifetch_pkt = NULL; + } } void @@ -459,17 +458,18 @@ TimingSimpleCPU::DcachePort::recvTiming(Packet *pkt) return true; } -Packet * +void TimingSimpleCPU::DcachePort::recvRetry() { // we shouldn't get a retry unless we have a packet that we're // waiting to transmit assert(cpu->dcache_pkt != NULL); assert(cpu->_status == DcacheRetry); - cpu->_status = DcacheWaitResponse; Packet *tmp = cpu->dcache_pkt; - cpu->dcache_pkt = NULL; - return tmp; + if (sendTiming(tmp)) { + cpu->_status = DcacheWaitResponse; + cpu->dcache_pkt = NULL; + } } diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh index b46631d5a..ab0b2d2ca 100644 --- a/src/cpu/simple/timing.hh +++ b/src/cpu/simple/timing.hh @@ -24,6 +24,8 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Steve Reinhardt */ #ifndef __CPU_SIMPLE_TIMING_HH__ @@ -100,7 +102,7 @@ class TimingSimpleCPU : public BaseSimpleCPU virtual bool recvTiming(Packet *pkt); - virtual Packet *recvRetry(); + virtual void recvRetry(); }; class DcachePort : public CpuPort @@ -115,7 +117,7 @@ class TimingSimpleCPU : public BaseSimpleCPU virtual bool recvTiming(Packet *pkt); - virtual Packet *recvRetry(); + virtual void recvRetry(); }; IcachePort icachePort; |