addr_range.hh (10481:59fb5779ec6e) addr_range.hh (10676:f6c168692b20)
1/*
1/*
2 * Copyright (c) 2012 ARM Limited
2 * Copyright (c) 2012, 2014 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

--- 37 unchanged lines hidden (view full) ---

48#include <list>
49#include <vector>
50
51#include "base/bitfield.hh"
52#include "base/cprintf.hh"
53#include "base/misc.hh"
54#include "base/types.hh"
55
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

--- 37 unchanged lines hidden (view full) ---

48#include <list>
49#include <vector>
50
51#include "base/bitfield.hh"
52#include "base/cprintf.hh"
53#include "base/misc.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 */
56class AddrRange
57{
58
59 private:
60
61 /// Private fields for the start and end of the range
62 /// Both _start and _end are part of the range.
63 Addr _start;
64 Addr _end;
65
66 /// The high bit of the slice that is used for interleaving
67 uint8_t intlvHighBit;
68
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
69 /// The number of bits used for interleaving, set to 0 to disable
70 uint8_t intlvBits;
71
72 /// The value to compare the slice addr[high:(high - bits + 1)]
73 /// with.
74 uint8_t intlvMatch;
75
76 public:
77
78 AddrRange()
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()
79 : _start(1), _end(0), intlvHighBit(0), intlvBits(0), intlvMatch(0)
99 : _start(1), _end(0), intlvHighBit(0), xorHighBit(0), intlvBits(0),
100 intlvMatch(0)
80 {}
81
82 AddrRange(Addr _start, Addr _end, uint8_t _intlv_high_bit,
101 {}
102
103 AddrRange(Addr _start, Addr _end, uint8_t _intlv_high_bit,
83 uint8_t _intlv_bits, uint8_t _intlv_match)
104 uint8_t _xor_high_bit, uint8_t _intlv_bits,
105 uint8_t _intlv_match)
84 : _start(_start), _end(_end), intlvHighBit(_intlv_high_bit),
106 : _start(_start), _end(_end), intlvHighBit(_intlv_high_bit),
85 intlvBits(_intlv_bits), intlvMatch(_intlv_match)
86 {}
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);
87
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
88 AddrRange(Addr _start, Addr _end)
132 AddrRange(Addr _start, Addr _end)
89 : _start(_start), _end(_end), intlvHighBit(0), intlvBits(0),
90 intlvMatch(0)
133 : _start(_start), _end(_end), intlvHighBit(0), xorHighBit(0),
134 intlvBits(0), intlvMatch(0)
91 {}
92
93 /**
94 * Create an address range by merging a collection of interleaved
95 * ranges.
96 *
97 * @param ranges Interleaved ranges to be merged
98 */
99 AddrRange(const std::vector<AddrRange>& ranges)
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)
100 : _start(1), _end(0), intlvHighBit(0), intlvBits(0), intlvMatch(0)
144 : _start(1), _end(0), intlvHighBit(0), xorHighBit(0), intlvBits(0),
145 intlvMatch(0)
101 {
102 if (!ranges.empty()) {
103 // get the values from the first one and check the others
104 _start = ranges.front()._start;
105 _end = ranges.front()._end;
106 intlvHighBit = ranges.front().intlvHighBit;
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;
107 intlvBits = ranges.front().intlvBits;
108
109 if (ranges.size() != (ULL(1) << intlvBits))
110 fatal("Got %d ranges spanning %d interleaving bits\n",
111 ranges.size(), intlvBits);
112
113 uint8_t match = 0;
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;
114 for (std::vector<AddrRange>::const_iterator r = ranges.begin();
115 r != ranges.end(); ++r) {
116 if (!mergesWith(*r))
160 for (const auto& r : ranges) {
161 if (!mergesWith(r))
117 fatal("Can only merge ranges with the same start, end "
118 "and interleaving bits\n");
119
162 fatal("Can only merge ranges with the same start, end "
163 "and interleaving bits\n");
164
120 if (r->intlvMatch != match)
165 if (r.intlvMatch != match)
121 fatal("Expected interleave match %d but got %d when "
166 fatal("Expected interleave match %d but got %d when "
122 "merging\n", match, r->intlvMatch);
167 "merging\n", match, r.intlvMatch);
123 ++match;
124 }
125
126 // our range is complete and we can turn this into a
127 // non-interleaved range
128 intlvHighBit = 0;
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;
129 intlvBits = 0;
130 }
131 }
132
133 /**
134 * Determine if the range is interleaved or not.
135 *
136 * @return true if interleaved
137 */
138 bool interleaved() const { return intlvBits != 0; }
139
140 /**
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 /**
141 * Determing the interleaving granularity of the range.
142 *
143 * @return The size of the regions created by the interleaving bits
144 */
145 uint64_t granularity() const
146 {
147 return ULL(1) << (intlvHighBit - intlvBits + 1);
148 }

--- 28 unchanged lines hidden (view full) ---

177
178 /**
179 * Get a string representation of the range. This could
180 * alternatively be implemented as a operator<<, but at the moment
181 * that seems like overkill.
182 */
183 std::string to_string() const
184 {
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 {
198 return ULL(1) << (intlvHighBit - intlvBits + 1);
199 }

--- 28 unchanged lines hidden (view full) ---

228
229 /**
230 * Get a string representation of the range. This could
231 * alternatively be implemented as a operator<<, but at the moment
232 * that seems like overkill.
233 */
234 std::string to_string() const
235 {
185 if (interleaved())
186 return csprintf("[%#llx : %#llx], [%d : %d] = %d", _start, _end,
187 intlvHighBit, intlvHighBit - intlvBits + 1,
188 intlvMatch);
189 else
236 if (interleaved()) {
237 if (hashed()) {
238 return csprintf("[%#llx : %#llx], [%d : %d] XOR [%d : %d] = %d",
239 _start, _end,
240 intlvHighBit, intlvHighBit - intlvBits + 1,
241 xorHighBit, xorHighBit - intlvBits + 1,
242 intlvMatch);
243 } else {
244 return csprintf("[%#llx : %#llx], [%d : %d] = %d",
245 _start, _end,
246 intlvHighBit, intlvHighBit - intlvBits + 1,
247 intlvMatch);
248 }
249 } else {
190 return csprintf("[%#llx : %#llx]", _start, _end);
250 return csprintf("[%#llx : %#llx]", _start, _end);
251 }
191 }
192
193 /**
194 * Determine if another range merges with the current one, i.e. if
195 * they are part of the same contigous range and have the same
196 * interleaving bits.
197 *
198 * @param r Range to evaluate merging with
199 * @return true if the two ranges would merge
200 */
201 bool mergesWith(const AddrRange& r) const
202 {
203 return r._start == _start && r._end == _end &&
204 r.intlvHighBit == intlvHighBit &&
252 }
253
254 /**
255 * Determine if another range merges with the current one, i.e. if
256 * they are part of the same contigous range and have the same
257 * interleaving bits.
258 *
259 * @param r Range to evaluate merging with
260 * @return true if the two ranges would merge
261 */
262 bool mergesWith(const AddrRange& r) const
263 {
264 return r._start == _start && r._end == _end &&
265 r.intlvHighBit == intlvHighBit &&
266 r.xorHighBit == xorHighBit &&
205 r.intlvBits == intlvBits;
206 }
207
208 /**
209 * Determine if another range intersects this one, i.e. if there
210 * is an address that is both in this range and the other
211 * range. No check is made to ensure either range is valid.
212 *

--- 45 unchanged lines hidden (view full) ---

258 * @param a Address to compare with
259 * @return true if the address is in the range
260 */
261 bool contains(const Addr& a) const
262 {
263 // check if the address is in the range and if there is either
264 // no interleaving, or with interleaving also if the selected
265 // bits from the address match the interleaving value
267 r.intlvBits == intlvBits;
268 }
269
270 /**
271 * Determine if another range intersects this one, i.e. if there
272 * is an address that is both in this range and the other
273 * range. No check is made to ensure either range is valid.
274 *

--- 45 unchanged lines hidden (view full) ---

320 * @param a Address to compare with
321 * @return true if the address is in the range
322 */
323 bool contains(const Addr& a) const
324 {
325 // check if the address is in the range and if there is either
326 // no interleaving, or with interleaving also if the selected
327 // bits from the address match the interleaving value
266 return a >= _start && a <= _end &&
267 (!interleaved() ||
268 (bits(a, intlvHighBit, intlvHighBit - intlvBits + 1) ==
269 intlvMatch));
328 bool in_range = a >= _start && a <= _end;
329 if (!interleaved()) {
330 return in_range;
331 } else if (in_range) {
332 if (!hashed()) {
333 return bits(a, intlvHighBit, intlvHighBit - intlvBits + 1) ==
334 intlvMatch;
335 } else {
336 return (bits(a, intlvHighBit, intlvHighBit - intlvBits + 1) ^
337 bits(a, xorHighBit, xorHighBit - intlvBits + 1)) ==
338 intlvMatch;
339 }
340 }
341 return false;
270 }
271
272/**
273 * Keep the operators away from SWIG.
274 */
275#ifndef SWIG
276
277 /**

--- 37 unchanged lines hidden ---
342 }
343
344/**
345 * Keep the operators away from SWIG.
346 */
347#ifndef SWIG
348
349 /**

--- 37 unchanged lines hidden ---