From e04f60667af9884fa871935e4c1274bdf0311707 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 26 May 2006 18:40:00 -0400 Subject: [PATCH] Implement PR/HPR/ASR for full system Rip out storage in miscreg file that will never store anything Add storage and defines for Priv and Hyperpriv registers Change defines to match the spec register numbers Change the way misc registers are named to match the spec with offsets to deal with ASR/PR/HPR/FSR. Change contextval to an int since both global registers and windowed registers are indexed by int in UA2005. Use bitfields for things that are rarely used in decoder Instead of decoding ASR/PR/HPR and having a specfic instruction, use a generic instruction instead Still todo: Protect rdpr, rdhpr, wrpr, wrhpr with checks that fault in insufficient privs Deal with signaling interrupts on timer expiration Deal with writes to softint/PIL generating interrupts how those are vectored to the CPU Other misc: Instruction decoding needs major help! src/arch/sparc/isa/decoder.isa: Remove tons of MISCREG_XXXX defines that weren't used and ControlRegs in that were never used. Ones that were used rarely changed to bitfields. src/arch/sparc/isa/formats/integerop.isa: These seems like a whole lot of overkill in printing, but i'll leave it the way it is for now. Allow Ccr to be set at once src/arch/sparc/isa/formats/priv.isa: PrivTick is handled by miscreg now, don't need a seperate class for it src/arch/sparc/isa/operands.isa: prune the number of control regs down to a reasonable amount src/arch/sparc/isa_traits.hh: Replace 8 defines with 1 and flick some bits src/arch/sparc/process.cc: Better to clean the entire registers that specific bits which leads to indetermanistic behavior. src/arch/sparc/regfile.hh: Rip out storage that will never be backed by anything Add storage for Priv and Hyperpriv registers change defines to match the spec change the way misc registers are named to match the spec with offsets to deal with ASR/PR/HPR/FSR. change contextval to an int since both global registers and windowed registers are indexed by int in UA2005. --HG-- extra : convert_revision : 64276a3ea884eea70112e721f85a515946ded4c2 --- src/arch/sparc/isa/decoder.isa | 198 ++++------- src/arch/sparc/isa/formats/integerop.isa | 48 ++- src/arch/sparc/isa/formats/priv.isa | 48 +-- src/arch/sparc/isa/operands.isa | 83 +---- src/arch/sparc/isa_traits.hh | 8 +- src/arch/sparc/process.cc | 21 +- src/arch/sparc/regfile.hh | 427 ++++++++++++----------- 7 files changed, 355 insertions(+), 478 deletions(-) diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index c6e05bf6f..fa8832920 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -44,13 +44,13 @@ decode OP default Unknown::unknown() format Branch19 { 0x0: bpcci({{ - if(passesCondition(CcrIcc, COND2)) + if(passesCondition(Ccr<3:0>, COND2)) NNPC = xc->readPC() + disp; else handle_annul }}); 0x2: bpccx({{ - if(passesCondition(CcrXcc, COND2)) + if(passesCondition(Ccr<7:4>, COND2)) NNPC = xc->readPC() + disp; else handle_annul @@ -58,7 +58,7 @@ decode OP default Unknown::unknown() } } 0x2: Branch22::bicc({{ - if(passesCondition(CcrIcc, COND2)) + if(passesCondition(Ccr<3:0>, COND2)) NNPC = xc->readPC() + disp; else handle_annul @@ -124,17 +124,17 @@ decode OP default Unknown::unknown() 0x05: andn({{Rd = Rs1.udw & ~Rs2_or_imm13;}}); 0x06: orn({{Rd = Rs1.udw | ~Rs2_or_imm13;}}); 0x07: xnor({{Rd = ~(Rs1.udw ^ Rs2_or_imm13);}}); - 0x08: addc({{Rd = Rs1.sdw + Rs2_or_imm13 + CcrIccC;}}); + 0x08: addc({{Rd = Rs1.sdw + Rs2_or_imm13 + Ccr<0:0>;}}); 0x09: mulx({{Rd = Rs1 * Rs2_or_imm13;}}); 0x0A: umul({{ Rd = Rs1.udw<31:0> * Rs2_or_imm13<31:0>; - YValue = Rd<63:32>; + Y = Rd<63:32>; }}); 0x0B: smul({{ Rd.sdw = Rs1.sdw<31:0> * Rs2_or_imm13<31:0>; - YValue = Rd.sdw; + Y = Rd.sdw; }}); - 0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 + CcrIccC;}}); + 0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 + Ccr<0:0>}}); 0x0D: udivx({{ if(Rs2_or_imm13 == 0) fault = new DivisionByZero; else Rd.udw = Rs1.udw / Rs2_or_imm13; @@ -143,7 +143,7 @@ decode OP default Unknown::unknown() if(Rs2_or_imm13 == 0) fault = new DivisionByZero; else { - Rd.udw = ((YValue << 32) | Rs1.udw<31:0>) / Rs2_or_imm13; + Rd.udw = ((Y << 32) | Rs1.udw<31:0>) / Rs2_or_imm13; if(Rd.udw >> 32 != 0) Rd.udw = 0xFFFFFFFF; } @@ -153,7 +153,7 @@ decode OP default Unknown::unknown() fault = new DivisionByZero; else { - Rd.udw = ((int64_t)((YValue << 32) | Rs1.sdw<31:0>)) / Rs2_or_imm13.sdw; + Rd.udw = ((int64_t)((Y << 32) | Rs1.sdw<31:0>)) / Rs2_or_imm13.sdw; if(Rd.udw<63:31> != 0) Rd.udw = 0x7FFFFFFF; else if(Rd.udw<63:> && Rd.udw<62:31> != 0xFFFFFFFF) @@ -187,7 +187,7 @@ decode OP default Unknown::unknown() 0x17: IntOpCcRes::xnorcc({{Rd = ~(Rs1 ^ Rs2_or_imm13);}}); 0x18: addccc({{ int64_t resTemp, val2 = Rs2_or_imm13; - int64_t carryin = CcrIccC; + int64_t carryin = Ccr<0:0>; Rd = resTemp = Rs1 + val2 + carryin;}}, {{(Rs1<31:0> + val2<31:0> + carryin)<32:>}}, {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, @@ -198,16 +198,16 @@ decode OP default Unknown::unknown() 0x1A: umulcc({{ uint64_t resTemp; Rd = resTemp = Rs1.udw<31:0> * Rs2_or_imm13.udw<31:0>; - YValue = resTemp<63:32>;}}, + Y = resTemp<63:32>;}}, {{0}},{{0}},{{0}},{{0}}); 0x1B: smulcc({{ int64_t resTemp; Rd = resTemp = Rs1.sdw<31:0> * Rs2_or_imm13.sdw<31:0>; - YValue = resTemp<63:32>;}}, + Y = resTemp<63:32>;}}, {{0}},{{0}},{{0}},{{0}}); 0x1C: subccc({{ int64_t resTemp, val2 = Rs2_or_imm13; - int64_t carryin = CcrIccC; + int64_t carryin = Ccr<0:0>; Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}}, {{(~((Rs1<31:0> + (~(val2 + carryin))<31:0> + 1))<32:>)}}, {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, @@ -224,7 +224,7 @@ decode OP default Unknown::unknown() if(val2 == 0) fault = new DivisionByZero; else { - resTemp = (uint64_t)((YValue << 32) | Rs1.udw<31:0>) / val2; + resTemp = (uint64_t)((Y << 32) | Rs1.udw<31:0>) / val2; overflow = (resTemp<63:32> != 0); if(overflow) Rd = resTemp = 0xFFFFFFFF; else Rd = resTemp; @@ -240,7 +240,7 @@ decode OP default Unknown::unknown() if(val2 == 0) fault = new DivisionByZero; else { - Rd = resTemp = (int64_t)((YValue << 32) | Rs1.sdw<31:0>) / val2; + Rd = resTemp = (int64_t)((Y << 32) | Rs1.sdw<31:0>) / val2; overflow = (resTemp<63:31> != 0); underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); if(overflow) Rd = resTemp = 0x7FFFFFFF; @@ -295,12 +295,12 @@ decode OP default Unknown::unknown() int32_t multiplier = Rs1<31:0>; int32_t savedLSB = Rs1<0:>; multiplier = multiplier<31:1> | - ((CcrIccN - ^ CcrIccV) << 32); - if(!YValue<0:>) + ((Ccr<3:3> + ^ Ccr<1:1>) << 32); + if(!Y<0:>) multiplicand = 0; Rd = resTemp = multiplicand + multiplier; - YValue = YValue<31:1> | (savedLSB << 31);}}, + Y = Y<31:1> | (savedLSB << 31);}}, {{((multiplicand & 0xFFFFFFFF + multiplier & 0xFFFFFFFF) >> 31)}}, {{multiplicand<31:> == multiplier<31:> && multiplier<31:> != resTemp<31:>}}, {{((multiplicand >> 1) + (multiplier >> 1) + (multiplicand & multiplier & 0x1))<63:>}}, @@ -321,56 +321,27 @@ decode OP default Unknown::unknown() 0x0: sra({{Rd = Rs1.sw >> (I ? SHCNT32 : Rs2<4:0>);}}); 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}}); } - 0x28: decode RS1 { - 0x0: rdy({{Rd = YValue;}}); - 0x2: rdccr({{Rd = Ccr;}}); - 0x3: rdasi({{Rd = Asi;}}); - 0x4: PrivTick::rdtick({{Rd = Tick;}}); - 0x5: rdpc({{Rd = xc->readPC();}}); - 0x6: rdfprs({{Rd = Fprs;}}); - 0xF: decode I { - 0x0: Nop::membar({{/*Membar isn't needed yet*/}}); - 0x1: Nop::stbar({{/*Stbar isn't needed yet*/}}); - } - } - 0x2A: decode RS1 { - format Priv - { - 0x0: rdprtpc({{ - Rd = xc->readMiscReg(MISCREG_TPC_BASE + Tl); - }}); - 0x1: rdprtnpc({{ - Rd = xc->readMiscReg(MISCREG_TNPC_BASE + Tl); - }}); - 0x2: rdprtstate({{ - Rd = xc->readMiscReg(MISCREG_TSTATE_BASE + Tl); - }}); - 0x3: rdprtt({{ - Rd = xc->readMiscReg(MISCREG_TT_BASE + Tl); - }}); - 0x4: rdprtick({{Rd = Tick;}}); - 0x5: rdprtba({{Rd = Tba;}}); - 0x6: rdprpstate({{Rd = Pstate;}}); - 0x7: rdprtl({{Rd = Tl;}}); - 0x8: rdprpil({{Rd = Pil;}}); - 0x9: rdprcwp({{Rd = Cwp;}}); - 0xA: rdprcansave({{Rd = Cansave;}}); - 0xB: rdprcanrestore({{Rd = Canrestore;}}); - 0xC: rdprcleanwin({{Rd = Cleanwin;}}); - 0xD: rdprotherwin({{Rd = Otherwin;}}); - 0xE: rdprwstate({{Rd = Wstate;}}); - } - //The floating point queue isn't implemented right now. - 0xF: Trap::rdprfq({{fault = new IllegalInstruction;}}); - 0x1F: Priv::rdprver({{Rd = Ver;}}); - } + // XXX might want a format rdipr thing here + 0x28: rdasr({{ + Rd = xc->readMiscRegWithEffect(RS1 + AsrStart, fault); + }}); + 0x29: rdhpr({{ + // XXX Need to protect with format that traps non-priv/priv + // access + Rd = xc->readMiscRegWithEffect(RS1 + HprStart, fault); + }}); + 0x2A: rdpr({{ + // XXX Need to protect with format that traps non-priv + // access + Rd = xc->readMiscRegWithEffect(RS1 + PrStart, fault); + }}); 0x2B: BasicOperate::flushw({{ if(NWindows - 2 - Cansave == 0) { if(Otherwin) - fault = new SpillNOther(WstateOther); + fault = new SpillNOther(Wstate<5:3>); else - fault = new SpillNNormal(WstateNormal); + fault = new SpillNNormal(Wstate<2:0>); } }}); 0x2C: decode MOVCC3 @@ -379,13 +350,13 @@ decode OP default Unknown::unknown() 0x1: decode CC { 0x0: movcci({{ - if(passesCondition(CcrIcc, COND4)) + if(passesCondition(Ccr<3:0>, COND4)) Rd = Rs2_or_imm11; else Rd = Rd; }}); 0x2: movccx({{ - if(passesCondition(CcrXcc, COND4)) + if(passesCondition(Ccr<7:4>, COND4)) Rd = Rs2_or_imm11; else Rd = Rd; @@ -419,49 +390,23 @@ decode OP default Unknown::unknown() 0x6: movrg({{Rd = (Rs1.sdw > 0) ? Rs2_or_imm10 : Rd;}}); 0x7: movrge({{Rd = (Rs1.sdw >= 0) ? Rs2_or_imm10 : Rd;}}); } - 0x30: decode RD { - 0x0: wry({{Y = Rs1 ^ Rs2_or_imm13;}}); - 0x2: wrccr({{Ccr = Rs1 ^ Rs2_or_imm13;}}); - 0x3: wrasi({{Asi = Rs1 ^ Rs2_or_imm13;}}); - 0x6: wrfprs({{Asi = Rs1 ^ Rs2_or_imm13;}}); - 0xF: Trap::sir({{fault = new SoftwareInitiatedReset;}}); - } + 0x30: wrasr({{ + xc->setMiscRegWithEffect(RD + AsrStart, Rs1 ^ Rs2_or_imm13); + }}); 0x31: decode FCN { 0x0: BasicOperate::saved({{/*Boogy Boogy*/}}); 0x1: BasicOperate::restored({{/*Boogy Boogy*/}}); } - 0x32: decode RD { - format Priv - { - 0x0: wrprtpc({{ - xc->setMiscReg(MISCREG_TPC_BASE + Tl, - Rs1 ^ Rs2_or_imm13); - }}); - 0x1: wrprtnpc({{ - xc->setMiscReg(MISCREG_TNPC_BASE + Tl, - Rs1 ^ Rs2_or_imm13); - }}); - 0x2: wrprtstate({{ - xc->setMiscReg(MISCREG_TSTATE_BASE + Tl, - Rs1 ^ Rs2_or_imm13); - }}); - 0x3: wrprtt({{ - xc->setMiscReg(MISCREG_TT_BASE + Tl, - Rs1 ^ Rs2_or_imm13); - }}); - 0x4: wrprtick({{Tick = Rs1 ^ Rs2_or_imm13;}}); - 0x5: wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}}); - 0x6: wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}}); - 0x7: wrprtl({{Tl = Rs1 ^ Rs2_or_imm13;}}); - 0x8: wrprpil({{Pil = Rs1 ^ Rs2_or_imm13;}}); - 0x9: wrprcwp({{Cwp = Rs1 ^ Rs2_or_imm13;}}); - 0xA: wrprcansave({{Cansave = Rs1 ^ Rs2_or_imm13;}}); - 0xB: wrprcanrestore({{Canrestore = Rs1 ^ Rs2_or_imm13;}}); - 0xC: wrprcleanwin({{Cleanwin = Rs1 ^ Rs2_or_imm13;}}); - 0xD: wrprotherwin({{Otherwin = Rs1 ^ Rs2_or_imm13;}}); - 0xE: wrprwstate({{Wstate = Rs1 ^ Rs2_or_imm13;}}); - } - } + 0x32: wrpr({{ + // XXX Need to protect with format that traps non-priv + // access + xc->setMiscRegWithEffect(RD + PrStart, Rs1 ^ Rs2_or_imm13); + }}); + 0x33: wrhpr({{ + // XXX Need to protect with format that traps non-priv/priv + // access + xc->setMiscRegWithEffect(RD + HprStart, Rs1 ^ Rs2_or_imm13); + }}); 0x34: Trap::fpop1({{fault = new FpDisabled;}}); 0x35: Trap::fpop2({{fault = new FpDisabled;}}); 0x38: Branch::jmpl({{ @@ -492,9 +437,9 @@ decode OP default Unknown::unknown() if(Canrestore == 0) { if(Otherwin) - fault = new FillNOther(WstateOther); + fault = new FillNOther(Wstate<5:3>); else - fault = new FillNNormal(WstateNormal); + fault = new FillNNormal(Wstate<2:0>); } else { @@ -511,7 +456,7 @@ decode OP default Unknown::unknown() 0x3A: decode CC { 0x0: Trap::tcci({{ - if(passesCondition(CcrIcc, COND2)) + if(passesCondition(Ccr<3:0>, COND2)) { int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2); DPRINTF(Sparc, "The trap number is %d\n", lTrapNum); @@ -524,7 +469,7 @@ decode OP default Unknown::unknown() } }}); 0x2: Trap::tccx({{ - if(passesCondition(CcrXcc, COND2)) + if(passesCondition(Ccr<7:4>, COND2)) { int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2); DPRINTF(Sparc, "The trap number is %d\n", lTrapNum); @@ -545,9 +490,9 @@ decode OP default Unknown::unknown() if(Cansave == 0) { if(Otherwin) - fault = new SpillNOther(WstateOther); + fault = new SpillNOther(Wstate<5:3>); else - fault = new SpillNNormal(WstateNormal); + fault = new SpillNNormal(Wstate<2:0>); Cwp = (Cwp + 2) % NWindows; } else if(Cleanwin - Canrestore == 0) @@ -575,9 +520,9 @@ decode OP default Unknown::unknown() if(Canrestore == 0) { if(Otherwin) - fault = new FillNOther(WstateOther); + fault = new FillNOther(Wstate<5:3>); else - fault = new FillNNormal(WstateNormal); + fault = new FillNNormal(Wstate<2:0>); } else { @@ -594,23 +539,26 @@ decode OP default Unknown::unknown() 0x0: Priv::done({{ if(Tl == 0) return new IllegalInstruction; - Cwp = xc->readMiscReg(MISCREG_TSTATE_CWP_BASE + Tl); - Asi = xc->readMiscReg(MISCREG_TSTATE_ASI_BASE + Tl); - Ccr = xc->readMiscReg(MISCREG_TSTATE_CCR_BASE + Tl); - Pstate = xc->readMiscReg(MISCREG_TSTATE_PSTATE_BASE + Tl); - NPC = xc->readMiscReg(MISCREG_TNPC_BASE + Tl); - NNPC = NPC + 4; + + Cwp = Tstate<4:0>; + Pstate = Tstate<20:8>; + Asi = Tstate<31:24>; + Ccr = Tstate<39:32>; + Gl = Tstate<42:40>; + NPC = Tnpc; + NNPC = Tnpc + 4; Tl = Tl - 1; }}); 0x1: BasicOperate::retry({{ if(Tl == 0) return new IllegalInstruction; - Cwp = xc->readMiscReg(MISCREG_TSTATE_CWP_BASE + Tl); - Asi = xc->readMiscReg(MISCREG_TSTATE_ASI_BASE + Tl); - Ccr = xc->readMiscReg(MISCREG_TSTATE_CCR_BASE + Tl); - Pstate = xc->readMiscReg(MISCREG_TSTATE_PSTATE_BASE + Tl); - NPC = xc->readMiscReg(MISCREG_TPC_BASE + Tl); - NNPC = xc->readMiscReg(MISCREG_TNPC_BASE + Tl); + Cwp = Tstate<4:0>; + Pstate = Tstate<20:8>; + Asi = Tstate<31:24>; + Ccr = Tstate<39:32>; + Gl = Tstate<42:40>; + NPC = Tpc; + NNPC = Tnpc + 4; Tl = Tl - 1; }}); } diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa index 1fd87b1d3..1894ce541 100644 --- a/src/arch/sparc/isa/formats/integerop.isa +++ b/src/arch/sparc/isa/formats/integerop.isa @@ -316,22 +316,38 @@ let {{ return (header_output, decoder_output, exec_output, decode_block) calcCcCode = ''' - CcrIccN = (Rd >> 31) & 1; - CcrIccZ = ((Rd & 0xFFFFFFFF) == 0); - CcrXccN = (Rd >> 63) & 1; - CcrXccZ = (Rd == 0); - CcrIccV = %(ivValue)s; - CcrIccC = %(icValue)s; - CcrXccV = %(xvValue)s; - CcrXccC = %(xcValue)s; - DPRINTF(Sparc, "in = %%d\\n", CcrIccN); - DPRINTF(Sparc, "iz = %%d\\n", CcrIccZ); - DPRINTF(Sparc, "xn = %%d\\n", CcrXccN); - DPRINTF(Sparc, "xz = %%d\\n", CcrXccZ); - DPRINTF(Sparc, "iv = %%d\\n", CcrIccV); - DPRINTF(Sparc, "ic = %%d\\n", CcrIccC); - DPRINTF(Sparc, "xv = %%d\\n", CcrXccV); - DPRINTF(Sparc, "xc = %%d\\n", CcrXccC); + uint8_t tmp_ccriccc; + uint8_t tmp_ccriccv; + uint8_t tmp_ccriccz; + uint8_t tmp_ccriccn; + uint8_t tmp_ccrxccc; + uint8_t tmp_ccrxccv; + uint8_t tmp_ccrxccz; + uint8_t tmp_ccrxccn; + + tmp_ccriccn = (Rd >> 31) & 1; + tmp_ccriccz = ((Rd & 0xFFFFFFFF) == 0); + tmp_ccrxccn = (Rd >> 63) & 1; + tmp_ccrxccz = (Rd == 0); + tmp_ccriccv = %(ivValue)s & 1; + tmp_ccriccc = %(icValue)s & 1; + tmp_ccrxccv = %(xvValue)s & 1; + tmp_ccrxccc = %(xcValue)s & 1; + + Ccr = tmp_ccriccc | tmp_ccriccv << 1 | + tmp_ccriccz << 2 | tmp_ccriccn << 3| + tmp_ccrxccc << 4 | tmp_ccrxccv << 5| + tmp_ccrxccz << 6| tmp_ccrxccn << 7; + + + DPRINTF(Sparc, "in = %%d\\n", (uint16_t)tmp_ccriccn); + DPRINTF(Sparc, "iz = %%d\\n", (uint16_t)tmp_ccriccz); + DPRINTF(Sparc, "xn = %%d\\n", (uint16_t)tmp_ccrxccn); + DPRINTF(Sparc, "xz = %%d\\n", (uint16_t)tmp_ccrxccz); + DPRINTF(Sparc, "iv = %%d\\n", (uint16_t)tmp_ccriccv); + DPRINTF(Sparc, "ic = %%d\\n", (uint16_t)tmp_ccriccc); + DPRINTF(Sparc, "xv = %%d\\n", (uint16_t)tmp_ccrxccv); + DPRINTF(Sparc, "xc = %%d\\n", (uint16_t)tmp_ccrxccc); ''' }}; diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa index a8de22c0e..7df59d736 100644 --- a/src/arch/sparc/isa/formats/priv.isa +++ b/src/arch/sparc/isa/formats/priv.isa @@ -50,23 +50,6 @@ output header {{ const SymbolTable *symtab) const; }; - /** - * Base class for user mode "tick" access. - */ - class PrivTick : public SparcStaticInst - { - protected: - // Constructor - PrivTick(const char *mnem, ExtMachInst _machInst, - OpClass __opClass) : - SparcStaticInst(mnem, _machInst, __opClass) - { - } - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; - }; - /** * Base class for privelege mode operations with immediates. */ @@ -83,21 +66,6 @@ output header {{ int32_t imm; }; - /** - * Base class for user mode "tick" access with immediates. - */ - class PrivTickImm : public PrivTick - { - protected: - // Constructor - PrivTickImm(const char *mnem, ExtMachInst _machInst, - OpClass __opClass) : - PrivTick(mnem, _machInst, __opClass), imm(SIMM13) - { - } - - int32_t imm; - }; }}; output decoder {{ @@ -106,12 +74,6 @@ output decoder {{ { return "Privileged Instruction"; } - - std::string PrivTick::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { - return "Regular access to Tick"; - } }}; def template PrivExecute {{ @@ -154,16 +116,10 @@ let {{ // Primary format for integer operate instructions: def format Priv(code, *opt_flags) {{ - checkCode = "(!PstatePriv)" + checkCode = "((xc->readMiscReg(PrStart + MISCREG_PSTATE))<2:2>)" (header_output, decoder_output, exec_output, decode_block) = doPrivFormat(code, checkCode, name, Name, opt_flags) }}; -// Primary format for integer operate instructions: -def format PrivTick(code, *opt_flags) {{ - checkCode = "(!PstatePriv && TickNpt)" - (header_output, decoder_output, - exec_output, decode_block) = doPrivFormat(code, - checkCode, name, Name, opt_flags) -}}; + diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa index a89034e30..9e5c783e8 100644 --- a/src/arch/sparc/isa/operands.isa +++ b/src/arch/sparc/isa/operands.isa @@ -63,83 +63,26 @@ def operands {{ 'R1': ('IntReg', 'udw', '1', None, 7), 'R15': ('IntReg', 'udw', '15', 'IsInteger', 8), 'R16': ('IntReg', 'udw', '16', None, 9), + # Control registers - 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 1), - 'PstateAg': ('ControlReg', 'udw', 'MISCREG_PSTATE_AG', None, 2), - 'PstateIe': ('ControlReg', 'udw', 'MISCREG_PSTATE_IE', None, 3), - 'PstatePriv': ('ControlReg', 'udw', 'MISCREG_PSTATE_PRIV', None, 4), - 'PstateAm': ('ControlReg', 'udw', 'MISCREG_PSTATE_AM', None, 5), - 'PstatePef': ('ControlReg', 'udw', 'MISCREG_PSTATE_PEF', None, 6), - 'PstateRed': ('ControlReg', 'udw', 'MISCREG_PSTATE_RED', None, 7), - 'PstateMm': ('ControlReg', 'udw', 'MISCREG_PSTATE_MM', None, 8), - 'PstateTle': ('ControlReg', 'udw', 'MISCREG_PSTATE_TLE', None, 9), - 'PstateCle': ('ControlReg', 'udw', 'MISCREG_PSTATE_CLE', None, 10), - 'Tba': ('ControlReg', 'udw', 'MISCREG_TBA', None, 11), 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 12), - 'YValue': ('ControlReg', 'udw', 'MISCREG_Y_VALUE', None, 13), - 'Pil': ('ControlReg', 'udw', 'MISCREG_PIL', None, 14), - 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 15), - #'Tt': ('ControlReg', 'udw', 'MISCREG_TT_BASE + tl', None, 16), 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 17), - 'CcrIcc': ('ControlReg', 'udw', 'MISCREG_CCR_ICC', None, 18), - 'CcrIccC': ('ControlReg', 'udw', 'MISCREG_CCR_ICC_C', None, 19), - 'CcrIccV': ('ControlReg', 'udw', 'MISCREG_CCR_ICC_V', None, 20), - 'CcrIccZ': ('ControlReg', 'udw', 'MISCREG_CCR_ICC_Z', None, 21), - 'CcrIccN': ('ControlReg', 'udw', 'MISCREG_CCR_ICC_N', None, 22), - 'CcrXcc': ('ControlReg', 'udw', 'MISCREG_CCR_XCC', None, 23), - 'CcrXccC': ('ControlReg', 'udw', 'MISCREG_CCR_XCC_C', None, 22), - 'CcrXccV': ('ControlReg', 'udw', 'MISCREG_CCR_XCC_V', None, 23), - 'CcrXccZ': ('ControlReg', 'udw', 'MISCREG_CCR_XCC_Z', None, 24), - 'CcrXccN': ('ControlReg', 'udw', 'MISCREG_CCR_XCC_N', None, 25), 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 26), + + 'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 28), + 'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 28), + 'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 28), + 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 1), 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 27), - #'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 28), - 'Tick': ('ControlReg', 'udw', 'MISCREG_TICK', None, 29), - 'TickCounter': ('ControlReg', 'udw', 'MISCREG_TICK_COUNTER', None, 32), - 'TickNpt': ('ControlReg', 'udw', 'MISCREG_TICK_NPT', None, 33), + + 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 15), 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 34), 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 35), - 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 36), 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 37), + 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 36), 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 38), - 'WstateNormal': ('ControlReg', 'udw', 'MISCREG_WSTATE_NORMAL', None,39), - 'WstateOther': ('ControlReg', 'udw', 'MISCREG_WSTATE_OTHER', None, 40), - 'Ver': ('ControlReg', 'udw', 'MISCREG_VER', None, 41), - 'VerMaxwin': ('ControlReg', 'udw', 'MISCREG_VER_MAXWIN', None, 42), - 'VerMaxtl': ('ControlReg', 'udw', 'MISCREG_VER_MAXTL', None, 43), - 'VerMask': ('ControlReg', 'udw', 'MISCREG_VER_MASK', None, 44), - 'VerImpl': ('ControlReg', 'udw', 'MISCREG_VER_MASK', None, 45), - 'VerManuf': ('ControlReg', 'udw', 'MISCREG_VER_MANUF', None, 46), - 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 47), - 'FsrCexc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC', None, 48), - 'FsrCexcNxc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC_NXC', None, 49), - 'FsrCexcDzc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC_DZC', None, 50), - 'FsrCexcUfc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC_UFC', None, 51), - 'FsrCexcOfc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC_OFC', None, 52), - 'FsrCexcNvc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC_NVC', None, 53), - 'FsrAexc': ('ControlReg', 'udw', 'MISCREG_FSR_AEXC', None, 54), - 'FsrAexcNxc': ('ControlReg', 'udw', 'MISCREG_FSR_AEXC_NXC', None, 55), - 'FsrAexcDzc': ('ControlReg', 'udw', 'MISCREG_FSR_AEXC_DZC', None, 56), - 'FsrAexcUfc': ('ControlReg', 'udw', 'MISCREG_FSR_AEXC_UFC', None, 57), - 'FsrAexcOfc': ('ControlReg', 'udw', 'MISCREG_FSR_AEXC_OFC', None, 58), - 'FsrAexcNvc': ('ControlReg', 'udw', 'MISCREC_FSR_AEXC_NVC', None, 59), - 'FsrFcc0': ('ControlReg', 'udw', 'MISCREG_FSR_FCC0', None, 60), - 'FsrQne': ('ControlReg', 'udw', 'MISCREG_FSR_QNE', None, 61), - 'FsrFtt': ('ControlReg', 'udw', 'MISCREG_FSR_FTT', None, 62), - 'FsrVer': ('ControlReg', 'udw', 'MISCREG_FSR_VER', None, 63), - 'FsrNs': ('ControlReg', 'udw', 'MISCREG_FSR_NS', None, 64), - 'FsrTem': ('ControlReg', 'udw', 'MISCREG_FSR_TEM', None, 65), - 'FsrTemNxm': ('ControlReg', 'udw', 'MISCREG_FSR_TEM_NXM', None, 66), - 'FsrTemDzm': ('ControlReg', 'udw', 'MISCREG_FSR_TEM_DZM', None, 67), - 'FsrTemUfm': ('ControlReg', 'udw', 'MISCREG_FSR_TEM_UFM', None, 68), - 'FsrTemOfm': ('ControlReg', 'udw', 'MISCREG_FSR_TEM_OFM', None, 69), - 'FsrTemNvm': ('ControlReg', 'udw', 'MISCREG_FSR_TEM_NVM', None, 70), - 'FsrRd': ('ControlReg', 'udw', 'MISCREG_FSR_RD', None, 71), - 'FsrFcc1': ('ControlReg', 'udw', 'MISCREG_FSR_FCC1', None, 72), - 'FsrFcc2': ('ControlReg', 'udw', 'MISCREG_FSR_FCC2', None, 73), - 'FsrFcc3': ('ControlReg', 'udw', 'MISCREG_FSR_FCC3', None, 74), - 'Fprs': ('ControlReg', 'udw', 'MISCREG_FPRS', None, 75), - 'FprsDl': ('ControlReg', 'udw', 'MISCREG_FPRS_DL', None, 76), - 'FprsDu': ('ControlReg', 'udw', 'MISCREG_FPRS_DU', None, 77), - 'FprsFef': ('ControlReg', 'udw', 'MISCREG_FPRS_FEF', None, 78) + 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 12), + + 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 47) + }}; diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index 453d14664..2b4d89441 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -172,12 +172,12 @@ namespace SparcISA // 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 - regs->setMiscReg(MISCREG_CCR_XCC_C, 0); + // no error, clear XCC.C + regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEF); regs->setIntReg(ReturnValueReg, return_value.value()); } else { - // got an error, return details - regs->setMiscReg(MISCREG_CCR_XCC_C, 1); + // got an error, set XCC.C + regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x10); regs->setIntReg(ReturnValueReg, return_value.value()); } } diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 250c1bec4..fe6692cc3 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -110,22 +110,13 @@ SparcLiveProcess::startup() //From the SPARC ABI //The process runs in user mode - execContexts[0]->setMiscRegWithEffect(MISCREG_PSTATE_PRIV, 0); - //Interrupts are enabled - execContexts[0]->setMiscRegWithEffect(MISCREG_PSTATE_IE, 1); - //Round to nearest - execContexts[0]->setMiscRegWithEffect(MISCREG_FSR_RD, 0); - //Floating point traps are not enabled - execContexts[0]->setMiscRegWithEffect(MISCREG_FSR_TEM, 0); - //Turn non standard mode off - execContexts[0]->setMiscRegWithEffect(MISCREG_FSR_NS, 0); - //The floating point queue is empty - execContexts[0]->setMiscRegWithEffect(MISCREG_FSR_QNE, 0); - //There are no accrued eexecContext[0]eptions - execContexts[0]->setMiscRegWithEffect(MISCREG_FSR_AEXC, 0); - //There are no current eexecContext[0]eptions - execContexts[0]->setMiscRegWithEffect(MISCREG_FSR_CEXC, 0); + execContexts[0]->setMiscRegWithEffect(MISCREG_PSTATE, 0x02); + //Setup default FP state + execContexts[0]->setMiscReg(MISCREG_FSR, 0); + + execContexts[0]->setMiscReg(MISCREG_TICK, 0); + // /* * Register window management registers */ diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh index 96f36eb91..4dfdc0cf3 100644 --- a/src/arch/sparc/regfile.hh +++ b/src/arch/sparc/regfile.hh @@ -32,6 +32,7 @@ #include "arch/sparc/faults.hh" #include "base/trace.hh" #include "sim/byteswap.hh" +#include "sim/eventq.hh" #include "sim/host.hh" class Checkpoint; @@ -42,7 +43,7 @@ namespace SparcISA typedef uint8_t RegIndex; // MAXTL - maximum trap level - const int MaxPTL = 6; + const int MaxPTL = 2; const int MaxTL = 6; const int MaxGL = 3; const int MaxPGL = 2; @@ -50,6 +51,15 @@ namespace SparcISA // NWINDOWS - number of register windows, can be 3 to 32 const int NWindows = 32; + + const int AsrStart = 0; + const int PrStart = 32; + const int HprStart = 64; + const int MiscStart = 96; + + + const uint64_t Bit64 = 0x8000000000000000; + class IntRegFile { protected: @@ -277,156 +287,83 @@ namespace SparcISA enum MiscRegIndex { - MISCREG_PSTATE, - MISCREG_PSTATE_AG, - MISCREG_PSTATE_IE, - MISCREG_PSTATE_PRIV, - MISCREG_PSTATE_AM, - MISCREG_PSTATE_PEF, - MISCREG_PSTATE_RED, - MISCREG_PSTATE_MM, - MISCREG_PSTATE_TLE, - MISCREG_PSTATE_CLE, - MISCREG_TBA, - MISCREG_Y, - MISCREG_Y_VALUE, - MISCREG_PIL, - MISCREG_CWP, - MISCREG_TT_BASE, - MISCREG_TT_END = MISCREG_TT_BASE + MaxTL, - MISCREG_CCR, - MISCREG_CCR_ICC, - MISCREG_CCR_ICC_C, - MISCREG_CCR_ICC_V, - MISCREG_CCR_ICC_Z, - MISCREG_CCR_ICC_N, - MISCREG_CCR_XCC, - MISCREG_CCR_XCC_C, - MISCREG_CCR_XCC_V, - MISCREG_CCR_XCC_Z, - MISCREG_CCR_XCC_N, - MISCREG_ASI, - MISCREG_TL, - MISCREG_TPC_BASE, - MISCREG_TPC_END = MISCREG_TPC_BASE + MaxTL, - MISCREG_TNPC_BASE, - MISCREG_TNPC_END = MISCREG_TNPC_BASE + MaxTL, - MISCREG_TSTATE_BASE, - MISCREG_TSTATE_END = MISCREG_TSTATE_BASE + MaxTL, - MISCREG_TSTATE_CWP_BASE, - MISCREG_TSTATE_CWP_END = MISCREG_TSTATE_CWP_BASE + MaxTL, - MISCREG_TSTATE_PSTATE_BASE, - MISCREG_TSTATE_PSTATE_END = MISCREG_TSTATE_PSTATE_BASE + MaxTL, - MISCREG_TSTATE_ASI_BASE, - MISCREG_TSTATE_ASI_END = MISCREG_TSTATE_ASI_BASE + MaxTL, - MISCREG_TSTATE_CCR_BASE, - MISCREG_TSTATE_CCR_END = MISCREG_TSTATE_CCR_BASE + MaxTL, - MISCREG_TICK, - MISCREG_TICK_COUNTER, - MISCREG_TICK_NPT, - MISCREG_CANSAVE, - MISCREG_CANRESTORE, - MISCREG_OTHERWIN, - MISCREG_CLEANWIN, - MISCREG_WSTATE, - MISCREG_WSTATE_NORMAL, - MISCREG_WSTATE_OTHER, - MISCREG_VER, - MISCREG_VER_MAXWIN, - MISCREG_VER_MAXTL, - MISCREG_VER_MASK, - MISCREG_VER_IMPL, - MISCREG_VER_MANUF, - MISCREG_FSR, - MISCREG_FSR_CEXC, - MISCREG_FSR_CEXC_NXC, - MISCREG_FSR_CEXC_DZC, - MISCREG_FSR_CEXC_UFC, - MISCREG_FSR_CEXC_OFC, - MISCREG_FSR_CEXC_NVC, - MISCREG_FSR_AEXC, - MISCREG_FSR_AEXC_NXC, - MISCREG_FSR_AEXC_DZC, - MISCREG_FSR_AEXC_UFC, - MISCREG_FSR_AEXC_OFC, - MISCREG_FSR_AEXC_NVC, - MISCREG_FSR_FCC0, - MISCREG_FSR_QNE, - MISCREG_FSR_FTT, - MISCREG_FSR_VER, - MISCREG_FSR_NS, - MISCREG_FSR_TEM, - MISCREG_FSR_TEM_NXM, - MISCREG_FSR_TEM_DZM, - MISCREG_FSR_TEM_UFM, - MISCREG_FSR_TEM_OFM, - MISCREG_FSR_TEM_NVM, - MISCREG_FSR_RD, - MISCREG_FSR_FCC1, - MISCREG_FSR_FCC2, - MISCREG_FSR_FCC3, - MISCREG_FPRS, - MISCREG_FPRS_DL, - MISCREG_FPRS_DU, - MISCREG_FPRS_FEF, - numMiscRegs + /** Ancillary State Registers */ + MISCREG_Y = AsrStart + 0, + MISCREG_CCR = AsrStart + 2, + MISCREG_ASI = AsrStart + 3, + MISCREG_TICK = AsrStart + 4, + MISCREG_PC = AsrStart + 5, + MISCREG_FPRS = AsrStart + 6, + MISCREG_PCR = AsrStart + 16, + MISCREG_PIC = AsrStart + 17, + MISCREG_GSR = AsrStart + 19, + MISCREG_SOFTINT_SET = AsrStart + 20, + MISCREG_SOFTINT_CLR = AsrStart + 21, + MISCREG_SOFTINT = AsrStart + 22, + MISCREG_TICK_CMPR = AsrStart + 23, + MISCREG_STICK = AsrStart + 24, + MISCREG_STICK_CMPR = AsrStart + 25, + + /** Privilged Registers */ + MISCREG_TPC = PrStart + 0, + MISCREG_TNPC = PrStart + 1, + MISCREG_TSTATE = PrStart + 2, + MISCREG_TT = PrStart + 3, + MISCREG_PRIVTICK = PrStart + 4, + MISCREG_TBA = PrStart + 5, + MISCREG_PSTATE = PrStart + 6, + MISCREG_TL = PrStart + 7, + MISCREG_PIL = PrStart + 8, + MISCREG_CWP = PrStart + 9, + MISCREG_CANSAVE = PrStart + 10, + MISCREG_CANRESTORE = PrStart + 11, + MISCREG_CLEANWIN = PrStart + 12, + MISCREG_OTHERWIN = PrStart + 13, + MISCREG_WSTATE = PrStart + 14, + MISCREG_GL = PrStart + 16, + + /** Hyper privileged registers */ + MISCREG_HPSTATE = HprStart + 0, + MISCREG_HTSTATE = HprStart + 1, + MISCREG_HINTP = HprStart + 3, + MISCREG_HTBA = HprStart + 5, + MISCREG_HVER = HprStart + 6, + MISCREG_STRAND_STS_REG = HprStart + 16, + MISCREG_HSTICK_CMPR = HprStart + 31, + + /** Floating Point Status Register */ + MISCREG_FSR = MiscStart + 0 + }; // The control registers, broken out into fields class MiscRegFile { private: - union - { - uint16_t pstate; // Process State Register - struct - { - uint16_t ag:1; // Alternate Globals - uint16_t ie:1; // Interrupt enable - uint16_t priv:1; // Privelege mode - uint16_t am:1; // Address mask - uint16_t pef:1; // PSTATE enable floating-point - uint16_t red:1; // RED (reset, error, debug) state - uint16_t mm:2; // Memory Model - uint16_t tle:1; // Trap little-endian - uint16_t cle:1; // Current little-endian - } pstateFields; - }; - uint64_t tba; // Trap Base Address - union - { + + /* ASR Registers */ + union { uint64_t y; // Y (used in obsolete multiplication) - struct - { + struct { uint64_t value:32; // The actual value stored in y uint64_t :32; // reserved bits } yFields; }; - uint8_t pil; // Process Interrupt Register - uint8_t cwp; // Current Window Pointer - uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured - // on the previous level) - union - { + union { uint8_t ccr; // Condition Code Register - struct - { - union - { + struct { + union { uint8_t icc:4; // 32-bit condition codes - struct - { + struct { uint8_t c:1; // Carry uint8_t v:1; // Overflow uint8_t z:1; // Zero uint8_t n:1; // Negative } iccFields; }; - union - { + union { uint8_t xcc:4; // 64-bit condition codes - struct - { + struct { uint8_t c:1; // Carry uint8_t v:1; // Overflow uint8_t z:1; // Zero @@ -436,73 +373,143 @@ namespace SparcISA } ccrFields; }; uint8_t asi; // Address Space Identifier - uint8_t tl; // Trap Level + union { + uint64_t tick; // Hardware clock-tick counter + struct { + int64_t counter:63; // Clock-tick count + uint64_t npt:1; // Non-priveleged trap + } tickFields; + }; + union { + uint8_t fprs; // Floating-Point Register State + struct { + uint8_t dl:1; // Dirty lower + uint8_t du:1; // Dirty upper + uint8_t fef:1; // FPRS enable floating-Point + } fprsFields; + }; + union { + uint64_t softint; + struct { + uint64_t tm:1; + uint64_t int_level:14; + uint64_t sm:1; + } softintFields; + }; + union { + uint64_t tick_cmpr; // Hardware tick compare registers + struct { + uint64_t tick_cmpr:63; // Clock-tick count + uint64_t int_dis:1; // Non-priveleged trap + } tick_cmprFields; + }; + union { + uint64_t stick; // Hardware clock-tick counter + struct { + int64_t counter:63; // Clock-tick count + uint64_t npt:1; // Non-priveleged trap + } stickFields; + }; + union { + uint64_t stick_cmpr; // Hardware tick compare registers + struct { + uint64_t tick_cmpr:63; // Clock-tick count + uint64_t int_dis:1; // Non-priveleged trap + } stick_cmprFields; + }; + + + /* Privileged Registers */ uint64_t tpc[MaxTL]; // Trap Program Counter (value from // previous trap level) uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from // previous trap level) - union - { + union { uint64_t tstate[MaxTL]; // Trap State - struct - { + struct { //Values are from previous trap level uint64_t cwp:5; // Current Window Pointer - uint64_t :2; // Reserved bits - uint64_t pstate:10; // Process State - uint64_t :6; // Reserved bits + uint64_t :3; // Reserved bits + uint64_t pstate:13; // Process State + uint64_t :3; // Reserved bits uint64_t asi:8; // Address Space Identifier uint64_t ccr:8; // Condition Code Register + uint64_t gl:8; // Global level } tstateFields[MaxTL]; }; - union - { - uint64_t tick; // Hardware clock-tick counter - struct - { - uint64_t counter:63; // Clock-tick count - uint64_t npt:1; // Non-priveleged trap - } tickFields; + uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured + // on the previous level) + uint64_t tba; // Trap Base Address + + union { + uint16_t pstate; // Process State Register + struct { + uint16_t :1; // reserved + uint16_t ie:1; // Interrupt enable + uint16_t priv:1; // Privelege mode + uint16_t am:1; // Address mask + uint16_t pef:1; // PSTATE enable floating-point + uint16_t :1; // reserved2 + uint16_t mm:2; // Memory Model + uint16_t tle:1; // Trap little-endian + uint16_t cle:1; // Current little-endian + } pstateFields; }; + uint8_t tl; // Trap Level + uint8_t pil; // Process Interrupt Register + uint8_t cwp; // Current Window Pointer uint8_t cansave; // Savable windows uint8_t canrestore; // Restorable windows - uint8_t otherwin; // Other windows uint8_t cleanwin; // Clean windows - union - { + uint8_t otherwin; // Other windows + union { uint8_t wstate; // Window State - struct - { + struct { uint8_t normal:3; // Bits TT<4:2> are set to on a normal // register window trap uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin" // register window trap } wstateFields; }; - union - { - uint64_t ver; // Version - struct - { - uint64_t maxwin:5; // Max CWP value - uint64_t :2; // Reserved bits - uint64_t maxtl:8; // Maximum trap level - uint64_t :8; // Reserved bits - uint64_t mask:8; // Processor mask set revision number - uint64_t impl:16; // Implementation identification number - uint64_t manuf:16; // Manufacturer code - } verFields; + uint8_t gl; // Global level register + + + /** Hyperprivileged Registers */ + union { + uint64_t hpstate; // Hyperprivileged State Register + struct { + uint8_t tlz: 1; + uint8_t :1; + uint8_t hpriv:1; + uint8_t :2; + uint8_t red:1; + uint8_t :4; + uint8_t ibe:1; + uint8_t id:1; + } hpstateFields; }; - union - { + + uint64_t htstate[MaxTL]; // Hyperprivileged Trap State Register + uint64_t hintp; + uint64_t htba; // Hyperprivileged Trap Base Address register + union { + uint64_t hstick_cmpr; // Hardware tick compare registers + struct { + uint64_t tick_cmpr:63; // Clock-tick count + uint64_t int_dis:1; // Non-priveleged trap + } hstick_cmprFields; + }; + + uint64_t strandStatusReg; // Per strand status register + + + /** Floating point misc registers. */ + union { uint64_t fsr; // Floating-Point State Register - struct - { - union - { + struct { + union { uint64_t cexc:5; // Current excpetion - struct - { + struct { uint64_t nxc:1; // Inexact uint64_t dzc:1; // Divide by zero uint64_t ufc:1; // Underflow @@ -510,11 +517,9 @@ namespace SparcISA uint64_t nvc:1; // Invalid operand } cexcFields; }; - union - { + union { uint64_t aexc:5; // Accrued exception - struct - { + struct { uint64_t nxc:1; // Inexact uint64_t dzc:1; // Divide by zero uint64_t ufc:1; // Underflow @@ -530,11 +535,9 @@ namespace SparcISA uint64_t ver:3; // Version (of the FPU) uint64_t :2; // Reserved bits uint64_t ns:1; // Nonstandard floating point - union - { + union { uint64_t tem:5; // Trap Enable Mask - struct - { + struct { uint64_t nxm:1; // Inexact uint64_t dzm:1; // Divide by zero uint64_t ufm:1; // Underflow @@ -550,16 +553,24 @@ namespace SparcISA uint64_t :26; // Reserved bits } fsrFields; }; - union - { - uint8_t fprs; // Floating-Point Register State - struct - { - uint8_t dl:1; // Dirty lower - uint8_t du:1; // Dirty upper - uint8_t fef:1; // FPRS enable floating-Point - } fprsFields; - }; + + // These need to check the int_dis field and if 0 then + // set appropriate bit in softint and checkinterrutps on the cpu + void processTickCompare() { panic("tick compare not implemented\n"); } + void processSTickCompare(){ panic("tick compare not implemented\n"); } + void processHSTickCompare(){ panic("tick compare not implemented\n"); } + + typedef EventWrapper TickCompareEvent; + TickCompareEvent tickCompare; + + typedef EventWrapper STickCompareEvent; + STickCompareEvent sTickCompare; + + typedef EventWrapper HSTickCompareEvent; + HSTickCompareEvent hSTickCompare; public: @@ -572,6 +583,7 @@ namespace SparcISA //on reset Trap which sets the processor into the following state. //Bits that aren't set aren't defined on startup. tl = MaxTL; + gl = MaxGL; tt[tl] = PowerOnReset.trapType(); pstateFields.mm = 0; //Total Store Order pstateFields.red = 1; //Enter RED_State @@ -581,9 +593,18 @@ namespace SparcISA pstateFields.ag = 1; //Globals are replaced with alternate globals pstateFields.tle = 0; //Big Endian mode for traps pstateFields.cle = 0; //Big Endian mode for non-traps - tickFields.counter = 0; //The TICK register is unreadable by - tickFields.npt = 1; //The TICK register is unreadable by - //non-priveleged software + tickFields.counter = 0; //The TICK register is unreadable bya + tickFields.npt = 1; //The TICK register is unreadable by by !priv + tick_cmpr.int_dis = 1; // disable timer compare interrupts + stickFields.counter = 0; //The TICK register is unreadable by + stickFields.npt = 1; //The TICK register is unreadable by by !priv + hpstateFields.id = 1; + hpstateFields.ibe = 0; + hpstateFields.red = 1; + hpstateFields.hpriv = 1; + hpstateFields.tlz = 0; // this is a guess + + #else /* //This sets up the initial state of the processor for usermode processes pstateFields.priv = 0; //Process runs in user mode @@ -604,6 +625,7 @@ namespace SparcISA } MiscRegFile() + : tickCompare(this), sTickCompare(this), hSTickCompare(this) { reset(); } @@ -622,6 +644,10 @@ namespace SparcISA void unserialize(Checkpoint * cp, const std::string & section); void copyMiscRegs(ExecContext * xc); + + bool isHyperPriv() { return hpstateFields.hpriv; } + bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; } + bool isNonPriv() { return !isPriv(); } }; typedef union @@ -775,22 +801,17 @@ namespace SparcISA CONTEXT_CWP, CONTEXT_GLOBALS }; - - union ContextVal - { - MiscReg reg; - int globalLevel; - }; + typedef int ContextVal; void changeContext(ContextParam param, ContextVal val) { switch(param) { case CONTEXT_CWP: - intRegFile.setCWP(val.reg); + intRegFile.setCWP(val); break; case CONTEXT_GLOBALS: - intRegFile.setGlobals(val.globalLevel); + intRegFile.setGlobals(val); break; default: panic("Tried to set illegal context parameter in the SPARC regfile.\n"); @@ -802,6 +823,8 @@ namespace SparcISA void copyMiscRegs(ExecContext *src, ExecContext *dest); + int InterruptLevel(uint64_t softint); + } // namespace SparcISA #endif