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];
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;

View file

@ -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).

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -48,10 +48,7 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
kernelStats(this, _cpu), cpu(_cpu), thread_num(_thread_num),
cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys),
memCtrl(_sys->memCtrl), physmem(_sys->physmem),
#ifdef FS_MEASURE
swCtx(NULL),
#endif
func_exe_inst(0), storeCondFailures(0)
swCtx(NULL), func_exe_inst(0), storeCondFailures(0)
{
memset(&regs, 0, sizeof(RegFile));
}
@ -107,6 +104,33 @@ ExecContext::serialize(ostream &os)
regs.serialize(os);
// thread_num and cpu_id are deterministic from the config
SERIALIZE_SCALAR(func_exe_inst);
#ifdef FULL_SYSTEM
bool ctx = false;
if (swCtx) {
ctx = true;
SERIALIZE_SCALAR(ctx);
SERIALIZE_SCALAR(swCtx->calls);
std::stack<fnCall *> *stack = &(swCtx->callStack);
fnCall *top;
int size = stack->size();
SERIALIZE_SCALAR(size);
for (int j=0; j<size; ++j) {
top = stack->top();
paramOut(os, csprintf("stackpos[%d]",j), top->name);
delete top;
stack->pop();
}
} else {
SERIALIZE_SCALAR(ctx);
}
if (system->bin) {
Statistics::MainBin *cur = Statistics::MainBin::curBin();
string bin_name = cur->name();
SERIALIZE_SCALAR(bin_name);
}
#endif //FULL_SYSTEM
}
@ -117,6 +141,37 @@ ExecContext::unserialize(Checkpoint *cp, const std::string &section)
regs.unserialize(cp, section);
// thread_num and cpu_id are deterministic from the config
UNSERIALIZE_SCALAR(func_exe_inst);
#ifdef FULL_SYSTEM
bool ctx;
UNSERIALIZE_SCALAR(ctx);
if (ctx) {
swCtx = new SWContext;
UNSERIALIZE_SCALAR(swCtx->calls);
int size;
UNSERIALIZE_SCALAR(size);
vector<fnCall *> calls;
fnCall *call;
for (int i=0; i<size; ++i) {
call = new fnCall;
paramIn(cp, section, csprintf("stackpos[%d]",i), call->name);
call->myBin = system->getBin(call->name);
calls.push_back(call);
}
for (int i=size-1; i>=0; --i) {
swCtx->callStack.push(calls[i]);
}
}
if (system->bin) {
string bin_name;
UNSERIALIZE_SCALAR(bin_name);
system->getBin(bin_name)->activate();
}
#endif //FULL_SYSTEM
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 &section);
public:
Tick cacheAccess(MemReqPtr &req);
};
#endif // __ALPHA_CONSOLE_HH__

View file

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

View file

@ -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 &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
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 &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)
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)

View file

@ -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 &section);
};
/*
@ -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 &section);
};
#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__
#define __ETHERPKT_HH__
#include <iosfwd>
#include <memory>
#include "sim/host.hh"
#include "base/refcnt.hh"
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 "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

View file

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

View file

@ -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\'");
int end = binned_fns.size();
assert(!(end & 1));
if (kernelSymtab->findAddress("es_rxeof", addr))
esRxeofEvent->schedule(addr);
else
panic("could not find kernel symbol \'es_rxeof\'");
Statistics::MainBin *Bin;
Addr address = 0;
if (kernelSymtab->findAddress("es_newbuf", addr))
esNewbufEvent->schedule(addr);
else
panic("could not find kernel symbol \'es_newbuf\'");
fnEvents.resize(end>>1);
if (kernelSymtab->findAddress("es_dma_load", addr))
esDmaLoadEvent->schedule(addr);
else
panic("could not find kernel symbol \'es_dma_load\'");
for (int i = 0; i < end; i +=2) {
Bin = new Statistics::MainBin(binned_fns[i]);
fnBins.insert(make_pair(binned_fns[i], Bin));
if (kernelSymtab->findAddress("dma_map_load", addr))
dmaMapLoadEvent->schedule(addr);
else
panic("could not find kernel symbol \'dma_map_load\'");
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 (kernelSymtab->findAddress("ether_input", addr))
etherInputEvent->schedule(addr);
else
panic("could not find kernel symbol \'ether_input\'");
if (binned_fns[i+1] == "null")
populateMap(binned_fns[i], "");
else
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
.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;
}

View file

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

View file

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

View file

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

View file

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

View file

@ -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 &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)

View file

@ -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 &section);
//
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:
////////////////////////////////////////////
//

View file

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

View file

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