Yet another merge with the main repository.
[gem5.git] / src / cpu / inorder / resources / cache_unit.hh
index 69c1dbd9e8afe8316fefb1379416a47c3f0696e3..2155c920c7fe314690e5f9f63b4bec607f610fec 100644 (file)
 #ifndef __CPU_INORDER_CACHE_UNIT_HH__
 #define __CPU_INORDER_CACHE_UNIT_HH__
 
-#include <vector>
 #include <list>
 #include <string>
+#include <vector>
 
 #include "arch/predecoder.hh"
 #include "arch/tlb.hh"
+#include "base/hashmap.hh"
 #include "config/the_isa.hh"
 #include "cpu/inorder/inorder_dyn_inst.hh"
 #include "cpu/inorder/pipeline_traits.hh"
@@ -92,25 +93,17 @@ class CacheUnit : public Resource
             cachePortUnit(_cachePortUnit)
         { }
 
-        bool snoopRangeSent;
-
       protected:
         /** Atomic version of receive.  Panics. */
         Tick recvAtomic(PacketPtr pkt);
 
-        /** Functional version of receive.  Panics. */
+        /** Functional version of receive.*/
         void recvFunctional(PacketPtr pkt);
 
-        /** Receives status change.  Other than range changing, panics. */
-        void recvStatusChange(Status status);
+        /** Receives range changes. */
+        void recvRangeChange();
 
-        /** Returns the address ranges of this device. */
-        void getDeviceAddressRanges(AddrRangeList &resp,
-                                            AddrRangeList &snoop)
-        { resp.clear(); snoop.clear(); }
-
-        /** Timing version of receive. Handles setting fetch to the
-         * proper status to start fetching. */
+        /** Timing version of receive */
         bool recvTiming(PacketPtr pkt);
 
         /** Handles doing a retry of a failed fetch. */
@@ -124,7 +117,7 @@ class CacheUnit : public Resource
                                 unsigned cmd);
 
     ResReqPtr findRequest(DynInstPtr inst);
-    ResReqPtr findSplitRequest(DynInstPtr inst, int idx);
+    ResReqPtr findRequest(DynInstPtr inst, int idx);
 
     void requestAgain(DynInstPtr inst, bool &try_request);
 
@@ -139,10 +132,24 @@ class CacheUnit : public Resource
     void squashDueToMemStall(DynInstPtr inst, int stage_num,
                              InstSeqNum squash_seq_num, ThreadID tid);
 
+    virtual void squashCacheRequest(CacheReqPtr req_ptr);
+
     /** After memory request is completedd in the cache, then do final
         processing to complete the request in the CPU.
     */
-   virtual void processCacheCompletion(PacketPtr pkt);
+    virtual void processCacheCompletion(PacketPtr pkt);
+
+    /** Create request that will interface w/TLB and Memory objects */
+    virtual void setupMemRequest(DynInstPtr inst, CacheReqPtr cache_req,
+                                 int acc_size, int flags);
+
+    void finishCacheUnitReq(DynInstPtr inst, CacheRequest *cache_req);
+
+    void buildDataPacket(CacheRequest *cache_req);
+
+    bool processSquash(CacheReqPacket *cache_pkt);
+
+    void trap(Fault fault, ThreadID tid, DynInstPtr inst);
 
     void recvRetry();
 
@@ -155,19 +162,19 @@ class CacheUnit : public Resource
     Fault write(DynInstPtr inst, uint8_t *data, unsigned size,
                 Addr addr, unsigned flags, uint64_t *res);
 
-    Fault doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
+    void doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
                       int flags,  TheISA::TLB::Mode tlb_mode);
 
     /** Read/Write on behalf of an instruction.
      *  curResSlot needs to be a valid value in instruction.
      */
-    Fault doCacheAccess(DynInstPtr inst, uint64_t *write_result=NULL,
+    void doCacheAccess(DynInstPtr inst, uint64_t *write_result=NULL,
                         CacheReqPtr split_req=NULL);
 
     uint64_t getMemData(Packet *packet);
 
     void setAddrDependency(DynInstPtr inst);
-    void removeAddrDependency(DynInstPtr inst);
+    virtual void removeAddrDependency(DynInstPtr inst);
     
   protected:
     /** Cache interface. */
@@ -175,9 +182,9 @@ class CacheUnit : public Resource
 
     bool cachePortBlocked;
 
-    std::vector<Addr> addrList[ThePipeline::MaxThreads];
+    std::list<Addr> addrList[ThePipeline::MaxThreads];
 
-    std::map<Addr, InstSeqNum> addrMap[ThePipeline::MaxThreads];
+    m5::hash_map<Addr, InstSeqNum> addrMap[ThePipeline::MaxThreads];
 
   public:
     int cacheBlkSize;
@@ -190,12 +197,10 @@ class CacheUnit : public Resource
         return (addr & ~(cacheBlkMask));
     }
 
-    TheISA::Predecoder predecoder;
-
     bool tlbBlocked[ThePipeline::MaxThreads];
+    InstSeqNum tlbBlockSeqNum[ThePipeline::MaxThreads];
 
     TheISA::TLB* tlb();
-
     TheISA::TLB *_tlb;
 };
 
@@ -215,27 +220,35 @@ class CacheUnitEvent : public ResourceEvent {
     void process();
 };
 
+//@todo: Move into CacheUnit Class for private access to "valid" field
 class CacheRequest : public ResourceRequest
 {
   public:
-    CacheRequest(CacheUnit *cres, DynInstPtr inst, int stage_num, int res_idx,
-                 int slot_num, unsigned cmd, int req_size,
-                 MemCmd::Command pkt_cmd, unsigned flags, int cpu_id, int idx)
-        : ResourceRequest(cres, inst, stage_num, res_idx, slot_num, cmd),
-          pktCmd(pkt_cmd), memReq(NULL), reqData(NULL), dataPkt(NULL),
-          retryPkt(NULL), memAccComplete(false), memAccPending(false),
-          tlbStall(false), splitAccess(false), splitAccessNum(-1),
-          split2ndAccess(false), instIdx(idx)
+    CacheRequest(CacheUnit *cres)
+        :  ResourceRequest(cres), memReq(NULL), reqData(NULL),
+           dataPkt(NULL), memAccComplete(false),
+           memAccPending(false), tlbStall(false), splitAccess(false),
+           splitAccessNum(-1), split2ndAccess(false),
+           fetchBufferFill(false)
     { }
 
-
     virtual ~CacheRequest()
     {
-        if (reqData && !splitAccess) {
+        if (reqData && !splitAccess)
             delete [] reqData;
-        }
     }
 
+    void setRequest(DynInstPtr _inst, int stage_num, int res_idx, int slot_num,
+                    unsigned _cmd, MemCmd::Command pkt_cmd, int idx)
+    {
+        pktCmd = pkt_cmd;
+        instIdx = idx;
+
+        ResourceRequest::setRequest(_inst, stage_num, res_idx, slot_num, _cmd);
+    }
+
+    void clearRequest();
+
     virtual PacketDataPtr getData()
     { return reqData; }
 
@@ -259,8 +272,7 @@ class CacheRequest : public ResourceRequest
     MemCmd::Command pktCmd;
     RequestPtr memReq;
     PacketDataPtr reqData;
-    PacketPtr dataPkt;
-    PacketPtr retryPkt;
+    CacheReqPacket *dataPkt;
 
     bool memAccComplete;
     bool memAccPending;
@@ -270,7 +282,9 @@ class CacheRequest : public ResourceRequest
     int splitAccessNum;
     bool split2ndAccess;
     int instIdx;    
-    
+
+    /** Should we expect block from cache access or fetch buffer? */
+    bool fetchBufferFill;
 };
 
 class CacheReqPacket : public Packet
@@ -278,14 +292,17 @@ class CacheReqPacket : public Packet
   public:
     CacheReqPacket(CacheRequest *_req,
                    Command _cmd, short _dest, int _idx = 0)
-        : Packet(_req->memReq, _cmd, _dest), cacheReq(_req), instIdx(_idx)
+        : Packet(&(*_req->memReq), _cmd, _dest), cacheReq(_req),
+          instIdx(_idx), hasSlot(false), reqData(NULL), memReq(NULL)
     {
 
     }
 
     CacheRequest *cacheReq;
     int instIdx;
-    
+    bool hasSlot;
+    PacketDataPtr reqData;
+    RequestPtr memReq;
 };
 
 #endif //__CPU_CACHE_UNIT_HH__