diff options
35 files changed, 943 insertions, 676 deletions
diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 8494ee9f6..551cbdabf 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -237,10 +237,17 @@ ExecContext::readIpr(int idx, Fault &fault) retval = ipr[idx]; break; + case AlphaISA::IPR_CC: + retval |= ipr[idx] & ULL(0xffffffff00000000); + retval |= curTick & ULL(0x00000000ffffffff); + break; + case AlphaISA::IPR_VA: // SFX: unlocks interrupt status registers retval = ipr[idx]; - regs.intrlock = false; + + if (!misspeculating()) + regs.intrlock = false; break; case AlphaISA::IPR_VA_FORM: @@ -253,7 +260,7 @@ ExecContext::readIpr(int idx, Fault &fault) case AlphaISA::IPR_DTB_PTE: { - AlphaISA::PTE &pte = dtb->index(); + AlphaISA::PTE &pte = dtb->index(!misspeculating()); retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32; retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8; @@ -327,13 +334,25 @@ ExecContext::setIpr(int idx, uint64_t val) case AlphaISA::IPR_PAL_BASE: case AlphaISA::IPR_IC_PERR_STAT: case AlphaISA::IPR_DC_PERR_STAT: - case AlphaISA::IPR_CC_CTL: - case AlphaISA::IPR_CC: case AlphaISA::IPR_PMCTR: // write entire quad w/ no side-effect ipr[idx] = val; break; + case AlphaISA::IPR_CC_CTL: + // This IPR resets the cycle counter. We assume this only + // happens once... let's verify that. + assert(ipr[idx] == 0); + ipr[idx] = 1; + break; + + case AlphaISA::IPR_CC: + // This IPR only writes the upper 64 bits. It's ok to write + // all 64 here since we mask out the lower 32 in rpcc (see + // isa_desc). + ipr[idx] = val; + break; + case AlphaISA::IPR_PALtemp23: // write entire quad w/ no side-effect ipr[idx] = val; diff --git a/arch/alpha/isa_desc b/arch/alpha/isa_desc index 75b2f4138..0da087f97 100644 --- a/arch/alpha/isa_desc +++ b/arch/alpha/isa_desc @@ -5,7 +5,7 @@ let {{ global rcs_id - rcs_id = "$Id$" + rcs_id = "$Id: s.isa_desc 1.43 04/02/29 22:41:10-05:00 ehallnor@zazzer.eecs.umich.edu $" }}; @@ -1000,10 +1000,50 @@ def template PrefetchDeclare {{ */ class %(class_name)s : public %(base_class)s { + protected: + + /** + * "Fake" effective address computation class for "%(mnemonic)s". + */ + class EAComp : public EACompBase + { + public: + /// Constructor + EAComp(MachInst machInst) + : EACompBase(machInst) + { + %(ea_constructor)s; + } + }; + + /** + * "Fake" memory access instruction class for "%(mnemonic)s". + */ + class MemAcc : public MemAccBase + { + public: + /// Constructor + MemAcc(MachInst machInst) + : MemAccBase(machInst, %(op_class)s) + { + %(memacc_constructor)s; + } + }; + + /// Pointer to EAComp object. + StaticInstPtr<AlphaISA> eaCompPtr; + /// Pointer to MemAcc object. + StaticInstPtr<AlphaISA> memAccPtr; + public: + + StaticInstPtr<AlphaISA> eaCompInst() { return eaCompPtr; } + StaticInstPtr<AlphaISA> memAccInst() { return memAccPtr; } + /// Constructor %(class_name)s(MachInst machInst) - : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s), + eaCompPtr(new EAComp(machInst)), memAccPtr(new MemAcc(machInst)) { %(constructor)s; } @@ -1814,6 +1854,9 @@ decode OPCODE default Unknown::unknown() { 0x23: ldt({{ EA = Rb + disp; }}, {{ Fa = Mem.df; }}); 0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED); 0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED); + 0x20: copy_load({{EA = Ra;}}, + {{ fault = memAccessObj->copySrcTranslate(EA);}}, + IsMemRef, IsLoad, IsCopy); } format LoadOrPrefetch { @@ -1833,6 +1876,9 @@ decode OPCODE default Unknown::unknown() { 0x0f: stq_u({{ EA = (Rb + disp) & ~7; }}, {{ Mem.uq = Ra.uq; }}); 0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }}); 0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }}); + 0x24: copy_store({{EA = Rb;}}, + {{ fault = memAccessObj->copy(EA);}}, + IsMemRef, IsStore, IsCopy); } format StoreCond { @@ -2342,7 +2388,13 @@ decode OPCODE default Unknown::unknown() { } format BasicOperate { - 0xc000: rpcc({{ Ra = curTick; }}); + 0xc000: rpcc({{ +#ifdef FULL_SYSTEM + Ra = xc->readIpr(AlphaISA::IPR_CC, fault); +#else + Ra = curTick; +#endif + }}); // All of the barrier instructions below do nothing in // their execute() methods (hence the empty code blocks). diff --git a/arch/alpha/osfpal.cc b/arch/alpha/osfpal.cc index 4c0ace8c0..90d645ef1 100644 --- a/arch/alpha/osfpal.cc +++ b/arch/alpha/osfpal.cc @@ -224,8 +224,8 @@ namespace { 0, // 0xbc 0, // 0xbd "nphalt", // 0xbe + "copypal", // 0xbf #if 0 - 0, // 0xbf 0, // 0xc0 0, // 0xc1 0, // 0xc2 diff --git a/arch/alpha/osfpal.hh b/arch/alpha/osfpal.hh index 61e545306..419235b4a 100644 --- a/arch/alpha/osfpal.hh +++ b/arch/alpha/osfpal.hh @@ -70,6 +70,7 @@ struct PAL gentrap = 0xaa, clrfen = 0xae, nphalt = 0xbe, + copypal = 0xbf, NumCodes }; diff --git a/base/statistics.cc b/base/statistics.cc index 49294ad27..dce545f18 100644 --- a/base/statistics.cc +++ b/base/statistics.cc @@ -57,7 +57,7 @@ __nan() } #endif -#ifdef STAT_DEBUG +#ifdef DEBUG static int total_stats = 0; #endif @@ -409,6 +409,14 @@ DataAccess::setPrint() Database::StatDB().regPrint(this); } +StatData::StatData() + : flags(none), precision(-1), prereq(0) +{ +#ifdef DEBUG + number = total_stats++; +#endif +} + StatData::~StatData() { } @@ -443,8 +451,8 @@ bool StatData::baseCheck() const { if (!(flags & init)) { -#ifdef STAT_DEBUG - cprintf("this is stat number %d\n",(*i)->number); +#ifdef DEBUG + cprintf("this is stat number %d\n", number); #endif panic("Not all stats have been initialized"); return false; diff --git a/base/statistics.hh b/base/statistics.hh index d8b78fbff..0dad31a5a 100644 --- a/base/statistics.hh +++ b/base/statistics.hh @@ -60,12 +60,6 @@ #include "base/str.hh" #include "sim/host.hh" -// -// Un-comment this to enable weirdo-stat debugging -// -// #define STAT_DEBUG - - #ifndef NAN float __nan(); /** Define Not a number. */ @@ -146,10 +140,7 @@ struct StatData /** A pointer to a prerequisite Stat. */ const StatData *prereq; - StatData() - : flags(none), precision(-1), prereq(0) - {} - + StatData(); virtual ~StatData(); /** @@ -193,6 +184,10 @@ struct StatData * @return stat1's name is alphabetically before stat2's */ static bool less(StatData *stat1, StatData *stat2); + +#ifdef DEBUG + int number; +#endif }; struct ScalarDataBase : public StatData @@ -2503,7 +2498,7 @@ struct NoBin * binned. If the typedef is NoBin, nothing is binned. If it is * MainBin, then all stats are binned under that Bin. */ -#ifdef FS_MEASURE +#if defined(FS_MEASURE) typedef MainBin DefaultBin; #else typedef NoBin DefaultBin; diff --git a/base/trace.cc b/base/trace.cc index 156110376..e56bdb11b 100644 --- a/base/trace.cc +++ b/base/trace.cc @@ -208,8 +208,7 @@ PrintfRecord::dump(ostream &os) -RawDataRecord::RawDataRecord(Tick _cycle, - const uint8_t *_data, int _len) +RawDataRecord::RawDataRecord(Tick _cycle, const void *_data, int _len) : Record(_cycle), len(_len) { data = new uint8_t[len]; @@ -320,3 +319,66 @@ echoTrace(bool on) } } } + +extern "C" +void +printTraceFlags() +{ + using namespace Trace; + for (int i = 0; i < numFlagStrings; ++i) + if (flags[i]) + cprintf("%s\n", flagStrings[i]); +} + +void +tweakTraceFlag(const char *string, bool value) +{ + using namespace Trace; + std::string str(string); + + for (int i = 0; i < numFlagStrings; ++i) { + if (str != flagStrings[i]) + continue; + + int idx = i; + + if (idx < NumFlags) { + flags[idx] = value; + } else { + idx -= NumFlags; + if (idx >= NumCompoundFlags) { + ccprintf(cerr, "Invalid compound flag"); + return; + } + + const Flags *flagVec = compoundFlags[idx]; + + for (int j = 0; flagVec[j] != -1; ++j) { + if (flagVec[j] >= NumFlags) { + ccprintf(cerr, "Invalid compound flag"); + return; + } + flags[flagVec[j]] = value; + } + } + + cprintf("flag %s was %s\n", string, value ? "set" : "cleared"); + return; + } + + cprintf("could not find flag %s\n", string); +} + +extern "C" +void +setTraceFlag(const char *string) +{ + tweakTraceFlag(string, true); +} + +extern "C" +void +clearTraceFlag(const char *string) +{ + tweakTraceFlag(string, false); +} diff --git a/base/trace.hh b/base/trace.hh index 9e5952765..e49d7aa61 100644 --- a/base/trace.hh +++ b/base/trace.hh @@ -108,7 +108,7 @@ namespace Trace { int len; public: - RawDataRecord(Tick cycle, const uint8_t *_data, int _len); + RawDataRecord(Tick cycle, const void *_data, int _len); virtual ~RawDataRecord(); virtual void dump(std::ostream &); @@ -149,7 +149,7 @@ namespace Trace { } inline void - rawDump(const uint8_t *data, int len) + rawDump(const void *data, int len) { theLog.append(new Trace::RawDataRecord(curTick, data, len)); } 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(®s, 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 §ion) 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]; } diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index ad9d0a239..f592b239d 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -43,6 +43,9 @@ #include "dev/console.hh" #include "dev/simple_disk.hh" #include "dev/tlaser_clock.hh" +#include "mem/bus/bus.hh" +#include "mem/bus/pio_interface.hh" +#include "mem/bus/pio_interface_impl.hh" #include "mem/functional_mem/memory_control.hh" #include "sim/builder.hh" #include "sim/system.hh" @@ -50,14 +53,21 @@ using namespace std; -AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, - SimpleDisk *d, System *system, - BaseCPU *cpu, TsunamiIO *clock, int num_cpus, - Addr a, MemoryController *mmu) - : FunctionalMemory(name), disk(d), console(cons), addr(a) +AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, + System *system, BaseCPU *cpu, TsunamiIO *clock, + int num_cpus, MemoryController *mmu, Addr a, + HierParams *hier, Bus *bus) + : PioDevice(name), disk(d), console(cons), addr(a) +>>>>>>> { mmu->add_child(this, Range<Addr>(addr, addr + size)); + if (bus) { + pioInterface = newPioInterface(name, hier, bus, this, + &AlphaConsole::cacheAccess); + pioInterface->addAddrRange(addr, addr + size); + } + consoleData = new uint8_t[size]; memset(consoleData, 0, size); @@ -185,6 +195,12 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data) return No_Fault; } +Tick +AlphaConsole::cacheAccess(MemReqPtr &req) +{ + return curTick + 1000; +} + void AlphaAccess::serialize(ostream &os) { @@ -253,6 +269,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) SimObjectParam<System *> system; SimObjectParam<BaseCPU *> cpu; SimObjectParam<TsunamiIO *> clock; + SimObjectParam<Bus*> io_bus; + SimObjectParam<HierParams *> hier; END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) @@ -265,14 +283,17 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole) INIT_PARAM(addr, "Device Address"), INIT_PARAM(system, "system object"), INIT_PARAM(cpu, "Processor"), - INIT_PARAM(clock, "Turbolaser Clock") + INIT_PARAM(clock, "Turbolaser Clock"), + INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL), + INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) END_INIT_SIM_OBJECT_PARAMS(AlphaConsole) CREATE_SIM_OBJECT(AlphaConsole) { - return new AlphaConsole(getInstanceName(), sim_console, disk, - system, cpu, clock, num_cpus, addr, mmu); + return new AlphaConsole(getInstanceName(), sim_console, disk, + system, cpu, clock, num_cpus, mmu, + addr, hier, io_bus); } REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole) diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh index d0fa552af..be8538e50 100644 --- a/dev/alpha_console.hh +++ b/dev/alpha_console.hh @@ -35,7 +35,7 @@ #include "base/range.hh" #include "dev/alpha_access.h" -#include "mem/functional_mem/functional_memory.hh" +#include "dev/io_device.hh" #include "sim/host.hh" #include "dev/tsunami_io.hh" @@ -70,7 +70,7 @@ class SimpleDisk; * primarily used doing boot before the kernel has loaded its device * drivers. */ -class AlphaConsole : public FunctionalMemory +class AlphaConsole : public PioDevice { protected: union { @@ -89,10 +89,10 @@ class AlphaConsole : public FunctionalMemory public: /** Standard Constructor */ - AlphaConsole(const std::string &name, SimConsole *cons, - SimpleDisk *d, System *system, BaseCPU *cpu, - TsunamiIO *clock, int num_cpus, - Addr a, MemoryController *mmu); + AlphaConsole(const std::string &name, SimConsole *cons, SimpleDisk *d, + System *system, BaseCPU *cpu, TsunamiIO *clock, + int num_cpus, MemoryController *mmu, Addr addr, + HierParams *hier, Bus *bus); /** * memory mapped reads and writes @@ -105,6 +105,9 @@ class AlphaConsole : public FunctionalMemory */ virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); + + public: + Tick cacheAccess(MemReqPtr &req); }; #endif // __ALPHA_CONSOLE_HH__ diff --git a/dev/etherdump.cc b/dev/etherdump.cc index 6d86adc32..b6d6bbe30 100644 --- a/dev/etherdump.cc +++ b/dev/etherdump.cc @@ -34,6 +34,7 @@ #include <string> +#include "base/misc.hh" #include "dev/etherdump.hh" #include "sim/builder.hh" #include "sim/universe.hh" @@ -43,11 +44,8 @@ using std::string; EtherDump::EtherDump(const string &name, const string &file) : SimObject(name) { - if (!file.empty()) { + if (!file.empty()) stream.open(file.c_str()); - if (stream.is_open()) - init(); - } } #define DLT_EN10MB 1 // Ethernet (10Mb) @@ -66,7 +64,8 @@ struct pcap_file_header { }; struct pcap_pkthdr { - struct timeval ts; // time stamp + uint32_t seconds; + uint32_t microseconds; uint32_t caplen; // length of portion present uint32_t len; // length this packet (off wire) }; @@ -74,6 +73,9 @@ struct pcap_pkthdr { void EtherDump::init() { + if (!stream.is_open()) + return; + curtime = time(NULL); s_freq = ticksPerSecond; us_freq = ticksPerSecond / ULL(1000000); @@ -96,8 +98,8 @@ EtherDump::init() * to sim_cycles. */ pcap_pkthdr pkthdr; - pkthdr.ts.tv_sec = curtime; - pkthdr.ts.tv_usec = 0; + pkthdr.seconds = curtime; + pkthdr.microseconds = 0; pkthdr.caplen = 0; pkthdr.len = 0; stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr)); @@ -109,8 +111,8 @@ void EtherDump::dumpPacket(PacketPtr &packet) { pcap_pkthdr pkthdr; - pkthdr.ts.tv_sec = curtime + (curTick / s_freq); - pkthdr.ts.tv_usec = (curTick / us_freq) % ULL(1000000); + pkthdr.seconds = curtime + (curTick / s_freq); + pkthdr.microseconds = (curTick / us_freq) % ULL(1000000); pkthdr.caplen = packet->length; pkthdr.len = packet->length; stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr)); diff --git a/dev/etherlink.cc b/dev/etherlink.cc index 676b1da1c..25991f1a7 100644 --- a/dev/etherlink.cc +++ b/dev/etherlink.cc @@ -42,17 +42,19 @@ #include "dev/etherpkt.hh" #include "sim/builder.hh" #include "sim/universe.hh" +#include "sim/system.hh" using namespace std; -EtherLink::EtherLink(const std::string &name, EtherInt *i1, EtherInt *i2, - Tick speed, EtherDump *dump) +EtherLink::EtherLink(const string &name, EtherInt *i1, EtherInt *i2, + Tick speed, Tick dly, EtherDump *dump) : SimObject(name) { double rate = ((double)ticksPerSecond * 8.0) / (double)speed; + Tick delay = US2Ticks(dly); - link1 = new Link(name + ".link1", rate, dump); - link2 = new Link(name + ".link2", rate, dump); + link1 = new Link(name + ".link1", rate, delay, dump); + link2 = new Link(name + ".link2", rate, delay, dump); int1 = new Interface(name + ".int1", link1, link2); int2 = new Interface(name + ".int2", link2, link1); @@ -72,28 +74,76 @@ EtherLink::~EtherLink() delete int2; } -EtherLink::Interface::Interface(const std::string &name, Link *tx, Link *rx) +EtherLink::Interface::Interface(const string &name, Link *tx, Link *rx) : EtherInt(name), txlink(tx) { tx->setTxInt(this); rx->setRxInt(this); } -EtherLink::Link::Link(const std::string &name, double rate, EtherDump *d) - : objName(name), txint(NULL), rxint(NULL), ticks_per_byte(rate), - dump(d), event(&mainEventQueue, this) +EtherLink::Link::Link(const string &name, double rate, Tick delay, + EtherDump *d) + : objName(name), txint(NULL), rxint(NULL), ticksPerByte(rate), + linkDelay(delay), dump(d), doneEvent(this) {} void +EtherLink::serialize(ostream &os) +{ + nameOut(os, name() + ".link1"); + link1->serialize(os); + nameOut(os, name() + ".link2"); + link2->serialize(os); +} + +void +EtherLink::unserialize(Checkpoint *cp, const string §ion) +{ + link1->unserialize(cp, section + ".link1"); + link2->unserialize(cp, section + ".link2"); +} + +void +EtherLink::Link::txComplete(PacketPtr &packet) +{ + DPRINTF(Ethernet, "packet received: len=%d\n", packet->length); + DDUMP(EthernetData, packet->data, packet->length); + rxint->sendPacket(packet); +} + +class LinkDelayEvent : public Event +{ + protected: + EtherLink::Link *link; + PacketPtr packet; + + // non-scheduling version for createForUnserialize() + LinkDelayEvent(EtherLink::Link *link); + + public: + LinkDelayEvent(EtherLink::Link *link, PacketPtr &pkt, Tick when); + + void process(); + + virtual void serialize(ostream &os); + virtual void unserialize(Checkpoint *cp, const string §ion); + static Serializable *createForUnserialize(Checkpoint *cp, + const string §ion); +}; + + +void EtherLink::Link::txDone() { if (dump) dump->dump(packet); - DPRINTF(Ethernet, "EtherLink packet received: len=%d\n", packet->length); - DDUMP(EthernetData, packet->data, packet->length); - - rxint->sendPacket(packet); + if (linkDelay > 0) { + DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay); + new LinkDelayEvent(this, packet, curTick + linkDelay); + } else { + txComplete(packet); + } packet = 0; assert(!busy()); @@ -105,27 +155,118 @@ bool EtherLink::Link::transmit(PacketPtr &pkt) { if (busy()) { - DPRINTF(Ethernet, "EtherLink packet not sent, link busy\n"); + DPRINTF(Ethernet, "packet not sent, link busy\n"); return false; } - DPRINTF(Ethernet, "EtherLink packet sent: len=%d\n", pkt->length); + DPRINTF(Ethernet, "packet sent: len=%d\n", pkt->length); DDUMP(EthernetData, pkt->data, pkt->length); packet = pkt; - int delay = (int)ceil(((double)pkt->length * ticks_per_byte) + 1.0); - DPRINTF(Ethernet, "EtherLink scheduling packet: delay=%d, (rate=%f)\n", - delay, ticks_per_byte); - event.schedule(curTick + delay); + Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0); + DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n", + delay, ticksPerByte); + doneEvent.schedule(curTick + delay); return true; } +void +EtherLink::Link::serialize(ostream &os) +{ + bool packet_exists = packet; + SERIALIZE_SCALAR(packet_exists); + + bool event_scheduled = doneEvent.scheduled(); + SERIALIZE_SCALAR(event_scheduled); + if (event_scheduled) { + Tick event_time = doneEvent.when(); + SERIALIZE_SCALAR(event_time); + } + + if (packet_exists) { + nameOut(os, csprintf("%s.packet", name())); + packet->serialize(os); + } +} + +void +EtherLink::Link::unserialize(Checkpoint *cp, const string §ion) +{ + bool packet_exists; + UNSERIALIZE_SCALAR(packet_exists); + if (packet_exists) { + packet = new EtherPacket; + packet->unserialize(cp, csprintf("%s.packet", section)); + } + + bool event_scheduled; + UNSERIALIZE_SCALAR(event_scheduled); + if (event_scheduled) { + Tick event_time; + UNSERIALIZE_SCALAR(event_time); + doneEvent.schedule(event_time); + } +} + +LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l) + : Event(&mainEventQueue), link(l) +{ + setFlags(AutoSerialize); + setFlags(AutoDelete); +} + +LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, PacketPtr &p, Tick when) + : Event(&mainEventQueue), link(l), packet(p) +{ + setFlags(AutoSerialize); + setFlags(AutoDelete); + schedule(when); +} + +void +LinkDelayEvent::process() +{ + link->txComplete(packet); +} + +void +LinkDelayEvent::serialize(ostream &os) +{ + paramOut(os, "type", string("LinkDelayEvent")); + Event::serialize(os); + SERIALIZE_OBJPTR(link); + + nameOut(os, csprintf("%s.packet", name())); + packet->serialize(os); +} + + +void +LinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) +{ + Event::unserialize(cp, section); + packet = new EtherPacket; + packet->unserialize(cp, csprintf("%s.packet", section)); +} + + +Serializable * +LinkDelayEvent::createForUnserialize(Checkpoint *cp, const string §ion) +{ + EtherLink::Link *link; + UNSERIALIZE_OBJPTR(link); + return new LinkDelayEvent(link); +} + +REGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent) + BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink) SimObjectParam<EtherInt *> interface1; SimObjectParam<EtherInt *> interface2; Param<Tick> link_speed; + Param<Tick> link_delay; SimObjectParam<EtherDump *> packet_dump; END_DECLARE_SIM_OBJECT_PARAMS(EtherLink) @@ -135,6 +276,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink) INIT_PARAM(interface1, "interface 1"), INIT_PARAM(interface2, "interface 2"), INIT_PARAM_DFLT(link_speed, "link speed in bits per second", 100000000), + INIT_PARAM_DFLT(link_delay, "transmit delay of packets in us", 0), INIT_PARAM_DFLT(packet_dump, "object to dump network packets to", NULL) END_INIT_SIM_OBJECT_PARAMS(EtherLink) @@ -142,7 +284,7 @@ END_INIT_SIM_OBJECT_PARAMS(EtherLink) CREATE_SIM_OBJECT(EtherLink) { return new EtherLink(getInstanceName(), interface1, interface2, link_speed, - packet_dump); + link_delay, packet_dump); } REGISTER_SIM_OBJECT("EtherLink", EtherLink) diff --git a/dev/etherlink.hh b/dev/etherlink.hh index e1a7957ee..3b1dd21bc 100644 --- a/dev/etherlink.hh +++ b/dev/etherlink.hh @@ -49,6 +49,7 @@ class EtherLink : public SimObject protected: class Interface; + friend class LinkDelayEvent; /* * Model for a single uni-directional link */ @@ -59,34 +60,26 @@ class EtherLink : public SimObject Interface *txint; Interface *rxint; - double ticks_per_byte; + double ticksPerByte; + Tick linkDelay; EtherDump *dump; protected: /* * Transfer is complete */ - class DoneEvent : public Event - { - protected: - Link *link; - - public: - DoneEvent(EventQueue *q, Link *l) - : Event(q), link(l) {} - virtual void process() { link->txDone(); } - virtual const char *description() - { return "ethernet link completion"; } - }; - - friend class DoneEvent; - DoneEvent event; PacketPtr packet; - void txDone(); + typedef EventWrapper<Link, &Link::txDone> DoneEvent; + friend class DoneEvent; + DoneEvent doneEvent; + + friend class LinkDelayEvent; + void txComplete(PacketPtr &packet); public: - Link(const std::string &name, double rate, EtherDump *dump); + Link(const std::string &name, double rate, Tick delay, + EtherDump *dump); ~Link() {} virtual const std::string name() const { return objName; } @@ -96,6 +89,9 @@ class EtherLink : public SimObject void setTxInt(Interface *i) { assert(!txint); txint = i; } void setRxInt(Interface *i) { assert(!rxint); rxint = i; } + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); }; /* @@ -120,8 +116,12 @@ class EtherLink : public SimObject public: EtherLink(const std::string &name, EtherInt *i1, EtherInt *i2, - Tick speed, EtherDump *dump); + Tick speed, Tick delay, EtherDump *dump); virtual ~EtherLink(); + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); + }; #endif // __ETHERLINK_HH__ diff --git a/dev/etherpkt.cc b/dev/etherpkt.cc new file mode 100644 index 000000000..cb6087c89 --- /dev/null +++ b/dev/etherpkt.cc @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2004 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 <iostream> + +#include "dev/etherpkt.hh" +#include "sim/serialize.hh" + +using namespace std; + +void +EtherPacket::serialize(ostream &os) +{ + SERIALIZE_SCALAR(length); + SERIALIZE_ARRAY(data, length); +} + +void +EtherPacket::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(length); + data = new uint8_t[length]; + UNSERIALIZE_ARRAY(data, length); +} + diff --git a/dev/etherpkt.hh b/dev/etherpkt.hh index c91322526..27ac526d6 100644 --- a/dev/etherpkt.hh +++ b/dev/etherpkt.hh @@ -33,10 +33,10 @@ #ifndef __ETHERPKT_HH__ #define __ETHERPKT_HH__ +#include <iosfwd> #include <memory> #include "sim/host.hh" - #include "base/refcnt.hh" class Checkpoint; diff --git a/dev/io_device.cc b/dev/io_device.cc new file mode 100644 index 000000000..4f53ba48d --- /dev/null +++ b/dev/io_device.cc @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2003 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 "dev/io_device.hh" +#include "mem/bus/base_interface.hh" +#include "mem/bus/dma_interface.hh" + +PioDevice::PioDevice(const std::string &name) + : FunctionalMemory(name), pioInterface(NULL) +{} + +PioDevice::~PioDevice() +{ + if (pioInterface) + delete pioInterface; +} + +DmaDevice::DmaDevice(const std::string &name) + : PioDevice(name), dmaInterface(NULL) +{} + +DmaDevice::~DmaDevice() +{ + if (dmaInterface) + delete dmaInterface; +} + diff --git a/dev/io_device.hh b/dev/io_device.hh new file mode 100644 index 000000000..9300d87e7 --- /dev/null +++ b/dev/io_device.hh @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2003 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 __IO_DEVICE_HH__ +#define __IO_DEVICE_HH__ + +#include "mem/functional_mem/functional_memory.hh" + +class BaseInterface; +class Bus; +class HierParams; +template <class Bus> class DMAInterface; + +class PioDevice : public FunctionalMemory +{ + protected: + BaseInterface *pioInterface; + + public: + PioDevice(const std::string &name); + virtual ~PioDevice(); +}; + +class DmaDevice : public PioDevice +{ + protected: + DMAInterface<Bus> *dmaInterface; + + public: + DmaDevice(const std::string &name); + virtual ~DmaDevice(); +}; + +#endif // __IO_DEVICE_HH__ diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc index f542256e4..a57c01841 100644 --- a/kern/tru64/tru64_events.cc +++ b/kern/tru64/tru64_events.cc @@ -35,11 +35,8 @@ #include "kern/tru64/tru64_events.hh" #include "mem/functional_mem/memory_control.hh" #include "targetarch/arguments.hh" - -#ifdef FS_MEASURE #include "sim/system.hh" #include "sim/sw_context.hh" -#endif void SkipFuncEvent::process(ExecContext *xc) @@ -110,7 +107,6 @@ DumpMbufEvent::process(ExecContext *xc) } } -#ifdef FS_MEASURE FnEvent::FnEvent(PCEventQueue *q, const std::string & desc, System *system) : PCEvent(q, desc), _name(desc) { @@ -128,13 +124,25 @@ FnEvent::process(ExecContext *xc) DPRINTF(TCPIP, "%s: %s Event!!!\n", xc->system->name(), description); if (ctx && !ctx->callStack.empty()) { + DPRINTF(TCPIP, "already a callstack!\n"); fnCall *last = ctx->callStack.top(); - if (!xc->system->findCaller(myname(), last->name)) { + + if (last->name == "idle_thread") + ctx->calls++; + + if (!xc->system->findCaller(myname(), "" ) && + !xc->system->findCaller(myname(), last->name)) { + + DPRINTF(TCPIP, "but can't find parent %s\n", last->name); return; } ctx->calls--; + + //assert(!ctx->calls && "on a binned fn, calls should == 0 (but can happen in boot)"); } else { + DPRINTF(TCPIP, "no callstack yet\n"); if (!xc->system->findCaller(myname(), "")) { + DPRINTF(TCPIP, "not the right function, returning\n"); return; } if (!ctx) { @@ -150,6 +158,7 @@ FnEvent::process(ExecContext *xc) ctx->callStack.push(call); myBin->activate(); xc->system->fnCalls++; + DPRINTF(TCPIP, "fnCalls for %s is %d\n", description, + xc->system->fnCalls.val()); xc->system->dumpState(xc); } -#endif //FS_MEASURE diff --git a/kern/tru64/tru64_events.hh b/kern/tru64/tru64_events.hh index 2067f2ef3..96e6a8b26 100644 --- a/kern/tru64/tru64_events.hh +++ b/kern/tru64/tru64_events.hh @@ -35,9 +35,7 @@ class ExecContext; -#ifdef FS_MEASURE class System; -#endif class SkipFuncEvent : public PCEvent { @@ -82,7 +80,6 @@ class DumpMbufEvent : public PCEvent virtual void process(ExecContext *xc); }; -#ifdef FS_MEASURE class FnEvent : public PCEvent { public: @@ -94,5 +91,4 @@ class FnEvent : public PCEvent std::string _name; Statistics::MainBin *myBin; }; -#endif //FS_MEASURE #endif // __TRU64_EVENTS_HH__ diff --git a/kern/tru64/tru64_system.cc b/kern/tru64/tru64_system.cc index 1cd98fdc1..b03d7bf26 100644 --- a/kern/tru64/tru64_system.cc +++ b/kern/tru64/tru64_system.cc @@ -41,17 +41,15 @@ #include "targetarch/isa_traits.hh" #include "targetarch/vtophys.hh" -//un-comment this to see the state of call stack when it changes. -//#define SW_DEBUG - using namespace std; Tru64System::Tru64System(const string _name, const uint64_t _init_param, MemoryController *_memCtrl, PhysicalMemory *_physmem, const string &kernel_path, const string &console_path, const string &palcode, const string &boot_osflags, - const bool _bin) - : System(_name, _init_param, _memCtrl, _physmem, _bin), bin(_bin) + const bool _bin, const vector<string> &binned_fns) + : System(_name, _init_param, _memCtrl, _physmem, _bin), + bin(_bin), binned_fns(binned_fns) { kernelSymtab = new SymbolTable; consoleSymtab = new SymbolTable; @@ -92,106 +90,6 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param, DPRINTF(Loader, "Kernel loaded...\n"); -#ifdef FS_MEASURE - //INSTRUMENTATION CODEGEN BEGIN ONE - if (bin == true) { - esIntrBin = new Statistics::MainBin(name() + " es_intr"); - fnBins.insert(make_pair("es_intr", esIntrBin)); - - esRxeofBin = new Statistics::MainBin(name() + " es_rxeof"); - fnBins.insert(make_pair("es_rxeof", esRxeofBin)); - - esNewbufBin = new Statistics::MainBin(name() + " es_newbuf"); - fnBins.insert(make_pair("es_newbuf", esNewbufBin)); - - esDmaLoadBin = new Statistics::MainBin(name() + " es_dma_load"); - fnBins.insert(make_pair("es_dma_load", esDmaLoadBin)); - - dmaMapLoadBin = new Statistics::MainBin(name() + " dma_map_load"); - fnBins.insert(make_pair("dma_map_load", dmaMapLoadBin)); - - etherInputBin = new Statistics::MainBin(name() + " ether_input"); - fnBins.insert(make_pair("ether_input", etherInputBin)); - - netisrInputBin = new Statistics::MainBin(name() + " netisr_input"); - fnBins.insert(make_pair("netisr_input", netisrInputBin)); - - schednetisrIsrBin = new Statistics::MainBin(name() + " schednetisr_isr"); - fnBins.insert(make_pair("schednetisr_isr", schednetisrIsrBin)); - - ipintrBin = new Statistics::MainBin(name() + " ipintr"); - fnBins.insert(make_pair("ipintr", ipintrBin)); - - ipDooptionsBin = new Statistics::MainBin(name() + " ip_dooptions"); - fnBins.insert(make_pair("ip_dooptions", ipDooptionsBin)); - - ipReassBin = new Statistics::MainBin(name() + " ip_reass"); - fnBins.insert(make_pair("ip_reass", ipReassBin)); - - tcpInputBin = new Statistics::MainBin(name() + " tcp_input"); - fnBins.insert(make_pair("tcp_input", tcpInputBin)); - - sbappendBin = new Statistics::MainBin(name() + " sbappend"); - fnBins.insert(make_pair("sbappend", sbappendBin)); - - readBin = new Statistics::MainBin(name() + " read"); - fnBins.insert(make_pair("read", readBin)); - - sooReadBin = new Statistics::MainBin(name() + " soo_read"); - fnBins.insert(make_pair("soo_read", sooReadBin)); - - orecvBin = new Statistics::MainBin(name() + " orecv"); - fnBins.insert(make_pair("orecv", orecvBin)); - - recvitBin = new Statistics::MainBin(name() + " recvit"); - fnBins.insert(make_pair("recvit", recvitBin)); - - soreceiveBin = new Statistics::MainBin(name() + " soreceive"); - fnBins.insert(make_pair("soreceive", soreceiveBin)); - - osendBin = new Statistics::MainBin(name() + " osend"); - fnBins.insert(make_pair("osend", osendBin)); - - writeBin = new Statistics::MainBin(name() + " write"); - fnBins.insert(make_pair("write", writeBin)); - - sooWriteBin = new Statistics::MainBin(name() + " soo_write"); - fnBins.insert(make_pair("soo_write", sooWriteBin)); - - senditBin = new Statistics::MainBin(name() + " sendit"); - fnBins.insert(make_pair("sendit", senditBin)); - - sosendBin = new Statistics::MainBin(name() + " sosend"); - fnBins.insert(make_pair("sosend", sosendBin)); - - tcpSosendBin = new Statistics::MainBin(name() + " tcp_sosend"); - fnBins.insert(make_pair("tcp_sosend", tcpSosendBin)); - - tcpOutputBin = new Statistics::MainBin(name() + " tcp_output"); - fnBins.insert(make_pair("tcp_output", tcpOutputBin)); - - ipOutputBin = new Statistics::MainBin(name() + " ip_output"); - fnBins.insert(make_pair("ip_output", ipOutputBin)); - - etherOutputBin = new Statistics::MainBin(name() + " ether_output"); - fnBins.insert(make_pair("ether_output", etherOutputBin)); - - esStartBin = new Statistics::MainBin(name() + " es_start"); - fnBins.insert(make_pair("es_start", esStartBin)); - - esTransmitBin = new Statistics::MainBin(name() + " es_transmit"); - fnBins.insert(make_pair("es_transmit", esTransmitBin)); - - esTxeofBin = new Statistics::MainBin(name() + " es_txeof"); - fnBins.insert(make_pair("es_txeof", esTxeofBin)); - - idleThreadBin = new Statistics::MainBin(name() + " idle_thread"); - fnBins.insert(make_pair("idle_thread", idleThreadBin)); - - } - //INSTRUMENTATION CODEGEN END -#endif //FS_MEASURE - #ifdef DEBUG kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic"); consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic"); @@ -208,44 +106,6 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param, "debug_printfr", true); dumpMbufEvent = new DumpMbufEvent(&pcEventQueue, "dump_mbuf"); -#ifdef FS_MEASURE - //INSTRUMENTATION CODEGEN BEGIN TWO - if (bin == true) { - esIntrEvent = new FnEvent(&pcEventQueue, "es_intr", this); - esRxeofEvent = new FnEvent(&pcEventQueue, "es_rxeof", this); - esNewbufEvent = new FnEvent(&pcEventQueue, "es_newbuf", this); - esDmaLoadEvent = new FnEvent(&pcEventQueue, "es_dma_load", this); - dmaMapLoadEvent = new FnEvent(&pcEventQueue, "dma_map_load", this); - etherInputEvent = new FnEvent(&pcEventQueue, "ether_input", this); - netisrInputEvent = new FnEvent(&pcEventQueue, "netisr_input", this); - schednetisrIsrEvent = new FnEvent(&pcEventQueue, "schednetisr_isr", this); - ipintrEvent = new FnEvent(&pcEventQueue, "ipintr", this); - ipDooptionsEvent = new FnEvent(&pcEventQueue, "ip_dooptions", this); - ipReassEvent = new FnEvent(&pcEventQueue, "ip_reass", this); - tcpInputEvent = new FnEvent(&pcEventQueue, "tcp_input", this); - sbappendEvent = new FnEvent(&pcEventQueue, "sbappend", this); - readEvent = new FnEvent(&pcEventQueue, "read", this); - sooReadEvent = new FnEvent(&pcEventQueue, "soo_read", this); - orecvEvent = new FnEvent(&pcEventQueue, "orecv", this); - recvitEvent = new FnEvent(&pcEventQueue, "recvit", this); - soreceiveEvent = new FnEvent(&pcEventQueue, "soreceive", this); - osendEvent = new FnEvent(&pcEventQueue, "osend", this); - writeEvent = new FnEvent(&pcEventQueue, "write", this); - sooWriteEvent = new FnEvent(&pcEventQueue, "soo_write", this); - senditEvent = new FnEvent(&pcEventQueue, "sendit", this); - sosendEvent = new FnEvent(&pcEventQueue, "sosend", this); - tcpSosendEvent = new FnEvent(&pcEventQueue, "tcp_sosend", this); - tcpOutputEvent = new FnEvent(&pcEventQueue, "tcp_output", this); - ipOutputEvent = new FnEvent(&pcEventQueue, "ip_output", this); - etherOutputEvent = new FnEvent(&pcEventQueue, "ether_output", this); - esStartEvent = new FnEvent(&pcEventQueue, "es_start", this); - esTransmitEvent = new FnEvent(&pcEventQueue, "es_transmit", this); - esTxeofEvent = new FnEvent(&pcEventQueue, "es_txeof", this); - idleThreadEvent = new FnEvent(&pcEventQueue, "idle_thread", this); - } - //INSTRUMENTATION CODEGEN END -#endif //FS_MEASURE - Addr addr = 0; if (kernelSymtab->findAddress("enable_async_printf", addr)) { Addr paddr = vtophys(physmem, addr); @@ -299,212 +159,38 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param, dumpMbufEvent->schedule(addr); #endif -#ifdef FS_MEASURE - //INSTRUMENTATION CODEGEN BEGIN THREE + // BINNING STUFF if (bin == true) { - if (kernelSymtab->findAddress("es_intr", addr)) - esIntrEvent->schedule(addr); - else - panic("could not find kernel symbol \'es_intr\'"); - - if (kernelSymtab->findAddress("es_rxeof", addr)) - esRxeofEvent->schedule(addr); - else - panic("could not find kernel symbol \'es_rxeof\'"); - - if (kernelSymtab->findAddress("es_newbuf", addr)) - esNewbufEvent->schedule(addr); - else - panic("could not find kernel symbol \'es_newbuf\'"); - - if (kernelSymtab->findAddress("es_dma_load", addr)) - esDmaLoadEvent->schedule(addr); - else - panic("could not find kernel symbol \'es_dma_load\'"); - - if (kernelSymtab->findAddress("dma_map_load", addr)) - dmaMapLoadEvent->schedule(addr); - else - panic("could not find kernel symbol \'dma_map_load\'"); - - if (kernelSymtab->findAddress("ether_input", addr)) - etherInputEvent->schedule(addr); - else - panic("could not find kernel symbol \'ether_input\'"); - - if (kernelSymtab->findAddress("netisr_input", addr)) - netisrInputEvent->schedule(addr); - else - panic("could not find kernel symbol \'netisr_input\'"); - - if (kernelSymtab->findAddress("schednetisr_isr", addr)) - schednetisrIsrEvent->schedule(addr); - else - panic("could not find kernel symbol \'schednetisr_isr\'"); - - if (kernelSymtab->findAddress("ipintr", addr)) - ipintrEvent->schedule(addr); - else - panic("could not find kernel symbol \'ipintr\'"); - - if (kernelSymtab->findAddress("ip_dooptions", addr)) - ipDooptionsEvent->schedule(addr); - else - panic("could not find kernel symbol \'ip_dooptions\'"); - - if (kernelSymtab->findAddress("ip_reass", addr)) - ipReassEvent->schedule(addr); - else - panic("could not find kernel symbol \'ip_reass\'"); - - if (kernelSymtab->findAddress("tcp_input", addr)) - tcpInputEvent->schedule(addr); - else - panic("could not find kernel symbol \'tcp_input\'"); - - if (kernelSymtab->findAddress("sbappend", addr)) - sbappendEvent->schedule(addr); - else - panic("could not find kernel symbol \'sbappend\'"); - - if (kernelSymtab->findAddress("read", addr)) - readEvent->schedule(addr); - else - panic("could not find kernel symbol \'read\'"); - - if (kernelSymtab->findAddress("soo_read", addr)) - sooReadEvent->schedule(addr); - else - panic("could not find kernel symbol \'soo_read\'"); - - if (kernelSymtab->findAddress("orecv", addr)) - orecvEvent->schedule(addr); - else - panic("could not find kernel symbol \'orecv\'"); - - if (kernelSymtab->findAddress("recvit", addr)) - recvitEvent->schedule(addr); - else - panic("could not find kernel symbol \'recvit\'"); - - if (kernelSymtab->findAddress("soreceive", addr)) - soreceiveEvent->schedule(addr); - else - panic("could not find kernel symbol \'soreceive\'"); - - if (kernelSymtab->findAddress("osend", addr)) - osendEvent->schedule(addr); - else - panic("could not find kernel symbol \'osend\'"); - - if (kernelSymtab->findAddress("write", addr)) - writeEvent->schedule(addr); - else - panic("could not find kernel symbol \'write\'"); - - if (kernelSymtab->findAddress("soo_write", addr)) - sooWriteEvent->schedule(addr); - else - panic("could not find kernel symbol \'soo_write\'"); - - if (kernelSymtab->findAddress("sendit", addr)) - senditEvent->schedule(addr); - else - panic("could not find kernel symbol \'sendit\'"); - - if (kernelSymtab->findAddress("sosend", addr)) - sosendEvent->schedule(addr); - else - panic("could not find kernel symbol \'sosend\'"); - - if (kernelSymtab->findAddress("tcp_sosend", addr)) - tcpSosendEvent->schedule(addr); - else - panic("could not find kernel symbol \'tcp_sosend\'"); - - if (kernelSymtab->findAddress("tcp_output", addr)) - tcpOutputEvent->schedule(addr); - else - panic("could not find kernel symbol \'tcp_output\'"); - - if (kernelSymtab->findAddress("ip_output", addr)) - ipOutputEvent->schedule(addr); - else - panic("could not find kernel symbol \'ip_output\'"); - - if (kernelSymtab->findAddress("ether_output", addr)) - etherOutputEvent->schedule(addr); - else - panic("could not find kernel symbol \'ether_output\'"); - - if (kernelSymtab->findAddress("es_start", addr)) - esStartEvent->schedule(addr); - else - panic("could not find kernel symbol \'es_start\'"); - - if (kernelSymtab->findAddress("es_transmit", addr)) - esTransmitEvent->schedule(addr); - else - panic("could not find kernel symbol \'es_transmit\'"); - - if (kernelSymtab->findAddress("es_txeof", addr)) - esTxeofEvent->schedule(addr); - else - panic("could not find kernel symbol \'es_txeof\'"); - - if (kernelSymtab->findAddress("idle_thread", addr)) - idleThreadEvent->schedule(addr); - else - panic("could not find kernel symbol \'idle_thread\'"); + int end = binned_fns.size(); + assert(!(end & 1)); + + Statistics::MainBin *Bin; + Addr address = 0; + + fnEvents.resize(end>>1); + + for (int i = 0; i < end; i +=2) { + Bin = new Statistics::MainBin(binned_fns[i]); + fnBins.insert(make_pair(binned_fns[i], Bin)); + + fnEvents[(i>>1)] = new FnEvent(&pcEventQueue, binned_fns[i], this); + if (kernelSymtab->findAddress(binned_fns[i], address)) + fnEvents[(i>>1)]->schedule(address); + else + panic("could not find kernel symbol %s\n", binned_fns[i]); + + if (binned_fns[i+1] == "null") + populateMap(binned_fns[i], ""); + else + populateMap(binned_fns[i], binned_fns[i+1]); + } - } - //INSTRUMENTATION CODEGEN END - if (bin == true) { fnCalls .name(name() + ":fnCalls") .desc("all fn calls being tracked") ; - - populateMap("es_intr", ""); - populateMap("es_rxeof", "es_intr"); - populateMap("es_newbuf", "es_rxeof"); - populateMap("es_dma_load", "es_newbuf"); - populateMap("dma_map_load", "es_dma_load"); - populateMap("ether_input", "es_rxeof"); - populateMap("netisr_input", "ether_input"); - populateMap("schednetisr_isr", "netisr_input"); - - populateMap("ipintr", ""); - populateMap("ip_dooptions", "ipintr"); - populateMap("ip_reass", "ipintr"); - populateMap("tcp_input", "ipintr"); - populateMap("sbappend", "tcp_input"); - - populateMap("read", ""); - populateMap("orecv", ""); - populateMap("soo_read", "read"); - populateMap("recvit", "orecv"); - populateMap("soreceive", "recvit"); - populateMap("soreceive", "soo_read"); - - populateMap("write", ""); - populateMap("osend", ""); - populateMap("soo_write", "write"); - populateMap("sendit", "osend"); - populateMap("sosend", "sendit"); - populateMap("sosend", "soo_write"); - populateMap("tcp_sosend", "sosend"); - populateMap("tcp_output", "tcp_sosend"); - populateMap("ip_output", "tcp_output"); - populateMap("ether_output", "ip_output"); - populateMap("es_start", "ether_output"); - populateMap("es_transmit", "es_start"); - - populateMap("es_txeof", "es_intr"); - - populateMap("idle_thread", ""); } -#endif //FS_MEASURE + // } Tru64System::~Tru64System() @@ -527,43 +213,13 @@ Tru64System::~Tru64System() delete debugPrintfrEvent; delete dumpMbufEvent; -#ifdef FS_MEASURE - //INSTRUMENTATION CODEGEN BEGIN FOUR if (bin == true) { - delete esIntrEvent; - delete esRxeofEvent; - delete esNewbufEvent; - delete esDmaLoadEvent; - delete dmaMapLoadEvent; - delete etherInputEvent; - delete netisrInputEvent; - delete schednetisrIsrEvent; - delete ipintrEvent; - delete ipDooptionsEvent; - delete ipReassEvent; - delete tcpInputEvent; - delete sbappendEvent; - delete readEvent; - delete sooReadEvent; - delete orecvEvent; - delete recvitEvent; - delete soreceiveEvent; - delete osendEvent; - delete writeEvent; - delete sooWriteEvent; - delete senditEvent; - delete sosendEvent; - delete tcpSosendEvent; - delete tcpOutputEvent; - delete ipOutputEvent; - delete etherOutputEvent; - delete esStartEvent; - delete esTransmitEvent; - delete esTxeofEvent; - delete idleThreadEvent; + int end = fnEvents.size(); + for (int i = 0; i < end; ++i) { + delete fnEvents[i]; + } + fnEvents.clear(); } - //INSTRUMENTATION CODEGEN END -#endif //FS_MEASURE } int @@ -604,7 +260,6 @@ Tru64System::breakpoint() return remoteGDB[0]->trap(ALPHA_KENTRY_INT); } -#ifdef FS_MEASURE void Tru64System::populateMap(std::string callee, std::string caller) { @@ -630,23 +285,19 @@ Tru64System::findCaller(std::string callee, std::string caller) const void Tru64System::dumpState(ExecContext *xc) const { -#ifndef SW_DEBUG - return; -#endif if (xc->swCtx) { stack<fnCall *> copy(xc->swCtx->callStack); if (copy.empty()) return; - cprintf("xc->swCtx:\n"); + DPRINTF(TCPIP, "xc->swCtx, size: %d:\n", copy.size()); fnCall *top; - cprintf("|| call: %d\n",xc->swCtx->calls); + DPRINTF(TCPIP, "|| call : %d\n",xc->swCtx->calls); for (top = copy.top(); !copy.empty(); copy.pop() ) { top = copy.top(); - cprintf("|| %13s : %s \n", top->name, top->myBin->name()); + DPRINTF(TCPIP, "|| %13s : %s \n", top->name, top->myBin->name()); } } } -#endif //FS_MEASURE BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64System) @@ -659,6 +310,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64System) Param<string> console_code; Param<string> pal_code; Param<string> boot_osflags; + VectorParam<string> binned_fns; END_DECLARE_SIM_OBJECT_PARAMS(Tru64System) @@ -672,8 +324,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64System) INIT_PARAM(console_code, "file that contains the console code"), INIT_PARAM(pal_code, "file that contains palcode"), INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", - "a") - + "a"), + INIT_PARAM(binned_fns, "functions to be broken down and binned") END_INIT_SIM_OBJECT_PARAMS(Tru64System) @@ -681,7 +333,8 @@ CREATE_SIM_OBJECT(Tru64System) { Tru64System *sys = new Tru64System(getInstanceName(), init_param, mem_ctl, physmem, kernel_code, console_code, - pal_code, boot_osflags, bin); + pal_code, boot_osflags, bin, + binned_fns); return sys; } diff --git a/kern/tru64/tru64_system.hh b/kern/tru64/tru64_system.hh index 93cc908e3..34569664d 100644 --- a/kern/tru64/tru64_system.hh +++ b/kern/tru64/tru64_system.hh @@ -29,15 +29,12 @@ #ifndef __TRU64_SYSTEM_HH__ #define __TRU64_SYSTEM_HH__ +#include <map> #include <vector> #include "sim/system.hh" #include "targetarch/isa_traits.hh" -#ifdef FS_MEASURE -#include <map> -#endif - class ExecContext; class EcoffObject; class SymbolTable; @@ -48,9 +45,7 @@ class SkipFuncEvent; class PrintfEvent; class DebugPrintfEvent; class DumpMbufEvent; -#ifdef FS_MEASURE class FnEvent; -#endif class AlphaArguments; class Tru64System : public System @@ -62,42 +57,6 @@ class Tru64System : public System SymbolTable *kernelSymtab; SymbolTable *consoleSymtab; -#ifdef FS_MEASURE - //INSTRUMENTATION CODEGEN BEGIN ONE - Statistics::MainBin *esIntrBin; - Statistics::MainBin *esRxeofBin; - Statistics::MainBin *esNewbufBin; - Statistics::MainBin *esDmaLoadBin; - Statistics::MainBin *dmaMapLoadBin; - Statistics::MainBin *etherInputBin; - Statistics::MainBin *netisrInputBin; - Statistics::MainBin *schednetisrIsrBin; - Statistics::MainBin *ipintrBin; - Statistics::MainBin *ipDooptionsBin; - Statistics::MainBin *ipReassBin; - Statistics::MainBin *tcpInputBin; - Statistics::MainBin *sbappendBin; - Statistics::MainBin *readBin; - Statistics::MainBin *sooReadBin; - Statistics::MainBin *orecvBin; - Statistics::MainBin *recvitBin; - Statistics::MainBin *soreceiveBin; - Statistics::MainBin *osendBin; - Statistics::MainBin *writeBin; - Statistics::MainBin *sooWriteBin; - Statistics::MainBin *senditBin; - Statistics::MainBin *sosendBin; - Statistics::MainBin *tcpSosendBin; - Statistics::MainBin *tcpOutputBin; - Statistics::MainBin *ipOutputBin; - Statistics::MainBin *etherOutputBin; - Statistics::MainBin *esStartBin; - Statistics::MainBin *esTransmitBin; - Statistics::MainBin *esTxeofBin; - Statistics::MainBin *idleThreadBin; - //INSTRUMENTATION CODEGEN END -#endif //FS_MEASURE - BreakPCEvent *kernelPanicEvent; BreakPCEvent *consolePanicEvent; BadAddrEvent *badaddrEvent; @@ -107,41 +66,8 @@ class Tru64System : public System DebugPrintfEvent *debugPrintfEvent; DebugPrintfEvent *debugPrintfrEvent; DumpMbufEvent *dumpMbufEvent; -#ifdef FS_MEASURE - //INSTRUMENTATION CODEGEN BEGIN TWO - FnEvent *esIntrEvent; - FnEvent *esRxeofEvent; - FnEvent *esNewbufEvent; - FnEvent *esDmaLoadEvent; - FnEvent *dmaMapLoadEvent; - FnEvent *etherInputEvent; - FnEvent *netisrInputEvent; - FnEvent *schednetisrIsrEvent; - FnEvent *ipintrEvent; - FnEvent *ipDooptionsEvent; - FnEvent *ipReassEvent; - FnEvent *tcpInputEvent; - FnEvent *sbappendEvent; - FnEvent *readEvent; - FnEvent *sooReadEvent; - FnEvent *orecvEvent; - FnEvent *recvitEvent; - FnEvent *soreceiveEvent; - FnEvent *osendEvent; - FnEvent *writeEvent; - FnEvent *sooWriteEvent; - FnEvent *senditEvent; - FnEvent *sosendEvent; - FnEvent *tcpSosendEvent; - FnEvent *tcpOutputEvent; - FnEvent *ipOutputEvent; - FnEvent *etherOutputEvent; - FnEvent *esStartEvent; - FnEvent *esTransmitEvent; - FnEvent *esTxeofEvent; - FnEvent *idleThreadEvent; - //INSTRUMENTATION CODEGEN END -#endif //FS_MEASURE + + std::vector<FnEvent *> fnEvents; private: @@ -149,11 +75,7 @@ class Tru64System : public System Addr kernelEnd; Addr kernelEntry; bool bin; - -#ifdef FS_MEASURE - std::multimap<const std::string, std::string> callerMap; - void populateMap(std::string caller, std::string callee); -#endif + std::vector<string> binned_fns; public: std::vector<RemoteGDB *> remoteGDB; @@ -168,7 +90,8 @@ class Tru64System : public System const std::string &console_path, const std::string &palcode, const std::string &boot_osflags, - const bool _bin); + const bool _bin, + const std::vector<string> &binned_fns); ~Tru64System(); int registerExecContext(ExecContext *xc); @@ -182,10 +105,16 @@ class Tru64System : public System static void Printf(AlphaArguments args); static void DumpMbuf(AlphaArguments args); -#ifdef FS_MEASURE + + // Lisa's binning stuff + private: + std::multimap<const std::string, std::string> callerMap; + void populateMap(std::string caller, std::string callee); + + public: bool findCaller(std::string callee, std::string caller) const; void dumpState(ExecContext *xc) const; -#endif //FS_MEASURE + // }; #endif // __TRU64_SYSTEM_HH__ diff --git a/sim/eventq.hh b/sim/eventq.hh index 31bf9d652..ed37fd4f4 100644 --- a/sim/eventq.hh +++ b/sim/eventq.hh @@ -236,6 +236,23 @@ DelayFunction(Tick when, T *object) new DelayEvent(when, object); } +template <class T, void (T::* F)()> +class EventWrapper : public Event +{ + private: + T *object; + + public: + EventWrapper(T *obj, bool del = false, EventQueue *q = &mainEventQueue, + Priority p = Default_Pri) + : Event(q, p), object(obj) + { + if (del) + setFlags(AutoDelete); + } + void process() { (object->*F)(); } +}; + /* * Queue of events sorted in time order */ @@ -310,6 +327,8 @@ inline void Event::schedule(Tick t) { assert(!scheduled()); + assert(t >= curTick); + setFlags(Scheduled); #if TRACING_ON when_scheduled = curTick; diff --git a/sim/sim_events.cc b/sim/sim_events.cc index a31da18dd..f7b07359c 100644 --- a/sim/sim_events.cc +++ b/sim/sim_events.cc @@ -28,11 +28,13 @@ #include <string> -#include "sim/param.hh" -#include "sim/eventq.hh" +#include "base/callback.hh" #include "base/hostinfo.hh" +#include "sim/eventq.hh" +#include "sim/param.hh" #include "sim/sim_events.hh" #include "sim/sim_exit.hh" +#include "sim/sim_init.hh" #include "sim/sim_stats.hh" using namespace std; @@ -178,7 +180,7 @@ class ProgressEvent : public Event ProgressEvent::ProgressEvent(EventQueue *q, Tick _interval) : Event(q), interval(_interval) { - schedule(interval); + schedule(curTick + interval); } // @@ -221,10 +223,24 @@ ProgressParamContext progessMessageParams("progress"); Param<Tick> progress_interval(&progessMessageParams, "cycle", "cycle interval for progress messages"); +namespace { + struct SetupProgress : public Callback + { + Tick interval; + SetupProgress(Tick tick) : interval(tick) {} + + virtual void process() + { + new ProgressEvent(&mainEventQueue, interval); + delete this; + } + }; +} + /* check execute options */ void ProgressParamContext::checkParams() { if (progress_interval.isValid()) - new ProgressEvent(&mainEventQueue, progress_interval); + registerInitCallback(new SetupProgress(progress_interval)); } diff --git a/sim/sim_object.cc b/sim/sim_object.cc index b3ac2c7a4..c55021e41 100644 --- a/sim/sim_object.cc +++ b/sim/sim_object.cc @@ -182,11 +182,11 @@ SimObject::printAllExtraOutput(ostream &os) void SimObject::serializeAll(ostream &os) { - SimObjectList::iterator i = simObjectList.begin(); - SimObjectList::iterator end = simObjectList.end(); + SimObjectList::reverse_iterator ri = simObjectList.rbegin(); + SimObjectList::reverse_iterator rend = simObjectList.rend(); - for (; i != end; ++i) { - SimObject *obj = *i; + for (; ri != rend; ++ri) { + SimObject *obj = *ri; obj->nameOut(os); obj->serialize(os); } diff --git a/sim/system.cc b/sim/system.cc index db93250ee..43f43baec 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -50,13 +50,12 @@ System::System(const std::string _name, { // add self to global system list systemList.push_back(this); -#ifdef FS_MEASURE if (bin == true) { - nonPath = new Statistics::MainBin("non TCPIP path stats"); - nonPath->activate(); + Kernel = new Statistics::MainBin("non TCPIP Kernel stats"); + Kernel->activate(); + User = new Statistics::MainBin("User stats"); } else - nonPath = NULL; -#endif + Kernel = NULL; } @@ -104,14 +103,13 @@ printSystems() System::printSystems(); } -#ifdef FS_MEASURE Statistics::MainBin * System::getBin(const std::string &name) { std::map<const std::string, Statistics::MainBin *>::const_iterator i; i = fnBins.find(name); if (i == fnBins.end()) - panic("trying to getBin that is not on system map!"); + panic("trying to getBin %s that is not on system map!", name); return (*i).second; } @@ -127,7 +125,73 @@ System::findContext(Addr pcb) } else return NULL; } -#endif //FS_MEASURE + +void +System::serialize(std::ostream &os) +{ + if (bin == true) { + map<const Addr, SWContext *>::const_iterator iter, end; + iter = swCtxMap.begin(); + end = swCtxMap.end(); + + int numCtxs = swCtxMap.size(); + SERIALIZE_SCALAR(numCtxs); + SWContext *ctx; + for (int i = 0; iter != end; ++i, ++iter) { + paramOut(os, csprintf("Addr[%d]",i), (*iter).first); + ctx = (*iter).second; + paramOut(os, csprintf("calls[%d]",i), ctx->calls); + + stack<fnCall *> *stack = &(ctx->callStack); + fnCall *top; + int size = stack->size(); + paramOut(os, csprintf("stacksize[%d]",i), size); + for (int j=0; j<size; ++j) { + top = stack->top(); + paramOut(os, csprintf("ctx[%d].stackpos[%d]",i,j), + top->name); + delete top; + stack->pop(); + } + } + } +} + +void +System::unserialize(Checkpoint *cp, const std::string §ion) +{ + if (bin == true) { + int numCtxs; + UNSERIALIZE_SCALAR(numCtxs); + + SWContext *ctx; + Addr addr; + int size; + for(int i = 0; i < numCtxs; ++i) { + ctx = new SWContext; + paramIn(cp, section, csprintf("Addr[%d]",i), addr); + paramIn(cp, section, csprintf("calls[%d]",i), ctx->calls); + + paramIn(cp, section, csprintf("stacksize[%d]",i), size); + + vector<fnCall *> calls; + fnCall *call; + for (int j = 0; j < size; ++j) { + call = new fnCall; + paramIn(cp, section, csprintf("ctx[%d].stackpos[%d]",i,j), + call->name); + call->myBin = getBin(call->name); + calls.push_back(call); + } + + for (int j=size-1; j>=0; --j) { + ctx->callStack.push(calls[j]); + } + + addContext(addr, ctx); + } + } +} DEFINE_SIM_OBJECT_CLASS_NAME("System", System) diff --git a/sim/system.hh b/sim/system.hh index e5d990e86..7b011aa8f 100644 --- a/sim/system.hh +++ b/sim/system.hh @@ -32,14 +32,11 @@ #include <string> #include <vector> -#include "sim/sim_object.hh" -#include "cpu/pc_event.hh" #include "base/loader/symtab.hh" - -#ifdef FS_MEASURE #include "base/statistics.hh" +#include "cpu/pc_event.hh" +#include "sim/sim_object.hh" #include "sim/sw_context.hh" -#endif class MemoryController; class PhysicalMemory; @@ -51,11 +48,33 @@ class ExecContext; class System : public SimObject { -#ifdef FS_MEASURE + // lisa's binning stuff protected: std::map<const std::string, Statistics::MainBin *> fnBins; std::map<const Addr, SWContext *> swCtxMap; -#endif //FS_MEASURE + + public: + Statistics::Scalar<Counter> fnCalls; + Statistics::MainBin *Kernel; + Statistics::MainBin *User; + + Statistics::MainBin * getBin(const std::string &name); + virtual bool findCaller(std::string, std::string) const = 0; + + SWContext *findContext(Addr pcb); + bool addContext(Addr pcb, SWContext *ctx) { + return (swCtxMap.insert(make_pair(pcb, ctx))).second; + } + void remContext(Addr pcb) { + swCtxMap.erase(pcb); + return; + } + + virtual void dumpState(ExecContext *xc) const = 0; + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); + // public: const uint64_t init_param; @@ -71,11 +90,6 @@ class System : public SimObject virtual int registerExecContext(ExecContext *xc); virtual void replaceExecContext(int xcIndex, ExecContext *xc); -#ifdef FS_MEASURE - Statistics::Scalar<Counter, Statistics::MainBin> fnCalls; - Statistics::MainBin *nonPath; -#endif //FS_MEASURE - public: System(const std::string _name, const uint64_t _init_param, MemoryController *, PhysicalMemory *, const bool); @@ -86,22 +100,6 @@ class System : public SimObject virtual Addr getKernelEntry() const = 0; virtual bool breakpoint() = 0; -#ifdef FS_MEASURE - Statistics::MainBin * getBin(const std::string &name); - virtual bool findCaller(std::string, std::string) const = 0; - - SWContext *findContext(Addr pcb); - bool addContext(Addr pcb, SWContext *ctx) { - return (swCtxMap.insert(make_pair(pcb, ctx))).second; - } - void remContext(Addr pcb) { - swCtxMap.erase(pcb); - return; - } - - virtual void dumpState(ExecContext *xc) const = 0; -#endif //FS_MEASURE - public: //////////////////////////////////////////// // diff --git a/sim/universe.cc b/sim/universe.cc index feede514e..d6c849ac7 100644 --- a/sim/universe.cc +++ b/sim/universe.cc @@ -47,6 +47,7 @@ Tick ticksPerSecond; double __ticksPerMS; double __ticksPerUS; double __ticksPerNS; +double __ticksPerPS; string outputDirectory; ostream *outputStream; @@ -79,6 +80,7 @@ UniverseParamContext::checkParams() __ticksPerMS = freq / 1.0e3; __ticksPerUS = freq / 1.0e6; __ticksPerNS = freq / 1.0e9; + __ticksPerPS = freq / 1.0e12; if (universe_output_dir.isValid()) { outputDirectory = universe_output_dir; diff --git a/util/tracediff b/util/tracediff index fac4f0ec0..0aa579a7d 100755 --- a/util/tracediff +++ b/util/tracediff @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright (c) 2003 The Regents of The University of Michigan +# Copyright (c) 2003-2004 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -39,7 +39,7 @@ $sim2 = shift; # Everything else on the command line is taken to be an m5 argument to # be given to both invocations -$simargs = join(' ', @ARGV); +$simargs = '"' . join('" "', @ARGV) . '"'; $cmd1 = "$sim1 $simargs --stats:file=tracediff-$$-1.stats 2>&1 |"; $cmd2 = "$sim2 $simargs --stats:file=tracediff-$$-2.stats 2>&1 |"; |