45 #ifndef __BASE_ADDR_RANGE_HH__ 46 #define __BASE_ADDR_RANGE_HH__ 96 : _start(1), _end(0), intlvMatch(0)
128 uint8_t _intlv_match)
129 : _start(_start), _end(_end), masks(_masks),
130 intlvMatch(_intlv_match)
133 fatal_if(!masks.empty() && _intlv_match >=
ULL(1) << masks.size(),
134 "Match value %d does not fit in %d interleaving bits\n",
135 _intlv_match, masks.size());
163 uint8_t _xor_high_bit, uint8_t _intlv_bits,
164 uint8_t _intlv_match)
165 : _start(_start), _end(_end), masks(_intlv_bits),
166 intlvMatch(_intlv_match)
169 fatal_if(_intlv_bits && _intlv_match >=
ULL(1) << _intlv_bits,
170 "Match value %d does not fit in %d interleaving bits\n",
171 _intlv_match, _intlv_bits);
174 if (_intlv_bits && _xor_high_bit) {
175 if (_xor_high_bit == _intlv_high_bit) {
176 fatal(
"XOR and interleave high bit must be different\n");
177 }
else if (_xor_high_bit > _intlv_high_bit) {
178 if ((_xor_high_bit - _intlv_high_bit) < _intlv_bits)
179 fatal(
"XOR and interleave high bit must be at least " 180 "%d bits apart\n", _intlv_bits);
182 if ((_intlv_high_bit - _xor_high_bit) < _intlv_bits) {
183 fatal(
"Interleave and XOR high bit must be at least " 184 "%d bits apart\n", _intlv_bits);
189 for (
auto i = 0;
i < _intlv_bits;
i++) {
190 uint8_t bit1 = _intlv_high_bit -
i;
193 uint8_t bit2 = _xor_high_bit -
i;
194 mask |= (1
ULL << bit2);
196 masks[_intlv_bits - i - 1] =
mask;
201 : _start(_start), _end(_end), intlvMatch(0)
211 : _start(1), _end(0), intlvMatch(0)
213 if (!ranges.empty()) {
215 _start = ranges.front()._start;
216 _end = ranges.front()._end;
217 masks = ranges.front().masks;
218 intlvMatch = ranges.front().intlvMatch;
222 if (ranges.size() > 1) {
224 if (ranges.size() != (
ULL(1) << masks.size()))
225 fatal(
"Got %d ranges spanning %d interleaving bits\n",
226 ranges.size(), masks.size());
229 for (
const auto&
r : ranges) {
231 fatal(
"Can only merge ranges with the same start, end " 232 "and interleaving bits, %s %s\n",
to_string(),
235 if (
r.intlvMatch != match)
236 fatal(
"Expected interleave match %d but got %d when " 237 "merging\n", match,
r.intlvMatch);
260 auto combined_mask = 0;
261 for (
auto mask: masks) {
262 combined_mask |=
mask;
264 const uint8_t lowest_bit =
ctz64(combined_mask);
265 return ULL(1) << lowest_bit;
286 return (_end - _start) >> masks.size();
313 for (
int i = 0;
i < masks.size();
i++) {
317 auto bit =
ctz64(mask);
318 mask &= ~(1
ULL << bit);
323 return csprintf(
"[%#llx:%#llx]%s", _start, _end, str);
325 return csprintf(
"[%#llx:%#llx]", _start, _end);
339 return r.
_start == _start && r.
_end == _end &&
371 panic(
"Cannot test intersection of %s and %s\n",
386 panic(
"Cannot test subset of interleaved range %s\n",
to_string());
411 bool in_range = a >= _start && a <
_end;
414 for (
int i = 0;
i < masks.size();
i++) {
415 Addr masked = a & masks[
i];
452 int masks_lsb[masks.size()];
453 for (
int i = 0;
i < masks.size();
i++) {
454 masks_lsb[
i] =
ctz64(masks[
i]);
459 std::sort(masks_lsb, masks_lsb + masks.size());
461 for (
int i = 0;
i < masks.size();
i++) {
462 const int intlv_bit = masks_lsb[
i];
482 int masks_lsb[masks.size()];
483 for (
int i = 0;
i < masks.size();
i++) {
484 masks_lsb[
i] =
ctz64(masks[
i]);
488 std::sort(masks_lsb, masks_lsb + masks.size());
489 for (
int i = 0;
i < masks.size();
i++) {
490 const int intlv_bit = masks_lsb[
i];
501 for (
int i = 0;
i < masks.size();
i++) {
502 const int lsb =
ctz64(masks[
i]);
503 const Addr intlv_bit =
bits(intlvMatch, i);
505 const Addr masked = a & masks[
i] & ~(1 << lsb);
526 bool in_range = a >= _start && a <
_end;
556 if (_start != r.
_start)
return false;
557 if (_end != r.
_end)
return false;
558 if (masks != r.
masks)
return false;
566 return !(*
this ==
r);
585 {
return AddrRange(start, start + size); }
587 #endif // __BASE_ADDR_RANGE_HH__ #define panic(...)
This implements a cprintf based panic() function.
AddrRange RangeSize(Addr start, Addr size)
int ctz64(uint64_t value)
Count trailing zeros in a 64-bit value.
#define fatal(...)
This implements a cprintf based fatal() function.
bool operator!=(const AddrRange &r) const
std::list< AddrRange > AddrRangeList
Convenience typedef for a collection of address ranges.
uint64_t granularity() const
Determing the interleaving granularity of the range.
bool contains(const Addr &a) const
Determine if the range contains an address.
bool isSubset(const AddrRange &r) const
Determine if this range is a subset of another range, i.e.
std::vector< Addr > masks
Each mask determines the bits we need to xor to get one bit of sel.
uint8_t intlvMatch
The value to compare sel with.
Addr removeIntlvBits(Addr a) const
Remove the interleaving bits from an input address.
uint32_t stripes() const
Determine the number of interleaved address stripes this range is part of.
int popCount(uint64_t val)
Returns the number of set ones in the provided value.
bool intersects(const AddrRange &r) const
Determine if another range intersects this one, i.e.
bool valid() const
Determine if the range is valid.
Addr _start
Private fields for the start and end of the range _start is the beginning of the range (inclusive)...
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
AddrRange(const std::vector< AddrRange > &ranges)
Create an address range by merging a collection of interleaved ranges.
std::string csprintf(const char *format, const Args &...args)
Addr end() const
Get the end address of the range.
Addr addIntlvBits(Addr a) const
This method adds the interleaving bits removed by removeIntlvBits.
bool operator<(const AddrRange &r) const
Less-than operator used to turn an STL map into a binary search tree of non-overlapping address range...
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
T insertBits(T val, int first, int last, B bit_val)
Returns val with bits first to last set to the LSBs of bit_val.
AddrRange RangeIn(Addr start, Addr end)
AddrRange(Addr _start, Addr _end)
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
#define ULL(N)
uint64_t constant
AddrRange RangeEx(Addr start, Addr end)
bool operator==(const AddrRange &r) const
bool mergesWith(const AddrRange &r) const
Determine if another range merges with the current one, i.e.
bool interleaved() const
Determine if the range is interleaved or not.
AddrRange(Addr _start, Addr _end, const std::vector< Addr > &_masks, uint8_t _intlv_match)
Construct an address range.
AddrRange(Addr _start, Addr _end, uint8_t _intlv_high_bit, uint8_t _xor_high_bit, uint8_t _intlv_bits, uint8_t _intlv_match)
Legacy constructor of AddrRange.
Addr start() const
Get the start address of the range.
Addr getOffset(const Addr &a) const
Determine the offset of an address within the range.
Addr size() const
Get the size of the address range.
std::string to_string() const
Get a string representation of the range.
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...