From 3a057bdbb10a265fb36f7827cd06142ad1624530 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Tue, 12 May 2009 15:01:16 -0400 Subject: inorder-tlb: squash insts in TLB correctly TLB had a bug where if it was stalled and waiting , it would not squash all instructions older than squashed instruction correctly * * * --- src/cpu/inorder/cpu.cc | 20 ++++++++++-- src/cpu/inorder/cpu.hh | 2 ++ src/cpu/inorder/resource.cc | 5 ++- src/cpu/inorder/resource_pool.cc | 2 +- src/cpu/inorder/resources/tlb_unit.cc | 61 +++++++++++++++++++++++++++++++++-- src/cpu/inorder/resources/tlb_unit.hh | 5 ++- 6 files changed, 87 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 51f763112..c522fc238 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -80,6 +80,22 @@ InOrderCPU::CPUEvent::CPUEvent(InOrderCPU *_cpu, CPUEventType e_type, setEvent(e_type, fault, _tid, _vpe); } + +std::string InOrderCPU::eventNames[NumCPUEvents] = +{ + "ActivateThread", + "DeallocateThread", + "SuspendThread", + "DisableThreads", + "EnableThreads", + "DisableVPEs", + "EnableVPEs", + "Trap", + "InstGraduated", + "SquashAll", + "UpdatePCs" +}; + void InOrderCPU::CPUEvent::process() { @@ -486,8 +502,8 @@ InOrderCPU::scheduleCpuEvent(CPUEventType c_event, Fault fault, CPUEvent *cpu_event = new CPUEvent(this, c_event, fault, tid, vpe); if (delay >= 0) { - DPRINTF(InOrderCPU, "Scheduling CPU Event Type #%i for cycle %i.\n", - c_event, curTick + delay); + DPRINTF(InOrderCPU, "Scheduling CPU Event Type #%s for cycle %i.\n", + eventNames[c_event], curTick + delay); mainEventQueue.schedule(cpu_event,curTick + delay); } else { cpu_event->process(); diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh index e3bfbb7f0..ea5404c60 100644 --- a/src/cpu/inorder/cpu.hh +++ b/src/cpu/inorder/cpu.hh @@ -175,6 +175,8 @@ class InOrderCPU : public BaseCPU NumCPUEvents }; + static std::string eventNames[NumCPUEvents]; + /** Define CPU Event */ class CPUEvent : public Event { diff --git a/src/cpu/inorder/resource.cc b/src/cpu/inorder/resource.cc index 2846efe7b..d8fefe0c9 100644 --- a/src/cpu/inorder/resource.cc +++ b/src/cpu/inorder/resource.cc @@ -304,9 +304,12 @@ Resource::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, unsi req_ptr->getInst()->readTid(), req_ptr->getInst()->seqNum); + req_ptr->setSquashed(); + int req_slot_num = req_ptr->getSlot(); - unscheduleEvent(req_slot_num); + if (resourceEvent[req_slot_num].scheduled()) + unscheduleEvent(req_slot_num); // Mark request for later removal cpu->reqRemoveList.push(req_ptr); diff --git a/src/cpu/inorder/resource_pool.cc b/src/cpu/inorder/resource_pool.cc index 725f6cbb3..2187e2818 100644 --- a/src/cpu/inorder/resource_pool.cc +++ b/src/cpu/inorder/resource_pool.cc @@ -256,7 +256,7 @@ ResourcePool::scheduleEvent(InOrderCPU::CPUEventType e_type, DynInstPtr inst, break; default: - DPRINTF(Resource, "Ignoring Unrecognized CPU Event Type #%i.\n", e_type); + DPRINTF(Resource, "Ignoring Unrecognized CPU Event Type #%s.\n", InOrderCPU::eventNames[e_type]); ; // If Resource Pool doesnt recognize event, we ignore it. } } diff --git a/src/cpu/inorder/resources/tlb_unit.cc b/src/cpu/inorder/resources/tlb_unit.cc index 93c066bb0..1ce8ff8c2 100644 --- a/src/cpu/inorder/resources/tlb_unit.cc +++ b/src/cpu/inorder/resources/tlb_unit.cc @@ -43,7 +43,7 @@ using namespace ThePipeline; TLBUnit::TLBUnit(string res_name, int res_id, int res_width, int res_latency, InOrderCPU *_cpu, ThePipeline::Params *params) - : InstBuffer(res_name, res_id, res_width, res_latency, _cpu, params) +: Resource(res_name, res_id, res_width, res_latency, _cpu) { // Hard-Code Selection For Now if (res_name == "I-TLB") @@ -124,7 +124,9 @@ TLBUnit::execute(int slot_idx) DPRINTF(InOrderTLB, "[tid:%i]: %s encountered while translating " "addr:%08p for [sn:%i].\n", tid, tlb_req->fault->name(), tlb_req->memReq->getVaddr(), seq_num); - //insert(inst); + + DPRINTF(InOrderTLB, "slot:%i sn:%i schedule event.\n", slot_idx, seq_num); + cpu->pipelineStage[stage_num]->setResStall(tlb_req, tid); tlbBlocked[tid] = true; scheduleEvent(slot_idx, 1); @@ -210,7 +212,7 @@ TLBUnitEvent::process() tlb_res->tlbBlocked[tid] = false; - tlb_res->cpu->pipelineStage[stage_num]->unsetResStall(resource->reqMap[slotIdx], tid); + tlb_res->cpu->pipelineStage[stage_num]->unsetResStall(tlb_res->reqMap[slotIdx], tid); // Effectively NOP the instruction but still allow it // to commit @@ -219,3 +221,56 @@ TLBUnitEvent::process() //inst->resSched.pop(); //} } + +void +TLBUnit::squash(DynInstPtr inst, int stage_num, + InstSeqNum squash_seq_num, unsigned tid) +{ + //@TODO: Figure out a way to consolidate common parts + // of this squash code + std::vector slot_remove_list; + + map::iterator map_it = reqMap.begin(); + map::iterator map_end = reqMap.end(); + + while (map_it != map_end) { + ResReqPtr req_ptr = (*map_it).second; + + if (req_ptr && + req_ptr->getInst()->readTid() == tid && + req_ptr->getInst()->seqNum > squash_seq_num) { + + DPRINTF(Resource, "[tid:%i]: Squashing [sn:%i].\n", + req_ptr->getInst()->readTid(), + req_ptr->getInst()->seqNum); + + req_ptr->setSquashed(); + + int req_slot_num = req_ptr->getSlot(); + + tlbBlocked[tid] = false; + + int stall_stage = reqMap[req_slot_num]->getStageNum(); + + cpu->pipelineStage[stall_stage]->unsetResStall(reqMap[req_slot_num], tid); + + if (resourceEvent[req_slot_num].scheduled()) + unscheduleEvent(req_slot_num); + + // Mark request for later removal + cpu->reqRemoveList.push(req_ptr); + + // Mark slot for removal from resource + slot_remove_list.push_back(req_ptr->getSlot()); + } + + map_it++; + } + + // Now Delete Slot Entry from Req. Map + for (int i = 0; i < slot_remove_list.size(); i++) { + freeSlot(slot_remove_list[i]); + } +} + + diff --git a/src/cpu/inorder/resources/tlb_unit.hh b/src/cpu/inorder/resources/tlb_unit.hh index 4ca240ba8..759fe14f1 100644 --- a/src/cpu/inorder/resources/tlb_unit.hh +++ b/src/cpu/inorder/resources/tlb_unit.hh @@ -41,7 +41,8 @@ #include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/cpu.hh" -class TLBUnit : public InstBuffer { +class TLBUnit : public Resource +{ public: typedef ThePipeline::DynInstPtr DynInstPtr; @@ -66,6 +67,8 @@ class TLBUnit : public InstBuffer { virtual void execute(int slot_num); + void squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, unsigned tid); + bool tlbBlocked[ThePipeline::MaxThreads]; TheISA::TLB* tlb(); -- cgit v1.2.3