#include "cpu/smt.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
-#include "kern/kernel_stats.hh"
-#include "mem/packet_impl.hh"
+#include "mem/packet.hh"
#include "sim/builder.hh"
#include "sim/byteswap.hh"
#include "sim/debug.hh"
#include "sim/system.hh"
#if FULL_SYSTEM
-#include "base/remote_gdb.hh"
-#include "arch/tlb.hh"
+#include "arch/kernel_stats.hh"
#include "arch/stacktrace.hh"
+#include "arch/tlb.hh"
#include "arch/vtophys.hh"
+#include "base/remote_gdb.hh"
#else // !FULL_SYSTEM
#include "mem/mem_object.hh"
#endif // FULL_SYSTEM
using namespace TheISA;
BaseSimpleCPU::BaseSimpleCPU(Params *p)
- : BaseCPU(p), mem(p->mem), thread(NULL)
+ : BaseCPU(p), thread(NULL)
{
#if FULL_SYSTEM
thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
#else
thread = new SimpleThread(this, /* thread_num */ 0, p->process,
- /* asid */ 0, mem);
+ /* asid */ 0);
#endif // !FULL_SYSTEM
thread->setStatus(ThreadContext::Suspended);
void
BaseSimpleCPU::resetStats()
{
- startNumInst = numInst;
+// startNumInst = numInst;
// notIdleFraction = (_status != Idle);
}
BaseSimpleCPU::checkForInterrupts()
{
#if FULL_SYSTEM
- if (checkInterrupts && check_interrupts() && !thread->inPalMode()) {
- int ipl = 0;
- int summary = 0;
- checkInterrupts = false;
-
- if (thread->readMiscReg(IPR_SIRR)) {
- for (int i = INTLEVEL_SOFTWARE_MIN;
- i < INTLEVEL_SOFTWARE_MAX; i++) {
- if (thread->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
- // See table 4-19 of 21164 hardware reference
- ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
- summary |= (ULL(1) << i);
- }
- }
- }
+ if (checkInterrupts && check_interrupts(tc)) {
+ Fault interrupt = interrupts.getInterrupt(tc);
- uint64_t interrupts = thread->cpu->intr_status();
- for (int i = INTLEVEL_EXTERNAL_MIN;
- i < INTLEVEL_EXTERNAL_MAX; i++) {
- if (interrupts & (ULL(1) << i)) {
- // See table 4-19 of 21164 hardware reference
- ipl = i;
- summary |= (ULL(1) << i);
- }
- }
-
- if (thread->readMiscReg(IPR_ASTRR))
- panic("asynchronous traps not implemented\n");
-
- if (ipl && ipl > thread->readMiscReg(IPR_IPLR)) {
- thread->setMiscReg(IPR_ISR, summary);
- thread->setMiscReg(IPR_INTID, ipl);
-
- Fault(new InterruptFault)->invoke(tc);
-
- DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
- thread->readMiscReg(IPR_IPLR), ipl, summary);
+ if (interrupt != NoFault) {
+ interrupts.updateIntrInfo(tc);
+ checkInterrupts = false;
+ interrupt->invoke(tc);
}
}
#endif
BaseSimpleCPU::setupFetchRequest(Request *req)
{
// set up memory request for instruction fetch
-#if THE_ISA == ALPHA_ISA
- DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p",thread->readPC(),
- thread->readNextPC());
-#else
+#if ISA_HAS_DELAY_SLOT
DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",thread->readPC(),
thread->readNextPC(),thread->readNextNPC());
+#else
+ DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p",thread->readPC(),
+ thread->readNextPC());
#endif
req->setVirt(0, thread->readPC() & ~3, sizeof(MachInst),
// decode the instruction
inst = gtoh(inst);
- curStaticInst = StaticInst::decode(makeExtMI(inst, thread->readPC()));
+ //If we're not in the middle of a macro instruction
+ if (!curMacroStaticInst) {
+#if THE_ISA == ALPHA_ISA
+ StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->readPC()));
+#elif THE_ISA == SPARC_ISA
+ StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC()));
+#elif THE_ISA == MIPS_ISA
+ //Mips doesn't do anything in it's MakeExtMI function right now,
+ //so it won't be called.
+ StaticInstPtr instPtr = StaticInst::decode(inst);
+#endif
+ if (instPtr->isMacroOp()) {
+ curMacroStaticInst = instPtr;
+ curStaticInst = curMacroStaticInst->
+ fetchMicroOp(thread->readMicroPC());
+ } else {
+ curStaticInst = instPtr;
+ }
+ } else {
+ //Read the next micro op from the macro op
+ curStaticInst = curMacroStaticInst->
+ fetchMicroOp(thread->readMicroPC());
+ }
- traceData = Trace::getInstRecord(curTick, tc, this, curStaticInst,
+
+ traceData = Trace::getInstRecord(curTick, tc, curStaticInst,
thread->readPC());
DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n",
{
#if FULL_SYSTEM
if (thread->profile) {
- bool usermode =
- (thread->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
+ bool usermode = TheISA::inUserMode(tc);
thread->profilePC = usermode ? 1 : thread->readPC();
ProfileNode *node = thread->profile->consume(tc, inst);
if (node)
BaseSimpleCPU::advancePC(Fault fault)
{
if (fault != NoFault) {
+ curMacroStaticInst = StaticInst::nullStaticInstPtr;
fault->invoke(tc);
- }
- else {
- // go to the next instruction
- thread->setPC(thread->readNextPC());
-#if THE_ISA == ALPHA_ISA
- thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
+ } else {
+ //If we're at the last micro op for this instruction
+ if (curStaticInst->isLastMicroOp()) {
+ //We should be working with a macro op
+ assert(curMacroStaticInst);
+ //Close out this macro op, and clean up the
+ //microcode state
+ curMacroStaticInst = StaticInst::nullStaticInstPtr;
+ thread->setMicroPC(0);
+ thread->setNextMicroPC(1);
+ }
+ //If we're still in a macro op
+ if (curMacroStaticInst) {
+ //Advance the micro pc
+ thread->setMicroPC(thread->readNextMicroPC());
+ //Advance the "next" micro pc. Note that there are no delay
+ //slots, and micro ops are "word" addressed.
+ thread->setNextMicroPC(thread->readNextMicroPC() + 1);
+ } else {
+ // go to the next instruction
+ thread->setPC(thread->readNextPC());
+#if ISA_HAS_DELAY_SLOT
+ thread->setNextPC(thread->readNextNPC());
+ thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
+ assert(thread->readNextPC() != thread->readNextNPC());
#else
- thread->setNextPC(thread->readNextNPC());
- thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
- assert(thread->readNextPC() != thread->readNextNPC());
+ thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
#endif
-
+ }
}
#if FULL_SYSTEM