Merge zizzer:/bk/newmem

into  zeep.pool:/z/saidi/work/m5.newmem

--HG--
extra : convert_revision : afd4266bd494bb8f127c06985f343219ded4f637
This commit is contained in:
Ali Saidi
2006-12-27 14:38:22 -05:00
6 changed files with 178 additions and 39 deletions

View File

@@ -45,7 +45,8 @@ namespace SparcISA
{
TLB::TLB(const std::string &name, int s)
: SimObject(name), size(s), usedEntries(0), cacheValid(false)
: SimObject(name), size(s), usedEntries(0), lastReplaced(0),
cacheValid(false)
{
// To make this work you'll have to change the hypervisor and OS
if (size > 64)
@@ -53,13 +54,16 @@ TLB::TLB(const std::string &name, int s)
tlb = new TlbEntry[size];
memset(tlb, 0, sizeof(TlbEntry) * size);
for (int x = 0; x < size; x++)
freeList.push_back(&tlb[x]);
}
void
TLB::clearUsedBits()
{
MapIter i;
for (i = lookupTable.begin(); i != lookupTable.end();) {
for (i = lookupTable.begin(); i != lookupTable.end(); i++) {
TlbEntry *t = i->second;
if (!t->pte.locked()) {
t->used = false;
@@ -77,32 +81,76 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real,
MapIter i;
TlbEntry *new_entry = NULL;
TlbRange tr;
int x;
cacheValid = false;
tr.va = va;
tr.size = PTE.size() - 1;
tr.contextId = context_id;
tr.partitionId = partition_id;
tr.real = real;
DPRINTF(TLB, "TLB: Inserting TLB Entry; va=%#x pa=%#x pid=%d cid=%d r=%d entryid=%d\n",
va, PTE.paddr(), partition_id, context_id, (int)real, entry);
// Demap any entry that conflicts
i = lookupTable.find(tr);
if (i != lookupTable.end()) {
i->second->valid = false;
if (i->second->used) {
i->second->used = false;
usedEntries--;
}
freeList.push_front(i->second);
DPRINTF(TLB, "TLB: Found conflicting entry %#X , deleting it\n",
i->second);
lookupTable.erase(i);
}
DPRINTF(TLB, "TLB: Inserting TLB Entry; va=%#x pa=%#x pid=%d cid=%d r=%d\n",
va, PTE.paddr(), partition_id, context_id, (int)real);
if (entry != -1) {
assert(entry < size && entry >= 0);
new_entry = &tlb[entry];
} else {
if (!freeList.empty()) {
new_entry = freeList.front();
} else {
x = lastReplaced;
do {
++x;
if (x == size)
x = 0;
if (x == lastReplaced)
goto insertAllLocked;
} while (tlb[x].pte.locked());
lastReplaced = x;
new_entry = &tlb[x];
lookupTable.erase(new_entry->range);
}
/*
for (x = 0; x < size; x++) {
if (!tlb[x].valid || !tlb[x].used) {
new_entry = &tlb[x];
break;
}
}
}*/
}
insertAllLocked:
// Update the last ently if their all locked
if (!new_entry)
if (!new_entry) {
new_entry = &tlb[size-1];
lookupTable.erase(new_entry->range);
}
freeList.remove(new_entry);
DPRINTF(TLB, "Using entry: %#X\n", new_entry);
assert(PTE.valid());
new_entry->range.va = va;
new_entry->range.size = PTE.size();
new_entry->range.size = PTE.size() - 1;
new_entry->range.partitionId = partition_id;
new_entry->range.contextId = context_id;
new_entry->range.real = real;
@@ -112,17 +160,6 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real,
usedEntries++;
// Demap any entry that conflicts
i = lookupTable.find(new_entry->range);
if (i != lookupTable.end()) {
i->second->valid = false;
if (i->second->used) {
i->second->used = false;
usedEntries--;
}
DPRINTF(TLB, "TLB: Found conflicting entry, deleting it\n");
lookupTable.erase(i);
}
i = lookupTable.insert(new_entry->range, new_entry);
assert(i != lookupTable.end());
@@ -219,6 +256,8 @@ TLB::demapPage(Addr va, int partition_id, bool real, int context_id)
i->second->used = false;
usedEntries--;
}
freeList.push_front(i->second);
DPRINTF(TLB, "Freeing TLB entry : %#X\n", i->second);
lookupTable.erase(i);
}
}
@@ -233,6 +272,10 @@ TLB::demapContext(int partition_id, int context_id)
for (x = 0; x < size; x++) {
if (tlb[x].range.contextId == context_id &&
tlb[x].range.partitionId == partition_id) {
if (tlb[x].valid == true) {
freeList.push_front(&tlb[x]);
DPRINTF(TLB, "Freeing TLB entry : %#X\n", &tlb[x]);
}
tlb[x].valid = false;
if (tlb[x].used) {
tlb[x].used = false;
@@ -251,6 +294,10 @@ TLB::demapAll(int partition_id)
cacheValid = false;
for (x = 0; x < size; x++) {
if (!tlb[x].pte.locked() && tlb[x].range.partitionId == partition_id) {
if (tlb[x].valid == true){
freeList.push_front(&tlb[x]);
DPRINTF(TLB, "Freeing TLB entry : %#X\n", &tlb[x]);
}
tlb[x].valid = false;
if (tlb[x].used) {
tlb[x].used = false;
@@ -267,7 +314,10 @@ TLB::invalidateAll()
int x;
cacheValid = false;
freeList.clear();
for (x = 0; x < size; x++) {
if (tlb[x].valid == true)
freeList.push_back(&tlb[x]);
tlb[x].valid = false;
}
usedEntries = 0;
@@ -275,17 +325,26 @@ TLB::invalidateAll()
uint64_t
TLB::TteRead(int entry) {
if (entry >= size)
panic("entry: %d\n", entry);
assert(entry < size);
return tlb[entry].pte();
if (tlb[entry].valid)
return tlb[entry].pte();
else
return (uint64_t)-1ll;
}
uint64_t
TLB::TagRead(int entry) {
assert(entry < size);
uint64_t tag;
if (!tlb[entry].valid)
return (uint64_t)-1ll;
tag = tlb[entry].range.contextId | tlb[entry].range.va |
(uint64_t)tlb[entry].range.partitionId << 61;
tag = tlb[entry].range.contextId;
tag |= tlb[entry].range.va;
tag |= (uint64_t)tlb[entry].range.partitionId << 61;
tag |= tlb[entry].range.real ? ULL(1) << 60 : 0;
tag |= (uint64_t)~tlb[entry].pte._size() << 56;
return tag;
@@ -501,13 +560,13 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
// Be fast if we can!
if (cacheValid && cacheState == tlbdata) {
if (cacheEntry[0] && cacheAsi[0] == asi && cacheEntry[0]->range.va < vaddr + size &&
cacheEntry[0]->range.va + cacheEntry[0]->range.size >= vaddr) {
cacheEntry[0]->range.va + cacheEntry[0]->range.size > vaddr) {
req->setPaddr(cacheEntry[0]->pte.paddr() & ~(cacheEntry[0]->pte.size()-1) |
vaddr & cacheEntry[0]->pte.size()-1 );
return NoFault;
}
if (cacheEntry[1] && cacheAsi[1] == asi && cacheEntry[1]->range.va < vaddr + size &&
cacheEntry[1]->range.va + cacheEntry[1]->range.size >= vaddr) {
cacheEntry[1]->range.va + cacheEntry[1]->range.size > vaddr) {
req->setPaddr(cacheEntry[1]->pte.paddr() & ~(cacheEntry[1]->pte.size()-1) |
vaddr & cacheEntry[1]->pte.size()-1 );
return NoFault;
@@ -667,8 +726,12 @@ continueDtbFlow:
}
// cache translation date for next translation
cacheValid = true;
cacheState = tlbdata;
if (!cacheValid) {
cacheEntry[1] = NULL;
cacheEntry[0] = NULL;
}
if (cacheEntry[0] != e && cacheEntry[1] != e) {
cacheEntry[1] = cacheEntry[0];
cacheEntry[0] = e;
@@ -677,7 +740,7 @@ continueDtbFlow:
if (implicit)
cacheAsi[0] = (ASI)0;
}
cacheValid = true;
req->setPaddr(e->pte.paddr() & ~(e->pte.size()-1) |
vaddr & e->pte.size()-1);
DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr());
@@ -696,7 +759,7 @@ handleQueueRegAccess:
writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
return new PrivilegedAction;
}
if (priv && vaddr & 0xF || vaddr > 0x3f8 || vaddr < 0x3c0) {
if (!hpriv && vaddr & 0xF || vaddr > 0x3f8 || vaddr < 0x3c0) {
writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
return new DataAccessException;
}

View File

@@ -54,10 +54,13 @@ class TLB : public SimObject
int size;
int usedEntries;
int lastReplaced;
uint64_t cacheState;
bool cacheValid;
std::list<TlbEntry*> freeList;
enum FaultTypes {
OtherFault = 0,
PrivViolation = 0x1,
@@ -93,9 +96,6 @@ class TLB : public SimObject
/** Given an entry id, read that tlb entries' tag. */
uint64_t TagRead(int entry);
/** Give an entry id, read that tlb entries' tte */
uint64_t TteRead(int entry);
/** Remove all entries from the TLB */
void invalidateAll();
@@ -128,6 +128,10 @@ class TLB : public SimObject
// Checkpointing
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
/** Give an entry id, read that tlb entries' tte */
uint64_t TteRead(int entry);
};
class ITB : public TLB

View File

@@ -312,6 +312,7 @@ Trace::InstRecord::dump(ostream &outs)
bool diffCanrestore = false;
bool diffOtherwin = false;
bool diffCleanwin = false;
bool diffTlb = false;
Addr m5Pc, lgnPc;
@@ -395,16 +396,23 @@ Trace::InstRecord::dump(ostream &outs)
if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
diffCleanwin = true;
for (int i = 0; i < 64; i++) {
if (shared_data->itb[i] != thread->getITBPtr()->TteRead(i))
diffTlb = true;
if (shared_data->dtb[i] != thread->getDTBPtr()->TteRead(i))
diffTlb = true;
}
if ((diffPC || diffCC || diffInst || diffRegs || diffTpc ||
diffTnpc || diffTstate || diffTt || diffHpstate ||
diffHtstate || diffHtba || diffPstate || diffY ||
diffCcr || diffTl || diffGl || diffAsi || diffPil ||
diffCwp || diffCansave || diffCanrestore ||
diffOtherwin || diffCleanwin)
diffOtherwin || diffCleanwin || diffTlb)
&& !((staticInst->machInst & 0xC1F80000) == 0x81D00000)
&& !((staticInst->machInst & 0xC1F80000) == 0xC0580000)
&& !((staticInst->machInst & 0xC1F80000) == 0xC0000000)
&& !((staticInst->machInst & 0xC1F80000) == 0xC0700000)) {
&& !(((staticInst->machInst & 0xC0000000) == 0xC0000000)
&& shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1)
) {
outs << "Differences found between M5 and Legion:";
if (diffPC)
@@ -453,6 +461,8 @@ Trace::InstRecord::dump(ostream &outs)
outs << " [Otherwin]";
if (diffCleanwin)
outs << " [Cleanwin]";
if (diffTlb)
outs << " [Tlb]";
outs << endl << endl;
outs << right << setfill(' ') << setw(15)
@@ -577,6 +587,22 @@ Trace::InstRecord::dump(ostream &outs)
<< endl;*/
}
}
printColumnLabels(outs);
char label[8];
for (int x = 0; x < 64; x++) {
if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) ||
thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) {
sprintf(label, "I-TLB:%02d", x);
printRegPair(outs, label, thread->getITBPtr()->TteRead(x), shared_data->itb[x]);
}
}
for (int x = 0; x < 64; x++) {
if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) ||
thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) {
sprintf(label, "D-TLB:%02d", x);
printRegPair(outs, label, thread->getDTBPtr()->TteRead(x), shared_data->dtb[x]);
}
}
thread->getITBPtr()->dumpAll();
thread->getDTBPtr()->dumpAll();

View File

@@ -30,7 +30,7 @@
#include <unistd.h>
#define VERSION 0xA1000006
#define VERSION 0xA1000007
#define OWN_M5 0x000000AA
#define OWN_LEGION 0x00000055
@@ -72,6 +72,9 @@ typedef struct {
uint8_t otherwin;
uint8_t cleanwin;
uint64_t itb[64];
uint64_t dtb[64];
} SharedData;
/** !!! ^^^ Increment VERSION on change ^^^ !!! **/

View File

@@ -42,6 +42,7 @@
#include "arch/isa_traits.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
#include "mem/packet_access.hh"
#include "mem/physical.hh"
#include "sim/builder.hh"
#include "sim/eventq.hh"
@@ -203,18 +204,60 @@ PhysicalMemory::doFunctionalAccess(PacketPtr pkt)
if (pkt->req->isLocked()) {
trackLoadLocked(pkt->req);
}
DPRINTF(MemoryAccess, "Performing Read of size %i on address 0x%x\n",
pkt->getSize(), pkt->getAddr());
memcpy(pkt->getPtr<uint8_t>(),
pmemAddr + pkt->getAddr() - params()->addrRange.start,
pkt->getSize());
#if TRACING_ON
switch (pkt->getSize()) {
case sizeof(uint64_t):
DPRINTF(MemoryAccess, "Read of size %i on address 0x%x data 0x%x\n",
pkt->getSize(), pkt->getAddr(),pkt->get<uint64_t>());
break;
case sizeof(uint32_t):
DPRINTF(MemoryAccess, "Read of size %i on address 0x%x data 0x%x\n",
pkt->getSize(), pkt->getAddr(),pkt->get<uint32_t>());
break;
case sizeof(uint16_t):
DPRINTF(MemoryAccess, "Read of size %i on address 0x%x data 0x%x\n",
pkt->getSize(), pkt->getAddr(),pkt->get<uint16_t>());
break;
case sizeof(uint8_t):
DPRINTF(MemoryAccess, "Read of size %i on address 0x%x data 0x%x\n",
pkt->getSize(), pkt->getAddr(),pkt->get<uint8_t>());
break;
default:
DPRINTF(MemoryAccess, "Read of size %i on address 0x%x\n",
pkt->getSize(), pkt->getAddr());
}
#endif
}
else if (pkt->isWrite()) {
if (writeOK(pkt->req)) {
DPRINTF(MemoryAccess, "Performing Write of size %i on address 0x%x\n",
pkt->getSize(), pkt->getAddr());
memcpy(pmemAddr + pkt->getAddr() - params()->addrRange.start,
pkt->getPtr<uint8_t>(), pkt->getSize());
#if TRACING_ON
switch (pkt->getSize()) {
case sizeof(uint64_t):
DPRINTF(MemoryAccess, "Write of size %i on address 0x%x data 0x%x\n",
pkt->getSize(), pkt->getAddr(),pkt->get<uint64_t>());
break;
case sizeof(uint32_t):
DPRINTF(MemoryAccess, "Write of size %i on address 0x%x data 0x%x\n",
pkt->getSize(), pkt->getAddr(),pkt->get<uint32_t>());
break;
case sizeof(uint16_t):
DPRINTF(MemoryAccess, "Write of size %i on address 0x%x data 0x%x\n",
pkt->getSize(), pkt->getAddr(),pkt->get<uint16_t>());
break;
case sizeof(uint8_t):
DPRINTF(MemoryAccess, "Write of size %i on address 0x%x data 0x%x\n",
pkt->getSize(), pkt->getAddr(),pkt->get<uint8_t>());
break;
default:
DPRINTF(MemoryAccess, "Write of size %i on address 0x%x\n",
pkt->getSize(), pkt->getAddr());
}
#endif
}
}
else if (pkt->isInvalidate()) {

View File

@@ -11,4 +11,4 @@ class SparcDTB(SparcTLB):
class SparcITB(SparcTLB):
type = 'SparcITB'
size = 48
size = 64