AlphaO3CPU<Impl>::hwrei(unsigned tid)
{
// Need to clear the lock flag upon returning from an interrupt.
- this->lockFlag = false;
+ this->setMiscReg(AlphaISA::MISCREG_LOCKFLAG, false, tid);
this->thread[tid]->kernelStats->hwrei();
return true;
}
+ template <class Impl>
+ Fault
+ AlphaO3CPU<Impl>::getInterrupts()
+ {
+ // Check if there are any outstanding interrupts
+ return this->interrupts.getInterrupt(this->threadContexts[0]);
+ }
+
template <class Impl>
void
- AlphaO3CPU<Impl>::processInterrupts()
+ AlphaO3CPU<Impl>::processInterrupts(Fault interrupt)
{
// Check for interrupts here. For now can copy the code that
// exists within isa_fullsys_traits.hh. Also assume that thread 0
// @todo: Possibly consolidate the interrupt checking code.
// @todo: Allow other threads to handle interrupts.
- // Check if there are any outstanding interrupts
- //Handle the interrupts
- Fault interrupt = this->interrupts.getInterrupt(this->tcBase(0));
+ assert(interrupt != NoFault);
+ this->interrupts.updateIntrInfo(this->threadContexts[0]);
- if (interrupt != NoFault) {
- this->checkInterrupts = false;
- this->trap(interrupt, 0);
- }
+ DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
+ this->checkInterrupts = false;
+ this->trap(interrupt, 0);
}
#endif // FULL_SYSTEM
void
DefaultFetch<Impl>::IcachePort::recvFunctional(PacketPtr pkt)
{
- warn("Default fetch doesn't update it's state from a functional call.");
+ DPRINTF(Fetch, "DefaultFetch doesn't update its state from a "
+ "functional call.");
}
template<class Impl>
bool
DefaultFetch<Impl>::IcachePort::recvTiming(PacketPtr pkt)
{
+ DPRINTF(Fetch, "Received timing\n");
if (pkt->isResponse()) {
fetch->processCacheCompletion(pkt);
}
Fault fault = NoFault;
//AlphaDep
- if (cacheBlocked || isSwitchedOut() ||
- (interruptPending && (fetch_PC & 0x3))) {
+ if (cacheBlocked) {
+ DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, cache blocked\n",
+ tid);
+ return false;
+ } else if (isSwitchedOut()) {
+ DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, switched out\n",
+ tid);
+ return false;
+ } else if (interruptPending && !(fetch_PC & 0x3)) {
// Hold off fetch from getting new instructions when:
// Cache is blocked, or
// while an interrupt is pending and we're not in PAL mode, or
// fetch is switched out.
+ DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, interrupt pending\n",
+ tid);
return false;
}
// Align the fetch PC so it's at the start of a cache block.
- fetch_PC = icacheBlockAlignPC(fetch_PC);
+ Addr block_PC = icacheBlockAlignPC(fetch_PC);
// If we've already got the block, no need to try to fetch it again.
- if (cacheDataValid[tid] && fetch_PC == cacheDataPC[tid]) {
+ if (cacheDataValid[tid] && block_PC == cacheDataPC[tid]) {
return true;
}
// Setup the memReq to do a read of the first instruction's address.
// Set the appropriate read size and flags as well.
// Build request here.
- RequestPtr mem_req = new Request(tid, fetch_PC, cacheBlkSize, 0,
+ RequestPtr mem_req = new Request(tid, block_PC, cacheBlkSize, 0,
fetch_PC, cpu->readCpuId(), tid);
memReq[tid] = mem_req;
Packet::ReadReq, Packet::Broadcast);
data_pkt->dataDynamicArray(new uint8_t[cacheBlkSize]);
- cacheDataPC[tid] = fetch_PC;
+ cacheDataPC[tid] = block_PC;
cacheDataValid[tid] = false;
DPRINTF(Fetch, "Fetch: Doing instruction read.\n");
} else {
if (fetchStatus[tid] == Idle) {
++fetchIdleCycles;
+ DPRINTF(Fetch, "[tid:%i]: Fetch is idle!\n", tid);
} else if (fetchStatus[tid] == Blocked) {
++fetchBlockedCycles;
+ DPRINTF(Fetch, "[tid:%i]: Fetch is blocked!\n", tid);
} else if (fetchStatus[tid] == Squashing) {
++fetchSquashCycles;
+ DPRINTF(Fetch, "[tid:%i]: Fetch is squashing!\n", tid);
} else if (fetchStatus[tid] == IcacheWaitResponse) {
++icacheStallCycles;
+ DPRINTF(Fetch, "[tid:%i]: Fetch is waiting cache response!\n", tid);
}
// Status is Idle, Squashing, Blocked, or IcacheWaitResponse, so
fetch_PC = next_PC;
if (instruction->isQuiesce()) {
-// warn("%lli: Quiesce instruction encountered, halting fetch!",
-// curTick);
+ DPRINTF(Fetch, "Quiesce instruction encountered, halting fetch!",
+ curTick);
fetchStatus[tid] = QuiescePending;
++numInst;
status_change = true;
fetchStatus[tid] = TrapPending;
status_change = true;
-
-// warn("%lli fault (%d) detected @ PC %08p", curTick, fault, PC[tid]);
#else // !FULL_SYSTEM
- warn("cycle %lli: fault (%s) detected @ PC %08p", curTick, fault->name(), PC[tid]);
+ fetchStatus[tid] = TrapPending;
+ status_change = true;
+
#endif // FULL_SYSTEM
+ DPRINTF(Fetch, "[tid:%i]: fault (%s) detected @ PC %08p",
+ tid, fault->name(), PC[tid]);
}
}
break;
}
}
+ if (_status != Running) {
+ _status = Idle;
+ }
}
SimObjectParam<TheISA::ITB *> itb;
SimObjectParam<TheISA::DTB *> dtb;
Param<Tick> profile;
+
+ Param<bool> do_quiesce;
+ Param<bool> do_checkpoint_insts;
+ Param<bool> do_statistics_insts;
#else
SimObjectParam<Process *> workload;
#endif // FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"),
INIT_PARAM(dtb, "Data TLB"),
INIT_PARAM(profile, ""),
+ INIT_PARAM(do_quiesce, ""),
+ INIT_PARAM(do_checkpoint_insts, ""),
+ INIT_PARAM(do_statistics_insts, ""),
#else
INIT_PARAM(workload, "processes to run"),
#endif // FULL_SYSTEM
params->itb = itb;
params->dtb = dtb;
params->profile = profile;
+ params->do_quiesce = do_quiesce;
+ params->do_checkpoint_insts = do_checkpoint_insts;
+ params->do_statistics_insts = do_statistics_insts;
#else
params->process = workload;
#endif