summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/bridge.cc40
-rw-r--r--src/mem/bridge.hh22
-rw-r--r--src/mem/bus.cc55
-rw-r--r--src/mem/bus.hh5
-rw-r--r--src/mem/physical.cc27
-rw-r--r--src/mem/ruby/system/RubyPort.cc39
-rw-r--r--src/mem/ruby/system/RubyPort.hh4
7 files changed, 104 insertions, 88 deletions
diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc
index b48662118..0733b6ea8 100644
--- a/src/mem/bridge.cc
+++ b/src/mem/bridge.cc
@@ -55,7 +55,7 @@
Bridge::BridgeSlavePort::BridgeSlavePort(const std::string &_name,
Bridge* _bridge,
- BridgeMasterPort* _masterPort,
+ BridgeMasterPort& _masterPort,
int _delay, int _nack_delay,
int _resp_limit,
std::vector<Range<Addr> > _ranges)
@@ -63,24 +63,25 @@ Bridge::BridgeSlavePort::BridgeSlavePort(const std::string &_name,
delay(_delay), nackDelay(_nack_delay),
ranges(_ranges.begin(), _ranges.end()),
outstandingResponses(0), inRetry(false),
- respQueueLimit(_resp_limit), sendEvent(this)
+ respQueueLimit(_resp_limit), sendEvent(*this)
{
}
Bridge::BridgeMasterPort::BridgeMasterPort(const std::string &_name,
Bridge* _bridge,
- BridgeSlavePort* _slavePort,
+ BridgeSlavePort& _slavePort,
int _delay, int _req_limit)
: Port(_name, _bridge), bridge(_bridge), slavePort(_slavePort),
- delay(_delay), inRetry(false), reqQueueLimit(_req_limit), sendEvent(this)
+ delay(_delay), inRetry(false), reqQueueLimit(_req_limit),
+ sendEvent(*this)
{
}
Bridge::Bridge(Params *p)
: MemObject(p),
- slavePort(p->name + "-slave", this, &masterPort, p->delay,
+ slavePort(p->name + "-slave", this, masterPort, p->delay,
p->nack_delay, p->resp_size, p->ranges),
- masterPort(p->name + "-master", this, &slavePort, p->delay, p->req_size),
+ masterPort(p->name + "-master", this, slavePort, p->delay, p->req_size),
ackWrites(p->write_ack), _params(p)
{
if (ackWrites)
@@ -90,19 +91,14 @@ Bridge::Bridge(Params *p)
Port*
Bridge::getPort(const std::string &if_name, int idx)
{
- Port* port;
-
if (if_name == "slave")
- port = &slavePort;
+ return &slavePort;
else if (if_name == "master")
- port = &masterPort;
- else
+ return &masterPort;
+ else {
+ panic("Bridge %s has no port named %s\n", name(), if_name);
return NULL;
-
- if (port->getPeer() != NULL)
- panic("bridge side %s already connected to %s.",
- if_name, port->getPeer()->name());
- return port;
+ }
}
@@ -148,7 +144,7 @@ Bridge::BridgeMasterPort::recvTiming(PacketPtr pkt)
DPRINTF(BusBridge, "Request queue size: %d\n", requestQueue.size());
- slavePort->queueForSendTiming(pkt);
+ slavePort.queueForSendTiming(pkt);
return true;
}
@@ -165,7 +161,7 @@ Bridge::BridgeSlavePort::recvTiming(PacketPtr pkt)
DPRINTF(BusBridge, "Response queue size: %d outresp: %d\n",
responseQueue.size(), outstandingResponses);
- if (masterPort->reqQueueFull()) {
+ if (masterPort.reqQueueFull()) {
DPRINTF(BusBridge, "Request queue full, nacking\n");
nackRequest(pkt);
return true;
@@ -187,7 +183,7 @@ Bridge::BridgeSlavePort::recvTiming(PacketPtr pkt)
}
}
- masterPort->queueForSendTiming(pkt);
+ masterPort.queueForSendTiming(pkt);
return true;
}
@@ -422,7 +418,7 @@ Bridge::BridgeMasterPort::recvAtomic(PacketPtr pkt)
Tick
Bridge::BridgeSlavePort::recvAtomic(PacketPtr pkt)
{
- return delay + masterPort->sendAtomic(pkt);
+ return delay + masterPort.sendAtomic(pkt);
}
void
@@ -450,14 +446,14 @@ Bridge::BridgeSlavePort::recvFunctional(PacketPtr pkt)
}
// also check the master port's request queue
- if (masterPort->checkFunctional(pkt)) {
+ if (masterPort.checkFunctional(pkt)) {
return;
}
pkt->popLabel();
// fall through if pkt still not satisfied
- masterPort->sendFunctional(pkt);
+ masterPort.sendFunctional(pkt);
}
bool
diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh
index d389c0a5e..3e0040514 100644
--- a/src/mem/bridge.hh
+++ b/src/mem/bridge.hh
@@ -131,10 +131,10 @@ class Bridge : public MemObject
Bridge *bridge;
/**
- * Pointer to the master port on the other side of the bridge
+ * Master port on the other side of the bridge
* (connected to the other bus).
*/
- BridgeMasterPort* masterPort;
+ BridgeMasterPort& masterPort;
/** Minimum request delay though this bridge. */
Tick delay;
@@ -189,11 +189,11 @@ class Bridge : public MemObject
*/
class SendEvent : public Event
{
- BridgeSlavePort *port;
+ BridgeSlavePort& port;
public:
- SendEvent(BridgeSlavePort *p) : port(p) {}
- virtual void process() { port->trySend(); }
+ SendEvent(BridgeSlavePort& p) : port(p) {}
+ virtual void process() { port.trySend(); }
virtual const char *description() const { return "bridge send"; }
};
@@ -214,7 +214,7 @@ class Bridge : public MemObject
* @param _ranges a number of address ranges to forward
*/
BridgeSlavePort(const std::string &_name, Bridge *_bridge,
- BridgeMasterPort* _masterPort, int _delay,
+ BridgeMasterPort& _masterPort, int _delay,
int _nack_delay, int _resp_limit,
std::vector<Range<Addr> > _ranges);
@@ -272,7 +272,7 @@ class Bridge : public MemObject
* Pointer to the slave port on the other side of the bridge
* (connected to the other bus).
*/
- BridgeSlavePort* slavePort;
+ BridgeSlavePort& slavePort;
/** Minimum delay though this bridge. */
Tick delay;
@@ -303,11 +303,11 @@ class Bridge : public MemObject
*/
class SendEvent : public Event
{
- BridgeMasterPort *port;
+ BridgeMasterPort& port;
public:
- SendEvent(BridgeMasterPort *p) : port(p) {}
- virtual void process() { port->trySend(); }
+ SendEvent(BridgeMasterPort& p) : port(p) {}
+ virtual void process() { port.trySend(); }
virtual const char *description() const { return "bridge send"; }
};
@@ -326,7 +326,7 @@ class Bridge : public MemObject
* @param _req_limit the size of the request queue
*/
BridgeMasterPort(const std::string &_name, Bridge *_bridge,
- BridgeSlavePort* _slavePort, int _delay,
+ BridgeSlavePort& _slavePort, int _delay,
int _req_limit);
/**
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index e37449b6e..827adc78e 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -57,6 +57,7 @@ Bus::Bus(const BusParams *p)
: MemObject(p), busId(p->bus_id), clock(p->clock),
headerCycles(p->header_cycles), width(p->width), tickNextIdle(0),
drainEvent(NULL), busIdle(this), inRetry(false),
+ nbrMasterPorts(p->port_master_connection_count),
defaultPortId(INVALID_PORT_ID), useDefaultRange(p->use_default_range),
defaultBlockSize(p->block_size),
cachedBlockSize(0), cachedBlockSizeValid(false)
@@ -68,27 +69,55 @@ Bus::Bus(const BusParams *p)
fatal("Bus clock period must be positive\n");
if (headerCycles <= 0)
fatal("Number of header cycles must be positive\n");
+
+ // create the ports based on the size of the master and slave
+ // vector ports, and the presence of the default master
+
+ // id used to index into interfaces which is a flat vector of all
+ // ports
+ int id = 0;
+ for (int i = 0; i < p->port_master_connection_count; ++i) {
+ std::string portName = csprintf("%s-p%d", name(), id);
+ interfaces.push_back(new BusPort(portName, this, id));
+ ++id;
+ }
+
+ // note that the first slave port is now stored on index
+ // nbrMasterPorts in the vector
+ for (int i = 0; i < p->port_slave_connection_count; ++i) {
+ std::string portName = csprintf("%s-p%d", name(), id);
+ interfaces.push_back(new BusPort(portName, this, id));
+ ++id;
+ }
+
+ // see if we have a default master connected and if so add the
+ // port at the end
+ if (p->port_default_connection_count) {
+ defaultPortId = id;
+ std::string portName = csprintf("%s-default", name());
+ interfaces.push_back(new BusPort(portName, this, id));
+ ++id;
+ }
+
clearPortCache();
}
Port *
Bus::getPort(const std::string &if_name, int idx)
{
- std::string portName;
- int id = interfaces.size();
- if (if_name == "default") {
- if (defaultPortId == INVALID_PORT_ID) {
- defaultPortId = id;
- portName = csprintf("%s-default", name());
- } else
- fatal("Default port already set on %s\n", name());
+ if (if_name == "master") {
+ // the master index translates directly to the interfaces
+ // vector as they are stored first
+ return interfaces[idx];
+ } else if (if_name == "slave") {
+ // the slaves are stored after the masters and we must thus
+ // offset the slave index with the number of master ports
+ return interfaces[nbrMasterPorts + idx];
+ } else if (if_name == "default") {
+ return interfaces[defaultPortId];
} else {
- portName = csprintf("%s-p%d", name(), id);
+ panic("No port %s %d on bus %s\n", if_name, idx, name());
}
- BusPort *bp = new BusPort(portName, this, id);
- interfaces.push_back(bp);
- cachedBlockSizeValid = false;
- return bp;
}
void
diff --git a/src/mem/bus.hh b/src/mem/bus.hh
index f7f69e08e..7fdf5db26 100644
--- a/src/mem/bus.hh
+++ b/src/mem/bus.hh
@@ -287,6 +287,11 @@ class Bus : public MemObject
bool inRetry;
std::set<int> inRecvRangeChange;
+ // keep track of the number of master ports (not counting the
+ // default master) since we need this as an offset into the
+ // interfaces vector
+ unsigned int nbrMasterPorts;
+
/** An ordered vector of pointers to the peer port interfaces
connected to this bus.*/
std::vector<BusPort*> interfaces;
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index 09ed8b292..999ad0cdb 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -76,6 +76,12 @@ PhysicalMemory::PhysicalMemory(const Params *p)
if (size() % TheISA::PageBytes != 0)
panic("Memory Size not divisible by page size\n");
+ // create the appropriate number of ports
+ for (int i = 0; i < p->port_port_connection_count; ++i) {
+ ports.push_back(new MemoryPort(csprintf("%s-port%d", name(), i),
+ this));
+ }
+
if (params()->null)
return;
@@ -109,13 +115,12 @@ PhysicalMemory::PhysicalMemory(const Params *p)
void
PhysicalMemory::init()
{
- if (ports.size() == 0) {
+ if (ports.empty()) {
fatal("PhysicalMemory object %s is unconnected!", name());
}
for (PortIterator pi = ports.begin(); pi != ports.end(); ++pi) {
- if (*pi)
- (*pi)->sendRangeChange();
+ (*pi)->sendRangeChange();
}
}
@@ -438,22 +443,14 @@ Port *
PhysicalMemory::getPort(const std::string &if_name, int idx)
{
if (if_name != "port") {
- panic("PhysicalMemory::getPort: unknown port %s requested", if_name);
+ panic("PhysicalMemory::getPort: unknown port %s requested\n", if_name);
}
- if (idx >= (int)ports.size()) {
- ports.resize(idx + 1);
+ if (idx >= static_cast<int>(ports.size())) {
+ panic("PhysicalMemory::getPort: unknown index %d requested\n", idx);
}
- 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;
+ return ports[idx];
}
PhysicalMemory::MemoryPort::MemoryPort(const std::string &_name,
diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc
index 2ef65a13a..c55b4a2c2 100644
--- a/src/mem/ruby/system/RubyPort.cc
+++ b/src/mem/ruby/system/RubyPort.cc
@@ -35,7 +35,8 @@
#include "mem/ruby/system/RubyPort.hh"
RubyPort::RubyPort(const Params *p)
- : MemObject(p)
+ : MemObject(p), pio_port(csprintf("%s-pio-port", name()), this),
+ physMemPort(csprintf("%s-physMemPort", name()), this)
{
m_version = p->version;
assert(m_version != -1);
@@ -46,8 +47,6 @@ RubyPort::RubyPort(const Params *p)
m_mandatory_q_ptr = NULL;
m_request_cnt = 0;
- pio_port = NULL;
- physMemPort = NULL;
m_usingRubyTester = p->using_ruby_tester;
access_phys_mem = p->access_phys_mem;
@@ -87,21 +86,11 @@ RubyPort::getPort(const std::string &if_name, int idx)
}
if (if_name == "pio_port") {
- // ensure there is only one pio port
- assert(pio_port == NULL);
-
- pio_port = new PioPort(csprintf("%s-pio-port%d", name(), idx), this);
-
- return pio_port;
+ return &pio_port;
}
if (if_name == "physMemPort") {
- // RubyPort should only have one port to physical memory
- assert (physMemPort == NULL);
-
- physMemPort = new PioPort(csprintf("%s-physMemPort", name()), this);
-
- return physMemPort;
+ return &physMemPort;
}
return NULL;
@@ -194,12 +183,12 @@ RubyPort::M5Port::recvTiming(PacketPtr pkt)
// Check for pio requests and directly send them to the dedicated
// pio port.
if (!isPhysMemAddress(pkt->getAddr())) {
- assert(ruby_port->pio_port != NULL);
+ assert(ruby_port->pio_port.isConnected());
DPRINTF(RubyPort,
"Request for address 0x%#x is assumed to be a pio request\n",
pkt->getAddr());
- return ruby_port->pio_port->sendTiming(pkt);
+ return ruby_port->pio_port.sendTiming(pkt);
}
assert(Address(pkt->getAddr()).getOffset() + pkt->getSize() <=
@@ -426,7 +415,7 @@ RubyPort::M5Port::recvFunctional(PacketPtr pkt)
// Check for pio requests and directly send them to the dedicated
// pio port.
if (!isPhysMemAddress(pkt->getAddr())) {
- assert(ruby_port->pio_port != NULL);
+ assert(ruby_port->pio_port.isConnected());
DPRINTF(RubyPort, "Request for address 0x%#x is a pio request\n",
pkt->getAddr());
panic("RubyPort::PioPort::recvFunctional() not implemented!\n");
@@ -461,7 +450,7 @@ RubyPort::M5Port::recvFunctional(PacketPtr pkt)
// The following command performs the real functional access.
// This line should be removed once Ruby supplies the official version
// of data.
- ruby_port->physMemPort->sendFunctional(pkt);
+ ruby_port->physMemPort.sendFunctional(pkt);
}
// turn packet around to go back to requester if response expected
@@ -554,12 +543,12 @@ RubyPort::getDrainCount(Event *de)
// event should have been descheduled.
assert(isDeadlockEventScheduled() == false);
- if (pio_port != NULL) {
- count += pio_port->drain(de);
+ if (pio_port.isConnected()) {
+ count += pio_port.drain(de);
DPRINTF(Config, "count after pio check %d\n", count);
}
- if (physMemPort != NULL) {
- count += physMemPort->drain(de);
+ if (physMemPort.isConnected()) {
+ count += physMemPort.drain(de);
DPRINTF(Config, "count after physmem check %d\n", count);
}
@@ -640,7 +629,7 @@ RubyPort::M5Port::hitCallback(PacketPtr pkt)
DPRINTF(RubyPort, "Hit callback needs response %d\n", needsResponse);
if (accessPhysMem) {
- ruby_port->physMemPort->sendAtomic(pkt);
+ ruby_port->physMemPort.sendAtomic(pkt);
} else if (needsResponse) {
pkt->makeResponse();
}
@@ -675,7 +664,7 @@ bool
RubyPort::M5Port::isPhysMemAddress(Addr addr)
{
AddrRangeList physMemAddrList =
- ruby_port->physMemPort->getPeer()->getAddrRanges();
+ ruby_port->physMemPort.getPeer()->getAddrRanges();
for (AddrRangeIter iter = physMemAddrList.begin();
iter != physMemAddrList.end();
iter++) {
diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh
index 6df713a13..0d84ec216 100644
--- a/src/mem/ruby/system/RubyPort.hh
+++ b/src/mem/ruby/system/RubyPort.hh
@@ -137,7 +137,7 @@ class RubyPort : public MemObject
int m_version;
AbstractController* m_controller;
MessageBuffer* m_mandatory_q_ptr;
- PioPort* pio_port;
+ PioPort pio_port;
bool m_usingRubyTester;
private:
@@ -155,7 +155,7 @@ class RubyPort : public MemObject
uint16_t m_port_id;
uint64_t m_request_cnt;
- PioPort* physMemPort;
+ PioPort physMemPort;
/*! Vector of CPU Port attached to this Ruby port. */
typedef std::vector<M5Port*>::iterator CpuPortIter;