diff -r 8650f0c53db5 -r dd82368c5370 src/arch/arm/linux/system.cc --- a/src/arch/arm/linux/system.cc Wed Oct 31 08:39:45 2012 -0400 +++ b/src/arch/arm/linux/system.cc Thu Nov 01 08:49:24 2012 +0000 @@ -166,7 +166,7 @@ } AtagMem am; am.memSize(atagRanges.begin()->size()); - am.memStart(atagRanges.begin()->start); + am.memStart(atagRanges.begin()->start()); AtagCmdline ad; ad.cmdline(params()->boot_osflags); diff -r 8650f0c53db5 -r dd82368c5370 src/base/addr_range.hh --- a/src/base/addr_range.hh Wed Oct 31 08:39:45 2012 -0400 +++ b/src/base/addr_range.hh Thu Nov 01 08:49:24 2012 +0000 @@ -45,30 +45,59 @@ #ifndef __BASE_ADDR_RANGE_HH__ #define __BASE_ADDR_RANGE_HH__ +#include "base/cprintf.hh" #include "base/types.hh" class AddrRange { + private: + + /// Private fields for the start and end of the range. In the + /// future, these will be extended with interleaving functionality + /// and hence should never be manipulated directly. + Addr _start; + Addr _end; + public: - Addr start; - Addr end; - AddrRange() - : start(1), end(0) + : _start(1), _end(0) {} AddrRange(Addr _start, Addr _end) - : start(_start), end(_end) + : _start(_start), _end(_end) {} AddrRange(const std::pair &r) - : start(r.first), end(r.second) + : _start(r.first), _end(r.second) {} - Addr size() const { return end - start + 1; } - bool valid() const { return start < end; } + /** + * Get the size of the address range. For a case where + * interleaving is used this should probably cause a panic. + */ + Addr size() const { return _end - _start + 1; } + + /** + * Determine if the range is valid. + */ + bool valid() const { return _start < _end; } + + /** + * Get the start address of the range. + */ + Addr start() const { return _start; } + + /** + * Get a string representation of the range. This could + * alternatively be implemented as a operator<<, but at the moment + * that seems like overkill. + */ + std::string to_string() const + { + return csprintf("[%#llx : %#llx]", _start, _end); + } /** * Determine if another range intersects this one, i.e. if there @@ -80,8 +109,7 @@ */ bool intersects(const AddrRange& r) const { - return (start <= r.start && end >= r.start) || - (start <= r.end && end >= r.end); + return _start <= r._end && _end >= r._start; } /** @@ -94,47 +122,66 @@ */ bool isSubset(const AddrRange& r) const { - return start >= r.start && end <= r.end; + return _start >= r._start && _end <= r._end; } -}; + + /** + * Determine if the range contains an address. + * + * @param a Address to compare with + * @return true if the address is in the range + */ + bool contains(const Addr& a) const + { + return a >= _start && a <= _end; + } + + /** + * Attempt to merge another range with the current range. This + * will return true if a merge took place. The different mergings + * possible currently include neighbouring ranges causing an + * extension of the current range. In the future, there is a + * possibility to merge two interleaved ranges. + * + * @param r Range to merge with + * @return true if a merge of any kind took place + */ + bool merge(const AddrRange& r) + { + // merge upwards + if (_end + 1 == r._start) { + _end = r._end; + return true; + } + + // merge downwards + if (r._end + 1 == _start) { + _start = r._start; + return true; + } + + return false; + } /** * Keep the operators away from SWIG. */ #ifndef SWIG -/** - * @param range1 is a range. - * @param range2 is a range. - * @return if range1 is less than range2 and does not overlap range1. - */ -inline bool -operator<(const AddrRange& range1, const AddrRange& range2) -{ - return range1.start < range2.start; -} + /** + * Less-than operator used to turn an STL map into a binary search + * tree of non-overlapping address ranges. + * + * @param r Range to compare with + * @return true if the start address is less than that of the other range + */ + bool operator<(const AddrRange& r) const + { + return _start < r._start; + } -/** - * @param addr address in the range - * @param range range compared against. - * @return indicates that the address is not within the range. - */ -inline bool -operator!=(const Addr& addr, const AddrRange& range) -{ - return addr < range.start || addr > range.end; -} - -/** - * @param range range compared against. - * @param pos position compared to the range. - * @return indicates that position pos is within the range. - */ -inline bool -operator==(const AddrRange& range, const Addr& addr) -{ - return addr >= range.start && addr <= range.end; -} +#endif // SWIG +}; inline AddrRange RangeEx(Addr start, Addr end) @@ -148,6 +195,4 @@ RangeSize(Addr start, Addr size) { return std::make_pair(start, start + size - 1); } -#endif // SWIG - #endif // __BASE_ADDR_RANGE_HH__ diff -r 8650f0c53db5 -r dd82368c5370 src/base/addr_range_map.hh --- a/src/base/addr_range_map.hh Wed Oct 31 08:39:45 2012 -0400 +++ b/src/base/addr_range_map.hh Thu Nov 01 08:49:24 2012 +0000 @@ -73,7 +73,7 @@ i = tree.upper_bound(r); if (i == tree.begin()) { - if (i->first.start <= r.end && i->first.end >= r.start) + if (i->first.intersects(r)) return i; else // Nothing could match, so return end() @@ -82,7 +82,7 @@ --i; - if (i->first.start <= r.end && i->first.end >= r.start) + if (i->first.intersects(r)) return i; return tree.end(); @@ -96,7 +96,7 @@ i = tree.upper_bound(r); if (i == tree.begin()) { - if (i->first.start <= r.end && i->first.end >= r.start) + if (i->first.intersects(r)) return i; else // Nothing could match, so return end() @@ -105,7 +105,7 @@ --i; - if (i->first.start <= r.end && i->first.end >= r.start) + if (i->first.intersects(r)) return i; return tree.end(); diff -r 8650f0c53db5 -r dd82368c5370 src/kern/tru64/tru64_events.cc --- a/src/kern/tru64/tru64_events.cc Wed Oct 31 08:39:45 2012 -0400 +++ b/src/kern/tru64/tru64_events.cc Thu Nov 01 08:49:24 2012 +0000 @@ -65,7 +65,7 @@ // get the address ranges of the connected slave port AddrRangeList resp = dataPort.getAddrRanges(); for (iter = resp.begin(); iter != resp.end(); iter++) { - if (*iter == (K0Seg2Phys(a0) & PAddrImplMask)) + if (iter->contains(K0Seg2Phys(a0) & PAddrImplMask)) found = true; } diff -r 8650f0c53db5 -r dd82368c5370 src/mem/abstract_mem.hh --- a/src/mem/abstract_mem.hh Wed Oct 31 08:39:45 2012 -0400 +++ b/src/mem/abstract_mem.hh Thu Nov 01 08:49:24 2012 +0000 @@ -266,7 +266,7 @@ * * @return the start address of the memory */ - Addr start() const { return range.start; } + Addr start() const { return range.start(); } /** * Should this memory be passed to the kernel and part of the OS diff -r 8650f0c53db5 -r dd82368c5370 src/mem/abstract_mem.cc --- a/src/mem/abstract_mem.cc Wed Oct 31 08:39:45 2012 -0400 +++ b/src/mem/abstract_mem.cc Thu Nov 01 08:49:24 2012 +0000 @@ -303,8 +303,8 @@ void AbstractMemory::access(PacketPtr pkt) { - assert(pkt->getAddr() >= range.start && - (pkt->getAddr() + pkt->getSize() - 1) <= range.end); + assert(AddrRange(pkt->getAddr(), + pkt->getAddr() + pkt->getSize() - 1).isSubset(range)); if (pkt->memInhibitAsserted()) { DPRINTF(MemoryAccess, "mem inhibited on 0x%x: not responding\n", @@ -312,7 +312,7 @@ return; } - uint8_t *hostAddr = pmemAddr + pkt->getAddr() - range.start; + uint8_t *hostAddr = pmemAddr + pkt->getAddr() - range.start(); if (pkt->cmd == MemCmd::SwapReq) { TheISA::IntReg overwrite_val; @@ -384,10 +384,10 @@ void AbstractMemory::functionalAccess(PacketPtr pkt) { - assert(pkt->getAddr() >= range.start && - (pkt->getAddr() + pkt->getSize() - 1) <= range.end); + assert(AddrRange(pkt->getAddr(), + pkt->getAddr() + pkt->getSize() - 1).isSubset(range)); - uint8_t *hostAddr = pmemAddr + pkt->getAddr() - range.start; + uint8_t *hostAddr = pmemAddr + pkt->getAddr() - range.start(); if (pkt->isRead()) { if (pmemAddr) diff -r 8650f0c53db5 -r dd82368c5370 src/mem/addr_mapper.cc --- a/src/mem/addr_mapper.cc Wed Oct 31 08:39:45 2012 -0400 +++ b/src/mem/addr_mapper.cc Thu Nov 01 08:49:24 2012 +0000 @@ -253,9 +253,9 @@ RangeAddrMapper::remapAddr(Addr addr) const { for (int i = 0; i < originalRanges.size(); ++i) { - if (originalRanges[i] == addr) { - Addr offset = addr - originalRanges[i].start; - return offset + remappedRanges[i].start; + if (originalRanges[i].contains(addr)) { + Addr offset = addr - originalRanges[i].start(); + return offset + remappedRanges[i].start(); } } @@ -277,11 +277,12 @@ " ranges but are not a subset.\n"); if (range.isSubset(originalRanges[j])) { // range is a subset - Addr offset = range.start - originalRanges[j].start; - range.start -= offset; - range.end -= offset; + Addr offset = range.start() - originalRanges[j].start(); + Addr start = range.start() - offset; + ranges.push_back(AddrRange(start, start + range.size() - 1)); + } else { + ranges.push_back(range); } - ranges.push_back(range); } } diff -r 8650f0c53db5 -r dd82368c5370 src/mem/bus.hh --- a/src/mem/bus.hh Wed Oct 31 08:39:45 2012 -0400 +++ b/src/mem/bus.hh Thu Nov 01 08:49:24 2012 +0000 @@ -264,13 +264,13 @@ // Checks the cache and returns the id of the port that has the requested // address within its range inline PortID checkPortCache(Addr addr) const { - if (portCache[0].valid && portCache[0].range == addr) { + if (portCache[0].valid && portCache[0].range.contains(addr)) { return portCache[0].id; } - if (portCache[1].valid && portCache[1].range == addr) { + if (portCache[1].valid && portCache[1].range.contains(addr)) { return portCache[1].id; } - if (portCache[2].valid && portCache[2].range == addr) { + if (portCache[2].valid && portCache[2].range.contains(addr)) { return portCache[2].id; } diff -r 8650f0c53db5 -r dd82368c5370 src/mem/bus.cc --- a/src/mem/bus.cc Wed Oct 31 08:39:45 2012 -0400 +++ b/src/mem/bus.cc Thu Nov 01 08:49:24 2012 +0000 @@ -356,7 +356,7 @@ // Check if this matches the default range if (useDefaultRange) { - if (defaultRange == addr) { + if (defaultRange.contains(addr)) { DPRINTF(BusAddrRanges, " found addr %#llx on default\n", addr); return defaultPortID; @@ -429,8 +429,8 @@ AddrRangeList ranges = masterPorts[master_port_id]->getAddrRanges(); for (AddrRangeConstIter r = ranges.begin(); r != ranges.end(); ++r) { - DPRINTF(BusAddrRanges, "Adding range %#llx : %#llx for id %d\n", - r->start, r->end, master_port_id); + DPRINTF(BusAddrRanges, "Adding range %s for id %d\n", + r->to_string(), master_port_id); if (portMap.insert(*r, master_port_id) == portMap.end()) { PortID conflict_id = portMap.find(*r)->second; fatal("%s has two ports with same range:\n\t%s\n\t%s\n", @@ -465,9 +465,9 @@ // overlapping the default range if (r->intersects(defaultRange) && !r->isSubset(defaultRange)) - fatal("Range %#llx : %#llx intersects the " \ + fatal("Range %s intersects the " \ "default range of %s but is not a " \ - "subset\n", r->start, r->end, name()); + "subset\n", r->to_string(), name()); } } } @@ -496,18 +496,16 @@ // start out with the default range AddrRangeList ranges; ranges.push_back(defaultRange); - DPRINTF(BusAddrRanges, " -- %#llx : %#llx DEFAULT\n", - defaultRange.start, defaultRange.end); + DPRINTF(BusAddrRanges, " -- %s DEFAULT\n", defaultRange.to_string()); // add any range that is not a subset of the default range for (PortMapConstIter p = portMap.begin(); p != portMap.end(); ++p) { if (useDefaultRange && p->first.isSubset(defaultRange)) { - DPRINTF(BusAddrRanges, " -- %#llx : %#llx is a SUBSET\n", - p->first.start, p->first.end); + DPRINTF(BusAddrRanges, " -- %s is a SUBSET\n", + p->first.to_string()); } else { ranges.push_back(p->first); - DPRINTF(BusAddrRanges, " -- %#llx : %#llx\n", - p->first.start, p->first.end); + DPRINTF(BusAddrRanges, " -- %s\n", p->first.to_string()); } } diff -r 8650f0c53db5 -r dd82368c5370 src/mem/physical.cc --- a/src/mem/physical.cc Wed Oct 31 08:39:45 2012 -0400 +++ b/src/mem/physical.cc Thu Nov 01 08:49:24 2012 +0000 @@ -111,14 +111,12 @@ // if the ranges are neighbours, then append, this // will eventually be extended to include support for // address striping and merge the interleaved ranges - if (curr_range.end + 1 == r->first.start) { + if (curr_range.merge(r->first)) { DPRINTF(BusAddrRanges, - "Merging neighbouring ranges %x:%x and %x:%x\n", - curr_range.start, curr_range.end, r->first.start, - r->first.end); - // update the end of the range and add the current - // memory to the list of memories - curr_range.end = r->first.end; + "Merging neighbouring ranges %s and %s\n", + curr_range.to_string(), r->first.to_string()); + // the current range is already updated, so simply + // add the current memory to the list of memories curr_memories.push_back(r->second); } else { // what we already have is valid, and this is not @@ -154,8 +152,8 @@ const vector& _memories) { // perform the actual mmap - DPRINTF(BusAddrRanges, "Creating backing store for range %x:%x\n", - range.start, range.end); + DPRINTF(BusAddrRanges, "Creating backing store for range %s\n", + range.to_string()); int map_flags = MAP_ANON | MAP_PRIVATE; uint8_t* pmem = (uint8_t*) mmap(NULL, range.size(), PROT_READ | PROT_WRITE, @@ -163,8 +161,8 @@ if (pmem == (uint8_t*) MAP_FAILED) { perror("mmap"); - fatal("Could not mmap %d bytes for range %x:%x!\n", range.size(), - range.start, range.end); + fatal("Could not mmap %d bytes for range %s!\n", range.size(), + range.to_string()); } // remember this backing store so we can checkpoint it and unmap @@ -200,7 +198,7 @@ PhysicalMemory::isMemAddr(Addr addr) const { // see if the address is within the last matched range - if (addr != rangeCache) { + if (!rangeCache.contains(addr)) { // lookup in the interval tree AddrRangeMap::const_iterator r = addrMap.find(addr); if (r == addrMap.end()) {