41 #ifndef __BASE_ADDR_RANGE_HH__ 42 #define __BASE_ADDR_RANGE_HH__ 92 : _start(1), _end(0), intlvMatch(0)
124 uint8_t _intlv_match)
125 : _start(_start), _end(_end), masks(_masks),
126 intlvMatch(_intlv_match)
129 fatal_if(!masks.empty() && _intlv_match >=
ULL(1) << masks.size(),
130 "Match value %d does not fit in %d interleaving bits\n",
131 _intlv_match, masks.size());
159 uint8_t _xor_high_bit, uint8_t _intlv_bits,
160 uint8_t _intlv_match)
161 : _start(_start), _end(_end), masks(_intlv_bits),
162 intlvMatch(_intlv_match)
165 fatal_if(_intlv_bits && _intlv_match >=
ULL(1) << _intlv_bits,
166 "Match value %d does not fit in %d interleaving bits\n",
167 _intlv_match, _intlv_bits);
170 if (_intlv_bits && _xor_high_bit) {
171 if (_xor_high_bit == _intlv_high_bit) {
172 fatal(
"XOR and interleave high bit must be different\n");
173 }
else if (_xor_high_bit > _intlv_high_bit) {
174 if ((_xor_high_bit - _intlv_high_bit) < _intlv_bits)
175 fatal(
"XOR and interleave high bit must be at least " 176 "%d bits apart\n", _intlv_bits);
178 if ((_intlv_high_bit - _xor_high_bit) < _intlv_bits) {
179 fatal(
"Interleave and XOR high bit must be at least " 180 "%d bits apart\n", _intlv_bits);
185 for (
auto i = 0;
i < _intlv_bits;
i++) {
186 uint8_t bit1 = _intlv_high_bit -
i;
189 uint8_t bit2 = _xor_high_bit -
i;
190 mask |= (1
ULL << bit2);
192 masks[_intlv_bits - i - 1] =
mask;
197 : _start(_start), _end(_end), intlvMatch(0)
207 : _start(1), _end(0), intlvMatch(0)
209 if (!ranges.empty()) {
211 _start = ranges.front()._start;
212 _end = ranges.front()._end;
213 masks = ranges.front().masks;
214 intlvMatch = ranges.front().intlvMatch;
218 if (ranges.size() > 1) {
220 if (ranges.size() != (
ULL(1) << masks.size()))
221 fatal(
"Got %d ranges spanning %d interleaving bits\n",
222 ranges.size(), masks.size());
225 for (
const auto&
r : ranges) {
227 fatal(
"Can only merge ranges with the same start, end " 228 "and interleaving bits, %s %s\n",
to_string(),
231 if (
r.intlvMatch != match)
232 fatal(
"Expected interleave match %d but got %d when " 233 "merging\n", match,
r.intlvMatch);
256 auto combined_mask = 0;
257 for (
auto mask: masks) {
258 combined_mask |=
mask;
260 const uint8_t lowest_bit =
ctz64(combined_mask);
261 return ULL(1) << lowest_bit;
282 return (_end - _start) >> masks.size();
309 for (
int i = 0;
i < masks.size();
i++) {
313 auto bit =
ctz64(mask);
314 mask &= ~(1
ULL << bit);
319 return csprintf(
"[%#llx:%#llx]%s", _start, _end, str);
321 return csprintf(
"[%#llx:%#llx]", _start, _end);
335 return r.
_start == _start && r.
_end == _end &&
367 panic(
"Cannot test intersection of %s and %s\n",
382 panic(
"Cannot test subset of interleaved range %s\n",
to_string());
407 bool in_range = a >= _start && a <
_end;
410 for (
int i = 0;
i < masks.size();
i++) {
411 Addr masked = a & masks[
i];
448 int masks_lsb[masks.size()];
449 for (
int i = 0;
i < masks.size();
i++) {
450 masks_lsb[
i] =
ctz64(masks[
i]);
455 std::sort(masks_lsb, masks_lsb + masks.size());
457 for (
int i = 0;
i < masks.size();
i++) {
458 const int intlv_bit = masks_lsb[
i];
478 int masks_lsb[masks.size()];
479 for (
int i = 0;
i < masks.size();
i++) {
480 masks_lsb[
i] =
ctz64(masks[
i]);
484 std::sort(masks_lsb, masks_lsb + masks.size());
485 for (
int i = 0;
i < masks.size();
i++) {
486 const int intlv_bit = masks_lsb[
i];
497 for (
int i = 0;
i < masks.size();
i++) {
498 const int lsb =
ctz64(masks[
i]);
499 const Addr intlv_bit =
bits(intlvMatch, i);
501 const Addr masked = a & masks[
i] & ~(1 << lsb);
522 bool in_range = a >= _start && a <
_end;
552 if (_start != r.
_start)
return false;
553 if (_end != r.
_end)
return false;
554 if (masks != r.
masks)
return false;
562 return !(*
this ==
r);
581 {
return AddrRange(start, start + size); }
583 #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...