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

Generated on Tue Sep 21 2021 12:24:52 for gem5 by doxygen 1.8.17