summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
authorLisa Hsu <hsul@eecs.umich.edu>2004-03-11 18:52:29 -0500
committerLisa Hsu <hsul@eecs.umich.edu>2004-03-11 18:52:29 -0500
commit3bc8cffc75c2e03a6a8fe5f4425940a16405f672 (patch)
tree1d44dba1a7dbd4aef6fad45753b7607928d3414a /cpu
parent1039028d408d5a374a67d8d3ecc640a0e6559fbb (diff)
parent2c60d7aa9e4b48f30ab8c48436ff2dfec8e390f2 (diff)
downloadgem5-3bc8cffc75c2e03a6a8fe5f4425940a16405f672.tar.xz
merge with m5 head
--HG-- extra : convert_revision : c90339248d1ee74df1c6b90a77ec9ea41f646311
Diffstat (limited to 'cpu')
-rw-r--r--cpu/base_cpu.cc6
-rw-r--r--cpu/exec_context.cc63
-rw-r--r--cpu/exec_context.hh18
-rw-r--r--cpu/memtest/memtest.cc32
-rw-r--r--cpu/simple_cpu/simple_cpu.cc97
-rw-r--r--cpu/simple_cpu/simple_cpu.hh15
-rw-r--r--cpu/static_inst.hh2
7 files changed, 174 insertions, 59 deletions
diff --git a/cpu/base_cpu.cc b/cpu/base_cpu.cc
index bba31303b..73fb3e7fa 100644
--- a/cpu/base_cpu.cc
+++ b/cpu/base_cpu.cc
@@ -184,6 +184,12 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
newXC->process->replaceExecContext(newXC->cpu_id, newXC);
#endif
}
+
+#ifdef FULL_SYSTEM
+ for (int i = 0; i < NumInterruptLevels; ++i)
+ interrupts[i] = oldCPU->interrupts[i];
+ intstatus = oldCPU->intstatus;
+#endif
}
diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc
index 6a5f463cd..eedd8b8a8 100644
--- a/cpu/exec_context.cc
+++ b/cpu/exec_context.cc
@@ -48,10 +48,7 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
kernelStats(this, _cpu), cpu(_cpu), thread_num(_thread_num),
cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys),
memCtrl(_sys->memCtrl), physmem(_sys->physmem),
-#ifdef FS_MEASURE
- swCtx(NULL),
-#endif
- func_exe_inst(0), storeCondFailures(0)
+ swCtx(NULL), func_exe_inst(0), storeCondFailures(0)
{
memset(&regs, 0, sizeof(RegFile));
}
@@ -107,6 +104,33 @@ ExecContext::serialize(ostream &os)
regs.serialize(os);
// thread_num and cpu_id are deterministic from the config
SERIALIZE_SCALAR(func_exe_inst);
+
+#ifdef FULL_SYSTEM
+ bool ctx = false;
+ if (swCtx) {
+ ctx = true;
+ SERIALIZE_SCALAR(ctx);
+ SERIALIZE_SCALAR(swCtx->calls);
+ std::stack<fnCall *> *stack = &(swCtx->callStack);
+ fnCall *top;
+ int size = stack->size();
+ SERIALIZE_SCALAR(size);
+
+ for (int j=0; j<size; ++j) {
+ top = stack->top();
+ paramOut(os, csprintf("stackpos[%d]",j), top->name);
+ delete top;
+ stack->pop();
+ }
+ } else {
+ SERIALIZE_SCALAR(ctx);
+ }
+ if (system->bin) {
+ Statistics::MainBin *cur = Statistics::MainBin::curBin();
+ string bin_name = cur->name();
+ SERIALIZE_SCALAR(bin_name);
+ }
+#endif //FULL_SYSTEM
}
@@ -117,6 +141,37 @@ ExecContext::unserialize(Checkpoint *cp, const std::string &section)
regs.unserialize(cp, section);
// thread_num and cpu_id are deterministic from the config
UNSERIALIZE_SCALAR(func_exe_inst);
+
+#ifdef FULL_SYSTEM
+ bool ctx;
+ UNSERIALIZE_SCALAR(ctx);
+ if (ctx) {
+ swCtx = new SWContext;
+ UNSERIALIZE_SCALAR(swCtx->calls);
+ int size;
+ UNSERIALIZE_SCALAR(size);
+
+ vector<fnCall *> calls;
+ fnCall *call;
+ for (int i=0; i<size; ++i) {
+ call = new fnCall;
+ paramIn(cp, section, csprintf("stackpos[%d]",i), call->name);
+ call->myBin = system->getBin(call->name);
+ calls.push_back(call);
+ }
+
+ for (int i=size-1; i>=0; --i) {
+ swCtx->callStack.push(calls[i]);
+ }
+
+ }
+
+ if (system->bin) {
+ string bin_name;
+ UNSERIALIZE_SCALAR(bin_name);
+ system->getBin(bin_name)->activate();
+ }
+#endif //FULL_SYSTEM
}
diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh
index e9dc5efec..a72516ac7 100644
--- a/cpu/exec_context.hh
+++ b/cpu/exec_context.hh
@@ -45,10 +45,7 @@ class MemoryController;
#include "kern/tru64/kernel_stats.hh"
#include "sim/system.hh"
-
-#ifdef FS_MEASURE
#include "sim/sw_context.hh"
-#endif
#else // !FULL_SYSTEM
@@ -137,10 +134,7 @@ class ExecContext
MemoryController *memCtrl;
PhysicalMemory *physmem;
-#ifdef FS_MEASURE
SWContext *swCtx;
-#endif
-
#else
Process *process;
@@ -153,6 +147,18 @@ class ExecContext
#endif
+ /**
+ * Temporary storage to pass the source address from copy_load to
+ * copy_store.
+ * @todo Remove this temporary when we have a better way to do it.
+ */
+ Addr copySrcAddr;
+ /**
+ * Temp storage for the physical source address of a copy.
+ * @todo Remove this temporary when we have a better way to do it.
+ */
+ Addr copySrcPhysAddr;
+
/*
* number of executed instructions, for matching with syscall trace
diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc
index 82bec8ac9..051d9623a 100644
--- a/cpu/memtest/memtest.cc
+++ b/cpu/memtest/memtest.cc
@@ -131,7 +131,8 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data)
case Read:
if (memcmp(req->data, data, req->size) != 0) {
cerr << name() << ": on read of 0x" << hex << req->paddr
- << " @ cycle " << dec << curTick
+ << " (0x" << hex << blockAddr(req->paddr) << ")"
+ << "@ cycle " << dec << curTick
<< ", cache returns 0x";
printData(cerr, req->data, req->size);
cerr << ", expected 0x";
@@ -163,11 +164,13 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data)
}
if (blockAddr(req->paddr) == traceBlockAddr) {
- cerr << hex << traceBlockAddr << ": " << name() << ": completed "
+ cerr << name() << ": completed "
<< (req->cmd.isWrite() ? "write" : "read")
<< " access of "
<< dec << req->size << " bytes at address 0x"
- << hex << req->paddr << ", value = 0x";
+ << hex << req->paddr
+ << " (0x" << hex << blockAddr(req->paddr) << ")"
+ << ", value = 0x";
printData(cerr, req->data, req->size);
cerr << " @ cycle " << dec << curTick;
@@ -249,11 +252,13 @@ MemTest::tick()
uint8_t *result = new uint8_t[8];
checkMem->access(Read, req->paddr, result, req->size);
if (blockAddr(req->paddr) == traceBlockAddr) {
- cerr << hex << traceBlockAddr << ": " << name()
+ cerr << name()
<< ": initiating read "
<< ((probe)?"probe of ":"access of ")
<< dec << req->size << " bytes from addr 0x"
- << hex << req->paddr << " at cycle "
+ << hex << req->paddr
+ << " (0x" << hex << blockAddr(req->paddr) << ")"
+ << " at cycle "
<< dec << curTick << endl;
}
if (probe) {
@@ -269,13 +274,14 @@ MemTest::tick()
memcpy(req->data, &data, req->size);
checkMem->access(Write, req->paddr, req->data, req->size);
if (blockAddr(req->paddr) == traceBlockAddr) {
- cerr << hex << traceBlockAddr << ": "
- << name() << ": initiating write "
+ cerr << name() << ": initiating write "
<< ((probe)?"probe of ":"access of ")
<< dec << req->size << " bytes (value = 0x";
printData(cerr, req->data, req->size);
cerr << ") to addr 0x"
- << hex << req->paddr << " at cycle "
+ << hex << req->paddr
+ << " (0x" << hex << blockAddr(req->paddr) << ")"
+ << " at cycle "
<< dec << curTick << endl;
}
if (probe) {
@@ -303,11 +309,15 @@ MemTest::tick()
req->data = new uint8_t[blockSize];
req->size = blockSize;
if (source == traceBlockAddr || dest == traceBlockAddr) {
- cerr << hex << traceBlockAddr << ": " << name()
+ cerr << name()
<< ": initiating copy of "
<< dec << req->size << " bytes from addr 0x"
- << hex << source << " to addr 0x"
- << hex << dest << " at cycle "
+ << hex << source
+ << " (0x" << hex << blockAddr(source) << ")"
+ << " to addr 0x"
+ << hex << dest
+ << " (0x" << hex << blockAddr(dest) << ")"
+ << " at cycle "
<< dec << curTick << endl;
}
cacheInterface->access(req);
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc
index efbe66020..c2796efd0 100644
--- a/cpu/simple_cpu/simple_cpu.cc
+++ b/cpu/simple_cpu/simple_cpu.cc
@@ -120,7 +120,7 @@ SimpleCPU::SimpleCPU(const string &_name,
FunctionalMemory *mem,
MemInterface *icache_interface,
MemInterface *dcache_interface,
- Tick freq)
+ bool _def_reg, Tick freq)
: BaseCPU(_name, /* number_of_threads */ 1,
max_insts_any_thread, max_insts_all_threads,
max_loads_any_thread, max_loads_all_threads,
@@ -132,12 +132,14 @@ SimpleCPU::SimpleCPU(const string &_name, Process *_process,
Counter max_loads_any_thread,
Counter max_loads_all_threads,
MemInterface *icache_interface,
- MemInterface *dcache_interface)
+ MemInterface *dcache_interface,
+ bool _def_reg)
: BaseCPU(_name, /* number_of_threads */ 1,
max_insts_any_thread, max_insts_all_threads,
max_loads_any_thread, max_loads_all_threads),
#endif
- tickEvent(this), xc(NULL), cacheCompletionEvent(this)
+ tickEvent(this), xc(NULL), defer_registration(_def_reg),
+ cacheCompletionEvent(this)
{
_status = Idle;
#ifdef FULL_SYSTEM
@@ -171,6 +173,13 @@ SimpleCPU::~SimpleCPU()
{
}
+void SimpleCPU::init()
+{
+ if (!defer_registration) {
+ this->registerExecContexts();
+ }
+}
+
void
SimpleCPU::switchOut()
{
@@ -318,6 +327,46 @@ change_thread_state(int thread_number, int activate, int priority)
{
}
+Fault
+SimpleCPU::copySrcTranslate(Addr src)
+{
+ memReq->reset(src, (dcacheInterface) ?
+ dcacheInterface->getBlockSize()
+ : 64);
+
+ // translate to physical address
+ Fault fault = xc->translateDataReadReq(memReq);
+
+ if (fault == No_Fault) {
+ xc->copySrcAddr = src;
+ xc->copySrcPhysAddr = memReq->paddr;
+ } else {
+ xc->copySrcAddr = 0;
+ xc->copySrcPhysAddr = 0;
+ }
+ return fault;
+}
+
+Fault
+SimpleCPU::copy(Addr dest)
+{
+ int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
+ uint8_t data[blk_size];
+ assert(xc->copySrcPhysAddr);
+ memReq->reset(dest, blk_size);
+ // translate to physical address
+ Fault fault = xc->translateDataWriteReq(memReq);
+ if (fault == No_Fault) {
+ Addr dest_addr = memReq->paddr;
+ // Need to read straight from memory since we have more than 8 bytes.
+ memReq->paddr = xc->copySrcPhysAddr;
+ xc->mem->read(memReq, data);
+ memReq->paddr = dest_addr;
+ xc->mem->write(memReq, data);
+ }
+ return fault;
+}
+
// precise architected memory state accessor macros
template <class T>
Fault
@@ -343,7 +392,6 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
memReq->cmd = Read;
memReq->completionEvent = NULL;
memReq->time = curTick;
- memReq->flags &= ~UNCACHEABLE;
MemAccessResult result = dcacheInterface->access(memReq);
// Ugly hack to get an event scheduled *only* if the access is
@@ -426,7 +474,6 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
memcpy(memReq->data,(uint8_t *)&data,memReq->size);
memReq->completionEvent = NULL;
memReq->time = curTick;
- memReq->flags &= ~UNCACHEABLE;
MemAccessResult result = dcacheInterface->access(memReq);
// Ugly hack to get an event scheduled *only* if the access is
@@ -629,7 +676,6 @@ SimpleCPU::tick()
memReq->completionEvent = NULL;
memReq->time = curTick;
- memReq->flags &= ~UNCACHEABLE;
MemAccessResult result = icacheInterface->access(memReq);
// Ugly hack to get an event scheduled *only* if the access is
@@ -669,32 +715,13 @@ SimpleCPU::tick()
xc->func_exe_inst++;
fault = si->execute(this, xc, traceData);
-#ifdef FS_MEASURE
- if (!(xc->misspeculating()) && (xc->system->bin)) {
- SWContext *ctx = xc->swCtx;
- if (ctx && !ctx->callStack.empty()) {
- if (si->isCall()) {
- ctx->calls++;
- }
- if (si->isReturn()) {
- if (ctx->calls == 0) {
- fnCall *top = ctx->callStack.top();
- DPRINTF(TCPIP, "Removing %s from callstack.\n", top->name);
- delete top;
- ctx->callStack.pop();
- if (ctx->callStack.empty())
- xc->system->nonPath->activate();
- else
- ctx->callStack.top()->myBin->activate();
-
- xc->system->dumpState(xc);
- } else {
- ctx->calls--;
- }
- }
- }
- }
+
+#ifdef FULL_SYSTEM
+ SWContext *ctx = xc->swCtx;
+ if (ctx)
+ ctx->process(xc, si.get());
#endif
+
if (si->isMemRef()) {
numMemRefs++;
}
@@ -813,6 +840,7 @@ CREATE_SIM_OBJECT(SimpleCPU)
itb, dtb, mem,
(icache) ? icache->getInterface() : NULL,
(dcache) ? dcache->getInterface() : NULL,
+ defer_registration,
ticksPerSecond * mult);
#else
@@ -820,14 +848,15 @@ CREATE_SIM_OBJECT(SimpleCPU)
max_insts_any_thread, max_insts_all_threads,
max_loads_any_thread, max_loads_all_threads,
(icache) ? icache->getInterface() : NULL,
- (dcache) ? dcache->getInterface() : NULL);
+ (dcache) ? dcache->getInterface() : NULL,
+ defer_registration);
#endif // FULL_SYSTEM
-
+#if 0
if (!defer_registration) {
cpu->registerExecContexts();
}
-
+#endif
return cpu;
}
diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh
index 16753fa4f..9edd66ab4 100644
--- a/cpu/simple_cpu/simple_cpu.hh
+++ b/cpu/simple_cpu/simple_cpu.hh
@@ -133,7 +133,7 @@ class SimpleCPU : public BaseCPU
Counter max_loads_any_thread, Counter max_loads_all_threads,
AlphaItb *itb, AlphaDtb *dtb, FunctionalMemory *mem,
MemInterface *icache_interface, MemInterface *dcache_interface,
- Tick freq);
+ bool _def_reg, Tick freq);
#else
@@ -142,11 +142,13 @@ class SimpleCPU : public BaseCPU
Counter max_insts_all_threads,
Counter max_loads_any_thread,
Counter max_loads_all_threads,
- MemInterface *icache_interface, MemInterface *dcache_interface);
+ MemInterface *icache_interface, MemInterface *dcache_interface,
+ bool _def_reg);
#endif
virtual ~SimpleCPU();
+ virtual void init();
// execution context
ExecContext *xc;
@@ -166,6 +168,8 @@ class SimpleCPU : public BaseCPU
// L1 data cache
MemInterface *dcacheInterface;
+ bool defer_registration;
+
// current instruction
MachInst inst;
@@ -233,16 +237,19 @@ class SimpleCPU : public BaseCPU
Fault write(T data, Addr addr, unsigned flags,
uint64_t *res);
- Fault prefetch(Addr addr, unsigned flags)
+ void prefetch(Addr addr, unsigned flags)
{
// need to do this...
- return No_Fault;
}
void writeHint(Addr addr, int size)
{
// need to do this...
}
+
+ Fault copySrcTranslate(Addr src);
+
+ Fault copy(Addr dest);
};
#endif // __SIMPLE_CPU_HH__
diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh
index 5f4bcae3d..cdf9aefa0 100644
--- a/cpu/static_inst.hh
+++ b/cpu/static_inst.hh
@@ -96,6 +96,7 @@ class StaticInstBase : public RefCounted
IsStore, ///< Writes to memory.
IsInstPrefetch, ///< Instruction-cache prefetch.
IsDataPrefetch, ///< Data-cache prefetch.
+ IsCopy, ///< Fast Cache block copy
IsControl, ///< Control transfer instruction.
IsDirectControl, ///< PC relative control transfer.
@@ -176,6 +177,7 @@ class StaticInstBase : public RefCounted
bool isStore() const { return flags[IsStore]; }
bool isInstPrefetch() const { return flags[IsInstPrefetch]; }
bool isDataPrefetch() const { return flags[IsDataPrefetch]; }
+ bool isCopy() const { return flags[IsCopy];}
bool isInteger() const { return flags[IsInteger]; }
bool isFloating() const { return flags[IsFloating]; }