gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
47using namespace gem5;
48
49using testing::ElementsAre;
50
51TEST(AddrRangeTest, ValidRange)
52{
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 */
63TEST(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
92TEST(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
105TEST(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
118TEST(AddrRangeTest, InvalidRange)
119{
120 AddrRange r(0x1, 0x0);
121 EXPECT_FALSE(r.valid());
122}
123
124TEST(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
142TEST(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
159TEST(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
172TEST(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
181TEST(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
190TEST(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
199TEST(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
208TEST(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
217TEST(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
230TEST(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
239TEST(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
248TEST(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
257TEST(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
266TEST(AddrRangeTest, isSubsetInterleavedCompleteOverlap)
267{
268 AddrRange r1(0x00, 0x100, {0x40}, 0);
269 AddrRange r2(0x00, 0x40);
270
271 EXPECT_TRUE(r2.isSubset(r1));
272}
273
274TEST(AddrRangeTest, isSubsetInterleavedNoOverlap)
275{
276 AddrRange r1(0x00, 0x100, {0x40}, 1);
277 AddrRange r2(0x00, 0x40);
278
279 EXPECT_FALSE(r2.isSubset(r1));
280}
281
282TEST(AddrRangeTest, isSubsetInterleavedPartialOverlap)
283{
284 AddrRange r1(0x00, 0x100, {0x40}, 0);
285 AddrRange r2(0x10, 0x50);
286
287 EXPECT_FALSE(r2.isSubset(r1));
288}
289
290TEST(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
304TEST(AddrRangeTest, ContainsInAnEmptyRange)
305{
306 AddrRange r(0x1, 0x1);
307
308 EXPECT_FALSE(r.contains(0x1));
309}
310
311TEST(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
324TEST(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
337TEST(AddrRangeTest, OffsetInRange)
338{
339 AddrRange r(0x01, 0xF0);
340 EXPECT_EQ(0x04, r.getOffset(0x5));
341}
342
343TEST(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
352TEST(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 */
362TEST(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
392TEST(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
415TEST(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
435TEST(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
454TEST(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
476TEST(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
503TEST(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
525TEST(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 */
561TEST(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
588TEST(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
606TEST(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 */
631TEST(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
654TEST(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
678TEST(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
701TEST(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
736TEST(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
763TEST(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
792TEST(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
820TEST(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
838TEST(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
863TEST(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
884TEST(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
903TEST(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 */
932TEST(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
959TEST(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 */
996TEST(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
1007TEST(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
1023TEST(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
1040TEST(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 */
1077TEST(AddrRangeTest, RangeExConstruction)
1078{
1079 AddrRange r = RangeEx(0x6, 0xE);
1080 EXPECT_EQ(0x6, r.start());
1081 EXPECT_EQ(0xE, r.end());
1082}
1083
1084TEST(AddrRangeTest, RangeInConstruction)
1085{
1086 AddrRange r = RangeIn(0x6, 0xE);
1087 EXPECT_EQ(0x6, r.start());
1088 EXPECT_EQ(0xF, r.end());
1089}
1090
1091TEST(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 */
1109TEST(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 */
1133TEST(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 */
1157TEST(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 */
1187TEST(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 */
1210TEST(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 */
1234TEST(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 */
1261TEST(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 */
1292TEST(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 */
1326TEST(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 */
1361TEST(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 */
1394TEST(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
1412TEST(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
1424TEST(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
1437TEST(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
1456TEST(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
1468TEST(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
1483TEST(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
1496TEST(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
1515TEST(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
1528TEST(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
1547TEST(AddrRangeTest, isNotSubsetLastByte)
1548{
1549 /* An issue raised in https://github.com/gem5/gem5/issues/240 where if an
1550 * address range ends at the last byte of a 64 bit address space, it will
1551 * be considered a subset of any other address range that starts at the
1552 * first byte of the range.
1553 */
1554
1555 AddrRange first_four_bytes = RangeSize(0x0, 4);
1556 AddrRange last_four_bytes = RangeSize(0xfffffffffffffffc, 4);
1557
1558 EXPECT_FALSE(last_four_bytes.isSubset(first_four_bytes));
1559}
1560
1561TEST(AddrRangeTest, isSubsetLastByte)
1562{
1563 /* An issue raised in https://github.com/gem5/gem5/issues/240 where if an
1564 * address range ends at the last byte of a 64 bit address space, it will
1565 * be considered a subset of any other address range that starts at the
1566 * first byte of the range.
1567 *
1568 * This test checks it subset works correctly when the range is the last
1569 * byte of the address space.
1570 */
1571 AddrRange last_four_bytes = RangeSize(0xfffffffffffffffc, 4);
1572 AddrRange not_wrapped_last_bytes = RangeSize(0xfffffffffffffffc, 3);
1573
1574 EXPECT_TRUE(not_wrapped_last_bytes.isSubset(last_four_bytes));
1575}
1576
1577/*
1578 * InterleavingRanges:
1579 * The exclude method does not support interleaving ranges
1580 */
1581TEST(AddrRangeDeathTest, ExcludeInterleavingRanges)
1582{
1583 /* An `assert(!interleaved());` exists at the top of the `exclude(...)`
1584 * method. This means EXPECT_DEATH will only function when DEBUG is enabled
1585 * (as when compiled to `.opt`). When disabled (as when compiled to `.fast`),
1586 * `r.exclude` fails more catastrophically via a `panic` which GTest cannot
1587 * handle correctly. We therefore include a `#ifdef NDEBUG` guard so this
1588 * test is skipped when DEBUG is disabled.
1589 */
1590#ifdef NDEBUG
1591 GTEST_SKIP() << "Skipping as assetions are stripped from fast builds.";
1592#endif
1593 const AddrRangeList exclude_ranges{
1594 AddrRange(0x180, 0x210),
1595 };
1596
1597 AddrRange r(0x100, 0x200, {1}, 0);
1598
1599 EXPECT_TRUE(r.interleaved());
1600 EXPECT_DEATH(r.exclude(exclude_ranges), "");
1601}
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
STL vector class.
Definition stl.hh:37
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.
AddrRange RangeEx(Addr start, Addr end)
AddrRange RangeSize(Addr start, Addr size)
AddrRange RangeIn(Addr start, Addr end)
std::list< AddrRange > AddrRangeList
Convenience typedef for a collection of address ranges.
Definition addr_range.hh:64
bool contains(const Addr &a) const
Determine if the range contains an address.
bool intersects(const AddrRange &r) const
Determine if another range intersects this one, i.e.
bool mergesWith(const AddrRange &r) const
Determine if another range merges with the current one, i.e.
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 8 > a
Definition misc_types.hh:66
Bitfield< 51, 12 > base
Definition pagetable.hh:141
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
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)
static void output(const char *filename)
Definition debug.cc:60
const Addr MaxAddr
Definition types.hh:171

Generated on Tue Jun 18 2024 16:24:00 for gem5 by doxygen 1.11.0