inorder-alpha-port: initial inorder support of ALPHA

Edit AlphaISA to support the inorder model. Mostly alternate constructor functions and also a few skeleton multithreaded support functions
* * *
Remove namespace from header file. Causes compiler issues that are hard to find
* * *
Separate the TLB from the CPU and allow it to live in the TLBUnit resource. Give CPU accessor functions for access and also bind at construction time
* * *
Expose memory access size and flags through instruction object
(temporarily memAccSize and memFlags to get TLB stuff working.)
This commit is contained in:
Korey Sewell
2009-05-12 15:01:13 -04:00
parent 63db33c4b1
commit 1c8dfd9254
16 changed files with 232 additions and 26 deletions

View File

@@ -180,15 +180,26 @@ InOrderCPU::InOrderCPU(Params *params)
// Bind the fetch & data ports from the resource pool.
fetchPortIdx = resPool->getPortIdx(params->fetchMemPort);
if (fetchPortIdx == 0) {
warn("Unable to find port to fetch instructions from.\n");
fatal("Unable to find port to fetch instructions from.\n");
}
dataPortIdx = resPool->getPortIdx(params->dataMemPort);
if (dataPortIdx == 0) {
warn("Unable to find port for data.\n");
fatal("Unable to find port for data.\n");
}
// Hard-Code Bindings to ITB & DTB
itbIdx = resPool->getResIdx(name() + "." + "I-TLB");
if (itbIdx == 0) {
fatal("Unable to find ITB resource.\n");
}
dtbIdx = resPool->getResIdx(name() + "." + "D-TLB");
if (dtbIdx == 0) {
fatal("Unable to find DTB resource.\n");
}
for (int i = 0; i < numThreads; ++i) {
if (i < params->workload.size()) {
DPRINTF(InOrderCPU, "Workload[%i] process is %#x\n",
@@ -814,6 +825,13 @@ InOrderCPU::removeThread(unsigned tid)
/** Broadcast to CPU resources*/
}
PipelineStage*
InOrderCPU::getPipeStage(int stage_num)
{
return pipelineStage[stage_num];
}
void
InOrderCPU::activateWhenReady(int tid)
{
@@ -1245,3 +1263,18 @@ InOrderCPU::write(DynInstPtr inst)
Resource *mem_res = resPool->getResource(dataPortIdx);
return mem_res->doDataAccess(inst);
}
TheISA::ITB*
InOrderCPU::getITBPtr()
{
TLBUnit *itb_res = dynamic_cast<TLBUnit*>(resPool->getResource(itbIdx));
return dynamic_cast<TheISA::ITB*>(itb_res->tlb());
}
TheISA::DTB*
InOrderCPU::getDTBPtr()
{
TLBUnit *dtb_res = dynamic_cast<TLBUnit*>(resPool->getResource(dtbIdx));
return dynamic_cast<TheISA::DTB*>(dtb_res->tlb());
}

View File

@@ -103,9 +103,6 @@ class InOrderCPU : public BaseCPU
Params *cpu_params;
TheISA::TLB * itb;
TheISA::TLB * dtb;
public:
enum Status {
Running,
@@ -236,11 +233,17 @@ class InOrderCPU : public BaseCPU
*/
unsigned fetchPortIdx;
/** Identifies the resource id that identifies a ITB */
unsigned itbIdx;
/** Identifies the resource id that identifies a data
* access unit.
*/
unsigned dataPortIdx;
/** Identifies the resource id that identifies a DTB */
unsigned dtbIdx;
/** The Pipeline Stages for the CPU */
PipelineStage *pipelineStage[ThePipeline::NumStages];
@@ -262,6 +265,9 @@ class InOrderCPU : public BaseCPU
/** Communication structure that sits in between pipeline stages */
StageQueue *stageQueue[ThePipeline::NumStages-1];
TheISA::ITB *getITBPtr();
TheISA::DTB *getDTBPtr();
public:
/** Registers statistics. */
@@ -308,6 +314,8 @@ class InOrderCPU : public BaseCPU
void deallocateThread(unsigned tid);
void deactivateThread(unsigned tid);
PipelineStage* getPipeStage(int stage_num);
int
contextId()
{

View File

@@ -37,7 +37,10 @@
#include <list>
#include <string>
#include "arch/isa_traits.hh"
#include "arch/faults.hh"
#include "arch/types.hh"
#include "arch/mt.hh"
#include "base/fast_alloc.hh"
#include "base/trace.hh"
#include "cpu/inorder/inorder_trace.hh"
@@ -827,6 +830,10 @@ class InOrderDynInst : public FastAlloc, public RefCounted
virtual uint64_t readRegOtherThread(unsigned idx, int tid = -1);
virtual void setRegOtherThread(unsigned idx, const uint64_t &val, int tid = -1);
/** Sets the number of consecutive store conditional failures. */
void setStCondFailures(unsigned sc_failures)
{ thread->storeCondFailures = sc_failures; }
//////////////////////////////////////////////////////////////
//
// INSTRUCTION STATUS FLAGS (READ/SET)

View File

@@ -143,6 +143,21 @@ ResourcePool::getPortIdx(const std::string &port_name)
return 0;
}
unsigned
ResourcePool::getResIdx(const std::string &res_name)
{
DPRINTF(Resource, "Finding Resource Idx for %s.\n", res_name);
int num_resources = resources.size();
for (int idx = 0; idx < num_resources; idx++) {
if (resources[idx]->name() == res_name)
return idx;
}
return 0;
}
ResReqPtr
ResourcePool::request(int res_idx, DynInstPtr inst)
{

View File

@@ -131,8 +131,12 @@ class ResourcePool {
Port* getPort(const std::string &if_name, int idx);
/** Returns a specific port. */
unsigned getPortIdx(const std::string &if_name);
unsigned getPortIdx(const std::string &port_name);
/** Returns a specific resource. */
unsigned getResIdx(const std::string &res_name);
/** Returns a pointer to a resource */
Resource* getResource(int res_idx) { return resources[res_idx]; }
/** Request usage of this resource. Returns -1 if not granted and

View File

@@ -32,7 +32,7 @@
#include <vector>
#include <list>
#include "arch/isa_traits.hh"
#include "arch/mips/locked_mem.hh"
#include "arch/locked_mem.hh"
#include "arch/utility.hh"
#include "cpu/inorder/resources/cache_unit.hh"
#include "cpu/inorder/pipeline_traits.hh"

View File

@@ -47,7 +47,7 @@ MultDivUnit::MultDivUnit(string res_name, int res_id, int res_width,
div16RepeatRate(params->div16RepeatRate), div16Latency(params->div16Latency),
div24RepeatRate(params->div24RepeatRate), div24Latency(params->div24Latency),
div32RepeatRate(params->div32RepeatRate), div32Latency(params->div32Latency),
lastMDUCycle(0)
lastMDUCycle(0), lastOpType(No_OpClass)
{ }
void

View File

@@ -33,6 +33,7 @@
#include <list>
#include "arch/isa_traits.hh"
#include "cpu/inorder/pipeline_traits.hh"
#include "cpu/inorder/first_stage.hh"
#include "cpu/inorder/resources/tlb_unit.hh"
#include "cpu/inorder/cpu.hh"
@@ -44,11 +45,26 @@ 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)
{
// Hard-Code Selection For Now
if (res_name == "I-TLB")
_tlb = params->itb;
else if (res_name == "D-TLB")
_tlb = params->dtb;
else
fatal("Unrecognized TLB name passed by user");
for (int i=0; i < MaxThreads; i++) {
tlbBlocked[i] = false;
}
}
TheISA::TLB*
TLBUnit::tlb()
{
return _tlb;
}
void
TLBUnit::init()
{
@@ -82,7 +98,7 @@ TLBUnit::execute(int slot_idx)
// After this is working, change this to a reinterpret cast
// for performance considerations
TLBUnitRequest* tlb_req = dynamic_cast<TLBUnitRequest*>(reqMap[slot_idx]);
assert(tlb_req);
assert(tlb_req != 0x0);
DynInstPtr inst = tlb_req->inst;
int tid, seq_num, stage_num;
@@ -93,12 +109,15 @@ TLBUnit::execute(int slot_idx)
tlb_req->fault = NoFault;
assert(cpu->thread[tid]->getTC() != 0x0);
assert(cpu->pipelineStage[stage_num] != 0x0);
switch (tlb_req->cmd)
{
case FetchLookup:
{
tlb_req->fault =
this->cpu->itb->translateAtomic(tlb_req->memReq,
_tlb->translateAtomic(tlb_req->memReq,
cpu->thread[tid]->getTC(), false, true);
if (tlb_req->fault != NoFault) {
@@ -129,7 +148,7 @@ TLBUnit::execute(int slot_idx)
tid, seq_num, tlb_req->memReq->getVaddr());
tlb_req->fault =
this->cpu->itb->translateAtomic(tlb_req->memReq,
_tlb->translateAtomic(tlb_req->memReq,
cpu->thread[tid]->getTC());
if (tlb_req->fault != NoFault) {

View File

@@ -67,14 +67,15 @@ class TLBUnit : public InstBuffer {
bool tlbBlocked[ThePipeline::MaxThreads];
TheISA::TLB* tlb();
protected:
/** List of instructions this resource is currently
* processing.
*/
std::list<DynInstPtr> instList;
/** @todo: Add Resource Stats Here */
TheISA::TLB *_tlb;
};
class TLBUnitEvent : public ResourceEvent {

View File

@@ -57,7 +57,7 @@ class InOrderThreadContext : public ThreadContext
public:
InOrderThreadContext() { }
/** Pointer to the CPU. */
/** Pointer to the CPU. */
InOrderCPU *cpu;
/** Pointer to the thread state that this TC corrseponds to. */
@@ -65,10 +65,12 @@ class InOrderThreadContext : public ThreadContext
/** Returns a pointer to the ITB. */
TheISA::TLB *getITBPtr() { return cpu->itb; }
/** @TODO: PERF: Should we bind this to a pointer in constructor? */
TheISA::TLB *getITBPtr() { return cpu->getITBPtr(); }
/** Returns a pointer to the DTB. */
TheISA::TLB *getDTBPtr() { return cpu->dtb; }
/** @TODO: PERF: Should we bind this to a pointer in constructor? */
TheISA::TLB *getDTBPtr() { return cpu->getDTBPtr(); }
System *getSystemPtr() { return cpu->system; }