changeset 489489c67fd9 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=489489c67fd9
description:
        CPU: Moving towards a more general port across CPU models

        This patch performs minimal changes to move the instruction and data
        ports from specialised subclasses to the base CPU (to the largest
        degree possible). Ultimately it servers to make the CPU(s) have a
        well-defined interface to the memory sub-system.

diffstat:

 src/cpu/BaseCPU.py                |    7 +-
 src/cpu/base.cc                   |   62 ++++++++++++++++++
 src/cpu/base.hh                   |   63 ++++++++++++++++++
 src/cpu/inorder/InOrderCPU.py     |    3 -
 src/cpu/o3/O3CPU.py               |    3 -
 src/cpu/o3/cpu.cc                 |   65 ++++++++++++++++++-
 src/cpu/o3/cpu.hh                 |   87 +++++++++++++++++++++++++-
 src/cpu/o3/fetch.hh               |   56 +---------------
 src/cpu/o3/fetch_impl.hh          |   87 ++----------------------
 src/cpu/o3/iew.hh                 |    3 -
 src/cpu/o3/lsq.hh                 |   76 +++++++---------------
 src/cpu/o3/lsq_impl.hh            |  129 ++++++++++++++++---------------------
 src/cpu/simple/AtomicSimpleCPU.py |    4 -
 src/cpu/simple/TimingSimpleCPU.py |    3 -
 src/cpu/simple/atomic.cc          |   45 -------------
 src/cpu/simple/atomic.hh          |   37 ++++------
 src/cpu/simple/timing.cc          |   38 +----------
 src/cpu/simple/timing.hh          |   43 +++++-------
 18 files changed, 409 insertions(+), 402 deletions(-)

diffs (truncated from 1233 to 300 lines):

diff -r b1838faf3bcc -r 489489c67fd9 src/cpu/BaseCPU.py
--- a/src/cpu/BaseCPU.py        Tue Jan 17 12:55:08 2012 -0600
+++ b/src/cpu/BaseCPU.py        Tue Jan 17 12:55:08 2012 -0600
@@ -152,9 +152,12 @@
 
     tracer = Param.InstTracer(default_tracer, "Instruction tracer")
 
-    _cached_ports = []
+    icache_port = Port("Instruction Port")
+    dcache_port = Port("Data Port")
+    _cached_ports = ['icache_port', 'dcache_port']
+
     if buildEnv['TARGET_ISA'] in ['x86', 'arm'] and buildEnv['FULL_SYSTEM']:
-        _cached_ports = ["itb.walker.port", "dtb.walker.port"]
+        _cached_ports += ["itb.walker.port", "dtb.walker.port"]
 
     _uncached_ports = []
     if buildEnv['TARGET_ISA'] == 'x86' and buildEnv['FULL_SYSTEM']:
diff -r b1838faf3bcc -r 489489c67fd9 src/cpu/base.cc
--- a/src/cpu/base.cc   Tue Jan 17 12:55:08 2012 -0600
+++ b/src/cpu/base.cc   Tue Jan 17 12:55:08 2012 -0600
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2002-2005 The Regents of The University of Michigan
  * Copyright (c) 2011 Regents of the University of California
  * All rights reserved.
@@ -485,3 +497,53 @@
         functionEntryTick = curTick();
     }
 }
+
+bool
+BaseCPU::CpuPort::recvTiming(PacketPtr pkt)
+{
+    panic("BaseCPU doesn't expect recvTiming callback!");
+    return true;
+}
+
+void
+BaseCPU::CpuPort::recvRetry()
+{
+    panic("BaseCPU doesn't expect recvRetry callback!");
+}
+
+Tick
+BaseCPU::CpuPort::recvAtomic(PacketPtr pkt)
+{
+    panic("BaseCPU doesn't expect recvAtomic callback!");
+    return curTick();
+}
+
+void
+BaseCPU::CpuPort::recvFunctional(PacketPtr pkt)
+{
+    // No internal storage to update (in the general case). In the
+    // long term this should never be called, but that assumed a split
+    // into master/slave and request/response.
+}
+
+void
+BaseCPU::CpuPort::recvStatusChange(Status status)
+{
+    if (status == RangeChange) {
+        if (!snoopRangeSent) {
+            snoopRangeSent = true;
+            sendStatusChange(Port::RangeChange);
+        }
+        return;
+    }
+
+    panic("BaseCPU doesn't expect recvStatusChange callback!");
+}
+
+void
+BaseCPU::CpuPort::getDeviceAddressRanges(AddrRangeList& resp,
+                                         bool& snoop)
+{
+    resp.clear();
+    snoop = false;
+}
diff -r b1838faf3bcc -r 489489c67fd9 src/cpu/base.hh
--- a/src/cpu/base.hh   Tue Jan 17 12:55:08 2012 -0600
+++ b/src/cpu/base.hh   Tue Jan 17 12:55:08 2012 -0600
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2002-2005 The Regents of The University of Michigan
  * Copyright (c) 2011 Regents of the University of California
  * All rights reserved.
@@ -95,6 +107,57 @@
     // therefore no setCpuId() method is provided
     int _cpuId;
 
+    /**
+     * Define a base class for the CPU ports (instruction and data)
+     * that is refined in the subclasses. This class handles the
+     * common cases, i.e. the functional accesses and the status
+     * changes and address range queries. The default behaviour for
+     * both atomic and timing access is to panic and the corresponding
+     * subclasses have to override these methods.
+     */
+    class CpuPort : public Port
+    {
+      public:
+
+        /**
+         * Create a CPU port with a name and a structural owner.
+         *
+         * @param _name port name including the owner
+         * @param _name structural owner of this port
+         */
+        CpuPort(const std::string& _name, MemObject* _owner) :
+            Port(_name, _owner), snoopRangeSent(false)
+        { }
+
+      protected:
+
+        virtual bool recvTiming(PacketPtr pkt);
+
+        virtual Tick recvAtomic(PacketPtr pkt);
+
+        virtual void recvRetry();
+
+        void recvFunctional(PacketPtr pkt);
+
+        void recvStatusChange(Status status);
+
+        /**
+         * Add CPU ports are master ports and do not respond to any
+         * address ranges. Note that the LSQ snoops for specific ISAs
+         * and thus has to override this method.
+         *
+         * @param resp list of ranges this port responds to
+         * @param snoop indicating if the port snoops or not
+         */
+        virtual void getDeviceAddressRanges(AddrRangeList& resp,
+                                            bool& snoop);
+
+      private:
+
+        bool snoopRangeSent;
+
+    };
+
   public:
     /** Reads this CPU's ID. */
     int cpuId() { return _cpuId; }
diff -r b1838faf3bcc -r 489489c67fd9 src/cpu/inorder/InOrderCPU.py
--- a/src/cpu/inorder/InOrderCPU.py     Tue Jan 17 12:55:08 2012 -0600
+++ b/src/cpu/inorder/InOrderCPU.py     Tue Jan 17 12:55:08 2012 -0600
@@ -44,9 +44,6 @@
 
     fetchMemPort = Param.String("icache_port" , "Name of Memory Port to get 
instructions from")
     dataMemPort = Param.String("dcache_port" , "Name of Memory Port to get 
data from")
-    icache_port = Port("Instruction Port")
-    dcache_port = Port("Data Port")
-    _cached_ports = ['icache_port', 'dcache_port']
 
     fetchBuffSize = Param.Unsigned(4, "Fetch Buffer Size (Number of Cache 
Blocks Stored)")
     memBlockSize = Param.Unsigned(64, "Memory Block Size")
diff -r b1838faf3bcc -r 489489c67fd9 src/cpu/o3/O3CPU.py
--- a/src/cpu/o3/O3CPU.py       Tue Jan 17 12:55:08 2012 -0600
+++ b/src/cpu/o3/O3CPU.py       Tue Jan 17 12:55:08 2012 -0600
@@ -53,9 +53,6 @@
         checker.dtb = Parent.dtb
 
     cachePorts = Param.Unsigned(200, "Cache Ports")
-    icache_port = Port("Instruction Port")
-    dcache_port = Port("Data Port")
-    _cached_ports = BaseCPU._cached_ports + ['icache_port', 'dcache_port']
 
     decodeToFetchDelay = Param.Unsigned(1, "Decode to fetch delay")
     renameToFetchDelay = Param.Unsigned(1 ,"Rename to fetch delay")
diff -r b1838faf3bcc -r 489489c67fd9 src/cpu/o3/cpu.cc
--- a/src/cpu/o3/cpu.cc Tue Jan 17 12:55:08 2012 -0600
+++ b/src/cpu/o3/cpu.cc Tue Jan 17 12:55:08 2012 -0600
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2004-2006 The Regents of The University of Michigan
  * Copyright (c) 2011 Regents of the University of California
  * All rights reserved.
@@ -79,6 +91,42 @@
     BaseCPU::regStats();
 }
 
+template<class Impl>
+bool
+FullO3CPU<Impl>::IcachePort::recvTiming(PacketPtr pkt)
+{
+    DPRINTF(O3CPU, "Fetch unit received timing\n");
+    if (pkt->isResponse()) {
+        // We shouldn't ever get a block in ownership state
+        assert(!(pkt->memInhibitAsserted() && !pkt->sharedAsserted()));
+
+        fetch->processCacheCompletion(pkt);
+    }
+    //else Snooped a coherence request, just return
+    return true;
+}
+
+template<class Impl>
+void
+FullO3CPU<Impl>::IcachePort::recvRetry()
+{
+    fetch->recvRetry();
+}
+
+template <class Impl>
+bool
+FullO3CPU<Impl>::DcachePort::recvTiming(PacketPtr pkt)
+{
+    return lsq->recvTiming(pkt);
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::DcachePort::recvRetry()
+{
+    lsq->recvRetry();
+}
+
 template <class Impl>
 FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
     : Event(CPU_Tick_Pri), cpu(c)
@@ -194,6 +242,9 @@
                  TheISA::NumMiscRegs * numThreads,
                  TheISA::ZeroReg),
 
+      icachePort(&fetch, this),
+      dcachePort(&iew.ldstQueue, this),
+
       timeBuffer(params->backComSize, params->forwardComSize),
       fetchQueue(params->backComSize, params->forwardComSize),
       decodeQueue(params->backComSize, params->forwardComSize),
@@ -218,6 +269,7 @@
     if (params->checker) {
         BaseCPU *temp_checker = params->checker;
         checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
+        checker->setIcachePort(&icachePort);
 #if FULL_SYSTEM
         checker->setSystem(params->system);
 #endif
@@ -528,9 +580,9 @@
 FullO3CPU<Impl>::getPort(const std::string &if_name, int idx)
 {
     if (if_name == "dcache_port")
-        return iew.getDcachePort();
+        return &dcachePort;
     else if (if_name == "icache_port")
-        return fetch.getIcachePort();
+        return &icachePort;
     else
         panic("No Such Port\n");
 }
@@ -606,6 +658,13 @@
     for (ThreadID tid = 0; tid < numThreads; ++tid)
         thread[tid]->inSyscall = true;
 
+    // this CPU could still be unconnected if we are restoring from a
+    // checkpoint and this CPU is to be switched in, thus we can only
+    // do this here if the instruction port is actually connected, if
+    // not we have to do it as part of takeOverFrom
+    if (icachePort.isConnected())
+        fetch.setIcache();
+
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to