summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/SConscript1
-rw-r--r--src/arch/alpha/floatregfile.hh56
-rw-r--r--src/arch/alpha/isa/mem.isa39
-rw-r--r--src/arch/alpha/miscregfile.cc16
-rw-r--r--src/arch/alpha/miscregfile.hh23
-rw-r--r--src/arch/mips/regfile/misc_regfile.hh2
-rw-r--r--src/cpu/inorder/cpu.cc37
-rw-r--r--src/cpu/inorder/cpu.hh14
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.hh7
-rw-r--r--src/cpu/inorder/resource_pool.cc15
-rw-r--r--src/cpu/inorder/resource_pool.hh6
-rw-r--r--src/cpu/inorder/resources/cache_unit.cc2
-rw-r--r--src/cpu/inorder/resources/mult_div_unit.cc2
-rw-r--r--src/cpu/inorder/resources/tlb_unit.cc25
-rw-r--r--src/cpu/inorder/resources/tlb_unit.hh5
-rw-r--r--src/cpu/inorder/thread_context.hh8
16 files changed, 232 insertions, 26 deletions
diff --git a/src/arch/SConscript b/src/arch/SConscript
index b85ffbd89..0d801fcad 100644
--- a/src/arch/SConscript
+++ b/src/arch/SConscript
@@ -51,6 +51,7 @@ isa_switch_hdrs = Split('''
locked_mem.hh
microcode_rom.hh
mmaped_ipr.hh
+ mt.hh
process.hh
predecoder.hh
regfile.hh
diff --git a/src/arch/alpha/floatregfile.hh b/src/arch/alpha/floatregfile.hh
index d5f9eec0f..a5a3a7861 100644
--- a/src/arch/alpha/floatregfile.hh
+++ b/src/arch/alpha/floatregfile.hh
@@ -42,6 +42,13 @@ class Checkpoint;
namespace AlphaISA {
+const int SingleWidth = 32;
+const int SingleBytes = SingleWidth / 4;
+const int DoubleWidth = 64;
+const int DoubleBytes = DoubleWidth / 4;
+const int QuadWidth = 128;
+const int QuadBytes = QuadWidth / 4;
+
class FloatRegFile
{
public:
@@ -54,6 +61,55 @@ class FloatRegFile
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
+
+ FloatReg
+ readReg(int floatReg)
+ {
+ return d[floatReg];
+ }
+
+ FloatReg
+ readReg(int floatReg, int width)
+ {
+ return readReg(floatReg);
+ }
+
+ FloatRegBits
+ readRegBits(int floatReg)
+ {
+ return q[floatReg];
+ }
+
+ FloatRegBits
+ readRegBits(int floatReg, int width)
+ {
+ return readRegBits(floatReg);
+ }
+
+ void
+ setReg(int floatReg, const FloatReg &val)
+ {
+ d[floatReg] = val;
+ }
+
+ void
+ setReg(int floatReg, const FloatReg &val, int width)
+ {
+ setReg(floatReg, val);
+ }
+
+ void
+ setRegBits(int floatReg, const FloatRegBits &val)
+ {
+ q[floatReg] = val;
+ }
+
+ void
+ setRegBits(int floatReg, const FloatRegBits &val, int width)
+ {
+ setRegBits(floatReg, val);
+ }
+
};
} // namespace AlphaISA
diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa
index cd5e117ec..9a8503637 100644
--- a/src/arch/alpha/isa/mem.isa
+++ b/src/arch/alpha/isa/mem.isa
@@ -65,6 +65,8 @@ output header {{
const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
const StaticInstPtr &memAccInst() const { return memAccPtr; }
+
+ Request::Flags memAccFlags() { return memAccessFlags; }
};
/**
@@ -176,6 +178,8 @@ def template LoadStoreDeclare {{
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
+
+ %(MemAccSizeDeclare)s
};
}};
@@ -190,6 +194,25 @@ def template CompleteAccDeclare {{
Trace::InstRecord *) const;
}};
+def template MemAccSizeDeclare {{
+ int memAccSize(%(CPU_exec_context)s *xc);
+}};
+
+def template MiscMemAccSize {{
+ int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
+ {
+ panic("Misc instruction does not support split access method!");
+ return 0;
+ }
+}};
+
+def template LoadStoreMemAccSize {{
+ int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
+ {
+ // Return the memory access size in bytes
+ return (%(mem_acc_size)d / 8);
+ }
+}};
def template EACompConstructor {{
/** TODO: change op_class to AddrGenOp or something (requires
@@ -620,6 +643,14 @@ def template MiscCompleteAcc {{
}
}};
+def template MiscMemAccSize {{
+ int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
+ {
+ panic("Misc instruction does not support split access method!");
+ return 0;
+ }
+}};
+
// load instructions use Ra as dest, so check for
// Ra == 31 to detect nops
def template LoadNopCheckDecode {{
@@ -693,6 +724,11 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
+ if (exec_template_base == 'Load' or exec_template_base == 'Store'):
+ memAccSizeTemplate = eval('LoadStoreMemAccSize')
+ else:
+ memAccSizeTemplate = eval('MiscMemAccSize')
+
# (header_output, decoder_output, decode_block, exec_output)
return (LoadStoreDeclare.subst(iop),
EACompConstructor.subst(ea_iop)
@@ -703,7 +739,8 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ memAccExecTemplate.subst(memacc_iop)
+ fullExecTemplate.subst(iop)
+ initiateAccTemplate.subst(iop)
- + completeAccTemplate.subst(iop))
+ + completeAccTemplate.subst(iop)
+ + memAccSizeTemplate.subst(memacc_iop))
}};
def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
diff --git a/src/arch/alpha/miscregfile.cc b/src/arch/alpha/miscregfile.cc
index 61a86f1fb..5dc316a83 100644
--- a/src/arch/alpha/miscregfile.cc
+++ b/src/arch/alpha/miscregfile.cc
@@ -57,8 +57,15 @@ MiscRegFile::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
}
+MiscRegFile::MiscRegFile(BaseCPU *_cpu)
+{
+ cpu = _cpu;
+ initializeIprTable();
+}
+
+
MiscReg
-MiscRegFile::readRegNoEffect(int misc_reg)
+MiscRegFile::readRegNoEffect(int misc_reg, unsigned tid )
{
switch (misc_reg) {
case MISCREG_FPCR:
@@ -78,7 +85,7 @@ MiscRegFile::readRegNoEffect(int misc_reg)
}
MiscReg
-MiscRegFile::readReg(int misc_reg, ThreadContext *tc)
+MiscRegFile::readReg(int misc_reg, ThreadContext *tc, unsigned tid )
{
switch (misc_reg) {
case MISCREG_FPCR:
@@ -97,7 +104,7 @@ MiscRegFile::readReg(int misc_reg, ThreadContext *tc)
}
void
-MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val)
+MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid)
{
switch (misc_reg) {
case MISCREG_FPCR:
@@ -123,7 +130,8 @@ MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val)
}
void
-MiscRegFile::setReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
+MiscRegFile::setReg(int misc_reg, const MiscReg &val, ThreadContext *tc,
+ unsigned tid)
{
switch (misc_reg) {
case MISCREG_FPCR:
diff --git a/src/arch/alpha/miscregfile.hh b/src/arch/alpha/miscregfile.hh
index 6105ce683..b194e00bb 100644
--- a/src/arch/alpha/miscregfile.hh
+++ b/src/arch/alpha/miscregfile.hh
@@ -41,6 +41,7 @@
class Checkpoint;
class ThreadContext;
+class BaseCPU;
namespace AlphaISA {
@@ -68,6 +69,8 @@ class MiscRegFile
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
+ BaseCPU *cpu;
+
protected:
InternalProcReg readIpr(int idx, ThreadContext *tc);
void setIpr(int idx, InternalProcReg val, ThreadContext *tc);
@@ -78,16 +81,18 @@ class MiscRegFile
initializeIprTable();
}
+ MiscRegFile(BaseCPU *cpu);
+
// These functions should be removed once the simplescalar cpu
// model has been replaced.
int getInstAsid();
int getDataAsid();
- MiscReg readRegNoEffect(int misc_reg);
- MiscReg readReg(int misc_reg, ThreadContext *tc);
+ MiscReg readRegNoEffect(int misc_reg, unsigned tid = 0);
+ MiscReg readReg(int misc_reg, ThreadContext *tc, unsigned tid = 0);
- void setRegNoEffect(int misc_reg, const MiscReg &val);
- void setReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
+ void setRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid = 0);
+ void setReg(int misc_reg, const MiscReg &val, ThreadContext *tc, unsigned tid = 0);
void
clear()
@@ -101,6 +106,16 @@ class MiscRegFile
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
+
+ void reset(std::string core_name, unsigned num_threads,
+ unsigned num_vpes, BaseCPU *_cpu)
+ { }
+
+
+ void expandForMultithreading(unsigned num_threads, unsigned num_vpes)
+ { }
+
+
};
void copyIprs(ThreadContext *src, ThreadContext *dest);
diff --git a/src/arch/mips/regfile/misc_regfile.hh b/src/arch/mips/regfile/misc_regfile.hh
index c611d94cc..0daf8f718 100644
--- a/src/arch/mips/regfile/misc_regfile.hh
+++ b/src/arch/mips/regfile/misc_regfile.hh
@@ -69,7 +69,7 @@ namespace MipsISA
public:
MiscRegFile();
- MiscRegFile(BaseCPU *cpu);
+ MiscRegFile(BaseCPU *_cpu);
void init();
diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc
index 0b38f39bc..83e94e74d 100644
--- a/src/cpu/inorder/cpu.cc
+++ b/src/cpu/inorder/cpu.cc
@@ -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());
+}
diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh
index 744dd5cf9..8b2442ac0 100644
--- a/src/cpu/inorder/cpu.hh
+++ b/src/cpu/inorder/cpu.hh
@@ -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()
{
diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh
index 3b47624fb..12a9a4176 100644
--- a/src/cpu/inorder/inorder_dyn_inst.hh
+++ b/src/cpu/inorder/inorder_dyn_inst.hh
@@ -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)
diff --git a/src/cpu/inorder/resource_pool.cc b/src/cpu/inorder/resource_pool.cc
index 94af68c7a..725f6cbb3 100644
--- a/src/cpu/inorder/resource_pool.cc
+++ b/src/cpu/inorder/resource_pool.cc
@@ -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)
{
diff --git a/src/cpu/inorder/resource_pool.hh b/src/cpu/inorder/resource_pool.hh
index 35fce7db7..6cc1f77e6 100644
--- a/src/cpu/inorder/resource_pool.hh
+++ b/src/cpu/inorder/resource_pool.hh
@@ -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
diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc
index 772437638..d273d7247 100644
--- a/src/cpu/inorder/resources/cache_unit.cc
+++ b/src/cpu/inorder/resources/cache_unit.cc
@@ -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"
diff --git a/src/cpu/inorder/resources/mult_div_unit.cc b/src/cpu/inorder/resources/mult_div_unit.cc
index b31d60ad5..df9d4c293 100644
--- a/src/cpu/inorder/resources/mult_div_unit.cc
+++ b/src/cpu/inorder/resources/mult_div_unit.cc
@@ -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
diff --git a/src/cpu/inorder/resources/tlb_unit.cc b/src/cpu/inorder/resources/tlb_unit.cc
index b3757d707..fbc6bc195 100644
--- a/src/cpu/inorder/resources/tlb_unit.cc
+++ b/src/cpu/inorder/resources/tlb_unit.cc
@@ -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) {
diff --git a/src/cpu/inorder/resources/tlb_unit.hh b/src/cpu/inorder/resources/tlb_unit.hh
index c7fee6030..b53f251fc 100644
--- a/src/cpu/inorder/resources/tlb_unit.hh
+++ b/src/cpu/inorder/resources/tlb_unit.hh
@@ -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 {
diff --git a/src/cpu/inorder/thread_context.hh b/src/cpu/inorder/thread_context.hh
index ec8cc1979..cde377dfc 100644
--- a/src/cpu/inorder/thread_context.hh
+++ b/src/cpu/inorder/thread_context.hh
@@ -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; }