summaryrefslogtreecommitdiff
path: root/src/mem/bridge.cc
diff options
context:
space:
mode:
authorAli Saidi <saidi@eecs.umich.edu>2007-05-14 16:37:22 -0400
committerAli Saidi <saidi@eecs.umich.edu>2007-05-14 16:37:22 -0400
commitfcf85725b5d2d67458c00680948d0a7baab942d4 (patch)
tree62fe730e450890d1d6ebea05b75b27406f3ca078 /src/mem/bridge.cc
parent011db5c8515804145202373440bad26fa21b30a7 (diff)
parent57104ea5f9e94dc4fe664f91e60278e486111ae9 (diff)
downloadgem5-fcf85725b5d2d67458c00680948d0a7baab942d4.tar.xz
Merge zizzer:/bk/newmem
into zeep.pool:/z/saidi/work/m5.newmem --HG-- extra : convert_revision : e445097240af7b4e73efaca855cd1f217cf00313
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