Updates to support new interrupt processing and removal of PcPAL.
authorKevin Lim <ktlim@umich.edu>
Mon, 13 Nov 2006 01:15:30 +0000 (20:15 -0500)
committerKevin Lim <ktlim@umich.edu>
Mon, 13 Nov 2006 01:15:30 +0000 (20:15 -0500)
src/arch/alpha/interrupts.hh:
    No need for this now that the ThreadContext is being used to set these IPRs in interrupts.
    Also split up the interrupt checking from the updating of the IPL and interrupt summary.
src/arch/alpha/tlb.cc:
    Check the PC for whether or not it's in PAL mode, not the addr.
src/cpu/o3/alpha/cpu.hh:
    Split up getting the interrupt from actually processing the interrupt.
src/cpu/o3/alpha/cpu_impl.hh:
    Splut up the processing of interrupts.
src/cpu/o3/commit_impl.hh:
    Update for ISA-oriented interrupt changes.
src/cpu/o3/fetch_impl.hh:
    Fix broken if statement from PcPAL updates, and properly populate the request fields.

    Also more debugging output.
src/cpu/ozone/cpu_impl.hh:
    Updates for ISA-oriented interrupt stuff.
src/cpu/ozone/front_end_impl.hh:
    Populate request fields properly.
src/cpu/simple/base.cc:
    Update for interrupt stuff.

--HG--
extra : convert_revision : 9bac3f9ffed4948ee788699b2fa8419bc1ca647c

src/arch/alpha/interrupts.hh
src/arch/alpha/tlb.cc
src/cpu/o3/alpha/cpu.hh
src/cpu/o3/alpha/cpu_impl.hh
src/cpu/o3/commit_impl.hh
src/cpu/o3/fetch_impl.hh
src/cpu/ozone/cpu_impl.hh
src/cpu/ozone/front_end_impl.hh
src/cpu/simple/base.cc

index 75031ae47cf695d9b755ecc7f503ce096193e328..a86fb2d7b39ba5ddc9be7a8d542d8140fddcb555 100644 (file)
@@ -49,6 +49,7 @@ namespace AlphaISA
         {
             memset(interrupts, 0, sizeof(interrupts));
             intstatus = 0;
+            newInfoSet = false;
         }
 
         void post(int int_num, int index)
@@ -137,18 +138,10 @@ namespace AlphaISA
             }
 
             if (ipl && ipl > tc->readMiscReg(IPR_IPLR)) {
-                tc->setMiscReg(IPR_ISR, summary);
-                tc->setMiscReg(IPR_INTID, ipl);
-
-        /* The following needs to be added back in somehow */
-        // Checker needs to know these two registers were updated.
-/*#if USE_CHECKER
-        if (this->checker) {
-            this->checker->threadBase()->setMiscReg(IPR_ISR, summary);
-            this->checker->threadBase()->setMiscReg(IPR_INTID, ipl);
-        }
-#endif*/
-
+//                assert(!newInfoSet);
+                newIpl = ipl;
+                newSummary = newSummary;
+                newInfoSet = true;
                 DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
                         tc->readMiscReg(IPR_IPLR), ipl, summary);
 
@@ -158,7 +151,18 @@ namespace AlphaISA
             }
         }
 
+        void updateIntrInfo(ThreadContext *tc)
+        {
+            assert(newInfoSet);
+            tc->setMiscReg(IPR_ISR, newSummary);
+            tc->setMiscReg(IPR_INTID, newIpl);
+            newInfoSet = false;
+        }
+
       private:
+        bool newInfoSet;
+        int newIpl;
+        int newSummary;
     };
 }
 
index ae302e6867fa4ad1fc4bf3454a8f878e61f9620a..af69e45c0744cd07a1f11b99c3a15931ea327473 100644 (file)
@@ -292,7 +292,7 @@ namespace AlphaISA
     Fault
     ITB::translate(RequestPtr &req, ThreadContext *tc) const
     {
-        if (PcPAL(req->getVaddr())) {
+        if (PcPAL(req->getPC())) {
             // strip off PAL PC marker (lsb is 1)
             req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask);
             hits++;
index b62550062c6389065cec318b8430b65092a4defd..0078db69fc588e01bc7144170e086fb06f20cd96 100644 (file)
@@ -156,8 +156,11 @@ class AlphaO3CPU : public FullO3CPU<Impl>
 
     bool simPalCheck(int palFunc, unsigned tid);
 
-    /** Processes any interrupts. */
-    void processInterrupts();
+    /** Returns the Fault for any valid interrupt. */
+    Fault getInterrupts();
+
+    /** Processes any an interrupt fault. */
+    void processInterrupts(Fault interrupt);
 
     /** Halts the CPU. */
     void halt() { panic("Halt not implemented!\n"); }
index 04eadfa5ad142d2028a1042e1ba42ade27e8a394..f5c39482678c4cb822ab03b1b7a09e549b9a58c6 100644 (file)
@@ -266,9 +266,17 @@ AlphaO3CPU<Impl>::simPalCheck(int palFunc, unsigned tid)
     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
@@ -276,14 +284,12 @@ AlphaO3CPU<Impl>::processInterrupts()
     // @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
index 30052a1483504d05f2cfff655836f846d6491c0a..d8e079a7e6b5272c1f539f8cf134a5095d8a0b13 100644 (file)
@@ -640,8 +640,18 @@ DefaultCommit<Impl>::commit()
     // @todo: Allow other threads to handle interrupts.
     if (cpu->checkInterrupts &&
         cpu->check_interrupts(cpu->tcBase(0)) &&
+        commitStatus[0] != TrapPending &&
         !trapSquash[0] &&
         !tcSquash[0]) {
+
+        // Get any interrupt that happened
+        Fault intr = cpu->getInterrupts();
+
+        // Exit this if block if there's no fault.
+        if (intr == NoFault) {
+            goto commit_insts;
+        }
+
         // Tell fetch that there is an interrupt pending.  This will
         // make fetch wait until it sees a non PAL-mode PC, at which
         // point it stops fetching instructions.
@@ -650,26 +660,24 @@ DefaultCommit<Impl>::commit()
         // Wait until the ROB is empty and all stores have drained in
         // order to enter the interrupt.
         if (rob->isEmpty() && !iewStage->hasStoresToWB()) {
-            // Not sure which thread should be the one to interrupt.  For now
-            // always do thread 0.
+            // Squash or record that I need to squash this cycle if
+            // an interrupt needed to be handled.
+            DPRINTF(Commit, "Interrupt detected.\n");
+
             assert(!thread[0]->inSyscall);
             thread[0]->inSyscall = true;
 
-            // CPU will handle implementation of the interrupt.
-            cpu->processInterrupts();
+            // CPU will handle interrupt.
+            cpu->processInterrupts(intr);
 
-            // Now squash or record that I need to squash this cycle.
-            commitStatus[0] = TrapPending;
-
-            // Exit state update mode to avoid accidental updating.
             thread[0]->inSyscall = false;
 
+            commitStatus[0] = TrapPending;
+
             // Generate trap squash event.
             generateTrapEvent(0);
 
             toIEW->commitInfo[0].clearInterrupt = true;
-
-            DPRINTF(Commit, "Interrupt detected.\n");
         } else {
             DPRINTF(Commit, "Interrupt pending, waiting for ROB to empty.\n");
         }
@@ -679,7 +687,7 @@ DefaultCommit<Impl>::commit()
     ////////////////////////////////////
     // Check for any possible squashes, handle them first
     ////////////////////////////////////
-
+  commit_insts:
     std::list<unsigned>::iterator threads = (*activeThreads).begin();
 
     while (threads != (*activeThreads).end()) {
index 5ef6e27ea3f6f8a955fc69e6589d7c5cb515edf9..b1fae8cf058137baff742c41aab303db88c94d9f 100644 (file)
@@ -559,27 +559,36 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
     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;
@@ -609,7 +618,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
                                         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");
@@ -1050,12 +1059,16 @@ DefaultFetch<Impl>::fetch(bool &status_change)
     } 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
index 86c973a0f0b21ef68135d45902495b65c77a62fa..accc8d29419c09d0f8fb420a7b2c7d0624cfb9ad 100644 (file)
@@ -700,52 +700,12 @@ OzoneCPU<Impl>::processInterrupts()
 
     // Check if there are any outstanding interrupts
     //Handle the interrupts
-    int ipl = 0;
-    int summary = 0;
+    Fault interrupt = this->interrupts.getInterrupt(thread.getTC());
 
-    checkInterrupts = false;
-
-    if (thread.readMiscReg(IPR_ASTRR))
-        panic("asynchronous traps not implemented\n");
-
-    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 the 21164 hardware reference
-                ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
-                summary |= (ULL(1) << i);
-            }
-        }
-    }
-
-    uint64_t interrupts = intr_status();
-
-    if (interrupts) {
-        for (int i = INTLEVEL_EXTERNAL_MIN;
-             i < INTLEVEL_EXTERNAL_MAX; i++) {
-            if (interrupts & (ULL(1) << i)) {
-                // See table 4-19 of the 21164 hardware reference
-                ipl = i;
-                summary |= (ULL(1) << i);
-            }
-        }
-    }
-
-    if (ipl && ipl > thread.readMiscReg(IPR_IPLR)) {
-        thread.setMiscReg(IPR_ISR, summary);
-        thread.setMiscReg(IPR_INTID, ipl);
-#if USE_CHECKER
-        // @todo: Make this more transparent
-        if (checker) {
-            checker->threadBase()->setMiscReg(IPR_ISR, summary);
-            checker->threadBase()->setMiscReg(IPR_INTID, ipl);
-        }
-#endif
-        Fault fault = new InterruptFault;
-        fault->invoke(thread.getTC());
-        DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
-                thread.readMiscReg(IPR_IPLR), ipl, summary);
+    if (interrupt != NoFault) {
+        this->interrupts.updateIntrInfo(thread.getTC());
+        this->checkInterrupts = false;
+        interrupt->invoke(thread.getTC());
     }
 }
 
index 73ca6afbe4fe83ea03b897a4c7751470876dfee9..198ce0308e7afb12637ac493f5d962cbf9aa6f2d 100644 (file)
@@ -476,8 +476,8 @@ FrontEnd<Impl>::fetchCacheLine()
 
     // Setup the memReq to do a read of the first isntruction's address.
     // Set the appropriate read size and flags as well.
-    memReq = new Request(0, fetch_PC, cacheBlkSize, flags,
-                         fetch_PC, cpu->readCpuId(), 0);
+    memReq = new Request(0, fetch_PC, cacheBlkSize, 0,
+                         PC, cpu->readCpuId(), 0);
 
     // Translate the instruction request.
     fault = cpu->translateInstReq(memReq, thread);
index ab438aa770a712a8681583bfa8c53dfc476f549d..4e5754bbb97b266e2c8e2703ffb492b0d4caf060 100644 (file)
@@ -315,6 +315,7 @@ BaseSimpleCPU::checkForInterrupts()
         Fault interrupt = interrupts.getInterrupt(tc);
 
         if (interrupt != NoFault) {
+            interrupts.updateIntrInfo(tc);
             checkInterrupts = false;
             interrupt->invoke(tc);
         }