summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/sparc/faults.cc51
-rw-r--r--src/arch/sparc/floatregfile.hh5
-rw-r--r--src/arch/sparc/intregfile.cc17
-rw-r--r--src/arch/sparc/intregfile.hh8
-rw-r--r--src/arch/sparc/isa/base.isa2
-rw-r--r--src/arch/sparc/isa/decoder.isa13
-rw-r--r--src/arch/sparc/isa/formats/mem/util.isa60
-rw-r--r--src/arch/sparc/isa/formats/priv.isa19
-rw-r--r--src/arch/sparc/isa/operands.isa2
-rw-r--r--src/arch/sparc/isa_traits.hh47
-rw-r--r--src/arch/sparc/miscregfile.cc19
-rw-r--r--src/arch/sparc/miscregfile.hh9
-rw-r--r--src/arch/sparc/process.cc3
-rw-r--r--src/arch/sparc/regfile.cc3
-rw-r--r--src/arch/sparc/sparc_traits.hh55
-rw-r--r--src/arch/sparc/system.cc108
-rw-r--r--src/arch/sparc/system.hh36
-rw-r--r--src/cpu/exetrace.cc278
-rwxr-xr-xsrc/cpu/o3/isa_specific.hh5
-rw-r--r--src/cpu/o3/sparc/cpu.cc38
-rw-r--r--src/cpu/o3/sparc/cpu.hh207
-rw-r--r--src/cpu/o3/sparc/cpu_builder.cc433
-rw-r--r--src/cpu/o3/sparc/cpu_impl.hh319
-rw-r--r--src/cpu/o3/sparc/dyn_inst.cc36
-rw-r--r--src/cpu/o3/sparc/dyn_inst.hh273
-rw-r--r--src/cpu/o3/sparc/dyn_inst_impl.hh139
-rw-r--r--src/cpu/o3/sparc/impl.hh92
-rw-r--r--src/cpu/o3/sparc/params.hh63
-rwxr-xr-xsrc/cpu/o3/sparc/thread_context.cc35
-rw-r--r--src/cpu/o3/sparc/thread_context.hh84
-rw-r--r--src/dev/sparc/SConscript1
-rw-r--r--src/dev/sparc/t1000.cc124
-rw-r--r--src/dev/sparc/t1000.hh108
-rw-r--r--src/mem/physical.cc11
-rw-r--r--src/mem/physical.hh1
-rw-r--r--src/python/m5/objects/PhysicalMemory.py1
-rw-r--r--src/python/m5/objects/System.py23
-rw-r--r--src/python/m5/objects/T1000.py31
38 files changed, 2623 insertions, 136 deletions
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc
index 4cf411d3b..9a29f24d5 100644
--- a/src/arch/sparc/faults.cc
+++ b/src/arch/sparc/faults.cc
@@ -284,6 +284,11 @@ void enterREDState(ThreadContext *tc)
//HPSTATE.hpriv = 1
HPSTATE |= (1 << 2);
tc->setMiscRegWithEffect(MISCREG_HPSTATE, HPSTATE);
+ //PSTATE.priv is set to 1 here. The manual says it should be 0, but
+ //Legion sets it to 1.
+ MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
+ PSTATE |= (1 << 2);
+ tc->setMiscRegWithEffect(MISCREG_PSTATE, PSTATE);
}
/**
@@ -340,10 +345,12 @@ void doREDFault(ThreadContext *tc, TrapType tt)
PSTATE |= (1 << 4);
//set PSTATE.am to 0
PSTATE &= ~(1 << 3);
- //set PSTATE.priv to 0
- PSTATE &= ~(1 << 2);
+/* //set PSTATE.priv to 0
+ PSTATE &= ~(1 << 2);*/
//set PSTATE.ie to 0
- PSTATE &= ~(1 << 1);
+ //PSTATE.priv is set to 1 here. The manual says it should be 0, but
+ //Legion sets it to 1.
+ PSTATE |= (1 << 2);
//set PSTATE.cle to 0
PSTATE &= ~(1 << 9);
//PSTATE.tle is unchanged
@@ -451,7 +458,9 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
else
{
//PSTATE.priv = 0
- PSTATE &= ~(1 << 2);
+ //PSTATE.priv is set to 1 here. The manual says it should be 0, but
+ //Legion sets it to 1.
+ PSTATE |= (1 << 2);
//PSTATE.cle = 0
PSTATE &= ~(1 << 9);
}
@@ -533,20 +542,22 @@ void SparcFaultBase::invoke(ThreadContext * tc)
Addr PC, NPC;
PrivilegeLevel current;
- if(!(PSTATE & (1 << 2)))
- current = User;
- else if(!(HPSTATE & (1 << 2)))
+ if(HPSTATE & (1 << 2))
+ current = Hyperprivileged;
+ else if(PSTATE & (1 << 2))
current = Privileged;
else
- current = Hyperprivileged;
+ current = User;
PrivilegeLevel level = getNextLevel(current);
if(HPSTATE & (1 << 5) || TL == MaxTL - 1)
{
getREDVector(5, PC, NPC);
- enterREDState(tc);
doREDFault(tc, TT);
+ //This changes the hpstate and pstate, so we need to make sure we
+ //save the old version on the trap stack in doREDFault.
+ enterREDState(tc);
}
else if(TL == MaxTL)
{
@@ -578,9 +589,6 @@ void SparcFaultBase::invoke(ThreadContext * tc)
void PowerOnReset::invoke(ThreadContext * tc)
{
- //First, enter RED state.
- enterREDState(tc);
-
//For SPARC, when a system is first started, there is a power
//on reset Trap which sets the processor into the following state.
//Bits that aren't set aren't defined on startup.
@@ -589,15 +597,28 @@ void PowerOnReset::invoke(ThreadContext * tc)
tc->setMiscReg(MISCREG_TT, trapType());
tc->setMiscRegWithEffect(MISCREG_GL, MaxGL);
- //Turn on pef, set everything else to 0
- tc->setMiscReg(MISCREG_PSTATE, 1 << 4);
+ //Turn on pef and priv, set everything else to 0
+ tc->setMiscReg(MISCREG_PSTATE, (1 << 4) | (1 << 2));
//Turn on red and hpriv, set everything else to 0
- tc->setMiscReg(MISCREG_HPSTATE, (1 << 5) | (1 << 2));
+ MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
+ //HPSTATE.red = 1
+ HPSTATE |= (1 << 5);
+ //HPSTATE.hpriv = 1
+ HPSTATE |= (1 << 2);
+ //HPSTATE.ibe = 0
+ HPSTATE &= ~(1 << 10);
+ //HPSTATE.tlz = 0
+ HPSTATE &= ~(1 << 0);
+ tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
//The tick register is unreadable by nonprivileged software
tc->setMiscReg(MISCREG_TICK, 1ULL << 63);
+ //Enter RED state. We do this last so that the actual state preserved in
+ //the trap stack is the state from before this fault.
+ enterREDState(tc);
+
Addr PC, NPC;
getREDVector(trapType(), PC, NPC);
tc->setPC(PC);
diff --git a/src/arch/sparc/floatregfile.hh b/src/arch/sparc/floatregfile.hh
index 9d760c9ff..72803a5e0 100644
--- a/src/arch/sparc/floatregfile.hh
+++ b/src/arch/sparc/floatregfile.hh
@@ -38,10 +38,15 @@
#include <string>
+class Checkpoint;
+
namespace SparcISA
{
std::string getFloatRegName(RegIndex);
+ const int NumFloatArchRegs = 64;
+ const int NumFloatRegs = 64;
+
typedef float float32_t;
typedef double float64_t;
//FIXME long double refers to a 10 byte float, rather than a
diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc
index 358368e5f..0a8ac055f 100644
--- a/src/arch/sparc/intregfile.cc
+++ b/src/arch/sparc/intregfile.cc
@@ -31,6 +31,7 @@
#include "arch/sparc/intregfile.hh"
#include "base/trace.hh"
+#include "base/misc.hh"
#include "sim/serialize.hh"
#include <string.h>
@@ -42,7 +43,7 @@ class Checkpoint;
string SparcISA::getIntRegName(RegIndex index)
{
- static std::string intRegName[NumIntRegs] =
+ static std::string intRegName[NumIntArchRegs] =
{"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
"o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
"l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
@@ -78,30 +79,30 @@ IntRegFile::IntRegFile()
IntReg IntRegFile::readReg(int intReg)
{
IntReg val;
- if(intReg < NumRegularIntRegs)
+ if(intReg < NumIntArchRegs)
val = regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask];
- else if((intReg -= NumRegularIntRegs) < NumMicroIntRegs)
+ else if((intReg -= NumIntArchRegs) < NumMicroIntRegs)
val = microRegs[intReg];
else
- panic("Tried to read non-existant integer register %d, %d\n", NumRegularIntRegs + NumMicroIntRegs + intReg, intReg);
+ panic("Tried to read non-existant integer register %d, %d\n",
+ NumIntArchRegs + NumMicroIntRegs + intReg, intReg);
DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val);
return val;
}
-Fault IntRegFile::setReg(int intReg, const IntReg &val)
+void IntRegFile::setReg(int intReg, const IntReg &val)
{
if(intReg)
{
DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val);
- if(intReg < NumRegularIntRegs)
+ if(intReg < NumIntArchRegs)
regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val;
- else if((intReg -= NumRegularIntRegs) < NumMicroIntRegs)
+ else if((intReg -= NumIntArchRegs) < NumMicroIntRegs)
microRegs[intReg] = val;
else
panic("Tried to set non-existant integer register\n");
}
- return NoFault;
}
//This doesn't effect the actual CWP register.
diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh
index 223e3b34c..59f767e8e 100644
--- a/src/arch/sparc/intregfile.hh
+++ b/src/arch/sparc/intregfile.hh
@@ -32,12 +32,13 @@
#ifndef __ARCH_SPARC_INTREGFILE_HH__
#define __ARCH_SPARC_INTREGFILE_HH__
-#include "arch/sparc/faults.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/types.hh"
#include <string>
+class Checkpoint;
+
namespace SparcISA
{
class RegFile;
@@ -45,6 +46,9 @@ namespace SparcISA
//This function translates integer register file indices into names
std::string getIntRegName(RegIndex);
+ const int NumIntArchRegs = 32;
+ const int NumIntRegs = MaxGL * 8 + NWindows * 16 + NumMicroIntRegs;
+
class IntRegFile
{
private:
@@ -85,7 +89,7 @@ namespace SparcISA
IntReg readReg(int intReg);
- Fault setReg(int intReg, const IntReg &val);
+ void setReg(int intReg, const IntReg &val);
void serialize(std::ostream &os);
diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa
index aa24c75be..4a806bfd0 100644
--- a/src/arch/sparc/isa/base.isa
+++ b/src/arch/sparc/isa/base.isa
@@ -205,7 +205,7 @@ output decoder {{
else if(reg < MaxMicroReg)
ccprintf(os, "%%u%d", reg - MaxInput);
else {
- ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
+ ccprintf(os, "%%f%d", reg - MaxMicroReg);
}
}
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index 2c8e59a1d..4e09e2e59 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -307,7 +307,7 @@ decode OP default Unknown::unknown()
int64_t resTemp, val2 = Rs2_or_imm13;
Rd = resTemp = Rs1 + val2;
int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
+ {{((Rs1<31:0> + val2<31:0>)<32:0>)}},
{{overflow}},
{{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
@@ -316,7 +316,7 @@ decode OP default Unknown::unknown()
int64_t resTemp, val2 = Rs2_or_imm13;
Rd = resTemp = Rs1 + val2;
int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}},
- {{(Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31}},
+ {{(Rs1<31:0> + val2<31:0>)<32:0>}},
{{overflow}},
{{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
@@ -327,7 +327,7 @@ decode OP default Unknown::unknown()
int32_t overflow = Rs1<1:0> || val2<1:0> ||
(Rs1<31:> == val2<31:> && val2<31:> != Rd<31:>);
if(overflow) fault = new TagOverflow;}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
+ {{((Rs1<31:0> + val2<31:0>)<32:0>)}},
{{overflow}},
{{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
{{Rs1<63:> == val2<63:> && val2<63:> != Rd<63:>}}
@@ -337,7 +337,7 @@ decode OP default Unknown::unknown()
Rd = resTemp = Rs1 + val2;
int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);
if(overflow) fault = new TagOverflow;}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
+ {{((Rs1<31:0> + val2<31:0>)<32:0>)}},
{{overflow}},
{{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
@@ -347,13 +347,12 @@ decode OP default Unknown::unknown()
int32_t multiplier = Rs1<31:0>;
int32_t savedLSB = Rs1<0:>;
multiplier = multiplier<31:1> |
- ((Ccr<3:3>
- ^ Ccr<1:1>) << 32);
+ ((Ccr<3:3> ^ Ccr<1:1>) << 32);
if(!Y<0:>)
multiplicand = 0;
Rd = resTemp = multiplicand + multiplier;
Y = Y<31:1> | (savedLSB << 31);}},
- {{((multiplicand & 0xFFFFFFFF + multiplier & 0xFFFFFFFF) >> 31)}},
+ {{((multiplicand<31:0> + multiplier<31:0>)<32:0>)}},
{{multiplicand<31:> == multiplier<31:> && multiplier<31:> != resTemp<31:>}},
{{((multiplicand >> 1) + (multiplier >> 1) + (multiplicand & multiplier & 0x1))<63:>}},
{{multiplicand<63:> == multiplier<63:> && multiplier<63:> != resTemp<63:>}}
diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa
index b9f7fde2d..857f37160 100644
--- a/src/arch/sparc/isa/formats/mem/util.isa
+++ b/src/arch/sparc/isa/formats/mem/util.isa
@@ -76,19 +76,22 @@ output decoder {{
{
std::stringstream response;
bool load = flags[IsLoad];
- bool save = flags[IsStore];
+ bool store = flags[IsStore];
printMnemonic(response, mnemonic);
- if(save)
+ if(store)
{
printReg(response, _srcRegIdx[0]);
ccprintf(response, ", ");
}
- ccprintf(response, "[ ");
- printReg(response, _srcRegIdx[!save ? 0 : 1]);
- ccprintf(response, " + ");
- printReg(response, _srcRegIdx[!save ? 1 : 2]);
- ccprintf(response, " ]");
+ ccprintf(response, "[");
+ if(_srcRegIdx[!store ? 0 : 1] != 0)
+ {
+ printSrcReg(response, !store ? 0 : 1);
+ ccprintf(response, " + ");
+ }
+ printSrcReg(response, !store ? 1 : 2);
+ ccprintf(response, "]");
if(load)
{
ccprintf(response, ", ");
@@ -111,12 +114,16 @@ output decoder {{
printReg(response, _srcRegIdx[0]);
ccprintf(response, ", ");
}
- ccprintf(response, "[ ");
- printReg(response, _srcRegIdx[!save ? 0 : 1]);
+ ccprintf(response, "[");
+ if(_srcRegIdx[!save ? 0 : 1] != 0)
+ {
+ printReg(response, _srcRegIdx[!save ? 0 : 1]);
+ ccprintf(response, " + ");
+ }
if(imm >= 0)
- ccprintf(response, " + 0x%x ]", imm);
+ ccprintf(response, "0x%x]", imm);
else
- ccprintf(response, " + -0x%x ]", -imm);
+ ccprintf(response, "-0x%x]", -imm);
if(load)
{
ccprintf(response, ", ");
@@ -149,8 +156,8 @@ def template LoadExecute {{
}
if(fault == NoFault)
{
- //Write the resulting state to the execution context
- %(op_wb)s;
+ //Write the resulting state to the execution context
+ %(op_wb)s;
}
return fault;
@@ -215,8 +222,8 @@ def template StoreExecute {{
}
if(fault == NoFault)
{
- //Write the resulting state to the execution context
- %(op_wb)s;
+ //Write the resulting state to the execution context
+ %(op_wb)s;
}
return fault;
@@ -244,7 +251,7 @@ def template StoreExecute {{
}
if(fault == NoFault)
{
- //Write the resulting state to the execution context
+ //Write the resulting state to the execution context
%(op_wb)s;
}
return fault;
@@ -293,7 +300,7 @@ let {{
//instruction at a certain micropc
let {{
def makeMicroName(name, microPc):
- return name + "::" + name + "_" + str(microPc)
+ return name + "::" + name + "_" + str(microPc)
}};
//This function properly generates the execute functions for one of the
@@ -302,13 +309,13 @@ let {{
//and in the other they're distributed across two. Also note that for
//execute functions, the name of the base class doesn't matter.
let {{
- def doSplitExecute(code, eaCode, execute,
- faultCode, name, Name, opt_flags):
- codeIop = InstObjParams(name, Name, '', code, opt_flags)
- eaIop = InstObjParams(name, Name, '', eaCode,
- opt_flags, {"fault_check": faultCode})
- iop = InstObjParams(name, Name, '', code, opt_flags,
- {"fault_check": faultCode, "ea_code" : eaCode})
+ def doSplitExecute(code, execute, name, Name, opt_flags, microParam):
+ codeParam = microParam.copy()
+ codeParam["ea_code"] = ''
+ codeIop = InstObjParams(name, Name, '', code, opt_flags, codeParam)
+ eaIop = InstObjParams(name, Name, '', microParam["ea_code"],
+ opt_flags, microParam)
+ iop = InstObjParams(name, Name, '', code, opt_flags, microParam)
(iop.ea_decl,
iop.ea_rd,
iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb)
@@ -324,7 +331,8 @@ let {{
for (eaCode, name, Name) in (
(eaRegCode, nameReg, NameReg),
(eaImmCode, nameImm, NameImm)):
- executeCode += doSplitExecute(code, eaCode,
- execute, faultCode, name, Name, opt_flags)
+ microParams = {"ea_code" : eaCode, "fault_check": faultCode}
+ executeCode += doSplitExecute(code, execute, name, Name,
+ opt_flags, microParams)
return executeCode
}};
diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa
index 94a68aebe..3d47ca02f 100644
--- a/src/arch/sparc/isa/formats/priv.isa
+++ b/src/arch/sparc/isa/formats/priv.isa
@@ -153,8 +153,13 @@ output decoder {{
printMnemonic(response, mnemonic);
ccprintf(response, " ");
- printSrcReg(response, 0);
- ccprintf(response, ", ");
+ //If the first reg is %g0, don't print it.
+ //This improves readability
+ if(_srcRegIdx[0] != 0)
+ {
+ printSrcReg(response, 0);
+ ccprintf(response, ", ");
+ }
printSrcReg(response, 1);
ccprintf(response, ", %%%s", regName);
@@ -169,8 +174,14 @@ output decoder {{
printMnemonic(response, mnemonic);
ccprintf(response, " ");
- printSrcReg(response, 0);
- ccprintf(response, ", 0x%x, %%%s", imm, regName);
+ //If the first reg is %g0, don't print it.
+ //This improves readability
+ if(_srcRegIdx[0] != 0)
+ {
+ printSrcReg(response, 0);
+ ccprintf(response, ", ");
+ }
+ ccprintf(response, "0x%x, %%%s", imm, regName);
return response.str();
}
diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa
index 2d200f568..80ed7362c 100644
--- a/src/arch/sparc/isa/operands.isa
+++ b/src/arch/sparc/isa/operands.isa
@@ -61,7 +61,7 @@ def operands {{
'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 3),
'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 4),
'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 5),
- 'uReg0': ('IntReg', 'udw', 'NumRegularIntRegs+0', 'IsInteger', 6),
+ 'uReg0': ('IntReg', 'udw', 'NumIntArchRegs', 'IsInteger', 6),
'Frds': ('FloatReg', 'sf', 'RD', 'IsFloating', 10),
'Frd': ('FloatReg', 'df', 'dfpr(RD)', 'IsFloating', 10),
# Each Frd_N refers to the Nth double precision register from Frd.
diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh
index 109fdfae7..2bd7ccf3b 100644
--- a/src/arch/sparc/isa_traits.hh
+++ b/src/arch/sparc/isa_traits.hh
@@ -33,16 +33,9 @@
#define __ARCH_SPARC_ISA_TRAITS_HH__
#include "arch/sparc/types.hh"
-#include "base/misc.hh"
+#include "arch/sparc/sparc_traits.hh"
#include "config/full_system.hh"
-#include "sim/host.hh"
-class ThreadContext;
-class FastCPU;
-//class FullCPU;
-class Checkpoint;
-
-class StaticInst;
class StaticInstPtr;
namespace BigEndianGuest {}
@@ -60,32 +53,12 @@ namespace SparcISA
// SPARC NOP (sethi %(hi(0), g0)
const MachInst NoopMachInst = 0x01000000;
- const int NumRegularIntRegs = 32;
- const int NumMicroIntRegs = 1;
- const int NumIntRegs =
- NumRegularIntRegs +
- NumMicroIntRegs;
- const int NumFloatRegs = 64;
- const int NumMiscRegs = 40;
-
// These enumerate all the registers for dependence tracking.
enum DependenceTags {
- // 0..31 are the integer regs 0..31
- // 32..95 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
- FP_Base_DepTag = NumIntRegs,
- Ctrl_Base_DepTag = NumIntRegs + NumMicroIntRegs + NumFloatRegs,
+ FP_Base_DepTag = 33,
+ Ctrl_Base_DepTag = 97,
};
-
- // MAXTL - maximum trap level
- const int MaxPTL = 2;
- const int MaxTL = 6;
- const int MaxGL = 3;
- const int MaxPGL = 2;
-
- // NWINDOWS - number of register windows, can be 3 to 32
- const int NWindows = 8;
-
// semantically meaningful register indices
const int ZeroReg = 0; // architecturally meaningful
// the rest of these depend on the ABI
@@ -113,24 +86,12 @@ namespace SparcISA
//Why does both the previous set of constants and this one exist?
const int PageShift = 13;
- const int PageBytes = ULL(1) << PageShift;
+ const int PageBytes = 1ULL << PageShift;
const int BranchPredAddrShiftAmt = 2;
- const int MachineBytes = 8;
- const int WordBytes = 4;
- const int HalfwordBytes = 2;
- const int ByteBytes = 1;
-
- void serialize(std::ostream & os);
-
- void unserialize(Checkpoint *cp, const std::string &section);
-
StaticInstPtr decodeInst(ExtMachInst);
- // return a no-op instruction... used for instruction fetch faults
- extern const MachInst NoopMachInst;
-
#if FULL_SYSTEM
////////// Interrupt Stuff ///////////
enum InterruptLevels
diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc
index 93737ad01..d2164155f 100644
--- a/src/arch/sparc/miscregfile.cc
+++ b/src/arch/sparc/miscregfile.cc
@@ -50,7 +50,7 @@ class Checkpoint;
string SparcISA::getMiscRegName(RegIndex index)
{
static::string miscRegName[NumMiscRegs] =
- {"y", "ccr", "asi", "tick", "pc", "fprs", "pcr", "pic",
+ {"y", "ccr", "asi", "tick", "fprs", "pcr", "pic",
"gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
"stick", "stick_cmpr",
"tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
@@ -62,7 +62,12 @@ string SparcISA::getMiscRegName(RegIndex index)
return miscRegName[index];
}
-void MiscRegFile::reset()
+enum RegMask
+{
+ PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
+};
+
+void MiscRegFile::clear()
{
y = 0;
ccr = 0;
@@ -88,12 +93,14 @@ void MiscRegFile::reset()
otherwin = 0;
wstate = 0;
gl = 0;
- hpstate = 0;
+ //In a T1, bit 11 is apparently always 1
+ hpstate = (1 << 11);
memset(htstate, 0, sizeof(htstate));
hintp = 0;
htba = 0;
hstick_cmpr = 0;
- strandStatusReg = 0;
+ //This is set this way in Legion for some reason
+ strandStatusReg = 0x50000;
fsr = 0;
priContext = 0;
@@ -360,7 +367,7 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val)
tba = val & ULL(~0x7FFF);
break;
case MISCREG_PSTATE:
- pstate = val;
+ pstate = (val & PSTATE_MASK);
break;
case MISCREG_TL:
tl = val;
@@ -522,7 +529,7 @@ void MiscRegFile::setRegWithEffect(int miscReg,
//Set up performance counting based on pcr value
break;
case MISCREG_PSTATE:
- pstate = val;
+ pstate = val & PSTATE_MASK;
return;
case MISCREG_TL:
tl = val;
diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh
index 9cfe3a8cf..90d7229e0 100644
--- a/src/arch/sparc/miscregfile.hh
+++ b/src/arch/sparc/miscregfile.hh
@@ -41,7 +41,6 @@
namespace SparcISA
{
-
//These functions map register indices to names
std::string getMiscRegName(RegIndex);
@@ -127,8 +126,12 @@ namespace SparcISA
MISCREG_SCRATCHPAD_R5,
MISCREG_SCRATCHPAD_R6,
MISCREG_SCRATCHPAD_R7
+ MISCREG_NUMMISCREGS
};
+ const int NumMiscArchRegs = MISCREG_NUMMISCREGS;
+ const int NumMiscRegs = MISCREG_NUMMISCREGS;
+
// The control registers, broken out into fields
class MiscRegFile
{
@@ -230,11 +233,11 @@ namespace SparcISA
#endif
public:
- void reset();
+ void clear();
MiscRegFile()
{
- reset();
+ clear();
}
MiscReg readReg(int miscReg);
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 3efe4fc08..405e408e5 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -32,6 +32,7 @@
#include "arch/sparc/asi.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/process.hh"
+#include "arch/sparc/types.hh"
#include "base/loader/object_file.hh"
#include "base/loader/elf_object.hh"
#include "base/misc.hh"
@@ -77,7 +78,7 @@ SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
void
SparcLiveProcess::startup()
{
- argsInit(MachineBytes, VMPageSize);
+ argsInit(sizeof(IntReg), VMPageSize);
//From the SPARC ABI
diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc
index 65e6017da..06ba13423 100644
--- a/src/arch/sparc/regfile.cc
+++ b/src/arch/sparc/regfile.cc
@@ -70,8 +70,9 @@ void RegFile::setNextNPC(Addr val)
void RegFile::clear()
{
- intRegFile.clear();
floatRegFile.clear();
+ intRegFile.clear();
+ miscRegFile.clear();
}
MiscReg RegFile::readMiscReg(int miscReg)
diff --git a/src/arch/sparc/sparc_traits.hh b/src/arch/sparc/sparc_traits.hh
new file mode 100644
index 000000000..a3d29ea8a
--- /dev/null
+++ b/src/arch/sparc/sparc_traits.hh
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_SPARC_SPARC_TRAITS_HH__
+#define __ARCH_SPARC_SPARC_TRAITS_HH__
+
+namespace SparcISA
+{
+ // Max trap levels
+ const int MaxPTL = 2;
+ const int MaxTL = 6;
+ const int MaxGL = 3;
+ const int MaxPGL = 2;
+
+ // Number of register windows, can legally be 3 to 32
+ const int NWindows = 8;
+ const int NumMicroIntRegs = 1;
+
+// const int NumRegularIntRegs = MaxGL * 8 + NWindows * 16;
+// const int NumMicroIntRegs = 1;
+// const int NumIntRegs =
+// NumRegularIntRegs +
+// NumMicroIntRegs;
+// const int NumFloatRegs = 64;
+// const int NumMiscRegs = 40;
+}
+
+#endif // __ARCH_SPARC_ISA_TRAITS_HH__
diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc
index 4e907f002..72c87f0ad 100644
--- a/src/arch/sparc/system.cc
+++ b/src/arch/sparc/system.cc
@@ -42,18 +42,35 @@
using namespace BigEndianGuest;
SparcSystem::SparcSystem(Params *p)
- : System(p), sysTick(0),funcRomPort(p->name + "-fport")
-
+ : System(p), sysTick(0),funcRomPort(p->name + "-fromport"),
+ funcNvramPort(p->name + "-fnvramport"),
+ funcHypDescPort(p->name + "-fhypdescport"),
+ funcPartDescPort(p->name + "-fpartdescport")
{
resetSymtab = new SymbolTable;
hypervisorSymtab = new SymbolTable;
openbootSymtab = new SymbolTable;
+ nvramSymtab = new SymbolTable;
+ hypervisorDescSymtab = new SymbolTable;
+ partitionDescSymtab = new SymbolTable;
Port *rom_port;
rom_port = params()->rom->getPort("functional");
funcRomPort.setPeer(rom_port);
rom_port->setPeer(&funcRomPort);
+ rom_port = params()->nvram->getPort("functional");
+ funcNvramPort.setPeer(rom_port);
+ rom_port->setPeer(&funcNvramPort);
+
+ rom_port = params()->hypervisor_desc->getPort("functional");
+ funcHypDescPort.setPeer(rom_port);
+ rom_port->setPeer(&funcHypDescPort);
+
+ rom_port = params()->partition_desc->getPort("functional");
+ funcPartDescPort.setPeer(rom_port);
+ rom_port->setPeer(&funcPartDescPort);
+
/**
* Load the boot code, and hypervisor into memory.
*/
@@ -72,6 +89,23 @@ SparcSystem::SparcSystem(Params *p)
if (hypervisor == NULL)
fatal("Could not load hypervisor binary %s", params()->hypervisor_bin);
+ // Read the nvram image
+ nvram = createObjectFile(params()->nvram_bin, true);
+ if (nvram == NULL)
+ fatal("Could not load nvram image %s", params()->nvram_bin);
+
+ // Read the hypervisor description image
+ hypervisor_desc = createObjectFile(params()->hypervisor_desc_bin, true);
+ if (hypervisor_desc == NULL)
+ fatal("Could not load hypervisor description image %s",
+ params()->hypervisor_desc_bin);
+
+ // Read the partition description image
+ partition_desc = createObjectFile(params()->partition_desc_bin, true);
+ if (partition_desc == NULL)
+ fatal("Could not load partition description image %s",
+ params()->partition_desc_bin);
+
// Load reset binary into memory
reset->setTextBase(params()->reset_addr);
@@ -82,6 +116,15 @@ SparcSystem::SparcSystem(Params *p)
// Load the hypervisor binary
hypervisor->setTextBase(params()->hypervisor_addr);
hypervisor->loadSections(&funcRomPort);
+ // Load the nvram image
+ nvram->setTextBase(params()->nvram_addr);
+ nvram->loadSections(&funcNvramPort);
+ // Load the hypervisor description image
+ hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
+ hypervisor_desc->loadSections(&funcHypDescPort);
+ // Load the partition description image
+ partition_desc->setTextBase(params()->partition_desc_addr);
+ partition_desc->loadSections(&funcPartDescPort);
// load symbols
if (!reset->loadGlobalSymbols(resetSymtab))
@@ -93,6 +136,15 @@ SparcSystem::SparcSystem(Params *p)
if (!hypervisor->loadLocalSymbols(hypervisorSymtab))
panic("could not load hypervisor symbols\n");
+ if (!nvram->loadLocalSymbols(nvramSymtab))
+ panic("could not load nvram symbols\n");
+
+ if (!hypervisor_desc->loadLocalSymbols(hypervisorDescSymtab))
+ panic("could not load hypervisor description symbols\n");
+
+ if (!partition_desc->loadLocalSymbols(partitionDescSymtab))
+ panic("could not load partition description symbols\n");
+
// load symbols into debug table
if (!reset->loadGlobalSymbols(debugSymbolTable))
panic("could not load reset symbols\n");
@@ -103,6 +155,15 @@ SparcSystem::SparcSystem(Params *p)
if (!hypervisor->loadLocalSymbols(debugSymbolTable))
panic("could not load hypervisor symbols\n");
+ if (!nvram->loadGlobalSymbols(debugSymbolTable))
+ panic("could not load reset symbols\n");
+
+ if (!hypervisor_desc->loadGlobalSymbols(debugSymbolTable))
+ panic("could not load hypervisor description symbols\n");
+
+ if (!partition_desc->loadLocalSymbols(debugSymbolTable))
+ panic("could not load partition description symbols\n");
+
// @todo any fixup code over writing data in binaries on setting break
// events on functions should happen here.
@@ -114,9 +175,15 @@ SparcSystem::~SparcSystem()
delete resetSymtab;
delete hypervisorSymtab;
delete openbootSymtab;
+ delete nvramSymtab;
+ delete hypervisorDescSymtab;
+ delete partitionDescSymtab;
delete reset;
delete openboot;
delete hypervisor;
+ delete nvram;
+ delete hypervisor_desc;
+ delete partition_desc;
}
bool
@@ -132,6 +199,9 @@ SparcSystem::serialize(std::ostream &os)
resetSymtab->serialize("reset_symtab", os);
hypervisorSymtab->serialize("hypervisor_symtab", os);
openbootSymtab->serialize("openboot_symtab", os);
+ nvramSymtab->serialize("nvram_symtab", os);
+ hypervisorDescSymtab->serialize("hypervisor_desc_symtab", os);
+ partitionDescSymtab->serialize("partition_desc_symtab", os);
}
@@ -142,6 +212,9 @@ SparcSystem::unserialize(Checkpoint *cp, const std::string &section)
resetSymtab->unserialize("reset_symtab", cp, section);
hypervisorSymtab->unserialize("hypervisor_symtab", cp, section);
openbootSymtab->unserialize("openboot_symtab", cp, section);
+ nvramSymtab->unserialize("nvram_symtab", cp, section);
+ hypervisorDescSymtab->unserialize("hypervisor_desc_symtab", cp, section);
+ partitionDescSymtab->unserialize("partition_desc_symtab", cp, section);
}
@@ -149,16 +222,25 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SparcSystem)
SimObjectParam<PhysicalMemory *> physmem;
SimObjectParam<PhysicalMemory *> rom;
+ SimObjectParam<PhysicalMemory *> nvram;
+ SimObjectParam<PhysicalMemory *> hypervisor_desc;
+ SimObjectParam<PhysicalMemory *> partition_desc;
SimpleEnumParam<System::MemoryMode> mem_mode;
Param<Addr> reset_addr;
Param<Addr> hypervisor_addr;
Param<Addr> openboot_addr;
+ Param<Addr> nvram_addr;
+ Param<Addr> hypervisor_desc_addr;
+ Param<Addr> partition_desc_addr;
Param<std::string> kernel;
Param<std::string> reset_bin;
Param<std::string> hypervisor_bin;
Param<std::string> openboot_bin;
+ Param<std::string> nvram_bin;
+ Param<std::string> hypervisor_desc_bin;
+ Param<std::string> partition_desc_bin;
Param<Tick> boot_cpu_frequency;
Param<std::string> boot_osflags;
@@ -171,17 +253,30 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SparcSystem)
INIT_PARAM(physmem, "phsyical memory"),
INIT_PARAM(rom, "ROM for boot code"),
+ INIT_PARAM(nvram, "Non-volatile RAM for the nvram"),
+ INIT_PARAM(hypervisor_desc, "ROM for the hypervisor description"),
+ INIT_PARAM(partition_desc, "ROM for the partition description"),
INIT_ENUM_PARAM(mem_mode, "Memory Mode, (1=atomic, 2=timing)",
System::MemoryModeStrings),
INIT_PARAM(reset_addr, "Address that reset should be loaded at"),
INIT_PARAM(hypervisor_addr, "Address that hypervisor should be loaded at"),
INIT_PARAM(openboot_addr, "Address that openboot should be loaded at"),
+ INIT_PARAM(nvram_addr, "Address that nvram should be loaded at"),
+ INIT_PARAM(hypervisor_desc_addr,
+ "Address that hypervisor description should be loaded at"),
+ INIT_PARAM(partition_desc_addr,
+ "Address that partition description should be loaded at"),
INIT_PARAM(kernel, "file that contains the kernel code"),
INIT_PARAM(reset_bin, "file that contains the reset code"),
INIT_PARAM(hypervisor_bin, "file that contains the hypervisor code"),
INIT_PARAM(openboot_bin, "file that contains the openboot code"),
+ INIT_PARAM(nvram_bin, "file that contains the nvram image"),
+ INIT_PARAM(hypervisor_desc_bin,
+ "file that contains the hypervisor description image"),
+ INIT_PARAM(partition_desc_bin,
+ "file that contains the partition description image"),
INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
"a"),
@@ -197,14 +292,23 @@ CREATE_SIM_OBJECT(SparcSystem)
p->boot_cpu_frequency = boot_cpu_frequency;
p->physmem = physmem;
p->rom = rom;
+ p->nvram = nvram;
+ p->hypervisor_desc = hypervisor_desc;
+ p->partition_desc = partition_desc;
p->mem_mode = mem_mode;
p->kernel_path = kernel;
p->reset_addr = reset_addr;
p->hypervisor_addr = hypervisor_addr;
p->openboot_addr = openboot_addr;
+ p->nvram_addr = nvram_addr;
+ p->hypervisor_desc_addr = hypervisor_desc_addr;
+ p->partition_desc_addr = partition_desc_addr;
p->reset_bin = reset_bin;
p->hypervisor_bin = hypervisor_bin;
p->openboot_bin = openboot_bin;
+ p->nvram_bin = nvram_bin;
+ p->hypervisor_desc_bin = hypervisor_desc_bin;
+ p->partition_desc_bin = partition_desc_bin;
p->boot_osflags = boot_osflags;
p->init_param = init_param;
p->readfile = readfile;
diff --git a/src/arch/sparc/system.hh b/src/arch/sparc/system.hh
index 9cf3bb568..5d50ea067 100644
--- a/src/arch/sparc/system.hh
+++ b/src/arch/sparc/system.hh
@@ -46,12 +46,21 @@ class SparcSystem : public System
struct Params : public System::Params
{
PhysicalMemory *rom;
+ PhysicalMemory *nvram;
+ PhysicalMemory *hypervisor_desc;
+ PhysicalMemory *partition_desc;
Addr reset_addr;
Addr hypervisor_addr;
Addr openboot_addr;
+ Addr nvram_addr;
+ Addr hypervisor_desc_addr;
+ Addr partition_desc_addr;
std::string reset_bin;
std::string hypervisor_bin;
std::string openboot_bin;
+ std::string nvram_bin;
+ std::string hypervisor_desc_bin;
+ std::string partition_desc_bin;
std::string boot_osflags;
};
@@ -77,6 +86,15 @@ class SparcSystem : public System
/** openboot symbol table */
SymbolTable *openbootSymtab;
+ /** nvram symbol table? */
+ SymbolTable *nvramSymtab;
+
+ /** hypervisor desc symbol table? */
+ SymbolTable *hypervisorDescSymtab;
+
+ /** partition desc symbol table? */
+ SymbolTable *partitionDescSymtab;
+
/** Object pointer for the reset binary */
ObjectFile *reset;
@@ -86,12 +104,30 @@ class SparcSystem : public System
/** Object pointer for the openboot code */
ObjectFile *openboot;
+ /** Object pointer for the nvram image */
+ ObjectFile *nvram;
+
+ /** Object pointer for the hypervisor description image */
+ ObjectFile *hypervisor_desc;
+
+ /** Object pointer for the partition description image */
+ ObjectFile *partition_desc;
+
/** System Tick for syncronized tick across all cpus. */
Tick sysTick;
/** functional port to ROM */
FunctionalPort funcRomPort;
+ /** functional port to nvram */
+ FunctionalPort funcNvramPort;
+
+ /** functional port to hypervisor description */
+ FunctionalPort funcHypDescPort;
+
+ /** functional port to partition description */
+ FunctionalPort funcPartDescPort;
+
protected:
const Params *params() const { return (const Params *)_params; }
diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc
index 113f0fe74..f3b9b51b2 100644
--- a/src/cpu/exetrace.cc
+++ b/src/cpu/exetrace.cc
@@ -66,6 +66,56 @@ SharedData *shared_data = NULL;
// Methods for the InstRecord object
//
+#if THE_ISA == SPARC_ISA
+
+inline char * genCenteredLabel(int length, char * buffer, char * label)
+{
+ int labelLength = strlen(label);
+ assert(labelLength <= length);
+ int leftPad = (length - labelLength) / 2;
+ int rightPad = length - leftPad - labelLength;
+ char format[64];
+ sprintf(format, "%%%ds%%s%%%ds", leftPad, rightPad);
+ sprintf(buffer, format, "", label, "");
+ return buffer;
+}
+
+inline void printRegPair(ostream & os, char const * title, uint64_t a, uint64_t b)
+{
+ ccprintf(os, " %16s | %#018x %s %#-018x \n",
+ title, a, (a == b) ? "|" : "X", b);
+}
+
+inline void printColumnLabels(ostream & os)
+{
+ static char * regLabel = genCenteredLabel(16, new char[17], "Register");
+ static char * m5Label = genCenteredLabel(18, new char[18], "M5");
+ static char * legionLabel = genCenteredLabel(18, new char[18], "Legion");
+ ccprintf(os, " %s | %s | %s \n", regLabel, m5Label, legionLabel);
+ ccprintf(os, "--------------------+-----------------------+-----------------------\n");
+}
+
+inline void printSectionHeader(ostream & os, char * name)
+{
+ char sectionString[70];
+ genCenteredLabel(69, sectionString, name);
+ ccprintf(os, "====================================================================\n");
+ ccprintf(os, "%69s\n", sectionString);
+ ccprintf(os, "====================================================================\n");
+}
+
+inline void printLevelHeader(ostream & os, int level)
+{
+ char sectionString[70];
+ char levelName[70];
+ sprintf(levelName, "Trap stack level %d", level);
+ genCenteredLabel(69, sectionString, levelName);
+ ccprintf(os, "====================================================================\n");
+ ccprintf(os, "%69s\n", sectionString);
+ ccprintf(os, "====================================================================\n");
+}
+
+#endif
void
Trace::InstRecord::dump(ostream &outs)
@@ -237,25 +287,110 @@ Trace::InstRecord::dump(ostream &outs)
bool diffPC = false;
bool diffInst = false;
bool diffRegs = false;
+ bool diffTpc = false;
+ bool diffTnpc = false;
+ bool diffTstate = false;
+ bool diffTt = false;
+ bool diffTba = false;
+ bool diffHpstate = false;
+ bool diffHtstate = false;
+ bool diffHtba = false;
+ bool diffPstate = false;
+ bool diffY = false;
+ bool diffCcr = false;
+ bool diffTl = false;
+ bool diffGl = false;
+ bool diffAsi = false;
+ bool diffPil = false;
+ bool diffCwp = false;
+ bool diffCansave = false;
+ bool diffCanrestore = false;
+ bool diffOtherwin = false;
+ bool diffCleanwin = false;
Addr m5Pc, lgnPc;
if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) {
while (!compared) {
- m5Pc = PC & TheISA::PAddrImplMask;
- lgnPc = shared_data->pc & TheISA::PAddrImplMask;
if (shared_data->flags == OWN_M5) {
+ m5Pc = PC & TheISA::PAddrImplMask;
+ lgnPc = shared_data->pc & TheISA::PAddrImplMask;
if (lgnPc != m5Pc)
diffPC = true;
- if (shared_data->instruction != staticInst->machInst)
+ if (shared_data->instruction !=
+ (SparcISA::MachInst)staticInst->machInst) {
diffInst = true;
- for (int i = 0; i < TheISA::NumRegularIntRegs; i++) {
+ }
+ for (int i = 0; i < TheISA::NumIntArchRegs; i++) {
if (thread->readIntReg(i) != shared_data->intregs[i]) {
diffRegs = true;
}
}
-
- if (diffPC || diffInst || diffRegs ) {
+ uint64_t oldTl = thread->readMiscReg(MISCREG_TL);
+ if (oldTl != shared_data->tl)
+ diffTl = true;
+ for (int i = 1; i <= MaxTL; i++) {
+ thread->setMiscReg(MISCREG_TL, i);
+ if (thread->readMiscReg(MISCREG_TPC) !=
+ shared_data->tpc[i])
+ diffTpc = true;
+ if (thread->readMiscReg(MISCREG_TNPC) !=
+ shared_data->tnpc[i])
+ diffTnpc = true;
+ if (thread->readMiscReg(MISCREG_TSTATE) !=
+ shared_data->tstate[i])
+ diffTstate = true;
+ if (thread->readMiscReg(MISCREG_TT) !=
+ shared_data->tt[i])
+ diffTt = true;
+ if (thread->readMiscReg(MISCREG_HTSTATE) !=
+ shared_data->htstate[i])
+ diffHtstate = true;
+ }
+ thread->setMiscReg(MISCREG_TL, oldTl);
+
+ if(shared_data->tba != thread->readMiscReg(MISCREG_TBA))
+ diffTba = true;
+ //When the hpstate register is read by an instruction,
+ //legion has bit 11 set. When it's in storage, it doesn't.
+ //Since we don't directly support seperate interpretations
+ //of the registers like that, the bit is always set to 1 and
+ //we just don't compare it. It's not supposed to matter
+ //anyway.
+ if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE))
+ diffHpstate = true;
+ if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA))
+ diffHtba = true;
+ if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE))
+ diffPstate = true;
+ if(shared_data->y != thread->readMiscReg(MISCREG_Y))
+ diffY = true;
+ if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
+ diffCcr = true;
+ if(shared_data->gl != thread->readMiscReg(MISCREG_GL))
+ diffGl = true;
+ if(shared_data->asi != thread->readMiscReg(MISCREG_ASI))
+ diffAsi = true;
+ if(shared_data->pil != thread->readMiscReg(MISCREG_PIL))
+ diffPil = true;
+ if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP))
+ diffCwp = true;
+ if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
+ diffCansave = true;
+ if(shared_data->canrestore !=
+ thread->readMiscReg(MISCREG_CANRESTORE))
+ diffCanrestore = true;
+ if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
+ diffOtherwin = true;
+ if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
+ diffCleanwin = true;
+
+ if (diffPC || diffInst || diffRegs || diffTpc || diffTnpc ||
+ diffTstate || diffTt || diffHpstate ||
+ diffHtstate || diffHtba || diffPstate || diffY ||
+ diffCcr || diffTl || diffGl || diffAsi || diffPil ||
+ diffCwp || diffCansave || diffCanrestore ||
+ diffOtherwin || diffCleanwin) {
outs << "Differences found between M5 and Legion:";
if (diffPC)
outs << " [PC]";
@@ -263,6 +398,44 @@ Trace::InstRecord::dump(ostream &outs)
outs << " [Instruction]";
if (diffRegs)
outs << " [IntRegs]";
+ if (diffTpc)
+ outs << " [Tpc]";
+ if (diffTnpc)
+ outs << " [Tnpc]";
+ if (diffTstate)
+ outs << " [Tstate]";
+ if (diffTt)
+ outs << " [Tt]";
+ if (diffHpstate)
+ outs << " [Hpstate]";
+ if (diffHtstate)
+ outs << " [Htstate]";
+ if (diffHtba)
+ outs << " [Htba]";
+ if (diffPstate)
+ outs << " [Pstate]";
+ if (diffY)
+ outs << " [Y]";
+ if (diffCcr)
+ outs << " [Ccr]";
+ if (diffTl)
+ outs << " [Tl]";
+ if (diffGl)
+ outs << " [Gl]";
+ if (diffAsi)
+ outs << " [Asi]";
+ if (diffPil)
+ outs << " [Pil]";
+ if (diffCwp)
+ outs << " [Cwp]";
+ if (diffCansave)
+ outs << " [Cansave]";
+ if (diffCanrestore)
+ outs << " [Canrestore]";
+ if (diffOtherwin)
+ outs << " [Otherwin]";
+ if (diffCleanwin)
+ outs << " [Cleanwin]";
outs << endl << endl;
outs << right << setfill(' ') << setw(15)
@@ -278,29 +451,106 @@ Trace::InstRecord::dump(ostream &outs)
<< staticInst->disassemble(m5Pc, debugSymbolTable)
<< endl;
- StaticInstPtr legionInst = StaticInst::decode(makeExtMI(shared_data->instruction, thread));
+ StaticInstPtr legionInst =
+ StaticInst::decode(makeExtMI(shared_data->instruction,
+ thread));
outs << setfill(' ') << setw(15)
<< " Legion Inst: "
<< "0x" << setw(8) << setfill('0') << hex
<< shared_data->instruction
<< legionInst->disassemble(lgnPc, debugSymbolTable)
- << endl;
-
+ << endl << endl;
+
+ printSectionHeader(outs, "General State");
+ printColumnLabels(outs);
+ printRegPair(outs, "HPstate",
+ thread->readMiscReg(MISCREG_HPSTATE),
+ shared_data->hpstate | (1 << 11));
+ printRegPair(outs, "Htba",
+ thread->readMiscReg(MISCREG_HTBA),
+ shared_data->htba);
+ printRegPair(outs, "Pstate",
+ thread->readMiscReg(MISCREG_PSTATE),
+ shared_data->pstate);
+ printRegPair(outs, "Y",
+ thread->readMiscReg(MISCREG_Y),
+ shared_data->y);
+ printRegPair(outs, "Ccr",
+ thread->readMiscReg(MISCREG_CCR),
+ shared_data->ccr);
+ printRegPair(outs, "Tl",
+ thread->readMiscReg(MISCREG_TL),
+ shared_data->tl);
+ printRegPair(outs, "Gl",
+ thread->readMiscReg(MISCREG_GL),
+ shared_data->gl);
+ printRegPair(outs, "Asi",
+ thread->readMiscReg(MISCREG_ASI),
+ shared_data->asi);
+ printRegPair(outs, "Pil",
+ thread->readMiscReg(MISCREG_PIL),
+ shared_data->pil);
+ printRegPair(outs, "Cwp",
+ thread->readMiscReg(MISCREG_CWP),
+ shared_data->cwp);
+ printRegPair(outs, "Cansave",
+ thread->readMiscReg(MISCREG_CANSAVE),
+ shared_data->cansave);
+ printRegPair(outs, "Canrestore",
+ thread->readMiscReg(MISCREG_CANRESTORE),
+ shared_data->canrestore);
+ printRegPair(outs, "Otherwin",
+ thread->readMiscReg(MISCREG_OTHERWIN),
+ shared_data->otherwin);
+ printRegPair(outs, "Cleanwin",
+ thread->readMiscReg(MISCREG_CLEANWIN),
+ shared_data->cleanwin);
+ outs << endl;
+ for (int i = 1; i <= MaxTL; i++) {
+ printLevelHeader(outs, i);
+ printColumnLabels(outs);
+ thread->setMiscReg(MISCREG_TL, i);
+ printRegPair(outs, "Tpc",
+ thread->readMiscReg(MISCREG_TPC),
+ shared_data->tpc[i]);
+ printRegPair(outs, "Tnpc",
+ thread->readMiscReg(MISCREG_TNPC),
+ shared_data->tnpc[i]);
+ printRegPair(outs, "Tstate",
+ thread->readMiscReg(MISCREG_TSTATE),
+ shared_data->tstate[i]);
+ printRegPair(outs, "Tt",
+ thread->readMiscReg(MISCREG_TT),
+ shared_data->tt[i]);
+ printRegPair(outs, "Htstate",
+ thread->readMiscReg(MISCREG_HTSTATE),
+ shared_data->htstate[i]);
+ }
+ thread->setMiscReg(MISCREG_TL, oldTl);
outs << endl;
+ printSectionHeader(outs, "General Purpose Registers");
static const char * regtypes[4] = {"%g", "%o", "%l", "%i"};
for(int y = 0; y < 4; y++)
{
for(int x = 0; x < 8; x++)
{
- outs << regtypes[y] << x << " " ;
- outs << "0x" << hex << setw(16) << thread->readIntReg(y*8+x);
- if (thread->readIntReg(y*8 + x) != shared_data->intregs[y*8+x])
+ char label[8];
+ sprintf(label, "%s%d", regtypes[y], x);
+ printRegPair(outs, label,
+ thread->readIntReg(y*8+x),
+ shared_data->intregs[y*8+x]);
+ /*outs << regtypes[y] << x << " " ;
+ outs << "0x" << hex << setw(16)
+ << thread->readIntReg(y*8+x);
+ if (thread->readIntReg(y*8 + x)
+ != shared_data->intregs[y*8+x])
outs << " X ";
else
outs << " | ";
- outs << "0x" << setw(16) << hex << shared_data->intregs[y*8+x]
- << endl;
+ outs << "0x" << setw(16) << hex
+ << shared_data->intregs[y*8+x]
+ << endl;*/
}
}
fatal("Differences found between Legion and M5\n");
diff --git a/src/cpu/o3/isa_specific.hh b/src/cpu/o3/isa_specific.hh
index 4937589e3..72a8d4021 100755
--- a/src/cpu/o3/isa_specific.hh
+++ b/src/cpu/o3/isa_specific.hh
@@ -40,6 +40,11 @@
#include "cpu/o3/mips/impl.hh"
#include "cpu/o3/mips/params.hh"
#include "cpu/o3/mips/dyn_inst.hh"
+#elif THE_ISA == SPARC_ISA
+ #include "cpu/o3/sparc/cpu.hh"
+ #include "cpu/o3/sparc/impl.hh"
+ #include "cpu/o3/sparc/params.hh"
+ #include "cpu/o3/sparc/dyn_inst.hh"
#else
#error "ISA-specific header files O3CPU not defined ISA"
#endif
diff --git a/src/cpu/o3/sparc/cpu.cc b/src/cpu/o3/sparc/cpu.cc
new file mode 100644
index 000000000..1546a2b88
--- /dev/null
+++ b/src/cpu/o3/sparc/cpu.cc
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "cpu/o3/sparc/impl.hh"
+#include "cpu/o3/sparc/cpu_impl.hh"
+#include "cpu/o3/sparc/dyn_inst.hh"
+
+// Force instantiation of SparcO3CPU for all the implementations that are
+// needed. Consider merging this and sparc_dyn_inst.cc, and maybe all
+// classes that depend on a certain impl, into one file (sparc_impl.cc?).
+template class SparcO3CPU<SparcSimpleImpl>;
diff --git a/src/cpu/o3/sparc/cpu.hh b/src/cpu/o3/sparc/cpu.hh
new file mode 100644
index 000000000..c4df79832
--- /dev/null
+++ b/src/cpu/o3/sparc/cpu.hh
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2004-2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Kevin Lim
+ */
+
+#ifndef __CPU_O3_SPARC_CPU_HH__
+#define __CPU_O3_SPARC_CPU_HH__
+
+#include "arch/sparc/regfile.hh"
+#include "arch/sparc/types.hh"
+#include "cpu/thread_context.hh"
+#include "cpu/o3/cpu.hh"
+#include "sim/byteswap.hh"
+
+namespace TheISA
+{
+ class ITB;
+ class DTB;
+}
+
+class EndQuiesceEvent;
+namespace Kernel {
+ class Statistics;
+};
+
+class TranslatingPort;
+
+/**
+ * SparcO3CPU class. Derives from the FullO3CPU class, and
+ * implements all ISA and implementation specific functions of the
+ * CPU. This is the CPU class that is used for the SimObjects, and is
+ * what is given to the DynInsts. Most of its state exists in the
+ * FullO3CPU; the state is has is mainly for ISA specific
+ * functionality.
+ */
+template <class Impl>
+class SparcO3CPU : public FullO3CPU<Impl>
+{
+ protected:
+ typedef TheISA::IntReg IntReg;
+ typedef TheISA::FloatReg FloatReg;
+ typedef TheISA::FloatRegBits FloatRegBits;
+ typedef TheISA::MiscReg MiscReg;
+ typedef TheISA::RegFile RegFile;
+ typedef TheISA::MiscRegFile MiscRegFile;
+
+ public:
+ typedef O3ThreadState<Impl> ImplState;
+ typedef O3ThreadState<Impl> Thread;
+ typedef typename Impl::Params Params;
+
+ /** Constructs an AlphaO3CPU with the given parameters. */
+ SparcO3CPU(Params *params);
+
+#if FULL_SYSTEM
+ /** ITB pointer. */
+ SparcISA::ITB *itb;
+ /** DTB pointer. */
+ SparcISA::DTB *dtb;
+#endif
+
+ /** Registers statistics. */
+ void regStats();
+
+#if FULL_SYSTEM
+ /** Translates instruction requestion. */
+ Fault translateInstReq(RequestPtr &req, Thread *thread)
+ {
+ return itb->translate(req, thread->getTC());
+ }
+
+ /** Translates data read request. */
+ Fault translateDataReadReq(RequestPtr &req, Thread *thread)
+ {
+ return dtb->translate(req, thread->getTC(), false);
+ }
+
+ /** Translates data write request. */
+ Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
+ {
+ return dtb->translate(req, thread->getTC(), true);
+ }
+
+#else
+ /** Translates instruction requestion in syscall emulation mode. */
+ Fault translateInstReq(RequestPtr &req, Thread *thread)
+ {
+ return thread->getProcessPtr()->pTable->translate(req);
+ }
+
+ /** Translates data read request in syscall emulation mode. */
+ Fault translateDataReadReq(RequestPtr &req, Thread *thread)
+ {
+ return thread->getProcessPtr()->pTable->translate(req);
+ }
+
+ /** Translates data write request in syscall emulation mode. */
+ Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
+ {
+ return thread->getProcessPtr()->pTable->translate(req);
+ }
+
+#endif
+ /** Reads a miscellaneous register. */
+ MiscReg readMiscReg(int misc_reg, unsigned tid);
+
+ /** Reads a misc. register, including any side effects the read
+ * might have as defined by the architecture.
+ */
+ MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid);
+
+ /** Sets a miscellaneous register. */
+ void setMiscReg(int misc_reg, const MiscReg &val, unsigned tid);
+
+ /** Sets a misc. register, including any side effects the write
+ * might have as defined by the architecture.
+ */
+ void setMiscRegWithEffect(int misc_reg, const MiscReg &val, unsigned tid);
+
+ /** Initiates a squash of all in-flight instructions for a given
+ * thread. The source of the squash is an external update of
+ * state through the TC.
+ */
+ void squashFromTC(unsigned tid);
+
+#if FULL_SYSTEM
+ /** Posts an interrupt. */
+ void post_interrupt(int int_num, int index);
+ /** HW return from error interrupt. */
+ Fault hwrei(unsigned tid);
+
+ bool simPalCheck(int palFunc, unsigned tid);
+
+ /** Returns the Fault for any valid interrupt. */
+ Fault getInterrupts();
+
+ /** Processes any an interrupt fault. */
+ void processInterrupts(Fault interrupt);
+
+ /** Halts the CPU. */
+ void halt() { panic("Halt not implemented!\n"); }
+#endif
+
+ /** Traps to handle given fault. */
+ void trap(Fault fault, unsigned tid);
+
+#if !FULL_SYSTEM
+ /** Executes a syscall.
+ * @todo: Determine if this needs to be virtual.
+ */
+ void syscall(int64_t callnum, int tid);
+ /** Gets a syscall argument. */
+ IntReg getSyscallArg(int i, int tid);
+
+ /** Used to shift args for indirect syscall. */
+ void setSyscallArg(int i, IntReg val, int tid);
+
+ /** Sets the return value of a syscall. */
+ void setSyscallReturn(SyscallReturn return_value, int tid);
+#endif
+
+ /** CPU read function, forwards read to LSQ. */
+ template <class T>
+ Fault read(RequestPtr &req, T &data, int load_idx)
+ {
+ return this->iew.ldstQueue.read(req, data, load_idx);
+ }
+
+ /** CPU write function, forwards write to LSQ. */
+ template <class T>
+ Fault write(RequestPtr &req, T &data, int store_idx)
+ {
+ return this->iew.ldstQueue.write(req, data, store_idx);
+ }
+
+ Addr lockAddr;
+
+ /** Temporary fix for the lock flag, works in the UP case. */
+ bool lockFlag;
+};
+
+#endif // __CPU_O3_ALPHA_CPU_HH__
diff --git a/src/cpu/o3/sparc/cpu_builder.cc b/src/cpu/o3/sparc/cpu_builder.cc
new file mode 100644
index 000000000..81f419ee0
--- /dev/null
+++ b/src/cpu/o3/sparc/cpu_builder.cc
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 2004-2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include <string>
+
+#include "cpu/base.hh"
+#include "cpu/o3/sparc/cpu.hh"
+#include "cpu/o3/sparc/impl.hh"
+#include "cpu/o3/sparc/params.hh"
+#include "cpu/o3/fu_pool.hh"
+#include "sim/builder.hh"
+
+class DerivO3CPU : public SparcO3CPU<SparcSimpleImpl>
+{
+ public:
+ DerivO3CPU(SparcSimpleParams *p)
+ : SparcO3CPU<SparcSimpleImpl>(p)
+ { }
+};
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(DerivO3CPU)
+
+ Param<int> clock;
+ Param<int> phase;
+ Param<int> numThreads;
+ Param<int> activity;
+
+#if FULL_SYSTEM
+ SimObjectParam<System *> system;
+ Param<int> cpu_id;
+ SimObjectParam<AlphaISA::ITB *> itb;
+ SimObjectParam<AlphaISA::DTB *> dtb;
+ Param<Tick> profile;
+
+ Param<bool> do_quiesce;
+ Param<bool> do_checkpoint_insts;
+ Param<bool> do_statistics_insts;
+#else
+ SimObjectVectorParam<Process *> workload;
+#endif // FULL_SYSTEM
+
+ SimObjectParam<BaseCPU *> checker;
+
+ Param<Counter> max_insts_any_thread;
+ Param<Counter> max_insts_all_threads;
+ Param<Counter> max_loads_any_thread;
+ Param<Counter> max_loads_all_threads;
+ Param<Tick> progress_interval;
+
+ Param<unsigned> cachePorts;
+
+ Param<unsigned> decodeToFetchDelay;
+ Param<unsigned> renameToFetchDelay;
+ Param<unsigned> iewToFetchDelay;
+ Param<unsigned> commitToFetchDelay;
+ Param<unsigned> fetchWidth;
+
+ Param<unsigned> renameToDecodeDelay;
+ Param<unsigned> iewToDecodeDelay;
+ Param<unsigned> commitToDecodeDelay;
+ Param<unsigned> fetchToDecodeDelay;
+ Param<unsigned> decodeWidth;
+
+ Param<unsigned> iewToRenameDelay;
+ Param<unsigned> commitToRenameDelay;
+ Param<unsigned> decodeToRenameDelay;
+ Param<unsigned> renameWidth;
+
+ Param<unsigned> commitToIEWDelay;
+ Param<unsigned> renameToIEWDelay;
+ Param<unsigned> issueToExecuteDelay;
+ Param<unsigned> dispatchWidth;
+ Param<unsigned> issueWidth;
+ Param<unsigned> wbWidth;
+ Param<unsigned> wbDepth;
+ SimObjectParam<FUPool *> fuPool;
+
+ Param<unsigned> iewToCommitDelay;
+ Param<unsigned> renameToROBDelay;
+ Param<unsigned> commitWidth;
+ Param<unsigned> squashWidth;
+ Param<Tick> trapLatency;
+
+ Param<unsigned> backComSize;
+ Param<unsigned> forwardComSize;
+
+ Param<std::string> predType;
+ Param<unsigned> localPredictorSize;
+ Param<unsigned> localCtrBits;
+ Param<unsigned> localHistoryTableSize;
+ Param<unsigned> localHistoryBits;
+ Param<unsigned> globalPredictorSize;
+ Param<unsigned> globalCtrBits;
+ Param<unsigned> globalHistoryBits;
+ Param<unsigned> choicePredictorSize;
+ Param<unsigned> choiceCtrBits;
+
+ Param<unsigned> BTBEntries;
+ Param<unsigned> BTBTagSize;
+
+ Param<unsigned> RASSize;
+
+ Param<unsigned> LQEntries;
+ Param<unsigned> SQEntries;
+ Param<unsigned> LFSTSize;
+ Param<unsigned> SSITSize;
+
+ Param<unsigned> numPhysIntRegs;
+ Param<unsigned> numPhysFloatRegs;
+ Param<unsigned> numIQEntries;
+ Param<unsigned> numROBEntries;
+
+ Param<unsigned> smtNumFetchingThreads;
+ Param<std::string> smtFetchPolicy;
+ Param<std::string> smtLSQPolicy;
+ Param<unsigned> smtLSQThreshold;
+ Param<std::string> smtIQPolicy;
+ Param<unsigned> smtIQThreshold;
+ Param<std::string> smtROBPolicy;
+ Param<unsigned> smtROBThreshold;
+ Param<std::string> smtCommitPolicy;
+
+ Param<unsigned> instShiftAmt;
+
+ Param<bool> defer_registration;
+
+ Param<bool> function_trace;
+ Param<Tick> function_trace_start;
+
+END_DECLARE_SIM_OBJECT_PARAMS(DerivO3CPU)
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(DerivO3CPU)
+
+ INIT_PARAM(clock, "clock speed"),
+ INIT_PARAM_DFLT(phase, "clock phase", 0),
+ INIT_PARAM(numThreads, "number of HW thread contexts"),
+ INIT_PARAM_DFLT(activity, "Initial activity count", 0),
+
+#if FULL_SYSTEM
+ INIT_PARAM(system, "System object"),
+ INIT_PARAM(cpu_id, "processor ID"),
+ INIT_PARAM(itb, "Instruction translation buffer"),
+ INIT_PARAM(dtb, "Data translation buffer"),
+ INIT_PARAM(profile, ""),
+
+ INIT_PARAM(do_quiesce, ""),
+ INIT_PARAM(do_checkpoint_insts, ""),
+ INIT_PARAM(do_statistics_insts, ""),
+#else
+ INIT_PARAM(workload, "Processes to run"),
+#endif // FULL_SYSTEM
+
+ INIT_PARAM_DFLT(checker, "Checker CPU", NULL),
+
+ INIT_PARAM_DFLT(max_insts_any_thread,
+ "Terminate when any thread reaches this inst count",
+ 0),
+ INIT_PARAM_DFLT(max_insts_all_threads,
+ "Terminate when all threads have reached"
+ "this inst count",
+ 0),
+ INIT_PARAM_DFLT(max_loads_any_thread,
+ "Terminate when any thread reaches this load count",
+ 0),
+ INIT_PARAM_DFLT(max_loads_all_threads,
+ "Terminate when all threads have reached this load"
+ "count",
+ 0),
+ INIT_PARAM_DFLT(progress_interval, "Progress interval", 0),
+
+ INIT_PARAM_DFLT(cachePorts, "Cache Ports", 200),
+
+ INIT_PARAM(decodeToFetchDelay, "Decode to fetch delay"),
+ INIT_PARAM(renameToFetchDelay, "Rename to fetch delay"),
+ INIT_PARAM(iewToFetchDelay, "Issue/Execute/Writeback to fetch"
+ "delay"),
+ INIT_PARAM(commitToFetchDelay, "Commit to fetch delay"),
+ INIT_PARAM(fetchWidth, "Fetch width"),
+ INIT_PARAM(renameToDecodeDelay, "Rename to decode delay"),
+ INIT_PARAM(iewToDecodeDelay, "Issue/Execute/Writeback to decode"
+ "delay"),
+ INIT_PARAM(commitToDecodeDelay, "Commit to decode delay"),
+ INIT_PARAM(fetchToDecodeDelay, "Fetch to decode delay"),
+ INIT_PARAM(decodeWidth, "Decode width"),
+
+ INIT_PARAM(iewToRenameDelay, "Issue/Execute/Writeback to rename"
+ "delay"),
+ INIT_PARAM(commitToRenameDelay, "Commit to rename delay"),
+ INIT_PARAM(decodeToRenameDelay, "Decode to rename delay"),
+ INIT_PARAM(renameWidth, "Rename width"),
+
+ INIT_PARAM(commitToIEWDelay, "Commit to "
+ "Issue/Execute/Writeback delay"),
+ INIT_PARAM(renameToIEWDelay, "Rename to "
+ "Issue/Execute/Writeback delay"),
+ INIT_PARAM(issueToExecuteDelay, "Issue to execute delay (internal"
+ "to the IEW stage)"),
+ INIT_PARAM(dispatchWidth, "Dispatch width"),
+ INIT_PARAM(issueWidth, "Issue width"),
+ INIT_PARAM(wbWidth, "Writeback width"),
+ INIT_PARAM(wbDepth, "Writeback depth (number of cycles it can buffer)"),
+ INIT_PARAM_DFLT(fuPool, "Functional unit pool", NULL),
+
+ INIT_PARAM(iewToCommitDelay, "Issue/Execute/Writeback to commit "
+ "delay"),
+ INIT_PARAM(renameToROBDelay, "Rename to reorder buffer delay"),
+ INIT_PARAM(commitWidth, "Commit width"),
+ INIT_PARAM(squashWidth, "Squash width"),
+ INIT_PARAM_DFLT(trapLatency, "Number of cycles before the trap is handled", 6),
+
+ INIT_PARAM(backComSize, "Time buffer size for backwards communication"),
+ INIT_PARAM(forwardComSize, "Time buffer size for forward communication"),
+
+ INIT_PARAM(predType, "Type of branch predictor ('local', 'tournament')"),
+ INIT_PARAM(localPredictorSize, "Size of local predictor"),
+ INIT_PARAM(localCtrBits, "Bits per counter"),
+ INIT_PARAM(localHistoryTableSize, "Size of local history table"),
+ INIT_PARAM(localHistoryBits, "Bits for the local history"),
+ INIT_PARAM(globalPredictorSize, "Size of global predictor"),
+ INIT_PARAM(globalCtrBits, "Bits per counter"),
+ INIT_PARAM(globalHistoryBits, "Bits of history"),
+ INIT_PARAM(choicePredictorSize, "Size of choice predictor"),
+ INIT_PARAM(choiceCtrBits, "Bits of choice counters"),
+
+ INIT_PARAM(BTBEntries, "Number of BTB entries"),
+ INIT_PARAM(BTBTagSize, "Size of the BTB tags, in bits"),
+
+ INIT_PARAM(RASSize, "RAS size"),
+
+ INIT_PARAM(LQEntries, "Number of load queue entries"),
+ INIT_PARAM(SQEntries, "Number of store queue entries"),
+ INIT_PARAM(LFSTSize, "Last fetched store table size"),
+ INIT_PARAM(SSITSize, "Store set ID table size"),
+
+ INIT_PARAM(numPhysIntRegs, "Number of physical integer registers"),
+ INIT_PARAM(numPhysFloatRegs, "Number of physical floating point "
+ "registers"),
+ INIT_PARAM(numIQEntries, "Number of instruction queue entries"),
+ INIT_PARAM(numROBEntries, "Number of reorder buffer entries"),
+
+ INIT_PARAM_DFLT(smtNumFetchingThreads, "SMT Number of Fetching Threads", 1),
+ INIT_PARAM_DFLT(smtFetchPolicy, "SMT Fetch Policy", "SingleThread"),
+ INIT_PARAM_DFLT(smtLSQPolicy, "SMT LSQ Sharing Policy", "Partitioned"),
+ INIT_PARAM_DFLT(smtLSQThreshold,"SMT LSQ Threshold", 100),
+ INIT_PARAM_DFLT(smtIQPolicy, "SMT IQ Policy", "Partitioned"),
+ INIT_PARAM_DFLT(smtIQThreshold, "SMT IQ Threshold", 100),
+ INIT_PARAM_DFLT(smtROBPolicy, "SMT ROB Sharing Policy", "Partitioned"),
+ INIT_PARAM_DFLT(smtROBThreshold,"SMT ROB Threshold", 100),
+ INIT_PARAM_DFLT(smtCommitPolicy,"SMT Commit Fetch Policy", "RoundRobin"),
+
+ INIT_PARAM(instShiftAmt, "Number of bits to shift instructions by"),
+ INIT_PARAM(defer_registration, "defer system registration (for sampling)"),
+
+ INIT_PARAM(function_trace, "Enable function trace"),
+ INIT_PARAM(function_trace_start, "Cycle to start function trace")
+
+END_INIT_SIM_OBJECT_PARAMS(DerivO3CPU)
+
+CREATE_SIM_OBJECT(DerivO3CPU)
+{
+ DerivO3CPU *cpu;
+
+#if FULL_SYSTEM
+ // Full-system only supports a single thread for the moment.
+ int actual_num_threads = 1;
+#else
+ // In non-full-system mode, we infer the number of threads from
+ // the workload if it's not explicitly specified.
+ int actual_num_threads =
+ (numThreads.isValid() && numThreads >= workload.size()) ?
+ numThreads : workload.size();
+
+ if (workload.size() == 0) {
+ fatal("Must specify at least one workload!");
+ }
+#endif
+
+ SparcSimpleParams *params = new SparcSimpleParams;
+
+ params->clock = clock;
+
+ params->name = getInstanceName();
+ params->numberOfThreads = actual_num_threads;
+ params->activity = activity;
+
+#if FULL_SYSTEM
+ params->system = system;
+ params->cpu_id = cpu_id;
+ params->itb = itb;
+ params->dtb = dtb;
+ params->profile = profile;
+
+ params->do_quiesce = do_quiesce;
+ params->do_checkpoint_insts = do_checkpoint_insts;
+ params->do_statistics_insts = do_statistics_insts;
+#else
+ params->workload = workload;
+#endif // FULL_SYSTEM
+
+ params->checker = checker;
+
+ params->max_insts_any_thread = max_insts_any_thread;
+ params->max_insts_all_threads = max_insts_all_threads;
+ params->max_loads_any_thread = max_loads_any_thread;
+ params->max_loads_all_threads = max_loads_all_threads;
+ params->progress_interval = progress_interval;
+
+ //
+ // Caches
+ //
+ params->cachePorts = cachePorts;
+
+ params->decodeToFetchDelay = decodeToFetchDelay;
+ params->renameToFetchDelay = renameToFetchDelay;
+ params->iewToFetchDelay = iewToFetchDelay;
+ params->commitToFetchDelay = commitToFetchDelay;
+ params->fetchWidth = fetchWidth;
+
+ params->renameToDecodeDelay = renameToDecodeDelay;
+ params->iewToDecodeDelay = iewToDecodeDelay;
+ params->commitToDecodeDelay = commitToDecodeDelay;
+ params->fetchToDecodeDelay = fetchToDecodeDelay;
+ params->decodeWidth = decodeWidth;
+
+ params->iewToRenameDelay = iewToRenameDelay;
+ params->commitToRenameDelay = commitToRenameDelay;
+ params->decodeToRenameDelay = decodeToRenameDelay;
+ params->renameWidth = renameWidth;
+
+ params->commitToIEWDelay = commitToIEWDelay;
+ params->renameToIEWDelay = renameToIEWDelay;
+ params->issueToExecuteDelay = issueToExecuteDelay;
+ params->dispatchWidth = dispatchWidth;
+ params->issueWidth = issueWidth;
+ params->wbWidth = wbWidth;
+ params->wbDepth = wbDepth;
+ params->fuPool = fuPool;
+
+ params->iewToCommitDelay = iewToCommitDelay;
+ params->renameToROBDelay = renameToROBDelay;
+ params->commitWidth = commitWidth;
+ params->squashWidth = squashWidth;
+ params->trapLatency = trapLatency;
+
+ params->backComSize = backComSize;
+ params->forwardComSize = forwardComSize;
+
+ params->predType = predType;
+ params->localPredictorSize = localPredictorSize;
+ params->localCtrBits = localCtrBits;
+ params->localHistoryTableSize = localHistoryTableSize;
+ params->localHistoryBits = localHistoryBits;
+ params->globalPredictorSize = globalPredictorSize;
+ params->globalCtrBits = globalCtrBits;
+ params->globalHistoryBits = globalHistoryBits;
+ params->choicePredictorSize = choicePredictorSize;
+ params->choiceCtrBits = choiceCtrBits;
+
+ params->BTBEntries = BTBEntries;
+ params->BTBTagSize = BTBTagSize;
+
+ params->RASSize = RASSize;
+
+ params->LQEntries = LQEntries;
+ params->SQEntries = SQEntries;
+
+ params->SSITSize = SSITSize;
+ params->LFSTSize = LFSTSize;
+
+ params->numPhysIntRegs = numPhysIntRegs;
+ params->numPhysFloatRegs = numPhysFloatRegs;
+ params->numIQEntries = numIQEntries;
+ params->numROBEntries = numROBEntries;
+
+ params->smtNumFetchingThreads = smtNumFetchingThreads;
+
+ // Default smtFetchPolicy to "RoundRobin", if necessary.
+ std::string round_robin_policy = "RoundRobin";
+ std::string single_thread = "SingleThread";
+
+ if (actual_num_threads > 1 && single_thread.compare(smtFetchPolicy) == 0)
+ params->smtFetchPolicy = round_robin_policy;
+ else
+ params->smtFetchPolicy = smtFetchPolicy;
+
+ params->smtIQPolicy = smtIQPolicy;
+ params->smtLSQPolicy = smtLSQPolicy;
+ params->smtLSQThreshold = smtLSQThreshold;
+ params->smtROBPolicy = smtROBPolicy;
+ params->smtROBThreshold = smtROBThreshold;
+ params->smtCommitPolicy = smtCommitPolicy;
+
+ params->instShiftAmt = 2;
+
+ params->deferRegistration = defer_registration;
+
+ params->functionTrace = function_trace;
+ params->functionTraceStart = function_trace_start;
+
+ cpu = new DerivO3CPU(params);
+
+ return cpu;
+}
+
+REGISTER_SIM_OBJECT("DerivO3CPU", DerivO3CPU)
+
diff --git a/src/cpu/o3/sparc/cpu_impl.hh b/src/cpu/o3/sparc/cpu_impl.hh
new file mode 100644
index 000000000..536a620bf
--- /dev/null
+++ b/src/cpu/o3/sparc/cpu_impl.hh
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2004-2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "config/use_checker.hh"
+
+#include "arch/sparc/faults.hh"
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/miscregfile.hh"
+#include "base/cprintf.hh"
+#include "base/statistics.hh"
+#include "base/timebuf.hh"
+#include "cpu/checker/thread_context.hh"
+#include "sim/sim_events.hh"
+#include "sim/stats.hh"
+
+#include "cpu/o3/sparc/cpu.hh"
+#include "cpu/o3/sparc/params.hh"
+#include "cpu/o3/sparc/thread_context.hh"
+#include "cpu/o3/comm.hh"
+#include "cpu/o3/thread_state.hh"
+
+#if FULL_SYSTEM
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/kernel_stats.hh"
+#include "cpu/quiesce_event.hh"
+#include "sim/sim_exit.hh"
+#include "sim/system.hh"
+#endif
+
+template <class Impl>
+SparcO3CPU<Impl>::SparcO3CPU(Params *params)
+#if FULL_SYSTEM
+ : FullO3CPU<Impl>(params), itb(params->itb), dtb(params->dtb)
+#else
+ : FullO3CPU<Impl>(params)
+#endif
+{
+ DPRINTF(O3CPU, "Creating SparcO3CPU object.\n");
+
+ // Setup any thread state.
+ this->thread.resize(this->numThreads);
+
+ for (int i = 0; i < this->numThreads; ++i) {
+#if FULL_SYSTEM
+ // SMT is not supported in FS mode yet.
+ assert(this->numThreads == 1);
+ this->thread[i] = new Thread(this, 0);
+ this->thread[i]->setStatus(ThreadContext::Suspended);
+#else
+ if (i < params->workload.size()) {
+ DPRINTF(O3CPU, "Workload[%i] process is %#x",
+ i, this->thread[i]);
+ this->thread[i] = new Thread(this, i, params->workload[i], i);
+
+ this->thread[i]->setStatus(ThreadContext::Suspended);
+
+ //usedTids[i] = true;
+ //threadMap[i] = i;
+ } else {
+ //Allocate Empty thread so M5 can use later
+ //when scheduling threads to CPU
+ Process* dummy_proc = NULL;
+
+ this->thread[i] = new Thread(this, i, dummy_proc, i);
+ //usedTids[i] = false;
+ }
+#endif // !FULL_SYSTEM
+
+ ThreadContext *tc;
+
+ // Setup the TC that will serve as the interface to the threads/CPU.
+ SparcTC<Impl> *sparc_tc = new SparcTC<Impl>;
+
+ tc = sparc_tc;
+
+ // If we're using a checker, then the TC should be the
+ // CheckerThreadContext.
+#if USE_CHECKER
+ if (params->checker) {
+ tc = new CheckerThreadContext<SparcTC<Impl> >(
+ sparc_tc, this->checker);
+ }
+#endif
+
+ sparc_tc->cpu = this;
+ sparc_tc->thread = this->thread[i];
+
+#if FULL_SYSTEM
+ // Setup quiesce event.
+ this->thread[i]->quiesceEvent = new EndQuiesceEvent(tc);
+#endif
+ // Give the thread the TC.
+ this->thread[i]->tc = tc;
+
+ // Add the TC to the CPU's list of TC's.
+ this->threadContexts.push_back(tc);
+ }
+
+ for (int i=0; i < this->numThreads; i++) {
+ this->thread[i]->setFuncExeInst(0);
+ }
+
+ // Sets CPU pointers. These must be set at this level because the CPU
+ // pointers are defined to be the highest level of CPU class.
+ this->fetch.setCPU(this);
+ this->decode.setCPU(this);
+ this->rename.setCPU(this);
+ this->iew.setCPU(this);
+ this->commit.setCPU(this);
+
+ this->rob.setCPU(this);
+ this->regFile.setCPU(this);
+
+ lockAddr = 0;
+ lockFlag = false;
+}
+
+template <class Impl>
+void
+SparcO3CPU<Impl>::regStats()
+{
+ // Register stats for everything that has stats.
+ this->fullCPURegStats();
+ this->fetch.regStats();
+ this->decode.regStats();
+ this->rename.regStats();
+ this->iew.regStats();
+ this->commit.regStats();
+}
+
+
+template <class Impl>
+TheISA::MiscReg
+SparcO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
+{
+ return this->regFile.readMiscReg(misc_reg, tid);
+}
+
+template <class Impl>
+TheISA::MiscReg
+SparcO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, unsigned tid)
+{
+ return this->regFile.readMiscRegWithEffect(misc_reg, tid);
+}
+
+template <class Impl>
+void
+SparcO3CPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid)
+{
+ this->regFile.setMiscReg(misc_reg, val, tid);
+}
+
+template <class Impl>
+void
+SparcO3CPU<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val,
+ unsigned tid)
+{
+ this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
+}
+
+template <class Impl>
+void
+SparcO3CPU<Impl>::squashFromTC(unsigned tid)
+{
+ this->thread[tid]->inSyscall = true;
+ this->commit.generateTCEvent(tid);
+}
+
+#if FULL_SYSTEM
+
+template <class Impl>
+void
+SparcO3CPU<Impl>::post_interrupt(int int_num, int index)
+{
+ BaseCPU::post_interrupt(int_num, index);
+
+ if (this->thread[0]->status() == ThreadContext::Suspended) {
+ DPRINTF(IPI,"Suspended Processor awoke\n");
+ this->threadContexts[0]->activate();
+ }
+}
+
+template <class Impl>
+Fault
+SparcO3CPU<Impl>::hwrei(unsigned tid)
+{
+ panic("This doesn't make sense for SPARC\n");
+ return NoFault;
+}
+
+template <class Impl>
+bool
+SparcO3CPU<Impl>::simPalCheck(int palFunc, unsigned tid)
+{
+ panic("This doesn't make sense for SPARC\n");
+ return true;
+}
+
+template <class Impl>
+Fault
+SparcO3CPU<Impl>::getInterrupts()
+{
+ // Check if there are any outstanding interrupts
+ return this->interrupts.getInterrupt(this->threadContexts[0]);
+}
+
+template <class Impl>
+void
+SparcO3CPU<Impl>::processInterrupts(Fault interrupt)
+{
+ // Check for interrupts here. For now can copy the code that
+ // exists within isa_fullsys_traits.hh. Also assume that thread 0
+ // is the one that handles the interrupts.
+ // @todo: Possibly consolidate the interrupt checking code.
+ // @todo: Allow other threads to handle interrupts.
+
+ assert(interrupt != NoFault);
+ this->interrupts.updateIntrInfo(this->threadContexts[0]);
+
+ DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
+ this->checkInterrupts = false;
+ this->trap(interrupt, 0);
+}
+
+#endif // FULL_SYSTEM
+
+template <class Impl>
+void
+SparcO3CPU<Impl>::trap(Fault fault, unsigned tid)
+{
+ // Pass the thread's TC into the invoke method.
+ fault->invoke(this->threadContexts[tid]);
+}
+
+#if !FULL_SYSTEM
+
+template <class Impl>
+void
+SparcO3CPU<Impl>::syscall(int64_t callnum, int tid)
+{
+ DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid);
+
+ DPRINTF(Activity,"Activity: syscall() called.\n");
+
+ // Temporarily increase this by one to account for the syscall
+ // instruction.
+ ++(this->thread[tid]->funcExeInst);
+
+ // Execute the actual syscall.
+ this->thread[tid]->syscall(callnum);
+
+ // Decrease funcExeInst by one as the normal commit will handle
+ // incrementing it.
+ --(this->thread[tid]->funcExeInst);
+}
+
+template <class Impl>
+TheISA::IntReg
+SparcO3CPU<Impl>::getSyscallArg(int i, int tid)
+{
+ return this->readArchIntReg(SparcISA::ArgumentReg0 + i, tid);
+}
+
+template <class Impl>
+void
+SparcO3CPU<Impl>::setSyscallArg(int i, IntReg val, int tid)
+{
+ this->setArchIntReg(SparcISA::ArgumentReg0 + i, val, tid);
+}
+
+template <class Impl>
+void
+SparcO3CPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
+{
+ // check for error condition. SPARC syscall convention is to
+ // indicate success/failure in reg the carry bit of the ccr
+ // and put the return value itself in the standard return value reg ().
+ if (return_value.successful()) {
+ // no error, clear XCC.C
+ this->setMiscReg(SparcISA::MISCREG_CCR,
+ this->readMiscReg(SparcISA::MISCREG_CCR, tid) & 0xEE, tid);
+ this->setArchIntReg(SparcISA::ReturnValueReg,
+ return_value.value(), tid);
+ } else {
+ // got an error, set XCC.C
+ this->setMiscReg(SparcISA::MISCREG_CCR,
+ this->readMiscReg(SparcISA::MISCREG_CCR, tid) | 0x11, tid);
+ this->setArchIntReg(SparcISA::ReturnValueReg,
+ return_value.value(), tid);
+ }
+}
+#endif
diff --git a/src/cpu/o3/sparc/dyn_inst.cc b/src/cpu/o3/sparc/dyn_inst.cc
new file mode 100644
index 000000000..984b58f4b
--- /dev/null
+++ b/src/cpu/o3/sparc/dyn_inst.cc
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "cpu/o3/sparc/dyn_inst_impl.hh"
+#include "cpu/o3/sparc/impl.hh"
+
+// Force instantiation of SparcDynInst for all the implementations that
+// are needed.
+template class SparcDynInst<SparcSimpleImpl>;
diff --git a/src/cpu/o3/sparc/dyn_inst.hh b/src/cpu/o3/sparc/dyn_inst.hh
new file mode 100644
index 000000000..f8d6bb63f
--- /dev/null
+++ b/src/cpu/o3/sparc/dyn_inst.hh
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2004-2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __CPU_O3_SPARC_DYN_INST_HH__
+#define __CPU_O3_SPARC_DYN_INST_HH__
+
+#include "arch/sparc/isa_traits.hh"
+#include "cpu/base_dyn_inst.hh"
+#include "cpu/inst_seq.hh"
+#include "cpu/o3/sparc/cpu.hh"
+#include "cpu/o3/sparc/impl.hh"
+
+class Packet;
+
+/**
+ * Mostly implementation & ISA specific SparcDynInst. As with most
+ * other classes in the new CPU model, it is templated on the Impl to
+ * allow for passing in of all types, such as the CPU type and the ISA
+ * type. The SparcDynInst serves as the primary interface to the CPU
+ * for instructions that are executing.
+ */
+template <class Impl>
+class SparcDynInst : public BaseDynInst<Impl>
+{
+ public:
+ /** Typedef for the CPU. */
+ typedef typename Impl::O3CPU O3CPU;
+
+ public:
+ /** BaseDynInst constructor given a binary instruction. */
+ SparcDynInst(TheISA::ExtMachInst inst, Addr PC,
+ Addr Pred_PC, InstSeqNum seq_num, O3CPU *cpu);
+
+ /** BaseDynInst constructor given a static inst pointer. */
+ SparcDynInst(StaticInstPtr &_staticInst);
+
+ /** Executes the instruction.*/
+ Fault execute();
+
+ /** Initiates the access. Only valid for memory operations. */
+ Fault initiateAcc();
+
+ /** Completes the access. Only valid for memory operations. */
+ Fault completeAcc(PacketPtr pkt);
+
+ private:
+ /** Initializes variables. */
+ void initVars();
+
+ public:
+ /** Reads a miscellaneous register. */
+ TheISA::MiscReg readMiscReg(int misc_reg)
+ {
+ return this->cpu->readMiscReg(misc_reg, this->threadNumber);
+ }
+
+ /** Reads a misc. register, including any side-effects the read
+ * might have as defined by the architecture.
+ */
+ TheISA::MiscReg readMiscRegWithEffect(int misc_reg)
+ {
+ return this->cpu->readMiscRegWithEffect(misc_reg, this->threadNumber);
+ }
+
+ /** Sets a misc. register. */
+ void setMiscReg(int misc_reg, const TheISA::MiscReg &val)
+ {
+ this->instResult.integer = val;
+ return this->cpu->setMiscReg(misc_reg, val, this->threadNumber);
+ }
+
+ /** Sets a misc. register, including any side-effects the write
+ * might have as defined by the architecture.
+ */
+ void setMiscRegWithEffect(int misc_reg, const TheISA::MiscReg &val)
+ {
+ return this->cpu->setMiscRegWithEffect(misc_reg, val,
+ this->threadNumber);
+ }
+
+#if FULL_SYSTEM
+ /** Calls hardware return from error interrupt. */
+ Fault hwrei();
+ /** Traps to handle specified fault. */
+ void trap(Fault fault);
+ bool simPalCheck(int palFunc);
+#else
+ /** Calls a syscall. */
+ void syscall(int64_t callnum);
+#endif
+
+ private:
+ /** Physical register index of the destination registers of this
+ * instruction.
+ */
+ PhysRegIndex _destRegIdx[TheISA::MaxInstDestRegs];
+
+ /** Physical register index of the source registers of this
+ * instruction.
+ */
+ PhysRegIndex _srcRegIdx[TheISA::MaxInstSrcRegs];
+
+ /** Physical register index of the previous producers of the
+ * architected destinations.
+ */
+ PhysRegIndex _prevDestRegIdx[TheISA::MaxInstDestRegs];
+
+ public:
+
+ // The register accessor methods provide the index of the
+ // instruction's operand (e.g., 0 or 1), not the architectural
+ // register index, to simplify the implementation of register
+ // renaming. We find the architectural register index by indexing
+ // into the instruction's own operand index table. Note that a
+ // raw pointer to the StaticInst is provided instead of a
+ // ref-counted StaticInstPtr to redice overhead. This is fine as
+ // long as these methods don't copy the pointer into any long-term
+ // storage (which is pretty hard to imagine they would have reason
+ // to do).
+
+ uint64_t readIntReg(const StaticInst *si, int idx)
+ {
+ return this->cpu->readIntReg(_srcRegIdx[idx]);
+ }
+
+ TheISA::FloatReg readFloatReg(const StaticInst *si, int idx, int width)
+ {
+ return this->cpu->readFloatReg(_srcRegIdx[idx], width);
+ }
+
+ TheISA::FloatReg readFloatReg(const StaticInst *si, int idx)
+ {
+ return this->cpu->readFloatReg(_srcRegIdx[idx]);
+ }
+
+ TheISA::FloatRegBits readFloatRegBits(const StaticInst *si,
+ int idx, int width)
+ {
+ return this->cpu->readFloatRegBits(_srcRegIdx[idx], width);
+ }
+
+ TheISA::FloatRegBits readFloatRegBits(const StaticInst *si, int idx)
+ {
+ return this->cpu->readFloatRegBits(_srcRegIdx[idx]);
+ }
+
+ /** @todo: Make results into arrays so they can handle multiple dest
+ * registers.
+ */
+ void setIntReg(const StaticInst *si, int idx, uint64_t val)
+ {
+ this->cpu->setIntReg(_destRegIdx[idx], val);
+ BaseDynInst<Impl>::setIntReg(si, idx, val);
+ }
+
+ void setFloatReg(const StaticInst *si, int idx,
+ TheISA::FloatReg val, int width)
+ {
+ this->cpu->setFloatReg(_destRegIdx[idx], val, width);
+ BaseDynInst<Impl>::setFloatReg(si, idx, val, width);
+ }
+
+ void setFloatReg(const StaticInst *si, int idx, TheISA::FloatReg val)
+ {
+ this->cpu->setFloatReg(_destRegIdx[idx], val);
+ BaseDynInst<Impl>::setFloatReg(si, idx, val);
+ }
+
+ void setFloatRegBits(const StaticInst *si, int idx,
+ TheISA::FloatRegBits val, int width)
+ {
+ this->cpu->setFloatRegBits(_destRegIdx[idx], val, width);
+ BaseDynInst<Impl>::setFloatRegBits(si, idx, val);
+ }
+
+ void setFloatRegBits(const StaticInst *si,
+ int idx, TheISA::FloatRegBits val)
+ {
+ this->cpu->setFloatRegBits(_destRegIdx[idx], val);
+ BaseDynInst<Impl>::setFloatRegBits(si, idx, val);
+ }
+
+ /** Returns the physical register index of the i'th destination
+ * register.
+ */
+ PhysRegIndex renamedDestRegIdx(int idx) const
+ {
+ return _destRegIdx[idx];
+ }
+
+ /** Returns the physical register index of the i'th source register. */
+ PhysRegIndex renamedSrcRegIdx(int idx) const
+ {
+ return _srcRegIdx[idx];
+ }
+
+ /** Returns the physical register index of the previous physical register
+ * that remapped to the same logical register index.
+ */
+ PhysRegIndex prevDestRegIdx(int idx) const
+ {
+ return _prevDestRegIdx[idx];
+ }
+
+ /** Renames a destination register to a physical register. Also records
+ * the previous physical register that the logical register mapped to.
+ */
+ void renameDestReg(int idx,
+ PhysRegIndex renamed_dest,
+ PhysRegIndex previous_rename)
+ {
+ _destRegIdx[idx] = renamed_dest;
+ _prevDestRegIdx[idx] = previous_rename;
+ }
+
+ /** Renames a source logical register to the physical register which
+ * has/will produce that logical register's result.
+ * @todo: add in whether or not the source register is ready.
+ */
+ void renameSrcReg(int idx, PhysRegIndex renamed_src)
+ {
+ _srcRegIdx[idx] = renamed_src;
+ }
+
+ public:
+ /** Calculates EA part of a memory instruction. Currently unused,
+ * though it may be useful in the future if we want to split
+ * memory operations into EA calculation and memory access parts.
+ */
+ Fault calcEA()
+ {
+ return this->staticInst->eaCompInst()->execute(this, this->traceData);
+ }
+
+ /** Does the memory access part of a memory instruction. Currently unused,
+ * though it may be useful in the future if we want to split
+ * memory operations into EA calculation and memory access parts.
+ */
+ Fault memAccess()
+ {
+ return this->staticInst->memAccInst()->execute(this, this->traceData);
+ }
+};
+
+#endif // __CPU_O3_SPARC_DYN_INST_HH__
+
diff --git a/src/cpu/o3/sparc/dyn_inst_impl.hh b/src/cpu/o3/sparc/dyn_inst_impl.hh
new file mode 100644
index 000000000..210daace2
--- /dev/null
+++ b/src/cpu/o3/sparc/dyn_inst_impl.hh
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2004-2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "cpu/o3/sparc/dyn_inst.hh"
+
+template <class Impl>
+SparcDynInst<Impl>::SparcDynInst(TheISA::ExtMachInst inst, Addr PC,
+ Addr Pred_PC, InstSeqNum seq_num, O3CPU *cpu)
+ : BaseDynInst<Impl>(inst, PC, Pred_PC, seq_num, cpu)
+{
+ initVars();
+}
+
+template <class Impl>
+SparcDynInst<Impl>::SparcDynInst(StaticInstPtr &_staticInst)
+ : BaseDynInst<Impl>(_staticInst)
+{
+ initVars();
+}
+
+template <class Impl>
+void
+SparcDynInst<Impl>::initVars()
+{
+ // Make sure to have the renamed register entries set to the same
+ // as the normal register entries. It will allow the IQ to work
+ // without any modifications.
+ for (int i = 0; i < this->staticInst->numDestRegs(); i++) {
+ _destRegIdx[i] = this->staticInst->destRegIdx(i);
+ }
+
+ for (int i = 0; i < this->staticInst->numSrcRegs(); i++) {
+ _srcRegIdx[i] = this->staticInst->srcRegIdx(i);
+ this->_readySrcRegIdx[i] = 0;
+ }
+}
+
+template <class Impl>
+Fault
+SparcDynInst<Impl>::execute()
+{
+ // @todo: Pretty convoluted way to avoid squashing from happening
+ // when using the TC during an instruction's execution
+ // (specifically for instructions that have side-effects that use
+ // the TC). Fix this.
+ bool in_syscall = this->thread->inSyscall;
+ this->thread->inSyscall = true;
+
+ this->fault = this->staticInst->execute(this, this->traceData);
+
+ this->thread->inSyscall = in_syscall;
+
+ return this->fault;
+}
+
+template <class Impl>
+Fault
+SparcDynInst<Impl>::initiateAcc()
+{
+ // @todo: Pretty convoluted way to avoid squashing from happening
+ // when using the TC during an instruction's execution
+ // (specifically for instructions that have side-effects that use
+ // the TC). Fix this.
+ bool in_syscall = this->thread->inSyscall;
+ this->thread->inSyscall = true;
+
+ this->fault = this->staticInst->initiateAcc(this, this->traceData);
+
+ this->thread->inSyscall = in_syscall;
+
+ return this->fault;
+}
+
+template <class Impl>
+Fault
+SparcDynInst<Impl>::completeAcc(PacketPtr pkt)
+{
+ this->fault = this->staticInst->completeAcc(pkt, this, this->traceData);
+
+ return this->fault;
+}
+
+#if FULL_SYSTEM
+template <class Impl>
+Fault
+SparcDynInst<Impl>::hwrei()
+{
+ return NoFault;
+}
+
+template <class Impl>
+void
+SparcDynInst<Impl>::trap(Fault fault)
+{
+ this->cpu->trap(fault, this->threadNumber);
+}
+
+template <class Impl>
+bool
+SparcDynInst<Impl>::simPalCheck(int palFunc)
+{
+ return this->cpu->simPalCheck(palFunc, this->threadNumber);
+}
+#else
+template <class Impl>
+void
+SparcDynInst<Impl>::syscall(int64_t callnum)
+{
+ this->cpu->syscall(callnum, this->threadNumber);
+}
+#endif
+
diff --git a/src/cpu/o3/sparc/impl.hh b/src/cpu/o3/sparc/impl.hh
new file mode 100644
index 000000000..0a970c2f0
--- /dev/null
+++ b/src/cpu/o3/sparc/impl.hh
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __CPU_O3_SPARC_IMPL_HH__
+#define __CPU_O3_SPARC_IMPL_HH__
+
+#include "arch/sparc/isa_traits.hh"
+
+#include "cpu/o3/sparc/params.hh"
+#include "cpu/o3/cpu_policy.hh"
+
+
+// Forward declarations.
+template <class Impl>
+class SparcDynInst;
+
+template <class Impl>
+class SparcO3CPU;
+
+/** Implementation specific struct that defines several key types to the
+ * CPU, the stages within the CPU, the time buffers, and the DynInst.
+ * The struct defines the ISA, the CPU policy, the specific DynInst, the
+ * specific O3CPU, and all of the structs from the time buffers to do
+ * communication.
+ * This is one of the key things that must be defined for each hardware
+ * specific CPU implementation.
+ */
+struct SparcSimpleImpl
+{
+ /** The type of MachInst. */
+ typedef TheISA::MachInst MachInst;
+
+ /** The CPU policy to be used, which defines all of the CPU stages. */
+ typedef SimpleCPUPolicy<SparcSimpleImpl> CPUPol;
+
+ /** The DynInst type to be used. */
+ typedef SparcDynInst<SparcSimpleImpl> DynInst;
+
+ /** The refcounted DynInst pointer to be used. In most cases this is
+ * what should be used, and not DynInst *.
+ */
+ typedef RefCountingPtr<DynInst> DynInstPtr;
+
+ /** The O3CPU type to be used. */
+ typedef SparcO3CPU<SparcSimpleImpl> O3CPU;
+
+ /** Same typedef, but for CPUType. BaseDynInst may not always use
+ * an O3 CPU, so it's clearer to call it CPUType instead in that
+ * case.
+ */
+ typedef O3CPU CPUType;
+
+ /** The Params to be passed to each stage. */
+ typedef SparcSimpleParams Params;
+
+ enum {
+ MaxWidth = 8,
+ MaxThreads = 4
+ };
+};
+
+/** The O3Impl to be used. */
+typedef SparcSimpleImpl O3CPUImpl;
+
+#endif // __CPU_O3_SPARC_IMPL_HH__
diff --git a/src/cpu/o3/sparc/params.hh b/src/cpu/o3/sparc/params.hh
new file mode 100644
index 000000000..d399d64c4
--- /dev/null
+++ b/src/cpu/o3/sparc/params.hh
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2004-2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __CPU_O3_SPARC_PARAMS_HH__
+#define __CPU_O3_SPARC_PARAMS_HH__
+
+#include "cpu/o3/cpu.hh"
+#include "cpu/o3/params.hh"
+
+//Forward declarations
+namespace SparcISA
+{
+ class DTB;
+ class ITB;
+}
+class MemObject;
+class Process;
+class System;
+
+/**
+ * This file defines the parameters that will be used for the AlphaO3CPU.
+ * This must be defined externally so that the Impl can have a params class
+ * defined that it can pass to all of the individual stages.
+ */
+
+class SparcSimpleParams : public O3Params
+{
+ public:
+
+#if FULL_SYSTEM
+ SparcISA::ITB *itb;
+ SparcISA::DTB *dtb;
+#endif
+};
+
+#endif // __CPU_O3_SPARC_PARAMS_HH__
diff --git a/src/cpu/o3/sparc/thread_context.cc b/src/cpu/o3/sparc/thread_context.cc
new file mode 100755
index 000000000..d85aff502
--- /dev/null
+++ b/src/cpu/o3/sparc/thread_context.cc
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2004-2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "cpu/o3/thread_context.hh"
+#include "cpu/o3/thread_context_impl.hh"
+
+template class O3ThreadContext<SparcSimpleImpl>;
+
diff --git a/src/cpu/o3/sparc/thread_context.hh b/src/cpu/o3/sparc/thread_context.hh
new file mode 100644
index 000000000..69d1e2d04
--- /dev/null
+++ b/src/cpu/o3/sparc/thread_context.hh
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2004-2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "arch/sparc/types.hh"
+#include "cpu/o3/thread_context.hh"
+
+template <class Impl>
+class SparcTC : public O3ThreadContext<Impl>
+{
+ public:
+#if FULL_SYSTEM
+ /** Returns a pointer to the ITB. */
+ virtual SparcISA::ITB *getITBPtr() { return this->cpu->itb; }
+
+ /** Returns a pointer to the DTB. */
+ virtual SparcISA::DTB *getDTBPtr() { return this->cpu->dtb; }
+
+ /** Returns pointer to the quiesce event. */
+ virtual EndQuiesceEvent *getQuiesceEvent()
+ {
+ return this->thread->quiesceEvent;
+ }
+#endif
+
+ virtual uint64_t readNextNPC()
+ {
+ return this->cpu->readNextNPC(this->thread->readTid());
+ }
+
+ virtual void setNextNPC(uint64_t val)
+ {
+ this->cpu->setNextNPC(val, this->thread->readTid());
+ }
+
+ virtual void changeRegFileContext(TheISA::RegContextParam param,
+ TheISA::RegContextVal val)
+ {
+ panic("This doesn't make sense!\n");
+ }
+
+
+ /** This function exits the thread context in the CPU and returns
+ * 1 if the CPU has no more active threads (meaning it's OK to exit);
+ * Used in syscall-emulation mode when a thread executes the 'exit'
+ * syscall.
+ */
+ virtual int exit()
+ {
+ this->deallocate();
+
+ // If there are still threads executing in the system
+ if (this->cpu->numActiveThreads())
+ return 0; // don't exit simulation
+ else
+ return 1; // exit simulation
+ }
+};
diff --git a/src/dev/sparc/SConscript b/src/dev/sparc/SConscript
index 701e533a8..c37294f0c 100644
--- a/src/dev/sparc/SConscript
+++ b/src/dev/sparc/SConscript
@@ -37,6 +37,7 @@ Import('env')
sources = []
sources += Split('''
+ t1000.cc
''')
# Convert file names to SCons File objects. This takes care of the
diff --git a/src/dev/sparc/t1000.cc b/src/dev/sparc/t1000.cc
new file mode 100644
index 000000000..1df6bf15f
--- /dev/null
+++ b/src/dev/sparc/t1000.cc
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ */
+
+/** @file
+ * Implementation of T1000 platform.
+ */
+
+#include <deque>
+#include <string>
+#include <vector>
+
+#include "cpu/intr_control.hh"
+#include "dev/simconsole.hh"
+#include "dev/sparc/t1000.hh"
+#include "sim/builder.hh"
+#include "sim/system.hh"
+
+using namespace std;
+//Should this be AlphaISA?
+using namespace TheISA;
+
+T1000::T1000(const string &name, System *s, IntrControl *ic)
+ : Platform(name, ic), system(s)
+{
+ // set the back pointer from the system to myself
+ system->platform = this;
+}
+
+Tick
+T1000::intrFrequency()
+{
+ return (Tick)0;
+}
+
+void
+T1000::postConsoleInt()
+{
+}
+
+void
+T1000::clearConsoleInt()
+{
+}
+
+void
+T1000::postPciInt(int line)
+{
+}
+
+void
+T1000::clearPciInt(int line)
+{
+}
+
+Addr
+T1000::pciToDma(Addr pciAddr) const
+{
+ return (Addr)0;
+}
+
+
+Addr
+T1000::calcConfigAddr(int bus, int dev, int func)
+{
+ return (Addr)0;
+}
+
+void
+T1000::serialize(std::ostream &os)
+{
+}
+
+void
+T1000::unserialize(Checkpoint *cp, const std::string &section)
+{
+}
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(T1000)
+
+ SimObjectParam<System *> system;
+ SimObjectParam<IntrControl *> intrctrl;
+
+END_DECLARE_SIM_OBJECT_PARAMS(T1000)
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(T1000)
+
+ INIT_PARAM(system, "system"),
+ INIT_PARAM(intrctrl, "interrupt controller")
+
+END_INIT_SIM_OBJECT_PARAMS(T1000)
+
+CREATE_SIM_OBJECT(T1000)
+{
+ return new T1000(getInstanceName(), system, intrctrl);
+}
+
+REGISTER_SIM_OBJECT("T1000", T1000)
diff --git a/src/dev/sparc/t1000.hh b/src/dev/sparc/t1000.hh
new file mode 100644
index 000000000..fb82dff11
--- /dev/null
+++ b/src/dev/sparc/t1000.hh
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ */
+
+/**
+ * @file
+ * Declaration of top level class for the Tsunami chipset. This class just
+ * retains pointers to all its children so the children can communicate.
+ */
+
+#ifndef __DEV_T1000_HH__
+#define __DEV_T1000_HH__
+
+#include "dev/platform.hh"
+
+class IdeController;
+class System;
+
+class T1000 : public Platform
+{
+ public:
+ /** Pointer to the system */
+ System *system;
+
+ public:
+ /**
+ * Constructor for the Tsunami Class.
+ * @param name name of the object
+ * @param s system the object belongs to
+ * @param intctrl pointer to the interrupt controller
+ */
+ T1000(const std::string &name, System *s, IntrControl *intctrl);
+
+ /**
+ * Return the interrupting frequency to AlphaAccess
+ * @return frequency of RTC interrupts
+ */
+ virtual Tick intrFrequency();
+
+ /**
+ * Cause the cpu to post a serial interrupt to the CPU.
+ */
+ virtual void postConsoleInt();
+
+ /**
+ * Clear a posted CPU interrupt (id=55)
+ */
+ virtual void clearConsoleInt();
+
+ /**
+ * Cause the chipset to post a cpi interrupt to the CPU.
+ */
+ virtual void postPciInt(int line);
+
+ /**
+ * Clear a posted PCI->CPU interrupt
+ */
+ virtual void clearPciInt(int line);
+
+
+ virtual Addr pciToDma(Addr pciAddr) const;
+
+ /**
+ * Calculate the configuration address given a bus/dev/func.
+ */
+ virtual Addr calcConfigAddr(int bus, int dev, int func);
+
+ /**
+ * Serialize this object to the given output stream.
+ * @param os The stream to serialize to.
+ */
+ virtual void serialize(std::ostream &os);
+
+ /**
+ * Reconstruct the state of this object from a checkpoint.
+ * @param cp The checkpoint use.
+ * @param section The section name of this object
+ */
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
+};
+
+#endif // __DEV_T1000_HH__
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index 94f60ad80..6610e547d 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -65,6 +65,10 @@ PhysicalMemory::PhysicalMemory(Params *p)
fatal("Could not mmap!\n");
}
+ //If requested, initialize all the memory to 0
+ if(params()->zero)
+ memset(pmemAddr, 0, params()->addrRange.size());
+
pagePtr = 0;
}
@@ -191,7 +195,7 @@ PhysicalMemory::checkLockedAddrList(Request *req)
void
PhysicalMemory::doFunctionalAccess(PacketPtr pkt)
{
- assert(pkt->getAddr() + pkt->getSize() > params()->addrRange.start &&
+ assert(pkt->getAddr() >= params()->addrRange.start &&
pkt->getAddr() + pkt->getSize() <= params()->addrRange.start +
params()->addrRange.size());
@@ -432,6 +436,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory)
Param<string> file;
Param<Range<Addr> > range;
Param<Tick> latency;
+ Param<bool> zero;
END_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory)
@@ -439,7 +444,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(PhysicalMemory)
INIT_PARAM_DFLT(file, "memory mapped file", ""),
INIT_PARAM(range, "Device Address Range"),
- INIT_PARAM(latency, "Memory access latency")
+ INIT_PARAM(latency, "Memory access latency"),
+ INIT_PARAM(zero, "Zero initialize memory")
END_INIT_SIM_OBJECT_PARAMS(PhysicalMemory)
@@ -449,6 +455,7 @@ CREATE_SIM_OBJECT(PhysicalMemory)
p->name = getInstanceName();
p->addrRange = range;
p->latency = latency;
+ p->zero = zero;
return new PhysicalMemory(p);
}
diff --git a/src/mem/physical.hh b/src/mem/physical.hh
index 045e61612..af88bcaa0 100644
--- a/src/mem/physical.hh
+++ b/src/mem/physical.hh
@@ -154,6 +154,7 @@ class PhysicalMemory : public MemObject
std::string name;
Range<Addr> addrRange;
Tick latency;
+ bool zero;
};
protected:
diff --git a/src/python/m5/objects/PhysicalMemory.py b/src/python/m5/objects/PhysicalMemory.py
index 4e097543d..b8df6229e 100644
--- a/src/python/m5/objects/PhysicalMemory.py
+++ b/src/python/m5/objects/PhysicalMemory.py
@@ -9,6 +9,7 @@ class PhysicalMemory(MemObject):
range = Param.AddrRange(AddrRange('128MB'), "Device Address")
file = Param.String('', "memory mapped file")
latency = Param.Latency(Parent.clock, "latency of an access")
+ zero = Param.Bool(False, "zero initialize memory")
class DRAMMemory(PhysicalMemory):
type = 'DRAMMemory'
diff --git a/src/python/m5/objects/System.py b/src/python/m5/objects/System.py
index 908c3d4ad..7ac4dd701 100644
--- a/src/python/m5/objects/System.py
+++ b/src/python/m5/objects/System.py
@@ -29,17 +29,40 @@ class AlphaSystem(System):
class SparcSystem(System):
type = 'SparcSystem'
_rom_base = 0xfff0000000
+ _nvram_base = 0x1f11000000
+ _hypervisor_desc_base = 0x1f12080000
+ _partition_desc_base = 0x1f12000000
# ROM for OBP/Reset/Hypervisor
rom = Param.PhysicalMemory(PhysicalMemory(range = AddrRange(_rom_base, size = '8MB')),
"Memory to hold the ROM data")
+ # nvram
+ nvram = Param.PhysicalMemory(
+ PhysicalMemory(range = AddrRange(_nvram_base, size = '8kB')),
+ "Memory to hold the nvram data")
+ # hypervisor description
+ hypervisor_desc = Param.PhysicalMemory(
+ PhysicalMemory(range = AddrRange(_hypervisor_desc_base, size = '8kB')),
+ "Memory to hold the hypervisor description")
+ # partition description
+ partition_desc = Param.PhysicalMemory(
+ PhysicalMemory(range = AddrRange(_partition_desc_base, size = '8kB')),
+ "Memory to hold the partition description")
reset_addr = Param.Addr(_rom_base, "Address to load ROM at")
hypervisor_addr = Param.Addr(Addr('64kB') + _rom_base,
"Address to load hypervisor at")
openboot_addr = Param.Addr(Addr('512kB') + _rom_base,
"Address to load openboot at")
+ nvram_addr = Param.Addr(_nvram_base, "Address to put the nvram")
+ hypervisor_desc_addr = Param.Addr(_hypervisor_desc_base,
+ "Address for the hypervisor description")
+ partition_desc_addr = Param.Addr(_partition_desc_base,
+ "Address for the partition description")
reset_bin = Param.String("file that contains the reset code")
hypervisor_bin = Param.String("file that contains the hypervisor code")
openboot_bin = Param.String("file that contains the openboot code")
+ nvram_bin = Param.String("file that contains the contents of nvram")
+ hypervisor_desc_bin = Param.String("file that contains the hypervisor description")
+ partition_desc_bin = Param.String("file that contains the partition description")
diff --git a/src/python/m5/objects/T1000.py b/src/python/m5/objects/T1000.py
new file mode 100644
index 000000000..bb0d37bf8
--- /dev/null
+++ b/src/python/m5/objects/T1000.py
@@ -0,0 +1,31 @@
+from m5.params import *
+from m5.proxy import *
+from Device import BasicPioDevice
+from Uart import Uart8250
+from Platform import Platform
+from SimConsole import SimConsole, ConsoleListener
+
+class IsaFake(BasicPioDevice):
+ type = 'IsaFake'
+ pio_size = Param.Addr(0x8, "Size of address range")
+ ret_data = Param.UInt8(0xFF, "Default data to return")
+ ret_bad_addr = Param.Bool(False, "Return pkt status bad address on access")
+
+class BadAddr(IsaFake):
+ ret_bad_addr = Param.Bool(True, "Return pkt status bad address on access")
+
+class T1000(Platform):
+ type = 'T1000'
+ system = Param.System(Parent.any, "system")
+
+ fake_iob = IsaFake(pio_addr=0x8000000000, pio_size=0x7F00000000)
+
+ uart = Uart8250(pio_addr=0xfff0c2c000)
+ console = SimConsole(listener = ConsoleListener())
+
+ # Attach I/O devices to specified bus object. Can't do this
+ # earlier, since the bus object itself is typically defined at the
+ # System level.
+ def attachIO(self, bus):
+ self.fake_iob.pio = bus.port
+ self.uart.pio = bus.port