summaryrefslogtreecommitdiff
path: root/src/mem/bridge.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/bridge.hh')
-rw-r--r--src/mem/bridge.hh51
1 files changed, 48 insertions, 3 deletions
diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh
index f7d0d12d0..d1154eda0 100644
--- a/src/mem/bridge.hh
+++ b/src/mem/bridge.hh
@@ -66,6 +66,8 @@ class Bridge : public MemObject
/** Minimum delay though this bridge. */
Tick delay;
+ bool fixPartialWrite;
+
class PacketBuffer : public Packet::SenderState {
public:
@@ -75,10 +77,13 @@ class Bridge : public MemObject
short origSrc;
bool expectResponse;
+ bool partialWriteFixed;
+ PacketPtr oldPkt;
+
PacketBuffer(PacketPtr _pkt, Tick t)
: ready(t), pkt(_pkt),
origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
- expectResponse(_pkt->needsResponse())
+ expectResponse(_pkt->needsResponse()), partialWriteFixed(false)
{
if (!pkt->isResponse())
pkt->senderState = this;
@@ -89,7 +94,46 @@ class Bridge : public MemObject
assert(pkt->senderState == this);
pkt->setDest(origSrc);
pkt->senderState = origSenderState;
+ if (partialWriteFixed)
+ delete oldPkt;
+ }
+
+ void partialWriteFix(Port *port)
+ {
+ assert(!partialWriteFixed);
+ assert(expectResponse);
+
+ int pbs = port->peerBlockSize();
+ partialWriteFixed = true;
+ PacketDataPtr data;
+
+ data = new uint8_t[pbs];
+ PacketPtr funcPkt = new Packet(pkt->req, MemCmd::ReadReq,
+ Packet::Broadcast, pbs);
+
+ funcPkt->dataStatic(data);
+ port->sendFunctional(funcPkt);
+ assert(funcPkt->result == Packet::Success);
+ delete funcPkt;
+
+ oldPkt = pkt;
+ memcpy(data + oldPkt->getOffset(pbs), pkt->getPtr<uint8_t>(),
+ pkt->getSize());
+ pkt = new Packet(oldPkt->req, MemCmd::WriteInvalidateReq,
+ Packet::Broadcast, pbs);
+ pkt->dataDynamicArray(data);
+ pkt->senderState = oldPkt->senderState;
}
+
+ void undoPartialWriteFix()
+ {
+ if (!partialWriteFixed)
+ return;
+ delete pkt;
+ pkt = oldPkt;
+ partialWriteFixed = false;
+ }
+
};
/**
@@ -140,7 +184,7 @@ class Bridge : public MemObject
/** Constructor for the BusPort.*/
BridgePort(const std::string &_name,
Bridge *_bridge, BridgePort *_otherPort,
- int _delay, int _queueLimit);
+ int _delay, int _queueLimit, bool fix_partial_write);
protected:
@@ -182,7 +226,8 @@ class Bridge : public MemObject
virtual void init();
- Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack);
+ Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack,
+ bool fix_partial_write_a, bool fix_partial_write_b);
};
#endif //__MEM_BUS_HH__