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:
@@ -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
|
||||
|
||||
@@ -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 §ion);
|
||||
|
||||
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
|
||||
|
||||
@@ -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; }},
|
||||
|
||||
@@ -57,8 +57,15 @@ MiscRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
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:
|
||||
|
||||
@@ -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 §ion);
|
||||
|
||||
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);
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace MipsISA
|
||||
|
||||
public:
|
||||
MiscRegFile();
|
||||
MiscRegFile(BaseCPU *cpu);
|
||||
MiscRegFile(BaseCPU *_cpu);
|
||||
|
||||
void init();
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user