physical.cc revision 8931
12391SN/A/*
28931Sandreas.hansson@arm.com * Copyright (c) 2012 ARM Limited
37733SAli.Saidi@ARM.com * All rights reserved
47733SAli.Saidi@ARM.com *
57733SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall
67733SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual
77733SAli.Saidi@ARM.com * property including but not limited to intellectual property relating
87733SAli.Saidi@ARM.com * to a hardware implementation of the functionality of the software
97733SAli.Saidi@ARM.com * licensed hereunder.  You may use the software subject to the license
107733SAli.Saidi@ARM.com * terms below provided that you ensure that this notice is replicated
117733SAli.Saidi@ARM.com * unmodified and in its entirety in all distributions of the software,
127733SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form.
137733SAli.Saidi@ARM.com *
142391SN/A * Redistribution and use in source and binary forms, with or without
152391SN/A * modification, are permitted provided that the following conditions are
162391SN/A * met: redistributions of source code must retain the above copyright
172391SN/A * notice, this list of conditions and the following disclaimer;
182391SN/A * redistributions in binary form must reproduce the above copyright
192391SN/A * notice, this list of conditions and the following disclaimer in the
202391SN/A * documentation and/or other materials provided with the distribution;
212391SN/A * neither the name of the copyright holders nor the names of its
222391SN/A * contributors may be used to endorse or promote products derived from
232391SN/A * this software without specific prior written permission.
242391SN/A *
252391SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262391SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272391SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282391SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292391SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302391SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312391SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322391SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332391SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342391SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352391SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362665Ssaidi@eecs.umich.edu *
378931Sandreas.hansson@arm.com * Authors: Andreas Hansson
382391SN/A */
392391SN/A
408931Sandreas.hansson@arm.com#include "debug/BusAddrRanges.hh"
412394SN/A#include "mem/physical.hh"
422394SN/A
432391SN/Ausing namespace std;
442391SN/A
458931Sandreas.hansson@arm.comPhysicalMemory::PhysicalMemory(const vector<AbstractMemory*>& _memories) :
468931Sandreas.hansson@arm.com    size(0)
472391SN/A{
488931Sandreas.hansson@arm.com    for (vector<AbstractMemory*>::const_iterator m = _memories.begin();
498931Sandreas.hansson@arm.com         m != _memories.end(); ++m) {
508931Sandreas.hansson@arm.com        // only add the memory if it is part of the global address map
518931Sandreas.hansson@arm.com        if ((*m)->isInAddrMap()) {
528931Sandreas.hansson@arm.com            memories.push_back(*m);
532391SN/A
548931Sandreas.hansson@arm.com            // calculate the total size once and for all
558931Sandreas.hansson@arm.com            size += (*m)->size();
568931Sandreas.hansson@arm.com
578931Sandreas.hansson@arm.com            // add the range to our interval tree and make sure it does not
588931Sandreas.hansson@arm.com            // intersect an existing range
598931Sandreas.hansson@arm.com            if (addrMap.insert((*m)->getAddrRange(), *m) == addrMap.end())
608931Sandreas.hansson@arm.com                fatal("Memory address range for %s is overlapping\n",
618931Sandreas.hansson@arm.com                      (*m)->name());
628931Sandreas.hansson@arm.com        }
638931Sandreas.hansson@arm.com        DPRINTF(BusAddrRanges,
648931Sandreas.hansson@arm.com                "Skipping memory %s that is not in global address map\n",
658931Sandreas.hansson@arm.com                (*m)->name());
668931Sandreas.hansson@arm.com    }
678931Sandreas.hansson@arm.com    rangeCache.invalidate();
688931Sandreas.hansson@arm.com}
698931Sandreas.hansson@arm.com
708931Sandreas.hansson@arm.combool
718931Sandreas.hansson@arm.comPhysicalMemory::isMemAddr(Addr addr) const
728931Sandreas.hansson@arm.com{
738931Sandreas.hansson@arm.com    // see if the address is within the last matched range
748931Sandreas.hansson@arm.com    if (addr != rangeCache) {
758931Sandreas.hansson@arm.com        // lookup in the interval tree
768931Sandreas.hansson@arm.com        range_map<Addr, AbstractMemory*>::const_iterator r =
778931Sandreas.hansson@arm.com            addrMap.find(addr);
788931Sandreas.hansson@arm.com        if (r == addrMap.end()) {
798931Sandreas.hansson@arm.com            // not in the cache, and not in the tree
808931Sandreas.hansson@arm.com            return false;
818931Sandreas.hansson@arm.com        }
828931Sandreas.hansson@arm.com        // the range is in the tree, update the cache
838931Sandreas.hansson@arm.com        rangeCache = r->first;
848851Sandreas.hansson@arm.com    }
858851Sandreas.hansson@arm.com
868931Sandreas.hansson@arm.com    assert(addrMap.find(addr) != addrMap.end());
875477Snate@binkert.org
888931Sandreas.hansson@arm.com    // either matched the cache or found in the tree
898931Sandreas.hansson@arm.com    return true;
908931Sandreas.hansson@arm.com}
917730SAli.Saidi@ARM.com
928931Sandreas.hansson@arm.comAddrRangeList
938931Sandreas.hansson@arm.comPhysicalMemory::getConfAddrRanges() const
948931Sandreas.hansson@arm.com{
958931Sandreas.hansson@arm.com    // this could be done once in the constructor, but since it is unlikely to
968931Sandreas.hansson@arm.com    // be called more than once the iteration should not be a problem
978931Sandreas.hansson@arm.com    AddrRangeList ranges;
988931Sandreas.hansson@arm.com    for (vector<AbstractMemory*>::const_iterator m = memories.begin();
998931Sandreas.hansson@arm.com         m != memories.end(); ++m) {
1008931Sandreas.hansson@arm.com        if ((*m)->isConfReported()) {
1018931Sandreas.hansson@arm.com            ranges.push_back((*m)->getAddrRange());
1028931Sandreas.hansson@arm.com        }
1037730SAli.Saidi@ARM.com    }
1042391SN/A
1058931Sandreas.hansson@arm.com    return ranges;
1062391SN/A}
1072391SN/A
1082541SN/Avoid
1098931Sandreas.hansson@arm.comPhysicalMemory::access(PacketPtr pkt)
1102541SN/A{
1118931Sandreas.hansson@arm.com    assert(pkt->isRequest());
1128931Sandreas.hansson@arm.com    Addr addr = pkt->getAddr();
1138931Sandreas.hansson@arm.com    range_map<Addr, AbstractMemory*>::const_iterator m = addrMap.find(addr);
1148931Sandreas.hansson@arm.com    assert(m != addrMap.end());
1158931Sandreas.hansson@arm.com    m->second->access(pkt);
1162391SN/A}
1172391SN/A
1188719SAli.Saidi@ARM.comvoid
1198931Sandreas.hansson@arm.comPhysicalMemory::functionalAccess(PacketPtr pkt)
1208719SAli.Saidi@ARM.com{
1218931Sandreas.hansson@arm.com    assert(pkt->isRequest());
1228931Sandreas.hansson@arm.com    Addr addr = pkt->getAddr();
1238931Sandreas.hansson@arm.com    range_map<Addr, AbstractMemory*>::const_iterator m = addrMap.find(addr);
1248931Sandreas.hansson@arm.com    assert(m != addrMap.end());
1258931Sandreas.hansson@arm.com    m->second->functionalAccess(pkt);
1268719SAli.Saidi@ARM.com}
127