}
-void
-X86ISA::Interrupts::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+X86ISA::Interrupts::getAddrRanges()
{
- range_list.clear();
+ AddrRangeList ranges;
Range<Addr> range = RangeEx(x86LocalAPICAddress(initialApicId, 0),
x86LocalAPICAddress(initialApicId, 0) +
PageBytes);
- range_list.push_back(range);
+ ranges.push_back(range);
pioAddr = range.start;
+ return ranges;
}
-void
-X86ISA::Interrupts::getIntAddrRange(AddrRangeList &range_list)
+AddrRangeList
+X86ISA::Interrupts::getIntAddrRange()
{
- range_list.clear();
- range_list.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
- x86InterruptAddress(initialApicId, 0) +
- PhysAddrAPICRangeSize));
+ AddrRangeList ranges;
+ ranges.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
+ x86InterruptAddress(initialApicId, 0) +
+ PhysAddrAPICRangeSize));
+ return ranges;
}
return entry.periodic;
}
- void addressRanges(AddrRangeList &range_list);
- void getIntAddrRange(AddrRangeList &range_list);
+ AddrRangeList getAddrRanges();
+ AddrRangeList getIntAddrRange();
Port *getPort(const std::string &if_name, int idx = -1)
{
}
void
-Walker::WalkerPort::recvStatusChange(Status status)
+Walker::WalkerPort::recvRangeChange()
{
- if (status == RangeChange) {
- if (!snoopRangeSent) {
- snoopRangeSent = true;
- sendStatusChange(Port::RangeChange);
- }
- return;
- }
-
- panic("Unexpected recvStatusChange.\n");
}
void
{
public:
WalkerPort(const std::string &_name, Walker * _walker) :
- Port(_name, _walker), walker(_walker),
- snoopRangeSent(false)
+ Port(_name, _walker), walker(_walker)
{}
protected:
Walker * walker;
- bool snoopRangeSent;
-
bool recvTiming(PacketPtr pkt);
Tick recvAtomic(PacketPtr pkt);
void recvFunctional(PacketPtr pkt);
- void recvStatusChange(Status status);
+ void recvRangeChange();
void recvRetry();
- void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- {
- resp.clear();
- snoop = true;
- }
+ bool isSnooping() { return true; }
};
friend class WalkerPort;
}
void
-BaseCPU::CpuPort::recvStatusChange(Status status)
+BaseCPU::CpuPort::recvRangeChange()
{
- if (status == RangeChange) {
- if (!snoopRangeSent) {
- snoopRangeSent = true;
- sendStatusChange(Port::RangeChange);
- }
- return;
- }
-
- panic("BaseCPU doesn't expect recvStatusChange callback!");
-}
-
-void
-BaseCPU::CpuPort::getDeviceAddressRanges(AddrRangeList& resp,
- bool& snoop)
-{
- resp.clear();
- snoop = false;
}
* @param _name structural owner of this port
*/
CpuPort(const std::string& _name, MemObject* _owner) :
- Port(_name, _owner), snoopRangeSent(false)
+ Port(_name, _owner)
{ }
protected:
void recvFunctional(PacketPtr pkt);
- void recvStatusChange(Status status);
-
- /**
- * Add CPU ports are master ports and do not respond to any
- * address ranges. Note that the LSQ snoops for specific ISAs
- * and thus has to override this method.
- *
- * @param resp list of ranges this port responds to
- * @param snoop indicating if the port snoops or not
- */
- virtual void getDeviceAddressRanges(AddrRangeList& resp,
- bool& snoop);
-
- private:
-
- bool snoopRangeSent;
+ void recvRangeChange();
};
}
void
-CacheUnit::CachePort::recvStatusChange(Status status)
+CacheUnit::CachePort::recvRangeChange()
{
- if (status == RangeChange) {
- if (!snoopRangeSent) {
- snoopRangeSent = true;
- sendStatusChange(Port::RangeChange);
- }
- return;
- }
-
- panic("CacheUnit::CachePort doesn't expect recvStatusChange callback!");
}
bool
CachePort(CacheUnit *_cachePortUnit)
: Port(_cachePortUnit->name() + "-cache-port",
(MemObject*)_cachePortUnit->cpu),
- cachePortUnit(_cachePortUnit), snoopRangeSent(false)
+ cachePortUnit(_cachePortUnit)
{ }
- bool snoopRangeSent;
-
protected:
/** Atomic version of receive. Panics. */
Tick recvAtomic(PacketPtr pkt);
/** Functional version of receive.*/
void recvFunctional(PacketPtr pkt);
- /** Receives status change. Other than range changing, panics. */
- void recvStatusChange(Status status);
-
- /** Returns the address ranges of this device. */
- void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = true; }
+ /** Receives range changes. */
+ void recvRangeChange();
/** Timing version of receive */
bool recvTiming(PacketPtr pkt);
* As this CPU requires snooping to maintain the load store queue
* change the behaviour from the base CPU port.
*
- * @param resp list of ranges this port responds to
- * @param snoop indicating if the port snoops or not
+ * @return true since we have to snoop
*/
- virtual void getDeviceAddressRanges(AddrRangeList& resp,
- bool& snoop)
- { resp.clear(); snoop = true; }
+ virtual bool isSnooping()
+ { return true; }
};
class TickEvent : public Event
/** Functional version of receive. Panics. */
virtual void recvFunctional(PacketPtr pkt);
- /** Receives status change. Other than range changing, panics. */
- virtual void recvStatusChange(Status status);
-
- /** Returns the address ranges of this device. */
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = true; }
+ /** Receives range change. */
+ virtual void recvRangeChange();
/** Timing version of receive. Handles setting fetch to the
* proper status to start fetching. */
template<class Impl>
void
-FrontEnd<Impl>::IcachePort::recvStatusChange(Status status)
+FrontEnd<Impl>::IcachePort::recvRangeChange()
{
- if (status == RangeChange)
- return;
-
- panic("FrontEnd doesn't expect recvStatusChange callback!");
}
template<class Impl>
virtual void recvFunctional(PacketPtr pkt);
- virtual void recvStatusChange(Status status);
+ virtual void recvRangeChange();
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = true; }
+ /**
+ * Is a snooper due to LSQ maintenance
+ */
+ virtual bool isSnooping()
+ { return true; }
virtual bool recvTiming(PacketPtr pkt);
template <class Impl>
void
-OzoneLWLSQ<Impl>::DcachePort::recvStatusChange(Status status)
+OzoneLWLSQ<Impl>::DcachePort::recvRangeChange()
{
- if (status == RangeChange)
- return;
-
- panic("O3CPU doesn't expect recvStatusChange callback!");
}
template <class Impl>
tcBase()->initMemProxies(tcBase());
#endif
if (hasPhysMemPort) {
- bool snoop = false;
- AddrRangeList pmAddrList;
- physmemPort.getPeerAddressRanges(pmAddrList, snoop);
+ AddrRangeList pmAddrList = physmemPort.getPeer()->getAddrRanges();
physMemAddr = *pmAddrList.begin();
}
// Atomic doesn't do MT right now, so contextId == threadId
}
void
-MemTest::CpuPort::recvStatusChange(Status status)
+MemTest::CpuPort::recvRangeChange()
{
- if (status == RangeChange) {
- if (!snoopRangeSent) {
- snoopRangeSent = true;
- sendStatusChange(Port::RangeChange);
- }
- return;
- }
-
- panic("MemTest doesn't expect recvStatusChange callback!");
}
void
atomic(p->atomic),
suppress_func_warnings(p->suppress_func_warnings)
{
- cachePort.snoopRangeSent = false;
- funcPort.snoopRangeSent = true;
-
id = TESTER_ALLOCATOR++;
// Needs to be masked off once we know the block size.
: Port(_name, _memtest), memtest(_memtest)
{ }
- bool snoopRangeSent;
-
protected:
virtual bool recvTiming(PacketPtr pkt);
virtual void recvFunctional(PacketPtr pkt);
- virtual void recvStatusChange(Status status);
+ virtual void recvRangeChange();
virtual void recvRetry();
-
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = false; }
};
CpuPort cachePort;
CpuPort funcPort;
- bool snoopRangeSent;
-
class MemTestSenderState : public Packet::SenderState, public FastAlloc
{
public:
}
void
-NetworkTest::CpuPort::recvStatusChange(Status status)
+NetworkTest::CpuPort::recvRangeChange()
{
- if (status == RangeChange) {
- if (!snoopRangeSent) {
- snoopRangeSent = true;
- sendStatusChange(Port::RangeChange);
- }
- return;
- }
-
- panic("NetworkTest doesn't expect recvStatusChange callback!");
}
void
injRate(p->inj_rate),
precision(p->precision)
{
- cachePort.snoopRangeSent = false;
-
// set up counters
noResponseCycles = 0;
schedule(tickEvent, 0);
: Port(_name, _networktest), networktest(_networktest)
{ }
- bool snoopRangeSent;
-
protected:
virtual bool recvTiming(PacketPtr pkt);
virtual void recvFunctional(PacketPtr pkt);
- virtual void recvStatusChange(Status status);
+ virtual void recvRangeChange();
virtual void recvRetry();
-
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = false; }
};
CpuPort cachePort;
- bool snoopRangeSent;
-
class NetworkTestSenderState : public Packet::SenderState, public FastAlloc
{
public:
eventq->schedule(postIntEvent[cpu], when);
}
-void
-Gic::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+Gic::getAddrRanges()
{
- range_list.clear();
- range_list.push_back(RangeSize(distAddr, DIST_SIZE));
- range_list.push_back(RangeSize(cpuAddr, CPU_SIZE));
+ AddrRangeList ranges;
+ ranges.push_back(RangeSize(distAddr, DIST_SIZE));
+ ranges.push_back(RangeSize(cpuAddr, CPU_SIZE));
+ return ranges;
}
/** Return the address ranges used by the Gic
* This is the distributor address + all cpu addresses
*/
- virtual void addressRanges(AddrRangeList &range_list);
+ virtual AddrRangeList getAddrRanges();
/** A PIO read to the device, immediately split up into
* readDistributor() or readCpu()
}
}
-void
-Pl111::addressRanges(AddrRangeList& range_list)
+AddrRangeList
+Pl111::getAddrRanges()
{
- range_list.clear();
- range_list.push_back(RangeSize(pioAddr, pioSize));
+ AddrRangeList ranges;
+ ranges.push_back(RangeSize(pioAddr, pioSize));
+ return ranges;
}
Pl111 *
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string §ion);
- /** return the address ranges that this device responds to.
- * @param range_list range list to populate with ranges
+ /**
+ * Determine the address ranges that this device responds to.
+ *
+ * @return a list of non-overlapping address ranges
*/
- void addressRanges(AddrRangeList &range_list);
+ AddrRangeList getAddrRanges();
};
#endif
void init();
std::string name() { assert(ce); return ce->name() + csprintf("-chan%d", channelId); }
- virtual void addressRanges(AddrRangeList &range_list) { range_list.clear(); }
virtual Tick read(PacketPtr pkt)
{ panic("CopyEngineChannel has no I/O access\n");}
virtual Tick write(PacketPtr pkt)
return pkt->isRead() ? device->read(pkt) : device->write(pkt);
}
-void
-PioPort::getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
+AddrRangeList
+PioPort::getAddrRanges()
{
- snoop = false;
- device->addressRanges(resp);
- for (AddrRangeIter i = resp.begin(); i != resp.end(); i++)
- DPRINTF(BusAddrRanges, "Adding Range %#x-%#x\n", i->start, i->end);
+ return device->getAddrRanges();
}
{
if (!pioPort)
panic("Pio port of %s not connected to anything!", name());
- pioPort->sendStatusChange(Port::RangeChange);
+ pioPort->sendRangeChange();
}
Port *
pioDelay(p->pio_latency)
{}
-void
-BasicPioDevice::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+BasicPioDevice::getAddrRanges()
{
assert(pioSize != 0);
- range_list.clear();
+ AddrRangeList ranges;
DPRINTF(BusAddrRanges, "registering range: %#x-%#x\n", pioAddr, pioSize);
- range_list.push_back(RangeSize(pioAddr, pioSize));
+ ranges.push_back(RangeSize(pioAddr, pioSize));
+ return ranges;
}
pendingCount(0), actionInProgress(0), drainEvent(NULL),
backoffTime(0), minBackoffDelay(min_backoff),
maxBackoffDelay(max_backoff), inRetry(false), recvSnoops(recv_snoops),
- snoopRangeSent(false), backoffEvent(this)
+ backoffEvent(this)
{ }
bool
* The PioPort class is a programmed i/o port that all devices that are
* sensitive to an address range use. The port takes all the memory
* access types and roles them into one read() and write() call that the device
- * must respond to. The device must also provide the addressRanges() function
+ * must respond to. The device must also provide getAddrRanges() function
* with which it returns the address ranges it is interested in.
*/
class PioPort : public SimpleTimingPort
virtual Tick recvAtomic(PacketPtr pkt);
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop);
+ virtual AddrRangeList getAddrRanges();
public:
/** Port accesses a cache which requires snooping */
bool recvSnoops;
- /** Records snoop response so we only reply once to a status change */
- bool snoopRangeSent;
-
virtual bool recvTiming(PacketPtr pkt);
virtual Tick recvAtomic(PacketPtr pkt)
{
panic("dma port shouldn't be used for pio access.");
}
- virtual void recvStatusChange(Status status)
+ virtual void recvRangeChange()
{
- if (recvSnoops) {
- if (status == RangeChange) {
- if (!snoopRangeSent) {
- snoopRangeSent = true;
- sendStatusChange(Port::RangeChange);
- }
- return;
- }
- panic("Unexpected recvStatusChange\n");
- }
+ // DMA port is a master with a single slave so there is no choice and
+ // thus no need to worry about any address changes
}
virtual void recvRetry() ;
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = recvSnoops; }
+ virtual bool isSnooping()
+ { return recvSnoops; }
void queueDma(PacketPtr pkt, bool front = false);
void sendDma();
/**
* This device is the base class which all devices senstive to an address range
* inherit from. There are three pure virtual functions which all devices must
- * implement addressRanges(), read(), and write(). The magic do choose which
+ * implement getAddrRanges(), read(), and write(). The magic do choose which
* mode we are in, etc is handled by the PioPort so the device doesn't have to
* bother.
*/
* that it sees. */
PioPort *pioPort;
- virtual void addressRanges(AddrRangeList &range_list) = 0;
+ /**
+ * Every PIO device is obliged to provide an implementation that
+ * returns the address ranges the device responds to.
+ *
+ * @return a list of non-overlapping address ranges
+ */
+ virtual AddrRangeList getAddrRanges() = 0;
/** Pure virtual function that the device must implement. Called
* when a read command is recieved by the port.
return dynamic_cast<const Params *>(_params);
}
- /** return the address ranges that this device responds to.
- * @param range_list range list to populate with ranges
+ /**
+ * Determine the address ranges that this device responds to.
+ *
+ * @return a list of non-overlapping address ranges
*/
- void addressRanges(AddrRangeList &range_list);
+ virtual AddrRangeList getAddrRanges();
};
}
-void
-PciConfigAll::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+PciConfigAll::getAddrRanges()
{
- range_list.clear();
- range_list.push_back(RangeSize(pioAddr, params()->size));
+ AddrRangeList ranges;
+ ranges.push_back(RangeSize(pioAddr, params()->size));
+ return ranges;
}
virtual Tick write(PacketPtr pkt);
- void addressRanges(AddrRangeList &range_list);
+ AddrRangeList getAddrRanges();
private:
Addr pioAddr;
return pkt->isRead() ? device->readConfig(pkt) : device->writeConfig(pkt);
}
-void
-PciDev::PciConfigPort::getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
+AddrRangeList
+PciDev::PciConfigPort::getAddrRanges()
{
- snoop = false;;
+ AddrRangeList ranges;
if (configAddr != ULL(-1))
- resp.push_back(RangeSize(configAddr, PCI_CONFIG_SIZE+1));
+ ranges.push_back(RangeSize(configAddr, PCI_CONFIG_SIZE+1));
+ return ranges;
}
{
if (!configPort)
panic("pci config port not connected to anything!");
- configPort->sendStatusChange(Port::RangeChange);
+ configPort->sendRangeChange();
PioDevice::init();
}
}
-void
-PciDev::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+PciDev::getAddrRanges()
{
+ AddrRangeList ranges;
int x = 0;
- range_list.clear();
for (x = 0; x < 6; x++)
if (BARAddrs[x] != 0)
- range_list.push_back(RangeSize(BARAddrs[x],BARSize[x]));
+ ranges.push_back(RangeSize(BARAddrs[x],BARSize[x]));
+ return ranges;
}
Tick
BARAddrs[barnum] = BAR_IO_SPACE(he_old_bar) ?
platform->calcPciIOAddr(he_new_bar) :
platform->calcPciMemAddr(he_new_bar);
- pioPort->sendStatusChange(Port::RangeChange);
+ pioPort->sendRangeChange();
}
}
config.baseAddr[barnum] = htole((he_new_bar & ~bar_mask) |
UNSERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0]));
UNSERIALIZE_ARRAY(config.data,
sizeof(config.data) / sizeof(config.data[0]));
- pioPort->sendStatusChange(Port::RangeChange);
+ pioPort->sendRangeChange();
}
virtual Tick recvAtomic(PacketPtr pkt);
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop);
+ virtual AddrRangeList getAddrRanges();
Platform *platform;
interruptLine()
{ return letoh(config.interruptLine); }
- /** return the address ranges that this device responds to.
- * @params range_list range list to populate with ranges
+ /**
+ * Determine the address ranges that this device responds to.
+ *
+ * @return a list of non-overlapping address ranges
*/
- void addressRanges(AddrRangeList &range_list);
+ AddrRangeList getAddrRanges();
/**
* Constructor for PCI Dev. This function copies data from the
if (transmitTick)
schedule(txEvent, curTick() + transmitTick);
- pioPort->sendStatusChange(Port::RangeChange);
+ pioPort->sendRangeChange();
}
return true;
}
-void
-Iob::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+Iob::getAddrRanges()
{
- range_list.clear();
- range_list.push_back(RangeSize(iobManAddr, iobManSize));
- range_list.push_back(RangeSize(iobJBusAddr, iobJBusSize));
+ AddrRangeList ranges;
+ ranges.push_back(RangeSize(iobManAddr, iobManSize));
+ ranges.push_back(RangeSize(iobJBusAddr, iobJBusSize));
+ return ranges;
}
bool receiveJBusInterrupt(int cpu_id, int source, uint64_t d0,
uint64_t d1);
- void addressRanges(AddrRangeList &range_list);
+ AddrRangeList getAddrRanges();
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string §ion);
}
-void
-Uart8250::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+Uart8250::getAddrRanges()
{
- assert(pioSize != 0);
- range_list.clear();
- range_list.push_back(RangeSize(pioAddr, pioSize));
+ AddrRangeList ranges;
+ ranges.push_back(RangeSize(pioAddr, pioSize));
+ return ranges;
}
-
-
void
Uart8250::serialize(ostream &os)
{
virtual Tick read(PacketPtr pkt);
virtual Tick write(PacketPtr pkt);
- virtual void addressRanges(AddrRangeList &range_list);
+ virtual AddrRangeList getAddrRanges();
/**
* Inform the uart that there is data available.
const uint8_t CommandNack = 0xfe;
const uint8_t BatSuccessful = 0xaa;
-void
-X86ISA::I8042::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+X86ISA::I8042::getAddrRanges()
{
- range_list.clear();
- range_list.push_back(RangeSize(dataPort, 1));
- range_list.push_back(RangeSize(commandPort, 1));
+ AddrRangeList ranges;
+ ranges.push_back(RangeSize(dataPort, 1));
+ ranges.push_back(RangeSize(commandPort, 1));
+ return ranges;
}
void
commandByte.keyboardFullInt = 1;
}
- void addressRanges(AddrRangeList &range_list);
+ AddrRangeList getAddrRanges();
Tick read(PacketPtr pkt);
Tick read(PacketPtr pkt);
Tick write(PacketPtr pkt);
- void addressRanges(AddrRangeList &range_list)
+ AddrRangeList getAddrRanges()
{
- range_list.clear();
- range_list.push_back(RangeEx(pioAddr, pioAddr + 4));
- range_list.push_back(RangeEx(pioAddr + 16, pioAddr + 20));
+ AddrRangeList ranges;
+ ranges.push_back(RangeEx(pioAddr, pioAddr + 4));
+ ranges.push_back(RangeEx(pioAddr + 16, pioAddr + 20));
+ return ranges;
}
- void getIntAddrRange(AddrRangeList &range_list)
+ AddrRangeList getIntAddrRange()
{
- range_list.clear();
- range_list.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
- x86InterruptAddress(initialApicId, 0) +
- PhysAddrAPICRangeSize));
+ AddrRangeList ranges;
+ ranges.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
+ x86InterruptAddress(initialApicId, 0) +
+ PhysAddrAPICRangeSize));
+ return ranges;
}
void writeReg(uint8_t offset, uint32_t value);
if (!intPort) {
panic("Int port not connected to anything!");
}
- intPort->sendStatusChange(Port::RangeChange);
+ intPort->sendRangeChange();
}
X86ISA::IntSourcePin *
{
}
- void getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
+ AddrRangeList getAddrRanges()
{
- snoop = false;
- device->getIntAddrRange(resp);
+ return device->getIntAddrRange();
}
Tick recvMessage(PacketPtr pkt)
return 0;
}
- virtual void
- getIntAddrRange(AddrRangeList &range_list)
+ virtual AddrRangeList
+ getIntAddrRange()
{
panic("intAddrRange not implemented.\n");
}
uint64_t a0 = tc->readIntReg(16);
- AddrRangeList resp;
- bool snoop;
AddrRangeIter iter;
bool found = false;
Port* dataPort = tc->getCpuPtr()->getPort("dcache_port");
- dataPort->getPeerAddressRanges(resp, snoop);
+ AddrRangeList resp = dataPort->getPeer()->getAddrRanges();
for (iter = resp.begin(); iter != resp.end(); iter++) {
if (*iter == (K0Seg2Phys(a0) & PAddrImplMask))
found = true;
otherPort->sendFunctional(pkt);
}
-/** Function called by the port when the bus is receiving a status change.*/
+/** Function called by the port when the bridge is receiving a range change.*/
void
-Bridge::BridgePort::recvStatusChange(Port::Status status)
+Bridge::BridgePort::recvRangeChange()
{
- otherPort->sendStatusChange(status);
+ otherPort->sendRangeChange();
}
-void
-Bridge::BridgePort::getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
+AddrRangeList
+Bridge::BridgePort::getAddrRanges()
{
- otherPort->getPeerAddressRanges(resp, snoop);
- FilterRangeList(filterRanges, resp);
- // we don't allow snooping across bridges
- snoop = false;
+ AddrRangeList ranges = otherPort->getPeer()->getAddrRanges();
+ FilterRangeList(filterRanges, ranges);
+ return ranges;
}
Bridge *
pass it to the bridge. */
virtual void recvFunctional(PacketPtr pkt);
- /** When receiving a status changefrom the peer port,
- pass it to the bridge. */
- virtual void recvStatusChange(Status status);
+ /**
+ * When receiving a range change, pass it through the bridge.
+ */
+ virtual void recvRangeChange();
/** When receiving a address range request the peer port,
pass it to the bridge. */
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop);
+ virtual AddrRangeList getAddrRanges();
};
BridgePort portA, portB;
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
return bp;
}
-/** Get the ranges of anyone other buses that we are connected to. */
void
Bus::init()
{
m5::hash_map<short,BusPort*>::iterator intIter;
- for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
- intIter->second->sendStatusChange(Port::RangeChange);
+ // iterate over our interfaces and determine which of our neighbours
+ // are snooping and add them as snoopers
+ for (intIter = interfaces.begin(); intIter != interfaces.end();
+ intIter++) {
+ if (intIter->second->getPeer()->isSnooping()) {
+ DPRINTF(BusAddrRanges, "Adding snooping neighbour %s\n",
+ intIter->second->getPeer()->name());
+ snoopPorts.push_back(intIter->second);
+ }
+ }
}
Bus::BusFreeEvent::BusFreeEvent(Bus *_bus)
}
}
-/** Function called by the port when the bus is receiving a status change.*/
+/** Function called by the port when the bus is receiving a range change.*/
void
-Bus::recvStatusChange(Port::Status status, int id)
+Bus::recvRangeChange(int id)
{
AddrRangeList ranges;
- bool snoops;
AddrRangeIter iter;
- if (inRecvStatusChange.count(id))
+ if (inRecvRangeChange.count(id))
return;
- inRecvStatusChange.insert(id);
-
- assert(status == Port::RangeChange &&
- "The other statuses need to be implemented.");
+ inRecvRangeChange.insert(id);
DPRINTF(BusAddrRanges, "received RangeChange from device id %d\n", id);
defaultRange.clear();
// Only try to update these ranges if the user set a default responder.
if (useDefaultRange) {
- defaultPort->getPeerAddressRanges(ranges, snoops);
- assert(snoops == false);
+ AddrRangeList ranges = defaultPort->getPeer()->getAddrRanges();
for(iter = ranges.begin(); iter != ranges.end(); iter++) {
defaultRange.push_back(*iter);
DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default range\n",
portIter++;
}
- for (SnoopIter s_iter = snoopPorts.begin();
- s_iter != snoopPorts.end(); ) {
- if ((*s_iter)->getId() == id)
- s_iter = snoopPorts.erase(s_iter);
- else
- s_iter++;
- }
-
- port->getPeerAddressRanges(ranges, snoops);
-
- if (snoops) {
- DPRINTF(BusAddrRanges, "Adding id %d to snoop list\n", id);
- snoopPorts.push_back(port);
- }
+ ranges = port->getPeer()->getAddrRanges();
for (iter = ranges.begin(); iter != ranges.end(); iter++) {
DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for id %d\n",
for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
if (intIter->first != id && intIter->first != funcPortId)
- intIter->second->sendStatusChange(Port::RangeChange);
+ intIter->second->sendRangeChange();
if (id != defaultId && defaultPort)
- defaultPort->sendStatusChange(Port::RangeChange);
- inRecvStatusChange.erase(id);
+ defaultPort->sendRangeChange();
+ inRecvRangeChange.erase(id);
}
-void
-Bus::addressRanges(AddrRangeList &resp, bool &snoop, int id)
+AddrRangeList
+Bus::getAddrRanges(int id)
{
- resp.clear();
- snoop = false;
+ AddrRangeList ranges;
DPRINTF(BusAddrRanges, "received address range request, returning:\n");
for (AddrRangeIter dflt_iter = defaultRange.begin();
dflt_iter != defaultRange.end(); dflt_iter++) {
- resp.push_back(*dflt_iter);
+ ranges.push_back(*dflt_iter);
DPRINTF(BusAddrRanges, " -- Dflt: %#llx : %#llx\n",dflt_iter->start,
dflt_iter->end);
}
}
}
if (portIter->second != id && !subset) {
- resp.push_back(portIter->first);
+ ranges.push_back(portIter->first);
DPRINTF(BusAddrRanges, " -- %#llx : %#llx\n",
portIter->first.start, portIter->first.end);
}
}
+ return ranges;
+}
+
+bool
+Bus::isSnooping(int id)
+{
+ // in essence, answer the question if there are other snooping
+ // ports rather than the port that is asking
+ bool snoop = false;
for (SnoopIter s_iter = snoopPorts.begin(); s_iter != snoopPorts.end();
s_iter++) {
if ((*s_iter)->getId() != id) {
break;
}
}
+ return snoop;
}
unsigned
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
int getId() { return id; }
+ /**
+ * Determine if this port should be considered a snooper. This
+ * is determined by the bus.
+ *
+ * @return a boolean that is true if this port is snooping
+ */
+ virtual bool isSnooping()
+ { return bus->isSnooping(id); }
+
protected:
/** When reciving a timing request from the peer port (at id),
virtual void recvFunctional(PacketPtr pkt)
{ pkt->setSrc(id); bus->recvFunctional(pkt); }
- /** When reciving a status changefrom the peer port (at id),
+ /** When reciving a range change from the peer port (at id),
pass it to the bus. */
- virtual void recvStatusChange(Status status)
- { bus->recvStatusChange(status, id); }
+ virtual void recvRangeChange()
+ { bus->recvRangeChange(id); }
/** When reciving a retry from the peer port (at id),
pass it to the bus. */
// downstream from this bus, yes? That is, the union of all
// the 'owned' address ranges of all the other interfaces on
// this bus...
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { bus->addressRanges(resp, snoop, id); }
+ virtual AddrRangeList getAddrRanges()
+ { return bus->getAddrRanges(id); }
// Ask the bus to ask everyone on the bus what their block size is and
// take the max of it. This might need to be changed a bit if we ever
* requests. */
void recvRetry(int id);
- /** Function called by the port when the bus is recieving a status change.*/
- void recvStatusChange(Port::Status status, int id);
+ /** Function called by the port when the bus is recieving a range change.*/
+ void recvRangeChange(int id);
/** Find which port connected to this bus (if any) should be given a packet
* with this address.
portCache[0].valid = false;
}
- /** Process address range request.
- * @param resp addresses that we can respond to
- * @param snoop addresses that we would like to snoop
- * @param id ide of the busport that made the request.
+ /**
+ * Return the address ranges this port is responsible for.
+ *
+ * @param id id of the bus port that made the request
+ *
+ * @return a list of non-overlapping address ranges
+ */
+ AddrRangeList getAddrRanges(int id);
+
+ /**
+ * Determine if the bus port is snooping or not.
+ *
+ * @param id id of the bus port that made the request
+ *
+ * @return a boolean indicating if this port is snooping or not
*/
- void addressRanges(AddrRangeList &resp, bool &snoop, int id);
+ bool isSnooping(int id);
/** Calculate the timing parameters for the packet. Updates the
* firstWordTime and finishTime fields of the packet object.
BusFreeEvent busIdle;
bool inRetry;
- std::set<int> inRecvStatusChange;
+ std::set<int> inRecvRangeChange;
/** max number of bus ids we've handed out so far */
short maxId;
}
void
-BaseCache::CachePort::recvStatusChange(Port::Status status)
+BaseCache::CachePort::recvRangeChange() const
{
- if (status == Port::RangeChange) {
- otherPort->sendStatusChange(Port::RangeChange);
- }
+ otherPort->sendRangeChange();
}
{
if (!cpuSidePort || !memSidePort)
panic("Cache not hooked up on both sides\n");
- cpuSidePort->sendStatusChange(Port::RangeChange);
+ cpuSidePort->sendRangeChange();
}
CachePort(const std::string &_name, BaseCache *_cache,
const std::string &_label);
- virtual void recvStatusChange(Status status);
+ virtual void recvRangeChange() const;
virtual unsigned deviceBlockSize() const;
return static_cast<Cache<TagStore> *>(cache);
}
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop);
+ virtual AddrRangeList getAddrRanges();
virtual bool recvTiming(PacketPtr pkt);
void processSendEvent();
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop);
+ virtual bool isSnooping();
virtual bool recvTiming(PacketPtr pkt);
///////////////
template<class TagStore>
-void
+AddrRangeList
Cache<TagStore>::CpuSidePort::
-getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
+getAddrRanges()
{
// CPU side port doesn't snoop; it's a target only. It can
// potentially respond to any address.
- snoop = false;
- resp.push_back(myCache()->getAddrRange());
+ AddrRangeList ranges;
+ ranges.push_back(myCache()->getAddrRange());
+ return ranges;
}
///////////////
template<class TagStore>
-void
-Cache<TagStore>::MemSidePort::
-getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
+bool
+Cache<TagStore>::MemSidePort::isSnooping()
{
// Memory-side port always snoops, but never passes requests
// through to targets on the cpu side (so we don't add anything to
// the address range list).
- snoop = true;
+ return true;
}
for (PortIterator pi = ports.begin(); pi != ports.end(); ++pi) {
if (*pi)
- (*pi)->sendStatusChange(Port::RangeChange);
+ (*pi)->sendRangeChange();
}
}
return port;
}
-
-void
-PhysicalMemory::recvStatusChange(Port::Status status)
-{
-}
-
PhysicalMemory::MemoryPort::MemoryPort(const std::string &_name,
PhysicalMemory *_memory)
: SimpleTimingPort(_name, _memory), memory(_memory)
{ }
void
-PhysicalMemory::MemoryPort::recvStatusChange(Port::Status status)
+PhysicalMemory::MemoryPort::recvRangeChange()
{
- memory->recvStatusChange(status);
+ // memory is a slave and thus should never have to worry about its
+ // neighbours address ranges
}
-void
-PhysicalMemory::MemoryPort::getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
+AddrRangeList
+PhysicalMemory::MemoryPort::getAddrRanges()
{
- memory->getAddressRanges(resp, snoop);
+ return memory->getAddrRanges();
}
-void
-PhysicalMemory::getAddressRanges(AddrRangeList &resp, bool &snoop)
+AddrRangeList
+PhysicalMemory::getAddrRanges()
{
- snoop = false;
- resp.clear();
- resp.push_back(RangeSize(start(), size()));
+ AddrRangeList ranges;
+ ranges.push_back(RangeSize(start(), size()));
+ return ranges;
}
unsigned
virtual void recvFunctional(PacketPtr pkt);
- virtual void recvStatusChange(Status status);
+ virtual void recvRangeChange();
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop);
+ virtual AddrRangeList getAddrRanges();
virtual unsigned deviceBlockSize() const;
};
public:
unsigned deviceBlockSize() const;
- void getAddressRanges(AddrRangeList &resp, bool &snoop);
+ AddrRangeList getAddrRanges();
virtual Port *getPort(const std::string &if_name, int idx = -1);
void virtual init();
unsigned int drain(Event *de);
Tick doAtomicAccess(PacketPtr pkt);
void doFunctionalAccess(PacketPtr pkt);
virtual Tick calculateLatency(PacketPtr pkt);
- void recvStatusChange(Port::Status status);
public:
virtual void serialize(std::ostream &os);
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
#include "mem/packet.hh"
#include "mem/request.hh"
-/** This typedef is used to clean up the parameter list of
- * getDeviceAddressRanges() and getPeerAddressRanges(). It's declared
+/** This typedef is used to clean up getAddrRanges(). It's declared
* outside the Port object since it's also used by some mem objects.
* Eventually we should move this typedef to wherever Addr is
* defined.
virtual ~Port();
- // mey be better to use subclasses & RTTI?
- /** Holds the ports status. Currently just that a range recomputation needs
- * to be done. */
- enum Status {
- RangeChange
- };
-
void setName(const std::string &name)
{ portName = name; }
/** Called to recive a functional call from the peer port. */
virtual void recvFunctional(PacketPtr pkt) = 0;
- /** Called to recieve a status change from the peer port. */
- virtual void recvStatusChange(Status status) = 0;
+ /** Called to recieve an address range change from the peer port. */
+ virtual void recvRangeChange() = 0;
/** Called by a peer port if the send was unsuccesful, and had to
wait. This shouldn't be valid for response paths (IO Devices).
*/
virtual unsigned deviceBlockSize() const { return 0; }
- /** The peer port is requesting us to reply with a list of the ranges we
- are responsible for.
- @param resp is a list of ranges responded to
- @param snoop is a list of ranges snooped
- */
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { panic("??"); }
-
public:
+ /**
+ * Get a list of the non-overlapping address ranges we are
+ * responsible for. The default implementation returns an empty
+ * list and thus no address ranges. Any slave port must override
+ * this function and return a populated list with at least one
+ * item.
+ *
+ * @return a list of ranges responded to
+ */
+ virtual AddrRangeList getAddrRanges()
+ { AddrRangeList ranges; return ranges; }
+
+ /**
+ * Determine if this port is snooping or not. The default
+ * implementation returns false and thus tells the neighbour we
+ * are not snooping. Any port that is to snoop (e.g. a cache
+ * connected to a bus) has to override this function.
+ *
+ * @return true if the port should be considered a snooper
+ */
+ virtual bool isSnooping()
+ { return false; }
+
/** Function called by associated memory device (cache, memory, iodevice)
in order to send a timing request to the port. Simply calls the peer
port receive function.
void sendFunctional(PacketPtr pkt)
{ return peer->recvFunctional(pkt); }
- /** Called by the associated device to send a status change to the device
- connected to the peer interface.
- */
- void sendStatusChange(Status status) {peer->recvStatusChange(status); }
+ /**
+ * Called by the associated device to send a status range to the
+ * peer interface.
+ */
+ void sendRangeChange() const { peer->recvRangeChange(); }
/** When a timing access doesn't return a success, some time later the
Retry will be sent.
*/
unsigned peerBlockSize() const { return peer->deviceBlockSize(); }
- /** Called by the associated device if it wishes to find out the address
- ranges connected to the peer ports devices.
- */
- void getPeerAddressRanges(AddrRangeList &resp, bool &snoop)
- { peer->getDeviceAddressRanges(resp, snoop); }
-
/** This function is a wrapper around sendFunctional()
that breaks a larger, arbitrarily aligned access into
appropriate chunks. The default implementation can use
bool
RubyPort::M5Port::isPhysMemAddress(Addr addr)
{
- AddrRangeList physMemAddrList;
- bool snoop = false;
- ruby_port->physMemPort->getPeerAddressRanges(physMemAddrList, snoop);
+ AddrRangeList physMemAddrList =
+ ruby_port->physMemPort->getPeer()->getAddrRanges();
for (AddrRangeIter iter = physMemAddrList.begin();
iter != physMemAddrList.end();
iter++) {
bool recvTiming(PacketPtr pkt);
/**
- * Simple ports generally don't care about any status
- * changes... can always override this in cases where that's not
- * true. */
- virtual void recvStatusChange(Status status) { }
+ * Simple ports are generally used as slave ports (i.e. the
+ * respond to requests) and thus do not expect to receive any
+ * range changes (as the neighbouring port has a master role and
+ * do not have any address ranges. A subclass can override the
+ * default behaviuor if needed.
+ */
+ virtual void recvRangeChange() { }
public:
{ panic("SystemPort does not receive atomic!\n"); return 0; }
void recvFunctional(PacketPtr pkt)
{ panic("SystemPort does not receive functional!\n"); }
- void recvStatusChange(Status status) { }
+
+ /**
+ * The system port is a master port connected to a single
+ * slave and thus do not care about what ranges the slave
+ * covers (as there is nothing to choose from).
+ */
+ void recvRangeChange() { }
};