#include "arch/alpha/regfile.hh"
#include "cpu/thread_context.hh"
+using namespace std;
+
namespace AlphaISA {
void
-RegFile::serialize(std::ostream &os)
+RegFile::serialize(EventManager *em, ostream &os)
{
intRegFile.serialize(os);
floatRegFile.serialize(os);
}
void
-RegFile::unserialize(Checkpoint *cp, const std::string §ion)
+RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion)
{
intRegFile.unserialize(cp, section);
floatRegFile.unserialize(cp, section);
//XXX These should be implemented by someone who knows the alpha stuff better
class Checkpoint;
+class EventManager;
class ThreadContext;
namespace AlphaISA {
intRegFile.setReg(intReg, val);
}
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string §ion);
+ void serialize(EventManager *em, std::ostream &os);
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string §ion);
void
changeContext(RegContextParam param, RegContextVal val)
//schedule UPDATE
CP0Event *cp0_event = new CP0Event(this, cpu, UpdateCP0);
- cp0_event->schedule(curTick + cpu->ticks(delay));
+ cpu->schedule(cp0_event, curTick + cpu->ticks(delay));
}
}
}
MiscRegFile::CP0Event::CP0Event(CP0 *_cp0, BaseCPU *_cpu, CP0EventType e_type)
- : Event(&mainEventQueue, CPU_Tick_Pri), cp0(_cp0), cpu(_cpu),
- cp0EventType(e_type)
+ : Event(CPU_Tick_Pri), cp0(_cp0), cpu(_cpu), cp0EventType(e_type)
{ }
void
void
MiscRegFile::CP0Event::scheduleEvent(int delay)
{
- if (squashed())
- reschedule(curTick + cpu->ticks(delay));
- else if (!scheduled())
- schedule(curTick + cpu->ticks(delay));
+ cpu->reschedule(this, curTick + cpu->ticks(delay), true);
}
void
}
void
-RegFile::serialize(std::ostream &os)
+RegFile::serialize(EventManager *em, std::ostream &os)
{
intRegFile.serialize(os);
//SERIALIZE_ARRAY(floatRegFile, NumFloatRegs);
}
void
-RegFile::unserialize(Checkpoint *cp, const std::string §ion)
+RegFile::unserialize(EventManager *em, Checkpoint *cp,
+ const std::string §ion)
{
intRegFile.unserialize(cp, section);
//UNSERIALIZE_ARRAY(floatRegFile);
//#include "cpu/base.hh"
#include "sim/faults.hh"
-class Checkpoint;
class BaseCPU;
+class Checkpoint;
+class EventManager;
namespace MipsISA
{
Addr readNextNPC();
void setNextNPC(Addr val);
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string §ion);
+ void serialize(EventManager *em, std::ostream &os);
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string §ion);
void changeContext(RegContextParam param, RegContextVal val)
{
setRegNoEffect(miscReg, new_val);
}
-void MiscRegFile::serialize(std::ostream & os)
+void
+MiscRegFile::serialize(EventManager *em, std::ostream &os)
{
SERIALIZE_SCALAR(asi);
SERIALIZE_SCALAR(tick);
#endif
}
-void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
+void
+MiscRegFile::unserialize(EventManager *em, Checkpoint *cp,
+ const string §ion)
{
UNSERIALIZE_SCALAR(asi);
UNSERIALIZE_SCALAR(tick);
if (tick_cmp) {
tickCompare = new TickCompareEvent(this, tc);
- tickCompare->schedule(tick_cmp);
+ em->schedule(tickCompare, tick_cmp);
}
if (stick_cmp) {
sTickCompare = new STickCompareEvent(this, tc);
- sTickCompare->schedule(stick_cmp);
+ em->schedule(sTickCompare, stick_cmp);
}
if (hstick_cmp) {
hSTickCompare = new HSTickCompareEvent(this, tc);
- hSTickCompare->schedule(hstick_cmp);
+ em->schedule(hSTickCompare, hstick_cmp);
}
}
}
return priContext | (uint32_t)partId << 13;
}
- void serialize(std::ostream & os);
+ void serialize(EventManager *em, std::ostream & os);
- void unserialize(Checkpoint * cp, const std::string & section);
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string & section);
void copyMiscRegs(ThreadContext * tc);
//return intRegFile.flattenIndex(reg);
}
-void RegFile::serialize(std::ostream &os)
+void
+RegFile::serialize(EventManager *em, ostream &os)
{
intRegFile.serialize(os);
floatRegFile.serialize(os);
- miscRegFile.serialize(os);
+ miscRegFile.serialize(em, os);
SERIALIZE_SCALAR(pc);
SERIALIZE_SCALAR(npc);
SERIALIZE_SCALAR(nnpc);
}
-void RegFile::unserialize(Checkpoint *cp, const std::string §ion)
+void
+RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion)
{
intRegFile.unserialize(cp, section);
floatRegFile.unserialize(cp, section);
- miscRegFile.unserialize(cp, section);
+ miscRegFile.unserialize(em, cp, section);
UNSERIALIZE_SCALAR(pc);
UNSERIALIZE_SCALAR(npc);
UNSERIALIZE_SCALAR(nnpc);
void setIntReg(int intReg, const IntReg &val);
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string §ion);
+ void serialize(EventManager *em, std::ostream &os);
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string §ion);
public:
tickCompare = new TickCompareEvent(this, tc);
setRegNoEffect(miscReg, val);
if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled())
- tickCompare->deschedule();
+ cpu->deschedule(tickCompare);
time = (tick_cmpr & mask(63)) - (tick & mask(63));
if (!(tick_cmpr & ~mask(63)) && time > 0) {
if (tickCompare->scheduled())
- tickCompare->deschedule();
- tickCompare->schedule(time * cpu->ticks(1));
+ cpu->deschedule(tickCompare);
+ cpu->schedule(tickCompare, curTick + time * cpu->ticks(1));
}
panic("writing to TICK compare register %#X\n", val);
break;
sTickCompare = new STickCompareEvent(this, tc);
setRegNoEffect(miscReg, val);
if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
- sTickCompare->deschedule();
+ cpu->deschedule(sTickCompare);
time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
cpu->instCount();
if (!(stick_cmpr & ~mask(63)) && time > 0) {
if (sTickCompare->scheduled())
- sTickCompare->deschedule();
- sTickCompare->schedule(time * cpu->ticks(1) + curTick);
+ cpu->deschedule(sTickCompare);
+ cpu->schedule(sTickCompare, curTick + time * cpu->ticks(1));
}
DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
break;
hSTickCompare = new HSTickCompareEvent(this, tc);
setRegNoEffect(miscReg, val);
if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
- hSTickCompare->deschedule();
+ cpu->deschedule(hSTickCompare);
time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
cpu->instCount();
if (!(hstick_cmpr & ~mask(63)) && time > 0) {
if (hSTickCompare->scheduled())
- hSTickCompare->deschedule();
- hSTickCompare->schedule(curTick + time * cpu->ticks(1));
+ cpu->deschedule(hSTickCompare);
+ cpu->schedule(hSTickCompare, curTick + time * cpu->ticks(1));
}
DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val);
break;
void
MiscRegFile::processSTickCompare(ThreadContext *tc)
{
+ BaseCPU *cpu = tc->getCpuPtr();
+
// since our microcode instructions take two cycles we need to check if
// we're actually at the correct cycle or we need to wait a little while
// more
int ticks;
ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
- tc->getCpuPtr()->instCount();
+ cpu->instCount();
assert(ticks >= 0 && "stick compare missed interrupt cycle");
if (ticks == 0 || tc->status() == ThreadContext::Suspended) {
setReg(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc);
}
} else
- sTickCompare->schedule(ticks * tc->getCpuPtr()->ticks(1) + curTick);
+ cpu->schedule(sTickCompare, curTick + ticks * cpu->ticks(1));
}
void
MiscRegFile::processHSTickCompare(ThreadContext *tc)
{
+ BaseCPU *cpu = tc->getCpuPtr();
+
// since our microcode instructions take two cycles we need to check if
// we're actually at the correct cycle or we need to wait a little while
// more
return;
ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
- tc->getCpuPtr()->instCount();
+ cpu->instCount();
assert(ticks >= 0 && "hstick compare missed interrupt cycle");
if (ticks == 0 || tc->status() == ThreadContext::Suspended) {
}
// Need to do something to cause interrupt to happen here !!! @todo
} else
- hSTickCompare->schedule(ticks * tc->getCpuPtr()->ticks(1) + curTick);
+ cpu->schedule(hSTickCompare, curTick + ticks * cpu->ticks(1));
}
class ApicTimerEvent : public Event
{
public:
- ApicTimerEvent() : Event(&mainEventQueue)
- {}
-
- void process()
+ void
+ process()
{
warn("Local APIC timer event doesn't do anything!\n");
}
return reg;
}
-void RegFile::serialize(std::ostream &os)
+void
+RegFile::serialize(EventManager *em, std::ostream &os)
{
intRegFile.serialize(os);
floatRegFile.serialize(os);
SERIALIZE_SCALAR(nextRip);
}
-void RegFile::unserialize(Checkpoint *cp, const std::string §ion)
+void
+RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion)
{
intRegFile.unserialize(cp, section);
floatRegFile.unserialize(cp, section);
#include <string>
class Checkpoint;
+class EventManager;
namespace X86ISA
{
void setIntReg(int intReg, const IntReg &val);
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string §ion);
+ void serialize(EventManager *em, std::ostream &os);
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string §ion);
public:
// been initialized
int maxThreadsPerCPU = 1;
-CPUProgressEvent::CPUProgressEvent(EventQueue *q, Tick ival,
- BaseCPU *_cpu)
- : Event(q, Event::Progress_Event_Pri), interval(ival),
- lastNumInst(0), cpu(_cpu)
+CPUProgressEvent::CPUProgressEvent(BaseCPU *_cpu, Tick ival)
+ : Event(Event::Progress_Event_Pri), interval(ival), lastNumInst(0),
+ cpu(_cpu)
{
if (interval)
- schedule(curTick + interval);
+ cpu->schedule(this, curTick + interval);
}
void
curTick, cpu->name(), temp - lastNumInst);
#endif
lastNumInst = temp;
- schedule(curTick + interval);
+ cpu->schedule(this, curTick + interval);
}
const char *
//
// set up instruction-count-based termination events, if any
//
- if (p->max_insts_any_thread != 0)
- for (int i = 0; i < number_of_threads; ++i)
- schedExitSimLoop("a thread reached the max instruction count",
- p->max_insts_any_thread, 0,
- comInstEventQueue[i]);
+ if (p->max_insts_any_thread != 0) {
+ const char *cause = "a thread reached the max instruction count";
+ for (int i = 0; i < number_of_threads; ++i) {
+ Event *event = new SimLoopExitEvent(cause, 0);
+ comInstEventQueue[i]->schedule(event, p->max_insts_any_thread);
+ }
+ }
if (p->max_insts_all_threads != 0) {
+ const char *cause = "all threads reached the max instruction count";
+
// allocate & initialize shared downcounter: each event will
// decrement this when triggered; simulation will terminate
// when counter reaches 0
int *counter = new int;
*counter = number_of_threads;
- for (int i = 0; i < number_of_threads; ++i)
- new CountedExitEvent(comInstEventQueue[i],
- "all threads reached the max instruction count",
- p->max_insts_all_threads, *counter);
+ for (int i = 0; i < number_of_threads; ++i) {
+ Event *event = new CountedExitEvent(cause, *counter);
+ comInstEventQueue[i]->schedule(event, p->max_insts_any_thread);
+ }
}
// allocate per-thread load-based event queues
//
// set up instruction-count-based termination events, if any
//
- if (p->max_loads_any_thread != 0)
- for (int i = 0; i < number_of_threads; ++i)
- schedExitSimLoop("a thread reached the max load count",
- p->max_loads_any_thread, 0,
- comLoadEventQueue[i]);
+ if (p->max_loads_any_thread != 0) {
+ const char *cause = "a thread reached the max load count";
+ for (int i = 0; i < number_of_threads; ++i) {
+ Event *event = new SimLoopExitEvent(cause, 0);
+ comLoadEventQueue[i]->schedule(event, p->max_loads_any_thread);
+ }
+ }
if (p->max_loads_all_threads != 0) {
+ const char *cause = "all threads reached the max load count";
// allocate & initialize shared downcounter: each event will
// decrement this when triggered; simulation will terminate
// when counter reaches 0
int *counter = new int;
*counter = number_of_threads;
- for (int i = 0; i < number_of_threads; ++i)
- new CountedExitEvent(comLoadEventQueue[i],
- "all threads reached the max load count",
- p->max_loads_all_threads, *counter);
+ for (int i = 0; i < number_of_threads; ++i) {
+ Event *event = new CountedExitEvent(cause, *counter);
+ comLoadEventQueue[i]->schedule(event, p->max_loads_all_threads);
+ }
}
functionTracingEnabled = false;
if (p->function_trace_start == 0) {
functionTracingEnabled = true;
} else {
- new EventWrapper<BaseCPU,
- &BaseCPU::enableFunctionTrace>(
- this, p->function_trace_start, true);
+ typedef EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace> wrap;
+ Event *event = new wrap(this, true);
+ schedule(event, p->function_trace_start);
}
}
#if FULL_SYSTEM
{
#if FULL_SYSTEM
if (!params()->defer_registration && profileEvent)
- profileEvent->schedule(curTick);
+ schedule(profileEvent, curTick);
#endif
if (params()->progress_interval) {
- new CPUProgressEvent(&mainEventQueue,
- ticks(params()->progress_interval),
- this);
+ Tick num_ticks = ticks(params()->progress_interval);
+ Event *event = new CPUProgressEvent(this, num_ticks);
+ schedule(event, curTick + num_ticks);
}
}
// panic("This CPU doesn't support sampling!");
#if FULL_SYSTEM
if (profileEvent && profileEvent->scheduled())
- profileEvent->deschedule();
+ deschedule(profileEvent);
#endif
}
threadContexts[i]->profileClear();
if (profileEvent)
- profileEvent->schedule(curTick);
+ schedule(profileEvent, curTick);
#endif
// Connect new CPU to old CPU's memory only if new CPU isn't
#if FULL_SYSTEM
BaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, Tick _interval)
- : Event(&mainEventQueue), cpu(_cpu), interval(_interval)
+ : cpu(_cpu), interval(_interval)
{ }
void
tc->profileSample();
}
- schedule(curTick + interval);
+ cpu->schedule(this, curTick + interval);
}
void
BaseCPU *cpu;
public:
- CPUProgressEvent(EventQueue *q, Tick ival, BaseCPU *_cpu);
+ CPUProgressEvent(BaseCPU *_cpu, Tick ival);
void process();
ThreadContext *tc;
public:
- CpuEvent(EventQueue *q, ThreadContext *_tc, Priority p = Default_Pri)
- : Event(q, p), tc(_tc)
+ CpuEvent(ThreadContext *_tc, Priority p = Default_Pri)
+ : Event(p), tc(_tc)
{ cpuEventList.push_back(this); }
/** delete the cpu event from the global list. */
T *object;
public:
- CpuEventWrapper(T *obj, ThreadContext *_tc,
- EventQueue *q = &mainEventQueue, Priority p = Default_Pri)
- : CpuEvent(q, _tc, p), object(obj)
+ CpuEventWrapper(T *obj, ThreadContext *_tc, Priority p = Default_Pri)
+ : CpuEvent(_tc, p), object(obj)
{ }
void process() { (object->*F)(tc); }
};
// set up counters
noResponseCycles = 0;
numReads = 0;
- tickEvent.schedule(0);
+ schedule(tickEvent, 0);
id = TESTER_ALLOCATOR++;
MemTest::tick()
{
if (!tickEvent.scheduled())
- tickEvent.schedule(curTick + ticks(1));
+ schedule(tickEvent, curTick + ticks(1));
if (++noResponseCycles >= 500000) {
cerr << name() << ": deadlocked at cycle " << curTick << endl;
{
private:
MemTest *cpu;
+
public:
- TickEvent(MemTest *c)
- : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c) {}
- void process() {cpu->tick();}
+ TickEvent(MemTest *c) : Event(CPU_Tick_Pri), cpu(c) {}
+ void process() { cpu->tick(); }
virtual const char *description() const { return "MemTest tick"; }
};
template <class Impl>
DefaultCommit<Impl>::TrapEvent::TrapEvent(DefaultCommit<Impl> *_commit,
unsigned _tid)
- : Event(&mainEventQueue, CPU_Tick_Pri), commit(_commit), tid(_tid)
+ : Event(CPU_Tick_Pri), commit(_commit), tid(_tid)
{
this->setFlags(Event::AutoDelete);
}
TrapEvent *trap = new TrapEvent(this, tid);
- trap->schedule(curTick + trapLatency);
+ cpu->schedule(trap, curTick + trapLatency);
trapInFlight[tid] = true;
}
template <class Impl>
FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
- : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c)
+ : Event(CPU_Tick_Pri), cpu(c)
{
}
template <class Impl>
FullO3CPU<Impl>::ActivateThreadEvent::ActivateThreadEvent()
- : Event(&mainEventQueue, CPU_Switch_Pri)
+ : Event(CPU_Switch_Pri)
{
}
template <class Impl>
FullO3CPU<Impl>::DeallocateContextEvent::DeallocateContextEvent()
- : Event(&mainEventQueue, CPU_Tick_Pri), tid(0), remove(false), cpu(NULL)
+ : Event(CPU_Tick_Pri), tid(0), remove(false), cpu(NULL)
{
}
lastRunningCycle = curTick;
timesIdled++;
} else {
- tickEvent.schedule(nextCycle(curTick + ticks(1)));
+ schedule(tickEvent, nextCycle(curTick + ticks(1)));
DPRINTF(O3CPU, "Scheduling next tick!\n");
}
}
#if !FULL_SYSTEM
updateThreadPriority();
#endif
-
}
template <class Impl>
#endif
if (!tickEvent.scheduled())
- tickEvent.schedule(nextCycle());
+ schedule(tickEvent, nextCycle());
_status = Running;
}
ThreadContext *tc = threadContexts[i];
if (tc->status() == ThreadContext::Active && _status != Running) {
_status = Running;
- tickEvent.schedule(nextCycle());
+ schedule(tickEvent, nextCycle());
}
}
if (!tickEvent.scheduled())
- tickEvent.schedule(nextCycle());
+ schedule(tickEvent, nextCycle());
}
template <class Impl>
idleCycles += tickToCycles((curTick - 1) - lastRunningCycle);
numCycles += tickToCycles((curTick - 1) - lastRunningCycle);
- tickEvent.schedule(nextCycle());
+ schedule(tickEvent, nextCycle());
}
template <class Impl>
void scheduleTickEvent(int delay)
{
if (tickEvent.squashed())
- tickEvent.reschedule(nextCycle(curTick + ticks(delay)));
+ reschedule(tickEvent, nextCycle(curTick + ticks(delay)));
else if (!tickEvent.scheduled())
- tickEvent.schedule(nextCycle(curTick + ticks(delay)));
+ schedule(tickEvent, nextCycle(curTick + ticks(delay)));
}
/** Unschedule tick event, regardless of its current state. */
{
// Schedule thread to activate, regardless of its current state.
if (activateThreadEvent[tid].squashed())
- activateThreadEvent[tid].
- reschedule(nextCycle(curTick + ticks(delay)));
+ reschedule(activateThreadEvent[tid],
+ nextCycle(curTick + ticks(delay)));
else if (!activateThreadEvent[tid].scheduled())
- activateThreadEvent[tid].
- schedule(nextCycle(curTick + ticks(delay)));
+ schedule(activateThreadEvent[tid],
+ nextCycle(curTick + ticks(delay)));
}
/** Unschedule actiavte thread event, regardless of its current state. */
{
// Schedule thread to activate, regardless of its current state.
if (deallocateContextEvent[tid].squashed())
- deallocateContextEvent[tid].
- reschedule(nextCycle(curTick + ticks(delay)));
+ reschedule(deallocateContextEvent[tid],
+ nextCycle(curTick + ticks(delay)));
else if (!deallocateContextEvent[tid].scheduled())
- deallocateContextEvent[tid].
- schedule(nextCycle(curTick + ticks(delay)));
+ schedule(deallocateContextEvent[tid],
+ nextCycle(curTick + ticks(delay)));
}
/** Unschedule thread deallocation in CPU */
public:
/** Default constructor. */
IcachePort(DefaultFetch<Impl> *_fetch)
- : Port(_fetch->name() + "-iport"), fetch(_fetch)
+ : Port(_fetch->name() + "-iport", _fetch->cpu), fetch(_fetch)
{ }
bool snoopRangeSent;
template <class Impl>
InstructionQueue<Impl>::FUCompletion::FUCompletion(DynInstPtr &_inst,
- int fu_idx,
- InstructionQueue<Impl> *iq_ptr)
- : Event(&mainEventQueue, Stat_Event_Pri),
- inst(_inst), fuIdx(fu_idx), iqPtr(iq_ptr), freeFU(false)
+ int fu_idx, InstructionQueue<Impl> *iq_ptr)
+ : Event(Stat_Event_Pri), inst(_inst), fuIdx(fu_idx), iqPtr(iq_ptr),
+ freeFU(false)
{
this->setFlags(Event::AutoDelete);
}
FUCompletion *execution = new FUCompletion(issuing_inst,
idx, this);
- execution->schedule(curTick + cpu->ticks(op_latency - 1));
+ cpu->schedule(execution, curTick + cpu->ticks(op_latency - 1));
// @todo: Enforce that issue_latency == 1 or op_latency
if (issue_latency > 1) {
public:
/** Default constructor. */
DcachePort(LSQ *_lsq)
- : Port(_lsq->name() + "-dport"), lsq(_lsq)
+ : Port(_lsq->name() + "-dport", _lsq->cpu), lsq(_lsq)
{ }
bool snoopRangeSent;
// We'll say this has a 1 cycle load-store forwarding latency
// for now.
// @todo: Need to make this a parameter.
- wb->schedule(curTick);
+ cpu->schedule(wb, curTick);
++lsqForwLoads;
return NoFault;
template<class Impl>
LSQUnit<Impl>::WritebackEvent::WritebackEvent(DynInstPtr &_inst, PacketPtr _pkt,
LSQUnit *lsq_ptr)
- : Event(&mainEventQueue), inst(_inst), pkt(_pkt), lsqPtr(lsq_ptr)
+ : inst(_inst), pkt(_pkt), lsqPtr(lsq_ptr)
{
this->setFlags(Event::AutoDelete);
}
"Instantly completing it.\n",
inst->seqNum);
WritebackEvent *wb = new WritebackEvent(inst, data_pkt, this);
- wb->schedule(curTick + 1);
+ cpu->schedule(wb, curTick + 1);
completeStore(storeWBIdx);
incrStIdx(storeWBIdx);
continue;
#include "cpu/quiesce_event.hh"
EndQuiesceEvent::EndQuiesceEvent(ThreadContext *_tc)
- : Event(&mainEventQueue), tc(_tc)
+ : tc(_tc)
{
}
using namespace TheISA;
AtomicSimpleCPU::TickEvent::TickEvent(AtomicSimpleCPU *c)
- : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c)
+ : Event(CPU_Tick_Pri), cpu(c)
{
}
changeState(SimObject::Running);
if (thread->status() == ThreadContext::Active) {
- if (!tickEvent.scheduled()) {
- tickEvent.schedule(nextCycle());
- }
+ if (!tickEvent.scheduled())
+ schedule(tickEvent, nextCycle());
}
}
ThreadContext *tc = threadContexts[i];
if (tc->status() == ThreadContext::Active && _status != Running) {
_status = Running;
- tickEvent.schedule(nextCycle());
+ schedule(tickEvent, nextCycle());
break;
}
}
numCycles += tickToCycles(thread->lastActivate - thread->lastSuspend);
//Make sure ticks are still on multiples of cycles
- tickEvent.schedule(nextCycle(curTick + ticks(delay)));
+ schedule(tickEvent, nextCycle(curTick + ticks(delay)));
_status = Running;
}
// tick event may not be scheduled if this gets called from inside
// an instruction's execution, e.g. "quiesce"
if (tickEvent.scheduled())
- tickEvent.deschedule();
+ deschedule(tickEvent);
notIdleFraction--;
_status = Idle;
latency = ticks(1);
if (_status != Idle)
- tickEvent.schedule(curTick + latency);
+ schedule(tickEvent, curTick + latency);
}
TimingSimpleCPU::CpuPort::TickEvent::schedule(PacketPtr _pkt, Tick t)
{
pkt = _pkt;
- Event::schedule(t);
+ cpu->schedule(this, t);
}
TimingSimpleCPU::TimingSimpleCPU(TimingSimpleCPUParams *p)
// Delete the old event if it existed.
if (fetchEvent) {
if (fetchEvent->scheduled())
- fetchEvent->deschedule();
+ deschedule(fetchEvent);
delete fetchEvent;
}
// If we've been scheduled to resume but are then told to switch out,
// we'll need to cancel it.
if (fetchEvent && fetchEvent->scheduled())
- fetchEvent->deschedule();
+ deschedule(fetchEvent);
}
_status = Running;
// kick things off by initiating the fetch of the next instruction
- fetchEvent = new FetchEvent(this, nextCycle(curTick + ticks(delay)));
+ fetchEvent = new FetchEvent(this);
+ schedule(fetchEvent, nextCycle(curTick + ticks(delay)));
}
}
}
-TimingSimpleCPU::IprEvent::IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu, Tick t)
- : Event(&mainEventQueue), pkt(_pkt), cpu(_cpu)
+TimingSimpleCPU::IprEvent::IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu,
+ Tick t)
+ : pkt(_pkt), cpu(_cpu)
{
- schedule(t);
+ cpu->schedule(this, t);
}
void
PacketPtr pkt;
TimingSimpleCPU *cpu;
- TickEvent(TimingSimpleCPU *_cpu)
- :Event(&mainEventQueue), cpu(_cpu) {}
+ TickEvent(TimingSimpleCPU *_cpu) : cpu(_cpu) {}
const char *description() const { return "Timing CPU tick"; }
void schedule(PacketPtr _pkt, Tick t);
};
SimpleThread::serialize(ostream &os)
{
ThreadState::serialize(os);
- regs.serialize(os);
+ regs.serialize(cpu, os);
// thread_num and cpu_id are deterministic from the config
}
SimpleThread::unserialize(Checkpoint *cp, const std::string §ion)
{
ThreadState::unserialize(cp, section);
- regs.unserialize(cp, section);
+ regs.unserialize(cpu, cp, section);
// thread_num and cpu_id are deterministic from the config
}
Tick quiesceEndTick;
UNSERIALIZE_SCALAR(quiesceEndTick);
if (quiesceEndTick)
- quiesceEvent->schedule(quiesceEndTick);
+ baseCpu->schedule(quiesceEvent, quiesceEndTick);
if (kernelStats)
kernelStats->unserialize(cp, section);
#endif
//Should this be AlphaISA?
using namespace TheISA;
-TsunamiIO::TsunamiRTC::TsunamiRTC(const string &n, const TsunamiIOParams *p) :
- MC146818(n, p->time, p->year_is_bcd, p->frequency), tsunami(p->tsunami)
+TsunamiIO::RTC::RTC(const string &n, const TsunamiIOParams *p)
+ : MC146818(p->tsunami, n, p->time, p->year_is_bcd, p->frequency),
+ tsunami(p->tsunami)
{
}
TsunamiIO::TsunamiIO(const Params *p)
- : BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"),
- rtc(p->name + ".rtc", p)
+ : BasicPioDevice(p), tsunami(p->tsunami),
+ pitimer(this, p->name + "pitimer"), rtc(p->name + ".rtc", p)
{
pioSize = 0x100;
protected:
- class TsunamiRTC : public MC146818
+ class RTC : public MC146818
{
public:
- Tsunami * tsunami;
- TsunamiRTC(const std::string &n, const TsunamiIOParams *p);
+ Tsunami *tsunami;
+ RTC(const std::string &n, const TsunamiIOParams *p);
protected:
void handleEvent()
/** Intel 8253 Periodic Interval Timer */
Intel8254Timer pitimer;
- TsunamiRTC rtc;
+ RTC rtc;
uint8_t rtcAddr;
EtherBus::EtherBus(const Params *p)
: EtherObject(p), ticksPerByte(p->speed), loopback(p->loopback),
- event(&mainEventQueue, this), sender(0), dump(p->dump)
+ event(this), sender(0), dump(p->dump)
{
}
int delay = (int)ceil(((double)pkt->length * ticksPerByte) + 1.0);
DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n",
delay, ticksPerByte);
- event.schedule(curTick + delay);
+ schedule(event, curTick + delay);
return true;
}
EtherBus *bus;
public:
- DoneEvent(EventQueue *q, EtherBus *b)
- : Event(q), bus(b) {}
+ DoneEvent(EtherBus *b) : bus(b) {}
virtual void process() { bus->txDone(); }
virtual const char *description() const
{ return "ethernet bus completion"; }
public:
// non-scheduling version for createForUnserialize()
LinkDelayEvent();
- LinkDelayEvent(EtherLink::Link *link, EthPacketPtr pkt, Tick when);
+ LinkDelayEvent(EtherLink::Link *link, EthPacketPtr pkt);
void process();
if (linkDelay > 0) {
DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay);
- new LinkDelayEvent(this, packet, curTick + linkDelay);
+ Event *event = new LinkDelayEvent(this, packet);
+ parent->schedule(event, curTick + linkDelay);
} else {
txComplete(packet);
}
DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n",
delay, ticksPerByte);
- doneEvent.schedule(curTick + delay);
+ parent->schedule(doneEvent, curTick + delay);
return true;
}
if (event_scheduled) {
Tick event_time;
paramIn(cp, section, base + ".event_time", event_time);
- doneEvent.schedule(event_time);
+ parent->schedule(doneEvent, event_time);
}
}
LinkDelayEvent::LinkDelayEvent()
- : Event(&mainEventQueue), link(NULL)
+ : link(NULL)
{
setFlags(AutoSerialize);
setFlags(AutoDelete);
}
-LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, EthPacketPtr p, Tick when)
- : Event(&mainEventQueue), link(l), packet(p)
+LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, EthPacketPtr p)
+ : link(l), packet(p)
{
setFlags(AutoSerialize);
setFlags(AutoDelete);
- schedule(when);
}
void
DPRINTF(Ethernet, "bus busy...buffer for retransmission\n");
packetBuffer.push(packet);
if (!txEvent.scheduled())
- txEvent.schedule(curTick + retryTime);
+ schedule(txEvent, curTick + retryTime);
} else if (dump) {
dump->dump(packet);
}
}
if (!packetBuffer.empty() && !txEvent.scheduled())
- txEvent.schedule(curTick + retryTime);
+ schedule(txEvent, curTick + retryTime);
}
EtherInt*
EtherTap *tap;
public:
- TxEvent(EtherTap *_tap)
- : Event(&mainEventQueue), tap(_tap) {}
+ TxEvent(EtherTap *_tap) : tap(_tap) {}
void process() { tap->retransmit(); }
virtual const char *description() const
{ return "EtherTap retransmit"; }
if (regs.itr.interval() == 0 || now || lastInterrupt + itr_interval <= curTick) {
if (interEvent.scheduled()) {
- interEvent.deschedule();
+ deschedule(interEvent);
}
cpuPostInt();
} else {
DPRINTF(EthernetIntr, "EINT: Scheduling timer interrupt for tick %d\n",
int_time);
if (!interEvent.scheduled()) {
- interEvent.schedule(int_time);
+ schedule(interEvent, int_time);
}
}
}
if (interEvent.scheduled()) {
- interEvent.deschedule();
+ deschedule(interEvent);
}
if (rdtrEvent.scheduled()) {
regs.icr.rxt0(1);
- rdtrEvent.deschedule();
+ deschedule(rdtrEvent);
}
if (radvEvent.scheduled()) {
regs.icr.rxt0(1);
- radvEvent.deschedule();
+ deschedule(radvEvent);
}
if (tadvEvent.scheduled()) {
regs.icr.txdw(1);
- tadvEvent.deschedule();
+ deschedule(tadvEvent);
}
if (tidvEvent.scheduled()) {
regs.icr.txdw(1);
- tidvEvent.deschedule();
+ deschedule(tidvEvent);
}
regs.icr.int_assert(1);
if (!(regs.icr() & regs.imr)) {
DPRINTF(Ethernet, "Mask cleaned all interrupts\n");
if (interEvent.scheduled())
- interEvent.deschedule();
+ deschedule(interEvent);
if (regs.icr.int_assert())
cpuClearInt();
}
if (!interEvent.scheduled()) {
DPRINTF(Ethernet, "Scheduling for %d\n", curTick + Clock::Int::ns
* 256 * regs.itr.interval());
- interEvent.schedule(curTick + Clock::Int::ns * 256 * regs.itr.interval());
+ schedule(interEvent,
+ curTick + Clock::Int::ns * 256 * regs.itr.interval());
}
}
}
if (igbe->regs.rdtr.delay()) {
DPRINTF(EthernetSM, "RXS: Scheduling DTR for %d\n",
igbe->regs.rdtr.delay() * igbe->intClock());
- igbe->rdtrEvent.reschedule(curTick + igbe->regs.rdtr.delay() *
- igbe->intClock(),true);
+ igbe->reschedule(igbe->rdtrEvent,
+ curTick + igbe->regs.rdtr.delay() * igbe->intClock(), true);
}
if (igbe->regs.radv.idv()) {
DPRINTF(EthernetSM, "RXS: Scheduling ADV for %d\n",
igbe->regs.radv.idv() * igbe->intClock());
if (!igbe->radvEvent.scheduled()) {
- igbe->radvEvent.schedule(curTick + igbe->regs.radv.idv() *
- igbe->intClock());
+ igbe->schedule(igbe->radvEvent,
+ curTick + igbe->regs.radv.idv() * igbe->intClock());
}
}
DPRINTF(EthernetDesc, "Descriptor had IDE set\n");
if (igbe->regs.tidv.idv()) {
DPRINTF(EthernetDesc, "setting tidv\n");
- igbe->tidvEvent.reschedule(curTick + igbe->regs.tidv.idv() *
- igbe->intClock(), true);
+ igbe->reschedule(igbe->tidvEvent,
+ curTick + igbe->regs.tidv.idv() * igbe->intClock(), true);
}
if (igbe->regs.tadv.idv() && igbe->regs.tidv.idv()) {
DPRINTF(EthernetDesc, "setting tadv\n");
if (!igbe->tadvEvent.scheduled()) {
- igbe->tadvEvent.schedule(curTick + igbe->regs.tadv.idv() *
- igbe->intClock());
+ igbe->schedule(igbe->tadvEvent,
+ curTick + igbe->regs.tadv.idv() * igbe->intClock());
}
}
}
void
IGbE::restartClock()
{
- if (!tickEvent.scheduled() && (rxTick || txTick || txFifoTick) && getState() ==
- SimObject::Running)
- tickEvent.schedule((curTick/ticks(1)) * ticks(1) + ticks(1));
+ if (!tickEvent.scheduled() && (rxTick || txTick || txFifoTick) &&
+ getState() == SimObject::Running)
+ schedule(tickEvent, (curTick / ticks(1)) * ticks(1) + ticks(1));
}
unsigned int
rxTick = false;
if (tickEvent.scheduled())
- tickEvent.deschedule();
+ deschedule(tickEvent);
if (count)
changeState(Draining);
if (rxTick || txTick || txFifoTick)
- tickEvent.schedule(curTick + ticks(1));
+ schedule(tickEvent, curTick + ticks(1));
}
void
UNSERIALIZE_SCALAR(inter_time);
if (rdtr_time)
- rdtrEvent.schedule(rdtr_time);
+ schedule(rdtrEvent, rdtr_time);
if (radv_time)
- radvEvent.schedule(radv_time);
+ schedule(radvEvent, radv_time);
if (tidv_time)
- tidvEvent.schedule(tidv_time);
+ schedule(tidvEvent, tidv_time);
if (tadv_time)
- tadvEvent.schedule(tadv_time);
+ schedule(tadvEvent, tadv_time);
if (inter_time)
- interEvent.schedule(inter_time);
+ schedule(interEvent, inter_time);
txDescCache.unserialize(cp, csprintf("%s.TxDescCache", section));
wbOut = max_to_wb;
assert(!wbDelayEvent.scheduled());
- wbDelayEvent.schedule(igbe->wbDelay + curTick);
+ igbe->schedule(wbDelayEvent, curTick + igbe->wbDelay);
}
void writeback1()
{
// If we're draining delay issuing this DMA
if (igbe->drainEvent) {
- wbDelayEvent.schedule(igbe->wbDelay + curTick);
+ igbe->schedule(wbDelayEvent, curTick + igbe->wbDelay);
return;
}
curFetching = max_to_fetch;
assert(!fetchDelayEvent.scheduled());
- fetchDelayEvent.schedule(igbe->fetchDelay + curTick);
+ igbe->schedule(fetchDelayEvent, curTick + igbe->fetchDelay);
}
void fetchDescriptors1()
{
// If we're draining delay issuing this DMA
if (igbe->drainEvent) {
- fetchDelayEvent.schedule(igbe->fetchDelay + curTick);
+ igbe->schedule(fetchDelayEvent, curTick + igbe->fetchDelay);
return;
}
UNSERIALIZE_SCALAR(fetch_delay);
UNSERIALIZE_SCALAR(wb_delay);
if (fetch_delay)
- fetchDelayEvent.schedule(fetch_delay);
+ igbe->schedule(fetchDelayEvent, fetch_delay);
if (wb_delay)
- wbDelayEvent.schedule(wb_delay);
+ igbe->schedule(wbDelayEvent, wb_delay);
}
dmaState, devState);
if (ctrl->dmaPending() || ctrl->getState() != SimObject::Running) {
- dmaTransferEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
+ schedule(dmaTransferEvent, curTick + DMA_BACKOFF_PERIOD);
return;
} else
ctrl->dmaRead(curPrdAddr, sizeof(PrdEntry_t), &dmaPrdReadEvent,
DPRINTF(IdeDisk, "doDmaRead, diskDelay: %d totalDiskDelay: %d\n",
diskDelay, totalDiskDelay);
- dmaReadWaitEvent.schedule(curTick + totalDiskDelay);
+ schedule(dmaReadWaitEvent, curTick + totalDiskDelay);
}
void
}
if (ctrl->dmaPending() || ctrl->getState() != SimObject::Running) {
- dmaReadWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
+ schedule(dmaReadWaitEvent, curTick + DMA_BACKOFF_PERIOD);
return;
} else if (!dmaReadCG->done()) {
assert(dmaReadCG->complete() < MAX_DMA_SIZE);
cmdBytesLeft -= SectorSize;
}
- dmaWriteWaitEvent.schedule(curTick + totalDiskDelay);
+ schedule(dmaWriteWaitEvent, curTick + totalDiskDelay);
}
void
curPrd.getByteCount(), TheISA::PageBytes);
}
if (ctrl->dmaPending() || ctrl->getState() != SimObject::Running) {
- dmaWriteWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
+ schedule(dmaWriteWaitEvent, curTick + DMA_BACKOFF_PERIOD);
return;
} else if (!dmaWriteCG->done()) {
assert(dmaWriteCG->complete() < MAX_DMA_SIZE);
dmaState = Dma_Transfer;
// schedule dma transfer (doDmaTransfer)
- dmaTransferEvent.schedule(curTick + 1);
+ schedule(dmaTransferEvent, curTick + 1);
}
void
switch (event) {
case None : break;
- case Transfer : dmaTransferEvent.schedule(reschedule); break;
- case ReadWait : dmaReadWaitEvent.schedule(reschedule); break;
- case WriteWait : dmaWriteWaitEvent.schedule(reschedule); break;
- case PrdRead : dmaPrdReadEvent.schedule(reschedule); break;
- case DmaRead : dmaReadEvent.schedule(reschedule); break;
- case DmaWrite : dmaWriteEvent.schedule(reschedule); break;
+ case Transfer : schedule(dmaTransferEvent, reschedule); break;
+ case ReadWait : schedule(dmaReadWaitEvent, reschedule); break;
+ case WriteWait : schedule(dmaWriteWaitEvent, reschedule); break;
+ case PrdRead : schedule(dmaPrdReadEvent, reschedule); break;
+ case DmaRead : schedule(dmaReadEvent, reschedule); break;
+ case DmaWrite : schedule(dmaWriteEvent, reschedule); break;
}
// Unserialize device registers
using namespace std;
-Intel8254Timer::Intel8254Timer(const string &name)
- : _name(name), counter0(name + ".counter0"), counter1(name + ".counter1"),
- counter2(name + ".counter2")
+Intel8254Timer::Intel8254Timer(EventManager *em, const string &name)
+ : EventManager(em), _name(name),
+ counter0(this, name + ".counter0"),
+ counter1(this, name + ".counter1"),
+ counter2(this, name + ".counter2")
{
counter[0] = &counter0;
counter[1] = &counter0;
counter2.unserialize(base + ".counter2", cp, section);
}
-Intel8254Timer::Counter::Counter(const string &name)
+Intel8254Timer::Counter::Counter(Intel8254Timer *p, const string &name)
: _name(name), event(this), count(0), latched_count(0), period(0),
mode(0), output_high(false), latch_on(false), read_byte(LSB),
- write_byte(LSB)
+ write_byte(LSB), parent(p)
{
}
count = (count & 0xFF00) | data;
if (event.scheduled())
- event.deschedule();
+ parent->deschedule(event);
output_high = false;
write_byte = MSB;
break;
Tick event_tick;
paramIn(cp, section, base + ".event_tick", event_tick);
if (event_tick)
- event.schedule(event_tick);
+ parent->schedule(event, event_tick);
}
Intel8254Timer::Counter::CounterEvent::CounterEvent(Counter* c_ptr)
- : Event(&mainEventQueue)
{
interval = (Tick)(Clock::Float::s / 1193180.0);
counter = c_ptr;
panic("Timer can't be set to go off instantly.\n");
DPRINTF(Intel8254Timer, "Timer set to curTick + %d\n",
clocks * interval);
- schedule(curTick + clocks * interval);
+ counter->parent->schedule(this, curTick + clocks * interval);
}
const char *
#ifndef __DEV_8254_HH__
#define __DEV_8254_HH__
+#include <string>
+#include <iostream>
+
#include "base/bitunion.hh"
#include "sim/eventq.hh"
#include "sim/host.hh"
#include "sim/serialize.hh"
-#include <string>
-#include <iostream>
-
/** Programmable Interval Timer (Intel 8254) */
-class Intel8254Timer
+class Intel8254Timer : public EventManager
{
BitUnion8(CtrlReg)
Bitfield<7, 6> sel;
/** Determine which byte of a 16-bit count value to read/write */
uint8_t read_byte, write_byte;
+ /** Pointer to container */
+ Intel8254Timer *parent;
+
public:
- Counter(const std::string &name);
+ Counter(Intel8254Timer *p, const std::string &name);
/** Latch the current count (if one is not already latched) */
void latchCount();
Counter counter1;
Counter counter2;
- Intel8254Timer(const std::string &name);
+ Intel8254Timer(EventManager *em, const std::string &name);
/** Write control word */
void writeControl(const CtrlReg data);
else if (backoffTime < device->maxBackoffDelay)
backoffTime <<= 1;
- backoffEvent.reschedule(curTick + backoffTime, true);
+ reschedule(backoffEvent, curTick + backoffTime, true);
DPRINTF(DMA, "Backoff time set to %d ticks\n", backoffTime);
assert(state->totBytes >= state->numBytes);
if (state->totBytes == state->numBytes) {
if (state->delay)
- state->completionEvent->schedule(state->delay + curTick);
+ schedule(state->completionEvent, curTick + state->delay);
else
state->completionEvent->process();
delete state;
if (transmitList.size() && backoffTime && !inRetry) {
DPRINTF(DMA, "Scheduling backoff for %d\n", curTick+backoffTime);
if (!backoffEvent.scheduled())
- backoffEvent.schedule(backoffTime+curTick);
+ schedule(backoffEvent, backoffTime + curTick);
}
DPRINTF(DMA, "TransmitList: %d, backoffTime: %d inRetry: %d es: %d\n",
transmitList.size(), backoffTime, inRetry,
!backoffEvent.scheduled()) {
DPRINTF(DMA, "-- Scheduling backoff timer for %d\n",
backoffTime+curTick);
- backoffEvent.schedule(backoffTime+curTick);
+ schedule(backoffEvent, backoffTime + curTick);
}
} else if (state == Enums::atomic) {
transmitList.pop_front();
if (state->totBytes == state->numBytes) {
assert(!state->completionEvent->scheduled());
- state->completionEvent->schedule(curTick + lat + state->delay);
+ schedule(state->completionEvent, curTick + lat + state->delay);
delete state;
delete pkt->req;
}
using namespace std;
-MC146818::MC146818(const string &n, const struct tm time,
- bool bcd, Tick frequency)
- : _name(n), event(this, frequency)
+MC146818::MC146818(EventManager *em, const string &n, const struct tm time,
+ bool bcd, Tick frequency)
+ : EventManager(em), _name(n), event(this, frequency)
{
memset(clock_data, 0, sizeof(clock_data));
stat_regA = RTCA_32768HZ | RTCA_1024HZ;
DPRINTFN("Real-time clock set to %s", asctime(&time));
}
+MC146818::~MC146818()
+{
+}
+
void
MC146818::writeData(const uint8_t addr, const uint8_t data)
{
event.scheduleIntr();
} else {
if (event.scheduled())
- event.deschedule();
+ deschedule(event);
}
stat_regB = data;
break;
// We're not unserializing the event here, but we need to
// rescehedule the event since curTick was moved forward by the
// checkpoint
- event.reschedule(curTick + event.interval);
+ reschedule(event, curTick + event.interval);
}
MC146818::RTCEvent::RTCEvent(MC146818 * _parent, Tick i)
- : Event(&mainEventQueue), parent(_parent), interval(i)
+ : parent(_parent), interval(i)
{
DPRINTF(MC146818, "RTC Event Initilizing\n");
- schedule(curTick + interval);
+ parent->schedule(this, curTick + interval);
}
void
MC146818::RTCEvent::scheduleIntr()
{
- schedule(curTick + interval);
+ parent->schedule(this, curTick + interval);
}
void
MC146818::RTCEvent::process()
{
DPRINTF(MC146818, "RTC Timer Interrupt\n");
- schedule(curTick + interval);
+ parent->schedule(this, curTick + interval);
parent->handleEvent();
}
#include "sim/eventq.hh"
/** Real-Time Clock (MC146818) */
-class MC146818
+class MC146818 : public EventManager
{
protected:
virtual void handleEvent()
uint8_t stat_regB;
public:
- virtual ~MC146818()
- {}
-
- MC146818(const std::string &name, const struct tm time,
+ MC146818(EventManager *em, const std::string &name, const struct tm time,
bool bcd, Tick frequency);
+ virtual ~MC146818();
/** RTC write data */
void writeData(const uint8_t addr, const uint8_t data);
if (intrEvent)
intrEvent->squash();
- intrEvent = new IntrEvent(this, intrTick, true);
+ intrEvent = new IntrEvent(this, true);
+ schedule(intrEvent, intrTick);
}
void
NsRxStateStrings[rxState]);
if (clock && !rxKickEvent.scheduled())
- rxKickEvent.schedule(rxKickTick);
+ schedule(rxKickEvent, rxKickTick);
}
void
if (!txFifo.empty() && !txEvent.scheduled()) {
DPRINTF(Ethernet, "reschedule transmit\n");
- txEvent.schedule(curTick + retryTime);
+ schedule(txEvent, curTick + retryTime);
}
}
NsTxStateStrings[txState]);
if (clock && !txKickEvent.scheduled())
- txKickEvent.schedule(txKickTick);
+ schedule(txKickEvent, txKickTick);
}
/**
DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n");
- txEvent.reschedule(curTick + ticks(1), true);
+ reschedule(txEvent, curTick + ticks(1), true);
}
bool
this->txDmaState = (DmaState) txDmaState;
UNSERIALIZE_SCALAR(txKickTick);
if (txKickTick)
- txKickEvent.schedule(txKickTick);
+ schedule(txKickEvent, txKickTick);
/*
* unserialize rx state machine
this->rxDmaState = (DmaState) rxDmaState;
UNSERIALIZE_SCALAR(rxKickTick);
if (rxKickTick)
- rxKickEvent.schedule(rxKickTick);
+ schedule(rxKickEvent, rxKickTick);
/*
* Unserialize EEPROM state machine
Tick transmitTick;
UNSERIALIZE_SCALAR(transmitTick);
if (transmitTick)
- txEvent.schedule(curTick + transmitTick);
+ schedule(txEvent, curTick + transmitTick);
/*
* unserialize receive address filter settings
Tick intrEventTick;
UNSERIALIZE_SCALAR(intrEventTick);
if (intrEventTick) {
- intrEvent = new IntrEvent(this, intrEventTick, true);
+ intrEvent = new IntrEvent(this, true);
+ schedule(intrEvent, intrEventTick);
}
}
PciDev::PciConfigPort::PciConfigPort(PciDev *dev, int busid, int devid,
int funcid, Platform *p)
- : SimpleTimingPort(dev->name() + "-pciconf"), device(dev), platform(p),
- busId(busid), deviceId(devid), functionId(funcid)
+ : SimpleTimingPort(dev->name() + "-pciconf", dev), device(dev),
+ platform(p), busId(busid), deviceId(devid), functionId(funcid)
{
configAddr = platform->calcConfigAddr(busId, deviceId, functionId);
}
if (intrEvent)
intrEvent->squash();
- intrEvent = new IntrEvent(this, intrTick, true);
+ intrEvent = new IntrEvent(this, true);
+ schedule(intrEvent, intrTick);
}
void
DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n");
- txEvent.reschedule(curTick + ticks(1), true);
+ reschedule(txEvent, curTick + ticks(1), true);
}
bool
Tick intrEventTick;
UNSERIALIZE_SCALAR(intrEventTick);
if (intrEventTick) {
- intrEvent = new IntrEvent(this, intrEventTick, true);
+ intrEvent = new IntrEvent(this, true);
+ schedule(intrEvent, intrEventTick);
}
}
Tick transmitTick;
UNSERIALIZE_SCALAR(transmitTick);
if (transmitTick)
- txEvent.schedule(curTick + transmitTick);
+ schedule(txEvent, curTick + transmitTick);
pioPort->sendStatusChange(Port::RangeChange);
using namespace TheISA;
Uart8250::IntrEvent::IntrEvent(Uart8250 *u, int bit)
- : Event(&mainEventQueue), uart(u)
+ : uart(u)
{
DPRINTF(Uart, "UART Interrupt Event Initilizing\n");
intrBit = bit;
DPRINTF(Uart, "Scheduling IER interrupt for %#x, at cycle %lld\n", intrBit,
curTick + interval);
if (!scheduled())
- schedule(curTick + interval);
+ uart->schedule(this, curTick + interval);
else
- reschedule(curTick + interval);
+ uart->reschedule(this, curTick + interval);
}
{
DPRINTF(Uart, "IER: IER_THRI cleared, descheduling TX intrrupt\n");
if (txIntrEvent.scheduled())
- txIntrEvent.deschedule();
+ deschedule(txIntrEvent);
if (status & TX_INT)
platform->clearConsoleInt();
status &= ~TX_INT;
} else {
DPRINTF(Uart, "IER: IER_RDI cleared, descheduling RX intrrupt\n");
if (rxIntrEvent.scheduled())
- rxIntrEvent.deschedule();
+ deschedule(rxIntrEvent);
if (status & RX_INT)
platform->clearConsoleInt();
status &= ~RX_INT;
UNSERIALIZE_SCALAR(rxintrwhen);
UNSERIALIZE_SCALAR(txintrwhen);
if (rxintrwhen != 0)
- rxIntrEvent.schedule(rxintrwhen);
+ schedule(rxIntrEvent, rxintrwhen);
if (txintrwhen != 0)
- txIntrEvent.schedule(txintrwhen);
+ schedule(txIntrEvent, txintrwhen);
}
Uart8250 *
int _delay, int _nack_delay, int _req_limit,
int _resp_limit,
std::vector<Range<Addr> > filter_ranges)
- : Port(_name), bridge(_bridge), otherPort(_otherPort),
+ : Port(_name, _bridge), bridge(_bridge), otherPort(_otherPort),
delay(_delay), nackDelay(_nack_delay), filterRanges(filter_ranges),
outstandingResponses(0), queuedRequests(0), inRetry(false),
reqQueueLimit(_req_limit), respQueueLimit(_resp_limit), sendEvent(this)
// nothing on the list, add it and we're done
if (sendQueue.empty()) {
assert(!sendEvent.scheduled());
- sendEvent.schedule(readyTime);
+ schedule(sendEvent, readyTime);
sendQueue.push_back(buf);
return;
}
while (i != end && !done) {
if (readyTime < (*i)->ready) {
if (i == begin)
- sendEvent.reschedule(readyTime);
+ reschedule(sendEvent, readyTime);
sendQueue.insert(i,buf);
done = true;
}
// should already be an event scheduled for sending the head
// packet.
if (sendQueue.empty()) {
- sendEvent.schedule(readyTime);
+ schedule(sendEvent, readyTime);
}
sendQueue.push_back(buf);
}
if (!sendQueue.empty()) {
buf = sendQueue.front();
DPRINTF(BusBridge, "Scheduling next send\n");
- sendEvent.schedule(std::max(buf->ready, curTick + 1));
+ schedule(sendEvent, std::max(buf->ready, curTick + 1));
}
} else {
DPRINTF(BusBridge, " unsuccessful\n");
if (nextReady <= curTick)
trySend();
else
- sendEvent.schedule(nextReady);
+ schedule(sendEvent, nextReady);
}
/** Function called by the port when the bus is receiving a Atomic
BridgePort *port;
public:
- SendEvent(BridgePort *p)
- : Event(&mainEventQueue), port(p) {}
-
+ SendEvent(BridgePort *p) : port(p) {}
virtual void process() { port->trySend(); }
-
virtual const char *description() const { return "bridge send"; }
};
intIter->second->sendStatusChange(Port::RangeChange);
}
-Bus::BusFreeEvent::BusFreeEvent(Bus *_bus) : Event(&mainEventQueue), bus(_bus)
+Bus::BusFreeEvent::BusFreeEvent(Bus *_bus)
+ : bus(_bus)
{}
-void Bus::BusFreeEvent::process()
+void
+Bus::BusFreeEvent::process()
{
bus->recvRetry(-1);
}
-const char * Bus::BusFreeEvent::description() const
+const char *
+Bus::BusFreeEvent::description() const
{
return "bus became available";
}
-Tick Bus::calcPacketTiming(PacketPtr pkt)
+Tick
+Bus::calcPacketTiming(PacketPtr pkt)
{
// Bring tickNextIdle up to the present tick.
// There is some potential ambiguity where a cycle starts, which
}
tickNextIdle = until;
+ reschedule(busIdle, tickNextIdle, true);
- if (!busIdle.scheduled()) {
- busIdle.schedule(tickNextIdle);
- } else {
- busIdle.reschedule(tickNextIdle);
- }
DPRINTF(Bus, "The bus is now occupied from tick %d to %d\n",
curTick, tickNextIdle);
}
//Burn a cycle for the missed grant.
tickNextIdle += clock;
- busIdle.reschedule(tickNextIdle, true);
+ reschedule(busIdle, tickNextIdle, true);
}
}
//If we weren't able to drain before, we might be able to now.
mustSendRetry = false;
SendRetryEvent *ev = new SendRetryEvent(this, true);
// @TODO: need to find a better time (next bus cycle?)
- ev->schedule(curTick + 1);
+ schedule(ev, curTick + 1);
}
}
// @TODO: need to facotr in prefetch requests here somehow
if (nextReady != MaxTick) {
DPRINTF(CachePort, "more packets to send @ %d\n", nextReady);
- sendEvent->schedule(std::max(nextReady, curTick + 1));
+ schedule(sendEvent, std::max(nextReady, curTick + 1));
} else {
// no more to send right now: if we're draining, we may be done
if (drainEvent) {
PhysicalMemory::MemoryPort::MemoryPort(const std::string &_name,
PhysicalMemory *_memory)
- : SimpleTimingPort(_name), memory(_memory)
+ : SimpleTimingPort(_name, _memory), memory(_memory)
{ }
void
if (success) {
if (!transmitList.empty() && !sendEvent->scheduled()) {
Tick time = transmitList.front().tick;
- sendEvent->schedule(time <= curTick ? curTick+1 : time);
+ schedule(sendEvent, time <= curTick ? curTick+1 : time);
}
if (transmitList.empty() && drainEvent) {
Tick deferredPacketReadyTime()
{ return transmitList.empty() ? MaxTick : transmitList.front().tick; }
- void schedSendEvent(Tick when)
+ void
+ schedSendEvent(Tick when)
{
if (waitingOnRetry) {
assert(!sendEvent->scheduled());
}
if (!sendEvent->scheduled()) {
- sendEvent->schedule(when);
+ schedule(sendEvent, when);
} else if (sendEvent->when() > when) {
- sendEvent->reschedule(when);
+ reschedule(sendEvent, when);
}
}
public:
- SimpleTimingPort(std::string pname, MemObject *_owner = NULL)
+ SimpleTimingPort(std::string pname, MemObject *_owner)
: Port(pname, _owner),
sendEvent(new SendEvent(this)),
drainEvent(NULL),
if options.trace_start:
def enable_trace():
internal.trace.cvar.enabled = True
- event.create(enable_trace, int(options.trace_start))
+
+ e = event.create(enable_trace)
+ event.mainq.schedule(e, options.trace_start)
else:
internal.trace.cvar.enabled = True
// Debug event: place a breakpoint on the process function and
// schedule the event to break at a particular cycle
//
-class DebugBreakEvent : public Event
+struct DebugBreakEvent : public Event
{
- public:
-
- DebugBreakEvent(EventQueue *q, Tick _when);
-
+ DebugBreakEvent();
void process(); // process event
virtual const char *description() const;
};
//
// constructor: schedule at specified time
//
-DebugBreakEvent::DebugBreakEvent(EventQueue *q, Tick _when)
- : Event(q, Debug_Break_Pri)
+DebugBreakEvent::DebugBreakEvent()
+ : Event(Debug_Break_Pri)
{
setFlags(AutoDelete);
- schedule(_when);
}
//
void
schedBreakCycle(Tick when)
{
- new DebugBreakEvent(&mainEventQueue, when);
+ mainEventQueue.schedule(new DebugBreakEvent, when);
+ warn("need to stop all queues");
}
void
eventqDump()
{
mainEventQueue.dump();
+ warn("need to dump all queues");
}
#include "params/BaseCPU.hh"
#include "sim/pseudo_inst.hh"
#include "sim/serialize.hh"
+#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
#include "sim/stat_control.hh"
#include "sim/stats.hh"
Tick resume = curTick + Clock::Int::ns * ns;
- quiesceEvent->reschedule(resume, true);
+ mainEventQueue.reschedule(quiesceEvent, resume, true);
DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
tc->getCpuPtr()->name(), ns, resume);
Tick resume = curTick + tc->getCpuPtr()->ticks(cycles);
- quiesceEvent->reschedule(resume, true);
+ mainEventQueue.reschedule(quiesceEvent, resume, true);
DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
tc->getCpuPtr()->name(), cycles, resume);
m5exit(ThreadContext *tc, Tick delay)
{
Tick when = curTick + delay * Clock::Int::ns;
- schedExitSimLoop("m5_exit instruction encountered", when);
+ Event *event = new SimLoopExitEvent("m5_exit instruction encountered", 0);
+ mainEventQueue.schedule(event, when);
}
void
Tick when = curTick + delay * Clock::Int::ns;
Tick repeat = period * Clock::Int::ns;
- schedExitSimLoop("checkpoint", when, repeat);
+ Event *event = new SimLoopExitEvent("checkpoint", 0, repeat);
+ mainEventQueue.schedule(event, when);
}
uint64_t
using namespace std;
+SimLoopExitEvent::SimLoopExitEvent(const std::string &_cause, int c, Tick r)
+ : Event(Sim_Exit_Pri), cause(_cause), code(c), repeat(r)
+{
+ setFlags(IsExitEvent);
+}
+
+
//
// handle termination event
//
// if this got scheduled on a different queue (e.g. the committed
// instruction queue) then make a corresponding event on the main
// queue.
- if (queue() != &mainEventQueue) {
+ if (!getFlags(IsMainQueue)) {
exitSimLoop(cause, code);
delete this;
}
// but if you are doing this on intervals, don't forget to make another
if (repeat) {
- schedule(curTick + repeat);
+ assert(getFlags(IsMainQueue));
+ mainEventQueue.schedule(this, curTick + repeat);
}
}
return "simulation loop exit";
}
-SimLoopExitEvent *
-schedExitSimLoop(const std::string &message, Tick when, Tick repeat,
- EventQueue *q, int exit_code)
-{
- if (q == NULL)
- q = &mainEventQueue;
-
- return new SimLoopExitEvent(q, when, repeat, message, exit_code);
-}
-
void
exitSimLoop(const std::string &message, int exit_code)
{
- schedExitSimLoop(message, curTick, 0, NULL, exit_code);
+ Event *event = new SimLoopExitEvent(message, exit_code);
+ mainEventQueue.schedule(event, curTick);
}
+CountedDrainEvent::CountedDrainEvent()
+ : SimLoopExitEvent("Finished drain", 0), count(0)
+{ }
+
void
CountedDrainEvent::process()
{
- if (--count == 0) {
- exitSimLoop("Finished drain");
- }
+ if (--count == 0)
+ exitSimLoop(cause, code);
}
//
// constructor: automatically schedules at specified time
//
-CountedExitEvent::CountedExitEvent(EventQueue *q, const std::string &_cause,
- Tick _when, int &_downCounter)
- : Event(q, Sim_Exit_Pri),
- cause(_cause),
- downCounter(_downCounter)
+CountedExitEvent::CountedExitEvent(const std::string &_cause, int &counter)
+ : Event(Sim_Exit_Pri), cause(_cause), downCounter(counter)
{
// catch stupid mistakes
assert(downCounter > 0);
-
- schedule(_when);
}
return "counted exit";
}
-#ifdef CHECK_SWAP_CYCLES
-new CheckSwapEvent(&mainEventQueue, CHECK_SWAP_CYCLES);
-#endif
+CheckSwapEvent::CheckSwapEvent(int ival)
+ : interval(ival)
+{
+ mainEventQueue.schedule(this, curTick + interval);
+}
void
CheckSwapEvent::process()
exitSimLoop("Lack of swap space");
}
- schedule(curTick + interval);
+ assert(getFlags(IsMainQueue));
+ mainEventQueue.schedule(this, curTick + interval);
}
const char *
//
class SimLoopExitEvent : public Event
{
- private:
+ protected:
// string explaining why we're terminating
std::string cause;
int code;
Tick repeat;
public:
- // Default constructor. Only really used for derived classes.
- SimLoopExitEvent()
- : Event(&mainEventQueue, Sim_Exit_Pri)
- { }
-
- SimLoopExitEvent(EventQueue *q,
- Tick _when, Tick _repeat, const std::string &_cause,
- int c = 0)
- : Event(q, Sim_Exit_Pri), cause(_cause),
- code(c), repeat(_repeat)
- { setFlags(IsExitEvent); schedule(_when); }
-
-// SimLoopExitEvent(EventQueue *q,
-// Tick _when, const std::string &_cause,
-// Tick _repeat = 0, int c = 0)
-// : Event(q, Sim_Exit_Pri), cause(_cause), code(c), repeat(_repeat)
-// { setFlags(IsExitEvent); schedule(_when); }
+ SimLoopExitEvent(const std::string &_cause, int c, Tick repeat = 0);
std::string getCause() { return cause; }
int getCode() { return code; }
private:
// Count of how many objects have not yet drained
int count;
+
public:
- CountedDrainEvent()
- : count(0)
- { }
+ CountedDrainEvent();
+
void process();
void setCount(int _count) { count = _count; }
int &downCounter; // decrement & terminate if zero
public:
- CountedExitEvent(EventQueue *q, const std::string &_cause,
- Tick _when, int &_downCounter);
+ CountedExitEvent(const std::string &_cause, int &_downCounter);
void process(); // process event
int interval;
public:
- CheckSwapEvent(EventQueue *q, int ival)
- : Event(q), interval(ival)
- { schedule(curTick + interval); }
-
+ CheckSwapEvent(int ival);
void process(); // process event
virtual const char *description() const;
/// sim/main.cc.
void registerExitCallback(Callback *);
-/// Schedule an event to exit the simulation loop (returning to
-/// Python) at the indicated tick. The message and exit_code
-/// parameters are saved in the SimLoopExitEvent to indicate why the
-/// exit occurred.
-SimLoopExitEvent *schedExitSimLoop(const std::string &message, Tick when,
- Tick repeat = 0, EventQueue *q = NULL,
- int exit_code = 0);
-
/// Schedule an event to exit the simulation loop (returning to
/// Python) at the end of the current cycle (curTick). The message
/// and exit_code parameters are saved in the SimLoopExitEvent to
#include <string>
struct EventQueue;
+
struct SimObjectParams
{
+ SimObjectParams()
+ {
+ extern EventQueue mainEventQueue;
+ eventq = &mainEventQueue;
+ }
virtual ~SimObjectParams() {}
std::string name;
else
num_cycles = curTick + num_cycles;
- Event *limit_event;
- limit_event = schedExitSimLoop("simulate() limit reached", num_cycles);
+ Event *limit_event =
+ new SimLoopExitEvent("simulate() limit reached", 0);
+ mainEventQueue.schedule(limit_event, num_cycles);
while (1) {
// there should always be at least one event (the SimLoopExitEvent
// if we didn't hit limit_event, delete it
if (se_event != limit_event) {
assert(limit_event->scheduled());
- limit_event->deschedule();
- delete limit_event;
+ limit_event->squash();
+ warn_once("be nice to actually delete the event here");
}
return se_event;
Tick repeat;
public:
- _StatEvent(bool _dump, bool _reset, Tick _when, Tick _repeat)
- : Event(&mainEventQueue, Stat_Event_Pri), dump(_dump), reset(_reset),
- repeat(_repeat)
+ _StatEvent(bool _dump, bool _reset, Tick _repeat)
+ : Event(Stat_Event_Pri), dump(_dump), reset(_reset), repeat(_repeat)
{
setFlags(AutoDelete);
- schedule(_when);
}
virtual void
if (reset)
Stats::reset();
- if (repeat)
- new _StatEvent(dump, reset, curTick + repeat, repeat);
+ if (repeat) {
+ Event *event = new _StatEvent(dump, reset, repeat);
+ mainEventQueue.schedule(event, curTick + repeat);
+ }
}
};
void
StatEvent(bool dump, bool reset, Tick when, Tick repeat)
{
- new _StatEvent(dump, reset, when, repeat);
+ Event *event = new _StatEvent(dump, reset, repeat);
+ mainEventQueue.schedule(event, when);
}
/* namespace Stats */ }