inorder-alpha-fs: edit inorder model to compile FS mode
authorKorey Sewell <ksewell@umich.edu>
Tue, 15 Sep 2009 05:44:48 +0000 (01:44 -0400)
committerKorey Sewell <ksewell@umich.edu>
Tue, 15 Sep 2009 05:44:48 +0000 (01:44 -0400)
src/cpu/inorder/SConscript
src/cpu/inorder/cpu.cc
src/cpu/inorder/cpu.hh
src/cpu/inorder/inorder_cpu_builder.cc
src/cpu/inorder/inorder_dyn_inst.cc
src/cpu/inorder/inorder_dyn_inst.hh
src/cpu/inorder/thread_context.cc
src/cpu/inorder/thread_context.hh
src/cpu/inorder/thread_state.cc [new file with mode: 0644]
src/cpu/inorder/thread_state.hh

index 64f1b54810cbac38ecd30f5b72b07751e94bb5ca..82a1028c25fa45196c998364d923a1c4b68e30cb 100644 (file)
@@ -79,6 +79,7 @@ if 'InOrderCPU' in env['CPU_MODELS']:
        Source('resources/mult_div_unit.cc')
        Source('resource_pool.cc')
        Source('reg_dep_map.cc')
+       Source('thread_state.cc')
        Source('thread_context.cc')
        Source('cpu.cc')
 
index a2367db6390f6b87fda1243db3b83d1b807b5e23..4107ac3b40aceb836df2f483ca3c077ff4d6b258 100644 (file)
 #include "sim/process.hh"
 #include "sim/stat_control.hh"
 
+#if FULL_SYSTEM
+#include "cpu/quiesce_event.hh"
+#include "sim/system.hh"
+#endif
+
+#if THE_ISA == ALPHA_ISA
+#include "arch/alpha/osfpal.hh"
+#endif
+
 using namespace std;
 using namespace TheISA;
 using namespace ThePipeline;
@@ -171,11 +180,16 @@ InOrderCPU::InOrderCPU(Params *params)
       timeBuffer(2 , 2),
       removeInstsThisCycle(false),
       activityRec(params->name, NumStages, 10, params->activity),
+#if FULL_SYSTEM
+      system(params->system),
+      physmem(system->physmem),
+#endif // FULL_SYSTEM
       switchCount(0),
       deferRegistration(false/*params->deferRegistration*/),
       stageTracing(params->stageTracing),
       numVirtProcs(1)
 {
+    ThreadID active_threads;
     cpu_params = params;
 
     resPool = new ResourcePool(this, params);
@@ -183,13 +197,17 @@ InOrderCPU::InOrderCPU(Params *params)
     // Resize for Multithreading CPUs
     thread.resize(numThreads);
 
-    ThreadID active_threads = params->workload.size();
+#if FULL_SYSTEM
+    active_threads = 1;
+#else
+    active_threads = params->workload.size();
 
     if (active_threads > MaxThreads) {
         panic("Workload Size too large. Increase the 'MaxThreads'"
               "in your InOrder implementation or "
               "edit your workload size.");
     }
+#endif
 
     // Bind the fetch & data ports from the resource pool.
     fetchPortIdx = resPool->getPortIdx(params->fetchMemPort);
@@ -203,6 +221,11 @@ InOrderCPU::InOrderCPU(Params *params)
     }
 
     for (ThreadID tid = 0; tid < numThreads; ++tid) {
+#if FULL_SYSTEM
+        // SMT is not supported in FS mode yet.
+        assert(this->numThreads == 1);
+        this->thread[tid] = new Thread(this, 0);
+#else
         if (tid < (ThreadID)params->workload.size()) {
             DPRINTF(InOrderCPU, "Workload[%i] process is %#x\n",
                     tid, this->thread[tid]);
@@ -214,6 +237,7 @@ InOrderCPU::InOrderCPU(Params *params)
             Process* dummy_proc = params->workload[0];
             this->thread[tid] = new Thread(this, tid, dummy_proc);
         }
+#endif
 
         // Setup the TC that will serve as the interface to the threads/CPU.
         InOrderThreadContext *tc = new InOrderThreadContext;
@@ -446,13 +470,6 @@ InOrderCPU::init()
     resPool->init();
 }
 
-void
-InOrderCPU::readFunctional(Addr addr, uint32_t &buffer)
-{
-    tcBase()->getMemPort()->readBlob(addr, (uint8_t*)&buffer, sizeof(uint32_t));
-    buffer = gtoh(buffer);
-}
-
 void
 InOrderCPU::reset()
 {
@@ -468,6 +485,61 @@ InOrderCPU::getPort(const std::string &if_name, int idx)
     return resPool->getPort(if_name, idx);
 }
 
+#if FULL_SYSTEM
+Fault
+InOrderCPU::hwrei(ThreadID tid)
+{
+    panic("hwrei: Unimplemented");
+    
+    return NoFault;
+}
+
+
+bool
+InOrderCPU::simPalCheck(int palFunc, ThreadID tid)
+{
+    panic("simPalCheck: Unimplemented");
+
+    return true;
+}
+
+
+Fault
+InOrderCPU::getInterrupts()
+{
+    // Check if there are any outstanding interrupts
+    return this->interrupts->getInterrupt(this->threadContexts[0]);
+}
+
+
+void
+InOrderCPU::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
+    // is the one that handles the interrupts.
+    // @todo: Possibly consolidate the interrupt checking code.
+    // @todo: Allow other threads to handle interrupts.
+
+    assert(interrupt != NoFault);
+    this->interrupts->updateIntrInfo(this->threadContexts[0]);
+
+    DPRINTF(InOrderCPU, "Interrupt %s being handled\n", interrupt->name());
+    this->trap(interrupt, 0);
+}
+
+
+void
+InOrderCPU::updateMemPorts()
+{
+    // Update all ThreadContext's memory ports (Functional/Virtual
+    // Ports)
+    ThreadID size = thread.size();
+    for (ThreadID i = 0; i < size; ++i)
+        thread[i]->connectMemPorts(thread[i]->getTC());
+}
+#endif
+
 void
 InOrderCPU::trap(Fault fault, ThreadID tid, int delay)
 {
@@ -1230,6 +1302,22 @@ InOrderCPU::wakeCPU()
     mainEventQueue.schedule(&tickEvent, curTick);
 }
 
+#if FULL_SYSTEM
+
+void
+InOrderCPU::wakeup()
+{
+    if (this->thread[0]->status() != ThreadContext::Suspended)
+        return;
+
+    this->wakeCPU();
+
+    DPRINTF(Quiesce, "Suspended Processor woken\n");
+    this->threadContexts[0]->activate();
+}
+#endif
+
+#if !FULL_SYSTEM
 void
 InOrderCPU::syscall(int64_t callnum, ThreadID tid)
 {
@@ -1251,6 +1339,7 @@ InOrderCPU::syscall(int64_t callnum, ThreadID tid)
     // Clear Non-Speculative Block Variable
     nonSpecInstActive[tid] = false;
 }
+#endif
 
 void
 InOrderCPU::prefetch(DynInstPtr inst)
index 75d77c81822fafe6430d63dd5493ea5e9687d4b2..9fb8e0df458e4d102781f56b9b591db4d3f77b17 100644 (file)
@@ -40,6 +40,7 @@
 
 #include "arch/isa_traits.hh"
 #include "arch/types.hh"
+#include "arch/registers.hh"
 #include "base/statistics.hh"
 #include "base/timebuf.hh"
 #include "base/types.hh"
@@ -297,6 +298,32 @@ class InOrderCPU : public BaseCPU
     /** Get a Memory Port */
     Port* getPort(const std::string &if_name, int idx = 0);
 
+#if FULL_SYSTEM
+    /** HW return from error interrupt. */
+    Fault hwrei(ThreadID tid);
+
+    bool simPalCheck(int palFunc, ThreadID tid);
+
+    /** 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"); }
+
+    /** Update the Virt and Phys ports of all ThreadContexts to
+     * reflect change in memory connections. */
+    void updateMemPorts();
+
+    /** Check if this address is a valid instruction address. */
+    bool validInstAddr(Addr addr) { return true; }
+
+    /** Check if this address is a valid data address. */
+    bool validDataAddr(Addr addr) { return true; }
+#endif
+
     /** trap() - sets up a trap event on the cpuTraps to handle given fault.
      *  trapCPU() - Traps to handle given fault
      */
@@ -578,8 +605,6 @@ class InOrderCPU : public BaseCPU
     ActivityRecorder activityRec;
 
   public:
-    void readFunctional(Addr addr, uint32_t &buffer);
-
     /** Number of Active Threads in the CPU */
     ThreadID numActiveThreads() { return activeThreads.size(); }
 
@@ -597,6 +622,10 @@ class InOrderCPU : public BaseCPU
     /** Wakes the CPU, rescheduling the CPU if it's not already active. */
     void wakeCPU();
 
+#if FULL_SYSTEM
+    virtual void wakeup();
+#endif
+
     /** Gets a free thread id. Use if thread ids change across system. */
     ThreadID getFreeTid();
 
@@ -622,6 +651,14 @@ class InOrderCPU : public BaseCPU
         return total;
     }
 
+#if FULL_SYSTEM
+    /** Pointer to the system. */
+    System *system;
+
+    /** Pointer to physical memory. */
+    PhysicalMemory *physmem;
+#endif
+
     /** The global sequence number counter. */
     InstSeqNum globalSeqNum[ThePipeline::MaxThreads];
 
index 5ee7b31dbd6069d4a32b1a5575d3877e44526b06..a19137dd8be2422734a69384ec077628a1b5cc44 100644 (file)
 InOrderCPU *
 InOrderCPUParams::create()
 {
+#if FULL_SYSTEM
+    // Full-system only supports a single thread for the moment.
+    ThreadID actual_num_threads = 1;
+#else
     ThreadID actual_num_threads =
         (numThreads >= workload.size()) ? numThreads : workload.size();
 
     if (workload.size() == 0) {
         fatal("Must specify at least one workload!");
     }
+#endif
 
     numThreads = actual_num_threads;
 
index a6abb28b21ad1b875e561a09a10005081ec823da..9f0927b2fbf4a0fd45ce51f33bca33f51056ea0f 100644 (file)
@@ -297,11 +297,39 @@ InOrderDynInst::memAccess()
     return initiateAcc();
 }
 
+
+#if FULL_SYSTEM
+
+Fault
+InOrderDynInst::hwrei()
+{
+    panic("InOrderDynInst: hwrei: unimplemented\n");    
+    return NoFault;
+}
+
+
+void
+InOrderDynInst::trap(Fault fault)
+{
+    this->cpu->trap(fault, this->threadNumber);
+}
+
+
+bool
+InOrderDynInst::simPalCheck(int palFunc)
+{
+#if THE_ISA != ALPHA_ISA
+    panic("simPalCheck called, but PAL only exists in Alpha!\n");
+#endif
+    return this->cpu->simPalCheck(palFunc, this->threadNumber);
+}
+#else
 void
 InOrderDynInst::syscall(int64_t callnum)
 {
     cpu->syscall(callnum, this->threadNumber);
 }
+#endif
 
 void
 InOrderDynInst::prefetch(Addr addr, unsigned flags)
index e95a6d03973ad1ec84b7594bf2dff886ad93ca17..a91c6a763ca1991d41c2e7e839f529cc58511ec6 100644 (file)
@@ -43,6 +43,7 @@
 #include "arch/mt.hh"
 #include "base/fast_alloc.hh"
 #include "base/trace.hh"
+#include "base/types.hh"
 #include "cpu/inorder/inorder_trace.hh"
 #include "config/full_system.hh"
 #include "cpu/thread_context.hh"
 #include "cpu/inorder/pipeline_traits.hh"
 #include "mem/packet.hh"
 #include "sim/system.hh"
+#include "sim/faults.hh"
+
+#if THE_ISA==ALPHA_ISA
+#include "arch/alpha/ev5.hh"
+#endif
 
 /**
  * @file
@@ -64,6 +70,7 @@
 // Forward declaration.
 class StaticInstPtr;
 class ResourceRequest;
+class Packet;
 
 class InOrderDynInst : public FastAlloc, public RefCounted
 {
@@ -486,7 +493,16 @@ class InOrderDynInst : public FastAlloc, public RefCounted
     void setCurResSlot(unsigned slot_num) { curResSlot = slot_num; }
 
     /** Calls a syscall. */
+#if FULL_SYSTEM
+    /** Calls hardware return from error interrupt. */
+    Fault hwrei();
+    /** Traps to handle specified fault. */
+    void trap(Fault fault);
+    bool simPalCheck(int palFunc);
+#else
+    /** Calls a syscall. */
     void syscall(int64_t callnum);
+#endif
     void prefetch(Addr addr, unsigned flags);
     void writeHint(Addr addr, int size, unsigned flags);
     Fault copySrcTranslate(Addr src);
index fe1a0faa1b52c4b55a31022c035e93555da58a1e..8247bf1fb57958a342d9ff560829d0dbeded1666 100644 (file)
 
 using namespace TheISA;
 
+#if FULL_SYSTEM
+
+VirtualPort *
+InOrderThreadContext::getVirtPort()
+{
+    return thread->getVirtPort();
+}
+
+
+void
+InOrderThreadContext::dumpFuncProfile()
+{
+    thread->dumpFuncProfile();
+}
+
+
+Tick
+InOrderThreadContext::readLastActivate()
+{
+    return thread->lastActivate;
+}
+
+
+Tick
+InOrderThreadContext::readLastSuspend()
+{
+    return thread->lastSuspend;
+}
+
+
+void
+InOrderThreadContext::profileClear()
+{
+    thread->profileClear();
+}
+
+
+void
+InOrderThreadContext::profileSample()
+{
+    thread->profileSample();
+}
+#endif
+
 void
 InOrderThreadContext::takeOverFrom(ThreadContext *old_context)
 {
     // some things should already be set up
+    assert(getSystemPtr() == old_context->getSystemPtr());
+#if !FULL_SYSTEM
     assert(getProcessPtr() == old_context->getProcessPtr());
+#endif
+
+
 
     // copy over functional state
     setStatus(old_context->status());
     copyArchRegs(old_context);
 
+#if !FULL_SYSTEM
     thread->funcExeInst = old_context->readFuncExeInst();
+#endif
     old_context->setStatus(ThreadContext::Halted);
+
     thread->inSyscall = false;
     thread->trapPending = false;
 }
@@ -97,8 +150,8 @@ void
 InOrderThreadContext::regStats(const std::string &name)
 {
 #if FULL_SYSTEM
-    thread->kernelStats = new Kernel::Statistics(cpu->system);
-    thread->kernelStats->regStats(name + ".kern");
+    //thread->kernelStats = new Kernel::Statistics(cpu->system);
+    //thread->kernelStats->regStats(name + ".kern");
 #endif
     ;
 }
@@ -107,22 +160,14 @@ InOrderThreadContext::regStats(const std::string &name)
 void
 InOrderThreadContext::serialize(std::ostream &os)
 {
-#if FULL_SYSTEM
-    if (thread->kernelStats)
-        thread->kernelStats->serialize(os);
-#endif
-    ;
+    panic("serialize unimplemented");
 }
 
 
 void
 InOrderThreadContext::unserialize(Checkpoint *cp, const std::string &section)
 {
-#if FULL_SYSTEM
-    if (thread->kernelStats)
-        thread->kernelStats->unserialize(cp, section);
-#endif
-    ;
+    panic("unserialize unimplemented");    
 }
 
 TheISA::MachInst
index 327f8ac7115380911268602c78c02fa6fb493d68..2489c525f1f233fdf2eb7fa9db007563f8c69f6a 100644 (file)
@@ -101,10 +101,48 @@ class InOrderThreadContext : public ThreadContext
 
     virtual void setNextMicroPC(uint64_t val) { };
 
+#if FULL_SYSTEM
+    /** Returns a pointer to physical memory. */
+    virtual PhysicalMemory *getPhysMemPtr() 
+    { assert(0); return 0; /*return cpu->physmem;*/ }
+
+    /** Returns a pointer to this thread's kernel statistics. */
+    virtual TheISA::Kernel::Statistics *getKernelStats()
+    { return thread->kernelStats; }
+
+    virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
+
+    virtual VirtualPort *getVirtPort();
+
+    virtual void connectMemPorts(ThreadContext *tc) { thread->connectMemPorts(tc); }
+
+    /** Dumps the function profiling information.
+     * @todo: Implement.
+     */
+    virtual void dumpFuncProfile();
+
+    /** Reads the last tick that this thread was activated on. */
+    virtual Tick readLastActivate();
+    /** Reads the last tick that this thread was suspended on. */
+    virtual Tick readLastSuspend();
+
+    /** Clears the function profiling information. */
+    virtual void profileClear();
+
+    /** Samples the function profiling information. */
+    virtual void profileSample();
+
+    /** Returns pointer to the quiesce event. */
+    virtual EndQuiesceEvent *getQuiesceEvent()
+    {
+        return this->thread->quiesceEvent;
+    }
+#else
     virtual TranslatingPort *getMemPort() { return thread->getMemPort(); }
 
     /** Returns a pointer to this thread's process. */
     virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
+#endif
 
     /** Returns this thread's status. */
     virtual Status status() const { return thread->status(); }
@@ -232,9 +270,11 @@ class InOrderThreadContext : public ThreadContext
      * misspeculating, this is set as false. */
     virtual bool misspeculating() { return false; }
 
+#if !FULL_SYSTEM
     /** Executes a syscall in SE mode. */
     virtual void syscall(int64_t callnum)
     { return cpu->syscall(callnum, thread->readTid()); }
+#endif
 
     /** Reads the funcExeInst counter. */
     virtual Counter readFuncExeInst() { return thread->funcExeInst; }
diff --git a/src/cpu/inorder/thread_state.cc b/src/cpu/inorder/thread_state.cc
new file mode 100644 (file)
index 0000000..b3a54ef
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007 MIPS Technologies, Inc.
+ * 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.
+ *
+ * Authors: Korey Sewell
+ *
+ */
+
+#include "arch/isa_traits.hh"
+#include "cpu/exetrace.hh"
+#include "cpu/inorder/thread_state.hh"
+#include "cpu/inorder/cpu.hh"
+
+using namespace TheISA;
+
+#if FULL_SYSTEM
+void 
+InOrderThreadState::dumpFuncProfile()    
+{
+    std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
+    profile->dump(tc, *os);
+}
+#endif
+
index 9b3b39fcb489294550fa0e6b25aa42bc7eef0ffa..0571b6e04e20df55a1f76b63b756f2b4b49665e3 100644 (file)
 
 #include "arch/faults.hh"
 #include "arch/isa_traits.hh"
+#include "base/callback.hh"
+#include "base/output.hh"
 #include "cpu/thread_context.hh"
 #include "cpu/thread_state.hh"
+#include "sim/sim_exit.hh"
 
 class Event;
+class InOrderCPU;
+
+#if FULL_SYSTEM
+class EndQuiesceEvent;
+class FunctionProfile;
+class ProfileNode;
+#else
 class FunctionalMemory;
 class Process;
-class InOrderCPU;
+#endif
 
 /**
  * Class that has various thread state, such as the status, the
@@ -66,16 +76,28 @@ class InOrderThreadState : public ThreadState {
      */
     bool trapPending;
 
-
+#if FULL_SYSTEM
+    InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num)
+        : ThreadState(reinterpret_cast<BaseCPU*>(_cpu), 0/*_thread_num*/),
+          cpu(_cpu), inSyscall(0), trapPending(0)
+    { }
+#else
     InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num,
                        Process *_process)
         : ThreadState(reinterpret_cast<BaseCPU*>(_cpu), 0/*_thread_num*/,
                       _process),
           cpu(_cpu), inSyscall(0), trapPending(0)
     { }
+#endif
 
+#if !FULL_SYSTEM
     /** Handles the syscall. */
     void syscall(int64_t callnum) { process->syscall(callnum, tc); }
+#endif
+
+#if FULL_SYSTEM
+    void dumpFuncProfile();    
+#endif
 
     /** Pointer to the ThreadContext of this thread. */
     ThreadContext *tc;