summaryrefslogtreecommitdiff
path: root/src/mem/bridge.hh
diff options
context:
space:
mode:
authorAli Saidi <saidi@eecs.umich.edu>2007-05-07 14:42:03 -0400
committerAli Saidi <saidi@eecs.umich.edu>2007-05-07 14:42:03 -0400
commit0dfc29a023ff407846ea4f200547e2b2d9de9c1a (patch)
treeea900fcfbb26455082766dfc99e39ab529f14e9c /src/mem/bridge.hh
parentb7292a1713afb95572dd0d379dcbb39d0bfd9191 (diff)
downloadgem5-0dfc29a023ff407846ea4f200547e2b2d9de9c1a.tar.xz
fix partial writes with a functional memory hack
figure out the block size from devices attached to the bus otherwise use a default block size when no devices that care are attached configs/common/FSConfig.py: src/mem/bridge.cc: src/mem/bridge.hh: src/python/m5/objects/Bridge.py: fix partial writes with a functional memory hack src/mem/bus.cc: src/mem/bus.hh: src/python/m5/objects/Bus.py: figure out the block size from devices attached to the bus otherwise use a default block size when no devices that care are attached src/mem/packet.cc: fix WriteInvalidateResp to not be a request that needs a response since it isn't src/mem/port.hh: by default return 0 for deviceBlockSize instead of panicing. This makes finding the block size the bus should use easier --HG-- extra : convert_revision : 3fcfe95f9f392ef76f324ee8bd1d7f6de95c1a64
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__