summaryrefslogtreecommitdiff
path: root/src/mem/physical.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/physical.cc')
-rw-r--r--src/mem/physical.cc60
1 files changed, 41 insertions, 19 deletions
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index 5d7d7382a..6621c36cf 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,14 @@ PhysicalMemory::PhysicalMemory(Params *p)
void
PhysicalMemory::init()
{
- if (!port)
- panic("PhysicalMemory not connected to anything!");
- port->sendStatusChange(Port::RangeChange);
+ if (ports.size() == 0) {
+ fatal("PhysicalMemory object %s is unconnected!", name());
+ }
+
+ for (PortIterator pi = ports.begin(); pi != ports.end(); ++pi) {
+ if (*pi)
+ (*pi)->sendStatusChange(Port::RangeChange);
+ }
}
PhysicalMemory::~PhysicalMemory()
@@ -335,19 +340,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)
{
@@ -366,18 +385,17 @@ PhysicalMemory::MemoryPort::recvStatusChange(Port::Status status)
void
PhysicalMemory::MemoryPort::getDeviceAddressRanges(AddrRangeList &resp,
- AddrRangeList &snoop)
+ bool &snoop)
{
memory->getAddressRanges(resp, snoop);
}
void
-PhysicalMemory::getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
+PhysicalMemory::getAddressRanges(AddrRangeList &resp, bool &snoop)
{
- snoop.clear();
+ snoop = false;
resp.clear();
- resp.push_back(RangeSize(start(),
- params()->addrRange.size()));
+ resp.push_back(RangeSize(start(), params()->addrRange.size()));
}
int
@@ -420,7 +438,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