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:
Ali Saidi 2006-12-14 19:01:21 -05:00
parent 139519ef87
commit fa4293af33
3 changed files with 94 additions and 38 deletions

View file

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

View file

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

View file

@ -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",