Merge
--HG-- extra : convert_revision : 8690e31b64235874d74ea4a1123a408610fb115b
This commit is contained in:
commit
4ae64216c3
19 changed files with 295 additions and 104 deletions
|
@ -538,7 +538,7 @@ declare {{
|
|||
trappingMode((enum TrappingMode)FP_TRAPMODE)
|
||||
{
|
||||
if (trappingMode != Imprecise) {
|
||||
warn("Warning: precise FP traps unimplemented\n");
|
||||
warn("precise FP traps unimplemented\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1609,7 +1609,7 @@ declare {{
|
|||
Trace::InstRecord *traceData)
|
||||
{
|
||||
if (!warned) {
|
||||
warn("Warning: instruction '%s' unimplemented\n", mnemonic);
|
||||
warn("instruction '%s' unimplemented\n", mnemonic);
|
||||
warned = true;
|
||||
}
|
||||
|
||||
|
@ -1620,7 +1620,7 @@ declare {{
|
|||
Trace::InstRecord *traceData)
|
||||
{
|
||||
if (!xc->spec_mode && !warned) {
|
||||
warn("Warning: instruction '%s' unimplemented\n", mnemonic);
|
||||
warn("instruction '%s' unimplemented\n", mnemonic);
|
||||
warned = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,9 +37,20 @@ using namespace std;
|
|||
|
||||
namespace cp {
|
||||
|
||||
ArgList::~ArgList()
|
||||
{
|
||||
while (!objects.empty()) {
|
||||
delete objects.front();
|
||||
objects.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ArgList::dump(const string &format)
|
||||
{
|
||||
list_t::iterator iter = objects.begin();
|
||||
list_t::iterator end = objects.end();
|
||||
|
||||
const char *p = format.c_str();
|
||||
|
||||
stream->fill(' ');
|
||||
|
@ -198,22 +209,19 @@ ArgList::dump(const string &format)
|
|||
}
|
||||
}
|
||||
|
||||
if (!objects.empty())
|
||||
if (iter != end)
|
||||
{
|
||||
Base *data = objects.front();
|
||||
objects.pop_front();
|
||||
|
||||
ios::fmtflags saved_flags = stream->flags();
|
||||
char old_fill = stream->fill();
|
||||
int old_precision = stream->precision();
|
||||
|
||||
data->process(*stream, fmt);
|
||||
(*iter)->process(*stream, fmt);
|
||||
|
||||
stream->flags(saved_flags);
|
||||
stream->fill(old_fill);
|
||||
stream->precision(old_precision);
|
||||
|
||||
delete data;
|
||||
++iter;
|
||||
} else {
|
||||
*stream << "<missing arg for format>";
|
||||
}
|
||||
|
@ -241,11 +249,9 @@ ArgList::dump(const string &format)
|
|||
}
|
||||
}
|
||||
|
||||
while (!objects.empty()) {
|
||||
while (iter != end) {
|
||||
*stream << "<extra arg>";
|
||||
Base *data = objects.front();
|
||||
objects.pop_front();
|
||||
delete data;
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ class ArgList
|
|||
|
||||
public:
|
||||
ArgList() : stream(&std::cout) {}
|
||||
~ArgList();
|
||||
|
||||
template<class T>
|
||||
void append(const T &data) {
|
||||
|
|
|
@ -30,7 +30,11 @@
|
|||
|
||||
// Because of the -Wundef flag we have to do this
|
||||
#define __LIBELF_INTERNAL__ 0
|
||||
#define __LIBELF64_LINUX 1
|
||||
// counterintuitive, but the flag below causes libelf to define
|
||||
// 64-bit elf types that apparently didn't exist in some older
|
||||
// versions of Linux. They seem to be there in 2.4.x, so don't
|
||||
// set this now (it causes things to break on 64-bit platforms).
|
||||
#define __LIBELF64_LINUX 0
|
||||
#define __LIBELF_NEED_LINK_H 0
|
||||
|
||||
#include <libelf/libelf.h>
|
||||
|
|
40
base/misc.cc
40
base/misc.cc
|
@ -42,7 +42,17 @@ void
|
|||
__panic(const string &format, cp::ArgList &args, const char *func,
|
||||
const char *file, int line)
|
||||
{
|
||||
string fmt = "panic: " + format + " @ cycle %d\n[%s:%s, line %d]\n";
|
||||
string fmt = "panic: " + format;
|
||||
switch (fmt[fmt.size() - 1]) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
break;
|
||||
default:
|
||||
fmt += "\n";
|
||||
}
|
||||
|
||||
fmt += " @ cycle %d\n[%s:%s, line %d]\n";
|
||||
|
||||
args.append(curTick);
|
||||
args.append(func);
|
||||
args.append(file);
|
||||
|
@ -63,8 +73,18 @@ void
|
|||
__fatal(const string &format, cp::ArgList &args, const char *func,
|
||||
const char *file, int line)
|
||||
{
|
||||
string fmt = "fatal: " + format + " @ cycle %d\n[%s:%s, line %d]\n"
|
||||
"Memory Usage: %ld KBytes\n";
|
||||
string fmt = "fatal: " + format;
|
||||
|
||||
switch (fmt[fmt.size() - 1]) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
break;
|
||||
default:
|
||||
fmt += "\n";
|
||||
}
|
||||
|
||||
fmt += " @ cycle %d\n[%s:%s, line %d]\n";
|
||||
fmt += "Memory Usage: %ld KBytes\n";
|
||||
|
||||
args.append(curTick);
|
||||
args.append(func);
|
||||
|
@ -83,16 +103,26 @@ __warn(const string &format, cp::ArgList &args, const char *func,
|
|||
const char *file, int line)
|
||||
{
|
||||
string fmt = "warn: " + format;
|
||||
|
||||
switch (fmt[fmt.size() - 1]) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
break;
|
||||
default:
|
||||
fmt += "\n";
|
||||
}
|
||||
|
||||
#ifdef VERBOSE_WARN
|
||||
fmt += " @ cycle %d\n[%s:%s, line %d]\n";
|
||||
args.append(curTick);
|
||||
args.append(func);
|
||||
args.append(file);
|
||||
args.append(line);
|
||||
#else
|
||||
fmt += "\n";
|
||||
#endif
|
||||
|
||||
args.dump(cerr, fmt);
|
||||
if (outputStream != &cerr && outputStream != &cout)
|
||||
args.dump(*outputStream, fmt);
|
||||
|
||||
delete &args;
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ Data::~Data()
|
|||
{
|
||||
if (stream) {
|
||||
delete py;
|
||||
ccprintf(*stream, "if __name__ == '__main__':\n");
|
||||
ccprintf(*stream, "\n\nif __name__ == '__main__':\n");
|
||||
ccprintf(*stream, " program_display()\n");
|
||||
stream->close();
|
||||
delete stream;
|
||||
|
@ -209,30 +209,41 @@ Data::python_dump(const string &name, const string &subname)
|
|||
++i;
|
||||
}
|
||||
}
|
||||
py->next();
|
||||
}
|
||||
|
||||
void
|
||||
Data::python(const string &name, const string &subname, const string &bin)
|
||||
{
|
||||
py->start("collections.append");
|
||||
py->start("Collection");
|
||||
py->name("collections.append");
|
||||
py->newline();
|
||||
py->name("Collection");
|
||||
py->newline();
|
||||
py->qarg(name);
|
||||
py->newline();
|
||||
py->qarg(subname);
|
||||
py->newline();
|
||||
py->qarg(bin);
|
||||
py->newline();
|
||||
py->qarg(hostname());
|
||||
py->newline();
|
||||
py->qarg(Time::start.date());
|
||||
py->startList();
|
||||
py->newline();
|
||||
py->list();
|
||||
list_t::iterator i = allStats.begin();
|
||||
list_t::iterator end = allStats.end();
|
||||
while (i != end) {
|
||||
StatData *stat = *i;
|
||||
py->newline();
|
||||
stat->python(*py);
|
||||
++i;
|
||||
}
|
||||
py->endList();
|
||||
py->end();
|
||||
py->end();
|
||||
py->newline();
|
||||
py->listEnd();
|
||||
py->newline();
|
||||
py->nameEnd();
|
||||
py->newline();
|
||||
py->nameEnd();
|
||||
py->newline();
|
||||
}
|
||||
|
||||
StatData *
|
||||
|
@ -996,7 +1007,7 @@ VectorDistDataBase::display(ostream &stream, DisplayMode mode) const
|
|||
void
|
||||
ScalarDataBase::python(Python &py) const
|
||||
{
|
||||
py.start("Scalar");
|
||||
py.name("Scalar");
|
||||
py.qarg(name);
|
||||
py.qqqarg(desc);
|
||||
py.kwarg("binned", binned());
|
||||
|
@ -1005,7 +1016,7 @@ ScalarDataBase::python(Python &py) const
|
|||
if (prereq)
|
||||
py.qkwarg("prereq", prereq->name);
|
||||
py.kwarg("value", val());
|
||||
py.end();
|
||||
py.nameEnd();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1013,7 +1024,7 @@ VectorDataBase::python(Python &py) const
|
|||
{
|
||||
const_cast<VectorDataBase *>(this)->update();
|
||||
|
||||
py.start("Vector");
|
||||
py.name("Vector");
|
||||
py.qarg(name);
|
||||
py.qqqarg(desc);
|
||||
py.kwarg("binned", binned());
|
||||
|
@ -1026,7 +1037,7 @@ VectorDataBase::python(Python &py) const
|
|||
py.qkwarg("subnames", subnames);
|
||||
if (!subdescs.empty())
|
||||
py.qkwarg("subdescs", subdescs);
|
||||
py.end();
|
||||
py.nameEnd();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1039,7 +1050,7 @@ DistDataData::python(Python &py, const string &name) const
|
|||
else
|
||||
s += "FullDist";
|
||||
|
||||
py.start(s);
|
||||
py.name(s);
|
||||
py.arg(sum);
|
||||
py.arg(squares);
|
||||
py.arg(samples);
|
||||
|
@ -1054,7 +1065,7 @@ DistDataData::python(Python &py, const string &name) const
|
|||
py.arg(bucket_size);
|
||||
py.arg(size);
|
||||
}
|
||||
py.end();
|
||||
py.nameEnd();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1062,7 +1073,7 @@ FormulaDataBase::python(Python &py) const
|
|||
{
|
||||
const_cast<FormulaDataBase *>(this)->update();
|
||||
|
||||
py.start("Formula");
|
||||
py.name("Formula");
|
||||
py.qarg(name);
|
||||
py.qqqarg(desc);
|
||||
py.kwarg("binned", binned());
|
||||
|
@ -1075,7 +1086,7 @@ FormulaDataBase::python(Python &py) const
|
|||
py.qkwarg("subnames", subnames);
|
||||
if (!subdescs.empty())
|
||||
py.qkwarg("subdescs", subdescs);
|
||||
py.end();
|
||||
py.nameEnd();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1083,7 +1094,7 @@ DistDataBase::python(Python &py) const
|
|||
{
|
||||
const_cast<DistDataBase *>(this)->update();
|
||||
|
||||
py.start("Dist");
|
||||
py.name("Dist");
|
||||
py.qarg(name);
|
||||
py.qqqarg(desc);
|
||||
py.kwarg("binned", binned());
|
||||
|
@ -1092,7 +1103,7 @@ DistDataBase::python(Python &py) const
|
|||
if (prereq)
|
||||
py.qkwarg("prereq", prereq->name);
|
||||
data.python(py, "dist");
|
||||
py.end();
|
||||
py.nameEnd();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1100,7 +1111,7 @@ VectorDistDataBase::python(Python &py) const
|
|||
{
|
||||
const_cast<VectorDistDataBase *>(this)->update();
|
||||
|
||||
py.start("VectorDist");
|
||||
py.name("VectorDist");
|
||||
py.qarg(name);
|
||||
py.qqqarg(desc);
|
||||
py.kwarg("binned", binned());
|
||||
|
@ -1121,8 +1132,8 @@ VectorDistDataBase::python(Python &py) const
|
|||
i->python(py, "");
|
||||
++i;
|
||||
}
|
||||
py.endTuple();
|
||||
py.end();
|
||||
py.tupleEnd();
|
||||
py.nameEnd();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1130,7 +1141,7 @@ Vector2dDataBase::python(Python &py) const
|
|||
{
|
||||
const_cast<Vector2dDataBase *>(this)->update();
|
||||
|
||||
py.start("Vector2d");
|
||||
py.name("Vector2d");
|
||||
py.qarg(name);
|
||||
py.qqqarg(desc);
|
||||
py.kwarg("binned", binned());
|
||||
|
@ -1149,7 +1160,7 @@ Vector2dDataBase::python(Python &py) const
|
|||
|
||||
py.kwarg("x", x);
|
||||
py.kwarg("y", y);
|
||||
py.end();
|
||||
py.nameEnd();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -49,7 +49,7 @@ FlagVec flags(NumFlags, false);
|
|||
// directly; use DebugOut() (see below) to access this stream for
|
||||
// output.
|
||||
//
|
||||
ostream *dprintf_stream = NULL;
|
||||
ostream *dprintf_stream = &cerr;
|
||||
|
||||
int dprintf_ignore_size;
|
||||
vector<string> dprintf_ignore;
|
||||
|
@ -267,10 +267,7 @@ RawDataRecord::dump(ostream &os)
|
|||
std::ostream &
|
||||
DebugOut()
|
||||
{
|
||||
if (Trace::dprintf_stream)
|
||||
return *Trace::dprintf_stream;
|
||||
else
|
||||
return cerr;
|
||||
return *Trace::dprintf_stream;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
|
|
@ -349,7 +349,7 @@ SimpleCPU::read(Addr addr, T& data, unsigned flags)
|
|||
// Ugly hack to get an event scheduled *only* if the access is
|
||||
// a miss. We really should add first-class support for this
|
||||
// at some point.
|
||||
if (result != MA_HIT && dcacheInterface->doEvents) {
|
||||
if (result != MA_HIT && dcacheInterface->doEvents()) {
|
||||
memReq->completionEvent = &cacheCompletionEvent;
|
||||
lastDcacheStall = curTick;
|
||||
unscheduleTickEvent();
|
||||
|
@ -432,7 +432,7 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
|
|||
// Ugly hack to get an event scheduled *only* if the access is
|
||||
// a miss. We really should add first-class support for this
|
||||
// at some point.
|
||||
if (result != MA_HIT && dcacheInterface->doEvents) {
|
||||
if (result != MA_HIT && dcacheInterface->doEvents()) {
|
||||
memReq->completionEvent = &cacheCompletionEvent;
|
||||
lastDcacheStall = curTick;
|
||||
unscheduleTickEvent();
|
||||
|
@ -635,7 +635,7 @@ SimpleCPU::tick()
|
|||
// Ugly hack to get an event scheduled *only* if the access is
|
||||
// a miss. We really should add first-class support for this
|
||||
// at some point.
|
||||
if (result != MA_HIT && icacheInterface->doEvents) {
|
||||
if (result != MA_HIT && icacheInterface->doEvents()) {
|
||||
memReq->completionEvent = &cacheCompletionEvent;
|
||||
lastIcacheStall = curTick;
|
||||
unscheduleTickEvent();
|
||||
|
|
|
@ -82,7 +82,7 @@ AlphaConsole::read(MemReqPtr req, uint8_t *data)
|
|||
Addr daddr = req->paddr & addr_mask;
|
||||
switch (daddr) {
|
||||
case offsetof(AlphaAccess, inputChar):
|
||||
val = console->in();
|
||||
val = console->console_in();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -228,27 +228,44 @@ SimConsole::configTerm()
|
|||
#define RECEIVE_NONE (ULL(2) << 62)
|
||||
#define RECEIVE_ERROR (ULL(3) << 62)
|
||||
|
||||
uint64_t
|
||||
SimConsole::in()
|
||||
bool
|
||||
SimConsole::in(uint8_t &c)
|
||||
{
|
||||
char c = 0;
|
||||
uint64_t val = 0;
|
||||
if (rxbuf.empty()) {
|
||||
clearInt(ReceiveInterrupt);
|
||||
val |= RECEIVE_NONE;
|
||||
return 0x8;
|
||||
} else {
|
||||
uint64_t val;
|
||||
rxbuf.read(&c, 1);
|
||||
val |= RECEIVE_SUCCESS | c;
|
||||
if (!rxbuf.empty())
|
||||
val |= MORE_PENDING;
|
||||
bool empty, ret;
|
||||
|
||||
empty = rxbuf.empty();
|
||||
ret = !empty;
|
||||
if (!empty) {
|
||||
rxbuf.read((char *)&c, 1);
|
||||
empty = rxbuf.empty();
|
||||
}
|
||||
|
||||
DPRINTF(ConsoleVerbose, "in: \'%c\' %#02x retval: %#x\n",
|
||||
isprint(c) ? c : ' ', c, val);
|
||||
if (empty)
|
||||
clearInt(ReceiveInterrupt);
|
||||
|
||||
return val;
|
||||
DPRINTF(ConsoleVerbose, "in: \'%c\' %#02x more: %d, return: %d\n",
|
||||
isprint(c) ? c : ' ', c, !empty, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
SimConsole::console_in()
|
||||
{
|
||||
uint8_t c;
|
||||
uint64_t value;
|
||||
|
||||
if (in(c)) {
|
||||
value = RECEIVE_SUCCESS | c;
|
||||
if (!rxbuf.empty())
|
||||
value |= MORE_PENDING;
|
||||
} else {
|
||||
value = RECEIVE_NONE;
|
||||
}
|
||||
|
||||
DPRINTF(ConsoleVerbose, "console_in: return: %#x\n", value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -383,8 +400,16 @@ END_INIT_SIM_OBJECT_PARAMS(SimConsole)
|
|||
CREATE_SIM_OBJECT(SimConsole)
|
||||
{
|
||||
string filename = output;
|
||||
if (!filename.empty() && append_name)
|
||||
filename += "." + getInstanceName();
|
||||
if (filename.empty()) {
|
||||
if (!outputDirectory.empty())
|
||||
filename = outputDirectory + getInstanceName();
|
||||
} else {
|
||||
if (append_name)
|
||||
filename += "." + getInstanceName();
|
||||
if (!outputDirectory.empty())
|
||||
filename = outputDirectory + filename;
|
||||
}
|
||||
|
||||
SimConsole *console = new SimConsole(getInstanceName(), filename, number);
|
||||
((ConsoleListener *)listener)->add(console);
|
||||
((SimConsole *)console)->initInt(intr_control);
|
||||
|
|
|
@ -109,7 +109,10 @@ class SimConsole : public SimObject
|
|||
// OS interface
|
||||
|
||||
// Get a character from the console.
|
||||
// the return value corresponds to the console GETC return value:
|
||||
bool in(uint8_t &value);
|
||||
|
||||
// get a character from the console in the console specific format
|
||||
// corresponds to GETC:
|
||||
// retval<63:61>
|
||||
// 000: success: character received
|
||||
// 001: success: character received, more pending
|
||||
|
@ -118,8 +121,9 @@ class SimConsole : public SimObject
|
|||
// 111: failure: character received with error, more pending
|
||||
// retval<31:0>
|
||||
// character read from console
|
||||
//
|
||||
// Interrupts are cleared when the buffer is empty.
|
||||
uint64_t in();
|
||||
uint64_t console_in();
|
||||
|
||||
// Send a character to the console
|
||||
void out(char c, bool raise_int = true);
|
||||
|
|
|
@ -126,13 +126,27 @@ END_DECLARE_SIM_OBJECT_PARAMS(EtherDump)
|
|||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(EtherDump)
|
||||
|
||||
INIT_PARAM_DFLT(file, "file to dump packets to", "")
|
||||
INIT_PARAM(file, "file to dump packets to")
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(EtherDump)
|
||||
|
||||
CREATE_SIM_OBJECT(EtherDump)
|
||||
{
|
||||
return new EtherDump(getInstanceName(), file);
|
||||
string filename;
|
||||
if (file.isValid()) {
|
||||
filename = file;
|
||||
|
||||
if (filename[0] != '/' && !outputDirectory.empty())
|
||||
filename = outputDirectory + filename;
|
||||
} else {
|
||||
if (outputDirectory.empty()) {
|
||||
filename = "etherdump";
|
||||
} else {
|
||||
filename = outputDirectory + "etherdump";
|
||||
}
|
||||
}
|
||||
|
||||
return new EtherDump(getInstanceName(), filename);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("EtherDump", EtherDump)
|
||||
|
|
|
@ -192,8 +192,10 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param,
|
|||
//INSTRUMENTATION CODEGEN END
|
||||
#endif //FS_MEASURE
|
||||
|
||||
#ifdef DEBUG
|
||||
kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic");
|
||||
consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic");
|
||||
#endif
|
||||
badaddrEvent = new BadAddrEvent(&pcEventQueue, "badaddr");
|
||||
skipPowerStateEvent = new SkipFuncEvent(&pcEventQueue,
|
||||
"tl_v48_capture_power_state");
|
||||
|
@ -262,6 +264,7 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param,
|
|||
strcpy(osflags, boot_osflags.c_str());
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (kernelSymtab->findAddress("panic", addr))
|
||||
kernelPanicEvent->schedule(addr);
|
||||
else
|
||||
|
@ -269,6 +272,7 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param,
|
|||
|
||||
if (consoleSymtab->findAddress("panic", addr))
|
||||
consolePanicEvent->schedule(addr);
|
||||
#endif
|
||||
|
||||
if (kernelSymtab->findAddress("badaddr", addr))
|
||||
badaddrEvent->schedule(addr);
|
||||
|
@ -511,8 +515,10 @@ Tru64System::~Tru64System()
|
|||
delete kernelSymtab;
|
||||
delete consoleSymtab;
|
||||
|
||||
#ifdef DEBUG
|
||||
delete kernelPanicEvent;
|
||||
delete consolePanicEvent;
|
||||
#endif
|
||||
delete badaddrEvent;
|
||||
delete skipPowerStateEvent;
|
||||
delete skipScavengeBootEvent;
|
||||
|
|
|
@ -34,10 +34,45 @@
|
|||
#include "sim/configfile.hh"
|
||||
#include "sim/host.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
#include "sim/sim_stats.hh"
|
||||
#include "sim/universe.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
ostream &
|
||||
builderStream()
|
||||
{
|
||||
static ofstream file;
|
||||
static ostream *stream = NULL;
|
||||
|
||||
if (!stream) {
|
||||
if (!outputDirectory.empty()) {
|
||||
string filename = outputDirectory + "builder.txt";
|
||||
file.open(filename.c_str());
|
||||
stream = &file;
|
||||
} else {
|
||||
stream = outputStream;
|
||||
}
|
||||
}
|
||||
|
||||
return *stream;
|
||||
}
|
||||
|
||||
SimObjectBuilder::SimObjectBuilder(const string &_configClass,
|
||||
const string &_instanceName,
|
||||
ConfigNode *_configNode,
|
||||
const string &_simObjClassName)
|
||||
: ParamContext(_configClass, true),
|
||||
instanceName(_instanceName),
|
||||
configNode(_configNode),
|
||||
simObjClassName(_simObjClassName)
|
||||
{
|
||||
}
|
||||
|
||||
SimObjectBuilder::~SimObjectBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// SimObjectBuilder member definitions
|
||||
|
@ -151,10 +186,10 @@ SimObjectClass::createObject(IniFile &configDB,
|
|||
|
||||
// echo object parameters to stats file (for documenting the
|
||||
// config used to generate the associated stats)
|
||||
*statStream << "[" << object->name() << "]" << endl;
|
||||
*statStream << "type=" << simObjClassName << endl;
|
||||
objectBuilder->showParams(*statStream);
|
||||
*statStream << endl;
|
||||
builderStream() << "[" << object->name() << "]" << endl;
|
||||
builderStream() << "type=" << simObjClassName << endl;
|
||||
objectBuilder->showParams(builderStream());
|
||||
builderStream() << endl;
|
||||
|
||||
// done with the SimObjectBuilder now
|
||||
delete objectBuilder;
|
||||
|
|
|
@ -29,15 +29,18 @@
|
|||
#ifndef __BUILDER_HH__
|
||||
#define __BUILDER_HH__
|
||||
|
||||
#include <map>
|
||||
#include <iosfwd>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#include "sim/param.hh"
|
||||
|
||||
class SimObject;
|
||||
|
||||
std::ostream &
|
||||
builderStream();
|
||||
|
||||
//
|
||||
// A SimObjectBuilder serves as an evaluation context for a set of
|
||||
// parameters that describe a specific instance of a SimObject. This
|
||||
|
@ -69,15 +72,9 @@ class SimObjectBuilder : public ParamContext
|
|||
SimObjectBuilder(const std::string &_configClass,
|
||||
const std::string &_instanceName,
|
||||
ConfigNode *_configNode,
|
||||
const std::string &_simObjClassName)
|
||||
: ParamContext(_configClass, true),
|
||||
instanceName(_instanceName),
|
||||
configNode(_configNode),
|
||||
simObjClassName(_simObjClassName)
|
||||
{
|
||||
}
|
||||
const std::string &_simObjClassName);
|
||||
|
||||
virtual ~SimObjectBuilder() {}
|
||||
virtual ~SimObjectBuilder();
|
||||
|
||||
// call parse() on all params in this context to convert string
|
||||
// representations to parameter values
|
||||
|
|
10
sim/main.cc
10
sim/main.cc
|
@ -54,6 +54,7 @@
|
|||
#include "sim/sim_init.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
#include "sim/sim_stats.hh"
|
||||
#include "sim/universe.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -355,12 +356,12 @@ main(int argc, char **argv)
|
|||
|
||||
// Print hello message to stats file if it's actually a file. If
|
||||
// it's not (i.e. it's cout or cerr) then we already did it above.
|
||||
if (statStreamIsFile)
|
||||
sayHello(*statStream);
|
||||
if (outputStream != &cout && outputStream != &cerr)
|
||||
sayHello(*outputStream);
|
||||
|
||||
// Echo command line and all parameter settings to stats file as well.
|
||||
echoCommandLine(argc, argv, *statStream);
|
||||
ParamContext::showAllContexts(*statStream);
|
||||
echoCommandLine(argc, argv, *outputStream);
|
||||
ParamContext::showAllContexts(builderStream());
|
||||
|
||||
// Now process the configuration hierarchy and create the SimObjects.
|
||||
ConfigHierarchy configHierarchy(simConfigDB);
|
||||
|
@ -400,6 +401,7 @@ main(int argc, char **argv)
|
|||
}
|
||||
|
||||
SimInit();
|
||||
warn("Entering event queue. Starting simulation...\n");
|
||||
|
||||
while (!mainEventQueue.empty()) {
|
||||
assert(curTick <= mainEventQueue.nextTick() &&
|
||||
|
|
|
@ -305,10 +305,9 @@ class SerializeParamContext : public ParamContext
|
|||
|
||||
SerializeParamContext serialParams("serialize");
|
||||
|
||||
Param<string> serialize_dir(&serialParams,
|
||||
"dir",
|
||||
Param<string> serialize_dir(&serialParams, "dir",
|
||||
"dir to stick checkpoint in "
|
||||
"(sprintf format with cycle #)", "m5.%012d");
|
||||
"(sprintf format with cycle #)");
|
||||
|
||||
Param<Counter> serialize_cycle(&serialParams,
|
||||
"cycle",
|
||||
|
@ -333,12 +332,19 @@ SerializeParamContext::~SerializeParamContext()
|
|||
void
|
||||
SerializeParamContext::checkParams()
|
||||
{
|
||||
checkpointDirBase = serialize_dir;
|
||||
// guarantee that directory ends with a '/'
|
||||
if (checkpointDirBase[checkpointDirBase.size() - 1] != '/') {
|
||||
checkpointDirBase += "/";
|
||||
if (serialize_dir.isValid()) {
|
||||
checkpointDirBase = serialize_dir;
|
||||
} else {
|
||||
if (outputDirectory.empty())
|
||||
checkpointDirBase = "m5.%012d";
|
||||
else
|
||||
checkpointDirBase = outputDirectory + "cpt.%012d";
|
||||
}
|
||||
|
||||
// guarantee that directory ends with a '/'
|
||||
if (checkpointDirBase[checkpointDirBase.size() - 1] != '/')
|
||||
checkpointDirBase += "/";
|
||||
|
||||
if (serialize_cycle > 0)
|
||||
Checkpoint::setup(serialize_cycle, serialize_period);
|
||||
}
|
||||
|
|
|
@ -26,10 +26,16 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/misc.hh"
|
||||
#include "sim/universe.hh"
|
||||
#include "sim/host.hh"
|
||||
#include "sim/param.hh"
|
||||
|
@ -42,8 +48,14 @@ double __ticksPerMS;
|
|||
double __ticksPerUS;
|
||||
double __ticksPerNS;
|
||||
|
||||
string outputDirectory;
|
||||
ostream *outputStream;
|
||||
|
||||
class UniverseParamContext : public ParamContext
|
||||
{
|
||||
private:
|
||||
ofstream outputFile;
|
||||
|
||||
public:
|
||||
UniverseParamContext(const string &is) : ParamContext(is) {}
|
||||
void checkParams();
|
||||
|
@ -54,6 +66,11 @@ UniverseParamContext universe("Universe");
|
|||
Param<Tick> universe_freq(&universe, "frequency", "tick frequency",
|
||||
200000000);
|
||||
|
||||
Param<string> universe_output_dir(&universe, "output_dir",
|
||||
"directory to output data to");
|
||||
Param<string> universe_output_file(&universe, "output_file",
|
||||
"file to dump simulator output to");
|
||||
|
||||
void
|
||||
UniverseParamContext::checkParams()
|
||||
{
|
||||
|
@ -62,4 +79,42 @@ UniverseParamContext::checkParams()
|
|||
__ticksPerMS = freq / 1.0e3;
|
||||
__ticksPerUS = freq / 1.0e6;
|
||||
__ticksPerNS = freq / 1.0e9;
|
||||
|
||||
if (universe_output_dir.isValid()) {
|
||||
outputDirectory = universe_output_dir;
|
||||
|
||||
// guarantee that directory ends with a '/'
|
||||
if (outputDirectory[outputDirectory.size() - 1] != '/')
|
||||
outputDirectory += "/";
|
||||
|
||||
if (mkdir(outputDirectory.c_str(), 0777) < 0) {
|
||||
if (errno != EEXIST) {
|
||||
panic("%s\ncould not make output directory: %s\n",
|
||||
strerror(errno), outputDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string filename;
|
||||
if (universe_output_file.isValid()) {
|
||||
string f = universe_output_file;
|
||||
if (f != "stdout" && f != "cout" && f != "stderr" && f != "cerr")
|
||||
filename = outputDirectory + f;
|
||||
else
|
||||
filename = f;
|
||||
} else {
|
||||
if (outputDirectory.empty())
|
||||
filename = "stdout";
|
||||
else
|
||||
filename = outputDirectory + "output.txt";
|
||||
}
|
||||
|
||||
if (filename == "stdout" || filename == "cout")
|
||||
outputStream = &cout;
|
||||
else if (filename == "stderr" || filename == "cerr")
|
||||
outputStream = &cerr;
|
||||
else {
|
||||
outputFile.open(filename.c_str(), ios::trunc);
|
||||
outputStream = &outputFile;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -510,10 +510,8 @@ main(int argc, char *argv[])
|
|||
s12.sample(100);
|
||||
|
||||
// dump(cout, mode_simplescalar);
|
||||
ofstream file("/tmp/stats.py");
|
||||
dump(file, "stattest", mode_python);
|
||||
file.close();
|
||||
|
||||
python_start("/tmp/stats.py");
|
||||
python_dump("stattest", "all");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue