gem5  v22.1.0.0
addr_range.test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 The Regents of the University of California
3  * Copyright (c) 2018-2019, 2021 Arm Limited
4  * All rights reserved
5  *
6  * The license below extends only to copyright in the software and shall
7  * not be construed as granting a license to any other intellectual
8  * property including but not limited to intellectual property relating
9  * to a hardware implementation of the functionality of the software
10  * licensed hereunder. You may use the software subject to the license
11  * terms below provided that you ensure that this notice is replicated
12  * unmodified and in its entirety in all distributions of the software,
13  * modified or unmodified, in source code or in binary form.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions are
17  * met: redistributions of source code must retain the above copyright
18  * notice, this list of conditions and the following disclaimer;
19  * redistributions in binary form must reproduce the above copyright
20  * notice, this list of conditions and the following disclaimer in the
21  * documentation and/or other materials provided with the distribution;
22  * neither the name of the copyright holders nor the names of its
23  * contributors may be used to endorse or promote products derived from
24  * this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 #include <gmock/gmock.h>
40 #include <gtest/gtest.h>
41 
42 #include <cmath>
43 
44 #include "base/addr_range.hh"
45 #include "base/bitfield.hh"
46 
47 using namespace gem5;
48 
49 using testing::ElementsAre;
50 
51 TEST(AddrRangeTest, ValidRange)
52 {
53  AddrRange r;
54  EXPECT_FALSE(r.valid());
55 }
56 
57 /*
58  * This following tests check the behavior of AddrRange when initialized with
59  * a start and end address. The expected behavior is that the first address
60  * within the range will be the start address, and the last address in the
61  * range will be the (end - 1) address.
62  */
63 TEST(AddrRangeTest, EmptyRange)
64 {
65  AddrRange r(0x0, 0x0);
66 
67  /*
68  * Empty ranges are valid.
69  */
70  EXPECT_TRUE(r.valid());
71  EXPECT_EQ(0x0, r.start());
72  EXPECT_EQ(0x0, r.end());
73  EXPECT_EQ(0, r.size());
74 
75  /*
76  * With no masks, granularity equals the size of the range.
77  */
78  EXPECT_EQ(0, r.granularity());
79 
80  /*
81  * With no masks, "interleaved()" returns false.
82  */
83  EXPECT_FALSE(r.interleaved());
84 
85  /*
86  * With no masks, "stripes()" returns 1ULL.
87  */
88  EXPECT_EQ(1ULL, r.stripes());
89  EXPECT_EQ("[0:0]", r.to_string());
90 }
91 
92 TEST(AddrRangeTest, RangeSizeOfOne)
93 {
94  AddrRange r(0x0, 0x1);
95  EXPECT_TRUE(r.valid());
96  EXPECT_EQ(0x0, r.start());
97  EXPECT_EQ(0x1, r.end());
98  EXPECT_EQ(1, r.size());
99  EXPECT_EQ(1, r.granularity());
100  EXPECT_FALSE(r.interleaved());
101  EXPECT_EQ(1ULL, r.stripes());
102  EXPECT_EQ("[0:0x1]", r.to_string());
103 }
104 
105 TEST(AddrRangeTest, Range16Bit)
106 {
107  AddrRange r(0xF000, 0xFFFF);
108  EXPECT_TRUE(r.valid());
109  EXPECT_EQ(0xF000, r.start());
110  EXPECT_EQ(0xFFFF, r.end());
111  EXPECT_EQ(0x0FFF, r.size());
112  EXPECT_EQ(0x0FFF, r.granularity());
113  EXPECT_FALSE(r.interleaved());
114  EXPECT_EQ(1ULL, r.stripes());
115  EXPECT_EQ("[0xf000:0xffff]", r.to_string());
116 }
117 
118 TEST(AddrRangeTest, InvalidRange)
119 {
120  AddrRange r(0x1, 0x0);
121  EXPECT_FALSE(r.valid());
122 }
123 
124 TEST(AddrRangeTest, LessThan)
125 {
126  /*
127  * The less-than override is a bit unintuitive and does not have a
128  * corresponding greater than. It compares the AddrRange.start() values.
129  * If they are equal, the "intlvMatch" values are compared. This is
130  * zero when AddRange is initialized with a just a start and end address.
131  */
132  AddrRange r1(0xF000, 0xFFFF);
133  AddrRange r2(0xF001, 0xFFFF);
134  AddrRange r3(0xF000, 0xFFFF);
135 
136  EXPECT_TRUE(r1 < r2);
137  EXPECT_FALSE(r2 < r1);
138  EXPECT_FALSE(r1 < r3);
139  EXPECT_FALSE(r3 < r1);
140 }
141 
142 TEST(AddrRangeTest, EqualToNotEqualTo)
143 {
144  AddrRange r1(0x1234, 0x5678);
145  AddrRange r2(0x1234, 0x5678);
146  AddrRange r3(0x1234, 0x5679);
147 
148  EXPECT_TRUE(r1 == r2);
149  EXPECT_FALSE(r1 == r3);
150  EXPECT_FALSE(r1 != r2);
151  EXPECT_TRUE(r1 != r3);
152 
153  EXPECT_TRUE(r2 == r1);
154  EXPECT_FALSE(r3 == r1);
155  EXPECT_FALSE(r2 != r1);
156  EXPECT_TRUE(r3 != r1);
157 }
158 
159 TEST(AddrRangeTest, MergesWith)
160 {
161  /*
162  * AddrRange.mergesWith will return true if the start, end, and masks
163  * are the same.
164  */
165  AddrRange r1(0x10, 0x1F);
166  AddrRange r2(0x10, 0x1F);
167 
168  EXPECT_TRUE(r1.mergesWith(r2));
169  EXPECT_TRUE(r2.mergesWith(r1));
170 }
171 
172 TEST(AddrRangeTest, DoesNotMergeWith)
173 {
174  AddrRange r1(0x10, 0x1E);
175  AddrRange r2(0x10, 0x1F);
176 
177  EXPECT_FALSE(r1.mergesWith(r2));
178  EXPECT_FALSE(r2.mergesWith(r1));
179 }
180 
181 TEST(AddrRangeTest, IntersectsCompleteOverlap)
182 {
183  AddrRange r1(0x21, 0x30);
184  AddrRange r2(0x21, 0x30);
185 
186  EXPECT_TRUE(r1.intersects(r2));
187  EXPECT_TRUE(r2.intersects(r1));
188 }
189 
190 TEST(AddrRangeTest, IntersectsAddressWithin)
191 {
192  AddrRange r1(0x0, 0xF);
193  AddrRange r2(0x1, 0xE);
194 
195  EXPECT_TRUE(r1.intersects(r2));
196  EXPECT_TRUE(r2.intersects(r1));
197 }
198 
199 TEST(AddrRangeTest, IntersectsPartialOverlap)
200 {
201  AddrRange r1(0x0F0, 0x0FF);
202  AddrRange r2(0x0F5, 0xF00);
203 
204  EXPECT_TRUE(r1.intersects(r2));
205  EXPECT_TRUE(r2.intersects(r1));
206 }
207 
208 TEST(AddrRangeTest, IntersectsNoOverlap)
209 {
210  AddrRange r1(0x00, 0x10);
211  AddrRange r2(0x11, 0xFF);
212 
213  EXPECT_FALSE(r1.intersects(r2));
214  EXPECT_FALSE(r2.intersects(r1));
215 }
216 
217 TEST(AddrRangeTest, IntersectsFirstLastAddressOverlap)
218 {
219  AddrRange r1(0x0, 0xF);
220  AddrRange r2(0xF, 0xF0);
221 
222  /*
223  * The "end address" is not in the range. Therefore, if
224  * r1.end() == r2.start(), the ranges do not intersect.
225  */
226  EXPECT_FALSE(r1.intersects(r2));
227  EXPECT_FALSE(r2.intersects(r1));
228 }
229 
230 TEST(AddrRangeTest, isSubsetCompleteOverlap)
231 {
232  AddrRange r1(0x10, 0x20);
233  AddrRange r2(0x10, 0x20);
234 
235  EXPECT_TRUE(r1.isSubset(r2));
236  EXPECT_TRUE(r2.isSubset(r1));
237 }
238 
239 TEST(AddrRangeTest, isSubsetNoOverlap)
240 {
241  AddrRange r1(0x10, 0x20);
242  AddrRange r2(0x20, 0x22);
243 
244  EXPECT_FALSE(r1.isSubset(r2));
245  EXPECT_FALSE(r2.isSubset(r1));
246 }
247 
248 TEST(AddrRangeTest, isSubsetTrueSubset)
249 {
250  AddrRange r1(0x10, 0x20);
251  AddrRange r2(0x15, 0x17);
252 
253  EXPECT_TRUE(r2.isSubset(r1));
254  EXPECT_FALSE(r1.isSubset(r2));
255 }
256 
257 TEST(AddrRangeTest, isSubsetPartialSubset)
258 {
259  AddrRange r1(0x20, 0x30);
260  AddrRange r2(0x26, 0xF0);
261 
262  EXPECT_FALSE(r1.isSubset(r2));
263  EXPECT_FALSE(r2.isSubset(r1));
264 }
265 
266 TEST(AddrRangeTest, isSubsetInterleavedCompleteOverlap)
267 {
268  AddrRange r1(0x00, 0x100, {0x40}, 0);
269  AddrRange r2(0x00, 0x40);
270 
271  EXPECT_TRUE(r2.isSubset(r1));
272 }
273 
274 TEST(AddrRangeTest, isSubsetInterleavedNoOverlap)
275 {
276  AddrRange r1(0x00, 0x100, {0x40}, 1);
277  AddrRange r2(0x00, 0x40);
278 
279  EXPECT_FALSE(r2.isSubset(r1));
280 }
281 
282 TEST(AddrRangeTest, isSubsetInterleavedPartialOverlap)
283 {
284  AddrRange r1(0x00, 0x100, {0x40}, 0);
285  AddrRange r2(0x10, 0x50);
286 
287  EXPECT_FALSE(r2.isSubset(r1));
288 }
289 
290 TEST(AddrRangeTest, Contains)
291 {
292  AddrRange r(0xF0, 0xF5);
293 
294  EXPECT_FALSE(r.contains(0xEF));
295  EXPECT_TRUE(r.contains(0xF0));
296  EXPECT_TRUE(r.contains(0xF1));
297  EXPECT_TRUE(r.contains(0xF2));
298  EXPECT_TRUE(r.contains(0xF3));
299  EXPECT_TRUE(r.contains(0xF4));
300  EXPECT_FALSE(r.contains(0xF5));
301  EXPECT_FALSE(r.contains(0xF6));
302 }
303 
304 TEST(AddrRangeTest, ContainsInAnEmptyRange)
305 {
306  AddrRange r(0x1, 0x1);
307 
308  EXPECT_FALSE(r.contains(0x1));
309 }
310 
311 TEST(AddrRangeTest, RemoveIntlvBits)
312 {
313  AddrRange r(0x01, 0x10);
314 
315  /*
316  * When there are no masks, AddrRange.removeIntlBits just returns the
317  * address parameter.
318  */
319  Addr a(56);
320  a = r.removeIntlvBits(a);
321  EXPECT_EQ(56, a);
322 }
323 
324 TEST(AddrRangeTest, addIntlvBits)
325 {
326  AddrRange r(0x01, 0x10);
327 
328  /*
329  * As with AddrRange.removeIntlBits, when there are no masks,
330  * AddrRange.addIntlvBits just returns the address parameter.
331  */
332  Addr a(56);
333  a = r.addIntlvBits(a);
334  EXPECT_EQ(56, a);
335 }
336 
337 TEST(AddrRangeTest, OffsetInRange)
338 {
339  AddrRange r(0x01, 0xF0);
340  EXPECT_EQ(0x04, r.getOffset(0x5));
341 }
342 
343 TEST(AddrRangeTest, OffsetOutOfRangeAfter)
344 {
345  /*
346  * If the address is less than the range, MaxAddr is returned.
347  */
348  AddrRange r(0x01, 0xF0);
349  EXPECT_EQ(MaxAddr, r.getOffset(0xF0));
350 }
351 
352 TEST(AddrRangeTest, OffsetOutOfRangeBefore)
353 {
354  AddrRange r(0x05, 0xF0);
355  EXPECT_EQ(MaxAddr, r.getOffset(0x04));
356 }
357 
358 /*
359  * The following tests check the behavior of AddrRange when initialized with
360  * a start and end address, as well as masks to distinguish interleaving bits.
361  */
362 TEST(AddrRangeTest, LsbInterleavingMask)
363 {
364  Addr start = 0x00;
365  Addr end = 0xFF;
366  std::vector<Addr> masks;
367  /*
368  * The address is in range if the LSB is set, i.e. is the value is odd.
369  */
370  masks.push_back(1);
371  uint8_t intlv_match = 1;
372 
373  AddrRange r(start, end, masks, intlv_match);
374  EXPECT_TRUE(r.valid());
375  EXPECT_EQ(start, r.start());
376  EXPECT_EQ(end, r.end());
377  /*
378  * With interleaving, it's assumed the size is equal to
379  * start - end >> [number of masks].
380  */
381  EXPECT_EQ(0x7F, r.size());
382  /*
383  * The Granularity, the size of regions created by the interleaving bits,
384  * which, in this case, is one.
385  */
386  EXPECT_EQ(1, r.granularity());
387  EXPECT_TRUE(r.interleaved());
388  EXPECT_EQ(2ULL, r.stripes());
389  EXPECT_EQ("[0:0xff] a[0]^\b=1", r.to_string());
390 }
391 
392 TEST(AddrRangeTest, TwoInterleavingMasks)
393 {
394  Addr start = 0x0000;
395  Addr end = 0xFFFF;
396  std::vector<Addr> masks;
397  /*
398  * There are two marks, the two LSBs.
399  */
400  masks.push_back(1);
401  masks.push_back((1 << 1));
402  uint8_t intlv_match = (1 << 1) | 1;
403 
404  AddrRange r(start, end, masks, intlv_match);
405  EXPECT_TRUE(r.valid());
406  EXPECT_EQ(start, r.start());
407  EXPECT_EQ(end, r.end());
408 
409  EXPECT_EQ(0x3FFF, r.size());
410  EXPECT_TRUE(r.interleaved());
411  EXPECT_EQ(4ULL, r.stripes());
412  EXPECT_EQ("[0:0xffff] a[0]^\b=1 a[1]^\b=1", r.to_string());
413 }
414 
415 TEST(AddrRangeTest, ComplexInterleavingMasks)
416 {
417  Addr start = 0x0000;
418  Addr end = 0xFFFF;
419  std::vector<Addr> masks;
420  masks.push_back((1 << 1) | 1);
421  masks.push_back((1ULL << 63) | (1ULL << 62));
422  uint8_t intlv_match = 0;
423 
424  AddrRange r(start, end, masks, intlv_match);
425  EXPECT_TRUE(r.valid());
426  EXPECT_EQ(start, r.start());
427  EXPECT_EQ(end, r.end());
428 
429  EXPECT_EQ(0x3FFF, r.size());
430  EXPECT_TRUE(r.interleaved());
431  EXPECT_EQ(4ULL, r.stripes());
432  EXPECT_EQ("[0:0xffff] a[0]^a[1]^\b=0 a[62]^a[63]^\b=0", r.to_string());
433 }
434 
435 TEST(AddrRangeTest, InterleavingAddressesMergesWith)
436 {
437  Addr start1 = 0x0000;
438  Addr end1 = 0xFFFF;
439  std::vector<Addr> masks;
440  masks.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
441  masks.push_back((1 << 2));
442  uint8_t intlv_match1 = 0;
443  AddrRange r1(start1, end1, masks, intlv_match1);
444 
445  Addr start2 = 0x0000;
446  Addr end2 = 0xFFFF;
447  uint8_t intlv_match2 = 1; // intlv_match may differ.
448  AddrRange r2(start2, end2, masks, intlv_match2);
449 
450  EXPECT_TRUE(r1.mergesWith(r2));
451  EXPECT_TRUE(r2.mergesWith(r1));
452 }
453 
454 TEST(AddrRangeTest, InterleavingAddressesDoNotMergeWith)
455 {
456  Addr start1 = 0x0000;
457  Addr end1 = 0xFFFF;
458  std::vector<Addr> masks1;
459  masks1.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
460  masks1.push_back((1 << 2));
461  uint8_t intlv_match1 = 0;
462  AddrRange r1(start1, end1, masks1, intlv_match1);
463 
464  Addr start2 = 0x0000;
465  Addr end2 = 0xFFFF;
466  std::vector<Addr> masks2;
467  masks2.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
468  masks2.push_back((1 << 3)); // Different mask here.
469  uint8_t intlv_match2 = 1; // intlv_match may differ.
470  AddrRange r2(start2, end2, masks2, intlv_match2);
471 
472  EXPECT_FALSE(r1.mergesWith(r2));
473  EXPECT_FALSE(r2.mergesWith(r1));
474 }
475 
476 TEST(AddrRangeTest, InterleavingAddressesDoNotIntersect)
477 {
478  /*
479  * Range 1: all the odd addresses between 0x0000 and 0xFFFF.
480  */
481  Addr start1 = 0x0000;
482  Addr end1 = 0xFFFF;
483  std::vector<Addr> masks1;
484  masks1.push_back(1);
485  uint8_t intlv_match1 = 1;
486  AddrRange r1(start1, end1, masks1, intlv_match1);
487 
488  /*
489  * Range 2: all the even addresses between 0x0000 and 0xFFFF. These
490  * addresses should thereby not intersect.
491  */
492  Addr start2 = 0x0000;
493  Addr end2 = 0xFFFF;
494  std::vector<Addr> masks2;
495  masks2.push_back(1);
496  uint8_t intv_match2 = 0;
497  AddrRange r2(start2, end2, masks2, intv_match2);
498 
499  EXPECT_FALSE(r1.intersects(r2));
500  EXPECT_FALSE(r2.intersects(r1));
501 }
502 
503 TEST(AddrRangeTest, InterleavingAddressesIntersectsViaMerging)
504 {
505  Addr start1 = 0x0000;
506  Addr end1 = 0xFFFF;
507  std::vector<Addr> masks1;
508  masks1.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
509  masks1.push_back((1 << 2));
510  uint8_t intlv_match1 = 0;
511  AddrRange r1(start1, end1, masks1, intlv_match1);
512 
513  Addr start2 = 0x0000;
514  Addr end2 = 0xFFFF;
515  std::vector<Addr> masks2;
516  masks2.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
517  masks2.push_back((1 << 2));
518  uint8_t intlv_match2 = 0;
519  AddrRange r2(start2, end2, masks2, intlv_match2);
520 
521  EXPECT_TRUE(r1.intersects(r2));
522  EXPECT_TRUE(r2.intersects(r1));
523 }
524 
525 TEST(AddrRangeTest, InterleavingAddressesDoesNotIntersectViaMerging)
526 {
527  Addr start1 = 0x0000;
528  Addr end1 = 0xFFFF;
529  std::vector<Addr> masks1;
530  masks1.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
531  masks1.push_back((1 << 2));
532  uint8_t intlv_match1 = 0;
533  AddrRange r1(start1, end1, masks1, intlv_match1);
534 
535  Addr start2 = 0x0000;
536  Addr end2 = 0xFFFF;
537  std::vector<Addr> masks2;
538  masks2.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
539  masks2.push_back((1 << 2));
540  /*
541  * These addresses can merge, but their intlv_match values differ. They
542  * therefore do not intersect.
543  */
544  uint8_t intlv_match2 = 1;
545  AddrRange r2(start2, end2, masks2, intlv_match2);
546 
547  EXPECT_FALSE(r1.intersects(r2));
548  EXPECT_FALSE(r2.intersects(r1));
549 }
550 
551 /*
552  * The following tests were created to test more complex cases where
553  * interleaving addresses may intersect. However, the "intersects" function
554  * does not cover all cases (a "Cannot test intersection..." exception will
555  * be thrown outside of very simple checks to see if an intersection occurs).
556  * The tests below accurately test whether two ranges intersect but, for now,
557  * code has yet to be implemented to utilize these tests. They are therefore
558  * disabled, but may be enabled at a later date if/when the "intersects"
559  * function is enhanced.
560  */
561 TEST(AddrRangeTest, DISABLED_InterleavingAddressesIntersect)
562 {
563  /*
564  * Range 1: all the odd addresses between 0x0000 and 0xFFFF.
565  */
566  Addr start1 = 0x0000;
567  Addr end1 = 0xFFFF;
568  std::vector<Addr> masks1;
569  masks1.push_back(1);
570  uint8_t intlv_match1 = 0;
571  AddrRange r1(start1, end1, masks1, intlv_match1);
572 
573  /*
574  * Range 2: all the addresses divisible by 4 between 0x0000 and
575  * 0xFFFF. These addresses should thereby intersect.
576  */
577  Addr start2 = 0x0000;
578  Addr end2 = 0xFFFF;
579  std::vector<Addr> masks2;
580  masks2.push_back(1 << 2);
581  uint8_t intlv_match2 = 1;
582  AddrRange r2(start2, end2, masks2, intlv_match2);
583 
584  EXPECT_TRUE(r1.intersects(r2));
585  EXPECT_TRUE(r2.intersects(r1));
586 }
587 
588 TEST(AddrRangeTest, DISABLED_InterleavingAddressesIntersectsOnOneByteAddress)
589 {
590  /*
591  * Range: all the odd addresses between 0x0000 and 0xFFFF.
592  */
593  Addr start = 0x0000;
594  Addr end = 0xFFFF;
595  std::vector<Addr> masks;
596  masks.push_back(1);
597  uint8_t intlv_match = 1;
598  AddrRange r1(start, end, masks, intlv_match);
599 
600  AddrRange r2(0x0000, 0x0001);
601 
602  EXPECT_FALSE(r1.intersects(r2));
603  EXPECT_FALSE(r2.intersects(r1));
604 }
605 
606 TEST(AddrRangeTest,
607  DISABLED_InterleavingAddressesDoesNotIntersectOnOneByteAddress)
608 {
609  /*
610  * Range: all the odd addresses between 0x0000 and 0xFFFF.
611  */
612  Addr start = 0x0000;
613  Addr end = 0xFFFF;
614  std::vector<Addr> masks;
615  masks.push_back(1);
616  uint8_t intlv_match = 1;
617  AddrRange r1(start, end, masks, intlv_match);
618 
619  AddrRange r2(0x0001, 0x0002);
620 
621  EXPECT_TRUE(r1.intersects(r2));
622  EXPECT_TRUE(r2.intersects(r1));
623 }
624 
625 
626 /*
627  * The following three tests were created to test the addr_range.isSubset
628  * function for Interleaving address ranges. However, for now, this
629  * functionality has not been implemented. These tests are therefore disabled.
630  */
631 TEST(AddrRangeTest, DISABLED_InterleavingAddressIsSubset)
632 {
633  // Range 1: all the even addresses between 0x0000 and 0xFFFF.
634  Addr start1 = 0x0000;
635  Addr end1 = 0xFFFF;
636  std::vector<Addr> masks1;
637  masks1.push_back(1);
638  uint8_t intlv_match1 = 0;
639  AddrRange r1(start1, end1, masks1, intlv_match1);
640 
641  // Range 2: all the even addresses between 0xF000 and 0x0FFF, this is
642  // a subset of Range 1.
643  Addr start2 = 0xF000;
644  Addr end2 = 0x0FFF;
645  std::vector<Addr> masks2;
646  masks2.push_back(1);
647  uint8_t intlv_match2 = 0;
648  AddrRange r2(start2, end2, masks2, intlv_match2);
649 
650  EXPECT_TRUE(r1.isSubset(r2));
651  EXPECT_TRUE(r2.isSubset(r1));
652 }
653 
654 TEST(AddrRangeTest, DISABLED_InterleavingAddressIsNotSubset)
655 {
656  //Range 1: all the even addresses between 0x0000 and 0xFFFF.
657  Addr start1 = 0x0000;
658  Addr end1 = 0xFFFF;
659  std::vector<Addr> masks1;
660  masks1.push_back(1);
661  uint8_t intlv_match1 = 0;
662  AddrRange r1(start1, end1, masks1, intlv_match1);
663 
664 
665  // Range 2: all the odd addresses between 0xF000 and 0x0FFF, this is
666  //a subset of Range 1.
667  Addr start2 = 0xF000;
668  Addr end2 = 0x0FFF;
669  std::vector<Addr> masks2;
670  masks2.push_back(1);
671  uint8_t intlv_match2 = 1;
672  AddrRange r2(start2, end2, masks2, intlv_match2);
673 
674  EXPECT_FALSE(r1.isSubset(r2));
675  EXPECT_FALSE(r2.isSubset(r1));
676 }
677 
678 TEST(AddrRangeTest, DISABLED_InterleavingAddressContains)
679 {
680  /*
681  * Range: all the address between 0x0 and 0xFF which have both the 1st
682  * and 5th bits 1, or both are 0
683  */
684  Addr start = 0x00;
685  Addr end = 0xFF;
686  std::vector<Addr> masks;
687  masks.push_back((1 << 4) | 1);
688  uint8_t intlv_match = 0;
689  AddrRange r(start, end, masks, intlv_match);
690 
691  for (Addr addr = start; addr < end; addr++) {
692  if (((addr & 1) && ((1 << 4) & addr)) || // addr[0] && addr[4]
693  (!(addr & 1) && !((1 << 4) & addr))) {
694  EXPECT_TRUE(r.contains(addr));
695  } else {
696  EXPECT_FALSE(r.contains(addr));
697  }
698  }
699 }
700 
701 TEST(AddrRangeTest, InterleavingAddressAddRemoveInterlvBits)
702 {
703  Addr start = 0x00000;
704  Addr end = 0x10000;
705  std::vector<Addr> masks;
706  masks.push_back(1);
707  uint8_t intlv_match = 1;
708  AddrRange r(start, end, masks, intlv_match);
709 
710  Addr input = 0xFFFF;
711  Addr output = r.removeIntlvBits(input);
712 
713  /*
714  * The removeIntlvBits function removes the LSB from each mask from the
715  * input address. For example, two masks:
716  * 00000001 and,
717  * 10000100
718  * with an input address of:
719  * 10101010
720  *
721  * we would remove bit at position 0, and at position 2, resulting in:
722  * 00101011
723  *
724  * In this test there is is one mask, with a LSB at position 0.
725  * Therefore, removing the interleaving bits is equivilant to bitshifting
726  * the input to the right.
727  */
728  EXPECT_EQ(input >> 1, output);
729 
730  /*
731  * The addIntlvBits function will re-insert bits at the removed locations
732  */
733  EXPECT_EQ(input, r.addIntlvBits(output));
734 }
735 
736 TEST(AddrRangeTest, InterleavingAddressAddRemoveInterlvBitsTwoMasks)
737 {
738  Addr start = 0x00000;
739  Addr end = 0x10000;
740  std::vector<Addr> masks;
741  masks.push_back((1 << 3) | (1 << 2) | (1 << 1) | 1);
742  masks.push_back((1 << 11) | (1 << 10) | (1 << 9) | (1 << 8));
743  uint8_t intlv_match = 1;
744  AddrRange r(start, end, masks, intlv_match);
745 
746  Addr input = (1 << 9) | (1 << 8) | 1;
747  /*
748  * (1 << 8) and 1 are interleaving bits to be removed.
749  */
750  Addr output = r.removeIntlvBits(input);
751 
752  /*
753  * The bit, formally at position 9, is now at 7.
754  */
755  EXPECT_EQ((1 << 7), output);
756 
757  /*
758  * Re-adding the interleaving.
759  */
760  EXPECT_EQ(input, r.addIntlvBits(output));
761 }
762 
763 TEST(AddrRangeTest, AddRemoveInterleavBitsAcrossRange)
764 {
765  /*
766  * This purpose of this test is to ensure that removing then adding
767  * interleaving bits has no net effect.
768  * E.g.:
769  * addr_range.addIntlvBits(add_range.removeIntlvBits(an_address)) should
770  * always return an_address.
771  */
772  Addr start = 0x00000;
773  Addr end = 0x10000;
774  std::vector<Addr> masks;
775  masks.push_back(1 << 2);
776  masks.push_back(1 << 3);
777  masks.push_back(1 << 7);
778  masks.push_back(1 << 11);
779  uint8_t intlv_match = 0xF;
780  AddrRange r(start, end, masks, intlv_match);
781 
782  for (Addr i = 0; i < 0xFFF; i++) {
783  Addr removedBits = r.removeIntlvBits(i);
784  /*
785  * As intlv_match = 0xF, all the interleaved bits should be set.
786  */
787  EXPECT_EQ(i | (1 << 2) | (1 << 3) | (1 << 7) | (1 << 11),
788  r.addIntlvBits(removedBits));
789  }
790 }
791 
792 TEST(AddrRangeTest, AddRemoveInterleavBitsAcrossContiguousRange)
793 {
794  /*
795  * This purpose of this test is to ensure that removing then adding
796  * interleaving bits has no net effect.
797  * E.g.:
798  * addr_range.addIntlvBits(add_range.removeIntlvBits(an_address)) should
799  * always return an_address.
800  */
801  Addr start = 0x00000;
802  Addr end = 0x10000;
803  std::vector<Addr> masks;
804  masks.push_back(1 << 2);
805  masks.push_back(1 << 3);
806  masks.push_back(1 << 4);
807  uint8_t intlv_match = 0x7;
808  AddrRange r(start, end, masks, intlv_match);
809 
810  for (Addr i = 0; i < 0xFFF; i++) {
811  Addr removedBits = r.removeIntlvBits(i);
812  /*
813  * As intlv_match = 0x7, all the interleaved bits should be set.
814  */
815  EXPECT_EQ(i | (1 << 2) | (1 << 3) | (1 << 4),
816  r.addIntlvBits(removedBits));
817  }
818 }
819 
820 TEST(AddrRangeTest, InterleavingAddressesGetOffset)
821 {
822  Addr start = 0x0002;
823  Addr end = 0xFFFF;
824  std::vector<Addr> masks;
825  masks.push_back((1 << 4) | (1 << 2));
826  uint8_t intlv_match = 0;
827  AddrRange r(start, end, masks, intlv_match);
828 
829  Addr value = ((1 << 10) | (1 << 9) | (1 << 8) | (1 << 2) | (1 << 1) | 1);
830  Addr value_interleaving_bits_removed =
831  ((1 << 9) | (1 << 8) | (1 << 7) | (1 << 1) | 1);
832 
833  Addr expected_output = value_interleaving_bits_removed - start;
834 
835  EXPECT_EQ(expected_output, r.getOffset(value));
836 }
837 
838 TEST(AddrRangeTest, InterleavingLessThanStartEquals)
839 {
840  Addr start1 = 0x0000FFFF;
841  Addr end1 = 0xFFFF0000;
842  std::vector<Addr> masks1;
843  masks1.push_back((1 << 4) | (1 << 2));
844  uint8_t intlv_match1 = 0;
845  AddrRange r1(start1, end1, masks1, intlv_match1);
846 
847  Addr start2 = 0x0000FFFF;
848  Addr end2 = 0x000F0000;
849  std::vector<Addr> masks2;
850  masks2.push_back((1 << 4) | (1 << 2));
851  masks2.push_back((1 << 10));
852  uint8_t intlv_match2 = 2;
853  AddrRange r2(start2, end2, masks2, intlv_match2);
854 
855  /*
856  * When The start addresses are equal, the intlv_match values are
857  * compared.
858  */
859  EXPECT_TRUE(r1 < r2);
860  EXPECT_FALSE(r2 < r1);
861 }
862 
863 TEST(AddrRangeTest, InterleavingLessThanStartNotEquals)
864 {
865  Addr start1 = 0x0000FFFF;
866  Addr end1 = 0xFFFF0000;
867  std::vector<Addr> masks1;
868  masks1.push_back((1 << 4) | (1 << 2));
869  uint8_t intlv_match1 = 0;
870  AddrRange r1(start1, end1, masks1, intlv_match1);
871 
872  Addr start2 = 0x0000FFFE;
873  Addr end2 = 0x000F0000;
874  std::vector<Addr> masks2;
875  masks2.push_back((1 << 4) | (1 << 2));
876  masks2.push_back((1 << 10));
877  uint8_t intlv_match2 = 2;
878  AddrRange r2(start2, end2, masks2, intlv_match2);
879 
880  EXPECT_TRUE(r2 < r1);
881  EXPECT_FALSE(r1 < r2);
882 }
883 
884 TEST(AddrRangeTest, InterleavingEqualTo)
885 {
886  Addr start1 = 0x0000FFFF;
887  Addr end1 = 0xFFFF0000;
888  std::vector<Addr> masks1;
889  masks1.push_back((1 << 4) | (1 << 2));
890  uint8_t intlv_match1 = 0;
891  AddrRange r1(start1, end1, masks1, intlv_match1);
892 
893  Addr start2 = 0x0000FFFF;
894  Addr end2 = 0xFFFF0000;
895  std::vector<Addr> masks2;
896  masks2.push_back((1 << 4) | (1 << 2));
897  uint8_t intlv_match2 = 0;
898  AddrRange r2(start2, end2, masks2, intlv_match2);
899 
900  EXPECT_TRUE(r1 == r2);
901 }
902 
903 TEST(AddrRangeTest, InterleavingNotEqualTo)
904 {
905  Addr start1 = 0x0000FFFF;
906  Addr end1 = 0xFFFF0000;
907  std::vector<Addr> masks1;
908  masks1.push_back((1 << 4) | (1 << 2));
909  uint8_t intlv_match1 = 0;
910  AddrRange r1(start1, end1, masks1, intlv_match1);
911 
912  Addr start2 = 0x0000FFFF;
913  Addr end2 = 0xFFFF0000;
914  std::vector<Addr> masks2;
915  masks2.push_back((1 << 4) | (1 << 2));
916  masks2.push_back((1 << 10));
917  uint8_t intlv_match2 = 2;
918  AddrRange r2(start2, end2, masks2, intlv_match2);
919 
920  /*
921  * These ranges are not equal due to having different masks.
922  */
923  EXPECT_FALSE(r1 == r2);
924 }
925 
926 /*
927  * The AddrRange(AddrRangeList) constructor "merges" the interleaving
928  * address ranges. It should be noted that this constructor simply checks that
929  * these interleaving addresses can be merged then creates a new address from
930  * the start and end addresses of the first address range in the list.
931  */
932 TEST(AddrRangeTest, MergingInterleavingAddressRanges)
933 {
934  Addr start1 = 0x0000;
935  Addr end1 = 0xFFFF;
936  std::vector<Addr> masks1;
937  masks1.push_back((1 << 4) | (1 << 2));
938  uint8_t intlv_match1 = 0;
939  AddrRange r1(start1, end1, masks1, intlv_match1);
940 
941  Addr start2 = 0x0000;
942  Addr end2 = 0xFFFF;
943  std::vector<Addr> masks2;
944  masks2.push_back((1 << 4) | (1 << 2));
945  uint8_t intlv_match2 = 1;
946  AddrRange r2(start2, end2, masks2, intlv_match2);
947 
948  AddrRangeList to_merge;
949  to_merge.push_back(r1);
950  to_merge.push_back(r2);
951 
952  AddrRange output(to_merge);
953 
954  EXPECT_EQ(0x0000, output.start());
955  EXPECT_EQ(0xFFFF, output.end());
956  EXPECT_FALSE(output.interleaved());
957 }
958 
959 TEST(AddrRangeTest, MergingInterleavingAddressRangesOneRange)
960 {
961  /*
962  * In the case where there is just one range in the list, the merged
963  * address range is equal to that range.
964  */
965  Addr start = 0x0000;
966  Addr end = 0xFFFF;
967  std::vector<Addr> masks;
968  masks.push_back((1 << 4) | (1 << 2));
969  uint8_t intlv_match = 0;
970  AddrRange r(start, end, masks, intlv_match);
971 
972  AddrRangeList to_merge;
973  to_merge.push_back(r);
974 
975  AddrRange output(to_merge);
976 
977  EXPECT_EQ(r, output);
978 }
979 
980 /*
981  * The following tests verify the soundness of the "legacy constructor",
982  * AddrRange(Addr, Addr, uint8_t, uint8_t, uint8_t, uint8_t).
983  *
984  * The address is assumed to contain two ranges; the interleaving bits, and
985  * the xor bits. The first two arguments of this constructor specify the
986  * start and end addresses. The third argument specifies the MSB of the
987  * interleaving bits. The fourth argument specifies the MSB of the xor bits.
988  * The firth argument specifies the size (in bits) of the xor and interleaving
989  * bits. These cannot overlap. The sixth argument specifies the value the
990  * XORing of the xor and interleaving bits should equal to be considered in
991  * range.
992  *
993  * This constructor does a lot of complex translation to migrate this
994  * constructor to the masks/intlv_match format.
995  */
996 TEST(AddrRangeTest, LegacyConstructorNoInterleaving)
997 {
998  /*
999  * This constructor should create a range with no interleaving.
1000  */
1001  AddrRange range(0x0000, 0xFFFF, 0, 0, 0 ,0);
1002  AddrRange expected(0x0000, 0xFFFF);
1003 
1004  EXPECT_EQ(expected, range);
1005 }
1006 
1007 TEST(AddrRangeTest, LegacyConstructorOneBitMask)
1008 {
1009  /*
1010  * In this test, the LSB of the address determines whether an address is
1011  * in range. If even, it's in range, if not, it's out of range. the XOR
1012  * bit range is not used.
1013  */
1014  AddrRange range(0x00000000, 0xFFFFFFFF, 0, 0, 1, 0);
1015 
1016  std::vector<Addr> masks;
1017  masks.push_back(1);
1018  AddrRange expected(0x00000000, 0xFFFFFFFF, masks, 0);
1019 
1020  EXPECT_TRUE(expected == range);
1021 }
1022 
1023 TEST(AddrRangeTest, LegacyConstructorTwoBitMask)
1024 {
1025  /*
1026  * In this test, the two LSBs of the address determines whether an address
1027  * is in range. If the two are set, the address is in range. The XOR bit
1028  * range is not used.
1029  */
1030  AddrRange range(0x00000000, 0xFFFFFFFF, 1, 0, 2, 3);
1031 
1032  std::vector<Addr> masks;
1033  masks.push_back(1);
1034  masks.push_back((1 << 1));
1035  AddrRange expected(0x00000000, 0xFFFFFFFF, masks, 3);
1036 
1037  EXPECT_TRUE(expected == range);
1038 }
1039 
1040 TEST(AddrRangeTest, LegacyConstructorTwoBitMaskWithXOR)
1041 {
1042  /*
1043  * In this test, the two LSBs of the address determine wether an address
1044  * is in range. They are XORed to the 10th and 11th bits in the address.
1045  * If XORed value is equal to 3, then the address is in range.
1046  */
1047 
1048  AddrRange range(0x00000000, 0xFFFFFFFF, 1, 11, 2, 3);
1049 
1050  /*
1051  * The easiest way to ensure this range is correct is to iterate throguh
1052  * the address range and ensure the correct set of addresses are contained
1053  * within the range.
1054  *
1055  * We start with the xor_mask: a mask to select the 10th and 11th bits.
1056  */
1057  Addr xor_mask = (1 << 11) | (1 << 10);
1058  for (Addr i = 0; i < 0x0000FFFF; i++) {
1059  // Get xor bits.
1060  Addr xor_value = (xor_mask & i) >> 10;
1061  /* If the XOR of xor_bits and the intlv bits (the 0th and 1st bits) is
1062  * equal to intlv_match (3, i.e., the 0th and 1st bit is set),then the
1063  * address is within range.
1064  */
1065  if (((xor_value ^ i) & 3) == 3) {
1066  EXPECT_TRUE(range.contains(i));
1067  } else {
1068  EXPECT_FALSE(range.contains(i));
1069  }
1070  }
1071 }
1072 
1073 /*
1074  * addr_range.hh contains some convenience constructors. The following tests
1075  * verify they construct AddrRange correctly.
1076  */
1077 TEST(AddrRangeTest, RangeExConstruction)
1078 {
1079  AddrRange r = RangeEx(0x6, 0xE);
1080  EXPECT_EQ(0x6, r.start());
1081  EXPECT_EQ(0xE, r.end());
1082 }
1083 
1084 TEST(AddrRangeTest, RangeInConstruction)
1085 {
1086  AddrRange r = RangeIn(0x6, 0xE);
1087  EXPECT_EQ(0x6, r.start());
1088  EXPECT_EQ(0xF, r.end());
1089 }
1090 
1091 TEST(AddrRangeTest, RangeSizeConstruction){
1092  AddrRange r = RangeSize(0x5, 5);
1093  EXPECT_EQ(0x5, r.start());
1094  EXPECT_EQ(0xA, r.end());
1095 }
1096 
1097 /*
1098  * The exclude list is excluding the entire range: return an empty
1099  * list of ranges
1100  *
1101  * |---------------------|
1102  * | range |
1103  * |---------------------|
1104  *
1105  * |------------------------------|
1106  * | exclude_range |
1107  * |------------------------------|
1108  */
1109 TEST(AddrRangeTest, ExcludeAll)
1110 {
1111  const AddrRangeList exclude_ranges{
1112  AddrRange(0x0, 0x200)
1113  };
1114 
1115  AddrRange r(0x00, 0x100);
1116  auto ranges = r.exclude(exclude_ranges);
1117 
1118  EXPECT_TRUE(ranges.empty());
1119 }
1120 
1121 /*
1122  * The exclude list is excluding the entire range: return an empty
1123  * list of ranges. The exclude_range = range
1124  *
1125  * |---------------------|
1126  * | range |
1127  * |---------------------|
1128  *
1129  * |---------------------|
1130  * | exclude_range |
1131  * |---------------------|
1132  */
1133 TEST(AddrRangeTest, ExcludeAllEqual)
1134 {
1135  const AddrRangeList exclude_ranges{
1136  AddrRange(0x0, 0x100)
1137  };
1138 
1139  AddrRange r(0x00, 0x100);
1140  auto ranges = r.exclude(exclude_ranges);
1141 
1142  EXPECT_TRUE(ranges.empty());
1143 }
1144 
1145 /*
1146  * The exclude list is made of multiple adjacent ranges covering the entire
1147  * interval: return an empty list of ranges.
1148  *
1149  * |---------------------------------------------------------------|
1150  * | range |
1151  * |---------------------------------------------------------------|
1152  *
1153  * |--------------------------|---------------|--------------------------|
1154  * | exclude_range | exclude_range | exclude_range |
1155  * |--------------------------|---------------|--------------------------|
1156  */
1157 TEST(AddrRangeTest, ExcludeAllMultiple)
1158 {
1159  const AddrRangeList exclude_ranges{
1160  AddrRange(0x0, 0x30),
1161  AddrRange(0x30, 0x40),
1162  AddrRange(0x40, 0x120)
1163  };
1164 
1165  AddrRange r(0x00, 0x100);
1166  auto ranges = r.exclude(exclude_ranges);
1167 
1168  EXPECT_TRUE(ranges.empty());
1169 }
1170 
1171 /*
1172  * ExcludeAllOverlapping:
1173  * The exclude list is made of multiple overlapping ranges covering the entire
1174  * interval: return an empty list of ranges.
1175  *
1176  * |-----------------------------------|
1177  * | range |
1178  * |-----------------------------------|
1179  *
1180  * |-----------------------------|
1181  * | exclude_range |
1182  * |-----------------------------|
1183  * |-----------------------------|
1184  * | exclude_range |
1185  * |-----------------------------|
1186  */
1187 TEST(AddrRangeTest, ExcludeAllOverlapping)
1188 {
1189  const AddrRangeList exclude_ranges{
1190  AddrRange(0x0, 0x150),
1191  AddrRange(0x140, 0x220)
1192  };
1193 
1194  AddrRange r(0x100, 0x200);
1195 
1196  auto ranges = r.exclude(exclude_ranges);
1197 
1198  EXPECT_TRUE(ranges.empty());
1199 }
1200 
1201 /*
1202  * The exclude list is empty:
1203  * the return list contains the unmodified range
1204  *
1205  * |---------------------|
1206  * | range |
1207  * |---------------------|
1208  *
1209  */
1210 TEST(AddrRangeTest, ExcludeEmpty)
1211 {
1212  const AddrRangeList exclude_ranges;
1213 
1214  AddrRange r(0x00, 0x100);
1215  auto ranges = r.exclude(exclude_ranges);
1216 
1217  EXPECT_EQ(ranges.size(), 1);
1218  EXPECT_EQ(ranges.front(), r);
1219 }
1220 
1221 
1222 /*
1223  * Ranges do not overlap:
1224  * the return list contains the unmodified range
1225  *
1226  * |---------------------|
1227  * | range |
1228  * |---------------------|
1229  *
1230  * |------------------------------|
1231  * | exclude_range |
1232  * |------------------------------|
1233  */
1234 TEST(AddrRangeTest, NoExclusion)
1235 {
1236  const AddrRangeList exclude_ranges{
1237  AddrRange(0x100, 0x200)
1238  };
1239 
1240  AddrRange r(0x00, 0x100);
1241  auto ranges = r.exclude(exclude_ranges);
1242 
1243  EXPECT_EQ(ranges.size(), 1);
1244  EXPECT_EQ(ranges.front(), r);
1245 }
1246 
1247 /*
1248  * DoubleExclusion:
1249  * The exclusion should return two ranges:
1250  * AddrRange(0x130, 0x140)
1251  * AddrRange(0x170, 0x200)
1252  *
1253  * |-----------------------------------|
1254  * | range |
1255  * |-----------------------------------|
1256  *
1257  * |-----------------| |-----------------|
1258  * | exclude_range | | exclude_range |
1259  * |-----------------| |-----------------|
1260  */
1261 TEST(AddrRangeTest, DoubleExclusion)
1262 {
1263  const AddrRangeList exclude_ranges{
1264  AddrRange(0x000, 0x130),
1265  AddrRange(0x140, 0x170),
1266  };
1267 
1268  const AddrRange expected_range1(0x130, 0x140);
1269  const AddrRange expected_range2(0x170, 0x200);
1270 
1271  AddrRange r(0x100, 0x200);
1272  auto ranges = r.exclude(exclude_ranges);
1273 
1274  EXPECT_EQ(ranges.size(), 2);
1275  EXPECT_THAT(ranges, ElementsAre(expected_range1, expected_range2));
1276 }
1277 
1278 /*
1279  * MultipleExclusion:
1280  * The exclusion should return two ranges:
1281  * AddrRange(0x130, 0x140)
1282  * AddrRange(0x170, 0x180)
1283  *
1284  * |-----------------------------------|
1285  * | range |
1286  * |-----------------------------------|
1287  *
1288  * |-----------------| |-----------------| |-----------------|
1289  * | exclude_range | | exclude_range | | exclude_range |
1290  * |-----------------| |-----------------| |-----------------|
1291  */
1292 TEST(AddrRangeTest, MultipleExclusion)
1293 {
1294  const AddrRangeList exclude_ranges{
1295  AddrRange(0x000, 0x130),
1296  AddrRange(0x140, 0x170),
1297  AddrRange(0x180, 0x210)
1298  };
1299 
1300  const AddrRange expected_range1(0x130, 0x140);
1301  const AddrRange expected_range2(0x170, 0x180);
1302 
1303  AddrRange r(0x100, 0x200);
1304  auto ranges = r.exclude(exclude_ranges);
1305 
1306  EXPECT_EQ(ranges.size(), 2);
1307  EXPECT_THAT(ranges, ElementsAre(expected_range1, expected_range2));
1308 }
1309 
1310 /*
1311  * MultipleExclusionOverlapping:
1312  * The exclusion should return one range:
1313  * AddrRange(0x130, 0x140)
1314  *
1315  * |-----------------------------------|
1316  * | range |
1317  * |-----------------------------------|
1318  *
1319  * |-----------------| |-----------------|
1320  * | exclude_range | | exclude_range |
1321  * |-----------------| |-----------------|
1322  * |-----------------|
1323  * | exclude_range |
1324  * |-----------------|
1325  */
1326 TEST(AddrRangeTest, MultipleExclusionOverlapping)
1327 {
1328  const AddrRangeList exclude_ranges{
1329  AddrRange(0x000, 0x130),
1330  AddrRange(0x140, 0x170),
1331  AddrRange(0x150, 0x210)
1332  };
1333 
1334  const AddrRange expected_range1(0x130, 0x140);
1335 
1336  AddrRange r(0x100, 0x200);
1337  auto ranges = r.exclude(exclude_ranges);
1338 
1339  EXPECT_EQ(ranges.size(), 1);
1340  EXPECT_THAT(ranges, ElementsAre(expected_range1));
1341 }
1342 
1343 /*
1344  * ExclusionOverlapping:
1345  * The exclusion should return two range:
1346  * AddrRange(0x100, 0x120)
1347  * AddrRange(0x180, 0x200)
1348  *
1349  * |-----------------------------------|
1350  * | range |
1351  * |-----------------------------------|
1352  *
1353  * |--------------------|
1354  * | exclude_range |
1355  * |--------------------|
1356  *
1357  * |---------------|
1358  * | exclude_range |
1359  * |---------------|
1360  */
1361 TEST(AddrRangeTest, ExclusionOverlapping)
1362 {
1363  const AddrRangeList exclude_ranges{
1364  AddrRange(0x120, 0x180),
1365  AddrRange(0x130, 0x170)
1366  };
1367 
1368  const AddrRange expected_range1(0x100, 0x120);
1369  const AddrRange expected_range2(0x180, 0x200);
1370 
1371  AddrRange r(0x100, 0x200);
1372  auto ranges = r.exclude(exclude_ranges);
1373 
1374  EXPECT_EQ(ranges.size(), 2);
1375  EXPECT_THAT(ranges, ElementsAre(expected_range1, expected_range2));
1376 }
1377 
1378 /*
1379  * MultipleExclusionUnsorted:
1380  * The exclusion should return two ranges:
1381  * AddrRange(0x130, 0x140)
1382  * AddrRange(0x170, 0x180)
1383  * Same as MultipleExclusion, but the exclude list is provided
1384  * in unsorted order
1385  *
1386  * |-----------------------------------|
1387  * | range |
1388  * |-----------------------------------|
1389  *
1390  * |-----------------| |-----------------| |-----------------|
1391  * | exclude_range | | exclude_range | | exclude_range |
1392  * |-----------------| |-----------------| |-----------------|
1393  */
1394 TEST(AddrRangeTest, MultipleExclusionUnsorted)
1395 {
1396  const AddrRangeList exclude_ranges{
1397  AddrRange(0x180, 0x210),
1398  AddrRange(0x000, 0x130),
1399  AddrRange(0x140, 0x170)
1400  };
1401 
1402  const AddrRange expected_range1(0x130, 0x140);
1403  const AddrRange expected_range2(0x170, 0x180);
1404 
1405  AddrRange r(0x100, 0x200);
1406  auto ranges = r.exclude(exclude_ranges);
1407 
1408  EXPECT_EQ(ranges.size(), 2);
1409  EXPECT_THAT(ranges, ElementsAre(expected_range1, expected_range2));
1410 }
1411 
1412 TEST(AddrRangeTest, ExclusionOfSingleRange)
1413 {
1414  const AddrRange expected_range1(0x100, 0x140);
1415  const AddrRange expected_range2(0x1c0, 0x200);
1416 
1417  AddrRange r(0x100, 0x200);
1418  auto ranges = r.exclude(AddrRange(0x140, 0x1c0));
1419 
1420  EXPECT_EQ(ranges.size(), 2);
1421  EXPECT_THAT(ranges, ElementsAre(expected_range1, expected_range2));
1422 }
1423 
1424 TEST(AddrRangeTest, ExclusionOfRangeFromRangeList)
1425 {
1426  AddrRangeList base({AddrRange(0x100, 0x200), AddrRange(0x300, 0x400)});
1427 
1428  const AddrRange expected_range1(0x100, 0x180);
1429  const AddrRange expected_range2(0x380, 0x400);
1430 
1431  auto ranges = exclude(base, AddrRange(0x180, 0x380));
1432 
1433  EXPECT_EQ(ranges.size(), 2);
1434  EXPECT_THAT(ranges, ElementsAre(expected_range1, expected_range2));
1435 }
1436 
1437 TEST(AddrRangeTest, ExclusionOfRangeListFromRangeList)
1438 {
1439  AddrRangeList base({AddrRange(0x100, 0x200), AddrRange(0x300, 0x400)});
1440 
1441  const AddrRange expected_range1(0x100, 0x140);
1442  const AddrRange expected_range2(0x180, 0x200);
1443  const AddrRange expected_range3(0x300, 0x340);
1444  const AddrRange expected_range4(0x380, 0x400);
1445 
1446  const AddrRangeList to_exclude({
1447  AddrRange(0x140, 0x180), AddrRange(0x340, 0x380)});
1448  auto ranges = exclude(base, to_exclude);
1449 
1450  EXPECT_EQ(ranges.size(), 4);
1451  EXPECT_THAT(ranges, ElementsAre(
1452  expected_range1, expected_range2,
1453  expected_range3, expected_range4));
1454 }
1455 
1456 TEST(AddrRangeTest, SubtractionOperatorRange)
1457 {
1458  const AddrRange expected_range1(0x100, 0x140);
1459  const AddrRange expected_range2(0x1c0, 0x200);
1460 
1461  AddrRange r(0x100, 0x200);
1462  auto ranges = r - AddrRange(0x140, 0x1c0);
1463 
1464  EXPECT_EQ(ranges.size(), 2);
1465  EXPECT_THAT(ranges, ElementsAre(expected_range1, expected_range2));
1466 }
1467 
1468 TEST(AddrRangeTest, SubtractionOperatorRangeList)
1469 {
1470  const AddrRange expected_range1(0x100, 0x140);
1471  const AddrRange expected_range2(0x160, 0x180);
1472  const AddrRange expected_range3(0x1a0, 0x200);
1473 
1474  AddrRange r(0x100, 0x200);
1475  auto ranges = r - AddrRangeList(
1476  {AddrRange(0x140, 0x160), AddrRange(0x180, 0x1a0)});
1477 
1478  EXPECT_EQ(ranges.size(), 3);
1479  EXPECT_THAT(ranges, ElementsAre(
1480  expected_range1, expected_range2, expected_range3));
1481 }
1482 
1483 TEST(AddrRangeTest, SubtractionOfRangeFromRangeList)
1484 {
1485  AddrRangeList base({AddrRange(0x100, 0x200), AddrRange(0x300, 0x400)});
1486 
1487  const AddrRange expected_range1(0x100, 0x180);
1488  const AddrRange expected_range2(0x380, 0x400);
1489 
1490  auto ranges = base - AddrRange(0x180, 0x380);
1491 
1492  EXPECT_EQ(ranges.size(), 2);
1493  EXPECT_THAT(ranges, ElementsAre(expected_range1, expected_range2));
1494 }
1495 
1496 TEST(AddrRangeTest, SubtractionOfRangeListFromRangeList)
1497 {
1498  AddrRangeList base({AddrRange(0x100, 0x200), AddrRange(0x300, 0x400)});
1499 
1500  const AddrRange expected_range1(0x100, 0x140);
1501  const AddrRange expected_range2(0x180, 0x200);
1502  const AddrRange expected_range3(0x300, 0x340);
1503  const AddrRange expected_range4(0x380, 0x400);
1504 
1505  const AddrRangeList to_exclude({
1506  AddrRange(0x140, 0x180), AddrRange(0x340, 0x380)});
1507  auto ranges = base - to_exclude;
1508 
1509  EXPECT_EQ(ranges.size(), 4);
1510  EXPECT_THAT(ranges, ElementsAre(
1511  expected_range1, expected_range2,
1512  expected_range3, expected_range4));
1513 }
1514 
1515 TEST(AddrRangeTest, SubtractionAssignmentOfRangeFromRangeList)
1516 {
1517  AddrRangeList base({AddrRange(0x100, 0x200), AddrRange(0x300, 0x400)});
1518 
1519  const AddrRange expected_range1(0x100, 0x180);
1520  const AddrRange expected_range2(0x380, 0x400);
1521 
1522  base -= AddrRange(0x180, 0x380);
1523 
1524  EXPECT_EQ(base.size(), 2);
1525  EXPECT_THAT(base, ElementsAre(expected_range1, expected_range2));
1526 }
1527 
1528 TEST(AddrRangeTest, SubtractionAssignmentOfRangeListFromRangeList)
1529 {
1530  AddrRangeList base({AddrRange(0x100, 0x200), AddrRange(0x300, 0x400)});
1531 
1532  const AddrRange expected_range1(0x100, 0x140);
1533  const AddrRange expected_range2(0x180, 0x200);
1534  const AddrRange expected_range3(0x300, 0x340);
1535  const AddrRange expected_range4(0x380, 0x400);
1536 
1537  const AddrRangeList to_exclude({
1538  AddrRange(0x140, 0x180), AddrRange(0x340, 0x380)});
1539  base -= to_exclude;
1540 
1541  EXPECT_EQ(base.size(), 4);
1542  EXPECT_THAT(base, ElementsAre(
1543  expected_range1, expected_range2,
1544  expected_range3, expected_range4));
1545 }
1546 
1547 /*
1548  * InterleavingRanges:
1549  * The exclude method does not support interleaving ranges
1550  */
1551 TEST(AddrRangeDeathTest, ExcludeInterleavingRanges)
1552 {
1553  /* An `assert(!interleaved());` exists at the top of the `exclude(...)`
1554  * method. This means EXPECT_DEATH will only function when DEBUG is enabled
1555  * (as when compiled to `.opt`). When disabled (as when compiled to `.fast`),
1556  * `r.exclude` fails more catastrophically via a `panic` which GTest cannot
1557  * handle correctly. We therefore include a `#ifdef NDEBUG` guard so this
1558  * test is skipped when DEBUG is disabled.
1559  */
1560 #ifdef NDEBUG
1561  GTEST_SKIP() << "Skipping as assetions are stripped from fast builds.";
1562 #endif
1563  const AddrRangeList exclude_ranges{
1564  AddrRange(0x180, 0x210),
1565  };
1566 
1567  AddrRange r(0x100, 0x200, {1}, 0);
1568 
1569  EXPECT_TRUE(r.interleaved());
1570  EXPECT_DEATH(r.exclude(exclude_ranges), "");
1571 }
TEST(AddrRangeTest, ValidRange)
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition: addr_range.hh:82
std::vector< SwitchingFiber * > expected({ &a, &b, &a, &a, &a, &b, &c, &a, &c, &c, &c })
bool isSubset(const AddrRange &r) const
Determine if this range is a subset of another range, i.e.
Definition: addr_range.hh:445
AddrRange RangeEx(Addr start, Addr end)
Definition: addr_range.hh:797
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:815
AddrRange RangeIn(Addr start, Addr end)
Definition: addr_range.hh:806
std::list< AddrRange > AddrRangeList
Convenience typedef for a collection of address ranges.
Definition: addr_range.hh:57
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:471
bool intersects(const AddrRange &r) const
Determine if another range intersects this one, i.e.
Definition: addr_range.hh:408
bool mergesWith(const AddrRange &r) const
Determine if another range merges with the current one, i.e.
Definition: addr_range.hh:391
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 8 > a
Definition: misc_types.hh:66
Bitfield< 5 > r
Definition: pagetable.hh:60
Bitfield< 51, 12 > base
Definition: pagetable.hh:141
Bitfield< 3 > addr
Definition: types.hh:84
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
static AddrRangeList exclude(const AddrRangeList &base, AddrRangeList to_exclude)
Definition: addr_range.hh:750
static void output(const char *filename)
Definition: debug.cc:60
const Addr MaxAddr
Definition: types.hh:171

Generated on Wed Dec 21 2022 10:22:28 for gem5 by doxygen 1.9.1