summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2006-05-23 17:04:25 -0400
committerKevin Lim <ktlim@umich.edu>2006-05-23 17:04:25 -0400
commitb414c9e736543acca639c50582c7df7abf59c11b (patch)
tree8eaa0fa7061af351955c59f0e2a525f3527f2ee7
parenteeeee7c58f26fac9fe9b8606e26ef8e99a28e399 (diff)
parent358cf1b11765024309fe986262bb3a3d16c8a720 (diff)
downloadgem5-b414c9e736543acca639c50582c7df7abf59c11b.tar.xz
Merge ktlim@zizzer:/bk/m5
into zamp.eecs.umich.edu:/z/ktlim2/clean/m5-o3 --HG-- extra : convert_revision : 0a6140f3f5e7c454981c5aa2b221224f076e50eb
-rw-r--r--arch/alpha/ev5.cc22
-rw-r--r--cpu/base.cc23
-rw-r--r--cpu/base.hh10
-rw-r--r--cpu/base_dyn_inst.hh5
-rw-r--r--cpu/checker/cpu.cc321
-rw-r--r--cpu/checker/cpu.hh16
-rw-r--r--cpu/checker/exec_context.hh44
-rw-r--r--cpu/cpu_exec_context.cc9
-rw-r--r--cpu/cpu_exec_context.hh7
-rw-r--r--cpu/exec_context.hh7
-rw-r--r--cpu/o3/alpha_cpu.hh11
-rw-r--r--cpu/o3/alpha_cpu_impl.hh62
-rw-r--r--cpu/o3/iew_impl.hh5
-rw-r--r--cpu/o3/inst_queue.hh4
-rw-r--r--cpu/o3/inst_queue_impl.hh22
-rw-r--r--cpu/ozone/cpu.hh28
-rw-r--r--cpu/ozone/cpu_impl.hh211
-rw-r--r--cpu/ozone/dyn_inst.hh52
-rw-r--r--cpu/ozone/dyn_inst_impl.hh7
-rw-r--r--cpu/ozone/front_end.hh34
-rw-r--r--cpu/ozone/front_end_impl.hh66
-rw-r--r--cpu/ozone/lw_back_end.hh103
-rw-r--r--cpu/ozone/lw_back_end_impl.hh67
-rw-r--r--cpu/ozone/lw_lsq.hh27
-rw-r--r--cpu/ozone/lw_lsq_impl.hh41
-rw-r--r--cpu/ozone/rename_table.hh28
-rw-r--r--cpu/ozone/thread_state.hh38
-rw-r--r--cpu/simple/cpu.cc2
-rw-r--r--cpu/thread_state.hh39
-rw-r--r--kern/system_events.cc11
-rw-r--r--sim/pseudo_inst.cc15
31 files changed, 553 insertions, 784 deletions
diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc
index 019e83dd4..ad3a9ec4c 100644
--- a/arch/alpha/ev5.cc
+++ b/arch/alpha/ev5.cc
@@ -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:
diff --git a/cpu/base.cc b/cpu/base.cc
index 74b679d5d..de03b9eab 100644
--- a/cpu/base.cc
+++ b/cpu/base.cc
@@ -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
diff --git a/cpu/base.hh b/cpu/base.hh
index 20166d7ee..dd776859d 100644
--- a/cpu/base.hh
+++ b/cpu/base.hh
@@ -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__
diff --git a/cpu/base_dyn_inst.hh b/cpu/base_dyn_inst.hh
index 9403faec3..388ea4a8d 100644
--- a/cpu/base_dyn_inst.hh
+++ b/cpu/base_dyn_inst.hh
@@ -450,13 +450,10 @@ class BaseDynInst : public FastAlloc, public RefCounted
instResult.integer = val;
}
- //Push to .cc file.
/** Records that one of the source registers is ready. */
void markSrcRegReady();
- /** Marks a specific register as ready.
- * @todo: Move this to .cc file.
- */
+ /** Marks a specific register as ready. */
void markSrcRegReady(RegIndex src_idx);
/** Returns if a source register is ready. */
diff --git a/cpu/checker/cpu.cc b/cpu/checker/cpu.cc
index f76f1e063..08ab5d5c8 100644
--- a/cpu/checker/cpu.cc
+++ b/cpu/checker/cpu.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-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,41 +26,17 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-//#include <cmath>
-#include <cstdio>
-//#include <cstdlib>
-#include <iostream>
-#include <iomanip>
#include <list>
-//#include <sstream>
#include <string>
-//#include "base/cprintf.hh"
-//#include "base/inifile.hh"
-//#include "base/loader/symtab.hh"
-#include "base/misc.hh"
-//#include "base/pollevent.hh"
-//#include "base/range.hh"
#include "base/refcnt.hh"
-//#include "base/stats/events.hh"
#include "cpu/base.hh"
#include "cpu/base_dyn_inst.hh"
#include "cpu/checker/cpu.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/smt.hh"
#include "cpu/static_inst.hh"
-//#include "kern/kernel_stats.hh"
-#include "mem/base_mem.hh"
-#include "mem/mem_interface.hh"
#include "sim/byteswap.hh"
-#include "sim/builder.hh"
-//#include "sim/debug.hh"
-//#include "sim/host.hh"
-//#include "sim/sim_events.hh"
#include "sim/sim_object.hh"
#include "sim/stats.hh"
@@ -72,15 +48,8 @@
#include "cpu/ozone/simple_impl.hh"
#if FULL_SYSTEM
-#include "base/remote_gdb.hh"
-#include "mem/functional/memory_control.hh"
-#include "mem/functional/physical.hh"
#include "sim/system.hh"
-#include "arch/tlb.hh"
-#include "arch/stacktrace.hh"
#include "arch/vtophys.hh"
-#else // !FULL_SYSTEM
-#include "mem/functional/functional.hh"
#endif // FULL_SYSTEM
using namespace std;
@@ -90,17 +59,6 @@ using namespace AlphaISA;
void
CheckerCPU::init()
{
-/*
- BaseCPU::init();
-#if FULL_SYSTEM
- for (int i = 0; i < execContexts.size(); ++i) {
- ExecContext *xc = execContexts[i];
-
- // initialize CPU, including PC
- TheISA::initCPU(xc, xc->readCpuId());
- }
-#endif
-*/
}
CheckerCPU::CheckerCPU(Params *p)
@@ -151,6 +109,8 @@ CheckerCPU::setMemory(FunctionalMemory *mem)
xcProxy = cpuXC->getProxy();
execContexts.push_back(xcProxy);
memReq->xc = xcProxy;
+ delete cpuXC->kernelStats;
+ cpuXC->kernelStats = NULL;
}
#endif
}
@@ -168,6 +128,8 @@ CheckerCPU::setSystem(System *system)
xcProxy = cpuXC->getProxy();
execContexts.push_back(xcProxy);
memReq->xc = xcProxy;
+ delete cpuXC->kernelStats;
+ cpuXC->kernelStats = NULL;
}
}
#endif
@@ -197,82 +159,15 @@ CheckerCPU::unserialize(Checkpoint *cp, const string &section)
Fault
CheckerCPU::copySrcTranslate(Addr src)
{
- static bool no_warn = true;
- int blk_size = 64;
- // Only support block sizes of 64 atm.
- assert(blk_size == 64);
- int offset = src & (blk_size - 1);
-
- // Make sure block doesn't span page
- if (no_warn &&
- (src & PageMask) != ((src + blk_size) & PageMask) &&
- (src >> 40) != 0xfffffc) {
- warn("Copied block source spans pages %x.", src);
- no_warn = false;
- }
-
- memReq->reset(src & ~(blk_size - 1), blk_size);
-
- // translate to physical address
- Fault fault = cpuXC->translateDataReadReq(memReq);
-
- if (fault == NoFault) {
- cpuXC->copySrcAddr = src;
- cpuXC->copySrcPhysAddr = memReq->paddr + offset;
- } else {
- assert(!fault->isAlignmentFault());
-
- cpuXC->copySrcAddr = 0;
- cpuXC->copySrcPhysAddr = 0;
- }
- return fault;
+ panic("Unimplemented!");
}
Fault
CheckerCPU::copy(Addr dest)
{
- static bool no_warn = true;
- int blk_size = 64;
- // Only support block sizes of 64 atm.
- assert(blk_size == 64);
- uint8_t data[blk_size];
- //assert(cpuXC->copySrcAddr);
- int offset = dest & (blk_size - 1);
-
- // Make sure block doesn't span page
- if (no_warn &&
- (dest & PageMask) != ((dest + blk_size) & PageMask) &&
- (dest >> 40) != 0xfffffc) {
- no_warn = false;
- warn("Copied block destination spans pages %x. ", dest);
- }
-
- memReq->reset(dest & ~(blk_size -1), blk_size);
- // translate to physical address
- Fault fault = cpuXC->translateDataWriteReq(memReq);
-
- 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 = dest_addr;
- cpuXC->mem->write(memReq, data);
- memReq->cmd = Copy;
- memReq->completionEvent = NULL;
- memReq->paddr = cpuXC->copySrcPhysAddr;
- memReq->dest = dest_addr;
- memReq->size = 64;
- memReq->time = curTick;
- memReq->flags &= ~INST_READ;
- }
- else
- assert(!fault->isAlignmentFault());
-
- return fault;
+ panic("Unimplemented!");
}
-// precise architected memory state accessor macros
template <class T>
Fault
CheckerCPU::read(Addr addr, T &data, unsigned flags)
@@ -280,17 +175,15 @@ CheckerCPU::read(Addr addr, T &data, unsigned flags)
memReq->reset(addr, sizeof(T), flags);
// translate to physical address
- // Should I probe the DTB? Or should I just take the physical address
- // and assume correct translation?
translateDataReadReq(memReq);
- // if we have a cache, do cache access too
memReq->cmd = Read;
memReq->completionEvent = NULL;
memReq->time = curTick;
memReq->flags &= ~INST_READ;
if (!(memReq->flags & UNCACHEABLE)) {
+ // Access memory to see if we have the same data
cpuXC->read(memReq, data);
} else {
// Assume the data is correct if it's an uncached access
@@ -350,29 +243,34 @@ CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
// translate to physical address
cpuXC->translateDataWriteReq(memReq);
- if ((!(unverifiedReq->flags & LOCKED) ||
- ((unverifiedReq->flags & LOCKED) &&
- unverifiedReq->result == 1)) &&
- !(unverifiedReq->flags & UNCACHEABLE)) {
- // do functional access
-// cpuXC->read(memReq, data);
-
- memReq->cmd = Write;
-// memcpy(memReq->data,(uint8_t *)&data,memReq->size);
- T inst_data;
- memcpy(&inst_data, unverifiedReq->data, sizeof(T));
+ // Can compare the write data and result only if it's cacheable,
+ // not a store conditional, or is a store conditional that
+ // succeeded.
+ // @todo: Verify that actual memory matches up with these values.
+ // Right now it only verifies that the instruction data is the
+ // same as what was in the request that got sent to memory; there
+ // is no verification that it is the same as what is in memory.
+ // This is because the LSQ would have to be snooped in the CPU to
+ // verify this data.
+ if (unverifiedReq &&
+ !(unverifiedReq->flags & UNCACHEABLE) &&
+ (!(unverifiedReq->flags & LOCKED) ||
+ ((unverifiedReq->flags & LOCKED) &&
+ unverifiedReq->result == 1))) {
+#if 0
+ memReq->cmd = Read;
memReq->completionEvent = NULL;
memReq->time = curTick;
memReq->flags &= ~INST_READ;
+ cpuXC->read(memReq, inst_data);
+#endif
+ T inst_data;
+ memcpy(&inst_data, unverifiedReq->data, sizeof(T));
- // Hard to verify this as the data writes back after the
- // instruction commits. May only be able to check that the
- // value produced from execute() matches the value produced
- // from the instruction's first execution.
if (data != inst_data) {
- warn("Store value does not match value in memory! "
+ warn("%lli: Store value does not match value in memory! "
"Instruction: %#x, memory: %#x",
- inst_data, data);
+ curTick, inst_data, data);
handleError();
}
}
@@ -436,19 +334,6 @@ CheckerCPU::dbg_vtophys(Addr addr)
}
#endif // FULL_SYSTEM
-#if FULL_SYSTEM
-void
-CheckerCPU::post_interrupt(int int_num, int index)
-{
- BaseCPU::post_interrupt(int_num, index);
-
- if (cpuXC->status() == ExecContext::Suspended) {
- DPRINTF(IPI,"Suspended Processor awoke\n");
- cpuXC->activate();
- }
-}
-#endif // FULL_SYSTEM
-
bool
CheckerCPU::translateInstReq(MemReqPtr &req)
{
@@ -466,15 +351,16 @@ CheckerCPU::translateDataReadReq(MemReqPtr &req)
cpuXC->translateDataReadReq(req);
if (req->vaddr != unverifiedReq->vaddr) {
- warn("Request virtual addresses do not match! Inst: %#x, checker:"
- " %#x",
- unverifiedReq->vaddr, req->vaddr);
+ warn("%lli: Request virtual addresses do not match! Inst: %#x, "
+ "checker: %#x",
+ curTick, unverifiedReq->vaddr, req->vaddr);
+ handleError();
}
req->paddr = unverifiedReq->paddr;
if (checkFlags(req)) {
- warn("Request flags do not match! Inst: %#x, checker: %#x",
- unverifiedReq->flags, req->flags);
+ warn("%lli: Request flags do not match! Inst: %#x, checker: %#x",
+ curTick, unverifiedReq->flags, req->flags);
handleError();
}
}
@@ -485,15 +371,16 @@ CheckerCPU::translateDataWriteReq(MemReqPtr &req)
cpuXC->translateDataWriteReq(req);
if (req->vaddr != unverifiedReq->vaddr) {
- warn("Request virtual addresses do not match! Inst: %#x, checker:"
- " %#x",
- unverifiedReq->vaddr, req->vaddr);
+ warn("%lli: Request virtual addresses do not match! Inst: %#x, "
+ "checker: %#x",
+ curTick, unverifiedReq->vaddr, req->vaddr);
+ handleError();
}
req->paddr = unverifiedReq->paddr;
if (checkFlags(req)) {
- warn("Request flags do not match! Inst: %#x, checker: %#x",
- unverifiedReq->flags, req->flags);
+ warn("%lli: Request flags do not match! Inst: %#x, checker: %#x",
+ curTick, unverifiedReq->flags, req->flags);
handleError();
}
}
@@ -512,13 +399,17 @@ CheckerCPU::checkFlags(MemReqPtr &req)
}
}
-/* start simulation, program loaded, processor precise state initialized */
template <class DynInstPtr>
void
Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
{
DynInstPtr inst;
+ // Either check this instruction, or add it to a list of
+ // instructions waiting to be checked. Instructions must be
+ // checked in program order, so if a store has committed yet not
+ // completed, there may be some instructions that are waiting
+ // behind it that have completed and must be checked.
if (!instList.empty()) {
if (youngestSN < completed_inst->seqNum) {
DPRINTF(Checker, "Adding instruction [sn:%lli] PC:%#x to list.\n",
@@ -547,16 +438,17 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
inst = completed_inst;
youngestSN = completed_inst->seqNum;
} else {
-// panic("SN already seen yet the list is empty!");
return;
}
}
}
+ // Try to check all instructions that are completed, ending if we
+ // run out of instructions to check or if an instruction is not
+ // yet completed.
while (1) {
DPRINTF(Checker, "Processing instruction [sn:%lli] PC:%#x.\n",
inst->seqNum, inst->readPC());
-// verifyInst = completed_inst;
unverifiedResult.integer = inst->readIntResult();
unverifiedReq = inst->req;
numCycles++;
@@ -569,15 +461,9 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
cpuXC->setFloatRegDouble(ZeroReg, 0.0);
#endif // TARGET_ALPHA
- // Try to fetch an instruction
-
- // set up memory request for instruction fetch
-#if FULL_SYSTEM
-#define IFETCH_FLAGS(pc) ((pc) & 1) ? PHYSICAL : 0
-#else
-#define IFETCH_FLAGS(pc) 0
-#endif
-
+ // Check if any recent PC changes match up with anything we
+ // expect to happen. This is mostly to check if traps or
+ // PC-based events have occurred in both the checker and CPU.
if (changedPC) {
DPRINTF(Checker, "Changed PC recently to %#x\n",
cpuXC->readPC());
@@ -585,9 +471,9 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
if (newPC == cpuXC->readPC()) {
DPRINTF(Checker, "Changed PC matches expected PC\n");
} else {
- warn("Changed PC does not match expected PC, changed: %#x, "
- "expected: %#x",
- cpuXC->readPC(), newPC);
+ warn("%lli: Changed PC does not match expected PC, "
+ "changed: %#x, expected: %#x",
+ curTick, cpuXC->readPC(), newPC);
handleError();
}
willChangePC = false;
@@ -600,6 +486,15 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
changedNextPC = false;
}
+ // Try to fetch the instruction
+
+#if FULL_SYSTEM
+#define IFETCH_FLAGS(pc) ((pc) & 1) ? PHYSICAL : 0
+#else
+#define IFETCH_FLAGS(pc) 0
+#endif
+
+ // set up memory request for instruction fetch
memReq->cmd = Read;
memReq->reset(cpuXC->readPC() & ~3, sizeof(uint32_t),
IFETCH_FLAGS(cpuXC->readPC()));
@@ -608,8 +503,13 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
if (!succeeded) {
if (inst->getFault() == NoFault) {
- warn("Instruction PC %#x was not found in the ITB!",
- cpuXC->readPC());
+ // In this case the instruction was not a dummy
+ // instruction carrying an ITB fault. In the single
+ // threaded case the ITB should still be able to
+ // translate this instruction; in the SMT case it's
+ // possible that its ITB entry was kicked out.
+ warn("%lli: Instruction PC %#x was not found in the ITB!",
+ curTick, cpuXC->readPC());
handleError();
// go to the next instruction
@@ -618,20 +518,18 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
return;
} else {
+ // The instruction is carrying an ITB fault. Handle
+ // the fault and see if our results match the CPU on
+ // the next tick().
fault = inst->getFault();
}
}
if (fault == NoFault) {
-// fault = cpuXC->mem->read(memReq, machInst);
cpuXC->mem->read(memReq, machInst);
- // If we've got a valid instruction (i.e., no fault on instruction
- // fetch), then execute it.
-
- // keep an instruction count
+ // keep an instruction count
numInst++;
-// numInsts++;
// decode the instruction
machInst = gtoh(machInst);
@@ -639,7 +537,8 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
// Checks both the machine instruction and the PC.
validateInst(inst);
- curStaticInst = StaticInst::decode(makeExtMI(machInst, cpuXC->readPC()));
+ curStaticInst = StaticInst::decode(makeExtMI(machInst,
+ cpuXC->readPC()));
#if FULL_SYSTEM
cpuXC->setInst(machInst);
@@ -660,10 +559,6 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
// Checks to make sure instrution results are correct.
validateExecution(inst);
-// if (curStaticInst->isMemRef()) {
-// numMemRefs++;
-// }
-
if (curStaticInst->isLoad()) {
++numLoad;
}
@@ -693,6 +588,9 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
}
#if FULL_SYSTEM
+ // @todo: Determine if these should happen only if the
+ // instruction hasn't faulted. In the SimpleCPU case this may
+ // not be true, but in the O3 or Ozone case this may be true.
Addr oldpc;
int count = 0;
do {
@@ -707,10 +605,12 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
}
#endif
- // Checks PC, next PC. Optionally can check all registers. (Or just those
+ // @todo: Optionally can check all registers. (Or just those
// that have been modified).
validateState();
+ // Continue verifying instructions if there's another completed
+ // instruction waiting to be verified.
if (instList.empty()) {
break;
} else if (instList.front()->isCompleted()) {
@@ -726,7 +626,6 @@ template <class DynInstPtr>
void
Checker<DynInstPtr>::switchOut(Sampler *s)
{
- sampler = s;
instList.clear();
}
@@ -734,15 +633,6 @@ template <class DynInstPtr>
void
Checker<DynInstPtr>::takeOverFrom(BaseCPU *oldCPU)
{
-// BaseCPU::takeOverFrom(oldCPU);
-
- // if any of this CPU's ExecContexts are active, mark the CPU as
- // running and schedule its tick event.
-/*
- for (int i = 0; i < execContexts.size(); ++i) {
- ExecContext *xc = execContexts[i];
- }
-*/
}
template <class DynInstPtr>
@@ -750,20 +640,22 @@ void
Checker<DynInstPtr>::validateInst(DynInstPtr &inst)
{
if (inst->readPC() != cpuXC->readPC()) {
- warn("PCs do not match! Inst: %#x, checker: %#x",
- inst->readPC(), cpuXC->readPC());
+ warn("%lli: PCs do not match! Inst: %#x, checker: %#x",
+ curTick, inst->readPC(), cpuXC->readPC());
if (changedPC) {
- warn("Changed PCs recently, may not be an error");
+ warn("%lli: Changed PCs recently, may not be an error",
+ curTick);
} else {
handleError();
}
}
- if (static_cast<MachInst>(inst->staticInst->machInst) !=
- machInst) {
- warn("Binary instructions do not match! Inst: %#x, checker: %#x",
- static_cast<MachInst>(inst->staticInst->machInst),
- machInst);
+ MachInst mi = static_cast<MachInst>(inst->staticInst->machInst);
+
+ if (mi != machInst) {
+ warn("%lli: Binary instructions do not match! Inst: %#x, "
+ "checker: %#x",
+ curTick, mi, machInst);
handleError();
}
}
@@ -773,10 +665,11 @@ void
Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
{
if (inst->numDestRegs()) {
+ // @todo: Support more destination registers.
if (inst->isUnverifiable()) {
- // @todo: Support more destination registers.
- // Grab the result from the instruction and write it to the
- // register.
+ // Unverifiable instructions assume they were executed
+ // properly by the CPU. Grab the result from the
+ // instruction and write it to the register.
RegIndex idx = inst->destRegIdx(0);
if (idx < TheISA::FP_Base_DepTag) {
cpuXC->setIntReg(idx, inst->readIntResult());
@@ -786,16 +679,17 @@ Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
cpuXC->setMiscReg(idx, inst->readIntResult());
}
} else if (result.integer != inst->readIntResult()) {
- warn("Instruction results do not match! (May not be integer results) "
- "Inst: %#x, checker: %#x",
- inst->readIntResult(), result.integer);
+ warn("%lli: Instruction results do not match! (Results may not "
+ "actually be integers) Inst: %#x, checker: %#x",
+ curTick, inst->readIntResult(), result.integer);
handleError();
}
}
if (inst->readNextPC() != cpuXC->readNextPC()) {
- warn("Instruction next PCs do not match! Inst: %#x, checker: %#x",
- inst->readNextPC(), cpuXC->readNextPC());
+ warn("%lli: Instruction next PCs do not match! Inst: %#x, "
+ "checker: %#x",
+ curTick, inst->readNextPC(), cpuXC->readNextPC());
handleError();
}
@@ -810,9 +704,10 @@ Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
if (inst->xcBase()->readMiscReg(misc_reg_idx) !=
cpuXC->readMiscReg(misc_reg_idx)) {
- warn("Misc reg idx %i (side effect) does not match! Inst: %#x, "
- "checker: %#x",
- misc_reg_idx, inst->xcBase()->readMiscReg(misc_reg_idx),
+ warn("%lli: Misc reg idx %i (side effect) does not match! "
+ "Inst: %#x, checker: %#x",
+ curTick, misc_reg_idx,
+ inst->xcBase()->readMiscReg(misc_reg_idx),
cpuXC->readMiscReg(misc_reg_idx));
handleError();
}
diff --git a/cpu/checker/cpu.hh b/cpu/checker/cpu.hh
index 678e888df..37fe59d95 100644
--- a/cpu/checker/cpu.hh
+++ b/cpu/checker/cpu.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-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
@@ -39,7 +39,6 @@
#include "cpu/base_dyn_inst.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/pc_event.hh"
-#include "cpu/sampler/sampler.hh"
#include "cpu/static_inst.hh"
#include "sim/eventq.hh"
@@ -63,6 +62,7 @@ class BaseDynInst;
class ExecContext;
class MemInterface;
class Checkpoint;
+class Sampler;
class CheckerCPU : public BaseCPU
{
@@ -86,8 +86,6 @@ class CheckerCPU : public BaseCPU
};
public:
- void post_interrupt(int int_num, int index);
-
CheckerCPU(Params *p);
virtual ~CheckerCPU();
@@ -111,8 +109,6 @@ class CheckerCPU : public BaseCPU
#if FULL_SYSTEM
Addr dbg_vtophys(Addr addr);
-
- bool interval_stats;
#endif
union Result {
@@ -129,11 +125,6 @@ class CheckerCPU : public BaseCPU
// Refcounted pointer to the one memory request.
MemReqPtr memReq;
- // Pointer to the sampler that is telling us to switchover.
- // Used to signal the completion of the pipe drain and schedule
- // the next switchover
- Sampler *sampler;
-
StaticInstPtr curStaticInst;
// number of simulated instructions
@@ -284,6 +275,7 @@ class CheckerCPU : public BaseCPU
bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); }
#else
// Assume that the normal CPU's call to syscall was successful.
+ // The checker's state would have already been updated by the syscall.
void syscall() { }
#endif
@@ -307,8 +299,6 @@ class CheckerCPU : public BaseCPU
bool exitOnError;
InstSeqNum youngestSN;
-// std::map<Addr, uint64_t> storeBuff;
-// typedef std::map<Addr, uint64_t>::iterator map_it;
};
template <class DynInstPtr>
diff --git a/cpu/checker/exec_context.hh b/cpu/checker/exec_context.hh
index 4843d1cf0..38784867d 100644
--- a/cpu/checker/exec_context.hh
+++ b/cpu/checker/exec_context.hh
@@ -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
};
diff --git a/cpu/cpu_exec_context.cc b/cpu/cpu_exec_context.cc
index 24de6d450..78ce058e8 100644
--- a/cpu/cpu_exec_context.cc
+++ b/cpu/cpu_exec_context.cc
@@ -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
diff --git a/cpu/cpu_exec_context.hh b/cpu/cpu_exec_context.hh
index cac006925..3d1428933 100644
--- a/cpu/cpu_exec_context.hh
+++ b/cpu/cpu_exec_context.hh
@@ -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;
diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh
index 7bd7d5682..e1f1016e5 100644
--- a/cpu/exec_context.hh
+++ b/cpu/exec_context.hh
@@ -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
diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh
index 78ad5f7d8..5c89e3462 100644
--- a/cpu/o3/alpha_cpu.hh
+++ b/cpu/o3/alpha_cpu.hh
@@ -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
diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh
index 58b2b3548..91cd3d9e6 100644
--- a/cpu/o3/alpha_cpu_impl.hh
+++ b/cpu/o3/alpha_cpu_impl.hh
@@ -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:
diff --git a/cpu/o3/iew_impl.hh b/cpu/o3/iew_impl.hh
index cf28f2efc..b0137d7fc 100644
--- a/cpu/o3/iew_impl.hh
+++ b/cpu/o3/iew_impl.hh
@@ -1232,13 +1232,14 @@ DefaultIEW<Impl>::executeInsts()
#endif
// Execute/writeback any instructions that are available.
+ int insts_to_execute = fromIssue->size;
int inst_num = 0;
- for ( ; inst_num < issueWidth && fromIssue->insts[inst_num];
+ for (; inst_num < insts_to_execute;
++inst_num) {
DPRINTF(IEW, "Execute: Executing instructions from IQ.\n");
- DynInstPtr inst = fromIssue->insts[inst_num];
+ DynInstPtr inst = instQueue.getInstToExecute();
DPRINTF(IEW, "Execute: Processing PC %#x, [tid:%i] [sn:%i].\n",
inst->readPC(), inst->threadNumber,inst->seqNum);
diff --git a/cpu/o3/inst_queue.hh b/cpu/o3/inst_queue.hh
index 6bdf4ddc2..518de73d9 100644
--- a/cpu/o3/inst_queue.hh
+++ b/cpu/o3/inst_queue.hh
@@ -171,6 +171,8 @@ class InstructionQueue
*/
void insertBarrier(DynInstPtr &barr_inst);
+ DynInstPtr getInstToExecute();
+
/**
* Records the instruction as the producer of a register without
* adding it to the rest of the IQ.
@@ -272,6 +274,8 @@ class InstructionQueue
/** List of all the instructions in the IQ (some of which may be issued). */
std::list<DynInstPtr> instList[Impl::MaxThreads];
+ std::list<DynInstPtr> instsToExecute;
+
/**
* Struct for comparing entries to be added to the priority queue. This
* gives reverse ordering to the instructions in terms of sequence
diff --git a/cpu/o3/inst_queue_impl.hh b/cpu/o3/inst_queue_impl.hh
index 71541b4f8..f1dc4e01f 100644
--- a/cpu/o3/inst_queue_impl.hh
+++ b/cpu/o3/inst_queue_impl.hh
@@ -589,6 +589,16 @@ InstructionQueue<Impl>::insertBarrier(DynInstPtr &barr_inst)
}
template <class Impl>
+typename Impl::DynInstPtr
+InstructionQueue<Impl>::getInstToExecute()
+{
+ assert(!instsToExecute.empty());
+ DynInstPtr inst = instsToExecute.front();
+ instsToExecute.pop_front();
+ return inst;
+}
+
+template <class Impl>
void
InstructionQueue<Impl>::addToOrderList(OpClass op_class)
{
@@ -662,9 +672,11 @@ InstructionQueue<Impl>::processFUCompletion(DynInstPtr &inst, int fu_idx)
// @todo: This could break if there's multiple multi-cycle ops
// finishing on this cycle. Maybe implement something like
// instToCommit in iew_impl.hh.
- int &size = issueToExecuteQueue->access(0)->size;
+ issueToExecuteQueue->access(0)->size++;
+ instsToExecute.push_back(inst);
+// int &size = issueToExecuteQueue->access(0)->size;
- issueToExecuteQueue->access(0)->insts[size++] = inst;
+// issueToExecuteQueue->access(0)->insts[size++] = inst;
}
// @todo: Figure out a better way to remove the squashed items from the
@@ -690,9 +702,8 @@ InstructionQueue<Impl>::scheduleReadyInsts()
ListOrderIt order_it = listOrder.begin();
ListOrderIt order_end_it = listOrder.end();
int total_issued = 0;
- int exec_queue_slot = i2e_info->size;
- while (exec_queue_slot < totalWidth && total_issued < totalWidth &&
+ while (total_issued < totalWidth &&
order_it != order_end_it) {
OpClass op_class = (*order_it).queueType;
@@ -733,8 +744,9 @@ InstructionQueue<Impl>::scheduleReadyInsts()
if (idx == -2 || idx != -1) {
if (op_latency == 1) {
- i2e_info->insts[exec_queue_slot++] = issuing_inst;
+// i2e_info->insts[exec_queue_slot++] = issuing_inst;
i2e_info->size++;
+ instsToExecute.push_back(issuing_inst);
// Add the FU onto the list of FU's to be freed next
// cycle if we used one.
diff --git a/cpu/ozone/cpu.hh b/cpu/ozone/cpu.hh
index 7e12e75e5..5af2b02b2 100644
--- a/cpu/ozone/cpu.hh
+++ b/cpu/ozone/cpu.hh
@@ -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;
diff --git a/cpu/ozone/cpu_impl.hh b/cpu/ozone/cpu_impl.hh
index 031b4b145..5675da3a8 100644
--- a/cpu/ozone/cpu_impl.hh
+++ b/cpu/ozone/cpu_impl.hh
@@ -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
diff --git a/cpu/ozone/dyn_inst.hh b/cpu/ozone/dyn_inst.hh
index f251c28ea..5d48bb361 100644
--- a/cpu/ozone/dyn_inst.hh
+++ b/cpu/ozone/dyn_inst.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005 The Regents of The University of Michigan
+ * Copyright (c) 2005-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -52,8 +52,6 @@ class OzoneDynInst : public BaseDynInst<Impl>
// Typedef for DynInstPtr. This is really just a RefCountingPtr<OoODynInst>.
typedef typename Impl::DynInstPtr DynInstPtr;
-// typedef typename Impl::BranchPred::BPredInfo BPredInfo;
-
typedef TheISA::ExtMachInst ExtMachInst;
typedef TheISA::MachInst MachInst;
typedef TheISA::MiscReg MiscReg;
@@ -107,12 +105,6 @@ class OzoneDynInst : public BaseDynInst<Impl>
// up. In the future, you only really need a counter.
bool memDepReady() { return srcMemInsts.empty(); }
-// void setBPredInfo(const BPredInfo &bp_info) { bpInfo = bp_info; }
-
-// BPredInfo &getBPredInfo() { return bpInfo; }
-
-// OzoneXC *thread;
-
private:
void initInstPtrs();
@@ -133,20 +125,12 @@ class OzoneDynInst : public BaseDynInst<Impl>
*/
DynInstPtr prevDestInst[MaxInstSrcRegs];
-// BPredInfo bpInfo;
-
public:
Fault initiateAcc();
Fault completeAcc();
-/*
- template <class T>
- Fault read(Addr addr, T &data, unsigned flags);
- template <class T>
- Fault write(T data, Addr addr, unsigned flags, uint64_t *res);
-*/
// The register accessor methods provide the index of the
// instruction's operand (e.g., 0 or 1), not the architectural
// register index, to simplify the implementation of register
@@ -244,38 +228,4 @@ class OzoneDynInst : public BaseDynInst<Impl>
bool iqItValid;
};
-/*
-template<class Impl>
-template<class T>
-inline Fault
-OzoneDynInst<Impl>::read(Addr addr, T &data, unsigned flags)
-{
- Fault fault = this->cpu->read(addr, data, flags, this);
-
- if (this->traceData) {
- this->traceData->setAddr(addr);
- this->traceData->setData(data);
- }
-
- return fault;
-}
-
-template<class Impl>
-template<class T>
-inline Fault
-OzoneDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res)
-{
- Fault fault = this->cpu->write(data, addr, flags, res, this);
-
- this->storeSize = sizeof(T);
- this->storeData = data;
-
- if (this->traceData) {
- this->traceData->setAddr(addr);
- this->traceData->setData(data);
- }
-
- return fault;
-}
-*/
#endif // __CPU_OZONE_DYN_INST_HH__
diff --git a/cpu/ozone/dyn_inst_impl.hh b/cpu/ozone/dyn_inst_impl.hh
index a7e4460a1..f891ec515 100644
--- a/cpu/ozone/dyn_inst_impl.hh
+++ b/cpu/ozone/dyn_inst_impl.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005 The Regents of The University of Michigan
+ * Copyright (c) 2005-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -266,12 +266,7 @@ OzoneDynInst<Impl>::hwrei()
this->setNextPC(this->thread->readMiscReg(AlphaISA::IPR_EXC_ADDR));
this->cpu->hwrei();
-/*
- this->cpu->kernelStats->hwrei();
- this->cpu->checkInterrupts = true;
- this->cpu->lockFlag = false;
-*/
// FIXME: XXX check for interrupts? XXX
return NoFault;
}
diff --git a/cpu/ozone/front_end.hh b/cpu/ozone/front_end.hh
index 326f7d2c9..dd382491f 100644
--- a/cpu/ozone/front_end.hh
+++ b/cpu/ozone/front_end.hh
@@ -1,14 +1,39 @@
+/*
+ * 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_OZONE_FRONT_END_HH__
#define __CPU_OZONE_FRONT_END_HH__
#include <deque>
-//#include "cpu/ozone/cpu.hh"
#include "cpu/inst_seq.hh"
#include "cpu/o3/bpred_unit.hh"
#include "cpu/ozone/rename_table.hh"
-//#include "cpu/ozone/thread_state.hh"
#include "mem/mem_req.hh"
#include "sim/eventq.hh"
#include "sim/stats.hh"
@@ -132,11 +157,6 @@ class FrontEnd
typedef typename Impl::BranchPred BranchPred;
- // Typedef for semi-opaque type that holds any information the branch
- // predictor needs to update itself. Only two fields are used outside of
- // branch predictor, nextPC and isTaken.
-// typedef typename BranchPred::BPredInfo BPredInfo;
-
BranchPred branchPred;
class ICacheCompletionEvent : public Event
diff --git a/cpu/ozone/front_end_impl.hh b/cpu/ozone/front_end_impl.hh
index cd57aeef4..15adae9b4 100644
--- a/cpu/ozone/front_end_impl.hh
+++ b/cpu/ozone/front_end_impl.hh
@@ -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.
+ */
#include "arch/faults.hh"
#include "arch/isa_traits.hh"
@@ -26,14 +53,6 @@ FrontEnd<Impl>::FrontEnd(Params *params)
status = Idle;
- // Setup branch predictor.
-
- // Setup Memory Request
-/*
- memReq = new MemReq();
- memReq->asid = 0;
- memReq->data = new uint8_t[64];
-*/
memReq = NULL;
// Size of cache block.
cacheBlkSize = icacheInterface ? icacheInterface->getBlockSize() : 64;
@@ -77,7 +96,6 @@ void
FrontEnd<Impl>::setXC(ExecContext *xc_ptr)
{
xc = xc_ptr;
-// memReq->xc = xc;
}
template <class Impl>
@@ -321,7 +339,6 @@ FrontEnd<Impl>::tick()
break;
}
- // if (generalizeFetch) {
processInst(inst);
if (status == SerializeBlocked) {
@@ -333,11 +350,6 @@ FrontEnd<Impl>::tick()
instBuffer.push_back(inst);
++instBufferSize;
++num_inst;
- // } else {
- // fetch(num_inst);
- // decode(num_inst);
- // rename(num_inst);
- // }
#if FULL_SYSTEM
if (inst->isQuiesce()) {
@@ -402,10 +414,6 @@ FrontEnd<Impl>::fetchCacheLine()
// Translate the instruction request.
fault = cpu->translateInstReq(memReq);
- // In the case of faults, the fetch stage may need to stall and wait
- // on what caused the fetch (ITB or Icache miss).
-// assert(fault == NoFault);
-
// Now do the timing access to see whether or not the instruction
// exists within the cache.
if (icacheInterface && fault == NoFault) {
@@ -466,7 +474,6 @@ FrontEnd<Impl>::processInst(DynInstPtr &inst)
Addr inst_PC = inst->readPC();
-// BPredInfo bp_info = branchPred.lookup(inst_PC);
if (!inst->isControl()) {
inst->setPredTarg(inst->readNextPC());
} else {
@@ -482,7 +489,6 @@ FrontEnd<Impl>::processInst(DynInstPtr &inst)
"%#x\n", inst->seqNum, inst_PC, next_PC);
// inst->setNextPC(next_PC);
-// inst->setBPredInfo(bp_info);
// Not sure where I should set this
PC = next_PC;
@@ -535,7 +541,7 @@ void
FrontEnd<Impl>::handleFault(Fault &fault)
{
DPRINTF(FE, "Fault at fetch, telling commit\n");
-// backEnd->fetchFault(fault);
+
// We're blocked on the back end until it handles this fault.
status = TrapPending;
@@ -586,9 +592,6 @@ FrontEnd<Impl>::squash(const InstSeqNum &squash_num, const Addr &next_PC,
instBuffer.pop_back();
--instBufferSize;
- // Fix up branch predictor if necessary.
-// branchPred.undo(inst->getBPredInfo());
-
freeRegs+= inst->numDestRegs();
}
@@ -607,7 +610,6 @@ FrontEnd<Impl>::squash(const InstSeqNum &squash_num, const Addr &next_PC,
// Clear the icache miss if it's outstanding.
if (status == IcacheMissStall && icacheInterface) {
DPRINTF(FE, "Squashing outstanding Icache miss.\n");
-// icacheInterface->squash(0);
memReq = NULL;
}
@@ -693,17 +695,9 @@ template <class Impl>
bool
FrontEnd<Impl>::updateStatus()
{
-// bool rename_block = freeRegs <= 0;
bool serialize_block = !backEnd->robEmpty() || instBufferSize;
bool be_block = cpu->decoupledFrontEnd ? false : backEnd->isBlocked();
bool ret_val = false;
-/*
- // Should already be handled through addFreeRegs function
- if (status == RenameBlocked && !rename_block) {
- status = Running;
- ret_val = true;
- }
-*/
if (status == SerializeBlocked && !serialize_block) {
status = SerializeComplete;
@@ -753,10 +747,6 @@ FrontEnd<Impl>::getInstFromCacheline()
// PC of inst is not in this cache block
if (PC >= (cacheBlkPC + cacheBlkSize) || PC < cacheBlkPC || !cacheBlkValid) {
-// DPRINTF(OoOCPU, "OoOCPU: PC is not in this cache block\n");
-// DPRINTF(OoOCPU, "OoOCPU: PC: %#x, cacheBlkPC: %#x, cacheBlkValid: %i",
-// PC, cacheBlkPC, cacheBlkValid);
-// panic("Instruction not in cache line or cache line invalid!");
return NULL;
}
diff --git a/cpu/ozone/lw_back_end.hh b/cpu/ozone/lw_back_end.hh
index 770b66ad5..1c03ffb73 100644
--- a/cpu/ozone/lw_back_end.hh
+++ b/cpu/ozone/lw_back_end.hh
@@ -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_OZONE_LW_BACK_END_HH__
#define __CPU_OZONE_LW_BACK_END_HH__
@@ -238,10 +265,6 @@ class LWBackEnd
Counter funcExeInst;
private:
-// typedef typename Impl::InstQueue InstQueue;
-
-// InstQueue IQ;
-
typedef typename Impl::LdstQueue LdstQueue;
LdstQueue LSQ;
@@ -342,8 +365,6 @@ class LWBackEnd
bool exactFullStall;
-// bool fetchRedirect[Impl::MaxThreads];
-
// number of cycles stalled for D-cache misses
/* Stats::Scalar<> dcacheStallCycles;
Counter lastDcacheStall;
@@ -438,43 +459,6 @@ template <class T>
Fault
LWBackEnd<Impl>::read(MemReqPtr &req, T &data, int load_idx)
{
-/* memReq->reset(addr, sizeof(T), flags);
-
- // translate to physical address
- Fault fault = cpu->translateDataReadReq(memReq);
-
- // if we have a cache, do cache access too
- if (fault == NoFault && dcacheInterface) {
- memReq->cmd = Read;
- memReq->completionEvent = NULL;
- memReq->time = curTick;
- memReq->flags &= ~INST_READ;
- MemAccessResult result = dcacheInterface->access(memReq);
-
- // Ugly hack to get an event scheduled *only* if the access is
- // a miss. We really should add first-class support for this
- // at some point.
- if (result != MA_HIT && dcacheInterface->doEvents()) {
- // Fix this hack for keeping funcExeInst correct with loads that
- // are executed twice.
- --funcExeInst;
-
- memReq->completionEvent = &cacheCompletionEvent;
- lastDcacheStall = curTick;
-// unscheduleTickEvent();
-// status = DcacheMissStall;
- DPRINTF(OzoneCPU, "Dcache miss stall!\n");
- } else {
- // do functional access
- fault = thread->mem->read(memReq, data);
-
- }
- }
-*/
-/*
- if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
- recordEvent("Uncached Read");
-*/
return LSQ.read(req, data, load_idx);
}
@@ -483,39 +467,6 @@ template <class T>
Fault
LWBackEnd<Impl>::write(MemReqPtr &req, T &data, int store_idx)
{
-/*
- memReq->reset(addr, sizeof(T), flags);
-
- // translate to physical address
- Fault fault = cpu->translateDataWriteReq(memReq);
-
- if (fault == NoFault && dcacheInterface) {
- memReq->cmd = Write;
- memcpy(memReq->data,(uint8_t *)&data,memReq->size);
- memReq->completionEvent = NULL;
- memReq->time = curTick;
- memReq->flags &= ~INST_READ;
- MemAccessResult result = dcacheInterface->access(memReq);
-
- // Ugly hack to get an event scheduled *only* if the access is
- // a miss. We really should add first-class support for this
- // at some point.
- if (result != MA_HIT && dcacheInterface->doEvents()) {
- memReq->completionEvent = &cacheCompletionEvent;
- lastDcacheStall = curTick;
-// unscheduleTickEvent();
-// status = DcacheMissStall;
- DPRINTF(OzoneCPU, "Dcache miss stall!\n");
- }
- }
-
- if (res && (fault == NoFault))
- *res = memReq->result;
- */
-/*
- if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
- recordEvent("Uncached Write");
-*/
return LSQ.write(req, data, store_idx);
}
diff --git a/cpu/ozone/lw_back_end_impl.hh b/cpu/ozone/lw_back_end_impl.hh
index db0872e52..881d6e6b1 100644
--- a/cpu/ozone/lw_back_end_impl.hh
+++ b/cpu/ozone/lw_back_end_impl.hh
@@ -1,7 +1,34 @@
+/*
+ * 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.
+ */
-#include "encumbered/cpu/full/op_class.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/ozone/lw_back_end.hh"
+#include "encumbered/cpu/full/op_class.hh"
template <class Impl>
void
@@ -194,7 +221,6 @@ LWBackEnd<Impl>::LWBackEnd(Params *params)
switchedOut = false;
switchPending = false;
-// IQ.setBE(this);
LSQ.setBE(this);
// Setup IQ and LSQ with their parameters here.
@@ -202,8 +228,6 @@ LWBackEnd<Impl>::LWBackEnd(Params *params)
instsToExecute = i2e.getWire(-1);
-// IQ.setIssueExecQueue(&i2e);
-
dispatchWidth = params->dispatchWidth ? params->dispatchWidth : width;
issueWidth = params->issueWidth ? params->issueWidth : width;
wbWidth = params->wbWidth ? params->wbWidth : width;
@@ -538,8 +562,6 @@ LWBackEnd<Impl>::regStats()
.desc("ROB Occupancy per cycle")
.flags(total | cdf)
;
-
-// IQ.regStats();
}
template <class Impl>
@@ -652,17 +674,7 @@ LWBackEnd<Impl>::tick()
squashFromTrap();
} else if (xcSquash) {
squashFromXC();
- } /*else if (fetchHasFault && robEmpty() && frontEnd->isEmpty() && !LSQ.hasStoresToWB()) {
- DPRINTF(BE, "ROB and front end empty, handling fetch fault\n");
- Fault fetch_fault = frontEnd->getFault();
- if (fetch_fault == NoFault) {
- DPRINTF(BE, "Fetch no longer has a fault, cancelling out.\n");
- fetchHasFault = false;
- } else {
- handleFault(fetch_fault);
- fetchHasFault = false;
- }
- }*/
+ }
#endif
if (dispatchStatus != Blocked) {
@@ -773,7 +785,8 @@ LWBackEnd<Impl>::dispatchInsts()
inst->iqItValid = true;
waitingInsts++;
} else {
- DPRINTF(BE, "Instruction [sn:%lli] ready, addding to exeList.\n",
+ DPRINTF(BE, "Instruction [sn:%lli] ready, addding to "
+ "exeList.\n",
inst->seqNum);
exeList.push(inst);
}
@@ -784,7 +797,8 @@ LWBackEnd<Impl>::dispatchInsts()
inst->setExecuted();
inst->setCanCommit();
} else {
- DPRINTF(BE, "Instruction [sn:%lli] ready, addding to exeList.\n",
+ DPRINTF(BE, "Instruction [sn:%lli] ready, addding to "
+ "exeList.\n",
inst->seqNum);
exeList.push(inst);
}
@@ -993,7 +1007,7 @@ LWBackEnd<Impl>::instToCommit(DynInstPtr &inst)
writeback_count[0]++;
}
-
+#if 0
template <class Impl>
void
LWBackEnd<Impl>::writebackInsts()
@@ -1040,7 +1054,7 @@ LWBackEnd<Impl>::writebackInsts()
consumer_inst[0]+= consumer_insts;
writeback_count[0]+= inst_num;
}
-
+#endif
template <class Impl>
bool
LWBackEnd<Impl>::commitInst(int inst_num)
@@ -1219,15 +1233,15 @@ LWBackEnd<Impl>::commitInst(int inst_num)
--numInsts;
++thread->funcExeInst;
- // Maybe move this to where the fault is handled; if the fault is handled,
- // don't try to set this myself as the fault will set it. If not, then
- // I set thread->PC = thread->nextPC and thread->nextPC = thread->nextPC + 4.
+ // Maybe move this to where the fault is handled; if the fault is
+ // handled, don't try to set this myself as the fault will set it.
+ // If not, then I set thread->PC = thread->nextPC and
+ // thread->nextPC = thread->nextPC + 4.
thread->setPC(thread->readNextPC());
thread->setNextPC(thread->readNextPC() + sizeof(TheISA::MachInst));
updateComInstStats(inst);
// Write the done sequence number here.
-// LSQ.commitLoads(inst->seqNum);
toIEW->doneSeqNum = inst->seqNum;
lastCommitCycle = curTick;
@@ -1357,7 +1371,8 @@ LWBackEnd<Impl>::squash(const InstSeqNum &sn)
}
while (memBarrier && memBarrier->seqNum > sn) {
- DPRINTF(BE, "[sn:%lli] Memory barrier squashed (or previously squashed)\n", memBarrier->seqNum);
+ DPRINTF(BE, "[sn:%lli] Memory barrier squashed (or previously "
+ "squashed)\n", memBarrier->seqNum);
memBarrier->clearMemDependents();
if (memBarrier->memDepReady()) {
DPRINTF(BE, "No previous barrier\n");
diff --git a/cpu/ozone/lw_lsq.hh b/cpu/ozone/lw_lsq.hh
index 042610324..6fe343b42 100644
--- a/cpu/ozone/lw_lsq.hh
+++ b/cpu/ozone/lw_lsq.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -138,7 +138,6 @@ class OzoneLWLSQ {
/** Executes a load instruction. */
Fault executeLoad(DynInstPtr &inst);
-// Fault executeLoad(int lq_idx);
/** Executes a store instruction. */
Fault executeStore(DynInstPtr &inst);
@@ -304,10 +303,8 @@ class OzoneLWLSQ {
Status _status;
/** The store queue. */
-// std::vector<SQEntry> storeQueue;
std::list<SQEntry> storeQueue;
/** The load queue. */
-// std::vector<DynInstPtr> loadQueue;
std::list<DynInstPtr> loadQueue;
typedef typename std::list<SQEntry>::iterator SQIt;
@@ -365,7 +362,6 @@ class OzoneLWLSQ {
*/
InstSeqNum stallingStoreIsn;
/** The index of the above store. */
-// int stallingLoadIdx;
LQIt stallingLoad;
/** Whether or not a load is blocked due to the memory system. It is
@@ -398,8 +394,6 @@ class OzoneLWLSQ {
template <class T>
Fault write(MemReqPtr &req, T &data, int store_idx);
- /** Returns the index of the head load instruction. */
-// int getLoadHead() { return loadHead; }
/** Returns the sequence number of the head load instruction. */
InstSeqNum getLoadHeadSeqNum()
{
@@ -411,8 +405,6 @@ class OzoneLWLSQ {
}
- /** Returns the index of the head store instruction. */
-// int getStoreHead() { return storeHead; }
/** Returns the sequence number of the head store instruction. */
InstSeqNum getStoreHeadSeqNum()
{
@@ -604,12 +596,7 @@ OzoneLWLSQ<Impl>::read(MemReqPtr &req, T &data, int load_idx)
DPRINTF(OzoneLSQ, "D-cache: PC:%#x reading from paddr:%#x "
"vaddr:%#x flags:%i\n",
inst->readPC(), req->paddr, req->vaddr, req->flags);
-/*
- Addr debug_addr = ULL(0xfffffc0000be81a8);
- if (req->vaddr == debug_addr) {
- debug_break();
- }
-*/
+
assert(!req->completionEvent);
req->completionEvent =
new typename BackEnd::LdWritebackEvent(inst, be);
@@ -631,9 +618,6 @@ OzoneLWLSQ<Impl>::read(MemReqPtr &req, T &data, int load_idx)
_status = DcacheMissStall;
} else {
-// DPRINTF(Activity, "Activity: ld accessing mem hit [sn:%lli]\n",
-// inst->seqNum);
-
DPRINTF(OzoneLSQ, "D-cache hit!\n");
}
} else {
@@ -664,12 +648,7 @@ OzoneLWLSQ<Impl>::write(MemReqPtr &req, T &data, int store_idx)
assert(!req->data);
req->data = new uint8_t[64];
memcpy(req->data, (uint8_t *)&(*sq_it).data, req->size);
-/*
- Addr debug_addr = ULL(0xfffffc0000be81a8);
- if (req->vaddr == debug_addr) {
- debug_break();
- }
-*/
+
// This function only writes the data to the store queue, so no fault
// can happen here.
return NoFault;
diff --git a/cpu/ozone/lw_lsq_impl.hh b/cpu/ozone/lw_lsq_impl.hh
index fdf6bff07..2f85a0396 100644
--- a/cpu/ozone/lw_lsq_impl.hh
+++ b/cpu/ozone/lw_lsq_impl.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -104,12 +104,6 @@ OzoneLWLSQ<Impl>::init(Params *params, unsigned maxLQEntries,
SQIndices.push(i);
}
- // May want to initialize these entries to NULL
-
-// loadHead = loadTail = 0;
-
-// storeHead = storeWBIdx = storeTail = 0;
-
usedPorts = 0;
cachePorts = params->cachePorts;
@@ -197,8 +191,6 @@ OzoneLWLSQ<Impl>::insert(DynInstPtr &inst)
} else {
insertStore(inst);
}
-
-// inst->setInLSQ();
}
template <class Impl>
@@ -569,12 +561,9 @@ OzoneLWLSQ<Impl>::writebackStores()
}
if (result != MA_HIT && dcacheInterface->doEvents()) {
-// Event *wb = NULL;
store_event->miss = true;
typename BackEnd::LdWritebackEvent *wb = NULL;
if (req->flags & LOCKED) {
- // Stx_C does not generate a system port transaction.
-// req->result=1;
wb = new typename BackEnd::LdWritebackEvent(inst,
be);
store_event->wbEvent = wb;
@@ -585,8 +574,6 @@ OzoneLWLSQ<Impl>::writebackStores()
// DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n",
// inst->seqNum);
- // Will stores need their own kind of writeback events?
- // Do stores even need writeback events?
be->addDcacheMiss(inst);
lastDcacheStall = curTick;
@@ -604,20 +591,16 @@ OzoneLWLSQ<Impl>::writebackStores()
// inst->seqNum);
if (req->flags & LOCKED) {
- // Stx_C does not generate a system port transaction.
-/* if (req->flags & UNCACHEABLE) {
- req->result = 2;
- } else {
- req->result = 1;
- }
-*/
+ // Stx_C does not generate a system port
+ // transaction in the 21264, but that might be
+ // hard to accomplish in this model.
+
typename BackEnd::LdWritebackEvent *wb =
new typename BackEnd::LdWritebackEvent(inst,
be);
store_event->wbEvent = wb;
}
sq_it--;
-// completeStore(inst->sqIdx);
}
} else {
panic("Must HAVE DCACHE!!!!!\n");
@@ -780,7 +763,7 @@ OzoneLWLSQ<Impl>::completeStore(int store_idx)
SQIndices.push(inst->sqIdx);
storeQueue.erase(sq_it);
--stores;
-// assert(!inst->isCompleted());
+
inst->setCompleted();
if (cpu->checker) {
cpu->checker->tick(inst);
@@ -791,7 +774,6 @@ template <class Impl>
void
OzoneLWLSQ<Impl>::switchOut()
{
-// assert(loads == 0);
assert(storesToWB == 0);
switchedOut = true;
SQIt sq_it = --(storeQueue.end());
@@ -804,8 +786,6 @@ OzoneLWLSQ<Impl>::switchOut()
if ((*sq_it).size == 0 && !(*sq_it).completed) {
sq_it--;
-// completeStore(inst->sqIdx);
-
continue;
}
@@ -817,7 +797,8 @@ OzoneLWLSQ<Impl>::switchOut()
continue;
} else if ((*sq_it).req->flags & LOCKED) {
sq_it--;
- assert(!(*sq_it).canWB || ((*sq_it).canWB && (*sq_it).req->flags & LOCKED));
+ assert(!(*sq_it).canWB ||
+ ((*sq_it).canWB && (*sq_it).req->flags & LOCKED));
continue;
}
@@ -886,12 +867,6 @@ OzoneLWLSQ<Impl>::takeOverFrom(ExecContext *old_xc)
SQIndices.push(i);
}
- // May want to initialize these entries to NULL
-
-// loadHead = loadTail = 0;
-
-// storeHead = storeWBIdx = storeTail = 0;
-
usedPorts = 0;
loadFaultInst = storeFaultInst = memDepViolator = NULL;
diff --git a/cpu/ozone/rename_table.hh b/cpu/ozone/rename_table.hh
index afbf6ff32..6ee23b21b 100644
--- a/cpu/ozone/rename_table.hh
+++ b/cpu/ozone/rename_table.hh
@@ -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_OZONE_RENAME_TABLE_HH__
#define __CPU_OZONE_RENAME_TABLE_HH__
diff --git a/cpu/ozone/thread_state.hh b/cpu/ozone/thread_state.hh
index 269fc6459..c86c3a720 100644
--- a/cpu/ozone/thread_state.hh
+++ b/cpu/ozone/thread_state.hh
@@ -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_OZONE_THREAD_STATE_HH__
#define __CPU_OZONE_THREAD_STATE_HH__
@@ -62,19 +89,14 @@ struct OzoneThreadState : public ThreadState {
void setStatus(Status new_status) { _status = new_status; }
- RenameTable<Impl> renameTable; // Should I include backend and frontend
- // tables here? For the ozone CPU, maybe, for the new full CPU, probably
- // not...you wouldn't want threads just accessing the backend/frontend
- // rename tables.
- Addr PC; // What should these be set to? Probably the committed ones.
+ RenameTable<Impl> renameTable;
+ Addr PC;
Addr nextPC;
- // Current instruction?
+ // Current instruction
TheISA::MachInst inst;
TheISA::RegFile regs;
- // Front end? Back end?
-// MemReqPtr memReq;
typename Impl::FullCPU *cpu;
diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc
index 07f9d0dad..c03945ffa 100644
--- a/cpu/simple/cpu.cc
+++ b/cpu/simple/cpu.cc
@@ -782,7 +782,7 @@ SimpleCPU::tick()
#if FULL_SYSTEM
if (system->kernelBinning->fnbin) {
- assert(kernelStats);
+ assert(cpuXC->getKernelStats());
system->kernelBinning->execute(xcProxy, inst);
}
diff --git a/cpu/thread_state.hh b/cpu/thread_state.hh
index e8381b9d3..e09cb12fd 100644
--- a/cpu/thread_state.hh
+++ b/cpu/thread_state.hh
@@ -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;
diff --git a/kern/system_events.cc b/kern/system_events.cc
index 9b9861497..221eb228d 100644
--- a/kern/system_events.cc
+++ b/kern/system_events.cc
@@ -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);
}
diff --git a/sim/pseudo_inst.cc b/sim/pseudo_inst.cc
index 4d9541b58..0c20a6a53 100644
--- a/sim/pseudo_inst.cc
+++ b/sim/pseudo_inst.cc
@@ -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