gem5  v20.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 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 <gtest/gtest.h>
40 
41 #include <cmath>
42 
43 #include "base/addr_range.hh"
44 #include "base/bitfield.hh"
45 
46 TEST(AddrRangeTest, ValidRange)
47 {
48  AddrRange r;
49  EXPECT_FALSE(r.valid());
50 }
51 
52 /*
53  * This following tests check the behavior of AddrRange when initialized with
54  * a start and end address. The expected behavior is that the first address
55  * within the range will be the start address, and the last address in the
56  * range will be the (end - 1) address.
57  */
58 TEST(AddrRangeTest, EmptyRange)
59 {
60  AddrRange r(0x0, 0x0);
61 
62  /*
63  * Empty ranges are valid.
64  */
65  EXPECT_TRUE(r.valid());
66  EXPECT_EQ(0x0, r.start());
67  EXPECT_EQ(0x0, r.end());
68  EXPECT_EQ(0, r.size());
69 
70  /*
71  * With no masks, granularity equals the size of the range.
72  */
73  EXPECT_EQ(0, r.granularity());
74 
75  /*
76  * With no masks, "interleaved()" returns false.
77  */
78  EXPECT_FALSE(r.interleaved());
79 
80  /*
81  * With no masks, "stripes()" returns ULL(1).
82  */
83  EXPECT_EQ(ULL(1), r.stripes());
84  EXPECT_EQ("[0:0]", r.to_string());
85 }
86 
87 TEST(AddrRangeTest, RangeSizeOfOne)
88 {
89  AddrRange r(0x0, 0x1);
90  EXPECT_TRUE(r.valid());
91  EXPECT_EQ(0x0, r.start());
92  EXPECT_EQ(0x1, r.end());
93  EXPECT_EQ(1, r.size());
94  EXPECT_EQ(1, r.granularity());
95  EXPECT_FALSE(r.interleaved());
96  EXPECT_EQ(ULL(1), r.stripes());
97  EXPECT_EQ("[0:0x1]", r.to_string());
98 }
99 
100 TEST(AddrRangeTest, Range16Bit)
101 {
102  AddrRange r(0xF000, 0xFFFF);
103  EXPECT_TRUE(r.valid());
104  EXPECT_EQ(0xF000, r.start());
105  EXPECT_EQ(0xFFFF, r.end());
106  EXPECT_EQ(0x0FFF, r.size());
107  EXPECT_EQ(0x0FFF, r.granularity());
108  EXPECT_FALSE(r.interleaved());
109  EXPECT_EQ(ULL(1), r.stripes());
110  EXPECT_EQ("[0xf000:0xffff]", r.to_string());
111 }
112 
113 TEST(AddrRangeTest, InvalidRange)
114 {
115  AddrRange r(0x1, 0x0);
116  EXPECT_FALSE(r.valid());
117 }
118 
119 TEST(AddrRangeTest, LessThan)
120 {
121  /*
122  * The less-than override is a bit unintuitive and does not have a
123  * corresponding greater than. It compares the AddrRange.start() values.
124  * If they are equal, the "intlvMatch" values are compared. This is
125  * zero when AddRange is initialized with a just a start and end address.
126  */
127  AddrRange r1(0xF000, 0xFFFF);
128  AddrRange r2(0xF001, 0xFFFF);
129  AddrRange r3(0xF000, 0xFFFF);
130 
131  EXPECT_TRUE(r1 < r2);
132  EXPECT_FALSE(r2 < r1);
133  EXPECT_FALSE(r1 < r3);
134  EXPECT_FALSE(r3 < r1);
135 }
136 
137 TEST(AddrRangeTest, EqualToNotEqualTo)
138 {
139  AddrRange r1(0x1234, 0x5678);
140  AddrRange r2(0x1234, 0x5678);
141  AddrRange r3(0x1234, 0x5679);
142 
143  EXPECT_TRUE(r1 == r2);
144  EXPECT_FALSE(r1 == r3);
145  EXPECT_FALSE(r1 != r2);
146  EXPECT_TRUE(r1 != r3);
147 
148  EXPECT_TRUE(r2 == r1);
149  EXPECT_FALSE(r3 == r1);
150  EXPECT_FALSE(r2 != r1);
151  EXPECT_TRUE(r3 != r1);
152 }
153 
154 TEST(AddrRangeTest, MergesWith)
155 {
156  /*
157  * AddrRange.mergesWith will return true if the start, end, and masks
158  * are the same.
159  */
160  AddrRange r1(0x10, 0x1F);
161  AddrRange r2(0x10, 0x1F);
162 
163  EXPECT_TRUE(r1.mergesWith(r2));
164  EXPECT_TRUE(r2.mergesWith(r1));
165 }
166 
167 TEST(AddrRangeTest, DoesNotMergeWith)
168 {
169  AddrRange r1(0x10, 0x1E);
170  AddrRange r2(0x10, 0x1F);
171 
172  EXPECT_FALSE(r1.mergesWith(r2));
173  EXPECT_FALSE(r2.mergesWith(r1));
174 }
175 
176 TEST(AddrRangeTest, IntersectsCompleteOverlap)
177 {
178  AddrRange r1(0x21, 0x30);
179  AddrRange r2(0x21, 0x30);
180 
181  EXPECT_TRUE(r1.intersects(r2));
182  EXPECT_TRUE(r2.intersects(r1));
183 }
184 
185 TEST(AddrRangeTest, IntersectsAddressWithin)
186 {
187  AddrRange r1(0x0, 0xF);
188  AddrRange r2(0x1, 0xE);
189 
190  EXPECT_TRUE(r1.intersects(r2));
191  EXPECT_TRUE(r2.intersects(r1));
192 }
193 
194 TEST(AddrRangeTest, IntersectsPartialOverlap)
195 {
196  AddrRange r1(0x0F0, 0x0FF);
197  AddrRange r2(0x0F5, 0xF00);
198 
199  EXPECT_TRUE(r1.intersects(r2));
200  EXPECT_TRUE(r2.intersects(r1));
201 }
202 
203 TEST(AddrRangeTest, IntersectsNoOverlap)
204 {
205  AddrRange r1(0x00, 0x10);
206  AddrRange r2(0x11, 0xFF);
207 
208  EXPECT_FALSE(r1.intersects(r2));
209  EXPECT_FALSE(r2.intersects(r1));
210 }
211 
212 TEST(AddrRangeTest, IntersectsFirstLastAddressOverlap)
213 {
214  AddrRange r1(0x0, 0xF);
215  AddrRange r2(0xF, 0xF0);
216 
217  /*
218  * The "end address" is not in the range. Therefore, if
219  * r1.end() == r2.start(), the ranges do not intersect.
220  */
221  EXPECT_FALSE(r1.intersects(r2));
222  EXPECT_FALSE(r2.intersects(r1));
223 }
224 
225 TEST(AddrRangeTest, isSubsetCompleteOverlap)
226 {
227  AddrRange r1(0x10, 0x20);
228  AddrRange r2(0x10, 0x20);
229 
230  EXPECT_TRUE(r1.isSubset(r2));
231  EXPECT_TRUE(r2.isSubset(r1));
232 }
233 
234 TEST(AddrRangeTest, isSubsetNoOverlap)
235 {
236  AddrRange r1(0x10, 0x20);
237  AddrRange r2(0x20, 0x22);
238 
239  EXPECT_FALSE(r1.isSubset(r2));
240  EXPECT_FALSE(r2.isSubset(r1));
241 }
242 
243 TEST(AddrRangeTest, isSubsetTrueSubset)
244 {
245  AddrRange r1(0x10, 0x20);
246  AddrRange r2(0x15, 0x17);
247 
248  EXPECT_TRUE(r2.isSubset(r1));
249  EXPECT_FALSE(r1.isSubset(r2));
250 }
251 
252 TEST(AddrRangeTest, isSubsetPartialSubset)
253 {
254  AddrRange r1(0x20, 0x30);
255  AddrRange r2(0x26, 0xF0);
256 
257  EXPECT_FALSE(r1.isSubset(r2));
258  EXPECT_FALSE(r2.isSubset(r1));
259 }
260 
261 TEST(AddrRangeTest, isSubsetInterleavedCompleteOverlap)
262 {
263  AddrRange r1(0x00, 0x100, {0x40}, 0);
264  AddrRange r2(0x00, 0x40);
265 
266  EXPECT_TRUE(r2.isSubset(r1));
267 }
268 
269 TEST(AddrRangeTest, isSubsetInterleavedNoOverlap)
270 {
271  AddrRange r1(0x00, 0x100, {0x40}, 1);
272  AddrRange r2(0x00, 0x40);
273 
274  EXPECT_FALSE(r2.isSubset(r1));
275 }
276 
277 TEST(AddrRangeTest, isSubsetInterleavedPartialOverlap)
278 {
279  AddrRange r1(0x00, 0x100, {0x40}, 0);
280  AddrRange r2(0x10, 0x50);
281 
282  EXPECT_FALSE(r2.isSubset(r1));
283 }
284 
285 TEST(AddrRangeTest, Contains)
286 {
287  AddrRange r(0xF0, 0xF5);
288 
289  EXPECT_FALSE(r.contains(0xEF));
290  EXPECT_TRUE(r.contains(0xF0));
291  EXPECT_TRUE(r.contains(0xF1));
292  EXPECT_TRUE(r.contains(0xF2));
293  EXPECT_TRUE(r.contains(0xF3));
294  EXPECT_TRUE(r.contains(0xF4));
295  EXPECT_FALSE(r.contains(0xF5));
296  EXPECT_FALSE(r.contains(0xF6));
297 }
298 
299 TEST(AddrRangeTest, ContainsInAnEmptyRange)
300 {
301  AddrRange r(0x1, 0x1);
302 
303  EXPECT_FALSE(r.contains(0x1));
304 }
305 
306 TEST(AddrRangeTest, RemoveIntlvBits)
307 {
308  AddrRange r(0x01, 0x10);
309 
310  /*
311  * When there are no masks, AddrRange.removeIntlBits just returns the
312  * address parameter.
313  */
314  Addr a(56);
315  a = r.removeIntlvBits(a);
316  EXPECT_EQ(56, a);
317 }
318 
319 TEST(AddrRangeTest, addIntlvBits)
320 {
321  AddrRange r(0x01, 0x10);
322 
323  /*
324  * As with AddrRange.removeIntlBits, when there are no masks,
325  * AddrRange.addIntlvBits just returns the address parameter.
326  */
327  Addr a(56);
328  a = r.addIntlvBits(a);
329  EXPECT_EQ(56, a);
330 }
331 
332 TEST(AddrRangeTest, OffsetInRange)
333 {
334  AddrRange r(0x01, 0xF0);
335  EXPECT_EQ(0x04, r.getOffset(0x5));
336 }
337 
338 TEST(AddrRangeTest, OffsetOutOfRangeAfter)
339 {
340  /*
341  * If the address is less than the range, MaxAddr is returned.
342  */
343  AddrRange r(0x01, 0xF0);
344  EXPECT_EQ(MaxAddr, r.getOffset(0xF0));
345 }
346 
347 TEST(AddrRangeTest, OffsetOutOfRangeBefore)
348 {
349  AddrRange r(0x05, 0xF0);
350  EXPECT_EQ(MaxAddr, r.getOffset(0x04));
351 }
352 
353 /*
354  * The following tests check the behavior of AddrRange when initialized with
355  * a start and end address, as well as masks to distinguish interleaving bits.
356  */
357 TEST(AddrRangeTest, LsbInterleavingMask)
358 {
359  Addr start = 0x00;
360  Addr end = 0xFF;
361  std::vector<Addr> masks;
362  /*
363  * The address is in range if the LSB is set, i.e. is the value is odd.
364  */
365  masks.push_back(1);
366  uint8_t intlv_match = 1;
367 
368  AddrRange r(start, end, masks, intlv_match);
369  EXPECT_TRUE(r.valid());
370  EXPECT_EQ(start, r.start());
371  EXPECT_EQ(end, r.end());
372  /*
373  * With interleaving, it's assumed the size is equal to
374  * start - end >> [number of masks].
375  */
376  EXPECT_EQ(0x7F, r.size());
377  /*
378  * The Granularity, the size of regions created by the interleaving bits,
379  * which, in this case, is one.
380  */
381  EXPECT_EQ(1, r.granularity());
382  EXPECT_TRUE(r.interleaved());
383  EXPECT_EQ(ULL(2), r.stripes());
384  EXPECT_EQ("[0:0xff] a[0]^\b=1", r.to_string());
385 }
386 
387 TEST(AddrRangeTest, TwoInterleavingMasks)
388 {
389  Addr start = 0x0000;
390  Addr end = 0xFFFF;
391  std::vector<Addr> masks;
392  /*
393  * There are two marks, the two LSBs.
394  */
395  masks.push_back(1);
396  masks.push_back((1 << 1));
397  uint8_t intlv_match = (1 << 1) | 1;
398 
399  AddrRange r(start, end, masks, intlv_match);
400  EXPECT_TRUE(r.valid());
401  EXPECT_EQ(start, r.start());
402  EXPECT_EQ(end, r.end());
403 
404  EXPECT_EQ(0x3FFF, r.size());
405  EXPECT_TRUE(r.interleaved());
406  EXPECT_EQ(ULL(4), r.stripes());
407  EXPECT_EQ("[0:0xffff] a[0]^\b=1 a[1]^\b=1", r.to_string());
408 }
409 
410 TEST(AddrRangeTest, ComplexInterleavingMasks)
411 {
412  Addr start = 0x0000;
413  Addr end = 0xFFFF;
414  std::vector<Addr> masks;
415  masks.push_back((1 << 1) | 1);
416  masks.push_back((ULL(1) << 63) | (ULL(1) << 62));
417  uint8_t intlv_match = 0;
418 
419  AddrRange r(start, end, masks, intlv_match);
420  EXPECT_TRUE(r.valid());
421  EXPECT_EQ(start, r.start());
422  EXPECT_EQ(end, r.end());
423 
424  EXPECT_EQ(0x3FFF, r.size());
425  EXPECT_TRUE(r.interleaved());
426  EXPECT_EQ(ULL(4), r.stripes());
427  EXPECT_EQ("[0:0xffff] a[0]^a[1]^\b=0 a[62]^a[63]^\b=0", r.to_string());
428 }
429 
430 TEST(AddrRangeTest, InterleavingAddressesMergesWith)
431 {
432  Addr start1 = 0x0000;
433  Addr end1 = 0xFFFF;
434  std::vector<Addr> masks;
435  masks.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
436  masks.push_back((1 << 2));
437  uint8_t intlv_match1 = 0;
438  AddrRange r1(start1, end1, masks, intlv_match1);
439 
440  Addr start2 = 0x0000;
441  Addr end2 = 0xFFFF;
442  uint8_t intlv_match2 = 1; // intlv_match may differ.
443  AddrRange r2(start2, end2, masks, intlv_match2);
444 
445  EXPECT_TRUE(r1.mergesWith(r2));
446  EXPECT_TRUE(r2.mergesWith(r1));
447 }
448 
449 TEST(AddrRangeTest, InterleavingAddressesDoNotMergeWith)
450 {
451  Addr start1 = 0x0000;
452  Addr end1 = 0xFFFF;
453  std::vector<Addr> masks1;
454  masks1.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
455  masks1.push_back((1 << 2));
456  uint8_t intlv_match1 = 0;
457  AddrRange r1(start1, end1, masks1, intlv_match1);
458 
459  Addr start2 = 0x0000;
460  Addr end2 = 0xFFFF;
461  std::vector<Addr> masks2;
462  masks2.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
463  masks2.push_back((1 << 3)); // Different mask here.
464  uint8_t intlv_match2 = 1; // intlv_match may differ.
465  AddrRange r2(start2, end2, masks2, intlv_match2);
466 
467  EXPECT_FALSE(r1.mergesWith(r2));
468  EXPECT_FALSE(r2.mergesWith(r1));
469 }
470 
471 TEST(AddrRangeTest, InterleavingAddressesDoNotIntersect)
472 {
473  /*
474  * Range 1: all the odd addresses between 0x0000 and 0xFFFF.
475  */
476  Addr start1 = 0x0000;
477  Addr end1 = 0xFFFF;
478  std::vector<Addr> masks1;
479  masks1.push_back(1);
480  uint8_t intlv_match1 = 1;
481  AddrRange r1(start1, end1, masks1, intlv_match1);
482 
483  /*
484  * Range 2: all the even addresses between 0x0000 and 0xFFFF. These
485  * addresses should thereby not intersect.
486  */
487  Addr start2 = 0x0000;
488  Addr end2 = 0xFFFF;
489  std::vector<Addr> masks2;
490  masks2.push_back(1);
491  uint8_t intv_match2 = 0;
492  AddrRange r2(start2, end2, masks2, intv_match2);
493 
494  EXPECT_FALSE(r1.intersects(r2));
495  EXPECT_FALSE(r2.intersects(r1));
496 }
497 
498 TEST(AddrRangeTest, InterleavingAddressesIntersectsViaMerging)
499 {
500  Addr start1 = 0x0000;
501  Addr end1 = 0xFFFF;
502  std::vector<Addr> masks1;
503  masks1.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
504  masks1.push_back((1 << 2));
505  uint8_t intlv_match1 = 0;
506  AddrRange r1(start1, end1, masks1, intlv_match1);
507 
508  Addr start2 = 0x0000;
509  Addr end2 = 0xFFFF;
510  std::vector<Addr> masks2;
511  masks2.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
512  masks2.push_back((1 << 2));
513  uint8_t intlv_match2 = 0;
514  AddrRange r2(start2, end2, masks2, intlv_match2);
515 
516  EXPECT_TRUE(r1.intersects(r2));
517  EXPECT_TRUE(r2.intersects(r1));
518 }
519 
520 TEST(AddrRangeTest, InterleavingAddressesDoesNotIntersectViaMerging)
521 {
522  Addr start1 = 0x0000;
523  Addr end1 = 0xFFFF;
524  std::vector<Addr> masks1;
525  masks1.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
526  masks1.push_back((1 << 2));
527  uint8_t intlv_match1 = 0;
528  AddrRange r1(start1, end1, masks1, intlv_match1);
529 
530  Addr start2 = 0x0000;
531  Addr end2 = 0xFFFF;
532  std::vector<Addr> masks2;
533  masks2.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
534  masks2.push_back((1 << 2));
535  /*
536  * These addresses can merge, but their intlv_match values differ. They
537  * therefore do not intersect.
538  */
539  uint8_t intlv_match2 = 1;
540  AddrRange r2(start2, end2, masks2, intlv_match2);
541 
542  EXPECT_FALSE(r1.intersects(r2));
543  EXPECT_FALSE(r2.intersects(r1));
544 }
545 
546 /*
547  * The following tests were created to test more complex cases where
548  * interleaving addresses may intersect. However, the "intersects" function
549  * does not cover all cases (a "Cannot test intersection..." exception will
550  * be thrown outside of very simple checks to see if an intersection occurs).
551  * The tests below accurately test whether two ranges intersect but, for now,
552  * code has yet to be implemented to utilize these tests. They are therefore
553  * disabled, but may be enabled at a later date if/when the "intersects"
554  * function is enhanced.
555  */
556 TEST(AddrRangeTest, DISABLED_InterleavingAddressesIntersect)
557 {
558  /*
559  * Range 1: all the odd addresses between 0x0000 and 0xFFFF.
560  */
561  Addr start1 = 0x0000;
562  Addr end1 = 0xFFFF;
563  std::vector<Addr> masks1;
564  masks1.push_back(1);
565  uint8_t intlv_match1 = 0;
566  AddrRange r1(start1, end1, masks1, intlv_match1);
567 
568  /*
569  * Range 2: all the addresses divisible by 4 between 0x0000 and
570  * 0xFFFF. These addresses should thereby intersect.
571  */
572  Addr start2 = 0x0000;
573  Addr end2 = 0xFFFF;
574  std::vector<Addr> masks2;
575  masks2.push_back(1 << 2);
576  uint8_t intlv_match2 = 1;
577  AddrRange r2(start2, end2, masks2, intlv_match2);
578 
579  EXPECT_TRUE(r1.intersects(r2));
580  EXPECT_TRUE(r2.intersects(r1));
581 }
582 
583 TEST(AddrRangeTest, DISABLED_InterleavingAddressesIntersectsOnOneByteAddress)
584 {
585  /*
586  * Range: all the odd addresses between 0x0000 and 0xFFFF.
587  */
588  Addr start = 0x0000;
589  Addr end = 0xFFFF;
590  std::vector<Addr> masks;
591  masks.push_back(1);
592  uint8_t intlv_match = 1;
593  AddrRange r1(start, end, masks, intlv_match);
594 
595  AddrRange r2(0x0000, 0x0001);
596 
597  EXPECT_FALSE(r1.intersects(r2));
598  EXPECT_FALSE(r2.intersects(r1));
599 }
600 
601 TEST(AddrRangeTest,
602  DISABLED_InterleavingAddressesDoesNotIntersectOnOneByteAddress)
603 {
604  /*
605  * Range: all the odd addresses between 0x0000 and 0xFFFF.
606  */
607  Addr start = 0x0000;
608  Addr end = 0xFFFF;
609  std::vector<Addr> masks;
610  masks.push_back(1);
611  uint8_t intlv_match = 1;
612  AddrRange r1(start, end, masks, intlv_match);
613 
614  AddrRange r2(0x0001, 0x0002);
615 
616  EXPECT_TRUE(r1.intersects(r2));
617  EXPECT_TRUE(r2.intersects(r1));
618 }
619 
620 
621 /*
622  * The following three tests were created to test the addr_range.isSubset
623  * function for Interleaving address ranges. However, for now, this
624  * functionality has not been implemented. These tests are therefore disabled.
625  */
626 TEST(AddrRangeTest, DISABLED_InterleavingAddressIsSubset)
627 {
628  // Range 1: all the even addresses between 0x0000 and 0xFFFF.
629  Addr start1 = 0x0000;
630  Addr end1 = 0xFFFF;
631  std::vector<Addr> masks1;
632  masks1.push_back(1);
633  uint8_t intlv_match1 = 0;
634  AddrRange r1(start1, end1, masks1, intlv_match1);
635 
636  // Range 2: all the even addresses between 0xF000 and 0x0FFF, this is
637  // a subset of Range 1.
638  Addr start2 = 0xF000;
639  Addr end2 = 0x0FFF;
640  std::vector<Addr> masks2;
641  masks2.push_back(1);
642  uint8_t intlv_match2 = 0;
643  AddrRange r2(start2, end2, masks2, intlv_match2);
644 
645  EXPECT_TRUE(r1.isSubset(r2));
646  EXPECT_TRUE(r2.isSubset(r1));
647 }
648 
649 TEST(AddrRangeTest, DISABLED_InterleavingAddressIsNotSubset)
650 {
651  //Range 1: all the even addresses between 0x0000 and 0xFFFF.
652  Addr start1 = 0x0000;
653  Addr end1 = 0xFFFF;
654  std::vector<Addr> masks1;
655  masks1.push_back(1);
656  uint8_t intlv_match1 = 0;
657  AddrRange r1(start1, end1, masks1, intlv_match1);
658 
659 
660  // Range 2: all the odd addresses between 0xF000 and 0x0FFF, this is
661  //a subset of Range 1.
662  Addr start2 = 0xF000;
663  Addr end2 = 0x0FFF;
664  std::vector<Addr> masks2;
665  masks2.push_back(1);
666  uint8_t intlv_match2 = 1;
667  AddrRange r2(start2, end2, masks2, intlv_match2);
668 
669  EXPECT_FALSE(r1.isSubset(r2));
670  EXPECT_FALSE(r2.isSubset(r1));
671 }
672 
673 TEST(AddrRangeTest, DISABLED_InterleavingAddressContains)
674 {
675  /*
676  * Range: all the address between 0x0 and 0xFF which have both the 1st
677  * and 5th bits 1, or both are 0
678  */
679  Addr start = 0x00;
680  Addr end = 0xFF;
681  std::vector<Addr> masks;
682  masks.push_back((1 << 4) | 1);
683  uint8_t intlv_match = 0;
684  AddrRange r(start, end, masks, intlv_match);
685 
686  for (Addr addr = start; addr < end; addr++) {
687  if (((addr & 1) && ((1 << 4) & addr)) || // addr[0] && addr[4]
688  (!(addr & 1) && !((1 << 4) & addr))) {
689  EXPECT_TRUE(r.contains(addr));
690  } else {
691  EXPECT_FALSE(r.contains(addr));
692  }
693  }
694 }
695 
696 TEST(AddrRangeTest, InterleavingAddressAddRemoveInterlvBits)
697 {
698  Addr start = 0x00000;
699  Addr end = 0x10000;
700  std::vector<Addr> masks;
701  masks.push_back(1);
702  uint8_t intlv_match = 1;
703  AddrRange r(start, end, masks, intlv_match);
704 
705  Addr input = 0xFFFF;
706  Addr output = r.removeIntlvBits(input);
707 
708  /*
709  * The removeIntlvBits function removes the LSB from each mask from the
710  * input address. For example, two masks:
711  * 00000001 and,
712  * 10000100
713  * with an input address of:
714  * 10101010
715  *
716  * we would remove bit at position 0, and at position 2, resulting in:
717  * 00101011
718  *
719  * In this test there is is one mask, with a LSB at position 0.
720  * Therefore, removing the interleaving bits is equivilant to bitshifting
721  * the input to the right.
722  */
723  EXPECT_EQ(input >> 1, output);
724 
725  /*
726  * The addIntlvBits function will re-insert bits at the removed locations
727  */
728  EXPECT_EQ(input, r.addIntlvBits(output));
729 }
730 
731 TEST(AddrRangeTest, InterleavingAddressAddRemoveInterlvBitsTwoMasks)
732 {
733  Addr start = 0x00000;
734  Addr end = 0x10000;
735  std::vector<Addr> masks;
736  masks.push_back((1 << 3) | (1 << 2) | (1 << 1) | 1);
737  masks.push_back((1 << 11) | (1 << 10) | (1 << 9) | (1 << 8));
738  uint8_t intlv_match = 1;
739  AddrRange r(start, end, masks, intlv_match);
740 
741  Addr input = (1 << 9) | (1 << 8) | 1;
742  /*
743  * (1 << 8) and 1 are interleaving bits to be removed.
744  */
745  Addr output = r.removeIntlvBits(input);
746 
747  /*
748  * The bit, formally at position 9, is now at 7.
749  */
750  EXPECT_EQ((1 << 7), output);
751 
752  /*
753  * Re-adding the interleaving.
754  */
755  EXPECT_EQ(input, r.addIntlvBits(output));
756 }
757 
758 TEST(AddrRangeTest, AddRemoveInterleavBitsAcrossRange)
759 {
760  /*
761  * This purpose of this test is to ensure that removing then adding
762  * interleaving bits has no net effect.
763  * E.g.:
764  * addr_range.addIntlvBits(add_range.removeIntlvBits(an_address)) should
765  * always return an_address.
766  */
767  Addr start = 0x00000;
768  Addr end = 0x10000;
769  std::vector<Addr> masks;
770  masks.push_back(1 << 2);
771  masks.push_back(1 << 3);
772  masks.push_back(1 << 16);
773  masks.push_back(1 << 30);
774  uint8_t intlv_match = 0xF;
775  AddrRange r(start, end, masks, intlv_match);
776 
777  for (Addr i = 0; i < 0xFFF; i++) {
778  Addr removedBits = r.removeIntlvBits(i);
779  /*
780  * As intlv_match = 0xF, all the interleaved bits should be set.
781  */
782  EXPECT_EQ(i | (1 << 2) | (1 << 3) | (1 << 16) | (1 << 30),
783  r.addIntlvBits(removedBits));
784  }
785 }
786 
787 TEST(AddrRangeTest, InterleavingAddressesGetOffset)
788 {
789  Addr start = 0x0002;
790  Addr end = 0xFFFF;
791  std::vector<Addr> masks;
792  masks.push_back((1 << 4) | (1 << 2));
793  uint8_t intlv_match = 0;
794  AddrRange r(start, end, masks, intlv_match);
795 
796  Addr value = ((1 << 10) | (1 << 9) | (1 << 8) | (1 << 2) | (1 << 1) | 1);
797  Addr value_interleaving_bits_removed =
798  ((1 << 9) | (1 << 8) | (1 << 7) | (1 << 1) | 1);
799 
800  Addr expected_output = value_interleaving_bits_removed - start;
801 
802  EXPECT_EQ(expected_output, r.getOffset(value));
803 }
804 
805 TEST(AddrRangeTest, InterleavingLessThanStartEquals)
806 {
807  Addr start1 = 0x0000FFFF;
808  Addr end1 = 0xFFFF0000;
809  std::vector<Addr> masks1;
810  masks1.push_back((1 << 4) | (1 << 2));
811  uint8_t intlv_match1 = 0;
812  AddrRange r1(start1, end1, masks1, intlv_match1);
813 
814  Addr start2 = 0x0000FFFF;
815  Addr end2 = 0x000F0000;
816  std::vector<Addr> masks2;
817  masks2.push_back((1 << 4) | (1 << 2));
818  masks2.push_back((1 << 10));
819  uint8_t intlv_match2 = 2;
820  AddrRange r2(start2, end2, masks2, intlv_match2);
821 
822  /*
823  * When The start addresses are equal, the intlv_match values are
824  * compared.
825  */
826  EXPECT_TRUE(r1 < r2);
827  EXPECT_FALSE(r2 < r1);
828 }
829 
830 TEST(AddrRangeTest, InterleavingLessThanStartNotEquals)
831 {
832  Addr start1 = 0x0000FFFF;
833  Addr end1 = 0xFFFF0000;
834  std::vector<Addr> masks1;
835  masks1.push_back((1 << 4) | (1 << 2));
836  uint8_t intlv_match1 = 0;
837  AddrRange r1(start1, end1, masks1, intlv_match1);
838 
839  Addr start2 = 0x0000FFFE;
840  Addr end2 = 0x000F0000;
841  std::vector<Addr> masks2;
842  masks2.push_back((1 << 4) | (1 << 2));
843  masks2.push_back((1 << 10));
844  uint8_t intlv_match2 = 2;
845  AddrRange r2(start2, end2, masks2, intlv_match2);
846 
847  EXPECT_TRUE(r2 < r1);
848  EXPECT_FALSE(r1 < r2);
849 }
850 
851 TEST(AddrRangeTest, InterleavingEqualTo)
852 {
853  Addr start1 = 0x0000FFFF;
854  Addr end1 = 0xFFFF0000;
855  std::vector<Addr> masks1;
856  masks1.push_back((1 << 4) | (1 << 2));
857  uint8_t intlv_match1 = 0;
858  AddrRange r1(start1, end1, masks1, intlv_match1);
859 
860  Addr start2 = 0x0000FFFF;
861  Addr end2 = 0xFFFF0000;
862  std::vector<Addr> masks2;
863  masks2.push_back((1 << 4) | (1 << 2));
864  uint8_t intlv_match2 = 0;
865  AddrRange r2(start2, end2, masks2, intlv_match2);
866 
867  EXPECT_TRUE(r1 == r2);
868 }
869 
870 TEST(AddrRangeTest, InterleavingNotEqualTo)
871 {
872  Addr start1 = 0x0000FFFF;
873  Addr end1 = 0xFFFF0000;
874  std::vector<Addr> masks1;
875  masks1.push_back((1 << 4) | (1 << 2));
876  uint8_t intlv_match1 = 0;
877  AddrRange r1(start1, end1, masks1, intlv_match1);
878 
879  Addr start2 = 0x0000FFFF;
880  Addr end2 = 0xFFFF0000;
881  std::vector<Addr> masks2;
882  masks2.push_back((1 << 4) | (1 << 2));
883  masks2.push_back((1 << 10));
884  uint8_t intlv_match2 = 2;
885  AddrRange r2(start2, end2, masks2, intlv_match2);
886 
887  /*
888  * These ranges are not equal due to having different masks.
889  */
890  EXPECT_FALSE(r1 == r2);
891 }
892 
893 /*
894  * The AddrRange(std::vector<AddrRange>) constructor "merges" the interleaving
895  * address ranges. It should be noted that this constructor simply checks that
896  * these interleaving addresses can be merged then creates a new address from
897  * the start and end addresses of the first address range in the vector.
898  */
899 TEST(AddrRangeTest, MergingInterleavingAddressRanges)
900 {
901  Addr start1 = 0x0000;
902  Addr end1 = 0xFFFF;
903  std::vector<Addr> masks1;
904  masks1.push_back((1 << 4) | (1 << 2));
905  uint8_t intlv_match1 = 0;
906  AddrRange r1(start1, end1, masks1, intlv_match1);
907 
908  Addr start2 = 0x0000;
909  Addr end2 = 0xFFFF;
910  std::vector<Addr> masks2;
911  masks2.push_back((1 << 4) | (1 << 2));
912  uint8_t intlv_match2 = 1;
913  AddrRange r2(start2, end2, masks2, intlv_match2);
914 
915  std::vector<AddrRange> to_merge;
916  to_merge.push_back(r1);
917  to_merge.push_back(r2);
918 
919  AddrRange output(to_merge);
920 
921  EXPECT_EQ(0x0000, output.start());
922  EXPECT_EQ(0xFFFF, output.end());
923  EXPECT_FALSE(output.interleaved());
924 }
925 
926 TEST(AddrRangeTest, MergingInterleavingAddressRangesOneRange)
927 {
928  /*
929  * In the case where there is just one range in the vector, the merged
930  * address range is equal to that range.
931  */
932  Addr start = 0x0000;
933  Addr end = 0xFFFF;
934  std::vector<Addr> masks;
935  masks.push_back((1 << 4) | (1 << 2));
936  uint8_t intlv_match = 0;
937  AddrRange r(start, end, masks, intlv_match);
938 
939  std::vector<AddrRange> to_merge;
940  to_merge.push_back(r);
941 
942  AddrRange output(to_merge);
943 
944  EXPECT_EQ(r, output);
945 }
946 
947 /*
948  * The following tests verify the soundness of the "legacy constructor",
949  * AddrRange(Addr, Addr, uint8_t, uint8_t, uint8_t, uint8_t).
950  *
951  * The address is assumed to contain two ranges; the interleaving bits, and
952  * the xor bits. The first two arguments of this constructor specify the
953  * start and end addresses. The third argument specifies the MSB of the
954  * interleaving bits. The fourth argument specifies the MSB of the xor bits.
955  * The firth argument specifies the size (in bits) of the xor and interleaving
956  * bits. These cannot overlap. The sixth argument specifies the value the
957  * XORing of the xor and interleaving bits should equal to be considered in
958  * range.
959  *
960  * This constructor does a lot of complex translation to migrate this
961  * constructor to the masks/intlv_match format.
962  */
963 TEST(AddrRangeTest, LegacyConstructorNoInterleaving)
964 {
965  /*
966  * This constructor should create a range with no interleaving.
967  */
968  AddrRange range(0x0000, 0xFFFF, 0, 0, 0 ,0);
969  AddrRange expected(0x0000, 0xFFFF);
970 
971  EXPECT_EQ(expected, range);
972 }
973 
974 TEST(AddrRangeTest, LegacyConstructorOneBitMask)
975 {
976  /*
977  * In this test, the LSB of the address determines whether an address is
978  * in range. If even, it's in range, if not, it's out of range. the XOR
979  * bit range is not used.
980  */
981  AddrRange range(0x00000000, 0xFFFFFFFF, 0, 0, 1, 0);
982 
983  std::vector<Addr> masks;
984  masks.push_back(1);
985  AddrRange expected(0x00000000, 0xFFFFFFFF, masks, 0);
986 
987  EXPECT_TRUE(expected == range);
988 }
989 
990 TEST(AddrRangeTest, LegacyConstructorTwoBitMask)
991 {
992  /*
993  * In this test, the two LSBs of the address determines whether an address
994  * is in range. If the two are set, the address is in range. The XOR bit
995  * range is not used.
996  */
997  AddrRange range(0x00000000, 0xFFFFFFFF, 1, 0, 2, 3);
998 
999  std::vector<Addr> masks;
1000  masks.push_back(1);
1001  masks.push_back((1 << 1));
1002  AddrRange expected(0x00000000, 0xFFFFFFFF, masks, 3);
1003 
1004  EXPECT_TRUE(expected == range);
1005 }
1006 
1007 TEST(AddrRangeTest, LegacyConstructorTwoBitMaskWithXOR)
1008 {
1009  /*
1010  * In this test, the two LSBs of the address determine wether an address
1011  * is in range. They are XORed to the 10th and 11th bits in the address.
1012  * If XORed value is equal to 3, then the address is in range.
1013  */
1014 
1015  AddrRange range(0x00000000, 0xFFFFFFFF, 1, 11, 2, 3);
1016 
1017  /*
1018  * The easiest way to ensure this range is correct is to iterate throguh
1019  * the address range and ensure the correct set of addresses are contained
1020  * within the range.
1021  *
1022  * We start with the xor_mask: a mask to select the 10th and 11th bits.
1023  */
1024  Addr xor_mask = (1 << 11) | (1 << 10);
1025  for (Addr i = 0; i < 0x0000FFFF; i++) {
1026  // Get xor bits.
1027  Addr xor_value = (xor_mask & i) >> 10;
1028  /* If the XOR of xor_bits and the intlv bits (the 0th and 1st bits) is
1029  * equal to intlv_match (3, i.e., the 0th and 1st bit is set),then the
1030  * address is within range.
1031  */
1032  if (((xor_value ^ i) & 3) == 3) {
1033  EXPECT_TRUE(range.contains(i));
1034  } else {
1035  EXPECT_FALSE(range.contains(i));
1036  }
1037  }
1038 }
1039 
1040 /*
1041  * addr_range.hh contains some convenience constructors. The following tests
1042  * verify they construct AddrRange correctly.
1043  */
1044 TEST(AddrRangeTest, RangeExConstruction)
1045 {
1046  AddrRange r = RangeEx(0x6, 0xE);
1047  EXPECT_EQ(0x6, r.start());
1048  EXPECT_EQ(0xE, r.end());
1049 }
1050 
1051 TEST(AddrRangeTest, RangeInConstruction)
1052 {
1053  AddrRange r = RangeIn(0x6, 0xE);
1054  EXPECT_EQ(0x6, r.start());
1055  EXPECT_EQ(0xF, r.end());
1056 }
1057 
1058 TEST(AddrRangeTest, RangeSizeConstruction){
1059  AddrRange r = RangeSize(0x5, 5);
1060  EXPECT_EQ(0x5, r.start());
1061  EXPECT_EQ(0xA, r.end());
1062 }
output
static void output(const char *filename)
Definition: debug.cc:60
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
AddrRange::contains
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:435
std::vector< Addr >
MaxAddr
const Addr MaxAddr
Definition: types.hh:166
EXPECT_EQ
#define EXPECT_EQ(lhs, rhs)
A macro which verifies that lhs and rhs are equal to each other.
Definition: unittest.hh:110
EXPECT_FALSE
#define EXPECT_FALSE(expr)
A macro which verifies that expr evaluates to false.
Definition: unittest.hh:106
ArmISA::a
Bitfield< 8 > a
Definition: miscregs_types.hh:62
bitfield.hh
AddrRange
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition: addr_range.hh:68
EXPECT_TRUE
#define EXPECT_TRUE(expr)
A macro which verifies that expr evaluates to true.
Definition: unittest.hh:103
MipsISA::r
r
Definition: pra_constants.hh:95
RangeSize
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:638
AddrRange::intersects
bool intersects(const AddrRange &r) const
Determine if another range intersects this one, i.e.
Definition: addr_range.hh:376
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
addr_range.hh
TEST
TEST(AddrRangeTest, ValidRange)
Definition: addr_range.test.cc:46
addr
ip6_addr_t addr
Definition: inet.hh:423
AddrRange::mergesWith
bool mergesWith(const AddrRange &r) const
Determine if another range merges with the current one, i.e.
Definition: addr_range.hh:360
RangeEx
AddrRange RangeEx(Addr start, Addr end)
Definition: addr_range.hh:624
AddrRange::isSubset
bool isSubset(const AddrRange &r) const
Determine if this range is a subset of another range, i.e.
Definition: addr_range.hh:410
RangeIn
AddrRange RangeIn(Addr start, Addr end)
Definition: addr_range.hh:631
ULL
#define ULL(N)
uint64_t constant
Definition: types.hh:50
expected
std::vector< SwitchingFiber * > expected({ &a, &b, &a, &a, &a, &b, &c, &a, &c, &c, &c })

Generated on Wed Sep 30 2020 14:02:07 for gem5 by doxygen 1.8.17