#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"
int res_latency, InOrderCPU *_cpu, ThePipeline::Params *params);
enum Command {
- InitiateFetch,
- CompleteFetch,
InitiateReadData,
CompleteReadData,
InitiateWriteData,
CompleteWriteData,
- Fetch,
- ReadData,
- WriteData,
InitSecondSplitRead,
InitSecondSplitWrite,
CompleteSecondSplitRead,
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);
-
- /** Returns the address ranges of this device. */
- void getDeviceAddressRanges(AddrRangeList &resp,
- AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); }
+ /** Receives range changes. */
+ void recvRangeChange();
- /** 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. */
void init();
ResourceRequest* getRequest(DynInstPtr _inst, int stage_num,
- int res_idx, int slot_num,
- unsigned cmd);
+ int res_idx, int slot_num,
+ 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);
- int getSlot(DynInstPtr inst);
+ 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 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);
- void prefetch(DynInstPtr inst);
-
- void writeHint(DynInstPtr inst);
-
uint64_t getMemData(Packet *packet);
void setAddrDependency(DynInstPtr inst);
- void removeAddrDependency(DynInstPtr inst);
+ virtual void removeAddrDependency(DynInstPtr inst);
protected:
/** Cache interface. */
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;
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;
};
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; }
+ { return reqData; }
void
setMemAccCompleted(bool completed = true)
MemCmd::Command pktCmd;
RequestPtr memReq;
PacketDataPtr reqData;
- PacketPtr dataPkt;
- PacketPtr retryPkt;
+ CacheReqPacket *dataPkt;
bool memAccComplete;
bool memAccPending;
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, 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__