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