fix twinx loads a little bit
bugfixes and demap implementation in tlb ignore some more differencs for one cycle src/arch/sparc/isa/formats/mem/blockmem.isa: twinx has 2 micro-ops src/arch/sparc/isa/formats/mem/util.isa: fix the fault check for twinx src/arch/sparc/tlb.cc: tlb bugfixes and write demapping code src/cpu/exetrace.cc: don't halt on a couple more instruction (ldx, stx) when things differ beacuse of the way tlb faults are handled in legion. --HG-- extra : convert_revision : 1e156dead6ebd58b257213625ed63c3793ef4b71
This commit is contained in:
parent
6841f863c5
commit
5e9d8795f2
4 changed files with 92 additions and 7 deletions
|
@ -101,7 +101,7 @@ output header {{
|
||||||
// We make the assumption that all block memory operations
|
// We make the assumption that all block memory operations
|
||||||
// Will take 8 instructions to execute
|
// Will take 8 instructions to execute
|
||||||
TwinMem(const char *mnem, ExtMachInst _machInst) :
|
TwinMem(const char *mnem, ExtMachInst _machInst) :
|
||||||
SparcMacroInst(mnem, _machInst, No_OpClass, 8)
|
SparcMacroInst(mnem, _machInst, No_OpClass, 2)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -285,9 +285,9 @@ let {{
|
||||||
fault = new MemAddressNotAligned;
|
fault = new MemAddressNotAligned;
|
||||||
'''
|
'''
|
||||||
TwinAlignmentFaultCheck = '''
|
TwinAlignmentFaultCheck = '''
|
||||||
if(RD & 0xe)
|
if(RD & 0x1)
|
||||||
fault = new IllegalInstruction;
|
fault = new IllegalInstruction;
|
||||||
else if(EA & 0x1f)
|
else if(EA & 0xf)
|
||||||
fault = new MemAddressNotAligned;
|
fault = new MemAddressNotAligned;
|
||||||
'''
|
'''
|
||||||
# XXX Need to take care of pstate.hpriv as well. The lower ASIs
|
# XXX Need to take care of pstate.hpriv as well. The lower ASIs
|
||||||
|
|
|
@ -124,7 +124,8 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real,
|
||||||
lookupTable.erase(i);
|
lookupTable.erase(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
lookupTable.insert(new_entry->range, new_entry);;
|
i = lookupTable.insert(new_entry->range, new_entry);
|
||||||
|
assert(i != lookupTable.end());
|
||||||
|
|
||||||
// If all entries have there used bit set, clear it on them all, but the
|
// If all entries have there used bit set, clear it on them all, but the
|
||||||
// one we just inserted
|
// one we just inserted
|
||||||
|
@ -148,7 +149,7 @@ TLB::lookup(Addr va, int partition_id, bool real, int context_id)
|
||||||
va, partition_id, context_id, real);
|
va, partition_id, context_id, real);
|
||||||
// Assemble full address structure
|
// Assemble full address structure
|
||||||
tr.va = va;
|
tr.va = va;
|
||||||
tr.size = va + MachineBytes;
|
tr.size = MachineBytes;
|
||||||
tr.contextId = context_id;
|
tr.contextId = context_id;
|
||||||
tr.partitionId = partition_id;
|
tr.partitionId = partition_id;
|
||||||
tr.real = real;
|
tr.real = real;
|
||||||
|
@ -180,6 +181,7 @@ TLB::lookup(Addr va, int partition_id, bool real, int context_id)
|
||||||
void
|
void
|
||||||
TLB::dumpAll()
|
TLB::dumpAll()
|
||||||
{
|
{
|
||||||
|
MapIter i;
|
||||||
for (int x = 0; x < size; x++) {
|
for (int x = 0; x < size; x++) {
|
||||||
if (tlb[x].valid) {
|
if (tlb[x].valid) {
|
||||||
DPRINTFN("%4d: %#2x:%#2x %c %#4x %#8x %#8x %#16x\n",
|
DPRINTFN("%4d: %#2x:%#2x %c %#4x %#8x %#8x %#16x\n",
|
||||||
|
@ -196,11 +198,14 @@ TLB::demapPage(Addr va, int partition_id, bool real, int context_id)
|
||||||
TlbRange tr;
|
TlbRange tr;
|
||||||
MapIter i;
|
MapIter i;
|
||||||
|
|
||||||
|
DPRINTF(IPR, "TLB: Demapping Page va=%#x pid=%#d cid=%d r=%d\n",
|
||||||
|
va, partition_id, context_id, real);
|
||||||
|
|
||||||
cacheValid = false;
|
cacheValid = false;
|
||||||
|
|
||||||
// Assemble full address structure
|
// Assemble full address structure
|
||||||
tr.va = va;
|
tr.va = va;
|
||||||
tr.size = va + MachineBytes;
|
tr.size = MachineBytes;
|
||||||
tr.contextId = context_id;
|
tr.contextId = context_id;
|
||||||
tr.partitionId = partition_id;
|
tr.partitionId = partition_id;
|
||||||
tr.real = real;
|
tr.real = real;
|
||||||
|
@ -208,6 +213,7 @@ TLB::demapPage(Addr va, int partition_id, bool real, int context_id)
|
||||||
// Demap any entry that conflicts
|
// Demap any entry that conflicts
|
||||||
i = lookupTable.find(tr);
|
i = lookupTable.find(tr);
|
||||||
if (i != lookupTable.end()) {
|
if (i != lookupTable.end()) {
|
||||||
|
DPRINTF(IPR, "TLB: Demapped page\n");
|
||||||
i->second->valid = false;
|
i->second->valid = false;
|
||||||
if (i->second->used) {
|
if (i->second->used) {
|
||||||
i->second->used = false;
|
i->second->used = false;
|
||||||
|
@ -221,6 +227,8 @@ void
|
||||||
TLB::demapContext(int partition_id, int context_id)
|
TLB::demapContext(int partition_id, int context_id)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
DPRINTF(IPR, "TLB: Demapping Context pid=%#d cid=%d\n",
|
||||||
|
partition_id, context_id);
|
||||||
cacheValid = false;
|
cacheValid = false;
|
||||||
for (x = 0; x < size; x++) {
|
for (x = 0; x < size; x++) {
|
||||||
if (tlb[x].range.contextId == context_id &&
|
if (tlb[x].range.contextId == context_id &&
|
||||||
|
@ -239,6 +247,7 @@ void
|
||||||
TLB::demapAll(int partition_id)
|
TLB::demapAll(int partition_id)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
DPRINTF(TLB, "TLB: Demapping All pid=%#d\n", partition_id);
|
||||||
cacheValid = false;
|
cacheValid = false;
|
||||||
for (x = 0; x < size; x++) {
|
for (x = 0; x < size; x++) {
|
||||||
if (!tlb[x].pte.locked() && tlb[x].range.partitionId == partition_id) {
|
if (!tlb[x].pte.locked() && tlb[x].range.partitionId == partition_id) {
|
||||||
|
@ -884,6 +893,9 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
|
||||||
int part_insert;
|
int part_insert;
|
||||||
int entry_insert = -1;
|
int entry_insert = -1;
|
||||||
bool real_insert;
|
bool real_insert;
|
||||||
|
bool ignore;
|
||||||
|
int part_id;
|
||||||
|
int ctx_id;
|
||||||
PageTableEntry pte;
|
PageTableEntry pte;
|
||||||
|
|
||||||
DPRINTF(IPR, "Memory Mapped IPR Write: asi=%#X a=%#x d=%#X\n",
|
DPRINTF(IPR, "Memory Mapped IPR Write: asi=%#X a=%#x d=%#X\n",
|
||||||
|
@ -1003,6 +1015,41 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
|
||||||
PageTableEntry::sun4u);
|
PageTableEntry::sun4u);
|
||||||
insert(va_insert, part_insert, ct_insert, real_insert, pte, entry_insert);
|
insert(va_insert, part_insert, ct_insert, real_insert, pte, entry_insert);
|
||||||
break;
|
break;
|
||||||
|
case ASI_IMMU_DEMAP:
|
||||||
|
ignore = false;
|
||||||
|
ctx_id = -1;
|
||||||
|
part_id = tc->readMiscRegWithEffect(MISCREG_MMU_PART_ID);
|
||||||
|
switch (bits(va,5,4)) {
|
||||||
|
case 0:
|
||||||
|
ctx_id = tc->readMiscRegWithEffect(MISCREG_MMU_P_CONTEXT);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ignore = true;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ctx_id = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ignore = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(bits(va,7,6)) {
|
||||||
|
case 0: // demap page
|
||||||
|
if (!ignore)
|
||||||
|
tc->getITBPtr()->demapPage(mbits(va,63,13), part_id,
|
||||||
|
bits(va,9,9), ctx_id);
|
||||||
|
break;
|
||||||
|
case 1: //demap context
|
||||||
|
if (!ignore)
|
||||||
|
tc->getITBPtr()->demapContext(part_id, ctx_id);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
tc->getITBPtr()->demapAll(part_id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic("Invalid type for IMMU demap\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ASI_DMMU:
|
case ASI_DMMU:
|
||||||
switch (va) {
|
switch (va) {
|
||||||
case 0x30:
|
case 0x30:
|
||||||
|
@ -1015,6 +1062,40 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
|
||||||
goto doMmuWriteError;
|
goto doMmuWriteError;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ASI_DMMU_DEMAP:
|
||||||
|
ignore = false;
|
||||||
|
ctx_id = -1;
|
||||||
|
part_id = tc->readMiscRegWithEffect(MISCREG_MMU_PART_ID);
|
||||||
|
switch (bits(va,5,4)) {
|
||||||
|
case 0:
|
||||||
|
ctx_id = tc->readMiscRegWithEffect(MISCREG_MMU_P_CONTEXT);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ctx_id = tc->readMiscRegWithEffect(MISCREG_MMU_S_CONTEXT);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ctx_id = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ignore = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(bits(va,7,6)) {
|
||||||
|
case 0: // demap page
|
||||||
|
if (!ignore)
|
||||||
|
demapPage(mbits(va,63,13), part_id, bits(va,9,9), ctx_id);
|
||||||
|
break;
|
||||||
|
case 1: //demap context
|
||||||
|
if (!ignore)
|
||||||
|
demapContext(part_id, ctx_id);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
demapAll(part_id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic("Invalid type for IMMU demap\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
doMmuWriteError:
|
doMmuWriteError:
|
||||||
panic("need to impl DTB::doMmuRegWrite() got asi=%#x, va=%#x d=%#x\n",
|
panic("need to impl DTB::doMmuRegWrite() got asi=%#x, va=%#x d=%#x\n",
|
||||||
|
|
|
@ -401,7 +401,11 @@ Trace::InstRecord::dump(ostream &outs)
|
||||||
diffCcr || diffTl || diffGl || diffAsi || diffPil ||
|
diffCcr || diffTl || diffGl || diffAsi || diffPil ||
|
||||||
diffCwp || diffCansave || diffCanrestore ||
|
diffCwp || diffCansave || diffCanrestore ||
|
||||||
diffOtherwin || diffCleanwin)
|
diffOtherwin || diffCleanwin)
|
||||||
&& !((staticInst->machInst & 0xC1F80000) == 0x81D00000)) {
|
&& !((staticInst->machInst & 0xC1F80000) == 0x81D00000)
|
||||||
|
&& !((staticInst->machInst & 0xC1F80000) == 0xC0580000)
|
||||||
|
&& !((staticInst->machInst & 0xC1F80000) == 0xC0000000)
|
||||||
|
&& !((staticInst->machInst & 0xC1F80000) == 0xC0700000)) {
|
||||||
|
|
||||||
outs << "Differences found between M5 and Legion:";
|
outs << "Differences found between M5 and Legion:";
|
||||||
if (diffPC)
|
if (diffPC)
|
||||||
outs << " [PC]";
|
outs << " [PC]";
|
||||||
|
|
Loading…
Reference in a new issue