PhysicalMemory::createBackingStore(AddrRange range,
const vector<AbstractMemory*>& _memories)
{
+ if (range.interleaved())
+ panic("Cannot create backing store for interleaved range %s\n",
+ range.to_string());
+
// 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 with size %d\n",
+ range.to_string(), range.size());
int map_flags = MAP_ANON | MAP_PRIVATE;
uint8_t* pmem = (uint8_t*) mmap(NULL, range.size(),
PROT_READ | PROT_WRITE,
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
if (init_to_zero != 0) {
if (init_to_zero != _memories.size())
- fatal("Some, but not all memories in range %x:%x are set zero\n",
- range.start, range.end);
+ fatal("Some, but not all memories in range %s are set zero\n",
+ range.to_string());
memset(pmem, 0, range.size());
}
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<AbstractMemory*>::const_iterator r = addrMap.find(addr);
if (r == addrMap.end()) {
// this could be done once in the constructor, but since it is unlikely to
// be called more than once the iteration should not be a problem
AddrRangeList ranges;
- for (vector<AbstractMemory*>::const_iterator m = memories.begin();
- m != memories.end(); ++m) {
- if ((*m)->isConfReported()) {
- ranges.push_back((*m)->getAddrRange());
+ vector<AddrRange> intlv_ranges;
+ for (AddrRangeMap<AbstractMemory*>::const_iterator r = addrMap.begin();
+ r != addrMap.end(); ++r) {
+ if (r->second->isConfReported()) {
+ // if the range is interleaved then save it for now
+ if (r->first.interleaved()) {
+ // if we already got interleaved ranges that are not
+ // part of the same range, then first do a merge
+ // before we add the new one
+ if (!intlv_ranges.empty() &&
+ !intlv_ranges.back().mergesWith(r->first)) {
+ ranges.push_back(AddrRange(intlv_ranges));
+ intlv_ranges.clear();
+ }
+ intlv_ranges.push_back(r->first);
+ } else {
+ // keep the current range
+ ranges.push_back(r->first);
+ }
}
}
+ // if there is still interleaved ranges waiting to be merged,
+ // go ahead and do it
+ if (!intlv_ranges.empty()) {
+ ranges.push_back(AddrRange(intlv_ranges));
+ }
+
return ranges;
}
arrayParamIn(cp, section, "lal_addr", lal_addr);
arrayParamIn(cp, section, "lal_cid", lal_cid);
for(size_t i = 0; i < lal_addr.size(); ++i) {
- AddrRangeMap<AbstractMemory*>::iterator m = addrMap.find(lal_addr[i]);
+ AddrRangeMap<AbstractMemory*>::const_iterator m =
+ addrMap.find(lal_addr[i]);
m->second->addLockedAddr(LockedAddr(lal_addr[i], lal_cid[i]));
}