flesh out twinx asis
fix TICK register reads reduce the number of readmiscreg accesses, implement tsb pointer stuff src/arch/sparc/asi.cc: flesh out twinx asis src/arch/sparc/miscregfile.cc: fix TICK register reads src/arch/sparc/tlb.cc: reduce the number of readmiscreg accesses, implement tsb pointer stuff --HG-- extra : convert_revision : 1995c3b04b7743c6122cbf8ded7c4d5de48fa3c8
This commit is contained in:
parent
139519ef87
commit
fa4293af33
3 changed files with 94 additions and 38 deletions
|
@ -185,6 +185,7 @@ namespace SparcISA
|
|||
bool AsiIsTwin(ASI asi)
|
||||
{
|
||||
return
|
||||
(asi == ASI_QUAD_LDD) ||
|
||||
(asi == ASI_LDTX_AIUP) ||
|
||||
(asi == ASI_LDTX_AIUS) ||
|
||||
(asi == ASI_LDTX_REAL) ||
|
||||
|
@ -196,7 +197,8 @@ namespace SparcISA
|
|||
(asi == ASI_LDTX_P) ||
|
||||
(asi == ASI_LDTX_S) ||
|
||||
(asi == ASI_LDTX_PL) ||
|
||||
(asi == ASI_LDTX_SL);
|
||||
(asi == ASI_LDTX_SL) ||
|
||||
(asi == ASI_LTX_L);
|
||||
}
|
||||
|
||||
bool AsiIsPartialStore(ASI asi)
|
||||
|
|
|
@ -314,16 +314,17 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
|
|||
{
|
||||
switch (miscReg) {
|
||||
// tick and stick are aliased to each other in niagra
|
||||
case MISCREG_TICK:
|
||||
// well store the tick data in stick and the interrupt bit in tick
|
||||
case MISCREG_STICK:
|
||||
case MISCREG_TICK:
|
||||
case MISCREG_PRIVTICK:
|
||||
// I'm not sure why legion ignores the lowest two bits, but we'll go
|
||||
// with it
|
||||
// change from curCycle() to instCount() until we're done with legion
|
||||
DPRINTFN("Instruction Count when STICK read: %#X\n",
|
||||
tc->getCpuPtr()->instCount());
|
||||
return mbits(tc->getCpuPtr()->instCount() - (tick &
|
||||
mask(63)),62,2) | mbits(tick,63,63) ;
|
||||
DPRINTFN("Instruction Count when TICK read: %#X stick=%#X\n",
|
||||
tc->getCpuPtr()->instCount(), stick);
|
||||
return mbits(tc->getCpuPtr()->instCount() + (int32_t)stick,62,2) |
|
||||
mbits(tick,63,63);
|
||||
case MISCREG_FPRS:
|
||||
warn("FPRS register read and FPU stuff not really implemented\n");
|
||||
return fprs;
|
||||
|
@ -601,13 +602,14 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val)
|
|||
void MiscRegFile::setRegWithEffect(int miscReg,
|
||||
const MiscReg &val, ThreadContext * tc)
|
||||
{
|
||||
const uint64_t Bit64 = (1ULL << 63);
|
||||
switch (miscReg) {
|
||||
case MISCREG_STICK:
|
||||
case MISCREG_TICK:
|
||||
// change from curCycle() to instCount() until we're done with legion
|
||||
tick = tc->getCpuPtr()->instCount() - val & ~Bit64;
|
||||
tick |= val & Bit64;
|
||||
// stick and tick are same thing on niagra
|
||||
// use stick for offset and tick for holding intrrupt bit
|
||||
stick = mbits(val,62,0) - tc->getCpuPtr()->instCount();
|
||||
tick = mbits(val,63,63);
|
||||
DPRINTFN("Writing TICK=%#X\n", val);
|
||||
break;
|
||||
case MISCREG_FPRS:
|
||||
//Configure the fpu based on the fprs
|
||||
|
|
|
@ -348,13 +348,18 @@ DTB::writeTagAccess(ThreadContext *tc, Addr va, int context)
|
|||
Fault
|
||||
ITB::translate(RequestPtr &req, ThreadContext *tc)
|
||||
{
|
||||
uint64_t hpstate = tc->readMiscReg(MISCREG_HPSTATE);
|
||||
uint64_t pstate = tc->readMiscReg(MISCREG_PSTATE);
|
||||
bool lsuIm = tc->readMiscReg(MISCREG_MMU_LSU_CTRL) >> 2 & 0x1;
|
||||
uint64_t tl = tc->readMiscReg(MISCREG_TL);
|
||||
uint64_t part_id = tc->readMiscReg(MISCREG_MMU_PART_ID);
|
||||
bool addr_mask = pstate >> 3 & 0x1;
|
||||
bool priv = pstate >> 2 & 0x1;
|
||||
uint64_t tlbdata = tc->readMiscReg(MISCREG_TLB_DATA);
|
||||
|
||||
bool hpriv = bits(tlbdata,0,0);
|
||||
bool red = bits(tlbdata,1,1);
|
||||
bool priv = bits(tlbdata,2,2);
|
||||
bool addr_mask = bits(tlbdata,3,3);
|
||||
bool lsu_im = bits(tlbdata,4,4);
|
||||
|
||||
int part_id = bits(tlbdata,15,8);
|
||||
int tl = bits(tlbdata,18,16);
|
||||
int pri_context = bits(tlbdata,47,32);
|
||||
|
||||
Addr vaddr = req->getVaddr();
|
||||
int context;
|
||||
ContextType ct;
|
||||
|
@ -364,8 +369,8 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
|
|||
|
||||
DPRINTF(TLB, "TLB: ITB Request to translate va=%#x size=%d\n",
|
||||
vaddr, req->getSize());
|
||||
DPRINTF(TLB, "TLB: pstate: %#X hpstate: %#X lsudm: %#X part_id: %#X\n",
|
||||
pstate, hpstate, lsuIm, part_id);
|
||||
DPRINTF(TLB, "TLB: priv:%d hpriv:%d red:%d lsuim:%d part_id: %#X\n",
|
||||
priv, hpriv, red, lsu_im, part_id);
|
||||
|
||||
assert(req->getAsi() == ASI_IMPLICIT);
|
||||
|
||||
|
@ -376,10 +381,10 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
|
|||
} else {
|
||||
asi = ASI_P;
|
||||
ct = Primary;
|
||||
context = tc->readMiscReg(MISCREG_MMU_P_CONTEXT);
|
||||
context = pri_context;
|
||||
}
|
||||
|
||||
if ( hpstate >> 2 & 0x1 || hpstate >> 5 & 0x1 ) {
|
||||
if ( hpriv || red ) {
|
||||
req->setPaddr(req->getVaddr() & PAddrImplMask);
|
||||
return NoFault;
|
||||
}
|
||||
|
@ -398,7 +403,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
|
|||
return new InstructionAccessException;
|
||||
}
|
||||
|
||||
if (!lsuIm) {
|
||||
if (!lsu_im) {
|
||||
e = lookup(req->getVaddr(), part_id, true);
|
||||
real = true;
|
||||
context = 0;
|
||||
|
@ -433,15 +438,19 @@ Fault
|
|||
DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
||||
{
|
||||
/* @todo this could really use some profiling and fixing to make it faster! */
|
||||
uint64_t hpstate = tc->readMiscReg(MISCREG_HPSTATE);
|
||||
uint64_t pstate = tc->readMiscReg(MISCREG_PSTATE);
|
||||
bool lsuDm = tc->readMiscReg(MISCREG_MMU_LSU_CTRL) >> 3 & 0x1;
|
||||
uint64_t tl = tc->readMiscReg(MISCREG_TL);
|
||||
uint64_t part_id = tc->readMiscReg(MISCREG_MMU_PART_ID);
|
||||
bool hpriv = hpstate >> 2 & 0x1;
|
||||
bool red = hpstate >> 5 >> 0x1;
|
||||
bool addr_mask = pstate >> 3 & 0x1;
|
||||
bool priv = pstate >> 2 & 0x1;
|
||||
uint64_t tlbdata = tc->readMiscReg(MISCREG_TLB_DATA);
|
||||
|
||||
bool hpriv = bits(tlbdata,0,0);
|
||||
bool red = bits(tlbdata,1,1);
|
||||
bool priv = bits(tlbdata,2,2);
|
||||
bool addr_mask = bits(tlbdata,3,3);
|
||||
bool lsu_dm = bits(tlbdata,5,5);
|
||||
|
||||
int part_id = bits(tlbdata,15,8);
|
||||
int tl = bits(tlbdata,18,16);
|
||||
int pri_context = bits(tlbdata,47,32);
|
||||
int sec_context = bits(tlbdata,47,32);
|
||||
|
||||
bool implicit = false;
|
||||
bool real = false;
|
||||
Addr vaddr = req->getVaddr();
|
||||
|
@ -455,8 +464,8 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
|||
asi = (ASI)req->getAsi();
|
||||
DPRINTF(TLB, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n",
|
||||
vaddr, size, asi);
|
||||
DPRINTF(TLB, "TLB: pstate: %#X hpstate: %#X lsudm: %#X part_id: %#X\n",
|
||||
pstate, hpstate, lsuDm, part_id);
|
||||
DPRINTF(TLB, "TLB: priv:%d hpriv:%d red:%d lsudm:%d part_id: %#X\n",
|
||||
priv, hpriv, red, lsu_dm, part_id);
|
||||
if (asi == ASI_IMPLICIT)
|
||||
implicit = true;
|
||||
|
||||
|
@ -468,7 +477,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
|||
} else {
|
||||
asi = ASI_P;
|
||||
ct = Primary;
|
||||
context = tc->readMiscReg(MISCREG_MMU_P_CONTEXT);
|
||||
context = pri_context;
|
||||
}
|
||||
} else if (!hpriv && !red) {
|
||||
if (tl > 0 || AsiIsNucleus(asi)) {
|
||||
|
@ -476,9 +485,9 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
|||
context = 0;
|
||||
} else if (AsiIsSecondary(asi)) {
|
||||
ct = Secondary;
|
||||
context = tc->readMiscReg(MISCREG_MMU_S_CONTEXT);
|
||||
context = sec_context;
|
||||
} else {
|
||||
context = tc->readMiscReg(MISCREG_MMU_P_CONTEXT);
|
||||
context = pri_context;
|
||||
ct = Primary; //???
|
||||
}
|
||||
|
||||
|
@ -496,7 +505,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
|||
} else if (hpriv) {
|
||||
if (asi == ASI_P) {
|
||||
ct = Primary;
|
||||
context = tc->readMiscReg(MISCREG_MMU_P_CONTEXT);
|
||||
context = pri_context;
|
||||
goto continueDtbFlow;
|
||||
}
|
||||
}
|
||||
|
@ -547,7 +556,7 @@ continueDtbFlow:
|
|||
}
|
||||
|
||||
|
||||
if ((!lsuDm && !hpriv) || AsiIsReal(asi)) {
|
||||
if ((!lsu_dm && !hpriv) || AsiIsReal(asi)) {
|
||||
real = true;
|
||||
context = 0;
|
||||
};
|
||||
|
@ -640,6 +649,8 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
|
|||
{
|
||||
Addr va = pkt->getAddr();
|
||||
ASI asi = (ASI)pkt->req->getAsi();
|
||||
uint64_t temp, data;
|
||||
uint64_t tsbtemp, cnftemp;
|
||||
|
||||
DPRINTF(IPR, "Memory Mapped IPR Read: asi=%#X a=%#x\n",
|
||||
(uint32_t)pkt->req->getAsi(), pkt->getAddr());
|
||||
|
@ -723,6 +734,10 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
|
|||
break;
|
||||
case ASI_IMMU:
|
||||
switch (va) {
|
||||
case 0x0:
|
||||
temp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS);
|
||||
pkt->set(bits(temp,63,22) | bits(temp,12,0) << 48);
|
||||
break;
|
||||
case 0x30:
|
||||
pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS));
|
||||
break;
|
||||
|
@ -732,6 +747,10 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
|
|||
break;
|
||||
case ASI_DMMU:
|
||||
switch (va) {
|
||||
case 0x0:
|
||||
temp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS);
|
||||
pkt->set(bits(temp,63,22) | bits(temp,12,0) << 48);
|
||||
break;
|
||||
case 0x30:
|
||||
pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS));
|
||||
break;
|
||||
|
@ -742,6 +761,39 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
|
|||
goto doMmuReadError;
|
||||
}
|
||||
break;
|
||||
case ASI_DMMU_TSB_PS0_PTR_REG:
|
||||
temp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS);
|
||||
if (bits(temp,12,0) == 0) {
|
||||
tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS0);
|
||||
cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG);
|
||||
} else {
|
||||
tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS0);
|
||||
cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG);
|
||||
}
|
||||
data = mbits(tsbtemp,63,13);
|
||||
data |= temp >> (9 + bits(cnftemp,2,0) * 3) &
|
||||
mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
|
||||
warn("base addr: %#X tag access: %#X page size: %#X tsb size: %#X\n",
|
||||
bits(tsbtemp,63,13), temp, bits(cnftemp,2,0), bits(tsbtemp,3,0));
|
||||
pkt->set(data);
|
||||
break;
|
||||
case ASI_DMMU_TSB_PS1_PTR_REG:
|
||||
temp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS);
|
||||
if (bits(temp,12,0) == 0) {
|
||||
tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS1);
|
||||
cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG);
|
||||
} else {
|
||||
tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS1);
|
||||
cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG);
|
||||
}
|
||||
data = mbits(tsbtemp,63,13);
|
||||
if (bits(tsbtemp,12,12))
|
||||
data |= ULL(1) << (13+bits(tsbtemp,3,0));
|
||||
data |= temp >> (9 + bits(cnftemp,2,0) * 3) &
|
||||
mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
|
||||
pkt->set(data);
|
||||
break;
|
||||
|
||||
default:
|
||||
doMmuReadError:
|
||||
panic("need to impl DTB::doMmuRegRead() got asi=%#x, va=%#x\n",
|
||||
|
|
Loading…
Reference in a new issue