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
This commit is contained in:
Ali Saidi 2006-05-26 18:40:00 -04:00
parent 28ea972942
commit e04f60667a
7 changed files with 355 additions and 478 deletions

View file

@ -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;
}});
}

View file

@ -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);
'''
}};

View file

@ -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)
}};

View file

@ -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)
}};

View file

@ -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());
}
}

View file

@ -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
*/

View file

@ -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<MiscRegFile,
&MiscRegFile::processTickCompare> TickCompareEvent;
TickCompareEvent tickCompare;
typedef EventWrapper<MiscRegFile,
&MiscRegFile::processSTickCompare> STickCompareEvent;
STickCompareEvent sTickCompare;
typedef EventWrapper<MiscRegFile,
&MiscRegFile::processHSTickCompare> 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