Move kernel stats out of CPU and into XC.

arch/alpha/ev5.cc:
    Move kernel stats out of CPU and into XC.  Also be sure to check if the kernel stats exist prior to using them.

--HG--
extra : convert_revision : 565cd7026410fd7d8586f953d9b328c2e67a9473
This commit is contained in:
Kevin Lim
2006-05-23 16:51:16 -04:00
parent e3d5588ca7
commit ff3d16ca1f
15 changed files with 221 additions and 276 deletions

View File

@@ -146,7 +146,7 @@ CPUExecContext::hwrei()
setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR));
if (!misspeculating()) {
cpu->kernelStats->hwrei();
kernelStats->hwrei();
cpu->checkInterrupts = true;
}
@@ -336,7 +336,8 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
// write entire quad w/ no side-effect
old = ipr[idx];
ipr[idx] = val;
xc->getCpuPtr()->kernelStats->context(old, val, xc);
if (xc->getKernelStats())
xc->getKernelStats()->context(old, val, xc);
break;
case AlphaISA::IPR_DTB_PTE:
@@ -363,14 +364,19 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
// only write least significant five bits - interrupt level
ipr[idx] = val & 0x1f;
xc->getCpuPtr()->kernelStats->swpipl(ipr[idx]);
if (xc->getKernelStats())
xc->getKernelStats()->swpipl(ipr[idx]);
break;
case AlphaISA::IPR_DTB_CM:
if (val & 0x18)
xc->getCpuPtr()->kernelStats->mode(Kernel::user, xc);
else
xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc);
if (val & 0x18) {
if (xc->getKernelStats())
xc->getKernelStats()->mode(Kernel::user, xc);
else {
if (xc->getKernelStats())
xc->getKernelStats()->mode(Kernel::kernel, xc);
}
}
case AlphaISA::IPR_ICM:
// only write two mode bits - processor mode
@@ -556,7 +562,7 @@ AlphaISA::MiscRegFile::copyIprs(ExecContext *xc)
bool
CPUExecContext::simPalCheck(int palFunc)
{
cpu->kernelStats->callpal(palFunc, proxy);
kernelStats->callpal(palFunc, proxy);
switch (palFunc) {
case PAL::halt:

View File

@@ -45,10 +45,6 @@
#include "base/trace.hh"
#if FULL_SYSTEM
#include "kern/kernel_stats.hh"
#endif
using namespace std;
vector<BaseCPU *> BaseCPU::cpuList;
@@ -153,8 +149,6 @@ BaseCPU::BaseCPU(Params *p)
profileEvent = NULL;
if (params->profile)
profileEvent = new ProfileEvent(this, params->profile);
kernelStats = new Kernel::Statistics(system);
#endif
}
@@ -175,10 +169,6 @@ BaseCPU::enableFunctionTrace()
BaseCPU::~BaseCPU()
{
#if FULL_SYSTEM
if (kernelStats)
delete kernelStats;
#endif
}
void
@@ -219,8 +209,6 @@ BaseCPU::regStats()
execContexts[0]->regStats(name());
#if FULL_SYSTEM
if (kernelStats)
kernelStats->regStats(name() + ".kern");
#endif
}
@@ -348,12 +336,6 @@ BaseCPU::serialize(std::ostream &os)
{
SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
SERIALIZE_SCALAR(intstatus);
#if FULL_SYSTEM
if (kernelStats)
kernelStats->serialize(os);
#endif
}
void
@@ -361,11 +343,6 @@ BaseCPU::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
UNSERIALIZE_SCALAR(intstatus);
#if FULL_SYSTEM
if (kernelStats)
kernelStats->unserialize(cp, section);
#endif
}
#endif // FULL_SYSTEM

View File

@@ -38,14 +38,10 @@
#include "sim/sim_object.hh"
#include "arch/isa_traits.hh"
#if FULL_SYSTEM
class System;
namespace Kernel { class Statistics; }
#endif
class BranchPred;
class CheckerCPU;
class ExecContext;
class System;
class BaseCPU : public SimObject
{
@@ -237,10 +233,6 @@ class BaseCPU : public SimObject
public:
// Number of CPU cycles simulated
Stats::Scalar<> numCycles;
#if FULL_SYSTEM
Kernel::Statistics *kernelStats;
#endif
};
#endif // __CPU_BASE_HH__

View File

@@ -1,3 +1,31 @@
/*
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* 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.
*/
#ifndef __CPU_CHECKER_EXEC_CONTEXT_HH__
#define __CPU_CHECKER_EXEC_CONTEXT_HH__
@@ -6,6 +34,9 @@
#include "cpu/exec_context.hh"
class EndQuiesceEvent;
namespace Kernel {
class Statistics;
};
template <class XC>
class CheckerExecContext : public ExecContext
@@ -13,7 +44,8 @@ class CheckerExecContext : public ExecContext
public:
CheckerExecContext(XC *actual_xc,
CheckerCPU *checker_cpu)
: actualXC(actual_xc), checkerXC(checker_cpu->cpuXC), checkerCPU(checker_cpu)
: actualXC(actual_xc), checkerXC(checker_cpu->cpuXC),
checkerCPU(checker_cpu)
{ }
private:
@@ -43,6 +75,8 @@ class CheckerExecContext : public ExecContext
AlphaITB *getITBPtr() { return actualXC->getITBPtr(); }
AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); }
Kernel::Statistics *getKernelStats() { return actualXC->getKernelStats(); }
#else
Process *getProcessPtr() { return actualXC->getProcessPtr(); }
#endif
@@ -50,8 +84,10 @@ class CheckerExecContext : public ExecContext
Status status() const { return actualXC->status(); }
void setStatus(Status new_status)
{ actualXC->setStatus(new_status);
checkerXC->setStatus(new_status); }
{
actualXC->setStatus(new_status);
checkerXC->setStatus(new_status);
}
/// Set the status to Active. Optional delay indicates number of
/// cycles to wait before beginning execution.
@@ -216,8 +252,6 @@ class CheckerExecContext : public ExecContext
actualXC->setSyscallReturn(return_value);
}
// void syscall() { actualXC->syscall(); }
Counter readFuncExeInst() { return actualXC->readFuncExeInst(); }
#endif
};

View File

@@ -188,7 +188,8 @@ CPUExecContext::serialize(ostream &os)
if (quiesceEvent->scheduled())
quiesceEndTick = quiesceEvent->when();
SERIALIZE_SCALAR(quiesceEndTick);
if (kernelStats)
kernelStats->serialize(os);
#endif
}
@@ -207,6 +208,8 @@ CPUExecContext::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(quiesceEndTick);
if (quiesceEndTick)
quiesceEvent->schedule(quiesceEndTick);
if (kernelStats)
kernelStats->unserialize(cp, section);
#endif
}
@@ -275,6 +278,10 @@ CPUExecContext::halt()
void
CPUExecContext::regStats(const string &name)
{
#if FULL_SYSTEM
kernelStats = new Kernel::Statistics(system);
kernelStats->regStats(name + ".kern");
#endif
}
void

View File

@@ -53,6 +53,10 @@ class FunctionProfile;
class ProfileNode;
class MemoryController;
namespace Kernel {
class Statistics;
};
#else // !FULL_SYSTEM
#include "sim/process.hh"
@@ -147,6 +151,9 @@ class CPUExecContext
void profileSample();
Kernel::Statistics *getKernelStats() { return kernelStats; }
Kernel::Statistics *kernelStats;
#else
Process *process;

View File

@@ -48,6 +48,9 @@ class FunctionalMemory;
class PhysicalMemory;
class Process;
class System;
namespace Kernel {
class Statistics;
};
class ExecContext
{
@@ -98,6 +101,8 @@ class ExecContext
virtual AlphaITB *getITBPtr() = 0;
virtual AlphaDTB * getDTBPtr() = 0;
virtual Kernel::Statistics *getKernelStats() = 0;
#else
virtual Process *getProcessPtr() = 0;
#endif
@@ -243,6 +248,8 @@ class ProxyExecContext : public ExecContext
AlphaITB *getITBPtr() { return actualXC->getITBPtr(); }
AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); }
Kernel::Statistics *getKernelStats() { return actualXC->getKernelStats(); }
#else
Process *getProcessPtr() { return actualXC->getProcessPtr(); }
#endif

View File

@@ -35,6 +35,9 @@
#include "sim/byteswap.hh"
class EndQuiesceEvent;
namespace Kernel {
class Statistics;
};
template <class Impl>
class AlphaFullCPU : public FullO3CPU<Impl>
@@ -60,11 +63,6 @@ class AlphaFullCPU : public FullO3CPU<Impl>
O3ThreadState<Impl> *thread;
Tick lastActivate;
Tick lastSuspend;
EndQuiesceEvent *quiesceEvent;
virtual BaseCPU *getCpuPtr() { return cpu; }
virtual void setCpuId(int id) { cpu->cpu_id = id; }
@@ -81,6 +79,9 @@ class AlphaFullCPU : public FullO3CPU<Impl>
virtual AlphaITB *getITBPtr() { return cpu->itb; }
virtual AlphaDTB * getDTBPtr() { return cpu->dtb; }
virtual Kernel::Statistics *getKernelStats()
{ return thread->kernelStats; }
#else
virtual Process *getProcessPtr() { return thread->process; }
#endif

View File

@@ -31,7 +31,6 @@
#include "base/statistics.hh"
#include "base/timebuf.hh"
#include "cpu/checker/exec_context.hh"
#include "cpu/quiesce_event.hh"
#include "mem/mem_interface.hh"
#include "sim/sim_events.hh"
#include "sim/stats.hh"
@@ -44,6 +43,8 @@
#if FULL_SYSTEM
#include "arch/alpha/osfpal.hh"
#include "arch/isa_traits.hh"
#include "cpu/quiesce_event.hh"
#include "kern/kernel_stats.hh"
#endif
using namespace TheISA;
@@ -101,11 +102,12 @@ AlphaFullCPU<Impl>::AlphaFullCPU(Params *params)
alpha_xc_proxy->cpu = this;
alpha_xc_proxy->thread = this->thread[i];
alpha_xc_proxy->quiesceEvent =
#if FULL_SYSTEM
this->thread[i]->quiesceEvent =
new EndQuiesceEvent(xc_proxy);
alpha_xc_proxy->lastActivate = 0;
alpha_xc_proxy->lastSuspend = 0;
this->thread[i]->lastActivate = 0;
this->thread[i]->lastSuspend = 0;
#endif
this->thread[i]->xcProxy = xc_proxy;
this->execContexts.push_back(xc_proxy);
@@ -181,6 +183,9 @@ AlphaFullCPU<Impl>::AlphaXC::takeOverFrom(ExecContext *old_context)
if (thread->quiesceEvent) {
thread->quiesceEvent->xc = this;
}
// Transfer kernel stats from one CPU to the other.
thread->kernelStats = old_context->getKernelStats();
// storeCondFailures = 0;
cpu->lockFlag = false;
#endif
@@ -200,7 +205,9 @@ AlphaFullCPU<Impl>::AlphaXC::activate(int delay)
if (thread->status() == ExecContext::Active)
return;
lastActivate = curTick;
#if FULL_SYSTEM
thread->lastActivate = curTick;
#endif
if (thread->status() == ExecContext::Unallocated) {
cpu->activateWhenReady(thread->tid);
@@ -222,8 +229,10 @@ AlphaFullCPU<Impl>::AlphaXC::suspend()
if (thread->status() == ExecContext::Suspended)
return;
lastActivate = curTick;
lastSuspend = curTick;
#if FULL_SYSTEM
thread->lastActivate = curTick;
thread->lastSuspend = curTick;
#endif
/*
#if FULL_SYSTEM
// Don't change the status from active if there are pending interrupts
@@ -266,38 +275,55 @@ AlphaFullCPU<Impl>::AlphaXC::halt()
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaXC::regStats(const std::string &name)
{}
{
#if FULL_SYSTEM
thread->kernelStats = new Kernel::Statistics(cpu->system);
thread->kernelStats->regStats(name + ".kern");
#endif
}
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaXC::serialize(std::ostream &os)
{}
{
#if FULL_SYSTEM
if (thread->kernelStats)
thread->kernelStats->serialize(os);
#endif
}
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaXC::unserialize(Checkpoint *cp, const std::string &section)
{}
{
#if FULL_SYSTEM
if (thread->kernelStats)
thread->kernelStats->unserialize(cp, section);
#endif
}
#if FULL_SYSTEM
template <class Impl>
EndQuiesceEvent *
AlphaFullCPU<Impl>::AlphaXC::getQuiesceEvent()
{
return quiesceEvent;
return thread->quiesceEvent;
}
template <class Impl>
Tick
AlphaFullCPU<Impl>::AlphaXC::readLastActivate()
{
return lastActivate;
return thread->lastActivate;
}
template <class Impl>
Tick
AlphaFullCPU<Impl>::AlphaXC::readLastSuspend()
{
return lastSuspend;
return thread->lastSuspend;
}
template <class Impl>
@@ -595,7 +621,7 @@ AlphaFullCPU<Impl>::hwrei(unsigned tid)
// Need to clear the lock flag upon returning from an interrupt.
this->lockFlag = false;
this->kernelStats->hwrei();
this->thread[tid]->kernelStats->hwrei();
this->checkInterrupts = true;
@@ -607,9 +633,9 @@ template <class Impl>
bool
AlphaFullCPU<Impl>::simPalCheck(int palFunc, unsigned tid)
{
if (this->kernelStats)
this->kernelStats->callpal(palFunc,
this->execContexts[tid]);
if (this->thread[tid]->kernelStats)
this->thread[tid]->kernelStats->callpal(palFunc,
this->execContexts[tid]);
switch (palFunc) {
case PAL::halt:

View File

@@ -57,6 +57,10 @@ class Sampler;
class RemoteGDB;
class GDBListener;
namespace Kernel {
class Statistics;
};
#else
class Process;
@@ -116,6 +120,8 @@ class OzoneCPU : public BaseCPU
AlphaITB *getITBPtr() { return cpu->itb; }
AlphaDTB * getDTBPtr() { return cpu->dtb; }
Kernel::Statistics *getKernelStats() { return thread->kernelStats; }
#else
Process *getProcessPtr() { return thread->process; }
#endif
@@ -238,14 +244,7 @@ class OzoneCPU : public BaseCPU
private:
OzoneThreadState<Impl> thread;
/*
// Squash event for when the XC needs to squash all inflight instructions.
struct XCSquashEvent : public Event
{
void process();
const char *description();
};
*/
public:
// main simulation loop (one cycle)
void tick();
@@ -288,7 +287,6 @@ class OzoneCPU : public BaseCPU
void trace_data(T data);
public:
//
enum Status {
Running,
Idle,
@@ -325,8 +323,6 @@ class OzoneCPU : public BaseCPU
int readCpuId() { return cpuId; }
// FunctionalMemory *getMemPtr() { return mem; }
int cpuId;
void switchOut(Sampler *sampler);
@@ -369,8 +365,6 @@ class OzoneCPU : public BaseCPU
Status status() const { return _status; }
void setStatus(Status new_status) { _status = new_status; }
// Not sure what an activate() call on the CPU's proxy XC would mean...
virtual void activateContext(int thread_num, int delay);
virtual void suspendContext(int thread_num);
virtual void deallocateContext(int thread_num);
@@ -384,7 +378,6 @@ class OzoneCPU : public BaseCPU
public:
Counter numInst;
Counter startNumInst;
// Stats::Scalar<> numInsts;
virtual Counter totalInstructions() const
{
@@ -392,9 +385,6 @@ class OzoneCPU : public BaseCPU
}
private:
// number of simulated memory references
// Stats::Scalar<> numMemRefs;
// number of simulated loads
Counter numLoad;
Counter startNumLoad;
@@ -472,7 +462,6 @@ class OzoneCPU : public BaseCPU
template <class T>
Fault read(MemReqPtr &req, T &data)
{
// panic("CPU READ NOT IMPLEMENTED W/NEW MEMORY\n");
#if 0
#if FULL_SYSTEM && defined(TARGET_ALPHA)
if (req->flags & LOCKED) {
@@ -483,7 +472,6 @@ class OzoneCPU : public BaseCPU
#endif
Fault error;
if (req->flags & LOCKED) {
// lockAddr = req->paddr;
lockAddrList.insert(req->paddr);
lockFlag = true;
}
@@ -558,7 +546,7 @@ class OzoneCPU : public BaseCPU
if (req->flags & UNCACHEABLE) {
req->result = 2;
} else {
if (this->lockFlag/* && this->lockAddr == req->paddr*/) {
if (this->lockFlag) {
if (lockAddrList.find(req->paddr) !=
lockAddrList.end()) {
req->result = 1;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005 The Regents of The University of Michigan
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,8 +26,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstdio>
#include <cstdlib>
//#include <cstdio>
//#include <cstdlib>
#include "arch/isa_traits.hh" // For MachInst
#include "base/trace.hh"
@@ -39,7 +39,7 @@
#include "cpu/ozone/cpu.hh"
#include "cpu/quiesce_event.hh"
#include "cpu/static_inst.hh"
#include "mem/base_mem.hh"
//#include "mem/base_mem.hh"
#include "mem/mem_interface.hh"
#include "sim/sim_object.hh"
#include "sim/stats.hh"
@@ -50,7 +50,7 @@
#include "arch/alpha/tlb.hh"
#include "arch/vtophys.hh"
#include "base/callback.hh"
#include "base/remote_gdb.hh"
//#include "base/remote_gdb.hh"
#include "cpu/profile.hh"
#include "kern/kernel_stats.hh"
#include "mem/functional/memory_control.hh"
@@ -94,80 +94,26 @@ OzoneCPU<Impl>::TickEvent::description()
{
return "OzoneCPU tick event";
}
/*
template <class Impl>
OzoneCPU<Impl>::ICacheCompletionEvent::ICacheCompletionEvent(OzoneCPU *_cpu)
: Event(&mainEventQueue),
cpu(_cpu)
{
}
template <class Impl>
void
OzoneCPU<Impl>::ICacheCompletionEvent::process()
{
cpu->processICacheCompletion();
}
template <class Impl>
const char *
OzoneCPU<Impl>::ICacheCompletionEvent::description()
{
return "OzoneCPU I-cache completion event";
}
template <class Impl>
OzoneCPU<Impl>::DCacheCompletionEvent::
DCacheCompletionEvent(OzoneCPU *_cpu,
DynInstPtr &_inst,
DCacheCompEventIt &_dcceIt)
: Event(&mainEventQueue),
cpu(_cpu),
inst(_inst),
dcceIt(_dcceIt)
{
this->setFlags(Event::AutoDelete);
}
template <class Impl>
void
OzoneCPU<Impl>::DCacheCompletionEvent::process()
{
inst->setCompleted();
// Maybe remove the EA from the list of addrs?
cpu->eaList.clearAddr(inst->seqNum, inst->getEA());
cpu->dCacheCompList.erase(this->dcceIt);
}
template <class Impl>
const char *
OzoneCPU<Impl>::DCacheCompletionEvent::description()
{
return "OzoneCPU D-cache completion event";
}
*/
template <class Impl>
OzoneCPU<Impl>::OzoneCPU(Params *p)
#if FULL_SYSTEM
: BaseCPU(p), thread(this, 0, p->mem), tickEvent(this, p->width), mem(p->mem),
: BaseCPU(p), thread(this, 0, p->mem), tickEvent(this, p->width),
mem(p->mem),
#else
: BaseCPU(p), thread(this, 0, p->workload[0], 0), tickEvent(this, p->width),
mem(p->workload[0]->getMemory()),
#endif
comm(5, 5)
{
if (p->checker) {
BaseCPU *temp_checker = p->checker;
checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
} else {
checker = NULL;
}
frontEnd = new FrontEnd(p);
backEnd = new BackEnd(p);
_status = Idle;
if (checker) {
if (p->checker) {
BaseCPU *temp_checker = p->checker;
checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
checker->setMemory(mem);
#if FULL_SYSTEM
checker->setSystem(p->system);
@@ -176,19 +122,18 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
thread.xcProxy = checkerXC;
xcProxy = checkerXC;
} else {
checker = NULL;
thread.xcProxy = &ozoneXC;
xcProxy = &ozoneXC;
}
thread.inSyscall = false;
ozoneXC.cpu = this;
ozoneXC.thread = &thread;
thread.inSyscall = false;
thread.setStatus(ExecContext::Suspended);
#if FULL_SYSTEM
// xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem);
/***** All thread state stuff *****/
thread.cpu = this;
thread.tid = 0;
@@ -217,31 +162,15 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
thread.profileNode = &dummyNode;
thread.profilePC = 3;
#else
// xc = new ExecContext(this, /* thread_num */ 0, p->workload[0], /* asid */ 0);
thread.cpu = this;
thread.tid = 0;
thread.process = p->workload[0];
// thread.mem = thread.process->getMemory();
thread.asid = 0;
#endif // !FULL_SYSTEM
/*
icacheInterface = p->icache_interface;
dcacheInterface = p->dcache_interface;
cacheMemReq = new MemReq();
cacheMemReq->xc = xc;
cacheMemReq->asid = 0;
cacheMemReq->data = new uint8_t[64];
*/
numInst = 0;
startNumInst = 0;
/* numLoad = 0;
startNumLoad = 0;
lastIcacheStall = 0;
lastDcacheStall = 0;
issueWidth = p->issueWidth;
*/
execContexts.push_back(xcProxy);
frontEnd->setCPU(this);
@@ -286,47 +215,7 @@ template <class Impl>
OzoneCPU<Impl>::~OzoneCPU()
{
}
/*
template <class Impl>
void
OzoneCPU<Impl>::copyFromXC()
{
for (int i = 0; i < TheISA::TotalNumRegs; ++i) {
if (i < TheISA::NumIntRegs) {
renameTable[i]->setIntResult(xc->readIntReg(i));
} else if (i < TheISA::NumFloatRegs) {
renameTable[i]->setDoubleResult(xc->readFloatRegDouble(i));
}
}
DPRINTF(OzoneCPU, "Func Exe inst is: %i\n", xc->func_exe_inst);
backEnd->funcExeInst = xc->func_exe_inst;
// PC = xc->readPC();
// nextPC = xc->regs.npc;
}
template <class Impl>
void
OzoneCPU<Impl>::copyToXC()
{
for (int i = 0; i < TheISA::TotalNumRegs; ++i) {
if (i < TheISA::NumIntRegs) {
xc->setIntReg(i, renameTable[i]->readIntResult());
} else if (i < TheISA::NumFloatRegs) {
xc->setFloatRegDouble(i, renameTable[i]->readDoubleResult());
}
}
this->xc->regs.miscRegs.fpcr = this->regFile.miscRegs[tid].fpcr;
this->xc->regs.miscRegs.uniq = this->regFile.miscRegs[tid].uniq;
this->xc->regs.miscRegs.lock_flag = this->regFile.miscRegs[tid].lock_flag;
this->xc->regs.miscRegs.lock_addr = this->regFile.miscRegs[tid].lock_addr;
xc->func_exe_inst = backEnd->funcExeInst;
xc->regs.pc = PC;
xc->regs.npc = nextPC;
}
*/
template <class Impl>
void
OzoneCPU<Impl>::switchOut(Sampler *_sampler)
@@ -394,7 +283,6 @@ OzoneCPU<Impl>::activateContext(int thread_num, int delay)
{
// Eventually change this in SMT.
assert(thread_num == 0);
// assert(xcProxy);
assert(_status == Idle);
notIdleFraction++;
@@ -410,8 +298,8 @@ OzoneCPU<Impl>::suspendContext(int thread_num)
{
// Eventually change this in SMT.
assert(thread_num == 0);
// assert(xcProxy);
// @todo: Figure out how to initially set the status properly so this is running.
// @todo: Figure out how to initially set the status properly so
// this is running.
// assert(_status == Running);
notIdleFraction--;
unscheduleTickEvent();
@@ -486,14 +374,7 @@ void
OzoneCPU<Impl>::init()
{
BaseCPU::init();
/*
copyFromXC();
// ALso copy over PC/nextPC. This isn't normally copied in "copyFromXC()"
// so that the XC doesn't mess up the PC when returning from a syscall.
PC = xc->readPC();
nextPC = xc->regs.npc;
*/
// Mark this as in syscall so it won't need to squash
thread.inSyscall = true;
#if FULL_SYSTEM
@@ -514,8 +395,6 @@ template <class Impl>
void
OzoneCPU<Impl>::serialize(std::ostream &os)
{
// At this point, all DCacheCompEvents should be processed.
BaseCPU::serialize(os);
SERIALIZE_ENUM(_status);
nameOut(os, csprintf("%s.xc", name()));
@@ -631,31 +510,7 @@ OzoneCPU<Impl>::dbg_vtophys(Addr addr)
return vtophys(xcProxy, addr);
}
#endif // FULL_SYSTEM
/*
template <class Impl>
void
OzoneCPU<Impl>::processICacheCompletion()
{
switch (status()) {
case IcacheMiss:
DPRINTF(OzoneCPU, "OzoneCPU: Finished Icache miss.\n");
icacheStallCycles += curTick - lastIcacheStall;
_status = IcacheMissComplete;
cacheBlkValid = true;
// scheduleTickEvent(1);
break;
case SwitchedOut:
// If this CPU has been switched out due to sampling/warm-up,
// ignore any further status changes (e.g., due to cache
// misses outstanding at the time of the switch).
return;
default:
panic("OzoneCPU::processICacheCompletion: bad state");
break;
}
}
*/
#if FULL_SYSTEM
template <class Impl>
void
@@ -663,7 +518,6 @@ OzoneCPU<Impl>::post_interrupt(int int_num, int index)
{
BaseCPU::post_interrupt(int_num, index);
// if (thread._status == ExecContext::Suspended) {
if (_status == Idle) {
DPRINTF(IPI,"Suspended Processor awoke\n");
// thread.activate();
@@ -690,9 +544,6 @@ OzoneCPU<Impl>::tick()
frontEnd->tick();
backEnd->tick();
// Do this here? For now the front end will control the PC.
// PC = nextPC;
// check for instruction-count-based events
comInstEventQueue[0]->serviceEvents(numInst);
@@ -742,11 +593,13 @@ OzoneCPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
if (return_value.successful()) {
// no error
thread.renameTable[SyscallSuccessReg]->setIntResult(0);
thread.renameTable[ReturnValueReg]->setIntResult(return_value.value());
thread.renameTable[ReturnValueReg]->setIntResult(
return_value.value());
} else {
// got an error, return details
thread.renameTable[SyscallSuccessReg]->setIntResult((IntReg) -1);
thread.renameTable[ReturnValueReg]->setIntResult(-return_value.value());
thread.renameTable[ReturnValueReg]->setIntResult(
-return_value.value());
}
}
#else
@@ -756,15 +609,10 @@ OzoneCPU<Impl>::hwrei()
{
// Need to move this to ISA code
// May also need to make this per thread
/*
if (!inPalMode())
return new UnimplementedOpcodeFault;
thread.setNextPC(thread.readMiscReg(AlphaISA::IPR_EXC_ADDR));
*/
lockFlag = false;
lockAddrList.clear();
kernelStats->hwrei();
thread.kernelStats->hwrei();
checkInterrupts = true;
@@ -835,7 +683,7 @@ OzoneCPU<Impl>::simPalCheck(int palFunc)
{
// Need to move this to ISA code
// May also need to make this per thread
this->kernelStats->callpal(palFunc, xcProxy);
thread.kernelStats->callpal(palFunc, xcProxy);
switch (palFunc) {
case PAL::halt:
@@ -874,7 +722,6 @@ template <class Impl>
void
OzoneCPU<Impl>::OzoneXC::setStatus(Status new_status)
{
// cpu->_status = new_status;
thread->_status = new_status;
}
@@ -932,6 +779,7 @@ OzoneCPU<Impl>::OzoneXC::takeOverFrom(ExecContext *old_context)
setStatus(old_context->status());
copyArchRegs(old_context);
setCpuId(old_context->readCpuId());
#if !FULL_SYSTEM
setFuncExeInst(old_context->readFuncExeInst());
#else
@@ -944,6 +792,8 @@ OzoneCPU<Impl>::OzoneXC::takeOverFrom(ExecContext *old_context)
if (thread->quiesceEvent) {
thread->quiesceEvent->xc = this;
}
thread->kernelStats = old_context->getKernelStats();
// storeCondFailures = 0;
cpu->lockFlag = false;
#endif
@@ -954,7 +804,12 @@ OzoneCPU<Impl>::OzoneXC::takeOverFrom(ExecContext *old_context)
template <class Impl>
void
OzoneCPU<Impl>::OzoneXC::regStats(const std::string &name)
{ }
{
#if FULL_SYSTEM
thread->kernelStats = new Kernel::Statistics(cpu->system);
thread->kernelStats->regStats(name + ".kern");
#endif
}
template <class Impl>
void

View File

@@ -782,7 +782,7 @@ SimpleCPU::tick()
#if FULL_SYSTEM
if (system->kernelBinning->fnbin) {
assert(kernelStats);
assert(cpuXC->getKernelStats());
system->kernelBinning->execute(xcProxy, inst);
}

View File

@@ -1,3 +1,30 @@
/*
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* 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.
*/
#ifndef __CPU_THREAD_STATE_HH__
#define __CPU_THREAD_STATE_HH__
@@ -8,11 +35,20 @@
class EndQuiesceEvent;
class FunctionProfile;
class ProfileNode;
namespace Kernel {
class Statistics;
};
#else
class Process;
class FunctionalMemory;
class Process;
#endif
/**
* Struct for holding general thread state that is needed across CPU
* models. This includes things such as pointers to the process,
* memory, quiesce events, and certain stats. This can be expanded
* to hold more thread-specific stats within it.
*/
struct ThreadState {
#if FULL_SYSTEM
ThreadState(int _cpuId, int _tid, FunctionalMemory *_mem)
@@ -55,6 +91,7 @@ struct ThreadState {
EndQuiesceEvent *quiesceEvent;
Kernel::Statistics *kernelStats;
#else
Process *process;

View File

@@ -67,15 +67,17 @@ FnEvent::process(ExecContext *xc)
void
IdleStartEvent::process(ExecContext *xc)
{
xc->getCpuPtr()->kernelStats->setIdleProcess(
xc->readMiscReg(AlphaISA::IPR_PALtemp23), xc);
if (xc->getKernelStats())
xc->getKernelStats()->setIdleProcess(
xc->readMiscReg(AlphaISA::IPR_PALtemp23), xc);
remove();
}
void
InterruptStartEvent::process(ExecContext *xc)
{
xc->getCpuPtr()->kernelStats->mode(Kernel::interrupt, xc);
if (xc->getKernelStats())
xc->getKernelStats()->mode(Kernel::interrupt, xc);
}
void
@@ -83,5 +85,6 @@ InterruptEndEvent::process(ExecContext *xc)
{
// We go back to kernel, if we are user, inside the rti
// pal code we will get switched to user because of the ICM write
xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc);
if (xc->getKernelStats())
xc->getKernelStats()->mode(Kernel::kernel, xc);
}

View File

@@ -65,7 +65,8 @@ namespace AlphaPseudo
void
arm(ExecContext *xc)
{
xc->getCpuPtr()->kernelStats->arm();
if (xc->getKernelStats())
xc->getKernelStats()->arm();
}
void
@@ -75,7 +76,8 @@ namespace AlphaPseudo
return;
xc->suspend();
xc->getCpuPtr()->kernelStats->quiesce();
if (xc->getKernelStats())
xc->getKernelStats()->arm();
}
void
@@ -92,7 +94,8 @@ namespace AlphaPseudo
quiesceEvent->schedule(curTick + Clock::Int::ns * ns);
xc->suspend();
xc->getCpuPtr()->kernelStats->quiesce();
if (xc->getKernelStats())
xc->getKernelStats()->quiesce();
}
void
@@ -111,7 +114,8 @@ namespace AlphaPseudo
xc->getCpuPtr()->cycles(cycles));
xc->suspend();
xc->getCpuPtr()->kernelStats->quiesce();
if (xc->getKernelStats())
xc->getKernelStats()->quiesce();
}
uint64_t
@@ -123,7 +127,8 @@ namespace AlphaPseudo
void
ivlb(ExecContext *xc)
{
xc->getCpuPtr()->kernelStats->ivlb();
if (xc->getKernelStats())
xc->getKernelStats()->ivlb();
}
void