X86: Fix the timing mode of the page table walker.
This commit is contained in:
parent
f02df8cb74
commit
7462cb0842
2 changed files with 25 additions and 28 deletions
|
@ -85,7 +85,7 @@ BitUnion64(PageTableEntry)
|
|||
EndBitUnion(PageTableEntry)
|
||||
|
||||
Fault
|
||||
Walker::doNext(PacketPtr &read, PacketPtr &write)
|
||||
Walker::doNext(PacketPtr &write)
|
||||
{
|
||||
assert(state != Ready && state != Waiting);
|
||||
write = NULL;
|
||||
|
@ -312,7 +312,6 @@ Walker::start(ThreadContext * _tc, BaseTLB::Translation *_translation,
|
|||
RequestPtr _req, bool _write, bool _execute)
|
||||
{
|
||||
assert(state == Ready);
|
||||
assert(!tc);
|
||||
tc = _tc;
|
||||
req = _req;
|
||||
Addr vaddr = req->getVaddr();
|
||||
|
@ -366,21 +365,22 @@ Walker::start(ThreadContext * _tc, BaseTLB::Translation *_translation,
|
|||
read->allocate();
|
||||
Enums::MemoryMode memMode = sys->getMemoryMode();
|
||||
if (memMode == Enums::timing) {
|
||||
nextState = state;
|
||||
state = Waiting;
|
||||
timingFault = NoFault;
|
||||
port.sendTiming(read);
|
||||
sendPackets();
|
||||
} else if (memMode == Enums::atomic) {
|
||||
Fault fault;
|
||||
do {
|
||||
port.sendAtomic(read);
|
||||
PacketPtr write = NULL;
|
||||
fault = doNext(read, write);
|
||||
fault = doNext(write);
|
||||
assert(fault == NoFault || read == NULL);
|
||||
state = nextState;
|
||||
nextState = Ready;
|
||||
if (write)
|
||||
port.sendAtomic(write);
|
||||
} while(read);
|
||||
tc = NULL;
|
||||
state = Ready;
|
||||
nextState = Waiting;
|
||||
return fault;
|
||||
|
@ -399,18 +399,18 @@ Walker::WalkerPort::recvTiming(PacketPtr pkt)
|
|||
bool
|
||||
Walker::recvTiming(PacketPtr pkt)
|
||||
{
|
||||
inflight--;
|
||||
if (pkt->isResponse() && !pkt->wasNacked()) {
|
||||
assert(inflight);
|
||||
assert(state == Waiting);
|
||||
assert(!read);
|
||||
inflight--;
|
||||
if (pkt->isRead()) {
|
||||
assert(inflight);
|
||||
assert(state == Waiting);
|
||||
assert(!read);
|
||||
state = nextState;
|
||||
nextState = Ready;
|
||||
PacketPtr write = NULL;
|
||||
timingFault = doNext(pkt, write);
|
||||
state = Waiting;
|
||||
read = pkt;
|
||||
timingFault = doNext(write);
|
||||
state = Waiting;
|
||||
assert(timingFault == NoFault || read == NULL);
|
||||
if (write) {
|
||||
writes.push_back(write);
|
||||
|
@ -420,7 +420,6 @@ Walker::recvTiming(PacketPtr pkt)
|
|||
sendPackets();
|
||||
}
|
||||
if (inflight == 0 && read == NULL && writes.size() == 0) {
|
||||
tc = NULL;
|
||||
state = Ready;
|
||||
nextState = Waiting;
|
||||
if (timingFault == NoFault) {
|
||||
|
@ -445,6 +444,7 @@ Walker::recvTiming(PacketPtr pkt)
|
|||
} else if (pkt->wasNacked()) {
|
||||
pkt->reinitNacked();
|
||||
if (!port.sendTiming(pkt)) {
|
||||
inflight--;
|
||||
retrying = true;
|
||||
if (pkt->isWrite()) {
|
||||
writes.push_back(pkt);
|
||||
|
@ -452,8 +452,6 @@ Walker::recvTiming(PacketPtr pkt)
|
|||
assert(!read);
|
||||
read = pkt;
|
||||
}
|
||||
} else {
|
||||
inflight++;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -507,27 +505,26 @@ Walker::sendPackets()
|
|||
|
||||
//Reads always have priority
|
||||
if (read) {
|
||||
if (!port.sendTiming(read)) {
|
||||
PacketPtr pkt = read;
|
||||
read = NULL;
|
||||
inflight++;
|
||||
if (!port.sendTiming(pkt)) {
|
||||
retrying = true;
|
||||
read = pkt;
|
||||
inflight--;
|
||||
return;
|
||||
} else {
|
||||
inflight++;
|
||||
delete read->req;
|
||||
delete read;
|
||||
read = NULL;
|
||||
}
|
||||
}
|
||||
//Send off as many of the writes as we can.
|
||||
while (writes.size()) {
|
||||
PacketPtr write = writes.back();
|
||||
writes.pop_back();
|
||||
inflight++;
|
||||
if (!port.sendTiming(write)) {
|
||||
retrying = true;
|
||||
writes.push_back(write);
|
||||
inflight--;
|
||||
return;
|
||||
} else {
|
||||
inflight++;
|
||||
delete write->req;
|
||||
delete write;
|
||||
writes.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,15 +85,15 @@ namespace X86ISA
|
|||
PSEPD, PD, PTE
|
||||
};
|
||||
|
||||
// Act on the current state and determine what to do next. read
|
||||
// should be the packet that just came back from a read and write
|
||||
// Act on the current state and determine what to do next. The global
|
||||
// read should be the packet that just came back from a read and write
|
||||
// should be NULL. When the function returns, read is either NULL
|
||||
// if the machine is finished, or points to a packet to initiate
|
||||
// the next read. If any write is required to update an "accessed"
|
||||
// bit, write will point to a packet to do the write. Otherwise it
|
||||
// will be NULL. The return value is whatever fault was incurred
|
||||
// during this stage of the lookup.
|
||||
Fault doNext(PacketPtr &read, PacketPtr &write);
|
||||
Fault doNext(PacketPtr &write);
|
||||
|
||||
// Kick off the state machine.
|
||||
Fault start(ThreadContext * _tc, BaseTLB::Translation *translation,
|
||||
|
|
Loading…
Reference in a new issue