addr_range.hh revision 9411
12SN/A/* 21762SN/A * Copyright (c) 2012 ARM Limited 35502Snate@binkert.org * All rights reserved 49983Sstever@gmail.com * 52SN/A * The license below extends only to copyright in the software and shall 62SN/A * not be construed as granting a license to any other intellectual 72SN/A * property including but not limited to intellectual property relating 82SN/A * to a hardware implementation of the functionality of the software 92SN/A * licensed hereunder. You may use the software subject to the license 102SN/A * terms below provided that you ensure that this notice is replicated 112SN/A * unmodified and in its entirety in all distributions of the software, 122SN/A * modified or unmodified, in source code or in binary form. 132SN/A * 142SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 152SN/A * All rights reserved. 162SN/A * 172SN/A * Redistribution and use in source and binary forms, with or without 182SN/A * modification, are permitted provided that the following conditions are 192SN/A * met: redistributions of source code must retain the above copyright 202SN/A * notice, this list of conditions and the following disclaimer; 212SN/A * redistributions in binary form must reproduce the above copyright 222SN/A * notice, this list of conditions and the following disclaimer in the 232SN/A * documentation and/or other materials provided with the distribution; 242SN/A * neither the name of the copyright holders nor the names of its 252SN/A * contributors may be used to endorse or promote products derived from 262SN/A * this software without specific prior written permission. 272SN/A * 282SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292665Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302665Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312665Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322665Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 355501Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392SN/A * 405502Snate@binkert.org * Authors: Nathan Binkert 415501Snate@binkert.org * Steve Reinhardt 425501Snate@binkert.org * Andreas Hansson 431717SN/A */ 448232Snate@binkert.org 455501Snate@binkert.org#ifndef __BASE_ADDR_RANGE_HH__ 469356Snilay@cs.wisc.edu#define __BASE_ADDR_RANGE_HH__ 472SN/A 482SN/A#include "base/bitfield.hh" 492SN/A#include "base/cprintf.hh" 509983Sstever@gmail.com#include "base/misc.hh" 519983Sstever@gmail.com#include "base/types.hh" 522SN/A 539983Sstever@gmail.comclass AddrRange 542SN/A{ 559983Sstever@gmail.com 562SN/A private: 572SN/A 589983Sstever@gmail.com /// Private fields for the start and end of the range 599983Sstever@gmail.com Addr _start; 609983Sstever@gmail.com Addr _end; 619983Sstever@gmail.com 629983Sstever@gmail.com /// The high bit of the slice that is used for interleaving 639983Sstever@gmail.com uint8_t intlvHighBit; 649983Sstever@gmail.com 659983Sstever@gmail.com /// The number of bits used for interleaving, set to 0 to disable 669983Sstever@gmail.com uint8_t intlvBits; 679983Sstever@gmail.com 689983Sstever@gmail.com /// The value to compare the slice addr[high:(high - bits + 1)] 699983Sstever@gmail.com /// with. 709983Sstever@gmail.com uint8_t intlvMatch; 719983Sstever@gmail.com 729983Sstever@gmail.com public: 739983Sstever@gmail.com 742SN/A AddrRange() 754017Sstever@eecs.umich.edu : _start(1), _end(0), intlvHighBit(0), intlvBits(0), intlvMatch(0) 764016Sstever@eecs.umich.edu {} 774017Sstever@eecs.umich.edu 784016Sstever@eecs.umich.edu AddrRange(Addr _start, Addr _end, uint8_t _intlv_high_bit, 795768Snate@binkert.org uint8_t _intlv_bits, uint8_t _intlv_match) 805768Snate@binkert.org : _start(_start), _end(_end), intlvHighBit(_intlv_high_bit), 815774Snate@binkert.org intlvBits(_intlv_bits), intlvMatch(_intlv_match) 827059Snate@binkert.org {} 835768Snate@binkert.org 845768Snate@binkert.org AddrRange(Addr _start, Addr _end) 855768Snate@binkert.org : _start(_start), _end(_end), intlvHighBit(0), intlvBits(0), 865768Snate@binkert.org intlvMatch(0) 875768Snate@binkert.org {} 885768Snate@binkert.org 895768Snate@binkert.org /** 905768Snate@binkert.org * Determine if the range is interleaved or not. 915768Snate@binkert.org * 925768Snate@binkert.org * @return true if interleaved 935768Snate@binkert.org */ 945768Snate@binkert.org bool interleaved() const { return intlvBits != 0; } 955768Snate@binkert.org 965602Snate@binkert.org /** 975602Snate@binkert.org * Determing the interleaving granularity of the range. 985502Snate@binkert.org * 995503Snate@binkert.org * @return The size of the regions created by the interleaving bits 1005502Snate@binkert.org */ 1015502Snate@binkert.org uint64_t granularity() const { return ULL(1) << intlvHighBit; } 1025502Snate@binkert.org 1035502Snate@binkert.org /** 1045502Snate@binkert.org * Determine the number of interleaved address stripes this range 1055503Snate@binkert.org * is part of. 1065502Snate@binkert.org * 1075502Snate@binkert.org * @return The number of stripes spanned by the interleaving bits 1085502Snate@binkert.org */ 1095502Snate@binkert.org uint32_t stripes() const { return ULL(1) << intlvBits; } 1105503Snate@binkert.org 1115503Snate@binkert.org /** 1125503Snate@binkert.org * Get the size of the address range. For a case where 1135502Snate@binkert.org * interleaving is used we make the simplifying assumption that 1145503Snate@binkert.org * the size is a divisible by the size of the interleaving slice. 1155502Snate@binkert.org */ 1165502Snate@binkert.org Addr size() const 1172SN/A { 1182SN/A return (_end - _start + 1) >> intlvBits; 1192SN/A } 1205502Snate@binkert.org 1215502Snate@binkert.org /** 1225602Snate@binkert.org * Determine if the range is valid. 1235502Snate@binkert.org */ 1245502Snate@binkert.org bool valid() const { return _start < _end; } 1252SN/A 1265502Snate@binkert.org /** 1275502Snate@binkert.org * Get the start address of the range. 1285503Snate@binkert.org */ 1295503Snate@binkert.org Addr start() const { return _start; } 1305503Snate@binkert.org 1315503Snate@binkert.org /** 1325503Snate@binkert.org * Get a string representation of the range. This could 1335502Snate@binkert.org * alternatively be implemented as a operator<<, but at the moment 1342SN/A * that seems like overkill. 1355503Snate@binkert.org */ 1365503Snate@binkert.org std::string to_string() const 1375602Snate@binkert.org { 1385502Snate@binkert.org if (interleaved()) 1392SN/A return csprintf("[%#llx : %#llx], [%d : %d] = %d", _start, _end, 1405602Snate@binkert.org intlvHighBit, intlvHighBit - intlvBits + 1, 1415602Snate@binkert.org intlvMatch); 1425502Snate@binkert.org else 1435503Snate@binkert.org return csprintf("[%#llx : %#llx]", _start, _end); 1445503Snate@binkert.org } 1455502Snate@binkert.org 1465503Snate@binkert.org /** 1475503Snate@binkert.org * Determine if another range merges with the current one, i.e. if 1485503Snate@binkert.org * they are part of the same contigous range and have the same 1495503Snate@binkert.org * interleaving bits. 1505503Snate@binkert.org * 1515503Snate@binkert.org * @param r Range to evaluate merging with 1525503Snate@binkert.org * @return true if the two ranges would merge 1535503Snate@binkert.org */ 1545503Snate@binkert.org bool mergesWith(const AddrRange& r) const 1555503Snate@binkert.org { 1565503Snate@binkert.org return r._start == _start && r._end == _end && 1575503Snate@binkert.org r.intlvHighBit == intlvHighBit && 1585503Snate@binkert.org r.intlvBits == intlvBits; 1595503Snate@binkert.org } 1605502Snate@binkert.org 1615502Snate@binkert.org /** 1625503Snate@binkert.org * Determine if another range intersects this one, i.e. if there 1635503Snate@binkert.org * is an address that is both in this range and the other 1642SN/A * range. No check is made to ensure either range is valid. 1655502Snate@binkert.org * 1665503Snate@binkert.org * @param r Range to intersect with 1675503Snate@binkert.org * @return true if the intersection of the two ranges is not empty 1685503Snate@binkert.org */ 1692SN/A bool intersects(const AddrRange& r) const 1702SN/A { 1712SN/A if (!interleaved()) { 1722SN/A return _start <= r._end && _end >= r._start; 1732SN/A } 1742SN/A 1755502Snate@binkert.org // the current range is interleaved, split the check up in 1762SN/A // three cases 1779983Sstever@gmail.com if (r.size() == 1) 1789983Sstever@gmail.com // keep it simple and check if the address is within 1795502Snate@binkert.org // this range 1805502Snate@binkert.org return contains(r.start()); 1815502Snate@binkert.org else if (!r.interleaved()) 1825602Snate@binkert.org // be conservative and ignore the interleaving 1832SN/A return _start <= r._end && _end >= r._start; 1842SN/A else if (mergesWith(r)) 1852SN/A // restrict the check to ranges that belong to the 1865502Snate@binkert.org // same chunk 1872SN/A return intlvMatch == r.intlvMatch; 1885502Snate@binkert.org else 1895502Snate@binkert.org panic("Cannot test intersection of interleaved range %s\n", 1902SN/A to_string()); 1915502Snate@binkert.org } 1922SN/A 1932SN/A /** 1945502Snate@binkert.org * Determine if this range is a subset of another range, i.e. if 1955502Snate@binkert.org * every address in this range is also in the other range. No 1965502Snate@binkert.org * check is made to ensure either range is valid. 1975503Snate@binkert.org * 1985503Snate@binkert.org * @param r Range to compare with 1995502Snate@binkert.org * @return true if the this range is a subset of the other one 2005602Snate@binkert.org */ 2012SN/A bool isSubset(const AddrRange& r) const 2022SN/A { 2032667Sstever@eecs.umich.edu if (interleaved()) 2042SN/A panic("Cannot test subset of interleaved range %s\n", to_string()); 2052SN/A return _start >= r._start && _end <= r._end; 2065503Snate@binkert.org } 2075503Snate@binkert.org 2085769Snate@binkert.org /** 2095502Snate@binkert.org * Determine if the range contains an address. 2105503Snate@binkert.org * 2115503Snate@binkert.org * @param a Address to compare with 2125503Snate@binkert.org * @return true if the address is in the range 2135503Snate@binkert.org */ 2145503Snate@binkert.org bool contains(const Addr& a) const 2155503Snate@binkert.org { 2165503Snate@binkert.org // check if the address is in the range and if there is either 2175502Snate@binkert.org // no interleaving, or with interleaving also if the selected 2185502Snate@binkert.org // bits from the address match the interleaving value 2195503Snate@binkert.org return a >= _start && a <= _end && 2205502Snate@binkert.org (interleaved() || 2212SN/A (bits(a, intlvHighBit, intlvHighBit - intlvBits + 1) == 2222SN/A intlvMatch)); 2232667Sstever@eecs.umich.edu } 2249356Snilay@cs.wisc.edu 2259356Snilay@cs.wisc.edu/** 2269356Snilay@cs.wisc.edu * Keep the operators away from SWIG. 2272SN/A */ 2282667Sstever@eecs.umich.edu#ifndef SWIG 2299328SAli.Saidi@ARM.com 2309328SAli.Saidi@ARM.com /** 2312667Sstever@eecs.umich.edu * Less-than operator used to turn an STL map into a binary search 2322667Sstever@eecs.umich.edu * tree of non-overlapping address ranges. 2332667Sstever@eecs.umich.edu * 2345769Snate@binkert.org * @param r Range to compare with 2352667Sstever@eecs.umich.edu * @return true if the start address is less than that of the other range 2362SN/A */ 2375769Snate@binkert.org bool operator<(const AddrRange& r) const 2382SN/A { 2392667Sstever@eecs.umich.edu if (_start != r._start) 2402667Sstever@eecs.umich.edu return _start < r._start; 2412SN/A else 2422SN/A // for now assume that the end is also the same, and that 243224SN/A // we are looking at the same interleaving bits 244224SN/A return intlvMatch < r.intlvMatch; 245224SN/A } 246224SN/A 247224SN/A#endif // SWIG 2485769Snate@binkert.org}; 2495769Snate@binkert.org 250224SN/Ainline AddrRange 251224SN/ARangeEx(Addr start, Addr end) 252224SN/A{ return AddrRange(start, end - 1); } 253237SN/A 254224SN/Ainline AddrRange 2559983Sstever@gmail.comRangeIn(Addr start, Addr end) 2569983Sstever@gmail.com{ return AddrRange(start, end); } 2579983Sstever@gmail.com 2589983Sstever@gmail.cominline AddrRange 2599983Sstever@gmail.comRangeSize(Addr start, Addr size) 2605695Snate@binkert.org{ return AddrRange(start, start + size - 1); } 2619983Sstever@gmail.com 262224SN/A#endif // __BASE_ADDR_RANGE_HH__ 263224SN/A