Merge ktlim@zizzer:/bk/newmem
into zamp.eecs.umich.edu:/z/ktlim2/clean/o3-merge/newmem --HG-- extra : convert_revision : 35e2ff6ce62281299ad98dca64ba04a3a8a6757c
This commit is contained in:
@@ -283,7 +283,7 @@ void enterREDState(ThreadContext *tc)
|
||||
HPSTATE |= (1 << 5);
|
||||
//HPSTATE.hpriv = 1
|
||||
HPSTATE |= (1 << 2);
|
||||
tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
|
||||
tc->setMiscRegWithEffect(MISCREG_HPSTATE, HPSTATE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -491,11 +491,11 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
|
||||
}
|
||||
}
|
||||
|
||||
void getREDVector(Addr & PC, Addr & NPC)
|
||||
void getREDVector(MiscReg TT, Addr & PC, Addr & NPC)
|
||||
{
|
||||
//XXX The following constant might belong in a header file.
|
||||
const Addr RSTVAddr = 0xFFFFFFFFF0000000ULL;
|
||||
PC = RSTVAddr | 0xA0;
|
||||
PC = RSTVAddr | ((TT << 5) & 0xFF);
|
||||
NPC = PC + sizeof(MachInst);
|
||||
}
|
||||
|
||||
@@ -519,6 +519,7 @@ void getPrivVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT, MiscRe
|
||||
|
||||
void SparcFaultBase::invoke(ThreadContext * tc)
|
||||
{
|
||||
panic("Invoking a second fault!\n");
|
||||
FaultBase::invoke(tc);
|
||||
countStat()++;
|
||||
|
||||
@@ -543,7 +544,7 @@ void SparcFaultBase::invoke(ThreadContext * tc)
|
||||
|
||||
if(HPSTATE & (1 << 5) || TL == MaxTL - 1)
|
||||
{
|
||||
getREDVector(PC, NPC);
|
||||
getREDVector(5, PC, NPC);
|
||||
enterREDState(tc);
|
||||
doREDFault(tc, TT);
|
||||
}
|
||||
@@ -583,28 +584,41 @@ void PowerOnReset::invoke(ThreadContext * 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.
|
||||
|
||||
tc->setMiscReg(MISCREG_TL, MaxTL);
|
||||
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 red and hpriv, set everything else to 0
|
||||
tc->setMiscReg(MISCREG_HPSTATE, (1 << 5) | (1 << 2));
|
||||
|
||||
//The tick register is unreadable by nonprivileged software
|
||||
tc->setMiscReg(MISCREG_TICK, 1ULL << 63);
|
||||
|
||||
Addr PC, NPC;
|
||||
getREDVector(trapType(), PC, NPC);
|
||||
tc->setPC(PC);
|
||||
tc->setNextPC(NPC);
|
||||
tc->setNextNPC(NPC + sizeof(MachInst));
|
||||
|
||||
//These registers are specified as "undefined" after a POR, and they
|
||||
//should have reasonable values after the miscregfile is reset
|
||||
/*
|
||||
tl = MaxTL;
|
||||
gl = MaxGL;
|
||||
|
||||
tickFields.counter = 0; //The TICK register is unreadable bya
|
||||
tickFields.npt = 1; //The TICK register is unreadable by by !priv
|
||||
|
||||
softint = 0; // Clear all the soft interrupt bits
|
||||
tick_cmprFields.int_dis = 1; // disable timer compare interrupts
|
||||
// Clear all the soft interrupt bits
|
||||
softint = 0;
|
||||
// disable timer compare interrupts, reset tick_cmpr
|
||||
tc->setMiscReg(MISCREG_
|
||||
tick_cmprFields.int_dis = 1;
|
||||
tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
|
||||
stickFields.npt = 1; //The TICK register is unreadable by by !priv
|
||||
stick_cmprFields.int_dis = 1; // disable timer compare interrupts
|
||||
stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
|
||||
|
||||
tt[tl] = _trapType;
|
||||
pstate = 0; // fields 0 but pef
|
||||
pstateFields.pef = 1;
|
||||
|
||||
hpstate = 0;
|
||||
hpstateFields.red = 1;
|
||||
hpstateFields.hpriv = 1;
|
||||
hpstateFields.tlz = 0; // this is a guess
|
||||
hintp = 0; // no interrupts pending
|
||||
hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
|
||||
hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
|
||||
|
||||
@@ -83,7 +83,7 @@ IntReg IntRegFile::readReg(int intReg)
|
||||
else if((intReg -= NumRegularIntRegs) < NumMicroIntRegs)
|
||||
val = microRegs[intReg];
|
||||
else
|
||||
panic("Tried to read non-existant integer register\n");
|
||||
panic("Tried to read non-existant integer register %d, %d\n", NumRegularIntRegs + NumMicroIntRegs + intReg, intReg);
|
||||
|
||||
DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val);
|
||||
return val;
|
||||
@@ -123,7 +123,7 @@ void IntRegFile::setCWP(int cwp)
|
||||
|
||||
void IntRegFile::setGlobals(int gl)
|
||||
{
|
||||
DPRINTF(Sparc, "Now using %d globals", gl);
|
||||
DPRINTF(Sparc, "Now using %d globals\n", gl);
|
||||
|
||||
regView[Globals] = regGlobals[gl];
|
||||
offset[Globals] = RegGlobalOffset + gl * RegsPerFrame;
|
||||
|
||||
@@ -189,6 +189,7 @@ output decoder {{
|
||||
const int MaxOutput = 16;
|
||||
const int MaxLocal = 24;
|
||||
const int MaxInput = 32;
|
||||
const int MaxMicroReg = 33;
|
||||
if (reg == FramePointerReg)
|
||||
ccprintf(os, "%%fp");
|
||||
else if (reg == StackPointerReg)
|
||||
@@ -201,6 +202,8 @@ output decoder {{
|
||||
ccprintf(os, "%%l%d", reg - MaxOutput);
|
||||
else if(reg < MaxInput)
|
||||
ccprintf(os, "%%i%d", reg - MaxLocal);
|
||||
else if(reg < MaxMicroReg)
|
||||
ccprintf(os, "%%u%d", reg - MaxInput);
|
||||
else {
|
||||
ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
|
||||
}
|
||||
|
||||
@@ -41,15 +41,16 @@ decode OP default Unknown::unknown()
|
||||
0x0: Trap::illtrap({{fault = new IllegalInstruction;}});
|
||||
format BranchN
|
||||
{
|
||||
//bpcc
|
||||
0x1: decode COND2
|
||||
{
|
||||
//Branch Always
|
||||
0x8: decode A
|
||||
{
|
||||
0x0: b(19, {{
|
||||
0x0: bpa(19, {{
|
||||
NNPC = xc->readPC() + disp;
|
||||
}});
|
||||
0x1: b(19, {{
|
||||
0x1: bpa(19, {{
|
||||
NPC = xc->readPC() + disp;
|
||||
NNPC = NPC + 4;
|
||||
}}, ',a');
|
||||
@@ -57,10 +58,10 @@ decode OP default Unknown::unknown()
|
||||
//Branch Never
|
||||
0x0: decode A
|
||||
{
|
||||
0x0: bn(19, {{
|
||||
0x0: bpn(19, {{
|
||||
NNPC = NNPC;//Don't do anything
|
||||
}});
|
||||
0x1: bn(19, {{
|
||||
0x1: bpn(19, {{
|
||||
NPC = xc->readNextPC() + 4;
|
||||
NNPC = NPC + 4;
|
||||
}}, ',a');
|
||||
@@ -81,12 +82,38 @@ decode OP default Unknown::unknown()
|
||||
}});
|
||||
}
|
||||
}
|
||||
0x2: bicc(22, {{
|
||||
if(passesCondition(Ccr<3:0>, COND2))
|
||||
NNPC = xc->readPC() + disp;
|
||||
else
|
||||
handle_annul
|
||||
}});
|
||||
//bicc
|
||||
0x2: decode COND2
|
||||
{
|
||||
//Branch Always
|
||||
0x8: decode A
|
||||
{
|
||||
0x0: ba(22, {{
|
||||
NNPC = xc->readPC() + disp;
|
||||
}});
|
||||
0x1: ba(22, {{
|
||||
NPC = xc->readPC() + disp;
|
||||
NNPC = NPC + 4;
|
||||
}}, ',a');
|
||||
}
|
||||
//Branch Never
|
||||
0x0: decode A
|
||||
{
|
||||
0x0: bn(22, {{
|
||||
NNPC = NNPC;//Don't do anything
|
||||
}});
|
||||
0x1: bn(22, {{
|
||||
NPC = xc->readNextPC() + 4;
|
||||
NNPC = NPC + 4;
|
||||
}}, ',a');
|
||||
}
|
||||
default: bicc(22, {{
|
||||
if(passesCondition(Ccr<3:0>, COND2))
|
||||
NNPC = xc->readPC() + disp;
|
||||
else
|
||||
handle_annul
|
||||
}});
|
||||
}
|
||||
}
|
||||
0x3: decode RCOND2
|
||||
{
|
||||
@@ -380,7 +407,15 @@ decode OP default Unknown::unknown()
|
||||
0x17: Priv::rdtick_cmpr({{Rd = TickCmpr;}});
|
||||
0x18: PrivCheck::rdstick({{Rd = Stick}}, {{Stick<63:>}});
|
||||
0x19: Priv::rdstick_cmpr({{Rd = StickCmpr;}});
|
||||
//0x1A-0x1F should cause an illegal instruction exception
|
||||
0x1A: Priv::rdstrand_sts_reg({{
|
||||
if(Pstate<2:> && !Hpstate<2:>)
|
||||
Rd = StrandStsReg<0:>;
|
||||
else
|
||||
Rd = StrandStsReg;
|
||||
}});
|
||||
//0x1A is supposed to be reserved, but it reads the strand
|
||||
//status register.
|
||||
//0x1B-0x1F should cause an illegal instruction exception
|
||||
}
|
||||
0x29: decode RS1 {
|
||||
0x00: HPriv::rdhprhpstate({{Rd = Hpstate;}});
|
||||
@@ -515,7 +550,16 @@ decode OP default Unknown::unknown()
|
||||
Stick = Rs1 ^ Rs2_or_imm13;
|
||||
}});
|
||||
0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}});
|
||||
//0x1A-0x1F should cause an illegal instruction exception
|
||||
0x1A: Priv::wrstrand_sts_reg({{
|
||||
if(Pstate<2:> && !Hpstate<2:>)
|
||||
StrandStsReg = StrandStsReg<63:1> |
|
||||
(Rs1 ^ Rs2_or_imm13)<0:>;
|
||||
else
|
||||
StrandStsReg = Rs1 ^ Rs2_or_imm13;
|
||||
}});
|
||||
//0x1A is supposed to be reserved, but it writes the strand
|
||||
//status register.
|
||||
//0x1B-0x1F should cause an illegal instruction exception
|
||||
}
|
||||
0x31: decode FCN {
|
||||
0x0: Priv::saved({{
|
||||
@@ -527,7 +571,7 @@ decode OP default Unknown::unknown()
|
||||
else
|
||||
Otherwin = Otherwin - 1;
|
||||
}});
|
||||
0x1: BasicOperate::restored({{
|
||||
0x1: Priv::restored({{
|
||||
assert(Cansave || Otherwin);
|
||||
assert(Canrestore < NWindows - 2);
|
||||
Canrestore = Canrestore + 1;
|
||||
|
||||
@@ -50,6 +50,42 @@ output header {{
|
||||
const SymbolTable *symtab) const;
|
||||
};
|
||||
|
||||
//This class is for instructions that explicitly read control
|
||||
//registers. It provides a special generateDisassembly function.
|
||||
class RdPriv : public Priv
|
||||
{
|
||||
protected:
|
||||
//Constructor
|
||||
RdPriv(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass, char const * _regName) :
|
||||
Priv(mnem, _machInst, __opClass), regName(_regName)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
|
||||
char const * regName;
|
||||
};
|
||||
|
||||
//This class is for instructions that explicitly write control
|
||||
//registers. It provides a special generateDisassembly function.
|
||||
class WrPriv : public Priv
|
||||
{
|
||||
protected:
|
||||
//Constructor
|
||||
WrPriv(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass, char const * _regName) :
|
||||
Priv(mnem, _machInst, __opClass), regName(_regName)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
|
||||
char const * regName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for privelege mode operations with immediates.
|
||||
*/
|
||||
@@ -66,6 +102,23 @@ output header {{
|
||||
int32_t imm;
|
||||
};
|
||||
|
||||
//This class is for instructions that explicitly write control
|
||||
//registers. It provides a special generateDisassembly function.
|
||||
class WrPrivImm : public PrivImm
|
||||
{
|
||||
protected:
|
||||
//Constructor
|
||||
WrPrivImm(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass, char const * _regName) :
|
||||
PrivImm(mnem, _machInst, __opClass), regName(_regName)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
|
||||
char const * regName;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
@@ -78,6 +131,58 @@ output decoder {{
|
||||
|
||||
return response.str();
|
||||
}
|
||||
|
||||
std::string RdPriv::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream response;
|
||||
|
||||
printMnemonic(response, mnemonic);
|
||||
|
||||
ccprintf(response, " %%%s, ", regName);
|
||||
printDestReg(response, 0);
|
||||
|
||||
return response.str();
|
||||
}
|
||||
|
||||
std::string WrPriv::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream response;
|
||||
|
||||
printMnemonic(response, mnemonic);
|
||||
|
||||
ccprintf(response, " ");
|
||||
printSrcReg(response, 0);
|
||||
ccprintf(response, ", ");
|
||||
printSrcReg(response, 1);
|
||||
ccprintf(response, ", %%%s", regName);
|
||||
|
||||
return response.str();
|
||||
}
|
||||
|
||||
std::string WrPrivImm::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream response;
|
||||
|
||||
printMnemonic(response, mnemonic);
|
||||
|
||||
ccprintf(response, " ");
|
||||
printSrcReg(response, 0);
|
||||
ccprintf(response, ", 0x%x, %%%s", imm, regName);
|
||||
|
||||
return response.str();
|
||||
}
|
||||
}};
|
||||
|
||||
def template ControlRegConstructor {{
|
||||
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
||||
: %(base_class)s("%(mnemonic)s", machInst,
|
||||
%(op_class)s, "%(reg_name)s")
|
||||
{
|
||||
%(constructor)s;
|
||||
}
|
||||
}};
|
||||
|
||||
def template PrivExecute {{
|
||||
@@ -102,16 +207,39 @@ let {{
|
||||
def doPrivFormat(code, checkCode, name, Name, opt_flags):
|
||||
(usesImm, code, immCode,
|
||||
rString, iString) = splitOutImm(code)
|
||||
iop = InstObjParams(name, Name, 'Priv', code,
|
||||
opt_flags, {"check": checkCode})
|
||||
#If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions,
|
||||
#cut any other info out of the mnemonic. Also pick a different
|
||||
#base class.
|
||||
regBase = 'Priv'
|
||||
regName = ''
|
||||
for mnem in ["rdhpr", "rdpr", "rd"]:
|
||||
if name.startswith(mnem):
|
||||
regName = name[len(mnem):]
|
||||
name = mnem
|
||||
regBase = 'RdPriv'
|
||||
break
|
||||
for mnem in ["wrhpr", "wrpr", "wr"]:
|
||||
if name.startswith(mnem):
|
||||
regName = name[len(mnem):]
|
||||
name = mnem
|
||||
regBase = 'WrPriv'
|
||||
break
|
||||
iop = InstObjParams(name, Name, regBase, code,
|
||||
opt_flags, {"check": checkCode, "reg_name": regName})
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
if regName == '':
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
else:
|
||||
decoder_output = ControlRegConstructor.subst(iop)
|
||||
exec_output = PrivExecute.subst(iop)
|
||||
if usesImm:
|
||||
imm_iop = InstObjParams(name, Name + 'Imm', 'PrivImm',
|
||||
immCode, opt_flags, {"check": checkCode})
|
||||
imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm',
|
||||
immCode, opt_flags, {"check": checkCode, "reg_name": regName})
|
||||
header_output += BasicDeclare.subst(imm_iop)
|
||||
decoder_output += BasicConstructor.subst(imm_iop)
|
||||
if regName == '':
|
||||
decoder_output += BasicConstructor.subst(imm_iop)
|
||||
else:
|
||||
decoder_output += ControlRegConstructor.subst(imm_iop)
|
||||
exec_output += PrivExecute.subst(imm_iop)
|
||||
decode_block = ROrImmDecode.subst(iop)
|
||||
else:
|
||||
|
||||
@@ -123,6 +123,7 @@ def operands {{
|
||||
'Htba': ('ControlReg', 'udw', 'MISCREG_HTBA', None, 72),
|
||||
'HstickCmpr': ('ControlReg', 'udw', 'MISCREG_HSTICK_CMPR', None, 73),
|
||||
'Hver': ('ControlReg', 'udw', 'MISCREG_HVER', None, 74),
|
||||
'StrandStsReg': ('ControlReg', 'udw', 'MISCREG_STRAND_STS_REG', None, 75),
|
||||
|
||||
'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 80),
|
||||
# Mem gets a large number so it's always last
|
||||
|
||||
@@ -76,10 +76,7 @@ namespace SparcISA
|
||||
// 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 + NumFloatRegs,
|
||||
//XXX These are here solely to get compilation and won't work
|
||||
Fpcr_DepTag = 0,
|
||||
Uniq_DepTag = 0
|
||||
Ctrl_Base_DepTag = NumIntRegs + NumMicroIntRegs + NumFloatRegs,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#ifndef __ARCH_SPARC_TLB_HH__
|
||||
#define __ARCH_SPARC_TLB_HH__
|
||||
|
||||
#include "base/misc.hh"
|
||||
#include "mem/request.hh"
|
||||
#include "sim/faults.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
@@ -56,6 +57,9 @@ namespace SparcISA
|
||||
|
||||
Fault translate(RequestPtr &req, ThreadContext *tc) const
|
||||
{
|
||||
//For now, always assume the address is already physical.
|
||||
//Also assume that there are 40 bits of physical address space.
|
||||
req->setPaddr(req->getVaddr() & ((1ULL << 40) - 1));
|
||||
return NoFault;
|
||||
}
|
||||
};
|
||||
@@ -69,6 +73,9 @@ namespace SparcISA
|
||||
|
||||
Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const
|
||||
{
|
||||
//For now, always assume the address is already physical.
|
||||
//Also assume that there are 40 bits of physical address space.
|
||||
req->setPaddr(req->getVaddr() & ((1ULL << 40) - 1));
|
||||
return NoFault;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user