Automerge
--HG-- extra : convert_revision : 2ca18ecbf04a1de72391073d0a5309fdbbdfefda
This commit is contained in:
commit
e4b52476bc
24 changed files with 751 additions and 147 deletions
|
@ -28,10 +28,11 @@ let {{
|
|||
#include "cpu/simple_cpu/simple_cpu.hh"
|
||||
#include "cpu/static_inst.hh"
|
||||
#include "sim/annotation.hh"
|
||||
#include "sim/sim_events.hh"
|
||||
#include "sim/sim_exit.hh"
|
||||
|
||||
#ifdef FULL_SYSTEM
|
||||
#include "targetarch/ev5.hh"
|
||||
#include "arch/alpha/ev5.hh"
|
||||
#include "arch/alpha/pseudo_inst.hh"
|
||||
#endif
|
||||
|
||||
namespace AlphaISA;
|
||||
|
@ -2372,7 +2373,7 @@ decode OPCODE default Unknown::unknown() {
|
|||
format EmulatedCallPal {
|
||||
0x00: halt ({{
|
||||
if (!xc->misspeculating())
|
||||
SimExit("halt instruction encountered");
|
||||
SimExit(curTick, "halt instruction encountered");
|
||||
}});
|
||||
0x83: callsys({{
|
||||
if (!xc->misspeculating())
|
||||
|
@ -2417,11 +2418,8 @@ decode OPCODE default Unknown::unknown() {
|
|||
}
|
||||
}});
|
||||
0x01: quiesce({{
|
||||
if (!xc->misspeculating()) {
|
||||
Annotate::QUIESCE(xc);
|
||||
xc->setStatus(ExecContext::Suspended);
|
||||
xc->kernelStats.quiesce();
|
||||
}
|
||||
if (!xc->misspeculating())
|
||||
AlphaPseudo::quiesce(xc);
|
||||
}});
|
||||
0x10: ivlb({{
|
||||
if (!xc->misspeculating()) {
|
||||
|
@ -2433,14 +2431,30 @@ decode OPCODE default Unknown::unknown() {
|
|||
if (!xc->misspeculating())
|
||||
Annotate::EndInterval(xc);
|
||||
}}, No_OpClass);
|
||||
0x20: m5exit({{
|
||||
0x20: m5exit_old({{
|
||||
if (!xc->misspeculating())
|
||||
SimExit("m5_exit instruction encountered");
|
||||
AlphaPseudo::m5exit_old(xc);
|
||||
}}, No_OpClass);
|
||||
0x21: m5exit({{
|
||||
if (!xc->misspeculating())
|
||||
AlphaPseudo::m5exit(xc);
|
||||
}}, No_OpClass);
|
||||
0x30: initparam({{ Ra = xc->cpu->system->init_param; }});
|
||||
0x40: resetstats({{
|
||||
if (!xc->misspeculating())
|
||||
Statistics::reset();
|
||||
AlphaPseudo::resetstats(xc);
|
||||
}});
|
||||
0x41: dumpstats({{
|
||||
if (!xc->misspeculating())
|
||||
AlphaPseudo::dumpstats(xc);
|
||||
}});
|
||||
0x42: dumpresetstats({{
|
||||
if (!xc->misspeculating())
|
||||
AlphaPseudo::dumpresetstats(xc);
|
||||
}});
|
||||
0x43: m5checkpoint({{
|
||||
if (!xc->misspeculating())
|
||||
AlphaPseudo::m5checkpoint(xc);
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
|
159
arch/alpha/pseudo_inst.cc
Normal file
159
arch/alpha/pseudo_inst.cc
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* 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 <string>
|
||||
|
||||
#include "arch/alpha/pseudo_inst.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "sim/annotation.hh"
|
||||
#include "sim/param.hh"
|
||||
#include "sim/serialize.hh"
|
||||
#include "sim/sim_exit.hh"
|
||||
#include "sim/sim_stats.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace Statistics;
|
||||
|
||||
namespace AlphaPseudo
|
||||
{
|
||||
bool doStatisticsInsts;
|
||||
bool doCheckpointInsts;
|
||||
bool doQuiesce;
|
||||
|
||||
void
|
||||
quiesce(ExecContext *xc)
|
||||
{
|
||||
if (!doQuiesce)
|
||||
return;
|
||||
|
||||
Annotate::QUIESCE(xc);
|
||||
xc->setStatus(ExecContext::Suspended);
|
||||
xc->kernelStats.quiesce();
|
||||
}
|
||||
|
||||
void
|
||||
m5exit_old(ExecContext *xc)
|
||||
{
|
||||
SimExit(curTick, "m5_exit_old instruction encountered");
|
||||
}
|
||||
|
||||
void
|
||||
m5exit(ExecContext *xc)
|
||||
{
|
||||
Tick delay = xc->regs.intRegFile[16];
|
||||
Tick when = curTick + NS2Ticks(delay);
|
||||
SimExit(when, "m5_exit instruction encountered");
|
||||
}
|
||||
|
||||
void
|
||||
resetstats(ExecContext *xc)
|
||||
{
|
||||
if (!doStatisticsInsts)
|
||||
return;
|
||||
|
||||
Tick delay = xc->regs.intRegFile[16];
|
||||
Tick period = xc->regs.intRegFile[17];
|
||||
|
||||
Tick when = curTick + NS2Ticks(delay);
|
||||
Tick repeat = NS2Ticks(period);
|
||||
|
||||
SetupEvent(Reset, when, repeat);
|
||||
}
|
||||
|
||||
void
|
||||
dumpstats(ExecContext *xc)
|
||||
{
|
||||
if (!doStatisticsInsts)
|
||||
return;
|
||||
|
||||
Tick delay = xc->regs.intRegFile[16];
|
||||
Tick period = xc->regs.intRegFile[17];
|
||||
|
||||
Tick when = curTick + NS2Ticks(delay);
|
||||
Tick repeat = NS2Ticks(period);
|
||||
|
||||
SetupEvent(Dump, when, repeat);
|
||||
}
|
||||
|
||||
void
|
||||
dumpresetstats(ExecContext *xc)
|
||||
{
|
||||
if (!doStatisticsInsts)
|
||||
return;
|
||||
|
||||
Tick delay = xc->regs.intRegFile[16];
|
||||
Tick period = xc->regs.intRegFile[17];
|
||||
|
||||
Tick when = curTick + NS2Ticks(delay);
|
||||
Tick repeat = NS2Ticks(period);
|
||||
|
||||
SetupEvent(Dump|Reset, when, repeat);
|
||||
}
|
||||
|
||||
void
|
||||
m5checkpoint(ExecContext *xc)
|
||||
{
|
||||
if (!doCheckpointInsts)
|
||||
return;
|
||||
|
||||
Tick delay = xc->regs.intRegFile[16];
|
||||
Tick period = xc->regs.intRegFile[17];
|
||||
|
||||
Tick when = curTick + NS2Ticks(delay);
|
||||
Tick repeat = NS2Ticks(period);
|
||||
|
||||
SetupCheckpoint(when, repeat);
|
||||
}
|
||||
|
||||
class Context : public ParamContext
|
||||
{
|
||||
public:
|
||||
Context(const string §ion) : ParamContext(section) {}
|
||||
void checkParams();
|
||||
};
|
||||
|
||||
Context context("PseudoInsts");
|
||||
|
||||
Param<bool> __quiesce(&context, "quiesce",
|
||||
"enable quiesce instructions",
|
||||
true);
|
||||
Param<bool> __statistics(&context, "statistics",
|
||||
"enable statistics pseudo instructions",
|
||||
true);
|
||||
Param<bool> __checkpoint(&context, "checkpoint",
|
||||
"enable checkpoint pseudo instructions",
|
||||
true);
|
||||
|
||||
void
|
||||
Context::checkParams()
|
||||
{
|
||||
doQuiesce = __quiesce;
|
||||
doStatisticsInsts = __statistics;
|
||||
doCheckpointInsts = __checkpoint;
|
||||
}
|
||||
}
|
40
arch/alpha/pseudo_inst.hh
Normal file
40
arch/alpha/pseudo_inst.hh
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class ExecContext;
|
||||
|
||||
namespace AlphaPseudo
|
||||
{
|
||||
void quiesce(ExecContext *xc);
|
||||
void m5exit(ExecContext *xc);
|
||||
void m5exit_old(ExecContext *xc);
|
||||
void resetstats(ExecContext *xc);
|
||||
void dumpstats(ExecContext *xc);
|
||||
void dumpresetstats(ExecContext *xc);
|
||||
void m5checkpoint(ExecContext *xc);
|
||||
}
|
|
@ -402,6 +402,14 @@ IniFile::findAppend(const string &_section, const string &entry,
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
IniFile::sectionExists(const string §ionName) const
|
||||
{
|
||||
return findSection(sectionName) != NULL;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
IniFile::Section::printUnreferenced(const string §ionName)
|
||||
{
|
||||
|
|
|
@ -208,6 +208,13 @@ class IniFile
|
|||
bool findAppend(const std::string §ion, const std::string &entry,
|
||||
std::string &value) const;
|
||||
|
||||
/// Determine whether the named section exists in the .ini file.
|
||||
/// Note that the 'Section' class is (intentionally) not public,
|
||||
/// so all clients can do is get a bool that says whether there
|
||||
/// are any values in that section or not.
|
||||
/// @return True if the section exists.
|
||||
bool sectionExists(const std::string §ion) const;
|
||||
|
||||
/// Print unreferenced entries in object. Iteratively calls
|
||||
/// printUnreferend() on all the constituent sections.
|
||||
bool printUnreferenced();
|
||||
|
|
|
@ -919,7 +919,7 @@ dump(ostream &stream)
|
|||
CallbackQueue resetQueue;
|
||||
|
||||
void
|
||||
regReset(Callback *cb)
|
||||
RegResetCallback(Callback *cb)
|
||||
{
|
||||
resetQueue.add(cb);
|
||||
}
|
||||
|
|
|
@ -2277,6 +2277,7 @@ struct StatBin : public GenBin
|
|||
int _size;
|
||||
|
||||
public:
|
||||
enum { binned = true };
|
||||
VectorBin() : _size(0) {}
|
||||
|
||||
bool initialized() const { return _size > 0; }
|
||||
|
@ -2762,7 +2763,7 @@ class Formula : public Detail::VectorStat
|
|||
void check();
|
||||
void dump(std::ostream &stream);
|
||||
void reset();
|
||||
void regReset(Callback *cb);
|
||||
void RegResetCallback(Callback *cb);
|
||||
|
||||
inline Detail::Temp
|
||||
operator+(Detail::Temp l, Detail::Temp r)
|
||||
|
|
|
@ -40,6 +40,42 @@ IntrControl::IntrControl(const string &name, BaseCPU *c)
|
|||
: SimObject(name), cpu(c)
|
||||
{}
|
||||
|
||||
/* @todo
|
||||
*Fix the cpu sim object parameter to be a system pointer
|
||||
*instead, to avoid some extra dereferencing
|
||||
*/
|
||||
void
|
||||
IntrControl::post(int int_num, int index)
|
||||
{
|
||||
std::vector<ExecContext *> &xcvec = cpu->system->execContexts;
|
||||
BaseCPU *temp = xcvec[0]->cpu;
|
||||
temp->post_interrupt(int_num, index);
|
||||
}
|
||||
|
||||
void
|
||||
IntrControl::post(int cpu_id, int int_num, int index)
|
||||
{
|
||||
std::vector<ExecContext *> &xcvec = cpu->system->execContexts;
|
||||
BaseCPU *temp = xcvec[cpu_id]->cpu;
|
||||
temp->post_interrupt(int_num, index);
|
||||
}
|
||||
|
||||
void
|
||||
IntrControl::clear(int int_num, int index)
|
||||
{
|
||||
std::vector<ExecContext *> &xcvec = cpu->system->execContexts;
|
||||
BaseCPU *temp = xcvec[0]->cpu;
|
||||
temp->clear_interrupt(int_num, index);
|
||||
}
|
||||
|
||||
void
|
||||
IntrControl::clear(int cpu_id, int int_num, int index)
|
||||
{
|
||||
std::vector<ExecContext *> &xcvec = cpu->system->execContexts;
|
||||
BaseCPU *temp = xcvec[cpu_id]->cpu;
|
||||
temp->clear_interrupt(int_num, index);
|
||||
}
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(IntrControl)
|
||||
|
||||
SimObjectParam<BaseCPU *> cpu;
|
||||
|
@ -48,7 +84,7 @@ END_DECLARE_SIM_OBJECT_PARAMS(IntrControl)
|
|||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(IntrControl)
|
||||
|
||||
INIT_PARAM(cpu, "the processor")
|
||||
INIT_PARAM(cpu, "the cpu")
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(IntrControl)
|
||||
|
||||
|
|
|
@ -29,9 +29,13 @@
|
|||
#ifndef __INTR_CONTROL_HH__
|
||||
#define __INTR_CONTROL_HH__
|
||||
|
||||
#include <vector>
|
||||
#include "base/misc.hh"
|
||||
#include "cpu/base_cpu.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
#include "sim/system.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
|
||||
|
||||
class IntrControl : public SimObject
|
||||
{
|
||||
|
@ -41,16 +45,10 @@ class IntrControl : public SimObject
|
|||
|
||||
void clear(int int_num, int index = 0);
|
||||
void post(int int_num, int index = 0);
|
||||
void clear(int cpu_id, int int_num, int index);
|
||||
void post(int cpu_id, int int_num, int index);
|
||||
};
|
||||
|
||||
inline void
|
||||
IntrControl::post(int int_num, int index)
|
||||
{ cpu->post_interrupt(int_num, index); }
|
||||
|
||||
inline void
|
||||
IntrControl::clear(int int_num, int index)
|
||||
{ cpu->clear_interrupt(int_num, index); }
|
||||
|
||||
#endif // __INTR_CONTROL_HH__
|
||||
|
||||
|
||||
|
|
|
@ -405,7 +405,7 @@ CowDiskImage::write(const uint8_t *data, off_t offset)
|
|||
void
|
||||
CowDiskImage::serialize(ostream &os)
|
||||
{
|
||||
string cowFilename = serializeFilename + ".cow";
|
||||
string cowFilename = CheckpointFile() + "." + name() + ".cow";
|
||||
SERIALIZE_SCALAR(cowFilename);
|
||||
save(cowFilename);
|
||||
}
|
||||
|
|
|
@ -125,11 +125,6 @@ extern "C" void sched_break_cycle(Tick when)
|
|||
new DebugBreakEvent(&mainEventQueue, when);
|
||||
}
|
||||
|
||||
extern "C" void dump_stats()
|
||||
{
|
||||
new DumpStatsEvent();
|
||||
}
|
||||
|
||||
extern "C" void eventq_dump()
|
||||
{
|
||||
mainEventQueue.dump();
|
||||
|
|
|
@ -112,7 +112,7 @@ EventQueue::serviceOne()
|
|||
else
|
||||
event->clearFlags(Event::Squashed);
|
||||
|
||||
if (event->getFlags(Event::AutoDelete))
|
||||
if (event->getFlags(Event::AutoDelete) && !event->scheduled())
|
||||
delete event;
|
||||
}
|
||||
|
||||
|
|
|
@ -400,7 +400,9 @@ main(int argc, char **argv)
|
|||
async_event = false;
|
||||
if (async_dump) {
|
||||
async_dump = false;
|
||||
new DumpStatsEvent();
|
||||
|
||||
using namespace Statistics;
|
||||
SetupEvent(Dump, curTick);
|
||||
}
|
||||
|
||||
if (async_exit) {
|
||||
|
|
|
@ -245,14 +245,14 @@ Serializer::add_objects()
|
|||
}
|
||||
|
||||
void
|
||||
Serializer::serialize(const string &f)
|
||||
Serializer::serialize()
|
||||
{
|
||||
if (Serializeable::serializer != NULL)
|
||||
panic("in process of serializing!");
|
||||
|
||||
Serializeable::serializer = this;
|
||||
|
||||
file = f;
|
||||
file = CheckpointFile();
|
||||
string cpt_file = file + ".cpt";
|
||||
output = new ofstream(cpt_file.c_str());
|
||||
time_t t = time(NULL);
|
||||
|
@ -286,38 +286,49 @@ class SerializeEvent : public Event
|
|||
{
|
||||
protected:
|
||||
string file;
|
||||
Tick repeat;
|
||||
|
||||
public:
|
||||
SerializeEvent(EventQueue *q, Tick when, const string &file);
|
||||
~SerializeEvent();
|
||||
|
||||
SerializeEvent(Tick _when, Tick _repeat);
|
||||
virtual void process();
|
||||
virtual void serialize(std::ostream &os);
|
||||
virtual void serialize(std::ostream &os)
|
||||
{
|
||||
panic("Cannot serialize the SerializeEvent");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
SerializeEvent::SerializeEvent(EventQueue *q, Tick when, const string &f)
|
||||
: Event(q), file(f)
|
||||
SerializeEvent::SerializeEvent(Tick _when, Tick _repeat)
|
||||
: Event(&mainEventQueue, 990), repeat(_repeat)
|
||||
{
|
||||
setFlags(AutoDelete);
|
||||
schedule(when);
|
||||
}
|
||||
|
||||
SerializeEvent::~SerializeEvent()
|
||||
{
|
||||
schedule(_when);
|
||||
}
|
||||
|
||||
void
|
||||
SerializeEvent::process()
|
||||
{
|
||||
Serializer serial;
|
||||
serial.serialize(file);
|
||||
new SimExitEvent("Serialization caused exit");
|
||||
serial.serialize();
|
||||
if (repeat)
|
||||
schedule(curTick + repeat);
|
||||
}
|
||||
|
||||
string __CheckpointFileBase;
|
||||
|
||||
string
|
||||
CheckpointFile()
|
||||
{
|
||||
if (__CheckpointFileBase.empty())
|
||||
return __CheckpointFileBase;
|
||||
|
||||
return csprintf("%s.%d", __CheckpointFileBase, curTick);
|
||||
}
|
||||
|
||||
void
|
||||
SerializeEvent::serialize(ostream &os)
|
||||
SetupCheckpoint(Tick when, Tick period)
|
||||
{
|
||||
panic("Cannot serialize the SerializeEvent");
|
||||
new SerializeEvent(when, period);
|
||||
}
|
||||
|
||||
class SerializeParamContext : public ParamContext
|
||||
|
@ -333,18 +344,21 @@ class SerializeParamContext : public ParamContext
|
|||
|
||||
SerializeParamContext serialParams("serialize");
|
||||
|
||||
Param<string> serialize_file(&serialParams,
|
||||
"file",
|
||||
"file to write to", "m5");
|
||||
|
||||
Param<Counter> serialize_cycle(&serialParams,
|
||||
"cycle",
|
||||
"cycle to serialize",
|
||||
0);
|
||||
|
||||
Param<string> serialize_file(&serialParams,
|
||||
"file",
|
||||
"file to write to", "");
|
||||
Param<Counter> serialize_period(&serialParams,
|
||||
"period",
|
||||
"period to repeat serializations",
|
||||
0);
|
||||
|
||||
|
||||
// Copy filename into regular string so we can export it without
|
||||
// having to include param.hh all over the place.
|
||||
string serializeFilename;
|
||||
|
||||
SerializeParamContext::SerializeParamContext(const string §ion)
|
||||
: ParamContext(section), event(NULL)
|
||||
|
@ -357,22 +371,23 @@ SerializeParamContext::~SerializeParamContext()
|
|||
void
|
||||
SerializeParamContext::checkParams()
|
||||
{
|
||||
serializeFilename = serialize_file;
|
||||
if (!serializeFilename.empty() && serialize_cycle > 0)
|
||||
event = new SerializeEvent(&mainEventQueue, serialize_cycle,
|
||||
serializeFilename);
|
||||
__CheckpointFileBase = serialize_file;
|
||||
if (serialize_cycle > 0)
|
||||
SetupCheckpoint(serialize_cycle, serialize_period);
|
||||
}
|
||||
|
||||
void
|
||||
debug_serialize(const char *file)
|
||||
debug_serialize()
|
||||
{
|
||||
Serializer serial;
|
||||
serial.serialize(file);
|
||||
new SimExitEvent("Serialization caused exit");
|
||||
serial.serialize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
debug_serialize(Tick when)
|
||||
{
|
||||
new SerializeEvent(when, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -479,3 +494,10 @@ Checkpoint::findObj(const std::string §ion, const std::string &entry,
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Checkpoint::sectionExists(const std::string §ion)
|
||||
{
|
||||
return db->sectionExists(section);
|
||||
}
|
||||
|
|
|
@ -148,7 +148,7 @@ class Serializer
|
|||
void add_objects();
|
||||
|
||||
public:
|
||||
void serialize(const std::string &file);
|
||||
void serialize();
|
||||
const std::string &filename() const { return file; }
|
||||
};
|
||||
|
||||
|
@ -244,6 +244,8 @@ class Checkpoint
|
|||
|
||||
bool findObj(const std::string §ion, const std::string &entry,
|
||||
Serializeable *&value);
|
||||
|
||||
bool sectionExists(const std::string §ion);
|
||||
};
|
||||
|
||||
|
||||
|
@ -251,6 +253,7 @@ class Checkpoint
|
|||
// Export checkpoint filename param so other objects can derive
|
||||
// filenames from it (e.g., memory).
|
||||
//
|
||||
extern std::string serializeFilename;
|
||||
std::string CheckpointFile();
|
||||
void SetupCheckpoint(Tick when, Tick period = 0);
|
||||
|
||||
#endif // __SERIALIZE_HH__
|
||||
|
|
|
@ -63,12 +63,6 @@ SimExitEvent::description()
|
|||
return "simulation termination";
|
||||
}
|
||||
|
||||
void
|
||||
SimExit(const char *message)
|
||||
{
|
||||
static SimExitEvent event(message);
|
||||
}
|
||||
|
||||
//
|
||||
// constructor: automatically schedules at specified time
|
||||
//
|
||||
|
@ -103,20 +97,6 @@ CountedExitEvent::description()
|
|||
return "counted exit";
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DumpStatsEvent::process()
|
||||
{
|
||||
dumpStats();
|
||||
}
|
||||
|
||||
const char *
|
||||
DumpStatsEvent::description()
|
||||
{
|
||||
return "stats dump";
|
||||
}
|
||||
|
||||
|
||||
#ifdef CHECK_SWAP_CYCLES
|
||||
new CheckSwapEvent(&mainEventQueue, CHECK_SWAP_CYCLES);
|
||||
#endif
|
||||
|
@ -148,33 +128,6 @@ CheckSwapEvent::description()
|
|||
}
|
||||
|
||||
|
||||
class DumpStatsContext : public ParamContext
|
||||
{
|
||||
public:
|
||||
DumpStatsContext(const string &_iniSection)
|
||||
: ParamContext(_iniSection) {}
|
||||
void checkParams();
|
||||
};
|
||||
|
||||
DumpStatsContext dumpStatsParams("stats");
|
||||
|
||||
VectorParam<Tick> dump_cycle(&dumpStatsParams, "dump_cycles",
|
||||
"cycles on which to dump stats");
|
||||
|
||||
void
|
||||
DumpStatsContext::checkParams()
|
||||
{
|
||||
if (dump_cycle.isValid()) {
|
||||
vector<Tick> &cycles = dump_cycle;
|
||||
|
||||
vector<Tick>::iterator i = cycles.begin();
|
||||
vector<Tick>::iterator end = cycles.end();
|
||||
|
||||
for (; i < end; ++i)
|
||||
new DumpStatsEvent(*i);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
//
|
||||
// Simulation termination parameters
|
||||
|
|
|
@ -66,8 +66,6 @@ class SimExitEvent : public Event
|
|||
virtual const char *description();
|
||||
};
|
||||
|
||||
void SimExit(const char *message);
|
||||
|
||||
//
|
||||
// Event class to terminate simulation after 'n' related events have
|
||||
// occurred using a shared counter: used to terminate when *all*
|
||||
|
@ -91,30 +89,6 @@ class CountedExitEvent : public Event
|
|||
//
|
||||
// Event to cause a statistics dump
|
||||
//
|
||||
class DumpStatsEvent : public Event
|
||||
{
|
||||
public:
|
||||
DumpStatsEvent()
|
||||
: Event(&mainEventQueue)
|
||||
{ setFlags(AutoDelete); schedule(curTick, 999); }
|
||||
|
||||
DumpStatsEvent(EventQueue *q)
|
||||
: Event(q)
|
||||
{ setFlags(AutoDelete); schedule(curTick, 999); }
|
||||
|
||||
DumpStatsEvent(Tick when)
|
||||
: Event(&mainEventQueue)
|
||||
{ setFlags(AutoDelete); schedule(when, 999); }
|
||||
|
||||
DumpStatsEvent(EventQueue *q, Tick when)
|
||||
: Event(q)
|
||||
{ setFlags(AutoDelete); schedule(when, 999); }
|
||||
|
||||
void process();
|
||||
|
||||
virtual const char *description();
|
||||
};
|
||||
|
||||
class CheckSwapEvent : public Event
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -31,11 +31,14 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "sim/host.hh"
|
||||
|
||||
class Callback;
|
||||
|
||||
void registerExitCallback(Callback *);
|
||||
|
||||
void exitNow(const std::string &cause, int exit_code);
|
||||
void exitNow(const char *cause, int exit_code);
|
||||
void SimExit(Tick when, const char *message);
|
||||
|
||||
#endif // __SIM_EXIT_HH__
|
||||
|
|
|
@ -38,6 +38,9 @@ using namespace std;
|
|||
|
||||
Tick curTick = 0;
|
||||
Tick ticksPerSecond;
|
||||
double __ticksPerMS;
|
||||
double __ticksPerUS;
|
||||
double __ticksPerNS;
|
||||
|
||||
class UniverseParamContext : public ParamContext
|
||||
{
|
||||
|
@ -49,10 +52,14 @@ class UniverseParamContext : public ParamContext
|
|||
UniverseParamContext universe("Universe");
|
||||
|
||||
Param<Tick> universe_freq(&universe, "frequency", "tick frequency",
|
||||
200000000);
|
||||
200000000);
|
||||
|
||||
void
|
||||
UniverseParamContext::checkParams()
|
||||
{
|
||||
ticksPerSecond = universe_freq;
|
||||
double freq = double(ticksPerSecond);
|
||||
__ticksPerMS = freq / 1.0e3;
|
||||
__ticksPerUS = freq / 1.0e6;
|
||||
__ticksPerNS = freq / 1.0e9;
|
||||
}
|
||||
|
|
26
util/m5/Makefile
Normal file
26
util/m5/Makefile
Normal file
|
@ -0,0 +1,26 @@
|
|||
AS=as
|
||||
CC=cc
|
||||
LD=cc
|
||||
|
||||
CCFLAGS=-O2
|
||||
#LDFLAGS=-non_shared
|
||||
|
||||
all: m5
|
||||
|
||||
m5: m5op.o m5.o
|
||||
$(LD) $(LDFLAGS) -o $@ $>
|
||||
strip $@
|
||||
|
||||
clean:
|
||||
@rm -f m5 *.o *.d *~ .#*
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES:.o .c .s
|
||||
|
||||
# C Compilation
|
||||
.c.o:
|
||||
$(CC) $(CCFLAGS) -o $@ -c $<
|
||||
|
||||
# Assembly
|
||||
.s.o:
|
||||
$(AS) $(ASFLAGS) -o $@ $<
|
186
util/m5/m5.c
Normal file
186
util/m5/m5.c
Normal file
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* 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 <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "m5op.h"
|
||||
|
||||
char *progname;
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
printf("usage: m5 ivlb <interval>\n"
|
||||
" m5 ivle <interval>\n"
|
||||
" m5 initparam\n"
|
||||
" m5 sw99param\n"
|
||||
" m5 exit [delay]\n"
|
||||
" m5 resetstats [delay [period]]\n"
|
||||
" m5 dumpstats [delay [period]]\n"
|
||||
" m5 dumpresetstats [delay [period]]\n"
|
||||
" m5 checkpoint [delay [period]]\n"
|
||||
"\n"
|
||||
"All times in nanoseconds!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#define COMPARE(X) (strcmp(X, command) == 0)
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *command;
|
||||
uint64_t param;
|
||||
uint64_t arg1 = 0;
|
||||
uint64_t arg2 = 0;
|
||||
|
||||
progname = argv[0];
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
command = argv[1];
|
||||
|
||||
if (COMPARE("ivlb")) {
|
||||
if (argc != 3)
|
||||
usage();
|
||||
|
||||
arg1 = strtoul(argv[2], NULL, 0);
|
||||
ivlb(arg1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (COMPARE("ivle")) {
|
||||
if (argc != 3)
|
||||
usage();
|
||||
|
||||
arg1 = strtoul(argv[2], NULL, 0);
|
||||
ivle(arg1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (COMPARE("initparam")) {
|
||||
if (argc != 2)
|
||||
usage();
|
||||
|
||||
printf("%ld", initparam());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (COMPARE("sw99param")) {
|
||||
if (argc != 2)
|
||||
usage();
|
||||
|
||||
param = initparam();
|
||||
// run-time, rampup-time, rampdown-time, warmup-time, connections
|
||||
printf("%d %d %d %d %d", (param >> 48) & 0xfff,
|
||||
(param >> 36) & 0xfff, (param >> 24) & 0xfff,
|
||||
(param >> 12) & 0xfff, (param >> 0) & 0xfff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (COMPARE("exit")) {
|
||||
switch (argc) {
|
||||
case 3:
|
||||
arg1 = strtoul(argv[2], NULL, 0);
|
||||
case 2:
|
||||
m5exit(arg1);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (COMPARE("resetstats")) {
|
||||
switch (argc) {
|
||||
case 4:
|
||||
arg2 = strtoul(argv[3], NULL, 0);
|
||||
case 3:
|
||||
arg1 = strtoul(argv[2], NULL, 0);
|
||||
case 2:
|
||||
reset_stats(arg1, arg2);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (COMPARE("dumpstats")) {
|
||||
switch (argc) {
|
||||
case 4:
|
||||
arg2 = strtoul(argv[3], NULL, 0);
|
||||
case 3:
|
||||
arg1 = strtoul(argv[2], NULL, 0);
|
||||
case 2:
|
||||
dump_stats(arg1, arg2);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (COMPARE("dumpresetstats")) {
|
||||
switch (argc) {
|
||||
case 4:
|
||||
arg2 = strtoul(argv[3], NULL, 0);
|
||||
case 3:
|
||||
arg1 = strtoul(argv[2], NULL, 0);
|
||||
case 2:
|
||||
dumpreset_stats(arg1, arg2);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (COMPARE("checkpoint")) {
|
||||
switch (argc) {
|
||||
case 4:
|
||||
arg2 = strtoul(argv[3], NULL, 0);
|
||||
case 3:
|
||||
arg1 = strtoul(argv[2], NULL, 0);
|
||||
case 2:
|
||||
checkpoint(arg1, arg2);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
usage();
|
||||
}
|
45
util/m5/m5op.h
Normal file
45
util/m5/m5op.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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 __M5OP_H__
|
||||
#define __M5OP_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
void arm(uint64_t address);
|
||||
void quiesce();
|
||||
void ivlb(uint64_t interval);
|
||||
void ivle(uint64_t interval);
|
||||
void m5exit(uint64_t ns_delay);
|
||||
uint64_t initparam();
|
||||
void checkpoint(uint64_t ns_delay, uint64_t ns_period);
|
||||
void reset_stats(uint64_t ns_delay, uint64_t ns_period);
|
||||
void dump_stats(uint64_t ns_delay, uint64_t ns_period);
|
||||
void dumpreset_stats(uint64_t ns_delay, uint64_t ns_period);
|
||||
|
||||
#endif // __M5OP_H__
|
121
util/m5/m5op.s
Normal file
121
util/m5/m5op.s
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* 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 <machine/asm.h>
|
||||
#include <regdef.h>
|
||||
|
||||
#define m5_op 0x01
|
||||
|
||||
#define arm_func 0x00
|
||||
#define quiesce_func 0x01
|
||||
#define ivlb_func 0x10
|
||||
#define ivle_func 0x11
|
||||
#define exit_old_func 0x20 // deprectated!
|
||||
#define exit_func 0x21
|
||||
#define initparam_func 0x30
|
||||
#define resetstats_func 0x40
|
||||
#define dumpstats_func 0x41
|
||||
#define dumprststats_func 0x42
|
||||
#define ckpt_func 0x43
|
||||
|
||||
#define INST(op, ra, rb, func) \
|
||||
.long (((op) << 26) | ((ra) << 21) | ((rb) << 16) | (func))
|
||||
|
||||
#define ARM(reg) INST(m5_op, reg, 0, arm_func)
|
||||
#define QUIESCE() INST(m5_op, 0, 0, quiesce_func)
|
||||
#define IVLB(reg) INST(m5_op, reg, 0, ivlb_func)
|
||||
#define IVLE(reg) INST(m5_op, reg, 0, ivle_func)
|
||||
#define M5EXIT(reg) INST(m5_op, reg, 0, exit_func)
|
||||
#define INITPARAM(reg) INST(m5_op, reg, 0, initparam_func)
|
||||
#define RESET_STATS(r1, r2) INST(m5_op, r1, r2, resetstats_func)
|
||||
#define DUMP_STATS(r1, r2) INST(m5_op, r1, r2, dumpstats_func)
|
||||
#define DUMPRST_STATS(r1, r2) INST(m5_op, r1, r2, dumprststats_func)
|
||||
#define CHECKPOINT(r1, r2) INST(m5_op, r1, r2, ckpt_func)
|
||||
|
||||
.set noreorder
|
||||
|
||||
.align 4
|
||||
LEAF(arm)
|
||||
ARM(16)
|
||||
RET
|
||||
END(arm)
|
||||
|
||||
.align 4
|
||||
LEAF(quiesce)
|
||||
QUIESCE()
|
||||
RET
|
||||
END(quiesce)
|
||||
|
||||
.align 4
|
||||
LEAF(ivlb)
|
||||
IVLB(16)
|
||||
RET
|
||||
END(ivlb)
|
||||
|
||||
.align 4
|
||||
LEAF(ivle)
|
||||
IVLE(16)
|
||||
RET
|
||||
END(ivle)
|
||||
|
||||
.align 4
|
||||
LEAF(m5exit)
|
||||
M5EXIT(16)
|
||||
RET
|
||||
END(m5exit)
|
||||
|
||||
.align 4
|
||||
LEAF(initparam)
|
||||
INITPARAM(0)
|
||||
RET
|
||||
END(initparam)
|
||||
|
||||
.align 4
|
||||
LEAF(reset_stats)
|
||||
RESET_STATS(16, 17)
|
||||
RET
|
||||
END(reset_stats)
|
||||
|
||||
.align 4
|
||||
LEAF(dump_stats)
|
||||
DUMP_STATS(16, 17)
|
||||
RET
|
||||
END(dump_stats)
|
||||
|
||||
.align 4
|
||||
LEAF(dumpreset_stats)
|
||||
DUMPRST_STATS(16, 17)
|
||||
RET
|
||||
END(dumpreset_stats)
|
||||
|
||||
.align 4
|
||||
LEAF(checkpoint)
|
||||
CHECKPOINT(16, 17)
|
||||
RET
|
||||
END(checkpoint)
|
||||
|
|
@ -200,7 +200,7 @@ main(int argc, char *argv[])
|
|||
int bufsize = 2000;
|
||||
bool listening = false;
|
||||
char *device = NULL;
|
||||
char *filter = "";
|
||||
char *filter = NULL;
|
||||
char c;
|
||||
int daemon = false;
|
||||
string host;
|
||||
|
@ -274,16 +274,20 @@ main(int argc, char *argv[])
|
|||
if (pcap == NULL)
|
||||
panic("pcap_open_live failed: %s\n", errbuf);
|
||||
|
||||
bpf_program program;
|
||||
bpf_u_int32 localnet, netmask;
|
||||
if (pcap_lookupnet(device, &localnet, &netmask, errbuf) == -1)
|
||||
panic("pcap_lookupnet failed: %s\n", errbuf);
|
||||
if (filter) {
|
||||
bpf_program program;
|
||||
bpf_u_int32 localnet, netmask;
|
||||
if (pcap_lookupnet(device, &localnet, &netmask, errbuf) == -1) {
|
||||
DPRINTF("pcap_lookupnet failed: %s\n", errbuf);
|
||||
netmask = 0xffffff00;
|
||||
}
|
||||
|
||||
if (pcap_compile(pcap, &program, filter, 1, netmask) == -1)
|
||||
panic("pcap_compile failed, invalid filter:\n%s\n", filter);
|
||||
if (pcap_compile(pcap, &program, filter, 1, netmask) == -1)
|
||||
panic("pcap_compile failed, invalid filter:\n%s\n", filter);
|
||||
|
||||
if (pcap_setfilter(pcap, &program) == -1)
|
||||
panic("pcap_setfilter failed\n");
|
||||
if (pcap_setfilter(pcap, &program) == -1)
|
||||
panic("pcap_setfilter failed\n");
|
||||
}
|
||||
|
||||
eth_t *ethernet = eth_open(device);
|
||||
if (!ethernet)
|
||||
|
|
Loading…
Reference in a new issue