2c2
< * Copyright (c) 2012 ARM Limited
---
> * Copyright (c) 2012, 2014 ARM Limited
55a56,71
> /**
> * The AddrRange class encapsulates an address range, and supports a
> * number of tests to check if two ranges intersect, if a range
> * contains a specific address etc. Besides a basic range, the
> * AddrRange also support interleaved ranges, to stripe across cache
> * banks, or memory controllers. The interleaving is implemented by
> * allowing a number of bits of the address, at an arbitrary bit
> * position, to be used as interleaving bits with an associated
> * matching value. In addition, to prevent uniformly strided address
> * patterns from a very biased interleaving, we also allow basic
> * XOR-based hashing by specifying an additional set of bits to XOR
> * with before matching.
> *
> * The AddrRange is also able to coalesce a number of interleaved
> * ranges to a contiguous range.
> */
68a85,88
> /// The high bit of the slice used to XOR hash the value we match
> /// against, set to 0 to disable.
> uint8_t xorHighBit;
>
79c99,100
< : _start(1), _end(0), intlvHighBit(0), intlvBits(0), intlvMatch(0)
---
> : _start(1), _end(0), intlvHighBit(0), xorHighBit(0), intlvBits(0),
> intlvMatch(0)
83c104,105
< uint8_t _intlv_bits, uint8_t _intlv_match)
---
> uint8_t _xor_high_bit, uint8_t _intlv_bits,
> uint8_t _intlv_match)
85,86c107,113
< intlvBits(_intlv_bits), intlvMatch(_intlv_match)
< {}
---
> xorHighBit(_xor_high_bit), intlvBits(_intlv_bits),
> intlvMatch(_intlv_match)
> {
> // sanity checks
> fatal_if(intlvBits && intlvMatch >= ULL(1) << intlvBits,
> "Match value %d does not fit in %d interleaving bits\n",
> intlvMatch, intlvBits);
87a115,131
> // ignore the XOR bits if not interleaving
> if (intlvBits && xorHighBit) {
> if (xorHighBit == intlvHighBit) {
> fatal("XOR and interleave high bit must be different\n");
> } else if (xorHighBit > intlvHighBit) {
> if ((xorHighBit - intlvHighBit) < intlvBits)
> fatal("XOR and interleave high bit must be at least "
> "%d bits apart\n", intlvBits);
> } else {
> if ((intlvHighBit - xorHighBit) < intlvBits) {
> fatal("Interleave and XOR high bit must be at least "
> "%d bits apart\n", intlvBits);
> }
> }
> }
> }
>
89,90c133,134
< : _start(_start), _end(_end), intlvHighBit(0), intlvBits(0),
< intlvMatch(0)
---
> : _start(_start), _end(_end), intlvHighBit(0), xorHighBit(0),
> intlvBits(0), intlvMatch(0)
100c144,145
< : _start(1), _end(0), intlvHighBit(0), intlvBits(0), intlvMatch(0)
---
> : _start(1), _end(0), intlvHighBit(0), xorHighBit(0), intlvBits(0),
> intlvMatch(0)
106a152
> xorHighBit = ranges.front().xorHighBit;
114,116c160,161
< for (std::vector<AddrRange>::const_iterator r = ranges.begin();
< r != ranges.end(); ++r) {
< if (!mergesWith(*r))
---
> for (const auto& r : ranges) {
> if (!mergesWith(r))
120c165
< if (r->intlvMatch != match)
---
> if (r.intlvMatch != match)
122c167
< "merging\n", match, r->intlvMatch);
---
> "merging\n", match, r.intlvMatch);
128a174
> xorHighBit = 0;
140a187,191
> * Determine if the range interleaving is hashed or not.
> */
> bool hashed() const { return interleaved() && xorHighBit != 0; }
>
> /**
185,189c236,249
< if (interleaved())
< return csprintf("[%#llx : %#llx], [%d : %d] = %d", _start, _end,
< intlvHighBit, intlvHighBit - intlvBits + 1,
< intlvMatch);
< else
---
> if (interleaved()) {
> if (hashed()) {
> return csprintf("[%#llx : %#llx], [%d : %d] XOR [%d : %d] = %d",
> _start, _end,
> intlvHighBit, intlvHighBit - intlvBits + 1,
> xorHighBit, xorHighBit - intlvBits + 1,
> intlvMatch);
> } else {
> return csprintf("[%#llx : %#llx], [%d : %d] = %d",
> _start, _end,
> intlvHighBit, intlvHighBit - intlvBits + 1,
> intlvMatch);
> }
> } else {
190a251
> }
204a266
> r.xorHighBit == xorHighBit &&
266,269c328,341
< return a >= _start && a <= _end &&
< (!interleaved() ||
< (bits(a, intlvHighBit, intlvHighBit - intlvBits + 1) ==
< intlvMatch));
---
> bool in_range = a >= _start && a <= _end;
> if (!interleaved()) {
> return in_range;
> } else if (in_range) {
> if (!hashed()) {
> return bits(a, intlvHighBit, intlvHighBit - intlvBits + 1) ==
> intlvMatch;
> } else {
> return (bits(a, intlvHighBit, intlvHighBit - intlvBits + 1) ^
> bits(a, xorHighBit, xorHighBit - intlvBits + 1)) ==
> intlvMatch;
> }
> }
> return false;