summaryrefslogtreecommitdiff
path: root/src/mem/bridge.cc
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@eecs.umich.edu>2007-05-14 13:54:22 -0700
committerSteve Reinhardt <stever@eecs.umich.edu>2007-05-14 13:54:22 -0700
commit224ae7813dd307bf22132d723120ac2060b06afe (patch)
treed902933ea6109fdd40256d91ab37933c91a043b6 /src/mem/bridge.cc
parentfecae03a0be9a5afc7f9c3536a425f8176afbd3e (diff)
parentfcf85725b5d2d67458c00680948d0a7baab942d4 (diff)
downloadgem5-224ae7813dd307bf22132d723120ac2060b06afe.tar.xz
Merge vm1.(none):/home/stever/bk/newmem-head
into vm1.(none):/home/stever/bk/newmem-cache2 --HG-- extra : convert_revision : 8a501917daf81021212d136b4ebbfa059b452a13
Diffstat (limited to 'src/mem/bridge.cc')
-rw-r--r--src/mem/bridge.cc60
1 files changed, 52 insertions, 8 deletions
diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc
index e89473be3..f525ccb48 100644
--- a/src/mem/bridge.cc
+++ b/src/mem/bridge.cc
@@ -119,7 +119,14 @@ Bridge::BridgePort::recvTiming(PacketPtr pkt)
DPRINTF(BusBridge, "recvTiming: src %d dest %d addr 0x%x\n",
pkt->getSrc(), pkt->getDest(), pkt->getAddr());
- if (pkt->isRequest() && otherPort->reqQueueFull()) {
+ DPRINTF(BusBridge, "Local queue size: %d outreq: %d outresp: %d\n",
+ sendQueue.size(), queuedRequests, outstandingResponses);
+ DPRINTF(BusBridge, "Remove queue size: %d outreq: %d outresp: %d\n",
+ otherPort->sendQueue.size(), otherPort->queuedRequests,
+ otherPort->outstandingResponses);
+
+ if (pkt->isRequest() && otherPort->reqQueueFull() && pkt->result !=
+ Packet::Nacked) {
DPRINTF(BusBridge, "Remote queue full, nacking\n");
nackRequest(pkt);
return true;
@@ -191,7 +198,7 @@ Bridge::BridgePort::nackRequest(PacketPtr pkt)
void
Bridge::BridgePort::queueForSendTiming(PacketPtr pkt)
{
- if (pkt->isResponse() || pkt->result == Packet::Nacked) {
+ if (pkt->isResponse() || pkt->result == Packet::Nacked) {
// This is a response for a request we forwarded earlier. The
// corresponding PacketBuffer should be stored in the packet's
// senderState field.
@@ -201,9 +208,9 @@ Bridge::BridgePort::queueForSendTiming(PacketPtr pkt)
// from original request
buf->fixResponse(pkt);
- // Check if this packet was expecting a response (this is either it or
- // its a nacked packet and we won't be seeing that response)
- if (buf->expectResponse)
+ // Check if this packet was expecting a response and it's a nacked
+ // packet, in which case we will never being seeing it
+ if (buf->expectResponse && pkt->result == Packet::Nacked)
--outstandingResponses;
@@ -213,6 +220,13 @@ Bridge::BridgePort::queueForSendTiming(PacketPtr pkt)
delete buf;
}
+
+ if (pkt->isRequest() && pkt->result != Packet::Nacked) {
+ ++queuedRequests;
+ }
+
+
+
Tick readyTime = curTick + delay;
PacketBuffer *buf = new PacketBuffer(pkt, readyTime);
DPRINTF(BusBridge, "old sender state: %#X, new sender state: %#X\n",
@@ -225,7 +239,6 @@ Bridge::BridgePort::queueForSendTiming(PacketPtr pkt)
if (sendQueue.empty()) {
sendEvent.schedule(readyTime);
}
- ++queuedRequests;
sendQueue.push_back(buf);
}
@@ -254,6 +267,8 @@ Bridge::BridgePort::trySend()
DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n",
buf->origSrc, pkt->getDest(), pkt->getAddr());
+ bool wasReq = pkt->isRequest();
+ bool wasNacked = pkt->result == Packet::Nacked;
if (sendTiming(pkt)) {
// send successful
@@ -270,8 +285,12 @@ Bridge::BridgePort::trySend()
delete buf;
}
- if (!buf->nacked)
+ if (!wasNacked) {
+ if (wasReq)
--queuedRequests;
+ else
+ --outstandingResponses;
+ }
// If there are more packets to send, schedule event to try again.
if (!sendQueue.empty()) {
@@ -305,7 +324,32 @@ Bridge::BridgePort::recvRetry()
Tick
Bridge::BridgePort::recvAtomic(PacketPtr pkt)
{
- return otherPort->sendAtomic(pkt) + delay;
+ int pbs = otherPort->peerBlockSize();
+ Tick atomic_delay;
+ // fix partial atomic writes... similar to the timing code that does the
+ // same
+ if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite &&
+ pkt->getOffset(pbs) && pkt->getSize() != pbs) {
+ PacketDataPtr data;
+ data = new uint8_t[pbs];
+ PacketPtr funcPkt = new Packet(pkt->req, MemCmd::ReadReq,
+ Packet::Broadcast, pbs);
+
+ funcPkt->dataStatic(data);
+ otherPort->sendFunctional(funcPkt);
+ assert(funcPkt->result == Packet::Success);
+ delete funcPkt;
+ memcpy(data + pkt->getOffset(pbs), pkt->getPtr<uint8_t>(),
+ pkt->getSize());
+ PacketPtr newPkt = new Packet(pkt->req, MemCmd::WriteInvalidateReq,
+ Packet::Broadcast, pbs);
+ pkt->dataDynamicArray(data);
+ atomic_delay = otherPort->sendAtomic(newPkt);
+ delete newPkt;
+ } else {
+ atomic_delay = otherPort->sendAtomic(pkt);
+ }
+ return atomic_delay + delay;
}
/** Function called by the port when the bus is receiving a Functional