summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mem/bridge.cc44
-rw-r--r--src/mem/bridge.hh51
-rw-r--r--src/mem/physical.cc47
-rw-r--r--src/mem/physical.hh3
-rw-r--r--src/python/m5/objects/PhysicalMemory.py3
-rw-r--r--src/python/swig/pyobject.cc1
6 files changed, 54 insertions, 95 deletions
diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc
index 5460c88dd..d68d4ded0 100644
--- a/src/mem/bridge.cc
+++ b/src/mem/bridge.cc
@@ -243,19 +243,21 @@ Bridge::BridgePort::trySend()
{
assert(!sendQueue.empty());
- int pbs = peerBlockSize();
-
PacketBuffer *buf = sendQueue.front();
assert(buf->ready <= curTick);
PacketPtr pkt = buf->pkt;
+ // Ugly! @todo When multilevel coherence works this will be removed
if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite &&
- pkt->result != Packet::Nacked && pkt->getOffset(pbs) &&
- pkt->getSize() != pbs) {
- buf->partialWriteFix(this);
- pkt = buf->pkt;
+ pkt->result != Packet::Nacked) {
+ PacketPtr funcPkt = new Packet(pkt->req, MemCmd::WriteReq,
+ Packet::Broadcast);
+ funcPkt->dataStatic(pkt->getPtr<uint8_t>());
+ sendFunctional(funcPkt);
+ pkt->cmd = MemCmd::WriteReq;
+ delete funcPkt;
}
DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n",
@@ -294,7 +296,6 @@ Bridge::BridgePort::trySend()
}
} else {
DPRINTF(BusBridge, " unsuccessful\n");
- buf->undoPartialWriteFix();
inRetry = true;
}
DPRINTF(BusBridge, "trySend: queue size: %d outreq: %d outstanding resp: %d\n",
@@ -318,32 +319,18 @@ Bridge::BridgePort::recvRetry()
Tick
Bridge::BridgePort::recvAtomic(PacketPtr pkt)
{
- 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);
+ // same... will be removed once our code gets this right
+ if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite) {
- funcPkt->dataStatic(data);
+ PacketPtr funcPkt = new Packet(pkt->req, MemCmd::WriteReq,
+ Packet::Broadcast);
+ funcPkt->dataStatic(pkt->getPtr<uint8_t>());
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);
+ pkt->cmd = MemCmd::WriteReq;
}
- return atomic_delay + delay;
+ return delay + otherPort->sendAtomic(pkt);
}
/** Function called by the port when the bus is receiving a Functional
@@ -425,3 +412,4 @@ CREATE_SIM_OBJECT(Bridge)
REGISTER_SIM_OBJECT("Bridge", Bridge)
+
diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh
index 5951eeb98..a47fe3c1e 100644
--- a/src/mem/bridge.hh
+++ b/src/mem/bridge.hh
@@ -80,14 +80,10 @@ class Bridge : public MemObject
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)
+ expectResponse(_pkt->needsResponse() && !nack)
{
if (!pkt->isResponse() && !nack && pkt->result != Packet::Nacked)
@@ -99,52 +95,7 @@ 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);
-
- 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;
- }
-
};
/**
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index 5d7d7382a..a49959e51 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -52,7 +52,7 @@ using namespace std;
using namespace TheISA;
PhysicalMemory::PhysicalMemory(Params *p)
- : MemObject(p->name), pmemAddr(NULL), port(NULL), lat(p->latency), _params(p)
+ : MemObject(p->name), pmemAddr(NULL), lat(p->latency), _params(p)
{
if (params()->addrRange.size() % TheISA::PageBytes != 0)
panic("Memory Size not divisible by page size\n");
@@ -76,9 +76,10 @@ PhysicalMemory::PhysicalMemory(Params *p)
void
PhysicalMemory::init()
{
- if (!port)
- panic("PhysicalMemory not connected to anything!");
- port->sendStatusChange(Port::RangeChange);
+ for (PortIterator pi = ports.begin(); pi != ports.end(); ++pi) {
+ if (*pi)
+ (*pi)->sendStatusChange(Port::RangeChange);
+ }
}
PhysicalMemory::~PhysicalMemory()
@@ -335,19 +336,33 @@ PhysicalMemory::doFunctionalAccess(PacketPtr pkt)
Port *
PhysicalMemory::getPort(const std::string &if_name, int idx)
{
- if (if_name == "port" && idx == -1) {
- if (port != NULL)
- panic("PhysicalMemory::getPort: additional port requested to memory!");
- port = new MemoryPort(name() + "-port", this);
- return port;
- } else if (if_name == "functional") {
- /* special port for functional writes at startup. And for memtester */
- return new MemoryPort(name() + "-funcport", this);
- } else {
+ // Accept request for "functional" port for backwards compatibility
+ // with places where this function is called from C++. I'd prefer
+ // to move all these into Python someday.
+ if (if_name == "functional") {
+ return new MemoryPort(csprintf("%s-functional", name()), this);
+ }
+
+ if (if_name != "port") {
panic("PhysicalMemory::getPort: unknown port %s requested", if_name);
}
+
+ if (idx >= ports.size()) {
+ ports.resize(idx+1);
+ }
+
+ if (ports[idx] != NULL) {
+ panic("PhysicalMemory::getPort: port %d already assigned", idx);
+ }
+
+ MemoryPort *port =
+ new MemoryPort(csprintf("%s-port%d", name(), idx), this);
+
+ ports[idx] = port;
+ return port;
}
+
void
PhysicalMemory::recvStatusChange(Port::Status status)
{
@@ -420,7 +435,11 @@ PhysicalMemory::MemoryPort::recvFunctional(PacketPtr pkt)
unsigned int
PhysicalMemory::drain(Event *de)
{
- int count = port->drain(de);
+ int count = 0;
+ for (PortIterator pi = ports.begin(); pi != ports.end(); ++pi) {
+ count += (*pi)->drain(de);
+ }
+
if (count)
changeState(Draining);
else
diff --git a/src/mem/physical.hh b/src/mem/physical.hh
index f7200b502..e3355d6aa 100644
--- a/src/mem/physical.hh
+++ b/src/mem/physical.hh
@@ -141,9 +141,10 @@ class PhysicalMemory : public MemObject
}
uint8_t *pmemAddr;
- MemoryPort *port;
int pagePtr;
Tick lat;
+ std::vector<MemoryPort*> ports;
+ typedef std::vector<MemoryPort*>::iterator PortIterator;
public:
Addr new_page();
diff --git a/src/python/m5/objects/PhysicalMemory.py b/src/python/m5/objects/PhysicalMemory.py
index c389e4a7f..83dbc7710 100644
--- a/src/python/m5/objects/PhysicalMemory.py
+++ b/src/python/m5/objects/PhysicalMemory.py
@@ -4,8 +4,7 @@ from MemObject import *
class PhysicalMemory(MemObject):
type = 'PhysicalMemory'
- port = Port("the access port")
- functional = Port("Functional Access Port")
+ port = VectorPort("the access port")
range = Param.AddrRange(AddrRange('128MB'), "Device Address")
file = Param.String('', "memory mapped file")
latency = Param.Latency('1t', "latency of an access")
diff --git a/src/python/swig/pyobject.cc b/src/python/swig/pyobject.cc
index 11141fa84..2a5f2b9fb 100644
--- a/src/python/swig/pyobject.cc
+++ b/src/python/swig/pyobject.cc
@@ -62,6 +62,7 @@ lookupPort(SimObject *so, const std::string &name, int i)
/**
* Connect the described MemObject ports. Called from Python via SWIG.
+ * The indices i1 & i2 will be -1 for regular ports, >= 0 for vector ports.
*/
int
connectPorts(SimObject *o1, const std::string &name1, int i1,