summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/bus.cc33
-rw-r--r--src/mem/bus.hh9
-rw-r--r--src/mem/cache/cache.hh1
-rw-r--r--src/mem/cache/cache_impl.hh11
-rw-r--r--src/mem/mem_object.cc5
-rw-r--r--src/mem/mem_object.hh4
-rw-r--r--src/mem/port.cc10
-rw-r--r--src/mem/port.hh5
8 files changed, 65 insertions, 13 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index cc2137e66..4988df3c5 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -34,6 +34,8 @@
*/
+#include <limits>
+
#include "base/misc.hh"
#include "base/trace.hh"
#include "mem/bus.hh"
@@ -52,20 +54,30 @@ Bus::getPort(const std::string &if_name, int idx)
}
// if_name ignored? forced to be empty?
- int id = interfaces.size();
+ int id = maxId++;
+ assert(maxId < std::numeric_limits<typeof(maxId)>::max());
BusPort *bp = new BusPort(csprintf("%s-p%d", name(), id), this, id);
- interfaces.push_back(bp);
+ interfaces[id] = bp;
return bp;
}
+void
+Bus::deletePortRefs(Port *p)
+{
+ BusPort *bp = dynamic_cast<BusPort*>(p);
+ if (bp == NULL)
+ panic("Couldn't convert Port* to BusPort*\n");
+ interfaces.erase(bp->getId());
+}
+
/** Get the ranges of anyone other buses that we are connected to. */
void
Bus::init()
{
- std::vector<BusPort*>::iterator intIter;
+ m5::hash_map<short,BusPort*>::iterator intIter;
for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
- (*intIter)->sendStatusChange(Port::RangeChange);
+ intIter->second->sendStatusChange(Port::RangeChange);
}
Bus::BusFreeEvent::BusFreeEvent(Bus *_bus) : Event(&mainEventQueue), bus(_bus)
@@ -186,7 +198,7 @@ Bus::recvTiming(PacketPtr pkt)
return false;
}
} else {
- assert(dest >= 0 && dest < interfaces.size());
+ assert(dest >= 0 && dest < maxId);
assert(dest != pkt->getSrc()); // catch infinite loops
port = interfaces[dest];
}
@@ -435,7 +447,6 @@ Bus::recvStatusChange(Port::Status status, int id)
{
AddrRangeList ranges;
AddrRangeList snoops;
- int x;
AddrRangeIter iter;
assert(status == Port::RangeChange &&
@@ -457,7 +468,7 @@ Bus::recvStatusChange(Port::Status status, int id)
}
} else {
- assert((id < interfaces.size() && id >= 0) || id == defaultId);
+ assert((id < maxId && id >= 0) || id == defaultId);
Port *port = interfaces[id];
range_map<Addr,int>::iterator portIter;
std::vector<DevMap>::iterator snoopIter;
@@ -502,9 +513,11 @@ Bus::recvStatusChange(Port::Status status, int id)
// tell all our peers that our address range has changed.
// Don't tell the device that caused this change, it already knows
- for (x = 0; x < interfaces.size(); x++)
- if (x != id)
- interfaces[x]->sendStatusChange(Port::RangeChange);
+ m5::hash_map<short,BusPort*>::iterator intIter;
+
+ for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
+ if (intIter->first != id)
+ intIter->second->sendStatusChange(Port::RangeChange);
if (id != defaultId && defaultPort)
defaultPort->sendStatusChange(Port::RangeChange);
diff --git a/src/mem/bus.hh b/src/mem/bus.hh
index 350a67b43..6706b6c77 100644
--- a/src/mem/bus.hh
+++ b/src/mem/bus.hh
@@ -42,6 +42,7 @@
#include <inttypes.h>
#include "base/range.hh"
+#include "base/hashmap.hh"
#include "base/range_map.hh"
#include "mem/mem_object.hh"
#include "mem/packet.hh"
@@ -212,9 +213,12 @@ class Bus : public MemObject
bool inRetry;
+ /** max number of bus ids we've handed out so far */
+ short maxId;
+
/** An array of pointers to the peer port interfaces
connected to this bus.*/
- std::vector<BusPort*> interfaces;
+ m5::hash_map<short,BusPort*> interfaces;
/** An array of pointers to ports that retry should be called on because the
* original send failed for whatever reason.*/
@@ -252,6 +256,7 @@ class Bus : public MemObject
/** A function used to return the port associated with this bus object. */
virtual Port *getPort(const std::string &if_name, int idx = -1);
+ virtual void deletePortRefs(Port *p);
virtual void init();
@@ -261,7 +266,7 @@ class Bus : public MemObject
bool responder_set)
: MemObject(n), busId(bus_id), clock(_clock), width(_width),
tickNextIdle(0), drainEvent(NULL), busIdle(this), inRetry(false),
- defaultPort(NULL), responderSet(responder_set)
+ maxId(0), defaultPort(NULL), responderSet(responder_set)
{
//Both the width and clock period must be positive
if (width <= 0)
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh
index 26dab2179..722ce216b 100644
--- a/src/mem/cache/cache.hh
+++ b/src/mem/cache/cache.hh
@@ -331,6 +331,7 @@ class Cache : public BaseCache
Cache(const std::string &_name, Params &params);
virtual Port *getPort(const std::string &if_name, int idx = -1);
+ virtual void deletePortRefs(Port *p);
virtual void recvStatusChange(Port::Status status, bool isCpuSide);
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index dac2b93a4..056f6033f 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -1100,7 +1100,7 @@ Cache<TagStore,Coherence>::getPort(const std::string &if_name, int idx)
}
else if (if_name == "functional")
{
- return new CpuSidePort(name() + "-cpu_side_port", this);
+ return new CpuSidePort(name() + "-cpu_side_funcport", this);
}
else if (if_name == "cpu_side")
{
@@ -1121,6 +1121,15 @@ Cache<TagStore,Coherence>::getPort(const std::string &if_name, int idx)
else panic("Port name %s unrecognized\n", if_name);
}
+template<class TagStore, class Coherence>
+void
+Cache<TagStore,Coherence>::deletePortRefs(Port *p)
+{
+ if (cpuSidePort == p || memSidePort == p)
+ panic("Can only delete functional ports\n");
+ // nothing else to do
+}
+
template<class TagStore, class Coherence>
bool
diff --git a/src/mem/mem_object.cc b/src/mem/mem_object.cc
index d4d3fd283..ef31cf999 100644
--- a/src/mem/mem_object.cc
+++ b/src/mem/mem_object.cc
@@ -35,5 +35,10 @@ MemObject::MemObject(const std::string &name)
: SimObject(name)
{
}
+void
+MemObject::deletePortRefs(Port *p)
+{
+ panic("This object does not support port deletion\n");
+}
DEFINE_SIM_OBJECT_CLASS_NAME("MemObject", MemObject)
diff --git a/src/mem/mem_object.hh b/src/mem/mem_object.hh
index d12eeffe0..ec6fa2b2a 100644
--- a/src/mem/mem_object.hh
+++ b/src/mem/mem_object.hh
@@ -51,6 +51,10 @@ class MemObject : public SimObject
public:
/** Additional function to return the Port of a memory object. */
virtual Port *getPort(const std::string &if_name, int idx = -1) = 0;
+
+ /** Tell object that this port is about to disappear, so it should remove it
+ * from any structures that it's keeping it in. */
+ virtual void deletePortRefs(Port *p) ;
};
#endif //__MEM_MEM_OBJECT_HH__
diff --git a/src/mem/port.cc b/src/mem/port.cc
index 048d7cf6d..e75e50e4d 100644
--- a/src/mem/port.cc
+++ b/src/mem/port.cc
@@ -36,6 +36,7 @@
#include "base/chunk_generator.hh"
#include "base/trace.hh"
+#include "mem/mem_object.hh"
#include "mem/port.hh"
void
@@ -46,6 +47,15 @@ Port::setPeer(Port *port)
}
void
+Port::removeConn()
+{
+ if (peer->getOwner())
+ peer->getOwner()->deletePortRefs(peer);
+ delete peer;
+ peer = NULL;
+}
+
+void
Port::blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd)
{
Request req;
diff --git a/src/mem/port.hh b/src/mem/port.hh
index fdb5bfab4..52162bf76 100644
--- a/src/mem/port.hh
+++ b/src/mem/port.hh
@@ -131,6 +131,11 @@ class Port
/** Function to return the owner of this port. */
MemObject *getOwner() { return owner; }
+ /** Inform the peer port to delete itself and notify it's owner about it's
+ * demise. */
+ void removeConn();
+
+
protected:
/** These functions are protected because they should only be