X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcpu%2Finorder%2Fresource.hh;h=3c1a8cc470e802d2995af82e18e4c559a268056b;hb=b00949d88bb3185dfa2e27799de7f90e5a449be8;hp=605b7f690e994b3234f256066c8ff0484b3687fe;hpb=279f179babc9e5663156777c533c06edc91bce9a;p=gem5.git diff --git a/src/cpu/inorder/resource.hh b/src/cpu/inorder/resource.hh index 605b7f690..3c1a8cc47 100644 --- a/src/cpu/inorder/resource.hh +++ b/src/cpu/inorder/resource.hh @@ -32,14 +32,14 @@ #ifndef __CPU_INORDER_RESOURCE_HH__ #define __CPU_INORDER_RESOURCE_HH__ -#include #include #include +#include #include "base/types.hh" -#include "cpu/inst_seq.hh" #include "cpu/inorder/inorder_dyn_inst.hh" #include "cpu/inorder/pipeline_traits.hh" +#include "cpu/inst_seq.hh" #include "sim/eventq.hh" #include "sim/sim_object.hh" @@ -51,6 +51,9 @@ class ResourceRequest; typedef ResourceRequest ResReq; typedef ResourceRequest* ResReqPtr; +class CacheRequest; +typedef CacheRequest* CacheReqPtr; + class Resource { public: typedef ThePipeline::DynInstPtr DynInstPtr; @@ -67,11 +70,6 @@ class Resource { /** Return name of this resource */ virtual std::string name(); - /** Define this function if resource, has a port to connect to an outside - * simulation object. - */ - virtual Port* getPort(const std::string &if_name, int idx) { return NULL; } - /** Return ID for this resource */ int getId() { return id; } @@ -82,7 +80,7 @@ class Resource { virtual void initSlots(); /** Register Stats for this resource */ - virtual void regStats(); + virtual void regStats() { } /** Resources that care about thread activation override this. */ virtual void activateThread(ThreadID tid) { } @@ -92,11 +90,22 @@ class Resource { */ virtual void deactivateThread(ThreadID tid); + /** Resources that care about thread activation override this. */ + virtual void suspendThread(ThreadID tid) { } + + /** Will be called the cycle before a context switch. Any bookkeeping + * that needs to be kept for that, can be done here + */ + virtual void updateAfterContextSwitch(DynInstPtr inst, ThreadID tid) { } + /** Resources that care when an instruction has been graduated * can override this */ virtual void instGraduated(InstSeqNum seq_num, ThreadID tid) { } + /** Post-processsing for Trap Generated from this instruction */ + virtual void trap(Fault fault, ThreadID tid, DynInstPtr inst) { } + /** Request usage of this resource. Returns a ResourceRequest object * with all the necessary resource information */ @@ -114,16 +123,16 @@ class Resource { /** Free a resource slot */ virtual void freeSlot(int slot_idx); - /** Request usage of a resource for this instruction. If this instruction already - * has made this request to this resource, and that request is uncompleted - * this function will just return that request + /** Request usage of a resource for this instruction. If this instruction + * already has made this request to this resource, and that request is + * uncompleted this function will just return that request */ virtual ResourceRequest* getRequest(DynInstPtr _inst, int stage_num, int res_idx, int slot_num, unsigned cmd); /** Schedule Execution of This Resource For A Given Slot*/ - virtual void scheduleExecution(int slot_idx); + void scheduleExecution(int slot_idx); /** Execute the function of this resource. The Default is action * is to do nothing. More specific models will derive from this @@ -142,19 +151,24 @@ class Resource { * if instruction is actually in resource before * trying to do access.Needs to be defined for derived units. */ - virtual Fault doCacheAccess(DynInstPtr inst, uint64_t *res=NULL) - { panic("doCacheAccess undefined for %s", name()); return NoFault; } + virtual void doCacheAccess(DynInstPtr inst, uint64_t *write_result = NULL, + CacheReqPtr split_req = NULL) + { panic("doCacheAccess undefined for %s", name()); } - virtual void prefetch(DynInstPtr inst) - { panic("prefetch undefined for %s", name()); } - - virtual void writeHint(DynInstPtr inst) - { panic("writeHint undefined for %s", name()); } + /** Setup Squash to be sent out to pipeline and resource pool */ + void setupSquash(DynInstPtr inst, int stage_num, ThreadID tid); /** Squash All Requests After This Seq Num */ virtual void squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, ThreadID tid); + /** Squash Requests Due to a Memory Stall (By Default, same as "squash" */ + virtual void squashDueToMemStall(DynInstPtr inst, int stage_num, + InstSeqNum squash_seq_num, ThreadID tid); + + /** Handle Squash & Trap that occured from an instruction in a resource */ + void squashThenTrap(int stage_num, DynInstPtr inst); + /** The number of instructions available that this resource can * can still process */ @@ -166,7 +180,8 @@ class Resource { /** Schedule resource event, regardless of its current state. */ void scheduleEvent(int slot_idx, int delay); - /** Find instruction in list, Schedule resource event, regardless of its current state. */ + /** Find instruction in list, Schedule resource event, regardless of its + * current state. */ bool scheduleEvent(DynInstPtr inst, int delay); /** Unschedule resource event, regardless of its current state. */ @@ -182,7 +197,7 @@ class Resource { virtual ResReqPtr findRequest(DynInstPtr inst); /** */ - virtual void rejectRequest(DynInstPtr inst); + void rejectRequest(DynInstPtr inst); /** Request a Resource again. Some resources have to special process this * in subsequent accesses. @@ -214,8 +229,10 @@ class Resource { const int latency; public: - /** Mapping of slot-numbers to the resource-request pointers */ - std::map reqMap; + /** List of all Requests the Resource is Servicing. Each request + represents part of the resource's bandwidth + */ + std::vector reqs; /** A list of all the available execution slots for this resource. * This correlates with the actual resource event idx. @@ -233,21 +250,12 @@ class Resource { /** Default denied resource request pointer*/ ResReqPtr deniedReq; - - public: - ///////////////////////////////////////////////////////////////// - // - // DEFAULT RESOURCE STATISTICS - // - ///////////////////////////////////////////////////////////////// - /** Number of Instruction Requests the Resource Processes */ - Stats::Scalar instReqsProcessed; }; class ResourceEvent : public Event { public: - /** Pointer to the CPU. */ + /** Pointer to the Resource this is an event for */ Resource *resource; @@ -255,7 +263,7 @@ class ResourceEvent : public Event /// (for InOrderCPU model). /// check src/sim/eventq.hh for more event priorities. enum InOrderPriority { - Resource_Event_Pri = 45, + Resource_Event_Pri = 45 }; /** The Resource Slot that this event is servicing */ @@ -273,19 +281,13 @@ class ResourceEvent : public Event virtual void process(); /** Returns the description of the resource event. */ - const char *description(); + const char *description() const; /** Set slot idx for event */ void setSlot(int slot) { slotIdx = slot; } /** Schedule resource event, regardless of its current state. */ - void scheduleEvent(int delay) - { - if (squashed()) - mainEventQueue.reschedule(this, curTick + resource->ticks(delay)); - else if (!scheduled()) - mainEventQueue.schedule(this, curTick + resource->ticks(delay)); - } + void scheduleEvent(int delay); /** Unschedule resource event, regardless of its current state. */ void unscheduleEvent() @@ -303,36 +305,30 @@ class ResourceRequest static int resReqID; - static int resReqCount; + static int maxReqCount; + + friend class Resource; public: - ResourceRequest(Resource *_res, DynInstPtr _inst, int stage_num, - int res_idx, int slot_num, unsigned _cmd) - : res(_res), inst(_inst), cmd(_cmd), stageNum(stage_num), - resIdx(res_idx), slotNum(slot_num), completed(false), - squashed(false), processing(false), waiting(false) - { - reqID = resReqID++; - resReqCount++; - DPRINTF(ResReqCount, "Res. Req %i created. resReqCount=%i.\n", reqID, resReqCount); + ResourceRequest(Resource *_res); + + virtual ~ResourceRequest(); - if (resReqCount > 100) { - fatal("Too many undeleted resource requests. Memory leak?\n"); - } - } + std::string name(); + + int reqID; - virtual ~ResourceRequest() - { - resReqCount--; - DPRINTF(ResReqCount, "Res. Req %i deleted. resReqCount=%i.\n", reqID, resReqCount); - } + void setRequest(DynInstPtr _inst, int stage_num, + int res_idx, int slot_num, unsigned _cmd); - int reqID; + virtual void clearRequest(); /** Acknowledge that this is a request is done and remove * from resource. */ void done(bool completed = true); + + void freeSlot(); ///////////////////////////////////////////// // @@ -341,9 +337,10 @@ class ResourceRequest ///////////////////////////////////////////// /** Get Resource Index */ int getResIdx() { return resIdx; } - + /** Get Slot Number */ int getSlot() { return slotNum; } + bool hasSlot() { return slotNum >= 0; } /** Get Stage Number */ int getStageNum() { return stageNum; } @@ -366,12 +363,18 @@ class ResourceRequest /** Instruction being used */ DynInstPtr inst; - /** Fault Associated With This Resource Request */ - Fault fault; - + /** Not guaranteed to be set, used for debugging */ + InstSeqNum seqNum; + /** Command For This Resource */ unsigned cmd; + short stagePasses; + + bool valid; + + bool doneInResource; + //////////////////////////////////////// // // GET RESOURCE REQUEST STATUS FROM VARIABLES @@ -387,11 +390,11 @@ class ResourceRequest /** Get/Set IsProcessing variables */ bool isProcessing() { return processing; } - void setProcessing() { processing = true; } + void setProcessing(bool cond = true) { processing = cond; } /** Get/Set IsWaiting variables */ - bool isWaiting() { return waiting; } - void setWaiting() { waiting = true; } + bool isMemStall() { return memStall; } + void setMemStall(bool stall = true) { memStall = stall; } protected: /** Resource Identification */ @@ -399,12 +402,13 @@ class ResourceRequest int stageNum; int resIdx; int slotNum; - - /** Resource Status */ + + /** Resource Request Status */ bool completed; bool squashed; bool processing; - bool waiting; + + bool memStall; }; #endif //__CPU_INORDER_RESOURCE_HH__