addr_range.hh (9405:c0a0593510db) addr_range.hh (9411:22e15f9c3fda)
1/*
2 * Copyright (c) 2012 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

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

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
1/*
2 * Copyright (c) 2012 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

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

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 "base/bitfield.hh"
48#include "base/cprintf.hh"
49#include "base/cprintf.hh"
50#include "base/misc.hh"
49#include "base/types.hh"
50
51class AddrRange
52{
53
54 private:
55
51#include "base/types.hh"
52
53class AddrRange
54{
55
56 private:
57
56 /// Private fields for the start and end of the range. In the
57 /// future, these will be extended with interleaving functionality
58 /// and hence should never be manipulated directly.
58 /// Private fields for the start and end of the range
59 Addr _start;
60 Addr _end;
61
59 Addr _start;
60 Addr _end;
61
62 /// The high bit of the slice that is used for interleaving
63 uint8_t intlvHighBit;
64
65 /// The number of bits used for interleaving, set to 0 to disable
66 uint8_t intlvBits;
67
68 /// The value to compare the slice addr[high:(high - bits + 1)]
69 /// with.
70 uint8_t intlvMatch;
71
62 public:
63
64 AddrRange()
72 public:
73
74 AddrRange()
65 : _start(1), _end(0)
75 : _start(1), _end(0), intlvHighBit(0), intlvBits(0), intlvMatch(0)
66 {}
67
76 {}
77
78 AddrRange(Addr _start, Addr _end, uint8_t _intlv_high_bit,
79 uint8_t _intlv_bits, uint8_t _intlv_match)
80 : _start(_start), _end(_end), intlvHighBit(_intlv_high_bit),
81 intlvBits(_intlv_bits), intlvMatch(_intlv_match)
82 {}
83
68 AddrRange(Addr _start, Addr _end)
84 AddrRange(Addr _start, Addr _end)
69 : _start(_start), _end(_end)
85 : _start(_start), _end(_end), intlvHighBit(0), intlvBits(0),
86 intlvMatch(0)
70 {}
71
72 /**
87 {}
88
89 /**
90 * Determine if the range is interleaved or not.
91 *
92 * @return true if interleaved
93 */
94 bool interleaved() const { return intlvBits != 0; }
95
96 /**
97 * Determing the interleaving granularity of the range.
98 *
99 * @return The size of the regions created by the interleaving bits
100 */
101 uint64_t granularity() const { return ULL(1) << intlvHighBit; }
102
103 /**
104 * Determine the number of interleaved address stripes this range
105 * is part of.
106 *
107 * @return The number of stripes spanned by the interleaving bits
108 */
109 uint32_t stripes() const { return ULL(1) << intlvBits; }
110
111 /**
73 * Get the size of the address range. For a case where
112 * Get the size of the address range. For a case where
74 * interleaving is used this should probably cause a panic.
113 * interleaving is used we make the simplifying assumption that
114 * the size is a divisible by the size of the interleaving slice.
75 */
115 */
76 Addr size() const { return _end - _start + 1; }
116 Addr size() const
117 {
118 return (_end - _start + 1) >> intlvBits;
119 }
77
78 /**
79 * Determine if the range is valid.
80 */
81 bool valid() const { return _start < _end; }
82
83 /**
84 * Get the start address of the range.
85 */
86 Addr start() const { return _start; }
87
88 /**
89 * Get a string representation of the range. This could
90 * alternatively be implemented as a operator<<, but at the moment
91 * that seems like overkill.
92 */
93 std::string to_string() const
94 {
120
121 /**
122 * Determine if the range is valid.
123 */
124 bool valid() const { return _start < _end; }
125
126 /**
127 * Get the start address of the range.
128 */
129 Addr start() const { return _start; }
130
131 /**
132 * Get a string representation of the range. This could
133 * alternatively be implemented as a operator<<, but at the moment
134 * that seems like overkill.
135 */
136 std::string to_string() const
137 {
95 return csprintf("[%#llx : %#llx]", _start, _end);
138 if (interleaved())
139 return csprintf("[%#llx : %#llx], [%d : %d] = %d", _start, _end,
140 intlvHighBit, intlvHighBit - intlvBits + 1,
141 intlvMatch);
142 else
143 return csprintf("[%#llx : %#llx]", _start, _end);
96 }
97
98 /**
144 }
145
146 /**
147 * Determine if another range merges with the current one, i.e. if
148 * they are part of the same contigous range and have the same
149 * interleaving bits.
150 *
151 * @param r Range to evaluate merging with
152 * @return true if the two ranges would merge
153 */
154 bool mergesWith(const AddrRange& r) const
155 {
156 return r._start == _start && r._end == _end &&
157 r.intlvHighBit == intlvHighBit &&
158 r.intlvBits == intlvBits;
159 }
160
161 /**
99 * Determine if another range intersects this one, i.e. if there
100 * is an address that is both in this range and the other
101 * range. No check is made to ensure either range is valid.
102 *
103 * @param r Range to intersect with
104 * @return true if the intersection of the two ranges is not empty
105 */
106 bool intersects(const AddrRange& r) const
107 {
162 * Determine if another range intersects this one, i.e. if there
163 * is an address that is both in this range and the other
164 * range. No check is made to ensure either range is valid.
165 *
166 * @param r Range to intersect with
167 * @return true if the intersection of the two ranges is not empty
168 */
169 bool intersects(const AddrRange& r) const
170 {
108 return _start <= r._end && _end >= r._start;
171 if (!interleaved()) {
172 return _start <= r._end && _end >= r._start;
173 }
174
175 // the current range is interleaved, split the check up in
176 // three cases
177 if (r.size() == 1)
178 // keep it simple and check if the address is within
179 // this range
180 return contains(r.start());
181 else if (!r.interleaved())
182 // be conservative and ignore the interleaving
183 return _start <= r._end && _end >= r._start;
184 else if (mergesWith(r))
185 // restrict the check to ranges that belong to the
186 // same chunk
187 return intlvMatch == r.intlvMatch;
188 else
189 panic("Cannot test intersection of interleaved range %s\n",
190 to_string());
109 }
110
111 /**
112 * Determine if this range is a subset of another range, i.e. if
113 * every address in this range is also in the other range. No
114 * check is made to ensure either range is valid.
115 *
116 * @param r Range to compare with
117 * @return true if the this range is a subset of the other one
118 */
119 bool isSubset(const AddrRange& r) const
120 {
191 }
192
193 /**
194 * Determine if this range is a subset of another range, i.e. if
195 * every address in this range is also in the other range. No
196 * check is made to ensure either range is valid.
197 *
198 * @param r Range to compare with
199 * @return true if the this range is a subset of the other one
200 */
201 bool isSubset(const AddrRange& r) const
202 {
203 if (interleaved())
204 panic("Cannot test subset of interleaved range %s\n", to_string());
121 return _start >= r._start && _end <= r._end;
122 }
123
124 /**
125 * Determine if the range contains an address.
126 *
127 * @param a Address to compare with
128 * @return true if the address is in the range
129 */
130 bool contains(const Addr& a) const
131 {
205 return _start >= r._start && _end <= r._end;
206 }
207
208 /**
209 * Determine if the range contains an address.
210 *
211 * @param a Address to compare with
212 * @return true if the address is in the range
213 */
214 bool contains(const Addr& a) const
215 {
132 return a >= _start && a <= _end;
216 // check if the address is in the range and if there is either
217 // no interleaving, or with interleaving also if the selected
218 // bits from the address match the interleaving value
219 return a >= _start && a <= _end &&
220 (interleaved() ||
221 (bits(a, intlvHighBit, intlvHighBit - intlvBits + 1) ==
222 intlvMatch));
133 }
134
135/**
136 * Keep the operators away from SWIG.
137 */
138#ifndef SWIG
139
140 /**
141 * Less-than operator used to turn an STL map into a binary search
142 * tree of non-overlapping address ranges.
143 *
144 * @param r Range to compare with
145 * @return true if the start address is less than that of the other range
146 */
147 bool operator<(const AddrRange& r) const
148 {
223 }
224
225/**
226 * Keep the operators away from SWIG.
227 */
228#ifndef SWIG
229
230 /**
231 * Less-than operator used to turn an STL map into a binary search
232 * tree of non-overlapping address ranges.
233 *
234 * @param r Range to compare with
235 * @return true if the start address is less than that of the other range
236 */
237 bool operator<(const AddrRange& r) const
238 {
149 return _start < r._start;
239 if (_start != r._start)
240 return _start < r._start;
241 else
242 // for now assume that the end is also the same, and that
243 // we are looking at the same interleaving bits
244 return intlvMatch < r.intlvMatch;
150 }
151
152#endif // SWIG
153};
154
155inline AddrRange
156RangeEx(Addr start, Addr end)
157{ return AddrRange(start, end - 1); }
158
159inline AddrRange
160RangeIn(Addr start, Addr end)
161{ return AddrRange(start, end); }
162
163inline AddrRange
164RangeSize(Addr start, Addr size)
165{ return AddrRange(start, start + size - 1); }
166
167#endif // __BASE_ADDR_RANGE_HH__
245 }
246
247#endif // SWIG
248};
249
250inline AddrRange
251RangeEx(Addr start, Addr end)
252{ return AddrRange(start, end - 1); }
253
254inline AddrRange
255RangeIn(Addr start, Addr end)
256{ return AddrRange(start, end); }
257
258inline AddrRange
259RangeSize(Addr start, Addr size)
260{ return AddrRange(start, start + size - 1); }
261
262#endif // __BASE_ADDR_RANGE_HH__