1/*
| 1/*
|
2 * Copyright (c) 2012, 2014, 2017 ARM Limited
| 2 * Copyright (c) 2012, 2014, 2017-2018 ARM Limited
|
3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Copyright (c) 2002-2005 The Regents of The University of Michigan 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions are 19 * met: redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer; 21 * redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution; 24 * neither the name of the copyright holders nor the names of its 25 * contributors may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Nathan Binkert 41 * Steve Reinhardt 42 * Andreas Hansson 43 */ 44 45#ifndef __BASE_ADDR_RANGE_HH__ 46#define __BASE_ADDR_RANGE_HH__ 47
| 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Copyright (c) 2002-2005 The Regents of The University of Michigan 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions are 19 * met: redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer; 21 * redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution; 24 * neither the name of the copyright holders nor the names of its 25 * contributors may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Nathan Binkert 41 * Steve Reinhardt 42 * Andreas Hansson 43 */ 44 45#ifndef __BASE_ADDR_RANGE_HH__ 46#define __BASE_ADDR_RANGE_HH__ 47
|
| 48#include <algorithm>
|
48#include <list> 49#include <vector> 50 51#include "base/bitfield.hh" 52#include "base/cprintf.hh" 53#include "base/logging.hh" 54#include "base/types.hh" 55 56/** 57 * The AddrRange class encapsulates an address range, and supports a 58 * number of tests to check if two ranges intersect, if a range 59 * contains a specific address etc. Besides a basic range, the 60 * AddrRange also support interleaved ranges, to stripe across cache 61 * banks, or memory controllers. The interleaving is implemented by 62 * allowing a number of bits of the address, at an arbitrary bit 63 * position, to be used as interleaving bits with an associated 64 * matching value. In addition, to prevent uniformly strided address 65 * patterns from a very biased interleaving, we also allow basic 66 * XOR-based hashing by specifying an additional set of bits to XOR 67 * with before matching. 68 * 69 * The AddrRange is also able to coalesce a number of interleaved 70 * ranges to a contiguous range. 71 */ 72class AddrRange 73{ 74 75 private: 76 77 /// Private fields for the start and end of the range 78 /// Both _start and _end are part of the range. 79 Addr _start; 80 Addr _end; 81 82 /// The high bit of the slice that is used for interleaving 83 uint8_t intlvHighBit; 84 85 /// The high bit of the slice used to XOR hash the value we match 86 /// against, set to 0 to disable. 87 uint8_t xorHighBit; 88 89 /// The number of bits used for interleaving, set to 0 to disable 90 uint8_t intlvBits; 91 92 /// The value to compare the slice addr[high:(high - bits + 1)] 93 /// with. 94 uint8_t intlvMatch; 95 96 public: 97 98 AddrRange() 99 : _start(1), _end(0), intlvHighBit(0), xorHighBit(0), intlvBits(0), 100 intlvMatch(0) 101 {} 102 103 AddrRange(Addr _start, Addr _end, uint8_t _intlv_high_bit, 104 uint8_t _xor_high_bit, uint8_t _intlv_bits, 105 uint8_t _intlv_match) 106 : _start(_start), _end(_end), intlvHighBit(_intlv_high_bit), 107 xorHighBit(_xor_high_bit), intlvBits(_intlv_bits), 108 intlvMatch(_intlv_match) 109 { 110 // sanity checks 111 fatal_if(intlvBits && intlvMatch >= ULL(1) << intlvBits, 112 "Match value %d does not fit in %d interleaving bits\n", 113 intlvMatch, intlvBits); 114 115 // ignore the XOR bits if not interleaving 116 if (intlvBits && xorHighBit) { 117 if (xorHighBit == intlvHighBit) { 118 fatal("XOR and interleave high bit must be different\n"); 119 } else if (xorHighBit > intlvHighBit) { 120 if ((xorHighBit - intlvHighBit) < intlvBits) 121 fatal("XOR and interleave high bit must be at least " 122 "%d bits apart\n", intlvBits); 123 } else { 124 if ((intlvHighBit - xorHighBit) < intlvBits) { 125 fatal("Interleave and XOR high bit must be at least " 126 "%d bits apart\n", intlvBits); 127 } 128 } 129 } 130 } 131 132 AddrRange(Addr _start, Addr _end) 133 : _start(_start), _end(_end), intlvHighBit(0), xorHighBit(0), 134 intlvBits(0), intlvMatch(0) 135 {} 136 137 /** 138 * Create an address range by merging a collection of interleaved 139 * ranges. 140 * 141 * @param ranges Interleaved ranges to be merged 142 */ 143 AddrRange(const std::vector<AddrRange>& ranges) 144 : _start(1), _end(0), intlvHighBit(0), xorHighBit(0), intlvBits(0), 145 intlvMatch(0) 146 { 147 if (!ranges.empty()) { 148 // get the values from the first one and check the others 149 _start = ranges.front()._start; 150 _end = ranges.front()._end; 151 intlvHighBit = ranges.front().intlvHighBit; 152 xorHighBit = ranges.front().xorHighBit; 153 intlvBits = ranges.front().intlvBits; 154 155 if (ranges.size() != (ULL(1) << intlvBits)) 156 fatal("Got %d ranges spanning %d interleaving bits\n", 157 ranges.size(), intlvBits); 158 159 uint8_t match = 0; 160 for (const auto& r : ranges) { 161 if (!mergesWith(r)) 162 fatal("Can only merge ranges with the same start, end " 163 "and interleaving bits\n"); 164 165 if (r.intlvMatch != match) 166 fatal("Expected interleave match %d but got %d when " 167 "merging\n", match, r.intlvMatch); 168 ++match; 169 } 170 171 // our range is complete and we can turn this into a 172 // non-interleaved range 173 intlvHighBit = 0; 174 xorHighBit = 0; 175 intlvBits = 0; 176 } 177 } 178 179 /** 180 * Determine if the range is interleaved or not. 181 * 182 * @return true if interleaved 183 */ 184 bool interleaved() const { return intlvBits != 0; } 185 186 /** 187 * Determine if the range interleaving is hashed or not. 188 */ 189 bool hashed() const { return interleaved() && xorHighBit != 0; } 190 191 /** 192 * Determing the interleaving granularity of the range. 193 * 194 * @return The size of the regions created by the interleaving bits 195 */ 196 uint64_t granularity() const 197 {
| 49#include <list> 50#include <vector> 51 52#include "base/bitfield.hh" 53#include "base/cprintf.hh" 54#include "base/logging.hh" 55#include "base/types.hh" 56 57/** 58 * The AddrRange class encapsulates an address range, and supports a 59 * number of tests to check if two ranges intersect, if a range 60 * contains a specific address etc. Besides a basic range, the 61 * AddrRange also support interleaved ranges, to stripe across cache 62 * banks, or memory controllers. The interleaving is implemented by 63 * allowing a number of bits of the address, at an arbitrary bit 64 * position, to be used as interleaving bits with an associated 65 * matching value. In addition, to prevent uniformly strided address 66 * patterns from a very biased interleaving, we also allow basic 67 * XOR-based hashing by specifying an additional set of bits to XOR 68 * with before matching. 69 * 70 * The AddrRange is also able to coalesce a number of interleaved 71 * ranges to a contiguous range. 72 */ 73class AddrRange 74{ 75 76 private: 77 78 /// Private fields for the start and end of the range 79 /// Both _start and _end are part of the range. 80 Addr _start; 81 Addr _end; 82 83 /// The high bit of the slice that is used for interleaving 84 uint8_t intlvHighBit; 85 86 /// The high bit of the slice used to XOR hash the value we match 87 /// against, set to 0 to disable. 88 uint8_t xorHighBit; 89 90 /// The number of bits used for interleaving, set to 0 to disable 91 uint8_t intlvBits; 92 93 /// The value to compare the slice addr[high:(high - bits + 1)] 94 /// with. 95 uint8_t intlvMatch; 96 97 public: 98 99 AddrRange() 100 : _start(1), _end(0), intlvHighBit(0), xorHighBit(0), intlvBits(0), 101 intlvMatch(0) 102 {} 103 104 AddrRange(Addr _start, Addr _end, uint8_t _intlv_high_bit, 105 uint8_t _xor_high_bit, uint8_t _intlv_bits, 106 uint8_t _intlv_match) 107 : _start(_start), _end(_end), intlvHighBit(_intlv_high_bit), 108 xorHighBit(_xor_high_bit), intlvBits(_intlv_bits), 109 intlvMatch(_intlv_match) 110 { 111 // sanity checks 112 fatal_if(intlvBits && intlvMatch >= ULL(1) << intlvBits, 113 "Match value %d does not fit in %d interleaving bits\n", 114 intlvMatch, intlvBits); 115 116 // ignore the XOR bits if not interleaving 117 if (intlvBits && xorHighBit) { 118 if (xorHighBit == intlvHighBit) { 119 fatal("XOR and interleave high bit must be different\n"); 120 } else if (xorHighBit > intlvHighBit) { 121 if ((xorHighBit - intlvHighBit) < intlvBits) 122 fatal("XOR and interleave high bit must be at least " 123 "%d bits apart\n", intlvBits); 124 } else { 125 if ((intlvHighBit - xorHighBit) < intlvBits) { 126 fatal("Interleave and XOR high bit must be at least " 127 "%d bits apart\n", intlvBits); 128 } 129 } 130 } 131 } 132 133 AddrRange(Addr _start, Addr _end) 134 : _start(_start), _end(_end), intlvHighBit(0), xorHighBit(0), 135 intlvBits(0), intlvMatch(0) 136 {} 137 138 /** 139 * Create an address range by merging a collection of interleaved 140 * ranges. 141 * 142 * @param ranges Interleaved ranges to be merged 143 */ 144 AddrRange(const std::vector<AddrRange>& ranges) 145 : _start(1), _end(0), intlvHighBit(0), xorHighBit(0), intlvBits(0), 146 intlvMatch(0) 147 { 148 if (!ranges.empty()) { 149 // get the values from the first one and check the others 150 _start = ranges.front()._start; 151 _end = ranges.front()._end; 152 intlvHighBit = ranges.front().intlvHighBit; 153 xorHighBit = ranges.front().xorHighBit; 154 intlvBits = ranges.front().intlvBits; 155 156 if (ranges.size() != (ULL(1) << intlvBits)) 157 fatal("Got %d ranges spanning %d interleaving bits\n", 158 ranges.size(), intlvBits); 159 160 uint8_t match = 0; 161 for (const auto& r : ranges) { 162 if (!mergesWith(r)) 163 fatal("Can only merge ranges with the same start, end " 164 "and interleaving bits\n"); 165 166 if (r.intlvMatch != match) 167 fatal("Expected interleave match %d but got %d when " 168 "merging\n", match, r.intlvMatch); 169 ++match; 170 } 171 172 // our range is complete and we can turn this into a 173 // non-interleaved range 174 intlvHighBit = 0; 175 xorHighBit = 0; 176 intlvBits = 0; 177 } 178 } 179 180 /** 181 * Determine if the range is interleaved or not. 182 * 183 * @return true if interleaved 184 */ 185 bool interleaved() const { return intlvBits != 0; } 186 187 /** 188 * Determine if the range interleaving is hashed or not. 189 */ 190 bool hashed() const { return interleaved() && xorHighBit != 0; } 191 192 /** 193 * Determing the interleaving granularity of the range. 194 * 195 * @return The size of the regions created by the interleaving bits 196 */ 197 uint64_t granularity() const 198 {
|
198 return ULL(1) << (intlvHighBit - intlvBits + 1);
| 199 if (interleaved()) { 200 const uint8_t intlv_low_bit = intlvHighBit - intlvBits + 1; 201 if (hashed()) { 202 const uint8_t xor_low_bit = xorHighBit - intlvBits + 1; 203 return ULL(1) << std::min(intlv_low_bit, xor_low_bit); 204 } else { 205 return ULL(1) << intlv_low_bit; 206 } 207 } else { 208 return size(); 209 }
|
199 } 200 201 /** 202 * Determine the number of interleaved address stripes this range 203 * is part of. 204 * 205 * @return The number of stripes spanned by the interleaving bits 206 */ 207 uint32_t stripes() const { return ULL(1) << intlvBits; } 208 209 /** 210 * Get the size of the address range. For a case where 211 * interleaving is used we make the simplifying assumption that 212 * the size is a divisible by the size of the interleaving slice. 213 */ 214 Addr size() const 215 { 216 return (_end - _start + 1) >> intlvBits; 217 } 218 219 /** 220 * Determine if the range is valid. 221 */ 222 bool valid() const { return _start <= _end; } 223 224 /** 225 * Get the start address of the range. 226 */ 227 Addr start() const { return _start; } 228 229 /** 230 * Get the end address of the range. 231 */ 232 Addr end() const { return _end; } 233 234 /** 235 * Get a string representation of the range. This could 236 * alternatively be implemented as a operator<<, but at the moment 237 * that seems like overkill. 238 */ 239 std::string to_string() const 240 { 241 if (interleaved()) { 242 if (hashed()) { 243 return csprintf("[%#llx : %#llx], [%d : %d] XOR [%d : %d] = %d", 244 _start, _end, 245 intlvHighBit, intlvHighBit - intlvBits + 1, 246 xorHighBit, xorHighBit - intlvBits + 1, 247 intlvMatch); 248 } else { 249 return csprintf("[%#llx : %#llx], [%d : %d] = %d", 250 _start, _end, 251 intlvHighBit, intlvHighBit - intlvBits + 1, 252 intlvMatch); 253 } 254 } else { 255 return csprintf("[%#llx : %#llx]", _start, _end); 256 } 257 } 258 259 /** 260 * Determine if another range merges with the current one, i.e. if 261 * they are part of the same contigous range and have the same 262 * interleaving bits. 263 * 264 * @param r Range to evaluate merging with 265 * @return true if the two ranges would merge 266 */ 267 bool mergesWith(const AddrRange& r) const 268 { 269 return r._start == _start && r._end == _end && 270 r.intlvHighBit == intlvHighBit && 271 r.xorHighBit == xorHighBit && 272 r.intlvBits == intlvBits; 273 } 274 275 /** 276 * Determine if another range intersects this one, i.e. if there 277 * is an address that is both in this range and the other 278 * range. No check is made to ensure either range is valid. 279 * 280 * @param r Range to intersect with 281 * @return true if the intersection of the two ranges is not empty 282 */ 283 bool intersects(const AddrRange& r) const 284 { 285 if (_start > r._end || _end < r._start) 286 // start with the simple case of no overlap at all, 287 // applicable even if we have interleaved ranges 288 return false; 289 else if (!interleaved() && !r.interleaved()) 290 // if neither range is interleaved, we are done 291 return true; 292 293 // now it gets complicated, focus on the cases we care about 294 if (r.size() == 1) 295 // keep it simple and check if the address is within 296 // this range 297 return contains(r.start()); 298 else if (mergesWith(r)) 299 // restrict the check to ranges that belong to the 300 // same chunk 301 return intlvMatch == r.intlvMatch; 302 else 303 panic("Cannot test intersection of %s and %s\n", 304 to_string(), r.to_string()); 305 } 306 307 /** 308 * Determine if this range is a subset of another range, i.e. if 309 * every address in this range is also in the other range. No 310 * check is made to ensure either range is valid. 311 * 312 * @param r Range to compare with 313 * @return true if the this range is a subset of the other one 314 */ 315 bool isSubset(const AddrRange& r) const 316 { 317 if (interleaved()) 318 panic("Cannot test subset of interleaved range %s\n", to_string());
| 210 } 211 212 /** 213 * Determine the number of interleaved address stripes this range 214 * is part of. 215 * 216 * @return The number of stripes spanned by the interleaving bits 217 */ 218 uint32_t stripes() const { return ULL(1) << intlvBits; } 219 220 /** 221 * Get the size of the address range. For a case where 222 * interleaving is used we make the simplifying assumption that 223 * the size is a divisible by the size of the interleaving slice. 224 */ 225 Addr size() const 226 { 227 return (_end - _start + 1) >> intlvBits; 228 } 229 230 /** 231 * Determine if the range is valid. 232 */ 233 bool valid() const { return _start <= _end; } 234 235 /** 236 * Get the start address of the range. 237 */ 238 Addr start() const { return _start; } 239 240 /** 241 * Get the end address of the range. 242 */ 243 Addr end() const { return _end; } 244 245 /** 246 * Get a string representation of the range. This could 247 * alternatively be implemented as a operator<<, but at the moment 248 * that seems like overkill. 249 */ 250 std::string to_string() const 251 { 252 if (interleaved()) { 253 if (hashed()) { 254 return csprintf("[%#llx : %#llx], [%d : %d] XOR [%d : %d] = %d", 255 _start, _end, 256 intlvHighBit, intlvHighBit - intlvBits + 1, 257 xorHighBit, xorHighBit - intlvBits + 1, 258 intlvMatch); 259 } else { 260 return csprintf("[%#llx : %#llx], [%d : %d] = %d", 261 _start, _end, 262 intlvHighBit, intlvHighBit - intlvBits + 1, 263 intlvMatch); 264 } 265 } else { 266 return csprintf("[%#llx : %#llx]", _start, _end); 267 } 268 } 269 270 /** 271 * Determine if another range merges with the current one, i.e. if 272 * they are part of the same contigous range and have the same 273 * interleaving bits. 274 * 275 * @param r Range to evaluate merging with 276 * @return true if the two ranges would merge 277 */ 278 bool mergesWith(const AddrRange& r) const 279 { 280 return r._start == _start && r._end == _end && 281 r.intlvHighBit == intlvHighBit && 282 r.xorHighBit == xorHighBit && 283 r.intlvBits == intlvBits; 284 } 285 286 /** 287 * Determine if another range intersects this one, i.e. if there 288 * is an address that is both in this range and the other 289 * range. No check is made to ensure either range is valid. 290 * 291 * @param r Range to intersect with 292 * @return true if the intersection of the two ranges is not empty 293 */ 294 bool intersects(const AddrRange& r) const 295 { 296 if (_start > r._end || _end < r._start) 297 // start with the simple case of no overlap at all, 298 // applicable even if we have interleaved ranges 299 return false; 300 else if (!interleaved() && !r.interleaved()) 301 // if neither range is interleaved, we are done 302 return true; 303 304 // now it gets complicated, focus on the cases we care about 305 if (r.size() == 1) 306 // keep it simple and check if the address is within 307 // this range 308 return contains(r.start()); 309 else if (mergesWith(r)) 310 // restrict the check to ranges that belong to the 311 // same chunk 312 return intlvMatch == r.intlvMatch; 313 else 314 panic("Cannot test intersection of %s and %s\n", 315 to_string(), r.to_string()); 316 } 317 318 /** 319 * Determine if this range is a subset of another range, i.e. if 320 * every address in this range is also in the other range. No 321 * check is made to ensure either range is valid. 322 * 323 * @param r Range to compare with 324 * @return true if the this range is a subset of the other one 325 */ 326 bool isSubset(const AddrRange& r) const 327 { 328 if (interleaved()) 329 panic("Cannot test subset of interleaved range %s\n", to_string());
|
319 return _start >= r._start && _end <= r._end;
| 330 331 // This address range is not interleaved and therefore it 332 // suffices to check the upper bound, the lower bound and 333 // whether it would fit in a continuous segment of the input 334 // addr range. 335 if (r.interleaved()) { 336 return r.contains(_start) && r.contains(_end) && 337 size() <= r.granularity(); 338 } else { 339 return _start >= r._start && _end <= r._end; 340 }
|
320 } 321 322 /** 323 * Determine if the range contains an address. 324 * 325 * @param a Address to compare with 326 * @return true if the address is in the range 327 */ 328 bool contains(const Addr& a) const 329 { 330 // check if the address is in the range and if there is either 331 // no interleaving, or with interleaving also if the selected 332 // bits from the address match the interleaving value 333 bool in_range = a >= _start && a <= _end; 334 if (!interleaved()) { 335 return in_range; 336 } else if (in_range) { 337 if (!hashed()) { 338 return bits(a, intlvHighBit, intlvHighBit - intlvBits + 1) == 339 intlvMatch; 340 } else { 341 return (bits(a, intlvHighBit, intlvHighBit - intlvBits + 1) ^ 342 bits(a, xorHighBit, xorHighBit - intlvBits + 1)) == 343 intlvMatch; 344 } 345 } 346 return false; 347 } 348 349 /** 350 * Remove the interleaving bits from an input address. 351 * 352 * This function returns a new address that doesn't have the bits 353 * that are use to determine which of the interleaved ranges it 354 * belongs to. 355 * 356 * e.g., if the input address is: 357 * ------------------------------- 358 * | prefix | intlvBits | suffix | 359 * ------------------------------- 360 * this function will return: 361 * ------------------------------- 362 * | 0 | prefix | suffix | 363 * ------------------------------- 364 * 365 * @param the input address 366 * @return the address without the interleaved bits 367 */ 368 inline Addr removeIntlvBits(const Addr &a) const 369 { 370 const auto intlv_low_bit = intlvHighBit - intlvBits + 1; 371 return insertBits(a >> intlvBits, intlv_low_bit - 1, 0, a); 372 } 373 374 /** 375 * Determine the offset of an address within the range. 376 * 377 * This function returns the offset of the given address from the 378 * starting address discarding any bits that are used for 379 * interleaving. This way we can convert the input address to a 380 * new unique address in a continuous range that starts from 0. 381 * 382 * @param the input address 383 * @return the flat offset in the address range 384 */ 385 Addr getOffset(const Addr& a) const 386 { 387 bool in_range = a >= _start && a <= _end; 388 if (!in_range) { 389 return MaxAddr; 390 } 391 if (interleaved()) { 392 return removeIntlvBits(a) - removeIntlvBits(_start); 393 } else { 394 return a - _start; 395 } 396 } 397 398 /** 399 * Less-than operator used to turn an STL map into a binary search 400 * tree of non-overlapping address ranges. 401 * 402 * @param r Range to compare with 403 * @return true if the start address is less than that of the other range 404 */ 405 bool operator<(const AddrRange& r) const 406 { 407 if (_start != r._start) 408 return _start < r._start; 409 else 410 // for now assume that the end is also the same, and that 411 // we are looking at the same interleaving bits 412 return intlvMatch < r.intlvMatch; 413 } 414 415 bool operator==(const AddrRange& r) const 416 { 417 if (_start != r._start) return false; 418 if (_end != r._end) return false; 419 if (intlvBits != r.intlvBits) return false; 420 if (intlvBits != 0) { 421 if (intlvHighBit != r.intlvHighBit) return false; 422 if (intlvMatch != r.intlvMatch) return false; 423 } 424 return true; 425 } 426 427 bool operator!=(const AddrRange& r) const 428 { 429 return !(*this == r); 430 } 431}; 432 433/** 434 * Convenience typedef for a collection of address ranges 435 */ 436typedef std::list<AddrRange> AddrRangeList; 437 438inline AddrRange 439RangeEx(Addr start, Addr end) 440{ return AddrRange(start, end - 1); } 441 442inline AddrRange 443RangeIn(Addr start, Addr end) 444{ return AddrRange(start, end); } 445 446inline AddrRange 447RangeSize(Addr start, Addr size) 448{ return AddrRange(start, start + size - 1); } 449 450#endif // __BASE_ADDR_RANGE_HH__
| 341 } 342 343 /** 344 * Determine if the range contains an address. 345 * 346 * @param a Address to compare with 347 * @return true if the address is in the range 348 */ 349 bool contains(const Addr& a) const 350 { 351 // check if the address is in the range and if there is either 352 // no interleaving, or with interleaving also if the selected 353 // bits from the address match the interleaving value 354 bool in_range = a >= _start && a <= _end; 355 if (!interleaved()) { 356 return in_range; 357 } else if (in_range) { 358 if (!hashed()) { 359 return bits(a, intlvHighBit, intlvHighBit - intlvBits + 1) == 360 intlvMatch; 361 } else { 362 return (bits(a, intlvHighBit, intlvHighBit - intlvBits + 1) ^ 363 bits(a, xorHighBit, xorHighBit - intlvBits + 1)) == 364 intlvMatch; 365 } 366 } 367 return false; 368 } 369 370 /** 371 * Remove the interleaving bits from an input address. 372 * 373 * This function returns a new address that doesn't have the bits 374 * that are use to determine which of the interleaved ranges it 375 * belongs to. 376 * 377 * e.g., if the input address is: 378 * ------------------------------- 379 * | prefix | intlvBits | suffix | 380 * ------------------------------- 381 * this function will return: 382 * ------------------------------- 383 * | 0 | prefix | suffix | 384 * ------------------------------- 385 * 386 * @param the input address 387 * @return the address without the interleaved bits 388 */ 389 inline Addr removeIntlvBits(const Addr &a) const 390 { 391 const auto intlv_low_bit = intlvHighBit - intlvBits + 1; 392 return insertBits(a >> intlvBits, intlv_low_bit - 1, 0, a); 393 } 394 395 /** 396 * Determine the offset of an address within the range. 397 * 398 * This function returns the offset of the given address from the 399 * starting address discarding any bits that are used for 400 * interleaving. This way we can convert the input address to a 401 * new unique address in a continuous range that starts from 0. 402 * 403 * @param the input address 404 * @return the flat offset in the address range 405 */ 406 Addr getOffset(const Addr& a) const 407 { 408 bool in_range = a >= _start && a <= _end; 409 if (!in_range) { 410 return MaxAddr; 411 } 412 if (interleaved()) { 413 return removeIntlvBits(a) - removeIntlvBits(_start); 414 } else { 415 return a - _start; 416 } 417 } 418 419 /** 420 * Less-than operator used to turn an STL map into a binary search 421 * tree of non-overlapping address ranges. 422 * 423 * @param r Range to compare with 424 * @return true if the start address is less than that of the other range 425 */ 426 bool operator<(const AddrRange& r) const 427 { 428 if (_start != r._start) 429 return _start < r._start; 430 else 431 // for now assume that the end is also the same, and that 432 // we are looking at the same interleaving bits 433 return intlvMatch < r.intlvMatch; 434 } 435 436 bool operator==(const AddrRange& r) const 437 { 438 if (_start != r._start) return false; 439 if (_end != r._end) return false; 440 if (intlvBits != r.intlvBits) return false; 441 if (intlvBits != 0) { 442 if (intlvHighBit != r.intlvHighBit) return false; 443 if (intlvMatch != r.intlvMatch) return false; 444 } 445 return true; 446 } 447 448 bool operator!=(const AddrRange& r) const 449 { 450 return !(*this == r); 451 } 452}; 453 454/** 455 * Convenience typedef for a collection of address ranges 456 */ 457typedef std::list<AddrRange> AddrRangeList; 458 459inline AddrRange 460RangeEx(Addr start, Addr end) 461{ return AddrRange(start, end - 1); } 462 463inline AddrRange 464RangeIn(Addr start, Addr end) 465{ return AddrRange(start, end); } 466 467inline AddrRange 468RangeSize(Addr start, Addr size) 469{ return AddrRange(start, start + size - 1); } 470 471#endif // __BASE_ADDR_RANGE_HH__
|