merge with m5 head

--HG--
extra : convert_revision : c90339248d1ee74df1c6b90a77ec9ea41f646311
This commit is contained in:
Lisa Hsu 2004-03-11 18:52:29 -05:00
commit 3bc8cffc75
35 changed files with 937 additions and 670 deletions

View file

@ -237,10 +237,17 @@ ExecContext::readIpr(int idx, Fault &fault)
retval = ipr[idx]; retval = ipr[idx];
break; break;
case AlphaISA::IPR_CC:
retval |= ipr[idx] & ULL(0xffffffff00000000);
retval |= curTick & ULL(0x00000000ffffffff);
break;
case AlphaISA::IPR_VA: case AlphaISA::IPR_VA:
// SFX: unlocks interrupt status registers // SFX: unlocks interrupt status registers
retval = ipr[idx]; retval = ipr[idx];
regs.intrlock = false;
if (!misspeculating())
regs.intrlock = false;
break; break;
case AlphaISA::IPR_VA_FORM: case AlphaISA::IPR_VA_FORM:
@ -253,7 +260,7 @@ ExecContext::readIpr(int idx, Fault &fault)
case AlphaISA::IPR_DTB_PTE: 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.ppn & ULL(0x7ffffff)) << 32;
retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8; 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_PAL_BASE:
case AlphaISA::IPR_IC_PERR_STAT: case AlphaISA::IPR_IC_PERR_STAT:
case AlphaISA::IPR_DC_PERR_STAT: case AlphaISA::IPR_DC_PERR_STAT:
case AlphaISA::IPR_CC_CTL:
case AlphaISA::IPR_CC:
case AlphaISA::IPR_PMCTR: case AlphaISA::IPR_PMCTR:
// write entire quad w/ no side-effect // write entire quad w/ no side-effect
ipr[idx] = val; ipr[idx] = val;
break; 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: case AlphaISA::IPR_PALtemp23:
// write entire quad w/ no side-effect // write entire quad w/ no side-effect
ipr[idx] = val; ipr[idx] = val;

View file

@ -5,7 +5,7 @@
let {{ let {{
global rcs_id 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 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: public:
StaticInstPtr<AlphaISA> eaCompInst() { return eaCompPtr; }
StaticInstPtr<AlphaISA> memAccInst() { return memAccPtr; }
/// Constructor /// Constructor
%(class_name)s(MachInst machInst) %(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; %(constructor)s;
} }
@ -1814,6 +1854,9 @@ decode OPCODE default Unknown::unknown() {
0x23: ldt({{ EA = Rb + disp; }}, {{ Fa = Mem.df; }}); 0x23: ldt({{ EA = Rb + disp; }}, {{ Fa = Mem.df; }});
0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED); 0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED);
0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, 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 { format LoadOrPrefetch {
@ -1833,6 +1876,9 @@ decode OPCODE default Unknown::unknown() {
0x0f: stq_u({{ EA = (Rb + disp) & ~7; }}, {{ Mem.uq = Ra.uq; }}); 0x0f: stq_u({{ EA = (Rb + disp) & ~7; }}, {{ Mem.uq = Ra.uq; }});
0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }}); 0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }});
0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }}); 0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }});
0x24: copy_store({{EA = Rb;}},
{{ fault = memAccessObj->copy(EA);}},
IsMemRef, IsStore, IsCopy);
} }
format StoreCond { format StoreCond {
@ -2342,7 +2388,13 @@ decode OPCODE default Unknown::unknown() {
} }
format BasicOperate { 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 // All of the barrier instructions below do nothing in
// their execute() methods (hence the empty code blocks). // their execute() methods (hence the empty code blocks).

View file

@ -224,8 +224,8 @@ namespace {
0, // 0xbc 0, // 0xbc
0, // 0xbd 0, // 0xbd
"nphalt", // 0xbe "nphalt", // 0xbe
"copypal", // 0xbf
#if 0 #if 0
0, // 0xbf
0, // 0xc0 0, // 0xc0
0, // 0xc1 0, // 0xc1
0, // 0xc2 0, // 0xc2

View file

@ -70,6 +70,7 @@ struct PAL
gentrap = 0xaa, gentrap = 0xaa,
clrfen = 0xae, clrfen = 0xae,
nphalt = 0xbe, nphalt = 0xbe,
copypal = 0xbf,
NumCodes NumCodes
}; };

View file

@ -57,7 +57,7 @@ __nan()
} }
#endif #endif
#ifdef STAT_DEBUG #ifdef DEBUG
static int total_stats = 0; static int total_stats = 0;
#endif #endif
@ -409,6 +409,14 @@ DataAccess::setPrint()
Database::StatDB().regPrint(this); Database::StatDB().regPrint(this);
} }
StatData::StatData()
: flags(none), precision(-1), prereq(0)
{
#ifdef DEBUG
number = total_stats++;
#endif
}
StatData::~StatData() StatData::~StatData()
{ {
} }
@ -443,8 +451,8 @@ bool
StatData::baseCheck() const StatData::baseCheck() const
{ {
if (!(flags & init)) { if (!(flags & init)) {
#ifdef STAT_DEBUG #ifdef DEBUG
cprintf("this is stat number %d\n",(*i)->number); cprintf("this is stat number %d\n", number);
#endif #endif
panic("Not all stats have been initialized"); panic("Not all stats have been initialized");
return false; return false;

View file

@ -60,12 +60,6 @@
#include "base/str.hh" #include "base/str.hh"
#include "sim/host.hh" #include "sim/host.hh"
//
// Un-comment this to enable weirdo-stat debugging
//
// #define STAT_DEBUG
#ifndef NAN #ifndef NAN
float __nan(); float __nan();
/** Define Not a number. */ /** Define Not a number. */
@ -146,10 +140,7 @@ struct StatData
/** A pointer to a prerequisite Stat. */ /** A pointer to a prerequisite Stat. */
const StatData *prereq; const StatData *prereq;
StatData() StatData();
: flags(none), precision(-1), prereq(0)
{}
virtual ~StatData(); virtual ~StatData();
/** /**
@ -193,6 +184,10 @@ struct StatData
* @return stat1's name is alphabetically before stat2's * @return stat1's name is alphabetically before stat2's
*/ */
static bool less(StatData *stat1, StatData *stat2); static bool less(StatData *stat1, StatData *stat2);
#ifdef DEBUG
int number;
#endif
}; };
struct ScalarDataBase : public StatData struct ScalarDataBase : public StatData
@ -2503,7 +2498,7 @@ struct NoBin
* binned. If the typedef is NoBin, nothing is binned. If it is * binned. If the typedef is NoBin, nothing is binned. If it is
* MainBin, then all stats are binned under that Bin. * MainBin, then all stats are binned under that Bin.
*/ */
#ifdef FS_MEASURE #if defined(FS_MEASURE)
typedef MainBin DefaultBin; typedef MainBin DefaultBin;
#else #else
typedef NoBin DefaultBin; typedef NoBin DefaultBin;

View file

@ -208,8 +208,7 @@ PrintfRecord::dump(ostream &os)
RawDataRecord::RawDataRecord(Tick _cycle, RawDataRecord::RawDataRecord(Tick _cycle, const void *_data, int _len)
const uint8_t *_data, int _len)
: Record(_cycle), len(_len) : Record(_cycle), len(_len)
{ {
data = new uint8_t[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);
}

View file

@ -108,7 +108,7 @@ namespace Trace {
int len; int len;
public: public:
RawDataRecord(Tick cycle, const uint8_t *_data, int _len); RawDataRecord(Tick cycle, const void *_data, int _len);
virtual ~RawDataRecord(); virtual ~RawDataRecord();
virtual void dump(std::ostream &); virtual void dump(std::ostream &);
@ -149,7 +149,7 @@ namespace Trace {
} }
inline void inline void
rawDump(const uint8_t *data, int len) rawDump(const void *data, int len)
{ {
theLog.append(new Trace::RawDataRecord(curTick, data, len)); theLog.append(new Trace::RawDataRecord(curTick, data, len));
} }

View file

@ -184,6 +184,12 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
newXC->process->replaceExecContext(newXC->cpu_id, newXC); newXC->process->replaceExecContext(newXC->cpu_id, newXC);
#endif #endif
} }
#ifdef FULL_SYSTEM
for (int i = 0; i < NumInterruptLevels; ++i)
interrupts[i] = oldCPU->interrupts[i];
intstatus = oldCPU->intstatus;
#endif
} }

View file

@ -48,10 +48,7 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
kernelStats(this, _cpu), cpu(_cpu), thread_num(_thread_num), kernelStats(this, _cpu), cpu(_cpu), thread_num(_thread_num),
cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys), cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys),
memCtrl(_sys->memCtrl), physmem(_sys->physmem), memCtrl(_sys->memCtrl), physmem(_sys->physmem),
#ifdef FS_MEASURE swCtx(NULL), func_exe_inst(0), storeCondFailures(0)
swCtx(NULL),
#endif
func_exe_inst(0), storeCondFailures(0)
{ {
memset(&regs, 0, sizeof(RegFile)); memset(&regs, 0, sizeof(RegFile));
} }
@ -107,6 +104,33 @@ ExecContext::serialize(ostream &os)
regs.serialize(os); regs.serialize(os);
// thread_num and cpu_id are deterministic from the config // thread_num and cpu_id are deterministic from the config
SERIALIZE_SCALAR(func_exe_inst); 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); regs.unserialize(cp, section);
// thread_num and cpu_id are deterministic from the config // thread_num and cpu_id are deterministic from the config
UNSERIALIZE_SCALAR(func_exe_inst); 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
} }

View file

@ -45,10 +45,7 @@ class MemoryController;
#include "kern/tru64/kernel_stats.hh" #include "kern/tru64/kernel_stats.hh"
#include "sim/system.hh" #include "sim/system.hh"
#ifdef FS_MEASURE
#include "sim/sw_context.hh" #include "sim/sw_context.hh"
#endif
#else // !FULL_SYSTEM #else // !FULL_SYSTEM
@ -137,10 +134,7 @@ class ExecContext
MemoryController *memCtrl; MemoryController *memCtrl;
PhysicalMemory *physmem; PhysicalMemory *physmem;
#ifdef FS_MEASURE
SWContext *swCtx; SWContext *swCtx;
#endif
#else #else
Process *process; Process *process;
@ -153,6 +147,18 @@ class ExecContext
#endif #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 * number of executed instructions, for matching with syscall trace

View file

@ -131,7 +131,8 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data)
case Read: case Read:
if (memcmp(req->data, data, req->size) != 0) { if (memcmp(req->data, data, req->size) != 0) {
cerr << name() << ": on read of 0x" << hex << req->paddr cerr << name() << ": on read of 0x" << hex << req->paddr
<< " @ cycle " << dec << curTick << " (0x" << hex << blockAddr(req->paddr) << ")"
<< "@ cycle " << dec << curTick
<< ", cache returns 0x"; << ", cache returns 0x";
printData(cerr, req->data, req->size); printData(cerr, req->data, req->size);
cerr << ", expected 0x"; cerr << ", expected 0x";
@ -163,11 +164,13 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data)
} }
if (blockAddr(req->paddr) == traceBlockAddr) { if (blockAddr(req->paddr) == traceBlockAddr) {
cerr << hex << traceBlockAddr << ": " << name() << ": completed " cerr << name() << ": completed "
<< (req->cmd.isWrite() ? "write" : "read") << (req->cmd.isWrite() ? "write" : "read")
<< " access of " << " access of "
<< dec << req->size << " bytes at address 0x" << 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); printData(cerr, req->data, req->size);
cerr << " @ cycle " << dec << curTick; cerr << " @ cycle " << dec << curTick;
@ -249,11 +252,13 @@ MemTest::tick()
uint8_t *result = new uint8_t[8]; uint8_t *result = new uint8_t[8];
checkMem->access(Read, req->paddr, result, req->size); checkMem->access(Read, req->paddr, result, req->size);
if (blockAddr(req->paddr) == traceBlockAddr) { if (blockAddr(req->paddr) == traceBlockAddr) {
cerr << hex << traceBlockAddr << ": " << name() cerr << name()
<< ": initiating read " << ": initiating read "
<< ((probe)?"probe of ":"access of ") << ((probe)?"probe of ":"access of ")
<< dec << req->size << " bytes from addr 0x" << 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; << dec << curTick << endl;
} }
if (probe) { if (probe) {
@ -269,13 +274,14 @@ MemTest::tick()
memcpy(req->data, &data, req->size); memcpy(req->data, &data, req->size);
checkMem->access(Write, req->paddr, req->data, req->size); checkMem->access(Write, req->paddr, req->data, req->size);
if (blockAddr(req->paddr) == traceBlockAddr) { if (blockAddr(req->paddr) == traceBlockAddr) {
cerr << hex << traceBlockAddr << ": " cerr << name() << ": initiating write "
<< name() << ": initiating write "
<< ((probe)?"probe of ":"access of ") << ((probe)?"probe of ":"access of ")
<< dec << req->size << " bytes (value = 0x"; << dec << req->size << " bytes (value = 0x";
printData(cerr, req->data, req->size); printData(cerr, req->data, req->size);
cerr << ") to addr 0x" cerr << ") to addr 0x"
<< hex << req->paddr << " at cycle " << hex << req->paddr
<< " (0x" << hex << blockAddr(req->paddr) << ")"
<< " at cycle "
<< dec << curTick << endl; << dec << curTick << endl;
} }
if (probe) { if (probe) {
@ -303,11 +309,15 @@ MemTest::tick()
req->data = new uint8_t[blockSize]; req->data = new uint8_t[blockSize];
req->size = blockSize; req->size = blockSize;
if (source == traceBlockAddr || dest == traceBlockAddr) { if (source == traceBlockAddr || dest == traceBlockAddr) {
cerr << hex << traceBlockAddr << ": " << name() cerr << name()
<< ": initiating copy of " << ": initiating copy of "
<< dec << req->size << " bytes from addr 0x" << dec << req->size << " bytes from addr 0x"
<< hex << source << " to addr 0x" << hex << source
<< hex << dest << " at cycle " << " (0x" << hex << blockAddr(source) << ")"
<< " to addr 0x"
<< hex << dest
<< " (0x" << hex << blockAddr(dest) << ")"
<< " at cycle "
<< dec << curTick << endl; << dec << curTick << endl;
} }
cacheInterface->access(req); cacheInterface->access(req);

View file

@ -120,7 +120,7 @@ SimpleCPU::SimpleCPU(const string &_name,
FunctionalMemory *mem, FunctionalMemory *mem,
MemInterface *icache_interface, MemInterface *icache_interface,
MemInterface *dcache_interface, MemInterface *dcache_interface,
Tick freq) bool _def_reg, Tick freq)
: BaseCPU(_name, /* number_of_threads */ 1, : BaseCPU(_name, /* number_of_threads */ 1,
max_insts_any_thread, max_insts_all_threads, max_insts_any_thread, max_insts_all_threads,
max_loads_any_thread, max_loads_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_any_thread,
Counter max_loads_all_threads, Counter max_loads_all_threads,
MemInterface *icache_interface, MemInterface *icache_interface,
MemInterface *dcache_interface) MemInterface *dcache_interface,
bool _def_reg)
: BaseCPU(_name, /* number_of_threads */ 1, : BaseCPU(_name, /* number_of_threads */ 1,
max_insts_any_thread, max_insts_all_threads, max_insts_any_thread, max_insts_all_threads,
max_loads_any_thread, max_loads_all_threads), max_loads_any_thread, max_loads_all_threads),
#endif #endif
tickEvent(this), xc(NULL), cacheCompletionEvent(this) tickEvent(this), xc(NULL), defer_registration(_def_reg),
cacheCompletionEvent(this)
{ {
_status = Idle; _status = Idle;
#ifdef FULL_SYSTEM #ifdef FULL_SYSTEM
@ -171,6 +173,13 @@ SimpleCPU::~SimpleCPU()
{ {
} }
void SimpleCPU::init()
{
if (!defer_registration) {
this->registerExecContexts();
}
}
void void
SimpleCPU::switchOut() 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 // precise architected memory state accessor macros
template <class T> template <class T>
Fault Fault
@ -343,7 +392,6 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
memReq->cmd = Read; memReq->cmd = Read;
memReq->completionEvent = NULL; memReq->completionEvent = NULL;
memReq->time = curTick; memReq->time = curTick;
memReq->flags &= ~UNCACHEABLE;
MemAccessResult result = dcacheInterface->access(memReq); MemAccessResult result = dcacheInterface->access(memReq);
// Ugly hack to get an event scheduled *only* if the access is // 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); memcpy(memReq->data,(uint8_t *)&data,memReq->size);
memReq->completionEvent = NULL; memReq->completionEvent = NULL;
memReq->time = curTick; memReq->time = curTick;
memReq->flags &= ~UNCACHEABLE;
MemAccessResult result = dcacheInterface->access(memReq); MemAccessResult result = dcacheInterface->access(memReq);
// Ugly hack to get an event scheduled *only* if the access is // Ugly hack to get an event scheduled *only* if the access is
@ -629,7 +676,6 @@ SimpleCPU::tick()
memReq->completionEvent = NULL; memReq->completionEvent = NULL;
memReq->time = curTick; memReq->time = curTick;
memReq->flags &= ~UNCACHEABLE;
MemAccessResult result = icacheInterface->access(memReq); MemAccessResult result = icacheInterface->access(memReq);
// Ugly hack to get an event scheduled *only* if the access is // Ugly hack to get an event scheduled *only* if the access is
@ -669,32 +715,13 @@ SimpleCPU::tick()
xc->func_exe_inst++; xc->func_exe_inst++;
fault = si->execute(this, xc, traceData); 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); #ifdef FULL_SYSTEM
} else { SWContext *ctx = xc->swCtx;
ctx->calls--; if (ctx)
} ctx->process(xc, si.get());
}
}
}
#endif #endif
if (si->isMemRef()) { if (si->isMemRef()) {
numMemRefs++; numMemRefs++;
} }
@ -813,6 +840,7 @@ CREATE_SIM_OBJECT(SimpleCPU)
itb, dtb, mem, itb, dtb, mem,
(icache) ? icache->getInterface() : NULL, (icache) ? icache->getInterface() : NULL,
(dcache) ? dcache->getInterface() : NULL, (dcache) ? dcache->getInterface() : NULL,
defer_registration,
ticksPerSecond * mult); ticksPerSecond * mult);
#else #else
@ -820,14 +848,15 @@ CREATE_SIM_OBJECT(SimpleCPU)
max_insts_any_thread, max_insts_all_threads, max_insts_any_thread, max_insts_all_threads,
max_loads_any_thread, max_loads_all_threads, max_loads_any_thread, max_loads_all_threads,
(icache) ? icache->getInterface() : NULL, (icache) ? icache->getInterface() : NULL,
(dcache) ? dcache->getInterface() : NULL); (dcache) ? dcache->getInterface() : NULL,
defer_registration);
#endif // FULL_SYSTEM #endif // FULL_SYSTEM
#if 0
if (!defer_registration) { if (!defer_registration) {
cpu->registerExecContexts(); cpu->registerExecContexts();
} }
#endif
return cpu; return cpu;
} }

View file

@ -133,7 +133,7 @@ class SimpleCPU : public BaseCPU
Counter max_loads_any_thread, Counter max_loads_all_threads, Counter max_loads_any_thread, Counter max_loads_all_threads,
AlphaItb *itb, AlphaDtb *dtb, FunctionalMemory *mem, AlphaItb *itb, AlphaDtb *dtb, FunctionalMemory *mem,
MemInterface *icache_interface, MemInterface *dcache_interface, MemInterface *icache_interface, MemInterface *dcache_interface,
Tick freq); bool _def_reg, Tick freq);
#else #else
@ -142,11 +142,13 @@ class SimpleCPU : public BaseCPU
Counter max_insts_all_threads, Counter max_insts_all_threads,
Counter max_loads_any_thread, Counter max_loads_any_thread,
Counter max_loads_all_threads, Counter max_loads_all_threads,
MemInterface *icache_interface, MemInterface *dcache_interface); MemInterface *icache_interface, MemInterface *dcache_interface,
bool _def_reg);
#endif #endif
virtual ~SimpleCPU(); virtual ~SimpleCPU();
virtual void init();
// execution context // execution context
ExecContext *xc; ExecContext *xc;
@ -166,6 +168,8 @@ class SimpleCPU : public BaseCPU
// L1 data cache // L1 data cache
MemInterface *dcacheInterface; MemInterface *dcacheInterface;
bool defer_registration;
// current instruction // current instruction
MachInst inst; MachInst inst;
@ -233,16 +237,19 @@ class SimpleCPU : public BaseCPU
Fault write(T data, Addr addr, unsigned flags, Fault write(T data, Addr addr, unsigned flags,
uint64_t *res); uint64_t *res);
Fault prefetch(Addr addr, unsigned flags) void prefetch(Addr addr, unsigned flags)
{ {
// need to do this... // need to do this...
return No_Fault;
} }
void writeHint(Addr addr, int size) void writeHint(Addr addr, int size)
{ {
// need to do this... // need to do this...
} }
Fault copySrcTranslate(Addr src);
Fault copy(Addr dest);
}; };
#endif // __SIMPLE_CPU_HH__ #endif // __SIMPLE_CPU_HH__

View file

@ -96,6 +96,7 @@ class StaticInstBase : public RefCounted
IsStore, ///< Writes to memory. IsStore, ///< Writes to memory.
IsInstPrefetch, ///< Instruction-cache prefetch. IsInstPrefetch, ///< Instruction-cache prefetch.
IsDataPrefetch, ///< Data-cache prefetch. IsDataPrefetch, ///< Data-cache prefetch.
IsCopy, ///< Fast Cache block copy
IsControl, ///< Control transfer instruction. IsControl, ///< Control transfer instruction.
IsDirectControl, ///< PC relative control transfer. IsDirectControl, ///< PC relative control transfer.
@ -176,6 +177,7 @@ class StaticInstBase : public RefCounted
bool isStore() const { return flags[IsStore]; } bool isStore() const { return flags[IsStore]; }
bool isInstPrefetch() const { return flags[IsInstPrefetch]; } bool isInstPrefetch() const { return flags[IsInstPrefetch]; }
bool isDataPrefetch() const { return flags[IsDataPrefetch]; } bool isDataPrefetch() const { return flags[IsDataPrefetch]; }
bool isCopy() const { return flags[IsCopy];}
bool isInteger() const { return flags[IsInteger]; } bool isInteger() const { return flags[IsInteger]; }
bool isFloating() const { return flags[IsFloating]; } bool isFloating() const { return flags[IsFloating]; }

View file

@ -43,6 +43,9 @@
#include "dev/console.hh" #include "dev/console.hh"
#include "dev/simple_disk.hh" #include "dev/simple_disk.hh"
#include "dev/tlaser_clock.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 "mem/functional_mem/memory_control.hh"
#include "sim/builder.hh" #include "sim/builder.hh"
#include "sim/system.hh" #include "sim/system.hh"
@ -50,14 +53,21 @@
using namespace std; using namespace std;
AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
SimpleDisk *d, System *system, System *system, BaseCPU *cpu, TsunamiIO *clock,
BaseCPU *cpu, TsunamiIO *clock, int num_cpus, int num_cpus, MemoryController *mmu, Addr a,
Addr a, MemoryController *mmu) HierParams *hier, Bus *bus)
: FunctionalMemory(name), disk(d), console(cons), addr(a) : PioDevice(name), disk(d), console(cons), addr(a)
>>>>>>>
{ {
mmu->add_child(this, Range<Addr>(addr, addr + size)); 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]; consoleData = new uint8_t[size];
memset(consoleData, 0, size); memset(consoleData, 0, size);
@ -185,6 +195,12 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
return No_Fault; return No_Fault;
} }
Tick
AlphaConsole::cacheAccess(MemReqPtr &req)
{
return curTick + 1000;
}
void void
AlphaAccess::serialize(ostream &os) AlphaAccess::serialize(ostream &os)
{ {
@ -253,6 +269,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
SimObjectParam<System *> system; SimObjectParam<System *> system;
SimObjectParam<BaseCPU *> cpu; SimObjectParam<BaseCPU *> cpu;
SimObjectParam<TsunamiIO *> clock; SimObjectParam<TsunamiIO *> clock;
SimObjectParam<Bus*> io_bus;
SimObjectParam<HierParams *> hier;
END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
@ -265,14 +283,17 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
INIT_PARAM(addr, "Device Address"), INIT_PARAM(addr, "Device Address"),
INIT_PARAM(system, "system object"), INIT_PARAM(system, "system object"),
INIT_PARAM(cpu, "Processor"), 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) END_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
CREATE_SIM_OBJECT(AlphaConsole) CREATE_SIM_OBJECT(AlphaConsole)
{ {
return new AlphaConsole(getInstanceName(), sim_console, disk, return new AlphaConsole(getInstanceName(), sim_console, disk,
system, cpu, clock, num_cpus, addr, mmu); system, cpu, clock, num_cpus, mmu,
addr, hier, io_bus);
} }
REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole) REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole)

View file

@ -35,7 +35,7 @@
#include "base/range.hh" #include "base/range.hh"
#include "dev/alpha_access.h" #include "dev/alpha_access.h"
#include "mem/functional_mem/functional_memory.hh" #include "dev/io_device.hh"
#include "sim/host.hh" #include "sim/host.hh"
#include "dev/tsunami_io.hh" #include "dev/tsunami_io.hh"
@ -70,7 +70,7 @@ class SimpleDisk;
* primarily used doing boot before the kernel has loaded its device * primarily used doing boot before the kernel has loaded its device
* drivers. * drivers.
*/ */
class AlphaConsole : public FunctionalMemory class AlphaConsole : public PioDevice
{ {
protected: protected:
union { union {
@ -89,10 +89,10 @@ class AlphaConsole : public FunctionalMemory
public: public:
/** Standard Constructor */ /** Standard Constructor */
AlphaConsole(const std::string &name, SimConsole *cons, AlphaConsole(const std::string &name, SimConsole *cons, SimpleDisk *d,
SimpleDisk *d, System *system, BaseCPU *cpu, System *system, BaseCPU *cpu, TsunamiIO *clock,
TsunamiIO *clock, int num_cpus, int num_cpus, MemoryController *mmu, Addr addr,
Addr a, MemoryController *mmu); HierParams *hier, Bus *bus);
/** /**
* memory mapped reads and writes * memory mapped reads and writes
@ -105,6 +105,9 @@ class AlphaConsole : public FunctionalMemory
*/ */
virtual void serialize(std::ostream &os); virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section); virtual void unserialize(Checkpoint *cp, const std::string &section);
public:
Tick cacheAccess(MemReqPtr &req);
}; };
#endif // __ALPHA_CONSOLE_HH__ #endif // __ALPHA_CONSOLE_HH__

View file

@ -34,6 +34,7 @@
#include <string> #include <string>
#include "base/misc.hh"
#include "dev/etherdump.hh" #include "dev/etherdump.hh"
#include "sim/builder.hh" #include "sim/builder.hh"
#include "sim/universe.hh" #include "sim/universe.hh"
@ -43,11 +44,8 @@ using std::string;
EtherDump::EtherDump(const string &name, const string &file) EtherDump::EtherDump(const string &name, const string &file)
: SimObject(name) : SimObject(name)
{ {
if (!file.empty()) { if (!file.empty())
stream.open(file.c_str()); stream.open(file.c_str());
if (stream.is_open())
init();
}
} }
#define DLT_EN10MB 1 // Ethernet (10Mb) #define DLT_EN10MB 1 // Ethernet (10Mb)
@ -66,7 +64,8 @@ struct pcap_file_header {
}; };
struct pcap_pkthdr { struct pcap_pkthdr {
struct timeval ts; // time stamp uint32_t seconds;
uint32_t microseconds;
uint32_t caplen; // length of portion present uint32_t caplen; // length of portion present
uint32_t len; // length this packet (off wire) uint32_t len; // length this packet (off wire)
}; };
@ -74,6 +73,9 @@ struct pcap_pkthdr {
void void
EtherDump::init() EtherDump::init()
{ {
if (!stream.is_open())
return;
curtime = time(NULL); curtime = time(NULL);
s_freq = ticksPerSecond; s_freq = ticksPerSecond;
us_freq = ticksPerSecond / ULL(1000000); us_freq = ticksPerSecond / ULL(1000000);
@ -96,8 +98,8 @@ EtherDump::init()
* to sim_cycles. * to sim_cycles.
*/ */
pcap_pkthdr pkthdr; pcap_pkthdr pkthdr;
pkthdr.ts.tv_sec = curtime; pkthdr.seconds = curtime;
pkthdr.ts.tv_usec = 0; pkthdr.microseconds = 0;
pkthdr.caplen = 0; pkthdr.caplen = 0;
pkthdr.len = 0; pkthdr.len = 0;
stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr)); stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr));
@ -109,8 +111,8 @@ void
EtherDump::dumpPacket(PacketPtr &packet) EtherDump::dumpPacket(PacketPtr &packet)
{ {
pcap_pkthdr pkthdr; pcap_pkthdr pkthdr;
pkthdr.ts.tv_sec = curtime + (curTick / s_freq); pkthdr.seconds = curtime + (curTick / s_freq);
pkthdr.ts.tv_usec = (curTick / us_freq) % ULL(1000000); pkthdr.microseconds = (curTick / us_freq) % ULL(1000000);
pkthdr.caplen = packet->length; pkthdr.caplen = packet->length;
pkthdr.len = packet->length; pkthdr.len = packet->length;
stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr)); stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr));

View file

@ -42,17 +42,19 @@
#include "dev/etherpkt.hh" #include "dev/etherpkt.hh"
#include "sim/builder.hh" #include "sim/builder.hh"
#include "sim/universe.hh" #include "sim/universe.hh"
#include "sim/system.hh"
using namespace std; using namespace std;
EtherLink::EtherLink(const std::string &name, EtherInt *i1, EtherInt *i2, EtherLink::EtherLink(const string &name, EtherInt *i1, EtherInt *i2,
Tick speed, EtherDump *dump) Tick speed, Tick dly, EtherDump *dump)
: SimObject(name) : SimObject(name)
{ {
double rate = ((double)ticksPerSecond * 8.0) / (double)speed; double rate = ((double)ticksPerSecond * 8.0) / (double)speed;
Tick delay = US2Ticks(dly);
link1 = new Link(name + ".link1", rate, dump); link1 = new Link(name + ".link1", rate, delay, dump);
link2 = new Link(name + ".link2", rate, dump); link2 = new Link(name + ".link2", rate, delay, dump);
int1 = new Interface(name + ".int1", link1, link2); int1 = new Interface(name + ".int1", link1, link2);
int2 = new Interface(name + ".int2", link2, link1); int2 = new Interface(name + ".int2", link2, link1);
@ -72,28 +74,76 @@ EtherLink::~EtherLink()
delete int2; 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) : EtherInt(name), txlink(tx)
{ {
tx->setTxInt(this); tx->setTxInt(this);
rx->setRxInt(this); rx->setRxInt(this);
} }
EtherLink::Link::Link(const std::string &name, double rate, EtherDump *d) EtherLink::Link::Link(const string &name, double rate, Tick delay,
: objName(name), txint(NULL), rxint(NULL), ticks_per_byte(rate), EtherDump *d)
dump(d), event(&mainEventQueue, this) : 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 &section)
{
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 &section);
static Serializable *createForUnserialize(Checkpoint *cp,
const string &section);
};
void void
EtherLink::Link::txDone() EtherLink::Link::txDone()
{ {
if (dump) if (dump)
dump->dump(packet); dump->dump(packet);
DPRINTF(Ethernet, "EtherLink packet received: len=%d\n", packet->length); if (linkDelay > 0) {
DDUMP(EthernetData, packet->data, packet->length); DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay);
new LinkDelayEvent(this, packet, curTick + linkDelay);
rxint->sendPacket(packet); } else {
txComplete(packet);
}
packet = 0; packet = 0;
assert(!busy()); assert(!busy());
@ -105,27 +155,118 @@ bool
EtherLink::Link::transmit(PacketPtr &pkt) EtherLink::Link::transmit(PacketPtr &pkt)
{ {
if (busy()) { if (busy()) {
DPRINTF(Ethernet, "EtherLink packet not sent, link busy\n"); DPRINTF(Ethernet, "packet not sent, link busy\n");
return false; 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); DDUMP(EthernetData, pkt->data, pkt->length);
packet = pkt; packet = pkt;
int delay = (int)ceil(((double)pkt->length * ticks_per_byte) + 1.0); Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0);
DPRINTF(Ethernet, "EtherLink scheduling packet: delay=%d, (rate=%f)\n", DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n",
delay, ticks_per_byte); delay, ticksPerByte);
event.schedule(curTick + delay); doneEvent.schedule(curTick + delay);
return true; 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 &section)
{
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 &section)
{
Event::unserialize(cp, section);
packet = new EtherPacket;
packet->unserialize(cp, csprintf("%s.packet", section));
}
Serializable *
LinkDelayEvent::createForUnserialize(Checkpoint *cp, const string &section)
{
EtherLink::Link *link;
UNSERIALIZE_OBJPTR(link);
return new LinkDelayEvent(link);
}
REGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent)
BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink) BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink)
SimObjectParam<EtherInt *> interface1; SimObjectParam<EtherInt *> interface1;
SimObjectParam<EtherInt *> interface2; SimObjectParam<EtherInt *> interface2;
Param<Tick> link_speed; Param<Tick> link_speed;
Param<Tick> link_delay;
SimObjectParam<EtherDump *> packet_dump; SimObjectParam<EtherDump *> packet_dump;
END_DECLARE_SIM_OBJECT_PARAMS(EtherLink) END_DECLARE_SIM_OBJECT_PARAMS(EtherLink)
@ -135,6 +276,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink)
INIT_PARAM(interface1, "interface 1"), INIT_PARAM(interface1, "interface 1"),
INIT_PARAM(interface2, "interface 2"), INIT_PARAM(interface2, "interface 2"),
INIT_PARAM_DFLT(link_speed, "link speed in bits per second", 100000000), 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) INIT_PARAM_DFLT(packet_dump, "object to dump network packets to", NULL)
END_INIT_SIM_OBJECT_PARAMS(EtherLink) END_INIT_SIM_OBJECT_PARAMS(EtherLink)
@ -142,7 +284,7 @@ END_INIT_SIM_OBJECT_PARAMS(EtherLink)
CREATE_SIM_OBJECT(EtherLink) CREATE_SIM_OBJECT(EtherLink)
{ {
return new EtherLink(getInstanceName(), interface1, interface2, link_speed, return new EtherLink(getInstanceName(), interface1, interface2, link_speed,
packet_dump); link_delay, packet_dump);
} }
REGISTER_SIM_OBJECT("EtherLink", EtherLink) REGISTER_SIM_OBJECT("EtherLink", EtherLink)

View file

@ -49,6 +49,7 @@ class EtherLink : public SimObject
protected: protected:
class Interface; class Interface;
friend class LinkDelayEvent;
/* /*
* Model for a single uni-directional link * Model for a single uni-directional link
*/ */
@ -59,34 +60,26 @@ class EtherLink : public SimObject
Interface *txint; Interface *txint;
Interface *rxint; Interface *rxint;
double ticks_per_byte; double ticksPerByte;
Tick linkDelay;
EtherDump *dump; EtherDump *dump;
protected: protected:
/* /*
* Transfer is complete * 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; PacketPtr packet;
void txDone(); void txDone();
typedef EventWrapper<Link, &Link::txDone> DoneEvent;
friend class DoneEvent;
DoneEvent doneEvent;
friend class LinkDelayEvent;
void txComplete(PacketPtr &packet);
public: public:
Link(const std::string &name, double rate, EtherDump *dump); Link(const std::string &name, double rate, Tick delay,
EtherDump *dump);
~Link() {} ~Link() {}
virtual const std::string name() const { return objName; } 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 setTxInt(Interface *i) { assert(!txint); txint = i; }
void setRxInt(Interface *i) { assert(!rxint); rxint = i; } void setRxInt(Interface *i) { assert(!rxint); rxint = i; }
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
}; };
/* /*
@ -120,8 +116,12 @@ class EtherLink : public SimObject
public: public:
EtherLink(const std::string &name, EtherInt *i1, EtherInt *i2, EtherLink(const std::string &name, EtherInt *i1, EtherInt *i2,
Tick speed, EtherDump *dump); Tick speed, Tick delay, EtherDump *dump);
virtual ~EtherLink(); virtual ~EtherLink();
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
}; };
#endif // __ETHERLINK_HH__ #endif // __ETHERLINK_HH__

50
dev/etherpkt.cc Normal file
View file

@ -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 &section)
{
UNSERIALIZE_SCALAR(length);
data = new uint8_t[length];
UNSERIALIZE_ARRAY(data, length);
}

View file

@ -33,10 +33,10 @@
#ifndef __ETHERPKT_HH__ #ifndef __ETHERPKT_HH__
#define __ETHERPKT_HH__ #define __ETHERPKT_HH__
#include <iosfwd>
#include <memory> #include <memory>
#include "sim/host.hh" #include "sim/host.hh"
#include "base/refcnt.hh" #include "base/refcnt.hh"
class Checkpoint; class Checkpoint;

52
dev/io_device.cc Normal file
View file

@ -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;
}

59
dev/io_device.hh Normal file
View file

@ -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__

View file

@ -35,11 +35,8 @@
#include "kern/tru64/tru64_events.hh" #include "kern/tru64/tru64_events.hh"
#include "mem/functional_mem/memory_control.hh" #include "mem/functional_mem/memory_control.hh"
#include "targetarch/arguments.hh" #include "targetarch/arguments.hh"
#ifdef FS_MEASURE
#include "sim/system.hh" #include "sim/system.hh"
#include "sim/sw_context.hh" #include "sim/sw_context.hh"
#endif
void void
SkipFuncEvent::process(ExecContext *xc) 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) FnEvent::FnEvent(PCEventQueue *q, const std::string & desc, System *system)
: PCEvent(q, desc), _name(desc) : PCEvent(q, desc), _name(desc)
{ {
@ -128,13 +124,25 @@ FnEvent::process(ExecContext *xc)
DPRINTF(TCPIP, "%s: %s Event!!!\n", xc->system->name(), description); DPRINTF(TCPIP, "%s: %s Event!!!\n", xc->system->name(), description);
if (ctx && !ctx->callStack.empty()) { if (ctx && !ctx->callStack.empty()) {
DPRINTF(TCPIP, "already a callstack!\n");
fnCall *last = ctx->callStack.top(); 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; return;
} }
ctx->calls--; ctx->calls--;
//assert(!ctx->calls && "on a binned fn, calls should == 0 (but can happen in boot)");
} else { } else {
DPRINTF(TCPIP, "no callstack yet\n");
if (!xc->system->findCaller(myname(), "")) { if (!xc->system->findCaller(myname(), "")) {
DPRINTF(TCPIP, "not the right function, returning\n");
return; return;
} }
if (!ctx) { if (!ctx) {
@ -150,6 +158,7 @@ FnEvent::process(ExecContext *xc)
ctx->callStack.push(call); ctx->callStack.push(call);
myBin->activate(); myBin->activate();
xc->system->fnCalls++; xc->system->fnCalls++;
DPRINTF(TCPIP, "fnCalls for %s is %d\n", description,
xc->system->fnCalls.val());
xc->system->dumpState(xc); xc->system->dumpState(xc);
} }
#endif //FS_MEASURE

View file

@ -35,9 +35,7 @@
class ExecContext; class ExecContext;
#ifdef FS_MEASURE
class System; class System;
#endif
class SkipFuncEvent : public PCEvent class SkipFuncEvent : public PCEvent
{ {
@ -82,7 +80,6 @@ class DumpMbufEvent : public PCEvent
virtual void process(ExecContext *xc); virtual void process(ExecContext *xc);
}; };
#ifdef FS_MEASURE
class FnEvent : public PCEvent class FnEvent : public PCEvent
{ {
public: public:
@ -94,5 +91,4 @@ class FnEvent : public PCEvent
std::string _name; std::string _name;
Statistics::MainBin *myBin; Statistics::MainBin *myBin;
}; };
#endif //FS_MEASURE
#endif // __TRU64_EVENTS_HH__ #endif // __TRU64_EVENTS_HH__

View file

@ -41,17 +41,15 @@
#include "targetarch/isa_traits.hh" #include "targetarch/isa_traits.hh"
#include "targetarch/vtophys.hh" #include "targetarch/vtophys.hh"
//un-comment this to see the state of call stack when it changes.
//#define SW_DEBUG
using namespace std; using namespace std;
Tru64System::Tru64System(const string _name, const uint64_t _init_param, Tru64System::Tru64System(const string _name, const uint64_t _init_param,
MemoryController *_memCtrl, PhysicalMemory *_physmem, MemoryController *_memCtrl, PhysicalMemory *_physmem,
const string &kernel_path, const string &console_path, const string &kernel_path, const string &console_path,
const string &palcode, const string &boot_osflags, const string &palcode, const string &boot_osflags,
const bool _bin) const bool _bin, const vector<string> &binned_fns)
: System(_name, _init_param, _memCtrl, _physmem, _bin), bin(_bin) : System(_name, _init_param, _memCtrl, _physmem, _bin),
bin(_bin), binned_fns(binned_fns)
{ {
kernelSymtab = new SymbolTable; kernelSymtab = new SymbolTable;
consoleSymtab = new SymbolTable; consoleSymtab = new SymbolTable;
@ -92,106 +90,6 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param,
DPRINTF(Loader, "Kernel loaded...\n"); 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 #ifdef DEBUG
kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic"); kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic");
consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic"); consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic");
@ -208,44 +106,6 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param,
"debug_printfr", true); "debug_printfr", true);
dumpMbufEvent = new DumpMbufEvent(&pcEventQueue, "dump_mbuf"); 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; Addr addr = 0;
if (kernelSymtab->findAddress("enable_async_printf", addr)) { if (kernelSymtab->findAddress("enable_async_printf", addr)) {
Addr paddr = vtophys(physmem, addr); Addr paddr = vtophys(physmem, addr);
@ -299,212 +159,38 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param,
dumpMbufEvent->schedule(addr); dumpMbufEvent->schedule(addr);
#endif #endif
#ifdef FS_MEASURE // BINNING STUFF
//INSTRUMENTATION CODEGEN BEGIN THREE
if (bin == true) { if (bin == true) {
if (kernelSymtab->findAddress("es_intr", addr)) int end = binned_fns.size();
esIntrEvent->schedule(addr); assert(!(end & 1));
else
panic("could not find kernel symbol \'es_intr\'");
if (kernelSymtab->findAddress("es_rxeof", addr)) Statistics::MainBin *Bin;
esRxeofEvent->schedule(addr); Addr address = 0;
else
panic("could not find kernel symbol \'es_rxeof\'");
if (kernelSymtab->findAddress("es_newbuf", addr)) fnEvents.resize(end>>1);
esNewbufEvent->schedule(addr);
else
panic("could not find kernel symbol \'es_newbuf\'");
if (kernelSymtab->findAddress("es_dma_load", addr)) for (int i = 0; i < end; i +=2) {
esDmaLoadEvent->schedule(addr); Bin = new Statistics::MainBin(binned_fns[i]);
else fnBins.insert(make_pair(binned_fns[i], Bin));
panic("could not find kernel symbol \'es_dma_load\'");
if (kernelSymtab->findAddress("dma_map_load", addr)) fnEvents[(i>>1)] = new FnEvent(&pcEventQueue, binned_fns[i], this);
dmaMapLoadEvent->schedule(addr); if (kernelSymtab->findAddress(binned_fns[i], address))
else fnEvents[(i>>1)]->schedule(address);
panic("could not find kernel symbol \'dma_map_load\'"); else
panic("could not find kernel symbol %s\n", binned_fns[i]);
if (kernelSymtab->findAddress("ether_input", addr)) if (binned_fns[i+1] == "null")
etherInputEvent->schedule(addr); populateMap(binned_fns[i], "");
else else
panic("could not find kernel symbol \'ether_input\'"); populateMap(binned_fns[i], binned_fns[i+1]);
}
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\'");
}
//INSTRUMENTATION CODEGEN END
if (bin == true) {
fnCalls fnCalls
.name(name() + ":fnCalls") .name(name() + ":fnCalls")
.desc("all fn calls being tracked") .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() Tru64System::~Tru64System()
@ -527,43 +213,13 @@ Tru64System::~Tru64System()
delete debugPrintfrEvent; delete debugPrintfrEvent;
delete dumpMbufEvent; delete dumpMbufEvent;
#ifdef FS_MEASURE
//INSTRUMENTATION CODEGEN BEGIN FOUR
if (bin == true) { if (bin == true) {
delete esIntrEvent; int end = fnEvents.size();
delete esRxeofEvent; for (int i = 0; i < end; ++i) {
delete esNewbufEvent; delete fnEvents[i];
delete esDmaLoadEvent; }
delete dmaMapLoadEvent; fnEvents.clear();
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;
} }
//INSTRUMENTATION CODEGEN END
#endif //FS_MEASURE
} }
int int
@ -604,7 +260,6 @@ Tru64System::breakpoint()
return remoteGDB[0]->trap(ALPHA_KENTRY_INT); return remoteGDB[0]->trap(ALPHA_KENTRY_INT);
} }
#ifdef FS_MEASURE
void void
Tru64System::populateMap(std::string callee, std::string caller) Tru64System::populateMap(std::string callee, std::string caller)
{ {
@ -630,23 +285,19 @@ Tru64System::findCaller(std::string callee, std::string caller) const
void void
Tru64System::dumpState(ExecContext *xc) const Tru64System::dumpState(ExecContext *xc) const
{ {
#ifndef SW_DEBUG
return;
#endif
if (xc->swCtx) { if (xc->swCtx) {
stack<fnCall *> copy(xc->swCtx->callStack); stack<fnCall *> copy(xc->swCtx->callStack);
if (copy.empty()) if (copy.empty())
return; return;
cprintf("xc->swCtx:\n"); DPRINTF(TCPIP, "xc->swCtx, size: %d:\n", copy.size());
fnCall *top; 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() ) { for (top = copy.top(); !copy.empty(); copy.pop() ) {
top = copy.top(); 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) BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64System)
@ -659,6 +310,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64System)
Param<string> console_code; Param<string> console_code;
Param<string> pal_code; Param<string> pal_code;
Param<string> boot_osflags; Param<string> boot_osflags;
VectorParam<string> binned_fns;
END_DECLARE_SIM_OBJECT_PARAMS(Tru64System) 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(console_code, "file that contains the console code"),
INIT_PARAM(pal_code, "file that contains palcode"), INIT_PARAM(pal_code, "file that contains palcode"),
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", 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) END_INIT_SIM_OBJECT_PARAMS(Tru64System)
@ -681,7 +333,8 @@ CREATE_SIM_OBJECT(Tru64System)
{ {
Tru64System *sys = new Tru64System(getInstanceName(), init_param, mem_ctl, Tru64System *sys = new Tru64System(getInstanceName(), init_param, mem_ctl,
physmem, kernel_code, console_code, physmem, kernel_code, console_code,
pal_code, boot_osflags, bin); pal_code, boot_osflags, bin,
binned_fns);
return sys; return sys;
} }

View file

@ -29,15 +29,12 @@
#ifndef __TRU64_SYSTEM_HH__ #ifndef __TRU64_SYSTEM_HH__
#define __TRU64_SYSTEM_HH__ #define __TRU64_SYSTEM_HH__
#include <map>
#include <vector> #include <vector>
#include "sim/system.hh" #include "sim/system.hh"
#include "targetarch/isa_traits.hh" #include "targetarch/isa_traits.hh"
#ifdef FS_MEASURE
#include <map>
#endif
class ExecContext; class ExecContext;
class EcoffObject; class EcoffObject;
class SymbolTable; class SymbolTable;
@ -48,9 +45,7 @@ class SkipFuncEvent;
class PrintfEvent; class PrintfEvent;
class DebugPrintfEvent; class DebugPrintfEvent;
class DumpMbufEvent; class DumpMbufEvent;
#ifdef FS_MEASURE
class FnEvent; class FnEvent;
#endif
class AlphaArguments; class AlphaArguments;
class Tru64System : public System class Tru64System : public System
@ -62,42 +57,6 @@ class Tru64System : public System
SymbolTable *kernelSymtab; SymbolTable *kernelSymtab;
SymbolTable *consoleSymtab; 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 *kernelPanicEvent;
BreakPCEvent *consolePanicEvent; BreakPCEvent *consolePanicEvent;
BadAddrEvent *badaddrEvent; BadAddrEvent *badaddrEvent;
@ -107,41 +66,8 @@ class Tru64System : public System
DebugPrintfEvent *debugPrintfEvent; DebugPrintfEvent *debugPrintfEvent;
DebugPrintfEvent *debugPrintfrEvent; DebugPrintfEvent *debugPrintfrEvent;
DumpMbufEvent *dumpMbufEvent; DumpMbufEvent *dumpMbufEvent;
#ifdef FS_MEASURE
//INSTRUMENTATION CODEGEN BEGIN TWO std::vector<FnEvent *> fnEvents;
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
private: private:
@ -149,11 +75,7 @@ class Tru64System : public System
Addr kernelEnd; Addr kernelEnd;
Addr kernelEntry; Addr kernelEntry;
bool bin; bool bin;
std::vector<string> binned_fns;
#ifdef FS_MEASURE
std::multimap<const std::string, std::string> callerMap;
void populateMap(std::string caller, std::string callee);
#endif
public: public:
std::vector<RemoteGDB *> remoteGDB; std::vector<RemoteGDB *> remoteGDB;
@ -168,7 +90,8 @@ class Tru64System : public System
const std::string &console_path, const std::string &console_path,
const std::string &palcode, const std::string &palcode,
const std::string &boot_osflags, const std::string &boot_osflags,
const bool _bin); const bool _bin,
const std::vector<string> &binned_fns);
~Tru64System(); ~Tru64System();
int registerExecContext(ExecContext *xc); int registerExecContext(ExecContext *xc);
@ -182,10 +105,16 @@ class Tru64System : public System
static void Printf(AlphaArguments args); static void Printf(AlphaArguments args);
static void DumpMbuf(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; bool findCaller(std::string callee, std::string caller) const;
void dumpState(ExecContext *xc) const; void dumpState(ExecContext *xc) const;
#endif //FS_MEASURE //
}; };
#endif // __TRU64_SYSTEM_HH__ #endif // __TRU64_SYSTEM_HH__

View file

@ -236,6 +236,23 @@ DelayFunction(Tick when, T *object)
new DelayEvent(when, 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 * Queue of events sorted in time order
*/ */
@ -310,6 +327,8 @@ inline void
Event::schedule(Tick t) Event::schedule(Tick t)
{ {
assert(!scheduled()); assert(!scheduled());
assert(t >= curTick);
setFlags(Scheduled); setFlags(Scheduled);
#if TRACING_ON #if TRACING_ON
when_scheduled = curTick; when_scheduled = curTick;

View file

@ -28,11 +28,13 @@
#include <string> #include <string>
#include "sim/param.hh" #include "base/callback.hh"
#include "sim/eventq.hh"
#include "base/hostinfo.hh" #include "base/hostinfo.hh"
#include "sim/eventq.hh"
#include "sim/param.hh"
#include "sim/sim_events.hh" #include "sim/sim_events.hh"
#include "sim/sim_exit.hh" #include "sim/sim_exit.hh"
#include "sim/sim_init.hh"
#include "sim/sim_stats.hh" #include "sim/sim_stats.hh"
using namespace std; using namespace std;
@ -178,7 +180,7 @@ class ProgressEvent : public Event
ProgressEvent::ProgressEvent(EventQueue *q, Tick _interval) ProgressEvent::ProgressEvent(EventQueue *q, Tick _interval)
: Event(q), interval(_interval) : Event(q), interval(_interval)
{ {
schedule(interval); schedule(curTick + interval);
} }
// //
@ -221,10 +223,24 @@ ProgressParamContext progessMessageParams("progress");
Param<Tick> progress_interval(&progessMessageParams, "cycle", Param<Tick> progress_interval(&progessMessageParams, "cycle",
"cycle interval for progress messages"); "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 */ /* check execute options */
void void
ProgressParamContext::checkParams() ProgressParamContext::checkParams()
{ {
if (progress_interval.isValid()) if (progress_interval.isValid())
new ProgressEvent(&mainEventQueue, progress_interval); registerInitCallback(new SetupProgress(progress_interval));
} }

View file

@ -182,11 +182,11 @@ SimObject::printAllExtraOutput(ostream &os)
void void
SimObject::serializeAll(ostream &os) SimObject::serializeAll(ostream &os)
{ {
SimObjectList::iterator i = simObjectList.begin(); SimObjectList::reverse_iterator ri = simObjectList.rbegin();
SimObjectList::iterator end = simObjectList.end(); SimObjectList::reverse_iterator rend = simObjectList.rend();
for (; i != end; ++i) { for (; ri != rend; ++ri) {
SimObject *obj = *i; SimObject *obj = *ri;
obj->nameOut(os); obj->nameOut(os);
obj->serialize(os); obj->serialize(os);
} }

View file

@ -50,13 +50,12 @@ System::System(const std::string _name,
{ {
// add self to global system list // add self to global system list
systemList.push_back(this); systemList.push_back(this);
#ifdef FS_MEASURE
if (bin == true) { if (bin == true) {
nonPath = new Statistics::MainBin("non TCPIP path stats"); Kernel = new Statistics::MainBin("non TCPIP Kernel stats");
nonPath->activate(); Kernel->activate();
User = new Statistics::MainBin("User stats");
} else } else
nonPath = NULL; Kernel = NULL;
#endif
} }
@ -104,14 +103,13 @@ printSystems()
System::printSystems(); System::printSystems();
} }
#ifdef FS_MEASURE
Statistics::MainBin * Statistics::MainBin *
System::getBin(const std::string &name) System::getBin(const std::string &name)
{ {
std::map<const std::string, Statistics::MainBin *>::const_iterator i; std::map<const std::string, Statistics::MainBin *>::const_iterator i;
i = fnBins.find(name); i = fnBins.find(name);
if (i == fnBins.end()) 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; return (*i).second;
} }
@ -127,7 +125,73 @@ System::findContext(Addr pcb)
} else } else
return NULL; 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 &section)
{
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) DEFINE_SIM_OBJECT_CLASS_NAME("System", System)

View file

@ -32,14 +32,11 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "sim/sim_object.hh"
#include "cpu/pc_event.hh"
#include "base/loader/symtab.hh" #include "base/loader/symtab.hh"
#ifdef FS_MEASURE
#include "base/statistics.hh" #include "base/statistics.hh"
#include "cpu/pc_event.hh"
#include "sim/sim_object.hh"
#include "sim/sw_context.hh" #include "sim/sw_context.hh"
#endif
class MemoryController; class MemoryController;
class PhysicalMemory; class PhysicalMemory;
@ -51,11 +48,33 @@ class ExecContext;
class System : public SimObject class System : public SimObject
{ {
#ifdef FS_MEASURE // lisa's binning stuff
protected: protected:
std::map<const std::string, Statistics::MainBin *> fnBins; std::map<const std::string, Statistics::MainBin *> fnBins;
std::map<const Addr, SWContext *> swCtxMap; 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 &section);
//
public: public:
const uint64_t init_param; const uint64_t init_param;
@ -71,11 +90,6 @@ class System : public SimObject
virtual int registerExecContext(ExecContext *xc); virtual int registerExecContext(ExecContext *xc);
virtual void replaceExecContext(int xcIndex, 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: public:
System(const std::string _name, const uint64_t _init_param, System(const std::string _name, const uint64_t _init_param,
MemoryController *, PhysicalMemory *, const bool); MemoryController *, PhysicalMemory *, const bool);
@ -86,22 +100,6 @@ class System : public SimObject
virtual Addr getKernelEntry() const = 0; virtual Addr getKernelEntry() const = 0;
virtual bool breakpoint() = 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: public:
//////////////////////////////////////////// ////////////////////////////////////////////
// //

View file

@ -47,6 +47,7 @@ Tick ticksPerSecond;
double __ticksPerMS; double __ticksPerMS;
double __ticksPerUS; double __ticksPerUS;
double __ticksPerNS; double __ticksPerNS;
double __ticksPerPS;
string outputDirectory; string outputDirectory;
ostream *outputStream; ostream *outputStream;
@ -79,6 +80,7 @@ UniverseParamContext::checkParams()
__ticksPerMS = freq / 1.0e3; __ticksPerMS = freq / 1.0e3;
__ticksPerUS = freq / 1.0e6; __ticksPerUS = freq / 1.0e6;
__ticksPerNS = freq / 1.0e9; __ticksPerNS = freq / 1.0e9;
__ticksPerPS = freq / 1.0e12;
if (universe_output_dir.isValid()) { if (universe_output_dir.isValid()) {
outputDirectory = universe_output_dir; outputDirectory = universe_output_dir;

View file

@ -1,5 +1,5 @@
#! /usr/bin/env perl #! /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. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # 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 # Everything else on the command line is taken to be an m5 argument to
# be given to both invocations # be given to both invocations
$simargs = join(' ', @ARGV); $simargs = '"' . join('" "', @ARGV) . '"';
$cmd1 = "$sim1 $simargs --stats:file=tracediff-$$-1.stats 2>&1 |"; $cmd1 = "$sim1 $simargs --stats:file=tracediff-$$-1.stats 2>&1 |";
$cmd2 = "$sim2 $simargs --stats:file=tracediff-$$-2.stats 2>&1 |"; $cmd2 = "$sim2 $simargs --stats:file=tracediff-$$-2.stats 2>&1 |";