Yet another merge with the main repository.
[gem5.git] / src / cpu / inorder / resources / cache_unit.hh
index 50cb475196abde7bca3dfe8357740dc2463e4cdd..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"
@@ -64,15 +65,14 @@ class CacheUnit : public Resource
               int res_latency, InOrderCPU *_cpu, ThePipeline::Params *params);
 
     enum Command {
-        InitiateFetch,
-        CompleteFetch,
         InitiateReadData,
         CompleteReadData,
         InitiateWriteData,
         CompleteWriteData,
-        Fetch,
-        ReadData,
-        WriteData
+        InitSecondSplitRead,
+        InitSecondSplitWrite,
+        CompleteSecondSplitRead,
+        CompleteSecondSplitWrite
     };
 
   public:
@@ -93,99 +93,98 @@ class CacheUnit : public Resource
             cachePortUnit(_cachePortUnit)
         { }
 
-        bool snoopRangeSent;
-
       protected:
         /** Atomic version of receive.  Panics. */
-        virtual Tick recvAtomic(PacketPtr pkt);
+        Tick recvAtomic(PacketPtr pkt);
 
-        /** Functional version of receive.  Panics. */
-        virtual void recvFunctional(PacketPtr pkt);
+        /** Functional version of receive.*/
+        void recvFunctional(PacketPtr pkt);
 
-        /** Receives status change.  Other than range changing, panics. */
-        virtual void recvStatusChange(Status status);
+        /** Receives range changes. */
+        void recvRangeChange();
 
-        /** Returns the address ranges of this device. */
-        virtual void getDeviceAddressRanges(AddrRangeList &resp,
-                                            AddrRangeList &snoop)
-        { resp.clear(); snoop.clear(); }
-
-        /** Timing version of receive. Handles setting fetch to the
-         * proper status to start fetching. */
-        virtual bool recvTiming(PacketPtr pkt);
+        /** Timing version of receive */
+        bool recvTiming(PacketPtr pkt);
 
         /** Handles doing a retry of a failed fetch. */
-        virtual void recvRetry();
+        void recvRetry();
     };
 
     void init();
 
-    virtual ResourceRequest* getRequest(DynInstPtr _inst, int stage_num,
-                                        int res_idx, int slot_num,
-                                        unsigned cmd);
+    ResourceRequest* getRequest(DynInstPtr _inst, int stage_num,
+                                int res_idx, int slot_num,
+                                unsigned cmd);
 
-    void requestAgain(DynInstPtr inst, bool &try_request);
+    ResReqPtr findRequest(DynInstPtr inst);
+    ResReqPtr findRequest(DynInstPtr inst, int idx);
 
-    int getSlot(DynInstPtr inst);
+    void requestAgain(DynInstPtr inst, bool &try_request);
 
-    void freeSlot(int slot_num);
+    virtual int getSlot(DynInstPtr inst);
 
-    /** Execute the function of this resource. The Default is action
-     *  is to do nothing. More specific models will derive from this
-     *  class and define their own execute function.
-     */
-    void execute(int slot_num);
+    /** Executes one of the commands from the "Command" enum */
+    virtual void execute(int slot_num);
 
-    void squash(DynInstPtr inst, int stage_num,
+    virtual void squash(DynInstPtr inst, int stage_num,
                 InstSeqNum squash_seq_num, ThreadID tid);
 
     void squashDueToMemStall(DynInstPtr inst, int stage_num,
                              InstSeqNum squash_seq_num, ThreadID tid);
 
-    /** Processes cache completion event. */
-    void processCacheCompletion(PacketPtr pkt);
+    virtual void squashCacheRequest(CacheReqPtr req_ptr);
 
-    void recvRetry();
+    /** After memory request is completedd in the cache, then do final
+        processing to complete the request in the CPU.
+    */
+    virtual void processCacheCompletion(PacketPtr pkt);
 
-    /** Align a PC to the start of an I-cache block. */
-    Addr cacheBlockAlignPC(Addr addr)
-    {
-        return (addr & ~(cacheBlkMask));
-    }
+    /** 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();
 
     /** Returns a specific port. */
     Port *getPort(const std::string &if_name, int idx);
+    
+    Fault read(DynInstPtr inst, Addr addr,
+               uint8_t *data, unsigned size, unsigned flags);
 
-    template <class T>
-    Fault read(DynInstPtr inst, Addr addr, T &data, unsigned flags);
-
-    template <class T>
-    Fault write(DynInstPtr inst, T data, Addr addr, unsigned flags,
-                        uint64_t *res);
+    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 prefetch(DynInstPtr inst);
-
-    void writeHint(DynInstPtr inst);
+    void doCacheAccess(DynInstPtr inst, uint64_t *write_result=NULL,
+                        CacheReqPtr split_req=NULL);
 
     uint64_t getMemData(Packet *packet);
 
+    void setAddrDependency(DynInstPtr inst);
+    virtual void removeAddrDependency(DynInstPtr inst);
+    
   protected:
     /** Cache interface. */
     CachePort *cachePort;
 
     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;
@@ -198,21 +197,10 @@ class CacheUnit : public Resource
         return (addr & ~(cacheBlkMask));
     }
 
-    /** The mem line being fetched. */
-    uint8_t *fetchData[ThePipeline::MaxThreads];
-
-    /** @TODO: Move functionaly of fetching more than
-        one instruction to 'fetch unit'*/
-    /** The Addr of the cacheline that has been loaded. */
-    //Addr cacheBlockAddr[ThePipeline::MaxThreads];
-    //unsigned fetchOffset[ThePipeline::MaxThreads];
-
-    TheISA::Predecoder predecoder;
-
     bool tlbBlocked[ThePipeline::MaxThreads];
+    InstSeqNum tlbBlockSeqNum[ThePipeline::MaxThreads];
 
     TheISA::TLB* tlb();
-
     TheISA::TLB *_tlb;
 };
 
@@ -229,31 +217,40 @@ class CacheUnitEvent : public ResourceEvent {
     virtual ~CacheUnitEvent() {}
 
     /** Processes a resource event. */
-    virtual void process();
+    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)
-        : 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)
+    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) {
+        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; }
+    { return reqData; }
 
     void
     setMemAccCompleted(bool completed = true)
@@ -261,6 +258,11 @@ class CacheRequest : public ResourceRequest
         memAccComplete = completed;
     }
 
+    bool is2ndSplit() 
+    {
+        return split2ndAccess;
+    }
+    
     bool isMemAccComplete() { return memAccComplete; }
 
     void setMemAccPending(bool pending = true) { memAccPending = pending; }
@@ -270,25 +272,37 @@ class CacheRequest : public ResourceRequest
     MemCmd::Command pktCmd;
     RequestPtr memReq;
     PacketDataPtr reqData;
-    PacketPtr dataPkt;
-    PacketPtr retryPkt;
+    CacheReqPacket *dataPkt;
 
     bool memAccComplete;
     bool memAccPending;
     bool tlbStall;
+
+    bool splitAccess;
+    int splitAccessNum;
+    bool split2ndAccess;
+    int instIdx;    
+
+    /** Should we expect block from cache access or fetch buffer? */
+    bool fetchBufferFill;
 };
 
 class CacheReqPacket : public Packet
 {
   public:
     CacheReqPacket(CacheRequest *_req,
-                   Command _cmd, short _dest)
-        : Packet(_req->memReq, _cmd, _dest), cacheReq(_req)
+                   Command _cmd, short _dest, int _idx = 0)
+        : 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__