diff options
Diffstat (limited to 'src/arch')
25 files changed, 610 insertions, 371 deletions
diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index ff5830822..c73c32bad 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -189,6 +189,11 @@ namespace AlphaISA } }; + static inline int flattenIntIndex(ThreadContext * tc, int reg) + { + return reg; + } + void copyRegs(ThreadContext *src, ThreadContext *dest); void copyMiscRegs(ThreadContext *src, ThreadContext *dest); diff --git a/src/arch/alpha/syscallreturn.hh b/src/arch/alpha/syscallreturn.hh index 803c3b7da..47b4ac8c7 100644 --- a/src/arch/alpha/syscallreturn.hh +++ b/src/arch/alpha/syscallreturn.hh @@ -32,54 +32,25 @@ #ifndef __ARCH_ALPHA_SYSCALLRETURN_HH__ #define __ARCH_ALPHA_SYSCALLRETURN_HH__ -class SyscallReturn { - public: - template <class T> - SyscallReturn(T v, bool s) - { - retval = (uint64_t)v; - success = s; - } - - template <class T> - SyscallReturn(T v) - { - success = (v >= 0); - retval = (uint64_t)v; - } - - ~SyscallReturn() {} - - SyscallReturn& operator=(const SyscallReturn& s) { - retval = s.retval; - success = s.success; - return *this; - } - - bool successful() { return success; } - uint64_t value() { return retval; } - - - private: - uint64_t retval; - bool success; -}; +#include "cpu/thread_context.hh" +#include "sim/syscallreturn.hh" namespace AlphaISA { - static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs) + static inline void setSyscallReturn(SyscallReturn return_value, + ThreadContext * tc) { // check for error condition. Alpha syscall convention is to // indicate success/failure in reg a3 (r19) and put the // return value itself in the standard return value reg (v0). if (return_value.successful()) { // no error - regs->setIntReg(SyscallSuccessReg, 0); - regs->setIntReg(ReturnValueReg, return_value.value()); + tc->setIntReg(SyscallSuccessReg, 0); + tc->setIntReg(ReturnValueReg, return_value.value()); } else { // got an error, return details - regs->setIntReg(SyscallSuccessReg, (IntReg)-1); - regs->setIntReg(ReturnValueReg, -return_value.value()); + tc->setIntReg(SyscallSuccessReg, (IntReg)-1); + tc->setIntReg(ReturnValueReg, -return_value.value()); } } } diff --git a/src/arch/mips/regfile/regfile.hh b/src/arch/mips/regfile/regfile.hh index dee883c4a..7b57b31f5 100644 --- a/src/arch/mips/regfile/regfile.hh +++ b/src/arch/mips/regfile/regfile.hh @@ -173,6 +173,11 @@ namespace MipsISA } }; + static inline int flattenIntIndex(ThreadContext * tc, int reg) + { + return reg; + } + void copyRegs(ThreadContext *src, ThreadContext *dest); void copyMiscRegs(ThreadContext *src, ThreadContext *dest); diff --git a/src/arch/mips/syscallreturn.hh b/src/arch/mips/syscallreturn.hh index ef1093caf..47290b634 100644 --- a/src/arch/mips/syscallreturn.hh +++ b/src/arch/mips/syscallreturn.hh @@ -32,51 +32,22 @@ #ifndef __ARCH_MIPS_SYSCALLRETURN_HH__ #define __ARCH_MIPS_SYSCALLRETURN_HH__ -class SyscallReturn { - public: - template <class T> - SyscallReturn(T v, bool s) - { - retval = (uint32_t)v; - success = s; - } - - template <class T> - SyscallReturn(T v) - { - success = (v >= 0); - retval = (uint32_t)v; - } - - ~SyscallReturn() {} - - SyscallReturn& operator=(const SyscallReturn& s) { - retval = s.retval; - success = s.success; - return *this; - } - - bool successful() { return success; } - uint64_t value() { return retval; } - - - private: - uint64_t retval; - bool success; -}; +#include "sim/syscallreturn.hh" +#include "cpu/thread_context.hh" namespace MipsISA { - static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs) + static inline void setSyscallReturn(SyscallReturn return_value, + ThreadContext *tc) { if (return_value.successful()) { // no error - regs->setIntReg(SyscallSuccessReg, 0); - regs->setIntReg(ReturnValueReg1, return_value.value()); + tc->setIntReg(SyscallSuccessReg, 0); + tc->setIntReg(ReturnValueReg1, return_value.value()); } else { // got an error, return details - regs->setIntReg(SyscallSuccessReg, (IntReg) -1); - regs->setIntReg(ReturnValueReg1, -return_value.value()); + tc->setIntReg(SyscallSuccessReg, (IntReg) -1); + tc->setIntReg(ReturnValueReg1, -return_value.value()); } } } diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 4cf411d3b..4326e8b67 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); } /** @@ -297,10 +302,12 @@ void doREDFault(ThreadContext *tc, TrapType tt) MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE); MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); - MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + //MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); MiscReg ASI = tc->readMiscReg(MISCREG_ASI); MiscReg CWP = tc->readMiscReg(MISCREG_CWP); - MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + MiscReg CANSAVE = tc->readMiscReg(NumIntArchRegs + 3); MiscReg GL = tc->readMiscReg(MISCREG_GL); MiscReg PC = tc->readPC(); MiscReg NPC = tc->readNextPC(); @@ -340,10 +347,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 @@ -389,10 +398,12 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE); MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); - MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + //MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); MiscReg ASI = tc->readMiscReg(MISCREG_ASI); MiscReg CWP = tc->readMiscReg(MISCREG_CWP); - MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3); MiscReg GL = tc->readMiscReg(MISCREG_GL); MiscReg PC = tc->readPC(); MiscReg NPC = tc->readNextPC(); @@ -451,7 +462,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 +546,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 +593,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 +601,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); @@ -665,19 +690,21 @@ void PageTableFault::invoke(ThreadContext *tc) { Process *p = tc->getProcessPtr(); - // address is higher than the stack region or in the current stack region - if (vaddr > p->stack_base || vaddr > p->stack_min) - FaultBase::invoke(tc); - - // We've accessed the next page - if (vaddr > p->stack_min - PageBytes) { + // We've accessed the next page of the stack, so extend the stack + // to cover it. + if(vaddr < p->stack_min && vaddr >= p->stack_min - PageBytes) + { p->stack_min -= PageBytes; - if (p->stack_base - p->stack_min > 8*1024*1024) + if(p->stack_base - p->stack_min > 8*1024*1024) fatal("Over max stack size for one thread\n"); p->pTable->allocate(p->stack_min, PageBytes); warn("Increasing stack size by one page."); - } else { - FaultBase::invoke(tc); + } + // Otherwise, we have an unexpected page fault. Report that fact, + // and what address was accessed to cause the fault. + else + { + panic("Page table fault when accessing virtual address %#x\n", vaddr); } } 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..594fe4bea 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", @@ -65,6 +66,7 @@ void IntRegFile::clear() memset(regGlobals[x], 0, sizeof(IntReg) * RegsPerFrame); for(int x = 0; x < 2 * NWindows; x++) memset(regSegments[x], 0, sizeof(IntReg) * RegsPerFrame); + memset(regs, 0, sizeof(IntReg) * NumIntRegs); } IntRegFile::IntRegFile() @@ -77,31 +79,39 @@ IntRegFile::IntRegFile() IntReg IntRegFile::readReg(int intReg) { + DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, regs[intReg]); + return regs[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) + regs[intReg] = val; + } + return; + if(intReg) + { + DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); + 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..503f3c453 100644 --- a/src/arch/sparc/intregfile.hh +++ b/src/arch/sparc/intregfile.hh @@ -32,12 +32,14 @@ #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 "base/bitfield.hh" #include <string> +class Checkpoint; + namespace SparcISA { class RegFile; @@ -45,20 +47,27 @@ 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: friend class RegFile; protected: + //The number of bits needed to index into each 8 register frame static const int FrameOffsetBits = 3; + //The number of bits to choose between the 4 sets of 8 registers static const int FrameNumBits = 2; + //The number of registers per "frame" (8) static const int RegsPerFrame = 1 << FrameOffsetBits; - static const int FrameNumMask = + //A mask to get the frame number + static const uint64_t FrameNumMask = (FrameNumBits == sizeof(int)) ? (unsigned int)(-1) : (1 << FrameNumBits) - 1; - static const int FrameOffsetMask = + static const uint64_t FrameOffsetMask = (FrameOffsetBits == sizeof(int)) ? (unsigned int)(-1) : (1 << FrameOffsetBits) - 1; @@ -66,6 +75,7 @@ namespace SparcISA IntReg regGlobals[MaxGL][RegsPerFrame]; IntReg regSegments[2 * NWindows][RegsPerFrame]; IntReg microRegs[NumMicroIntRegs]; + IntReg regs[NumIntRegs]; enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames}; @@ -85,7 +95,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..c3cff42ee 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -76,9 +76,15 @@ decode OP default Unknown::unknown() }}); 0x2: bpccx(19, {{ if(passesCondition(Ccr<7:4>, COND2)) + { + //warn("Took branch!\n"); NNPC = xc->readPC() + disp; + } else + { + //warn("Didn't take branch!\n"); handle_annul + } }}); } } @@ -247,16 +253,14 @@ decode OP default Unknown::unknown() ((Rs1 & val2) | (carryin & (Rs1 | val2)))<0:>)<63:>}}, {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} ); - 0x1A: umulcc({{ + 0x1A: IntOpCcRes::umulcc({{ uint64_t resTemp; Rd = resTemp = Rs1.udw<31:0> * Rs2_or_imm13.udw<31:0>; - Y = resTemp<63:32>;}}, - {{0}},{{0}},{{0}},{{0}}); - 0x1B: smulcc({{ + Y = resTemp<63:32>;}}); + 0x1B: IntOpCcRes::smulcc({{ int64_t resTemp; Rd = resTemp = Rs1.sdw<31:0> * Rs2_or_imm13.sdw<31:0>; - Y = resTemp<63:32>;}}, - {{0}},{{0}},{{0}},{{0}}); + Y = resTemp<63:32>;}}); 0x1C: subccc({{ int64_t resTemp, val2 = Rs2_or_imm13; int64_t carryin = Ccr<0:0>; @@ -266,10 +270,9 @@ decode OP default Unknown::unknown() {{(~((Rs1<63:1> + (~(val2 + carryin))<63:1>) + (Rs1<0:> + (~(val2+carryin))<0:> + 1)<63:1>))<63:>}}, {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} ); - 0x1D: udivxcc({{ + 0x1D: IntOpCcRes::udivxcc({{ if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero; - else Rd = Rs1.udw / Rs2_or_imm13.udw;}} - ,{{0}},{{0}},{{0}},{{0}}); + else Rd = Rs1.udw / Rs2_or_imm13.udw;}}); 0x1E: udivcc({{ uint32_t resTemp, val2 = Rs2_or_imm13.udw; int32_t overflow = 0; @@ -307,7 +310,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 +319,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 +330,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 +340,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 +350,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:>}} @@ -881,16 +883,11 @@ decode OP default Unknown::unknown() } }}); 0x39: Branch::return({{ - //If both MemAddressNotAligned and - //a fill trap happen, it's not clear - //which one should be returned. Addr target = Rs1 + Rs2_or_imm13; - if(target & 0x3) - fault = new MemAddressNotAligned; - else - NNPC = target; if(fault == NoFault) { + //Check for fills which are higher priority than alignment + //faults. if(Canrestore == 0) { if(Otherwin) @@ -898,18 +895,15 @@ decode OP default Unknown::unknown() else fault = new FillNNormal(Wstate<2:0>); } + //Check for alignment faults + else if(target & 0x3) + fault = new MemAddressNotAligned; else { - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one + NNPC = target; Cwp = (Cwp - 1 + NWindows) % NWindows; Cansave = Cansave + 1; Canrestore = Canrestore - 1; - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } } }}); @@ -927,7 +921,7 @@ decode OP default Unknown::unknown() xc->syscall(R1); #endif } - }}); + }}, IsSerializeAfter, IsNonSpeculative); 0x2: Trap::tccx({{ if(passesCondition(Ccr<7:4>, COND2)) { @@ -940,36 +934,27 @@ decode OP default Unknown::unknown() xc->syscall(R1); #endif } - }}); + }}, IsSerializeAfter, IsNonSpeculative); } 0x3B: Nop::flush({{/*Instruction memory flush*/}}); 0x3C: save({{ - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one if(Cansave == 0) { if(Otherwin) fault = new SpillNOther(Wstate<5:3>); else fault = new SpillNNormal(Wstate<2:0>); - //Cwp = (Cwp + 2) % NWindows; } else if(Cleanwin - Canrestore == 0) { - //Cwp = (Cwp + 1) % NWindows; fault = new CleanWindow; } else { Cwp = (Cwp + 1) % NWindows; - Rd = Rs1 + Rs2_or_imm13; + Rd_next = Rs1 + Rs2_or_imm13; Cansave = Cansave - 1; Canrestore = Canrestore + 1; - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } }}); 0x3D: restore({{ @@ -982,17 +967,10 @@ decode OP default Unknown::unknown() } else { - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one Cwp = (Cwp - 1 + NWindows) % NWindows; - Rd = Rs1 + Rs2_or_imm13; + Rd_prev = Rs1 + Rs2_or_imm13; Cansave = Cansave + 1; Canrestore = Canrestore - 1; - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } }}); 0x3E: decode FCN { diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa index 5fb7ade2d..3062f38b2 100644 --- a/src/arch/sparc/isa/formats/branch.isa +++ b/src/arch/sparc/isa/formats/branch.isa @@ -170,7 +170,7 @@ output decoder {{ printMnemonic(response, mnemonic); ccprintf(response, "0x%x", target); - if(symtab->findNearestSymbol(target, symbol, symbolAddr)) + if(symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) { ccprintf(response, " <%s", symbol); if(symbolAddr != target) @@ -178,6 +178,10 @@ output decoder {{ else ccprintf(response, ">"); } + else + { + ccprintf(response, "<%d>", target); + } return response.str(); } diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index b9f7fde2d..f3adbe19f 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, ", "); @@ -137,7 +144,7 @@ def template LoadExecute {{ %(op_decl)s; %(op_rd)s; %(ea_code)s; - DPRINTF(Sparc, "The address is 0x%x\n", EA); + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; if(fault == NoFault) { @@ -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; @@ -165,6 +172,7 @@ def template LoadExecute {{ %(ea_decl)s; %(ea_rd)s; %(ea_code)s; + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; if(fault == NoFault) { @@ -195,7 +203,6 @@ def template StoreExecute {{ Trace::InstRecord *traceData) const { Fault fault = NoFault; - uint64_t write_result = 0; //This is to support the conditional store in cas instructions. //It should be optomized out in all the others bool storeCond = true; @@ -203,7 +210,7 @@ def template StoreExecute {{ %(op_decl)s; %(op_rd)s; %(ea_code)s; - DPRINTF(Sparc, "The address is 0x%x\n", EA); + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; if(fault == NoFault) { @@ -211,12 +218,12 @@ def template StoreExecute {{ } if(storeCond && fault == NoFault) { - fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); + fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, 0); } 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; @@ -226,13 +233,12 @@ def template StoreExecute {{ Trace::InstRecord * traceData) const { Fault fault = NoFault; - uint64_t write_result = 0; bool storeCond = true; Addr EA; %(op_decl)s; %(op_rd)s; %(ea_code)s; - DPRINTF(Sparc, "The address is 0x%x\n", EA); + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; if(fault == NoFault) { @@ -240,11 +246,11 @@ def template StoreExecute {{ } if(storeCond && fault == NoFault) { - fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); + fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, 0); } 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 +299,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 +308,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 +330,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/includes.isa b/src/arch/sparc/isa/includes.isa index 624afb693..2e7b16f20 100644 --- a/src/arch/sparc/isa/includes.isa +++ b/src/arch/sparc/isa/includes.isa @@ -37,12 +37,13 @@ output header {{ #include <sstream> #include <iostream> -#include "cpu/static_inst.hh" #include "arch/sparc/faults.hh" -#include "mem/request.hh" // some constructors use MemReq flags -#include "mem/packet.hh" #include "arch/sparc/isa_traits.hh" #include "arch/sparc/regfile.hh" +#include "base/misc.hh" +#include "cpu/static_inst.hh" +#include "mem/packet.hh" +#include "mem/request.hh" // some constructors use MemReq flags }}; output decoder {{ diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa index 2d200f568..9a5fda6ff 100644 --- a/src/arch/sparc/isa/operands.isa +++ b/src/arch/sparc/isa/operands.isa @@ -56,12 +56,23 @@ def operands {{ # Int regs default to unsigned, but code should not count on this. # For clarity, descriptions that depend on unsigned behavior should # explicitly specify '.uq'. + 'Rd': ('IntReg', 'udw', 'RD', 'IsInteger', 1), - 'RdLow': ('IntReg', 'udw', 'RD & (~1)', 'IsInteger', 2), - '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), + # The Rd from the previous window + 'Rd_prev': ('IntReg', 'udw', 'RD + NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 2), + # The Rd from the next window + 'Rd_next': ('IntReg', 'udw', 'RD + 2 * NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 3), + # The low (even) register of a two register pair + 'RdLow': ('IntReg', 'udw', 'RD & (~1)', 'IsInteger', 4), + # The high (odd) register of a two register pair + 'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 5), + 'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 6), + 'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 7), + # A microcode register. Right now, this is the only one. + 'uReg0': ('IntReg', 'udw', 'NumIntArchRegs', 'IsInteger', 8), + # Because double and quad precision register numbers are decoded + # differently, they get different operands. The single precision versions + # have an s post pended to their name. '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. @@ -80,14 +91,17 @@ def operands {{ 'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12), 'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31), 'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32), + # Registers which are used explicitly in instructions 'R0': ('IntReg', 'udw', '0', None, 6), 'R1': ('IntReg', 'udw', '1', None, 7), 'R15': ('IntReg', 'udw', '15', 'IsInteger', 8), 'R16': ('IntReg', 'udw', '16', None, 9), # Control registers - 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40), - 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41), +# 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40), +# 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41), + 'Y': ('IntReg', 'udw', 'NumIntArchRegs + 1', None, 40), + 'Ccr': ('IntReg', 'udw', 'NumIntArchRegs + 2', None, 41), 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 42), 'Fprs': ('ControlReg', 'udw', 'MISCREG_FPRS', None, 43), 'Pcr': ('ControlReg', 'udw', 'MISCREG_PCR', None, 44), @@ -109,12 +123,17 @@ def operands {{ 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 59), 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 60), 'Pil': ('ControlReg', 'udw', 'MISCREG_PIL', None, 61), - 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 62), - 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63), - 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64), - 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65), - 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66), - 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67), + 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', (None, None, ['IsSerializeAfter','IsSerializing']), 62), +# 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63), +# 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64), +# 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65), +# 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66), +# 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67), + 'Cansave': ('IntReg', 'udw', 'NumIntArchRegs + 3', None, 63), + 'Canrestore': ('IntReg', 'udw', 'NumIntArchRegs + 4', None, 64), + 'Cleanwin': ('IntReg', 'udw', 'NumIntArchRegs + 5', None, 65), + 'Otherwin': ('IntReg', 'udw', 'NumIntArchRegs + 6', None, 66), + 'Wstate': ('IntReg', 'udw', 'NumIntArchRegs + 7', None, 67), 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 68), 'Hpstate': ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 69), diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index 1433ba3f8..7d786dc3b 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -32,16 +32,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 {} @@ -63,32 +56,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 = 32*3+8, + Ctrl_Base_DepTag = FP_Base_DepTag + 64, }; - - // 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 @@ -116,23 +89,11 @@ 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 §ion); - StaticInstPtr decodeInst(ExtMachInst); - - // return a no-op instruction... used for instruction fetch faults - extern const MachInst NoopMachInst; } #endif // __ARCH_SPARC_ISA_TRAITS_HH__ diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index d52e3983f..50a4f4871 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -50,19 +50,24 @@ 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", - "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin", - "wstate", "gl", + "pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin", + "wstate",*/ "gl", "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg", "hstick_cmpr", "fsr"}; 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; implicitInstAsi = ASI_PRIMARY; implicitDataAsi = ASI_PRIMARY; @@ -102,10 +109,10 @@ void MiscRegFile::reset() MiscReg MiscRegFile::readReg(int miscReg) { switch (miscReg) { - case MISCREG_Y: - return y; - case MISCREG_CCR: - return ccr; +// case MISCREG_Y: +// return y; +// case MISCREG_CCR: +// return ccr; case MISCREG_ASI: return asi; case MISCREG_FPRS: @@ -148,16 +155,16 @@ MiscReg MiscRegFile::readReg(int miscReg) return pil; case MISCREG_CWP: return cwp; - case MISCREG_CANSAVE: - return cansave; - case MISCREG_CANRESTORE: - return canrestore; - case MISCREG_CLEANWIN: - return cleanwin; - case MISCREG_OTHERWIN: - return otherwin; - case MISCREG_WSTATE: - return wstate; +// case MISCREG_CANSAVE: +// return cansave; +// case MISCREG_CANRESTORE: +// return canrestore; +// case MISCREG_CLEANWIN: +// return cleanwin; +// case MISCREG_OTHERWIN: +// return otherwin; +// case MISCREG_WSTATE: +// return wstate; case MISCREG_GL: return gl; @@ -218,12 +225,12 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc) void MiscRegFile::setReg(int miscReg, const MiscReg &val) { switch (miscReg) { - case MISCREG_Y: - y = val; - break; - case MISCREG_CCR: - ccr = val; - break; +// case MISCREG_Y: +// y = val; +// break; +// case MISCREG_CCR: +// ccr = val; +// break; case MISCREG_ASI: asi = val; break; @@ -273,7 +280,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; @@ -284,21 +291,21 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val) case MISCREG_CWP: cwp = val; break; - case MISCREG_CANSAVE: - cansave = val; - break; - case MISCREG_CANRESTORE: - canrestore = val; - break; - case MISCREG_CLEANWIN: - cleanwin = val; - break; - case MISCREG_OTHERWIN: - otherwin = val; - break; - case MISCREG_WSTATE: - wstate = val; - break; +// case MISCREG_CANSAVE: +// cansave = val; +// break; +// case MISCREG_CANRESTORE: +// canrestore = val; +// break; +// case MISCREG_CLEANWIN: +// cleanwin = val; +// break; +// case MISCREG_OTHERWIN: +// otherwin = val; +// break; +// case MISCREG_WSTATE: +// wstate = val; +// break; case MISCREG_GL: gl = val; break; @@ -375,7 +382,7 @@ void MiscRegFile::setRegWithEffect(int miscReg, //Set up performance counting based on pcr value break; case MISCREG_PSTATE: - pstate = val; + pstate = val & PSTATE_MASK; setImplicitAsis(); return; case MISCREG_TL: diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index f74943256..cf0405ac4 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -42,15 +42,14 @@ namespace SparcISA { - //These functions map register indices to names std::string getMiscRegName(RegIndex); enum MiscRegIndex { /** Ancillary State Registers */ - MISCREG_Y, - MISCREG_CCR, +// MISCREG_Y, +// MISCREG_CCR, MISCREG_ASI, MISCREG_TICK, MISCREG_FPRS, @@ -75,11 +74,11 @@ namespace SparcISA MISCREG_TL, MISCREG_PIL, MISCREG_CWP, - MISCREG_CANSAVE, - MISCREG_CANRESTORE, - MISCREG_CLEANWIN, - MISCREG_OTHERWIN, - MISCREG_WSTATE, +// MISCREG_CANSAVE, +// MISCREG_CANRESTORE, +// MISCREG_CLEANWIN, +// MISCREG_OTHERWIN, +// MISCREG_WSTATE, MISCREG_GL, /** Hyper privileged registers */ @@ -92,9 +91,14 @@ namespace SparcISA MISCREG_HSTICK_CMPR, /** Floating Point Status Register */ - MISCREG_FSR + MISCREG_FSR, + + MISCREG_NUMMISCREGS }; + const int NumMiscArchRegs = MISCREG_NUMMISCREGS; + const int NumMiscRegs = MISCREG_NUMMISCREGS; + // The control registers, broken out into fields class MiscRegFile { @@ -172,11 +176,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..073117a84 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 @@ -94,17 +95,22 @@ SparcLiveProcess::startup() */ //No windows contain info from other programs - threadContexts[0]->setMiscReg(MISCREG_OTHERWIN, 0); + //threadContexts[0]->setMiscReg(MISCREG_OTHERWIN, 0); + threadContexts[0]->setIntReg(NumIntArchRegs + 6, 0); //There are no windows to pop - threadContexts[0]->setMiscReg(MISCREG_CANRESTORE, 0); + //threadContexts[0]->setMiscReg(MISCREG_CANRESTORE, 0); + threadContexts[0]->setIntReg(NumIntArchRegs + 4, 0); //All windows are available to save into - threadContexts[0]->setMiscReg(MISCREG_CANSAVE, NWindows - 2); + //threadContexts[0]->setMiscReg(MISCREG_CANSAVE, NWindows - 2); + threadContexts[0]->setIntReg(NumIntArchRegs + 3, NWindows - 2); //All windows are "clean" - threadContexts[0]->setMiscReg(MISCREG_CLEANWIN, NWindows); + //threadContexts[0]->setMiscReg(MISCREG_CLEANWIN, NWindows); + threadContexts[0]->setIntReg(NumIntArchRegs + 5, NWindows); //Start with register window 0 threadContexts[0]->setMiscReg(MISCREG_CWP, 0); //Always use spill and fill traps 0 - threadContexts[0]->setMiscReg(MISCREG_WSTATE, 0); + //threadContexts[0]->setMiscReg(MISCREG_WSTATE, 0); + threadContexts[0]->setIntReg(NumIntArchRegs + 7, 0); //Set the trap level to 0 threadContexts[0]->setMiscReg(MISCREG_TL, 0); //Set the ASI register to something fixed diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index 65e6017da..29aca50c6 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) @@ -150,6 +151,72 @@ void RegFile::setIntReg(int intReg, const IntReg &val) intRegFile.setReg(intReg, val); } +int SparcISA::flattenIntIndex(ThreadContext * tc, int reg) +{ + int gl = tc->readMiscReg(MISCREG_GL); + int cwp = tc->readMiscReg(MISCREG_CWP); + //DPRINTF(Sparc, "Global Level = %d, Current Window Pointer = %d\n", gl, cwp); + int newReg; + if(reg < 8) + { + //Global register + //Put it in the appropriate set of globals + newReg = reg + gl * 8; + } + else if(reg < NumIntArchRegs) + { + //Regular windowed register + //Put it in the window pointed to by cwp + newReg = MaxGL * 8 + + ((reg - 8 - cwp * 16 + NWindows * 16) % (NWindows * 16)); + } + else if(reg < NumIntArchRegs + NumMicroIntRegs) + { + //Microcode register + //Displace from the end of the regular registers + newReg = reg - NumIntArchRegs + MaxGL * 8 + NWindows * 16; + } + else if(reg < 2 * NumIntArchRegs + NumMicroIntRegs) + { + reg -= (NumIntArchRegs + NumMicroIntRegs); + if(reg < 8) + { + //Global register from the next window + //Put it in the appropriate set of globals + newReg = reg + gl * 8; + } + else + { + //Windowed register from the previous window + //Put it in the window before the one pointed to by cwp + newReg = MaxGL * 8 + + ((reg - 8 - (cwp - 1) * 16 + NWindows * 16) % (NWindows * 16)); + } + } + else if(reg < 3 * NumIntArchRegs + NumMicroIntRegs) + { + reg -= (2 * NumIntArchRegs + NumMicroIntRegs); + if(reg < 8) + { + //Global register from the previous window + //Put it in the appropriate set of globals + newReg = reg + gl * 8; + } + else + { + //Windowed register from the next window + //Put it in the window after the one pointed to by cwp + newReg = MaxGL * 8 + + ((reg - 8 - (cwp + 1) * 16 + NWindows * 16) % (NWindows * 16)); + } + } + else + panic("Tried to flatten invalid register index %d!\n", reg); + DPRINTF(Sparc, "Flattened register %d to %d.\n", reg, newReg); + return newReg; + //return intRegFile.flattenIndex(reg); +} + void RegFile::serialize(std::ostream &os) { intRegFile.serialize(os); @@ -219,8 +286,8 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest) // ASRs - dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y)); - dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR)); +// dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y)); +// dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR)); dest->setMiscReg(MISCREG_ASI, src->readMiscReg(MISCREG_ASI)); dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK)); dest->setMiscReg(MISCREG_FPRS, src->readMiscReg(MISCREG_FPRS)); @@ -235,11 +302,11 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest) dest->setMiscReg(MISCREG_PSTATE, src->readMiscReg(MISCREG_PSTATE)); dest->setMiscReg(MISCREG_PIL, src->readMiscReg(MISCREG_PIL)); dest->setMiscReg(MISCREG_CWP, src->readMiscReg(MISCREG_CWP)); - dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE)); - dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE)); - dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN)); - dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN)); - dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE)); +// dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE)); +// dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE)); +// dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN)); +// dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN)); +// dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE)); dest->setMiscReg(MISCREG_GL, src->readMiscReg(MISCREG_GL)); // Hyperprivilged registers diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh index 9f33435f6..51f1b5fef 100644 --- a/src/arch/sparc/regfile.hh +++ b/src/arch/sparc/regfile.hh @@ -120,6 +120,8 @@ namespace SparcISA void changeContext(RegContextParam param, RegContextVal val); }; + int flattenIntIndex(ThreadContext * tc, int reg); + void copyRegs(ThreadContext *src, ThreadContext *dest); void copyMiscRegs(ThreadContext *src, ThreadContext *dest); diff --git a/src/arch/sparc/sparc_traits.hh b/src/arch/sparc/sparc_traits.hh new file mode 100644 index 000000000..d89ec1119 --- /dev/null +++ b/src/arch/sparc/sparc_traits.hh @@ -0,0 +1,56 @@ +/* + * 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 NumMicroIntRegs = 8; + +// 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/syscallreturn.hh b/src/arch/sparc/syscallreturn.hh index 75a063da1..d92b12790 100644 --- a/src/arch/sparc/syscallreturn.hh +++ b/src/arch/sparc/syscallreturn.hh @@ -33,58 +33,30 @@ #include <inttypes.h> +#include "sim/syscallreturn.hh" #include "arch/sparc/regfile.hh" - -class SyscallReturn -{ - public: - template <class T> - SyscallReturn(T v, bool s) - { - retval = (uint64_t)v; - success = s; - } - - template <class T> - SyscallReturn(T v) - { - success = (v >= 0); - retval = (uint64_t)v; - } - - ~SyscallReturn() {} - - SyscallReturn& operator=(const SyscallReturn& s) - { - retval = s.retval; - success = s.success; - return *this; - } - - bool successful() { return success; } - uint64_t value() { return retval; } - - private: - uint64_t retval; - bool success; -}; +#include "cpu/thread_context.hh" namespace SparcISA { static inline void setSyscallReturn(SyscallReturn return_value, - RegFile *regs) + ThreadContext * tc) { // 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 - regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEE); - regs->setIntReg(ReturnValueReg, return_value.value()); + tc->setIntReg(NumIntArchRegs + 2, + tc->readIntReg(NumIntArchRegs + 2) & 0xEE); + //tc->setMiscReg(MISCREG_CCR, tc->readMiscReg(MISCREG_CCR) & 0xEE); + tc->setIntReg(ReturnValueReg, return_value.value()); } else { // got an error, set XCC.C - regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x11); - regs->setIntReg(ReturnValueReg, return_value.value()); + tc->setIntReg(NumIntArchRegs + 2, + tc->readIntReg(NumIntArchRegs + 2) | 0x11); + //tc->setMiscReg(MISCREG_CCR, tc->readMiscReg(MISCREG_CCR) | 0x11); + tc->setIntReg(ReturnValueReg, -return_value.value()); } } }; 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 §ion) 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; } |