#include <inttypes.h>
#include <queue>
+#include "base/fast_alloc.hh"
#include "mem/mem_object.hh"
#include "mem/packet.hh"
#include "mem/port.hh"
+#include "params/Bridge.hh"
#include "sim/eventq.hh"
class Bridge : public MemObject
/** Min delay to respond to a nack. */
Tick nackDelay;
- bool fixPartialWrite;
+ /** Pass ranges from one side of the bridge to the other? */
+ std::vector<Range<Addr> > filterRanges;
- class PacketBuffer : public Packet::SenderState {
+ class PacketBuffer : public Packet::SenderState, public FastAlloc {
public:
Tick ready;
PacketPtr pkt;
+ bool nackedHere;
Packet::SenderState *origSenderState;
short origSrc;
bool expectResponse;
- bool partialWriteFixed;
- PacketPtr oldPkt;
-
PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false)
- : ready(t), pkt(_pkt),
- origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
- expectResponse(_pkt->needsResponse() && !nack),
- partialWriteFixed(false)
+ : ready(t), pkt(_pkt), nackedHere(nack),
+ origSenderState(_pkt->senderState),
+ origSrc(nack ? _pkt->getDest() : _pkt->getSrc() ),
+ expectResponse(_pkt->needsResponse() && !nack)
{
- if (!pkt->isResponse() && !nack && pkt->result != Packet::Nacked)
+ if (!pkt->isResponse() && !nack)
pkt->senderState = this;
}
assert(pkt->senderState == this);
pkt->setDest(origSrc);
pkt->senderState = origSenderState;
- if (partialWriteFixed)
- delete oldPkt;
- }
-
- void partialWriteFix(Port *port)
- {
- assert(!partialWriteFixed);
- assert(expectResponse);
-
- Addr pbs = port->peerBlockSize();
- Addr blockAddr = pkt->getAddr() & ~(pbs-1);
- partialWriteFixed = true;
- PacketDataPtr data;
-
- data = new uint8_t[pbs];
- RequestPtr funcReq = new Request(blockAddr, 4, 0);
- PacketPtr funcPkt = new Packet(funcReq, MemCmd::ReadReq,
- Packet::Broadcast);
- for (int x = 0; x < pbs; x+=4) {
- funcReq->setPhys(blockAddr + x, 4, 0);
- funcPkt->reinitFromRequest();
- funcPkt->dataStatic(data + x);
- port->sendFunctional(funcPkt);
- assert(funcPkt->result == Packet::Success);
- }
- delete funcPkt;
- delete funcReq;
-
- 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;
}
-
};
/**
BridgePort *port;
public:
- SendEvent(BridgePort *p)
- : Event(&mainEventQueue), port(p) {}
-
+ SendEvent(BridgePort *p) : port(p) {}
virtual void process() { port->trySend(); }
-
- virtual const char *description() { return "bridge send event"; }
+ virtual const char *description() const { return "bridge send"; }
};
SendEvent sendEvent;
/** Constructor for the BusPort.*/
BridgePort(const std::string &_name, Bridge *_bridge,
BridgePort *_otherPort, int _delay, int _nack_delay,
- int _req_limit, int _resp_limit, bool fix_partial_write);
+ int _req_limit, int _resp_limit,
+ std::vector<Range<Addr> > filter_ranges);
protected:
/** When receiving a address range request the peer port,
pass it to the bridge. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
- AddrRangeList &snoop);
+ bool &snoop);
};
BridgePort portA, portB;
bool ackWrites;
public:
- struct Params
- {
- std::string name;
- int req_size_a;
- int req_size_b;
- int resp_size_a;
- int resp_size_b;
- Tick delay;
- Tick nack_delay;
- bool write_ack;
- bool fix_partial_write_a;
- bool fix_partial_write_b;
- };
+ typedef BridgeParams Params;
protected:
Params *_params;