summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/x86/tlb.cc4
-rw-r--r--src/base/addr_range.hh24
-rw-r--r--src/base/addr_range.test.cc1079
-rw-r--r--src/dev/arm/gic_v2.cc20
-rw-r--r--src/dev/arm/gic_v3_distributor.cc28
-rw-r--r--src/dev/arm/gic_v3_its.cc2
-rw-r--r--src/dev/arm/gic_v3_redistributor.cc2
-rw-r--r--src/python/m5/params.py6
-rw-r--r--src/sim/system.cc2
9 files changed, 983 insertions, 184 deletions
diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc
index 84965b881..2985a8bcb 100644
--- a/src/arch/x86/tlb.cc
+++ b/src/arch/x86/tlb.cc
@@ -229,7 +229,7 @@ TLB::finalizePhysical(const RequestPtr &req,
{
Addr paddr = req->getPaddr();
- AddrRange m5opRange(0xFFFF0000, 0xFFFFFFFF);
+ AddrRange m5opRange(0xFFFF0000, 0x100000000);
if (m5opRange.contains(paddr)) {
req->setFlags(Request::MMAPPED_IPR | Request::GENERIC_IPR |
@@ -241,7 +241,7 @@ TLB::finalizePhysical(const RequestPtr &req,
LocalApicBase localApicBase =
tc->readMiscRegNoEffect(MISCREG_APIC_BASE);
AddrRange apicRange(localApicBase.base * PageBytes,
- (localApicBase.base + 1) * PageBytes - 1);
+ (localApicBase.base + 1) * PageBytes);
if (apicRange.contains(paddr)) {
// The Intel developer's manuals say the below restrictions apply,
diff --git a/src/base/addr_range.hh b/src/base/addr_range.hh
index 84a3d4de5..2a18551b2 100644
--- a/src/base/addr_range.hh
+++ b/src/base/addr_range.hh
@@ -75,7 +75,8 @@ class AddrRange
private:
/// Private fields for the start and end of the range
- /// Both _start and _end are part of the range.
+ /// _start is the beginning of the range (inclusive).
+ /// _end is not part of the range.
Addr _start;
Addr _end;
@@ -121,7 +122,7 @@ class AddrRange
* @param _start The start address of this range
* @param _end The end address of this range (not included in the range)
* @param _masks The input vector of masks
- * @param intlv_math The matching value of the xor operations
+ * @param intlv_match The matching value of the xor operations
*/
AddrRange(Addr _start, Addr _end, const std::vector<Addr> &_masks,
uint8_t _intlv_match)
@@ -155,7 +156,8 @@ class AddrRange
* @param _end The end address of this range (not included in the range)
* @param _intlv_high_bit The MSB of the intlv bits (disabled if 0)
* @param _xor_high_bit The MSB of the xor bit (disabled if 0)
- * @param intlv_math The matching value of the xor operations
+ * @param _intlv_bits the size, in bits, of the intlv and xor bits
+ * @param intlv_match The matching value of the xor operations
*/
AddrRange(Addr _start, Addr _end, uint8_t _intlv_high_bit,
uint8_t _xor_high_bit, uint8_t _intlv_bits,
@@ -281,7 +283,7 @@ class AddrRange
*/
Addr size() const
{
- return (_end - _start + 1) >> masks.size();
+ return (_end - _start) >> masks.size();
}
/**
@@ -348,7 +350,7 @@ class AddrRange
*/
bool intersects(const AddrRange& r) const
{
- if (_start > r._end || _end < r._start)
+ if (_start >= r._end || _end <= r._start)
// start with the simple case of no overlap at all,
// applicable even if we have interleaved ranges
return false;
@@ -406,7 +408,7 @@ class AddrRange
// check if the address is in the range and if there is either
// no interleaving, or with interleaving also if the selected
// bits from the address match the interleaving value
- bool in_range = a >= _start && a <= _end;
+ bool in_range = a >= _start && a < _end;
if (in_range) {
auto sel = 0;
for (int i = 0; i < masks.size(); i++) {
@@ -441,7 +443,7 @@ class AddrRange
* | 0 | a_high | a_mid | a_low |
* ---------------------------------
*
- * @param the input address
+ * @param a the input address
* @return the new address
*/
inline Addr removeIntlvBits(Addr a) const
@@ -521,7 +523,7 @@ class AddrRange
*/
Addr getOffset(const Addr& a) const
{
- bool in_range = a >= _start && a <= _end;
+ bool in_range = a >= _start && a < _end;
if (!in_range) {
return MaxAddr;
}
@@ -572,14 +574,14 @@ typedef std::list<AddrRange> AddrRangeList;
inline AddrRange
RangeEx(Addr start, Addr end)
-{ return AddrRange(start, end - 1); }
+{ return AddrRange(start, end); }
inline AddrRange
RangeIn(Addr start, Addr end)
-{ return AddrRange(start, end); }
+{ return AddrRange(start, end + 1); }
inline AddrRange
RangeSize(Addr start, Addr size)
-{ return AddrRange(start, start + size - 1); }
+{ return AddrRange(start, start + size); }
#endif // __BASE_ADDR_RANGE_HH__
diff --git a/src/base/addr_range.test.cc b/src/base/addr_range.test.cc
index 93afbb0e7..4ab4ae402 100644
--- a/src/base/addr_range.test.cc
+++ b/src/base/addr_range.test.cc
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2019 The Regents of the University of California
* Copyright (c) 2018-2019 ARM Limited
* All rights reserved
*
@@ -35,210 +36,1006 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Nikos Nikoleris
+ * Bobby R. Bruce
*/
#include <gtest/gtest.h>
+#include <cmath>
+
#include "base/addr_range.hh"
#include "base/bitfield.hh"
-TEST(AddrRangeComp, AddrRangeIsSubset)
+TEST(AddrRangeTest, ValidRange)
{
- AddrRange r, r1, r2;
+ AddrRange r;
+ EXPECT_FALSE(r.valid());
+}
+
+/*
+ * This following tests check the behavior of AddrRange when initialized with
+ * a start and end address. The expected behavior is that the first address
+ * within the range will be the start address, and the last address in the
+ * range will be the (end - 1) address.
+ */
+TEST(AddrRangeTest, EmptyRange)
+{
+ AddrRange r(0x0, 0x0);
+
+ /*
+ * Empty ranges are valid.
+ */
+ EXPECT_TRUE(r.valid());
+ EXPECT_EQ(0x0, r.start());
+ EXPECT_EQ(0x0, r.end());
+ EXPECT_EQ(0, r.size());
- // Test non-interleaved ranges
- r1 = AddrRange(0x0, 0x7f);
- r2 = AddrRange(0x80, 0xff);
+ /*
+ * With no masks, granularity equals the size of the range.
+ */
+ EXPECT_EQ(0, r.granularity());
- r = AddrRange(0x0, 0xf);
- EXPECT_TRUE(r.isSubset(r1));
- EXPECT_FALSE(r.isSubset(r2));
+ /*
+ * With no masks, "interleaved()" returns false.
+ */
+ EXPECT_FALSE(r.interleaved());
- r = AddrRange(0x80, 0x8f);
- EXPECT_FALSE(r.isSubset(r1));
- EXPECT_TRUE(r.isSubset(r2));
+ /*
+ * With no masks, "stripes()" returns ULL(1).
+ */
+ EXPECT_EQ(ULL(1), r.stripes());
+ EXPECT_EQ("[0:0]", r.to_string());
+}
- // Test interleaved ranges
- r1 = AddrRange(0x0, 0xff, 6, 0, 1, 0);
- r2 = AddrRange(0x0, 0xff, 6, 0, 1, 1);
+TEST(AddrRangeTest, RangeSizeOfOne)
+{
+ AddrRange r(0x0, 0x1);
+ EXPECT_TRUE(r.valid());
+ EXPECT_EQ(0x0, r.start());
+ EXPECT_EQ(0x1, r.end());
+ EXPECT_EQ(1, r.size());
+ EXPECT_EQ(1, r.granularity());
+ EXPECT_FALSE(r.interleaved());
+ EXPECT_EQ(ULL(1), r.stripes());
+ EXPECT_EQ("[0:0x1]", r.to_string());
+}
- r = AddrRange(0x0, 0xf);
- EXPECT_TRUE(r.isSubset(r1));
- EXPECT_FALSE(r.isSubset(r2));
+TEST(AddrRangeTest, Range16Bit)
+{
+ AddrRange r(0xF000, 0xFFFF);
+ EXPECT_TRUE(r.valid());
+ EXPECT_EQ(0xF000, r.start());
+ EXPECT_EQ(0xFFFF, r.end());
+ EXPECT_EQ(0x0FFF, r.size());
+ EXPECT_EQ(0x0FFF, r.granularity());
+ EXPECT_FALSE(r.interleaved());
+ EXPECT_EQ(ULL(1), r.stripes());
+ EXPECT_EQ("[0xf000:0xffff]", r.to_string());
+}
- r = AddrRange(0x40, 0x4f);
- EXPECT_FALSE(r.isSubset(r1));
- EXPECT_TRUE(r.isSubset(r2));
+TEST(AddrRangeTest, InvalidRange)
+{
+ AddrRange r(0x1, 0x0);
+ EXPECT_FALSE(r.valid());
+}
- r = AddrRange(0xbf, 0xc0);
- EXPECT_FALSE(r.isSubset(r1));
- EXPECT_FALSE(r.isSubset(r2));
+TEST(AddrRangeTest, LessThan)
+{
+ /*
+ * The less-than override is a bit unintuitive and does not have a
+ * corresponding greater than. It compares the AddrRange.start() values.
+ * If they are equal, the "intlvMatch" values are compared. This is
+ * zero when AddRange is initialized with a just a start and end address.
+ */
+ AddrRange r1(0xF000, 0xFFFF);
+ AddrRange r2(0xF001, 0xFFFF);
+ AddrRange r3(0xF000, 0xFFFF);
- // Test interleaved ranges with hashing
- r1 = AddrRange(0x0, 0xff, 6, 7, 1, 0);
- r2 = AddrRange(0x0, 0xff, 6, 7, 1, 1);
+ EXPECT_TRUE(r1 < r2);
+ EXPECT_FALSE(r2 < r1);
+ EXPECT_FALSE(r1 < r3);
+ EXPECT_FALSE(r3 < r1);
+}
- r = AddrRange(0x0, 0xf);
- EXPECT_TRUE(r.isSubset(r1));
- EXPECT_FALSE(r.isSubset(r2));
+TEST(AddrRangeTest, EqualToNotEqualTo)
+{
+ AddrRange r1(0x1234, 0x5678);
+ AddrRange r2(0x1234, 0x5678);
+ AddrRange r3(0x1234, 0x5679);
- r = AddrRange(0x40, 0x4f);
- EXPECT_FALSE(r.isSubset(r1));
- EXPECT_TRUE(r.isSubset(r2));
+ EXPECT_TRUE(r1 == r2);
+ EXPECT_FALSE(r1 == r3);
+ EXPECT_FALSE(r1 != r2);
+ EXPECT_TRUE(r1 != r3);
- r = AddrRange(0xbf, 0xc0);
- EXPECT_FALSE(r.isSubset(r1));
- EXPECT_FALSE(r.isSubset(r2));
+ EXPECT_TRUE(r2 == r1);
+ EXPECT_FALSE(r3 == r1);
+ EXPECT_FALSE(r2 != r1);
+ EXPECT_TRUE(r3 != r1);
}
-class AddrRangeBase : public testing::Test {
- protected:
+TEST(AddrRangeTest, MergesWith)
+{
+ /*
+ * AddrRange.mergesWith will return true if the start, end, and masks
+ * are the same.
+ */
+ AddrRange r1(0x10, 0x1F);
+ AddrRange r2(0x10, 0x1F);
- virtual int getIndex(Addr addr) = 0;
+ EXPECT_TRUE(r1.mergesWith(r2));
+ EXPECT_TRUE(r2.mergesWith(r1));
+}
- void testContains()
- {
- for (Addr addr = start; addr <= end; addr++) {
- int i = getIndex(addr);
- ASSERT_TRUE(range[i].contains(addr));
- for (int j = 1; j < intlvSize; j++) {
- ASSERT_FALSE(range[(i + j) % intlvSize].contains(addr));
- }
- }
- }
+TEST(AddrRangeTest, DoesNotMergeWith)
+{
+ AddrRange r1(0x10, 0x1E);
+ AddrRange r2(0x10, 0x1F);
- void testGetOffset()
- {
- Addr offsets[intlvSize] = {0, 0, 0, 0};
- for (Addr addr = start; addr <= end; addr++) {
- int i = getIndex(addr);
- Addr offset = range[i].getOffset(addr);
- ASSERT_EQ(offsets[i], offset);
- offsets[i]++;
- }
- for (Addr offset: offsets) {
- ASSERT_EQ(offset, (end - start + 1) / intlvSize);
- }
- }
+ EXPECT_FALSE(r1.mergesWith(r2));
+ EXPECT_FALSE(r2.mergesWith(r1));
+}
- void testAddRemoveIntlvBits()
- {
- for (Addr addr = start; addr <= end; addr++) {
- AddrRange &r = range[getIndex(addr)];
- Addr ch_addr = r.removeIntlvBits(addr);
- Addr pa = r.addIntlvBits(ch_addr);
- ASSERT_EQ(addr, pa);
- }
- }
+TEST(AddrRangeTest, IntersectsCompleteOverlap)
+{
+ AddrRange r1(0x21, 0x30);
+ AddrRange r2(0x21, 0x30);
- static const Addr end = 0x1ffff;
- static const Addr start = 0x0;
- static const int intlvSize = 4;
+ EXPECT_TRUE(r1.intersects(r2));
+ EXPECT_TRUE(r2.intersects(r1));
+}
- AddrRange range[intlvSize];
-};
+TEST(AddrRangeTest, IntersectsAddressWithin)
+{
+ AddrRange r1(0x0, 0xF);
+ AddrRange r2(0x1, 0xE);
+ EXPECT_TRUE(r1.intersects(r2));
+ EXPECT_TRUE(r2.intersects(r1));
+}
-class AddrRangeCont : public AddrRangeBase {
- protected:
- void SetUp() override
- {
- std::vector<Addr> masks = {
- 1UL << xorBits0[0] | 1UL << xorBits0[1],
- 1UL << xorBits1[0] | 1UL << xorBits1[1]
- };
- for (auto i = 0; i < intlvSize; i++) {
- range[i] = AddrRange(start, end, masks, i);
- }
- }
+TEST(AddrRangeTest, IntersectsPartialOverlap)
+{
+ AddrRange r1(0x0F0, 0x0FF);
+ AddrRange r2(0x0F5, 0xF00);
- int getIndex(Addr addr) override
- {
- return bits(addr, xorBits1[1], xorBits0[1]) ^
- bits(addr, xorBits1[0], xorBits0[0]);
- }
+ EXPECT_TRUE(r1.intersects(r2));
+ EXPECT_TRUE(r2.intersects(r1));
+}
+
+TEST(AddrRangeTest, IntersectsNoOverlap)
+{
+ AddrRange r1(0x00, 0x10);
+ AddrRange r2(0x11, 0xFF);
+
+ EXPECT_FALSE(r1.intersects(r2));
+ EXPECT_FALSE(r2.intersects(r1));
+}
+
+TEST(AddrRangeTest, IntersectsFirstLastAddressOverlap)
+{
+ AddrRange r1(0x0, 0xF);
+ AddrRange r2(0xF, 0xF0);
- const int xorBits0[2] = {8, 14};
- const int xorBits1[2] = {9, 15};
-};
+ /*
+ * The "end address" is not in the range. Therefore, if
+ * r1.end() == r2.start(), the ranges do not intersect.
+ */
+ EXPECT_FALSE(r1.intersects(r2));
+ EXPECT_FALSE(r2.intersects(r1));
+}
-TEST_F(AddrRangeCont, AddrRangeContains)
+TEST(AddrRangeTest, isSubsetCompleteOverlap)
{
- testContains();
+ AddrRange r1(0x10, 0x20);
+ AddrRange r2(0x10, 0x20);
+
+ EXPECT_TRUE(r1.isSubset(r2));
+ EXPECT_TRUE(r2.isSubset(r1));
}
-TEST_F(AddrRangeCont, AddrRangeGetOffset)
+TEST(AddrRangeTest, isSubsetNoOverlap)
{
- testGetOffset();
+ AddrRange r1(0x10, 0x20);
+ AddrRange r2(0x20, 0x22);
+
+ EXPECT_FALSE(r1.isSubset(r2));
+ EXPECT_FALSE(r2.isSubset(r1));
}
-TEST_F(AddrRangeCont, AddrRangeAddRemoveIntlvBits)
+TEST(AddrRangeTest, isSubsetTrueSubset)
{
- testAddRemoveIntlvBits();
+ AddrRange r1(0x10, 0x20);
+ AddrRange r2(0x15, 0x17);
+
+ EXPECT_TRUE(r2.isSubset(r1));
+ EXPECT_FALSE(r1.isSubset(r2));
}
+TEST(AddrRangeTest, isSubsetPartialSubset)
+{
+ AddrRange r1(0x20, 0x30);
+ AddrRange r2(0x26, 0xF0);
-class AddrRangeContLegacy : public AddrRangeCont {
- protected:
- void SetUp() override
- {
- // Test interleaved ranges with hashing
- for (auto i = 0; i < intlvSize; i++) {
- range[i] = AddrRange(start, end, xorBits1[0], xorBits1[1],
- 2, i);
- }
- }
-};
+ EXPECT_FALSE(r1.isSubset(r2));
+ EXPECT_FALSE(r2.isSubset(r1));
+}
+
+TEST(AddrRangeTest, Contains)
+{
+ AddrRange r(0xF0, 0xF5);
+
+ EXPECT_FALSE(r.contains(0xEF));
+ EXPECT_TRUE(r.contains(0xF0));
+ EXPECT_TRUE(r.contains(0xF1));
+ EXPECT_TRUE(r.contains(0xF2));
+ EXPECT_TRUE(r.contains(0xF3));
+ EXPECT_TRUE(r.contains(0xF4));
+ EXPECT_FALSE(r.contains(0xF5));
+ EXPECT_FALSE(r.contains(0xF6));
+}
+
+TEST(AddrRangeTest, ContainsInAnEmptyRange)
+{
+ AddrRange r(0x1, 0x1);
+
+ EXPECT_FALSE(r.contains(0x1));
+}
+
+TEST(AddrRangeTest, RemoveIntlvBits)
+{
+ AddrRange r(0x01, 0x10);
+
+ /*
+ * When there are no masks, AddrRange.removeIntlBits just returns the
+ * address parameter.
+ */
+ Addr a(56);
+ a = r.removeIntlvBits(a);
+ EXPECT_EQ(56, a);
+}
+
+TEST(AddrRangeTest, addIntlvBits)
+{
+ AddrRange r(0x01, 0x10);
+
+ /*
+ * As with AddrRange.removeIntlBits, when there are no masks,
+ * AddrRange.addIntlvBits just returns the address parameter.
+ */
+ Addr a(56);
+ a = r.addIntlvBits(a);
+ EXPECT_EQ(56, a);
+}
+
+TEST(AddrRangeTest, OffsetInRange)
+{
+ AddrRange r(0x01, 0xF0);
+ EXPECT_EQ(0x04, r.getOffset(0x5));
+}
+
+TEST(AddrRangeTest, OffsetOutOfRangeAfter)
+{
+ /*
+ * If the address is less than the range, MaxAddr is returned.
+ */
+ AddrRange r(0x01, 0xF0);
+ EXPECT_EQ(MaxAddr, r.getOffset(0xF0));
+}
+
+TEST(AddrRangeTest, OffsetOutOfRangeBefore)
+{
+ AddrRange r(0x05, 0xF0);
+ EXPECT_EQ(MaxAddr, r.getOffset(0x04));
+}
+
+/*
+ * The following tests check the behavior of AddrRange when initialized with
+ * a start and end address, as well as masks to distinguish interleaving bits.
+ */
+TEST(AddrRangeTest, LsbInterleavingMask)
+{
+ Addr start = 0x00;
+ Addr end = 0xFF;
+ std::vector<Addr> masks;
+ /*
+ * The address is in range if the LSB is set, i.e. is the value is odd.
+ */
+ masks.push_back(1);
+ uint8_t intlv_match = 1;
+
+ AddrRange r(start, end, masks, intlv_match);
+ EXPECT_TRUE(r.valid());
+ EXPECT_EQ(start, r.start());
+ EXPECT_EQ(end, r.end());
+ /*
+ * With interleaving, it's assumed the size is equal to
+ * start - end >> [number of masks].
+ */
+ EXPECT_EQ(0x7F, r.size());
+ /*
+ * The Granularity, the size of regions created by the interleaving bits,
+ * which, in this case, is one.
+ */
+ EXPECT_EQ(1, r.granularity());
+ EXPECT_TRUE(r.interleaved());
+ EXPECT_EQ(ULL(2), r.stripes());
+ EXPECT_EQ("[0:0xff] a[0]^\b=1", r.to_string());
+}
+
+TEST(AddrRangeTest, TwoInterleavingMasks)
+{
+ Addr start = 0x0000;
+ Addr end = 0xFFFF;
+ std::vector<Addr> masks;
+ /*
+ * There are two marks, the two LSBs.
+ */
+ masks.push_back(1);
+ masks.push_back((1 << 1));
+ uint8_t intlv_match = (1 << 1) | 1;
+
+ AddrRange r(start, end, masks, intlv_match);
+ EXPECT_TRUE(r.valid());
+ EXPECT_EQ(start, r.start());
+ EXPECT_EQ(end, r.end());
+
+ EXPECT_EQ(0x3FFF, r.size());
+ EXPECT_TRUE(r.interleaved());
+ EXPECT_EQ(ULL(4), r.stripes());
+ EXPECT_EQ("[0:0xffff] a[0]^\b=1 a[1]^\b=1", r.to_string());
+}
+
+TEST(AddrRangeTest, ComplexInterleavingMasks)
+{
+ Addr start = 0x0000;
+ Addr end = 0xFFFF;
+ std::vector<Addr> masks;
+ masks.push_back((1 << 1) | 1);
+ masks.push_back((ULL(1) << 63) | (ULL(1) << 62));
+ uint8_t intlv_match = 0;
+
+ AddrRange r(start, end, masks, intlv_match);
+ EXPECT_TRUE(r.valid());
+ EXPECT_EQ(start, r.start());
+ EXPECT_EQ(end, r.end());
+
+ EXPECT_EQ(0x3FFF, r.size());
+ EXPECT_TRUE(r.interleaved());
+ EXPECT_EQ(ULL(4), r.stripes());
+ EXPECT_EQ("[0:0xffff] a[0]^a[1]^\b=0 a[62]^a[63]^\b=0", r.to_string());
+}
+
+TEST(AddrRangeTest, InterleavingAddressesMergesWith)
+{
+ Addr start1 = 0x0000;
+ Addr end1 = 0xFFFF;
+ std::vector<Addr> masks;
+ masks.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
+ masks.push_back((1 << 2));
+ uint8_t intlv_match1 = 0;
+ AddrRange r1(start1, end1, masks, intlv_match1);
+
+ Addr start2 = 0x0000;
+ Addr end2 = 0xFFFF;
+ uint8_t intlv_match2 = 1; // intlv_match may differ.
+ AddrRange r2(start2, end2, masks, intlv_match2);
+
+ EXPECT_TRUE(r1.mergesWith(r2));
+ EXPECT_TRUE(r2.mergesWith(r1));
+}
+
+TEST(AddrRangeTest, InterleavingAddressesDoNotMergeWith)
+{
+ Addr start1 = 0x0000;
+ Addr end1 = 0xFFFF;
+ std::vector<Addr> masks1;
+ masks1.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
+ masks1.push_back((1 << 2));
+ uint8_t intlv_match1 = 0;
+ AddrRange r1(start1, end1, masks1, intlv_match1);
+
+ Addr start2 = 0x0000;
+ Addr end2 = 0xFFFF;
+ std::vector<Addr> masks2;
+ masks2.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
+ masks2.push_back((1 << 3)); // Different mask here.
+ uint8_t intlv_match2 = 1; // intlv_match may differ.
+ AddrRange r2(start2, end2, masks2, intlv_match2);
+
+ EXPECT_FALSE(r1.mergesWith(r2));
+ EXPECT_FALSE(r2.mergesWith(r1));
+}
+
+TEST(AddrRangeTest, InterleavingAddressesDoNotIntersect)
+{
+ /*
+ * Range 1: all the odd addresses between 0x0000 and 0xFFFF.
+ */
+ Addr start1 = 0x0000;
+ Addr end1 = 0xFFFF;
+ std::vector<Addr> masks1;
+ masks1.push_back(1);
+ uint8_t intlv_match1 = 1;
+ AddrRange r1(start1, end1, masks1, intlv_match1);
+
+ /*
+ * Range 2: all the even addresses between 0x0000 and 0xFFFF. These
+ * addresses should thereby not intersect.
+ */
+ Addr start2 = 0x0000;
+ Addr end2 = 0xFFFF;
+ std::vector<Addr> masks2;
+ masks2.push_back(1);
+ uint8_t intv_match2 = 0;
+ AddrRange r2(start2, end2, masks2, intv_match2);
+
+ EXPECT_FALSE(r1.intersects(r2));
+ EXPECT_FALSE(r2.intersects(r1));
+}
+
+TEST(AddrRangeTest, InterleavingAddressesIntersectsViaMerging)
+{
+ Addr start1 = 0x0000;
+ Addr end1 = 0xFFFF;
+ std::vector<Addr> masks1;
+ masks1.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
+ masks1.push_back((1 << 2));
+ uint8_t intlv_match1 = 0;
+ AddrRange r1(start1, end1, masks1, intlv_match1);
+
+ Addr start2 = 0x0000;
+ Addr end2 = 0xFFFF;
+ std::vector<Addr> masks2;
+ masks2.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
+ masks2.push_back((1 << 2));
+ uint8_t intlv_match2 = 0;
+ AddrRange r2(start2, end2, masks2, intlv_match2);
+
+ EXPECT_TRUE(r1.intersects(r2));
+ EXPECT_TRUE(r2.intersects(r1));
+}
+
+TEST(AddrRangeTest, InterleavingAddressesDoesNotIntersectViaMerging)
+{
+ Addr start1 = 0x0000;
+ Addr end1 = 0xFFFF;
+ std::vector<Addr> masks1;
+ masks1.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
+ masks1.push_back((1 << 2));
+ uint8_t intlv_match1 = 0;
+ AddrRange r1(start1, end1, masks1, intlv_match1);
+
+ Addr start2 = 0x0000;
+ Addr end2 = 0xFFFF;
+ std::vector<Addr> masks2;
+ masks2.push_back((1 << 29) | (1 << 20) | (1 << 10) | 1);
+ masks2.push_back((1 << 2));
+ /*
+ * These addresses can merge, but their intlv_match values differ. They
+ * therefore do not intersect.
+ */
+ uint8_t intlv_match2 = 1;
+ AddrRange r2(start2, end2, masks2, intlv_match2);
+
+ EXPECT_FALSE(r1.intersects(r2));
+ EXPECT_FALSE(r2.intersects(r1));
+}
+
+/*
+ * The following tests were created to test more complex cases where
+ * interleaving addresses may intersect. However, the "intersects" function
+ * does not cover all cases (a "Cannot test intersection..." exception will
+ * be thrown outside of very simple checks to see if an intersection occurs).
+ * The tests below accurately test whether two ranges intersect but, for now,
+ * code has yet to be implemented to utilize these tests. They are therefore
+ * disabled, but may be enabled at a later date if/when the "intersects"
+ * function is enhanced.
+ */
+TEST(AddrRangeTest, DISABLED_InterleavingAddressesIntersect)
+{
+ /*
+ * Range 1: all the odd addresses between 0x0000 and 0xFFFF.
+ */
+ Addr start1 = 0x0000;
+ Addr end1 = 0xFFFF;
+ std::vector<Addr> masks1;
+ masks1.push_back(1);
+ uint8_t intlv_match1 = 0;
+ AddrRange r1(start1, end1, masks1, intlv_match1);
+
+ /*
+ * Range 2: all the addresses divisible by 4 between 0x0000 and
+ * 0xFFFF. These addresses should thereby intersect.
+ */
+ Addr start2 = 0x0000;
+ Addr end2 = 0xFFFF;
+ std::vector<Addr> masks2;
+ masks2.push_back(1 << 2);
+ uint8_t intlv_match2 = 1;
+ AddrRange r2(start2, end2, masks2, intlv_match2);
+
+ EXPECT_TRUE(r1.intersects(r2));
+ EXPECT_TRUE(r2.intersects(r1));
+}
+
+TEST(AddrRangeTest, DISABLED_InterleavingAddressesIntersectsOnOneByteAddress)
+{
+ /*
+ * Range: all the odd addresses between 0x0000 and 0xFFFF.
+ */
+ Addr start = 0x0000;
+ Addr end = 0xFFFF;
+ std::vector<Addr> masks;
+ masks.push_back(1);
+ uint8_t intlv_match = 1;
+ AddrRange r1(start, end, masks, intlv_match);
+
+ AddrRange r2(0x0000, 0x0001);
+
+ EXPECT_FALSE(r1.intersects(r2));
+ EXPECT_FALSE(r2.intersects(r1));
+}
-TEST_F(AddrRangeContLegacy, AddrRangeContains)
+TEST(AddrRangeTest,
+ DISABLED_InterleavingAddressesDoesNotIntersectOnOneByteAddress)
{
- testContains();
+ /*
+ * Range: all the odd addresses between 0x0000 and 0xFFFF.
+ */
+ Addr start = 0x0000;
+ Addr end = 0xFFFF;
+ std::vector<Addr> masks;
+ masks.push_back(1);
+ uint8_t intlv_match = 1;
+ AddrRange r1(start, end, masks, intlv_match);
+
+ AddrRange r2(0x0001, 0x0002);
+
+ EXPECT_TRUE(r1.intersects(r2));
+ EXPECT_TRUE(r2.intersects(r1));
}
-TEST_F(AddrRangeContLegacy, AddrRangeGetOffset)
+
+/*
+ * The following three tests were created to test the addr_range.isSubset
+ * function for Interleaving address ranges. However, for now, this
+ * functionality has not been implemented. These tests are therefore disabled.
+ */
+TEST(AddrRangeTest, DISABLED_InterleavingAddressIsSubset)
{
- testGetOffset();
+ // Range 1: all the even addresses between 0x0000 and 0xFFFF.
+ Addr start1 = 0x0000;
+ Addr end1 = 0xFFFF;
+ std::vector<Addr> masks1;
+ masks1.push_back(1);
+ uint8_t intlv_match1 = 0;
+ AddrRange r1(start1, end1, masks1, intlv_match1);
+
+ // Range 2: all the even addresses between 0xF000 and 0x0FFF, this is
+ // a subset of Range 1.
+ Addr start2 = 0xF000;
+ Addr end2 = 0x0FFF;
+ std::vector<Addr> masks2;
+ masks2.push_back(1);
+ uint8_t intlv_match2 = 0;
+ AddrRange r2(start2, end2, masks2, intlv_match2);
+
+ EXPECT_TRUE(r1.isSubset(r2));
+ EXPECT_TRUE(r2.isSubset(r1));
}
-TEST_F(AddrRangeContLegacy, AddrRangeAddRemoveIntlvBits)
+TEST(AddrRangeTest, DISABLED_InterleavingAddressIsNotSubset)
{
- testAddRemoveIntlvBits();
+ //Range 1: all the even addresses between 0x0000 and 0xFFFF.
+ Addr start1 = 0x0000;
+ Addr end1 = 0xFFFF;
+ std::vector<Addr> masks1;
+ masks1.push_back(1);
+ uint8_t intlv_match1 = 0;
+ AddrRange r1(start1, end1, masks1, intlv_match1);
+
+
+ // Range 2: all the odd addresses between 0xF000 and 0x0FFF, this is
+ //a subset of Range 1.
+ Addr start2 = 0xF000;
+ Addr end2 = 0x0FFF;
+ std::vector<Addr> masks2;
+ masks2.push_back(1);
+ uint8_t intlv_match2 = 1;
+ AddrRange r2(start2, end2, masks2, intlv_match2);
+
+ EXPECT_FALSE(r1.isSubset(r2));
+ EXPECT_FALSE(r2.isSubset(r1));
}
-class AddrRangeArb : public AddrRangeBase {
- protected:
- void SetUp() override
- {
- std::vector<Addr> masks = {
- 1UL << xorBits0[0] | 1UL << xorBits0[1],
- 1UL << xorBits1[0] | 1UL << xorBits1[1]
- };
- for (auto i = 0; i < intlvSize; i++) {
- range[i] = AddrRange(start, end, masks, i);
+TEST(AddrRangeTest, DISABLED_InterleavingAddressContains)
+{
+ /*
+ * Range: all the address between 0x0 and 0xFF which have both the 1st
+ * and 5th bits 1, or both are 0
+ */
+ Addr start = 0x00;
+ Addr end = 0xFF;
+ std::vector<Addr> masks;
+ masks.push_back((1 << 4) | 1);
+ uint8_t intlv_match = 0;
+ AddrRange r(start, end, masks, intlv_match);
+
+ for (Addr addr = start; addr < end; addr++) {
+ if (((addr & 1) && ((1 << 4) & addr)) || // addr[0] && addr[4]
+ (!(addr & 1) && !((1 << 4) & addr))) { //!addr[0] && !addr[4]
+ EXPECT_TRUE(r.contains(addr));
+ } else {
+ EXPECT_FALSE(r.contains(addr));
}
}
+}
+
+TEST(AddrRangeTest, InterleavingAddressAddRemoveInterlvBits)
+{
+ Addr start = 0x00000;
+ Addr end = 0x10000;
+ std::vector<Addr> masks;
+ masks.push_back(1);
+ uint8_t intlv_match = 1;
+ AddrRange r(start, end, masks, intlv_match);
+
+ Addr input = 0xFFFF;
+ Addr output = r.removeIntlvBits(input);
+
+ /*
+ * The removeIntlvBits function removes the LSB from each mask from the
+ * input address. For example, two masks:
+ * 00000001 and,
+ * 10000100
+ * with an input address of:
+ * 10101010
+ *
+ * we would remove bit at position 0, and at position 2, resulting in:
+ * 00101011
+ *
+ * In this test there is is one mask, with a LSB at position 0.
+ * Therefore, removing the interleaving bits is equivilant to bitshifting
+ * the input to the right.
+ */
+ EXPECT_EQ(input >> 1, output);
+
+ /*
+ * The addIntlvBits function will re-insert bits at the removed locations
+ */
+ EXPECT_EQ(input, r.addIntlvBits(output));
+}
+
+TEST(AddrRangeTest, InterleavingAddressAddRemoveInterlvBitsTwoMasks)
+{
+ Addr start = 0x00000;
+ Addr end = 0x10000;
+ std::vector<Addr> masks;
+ masks.push_back((1 << 3) | (1 << 2) | (1 << 1) | 1);
+ masks.push_back((1 << 11) | (1 << 10) | (1 << 9) | (1 << 8));
+ uint8_t intlv_match = 1;
+ AddrRange r(start, end, masks, intlv_match);
+
+ Addr input = (1 << 9) | (1 << 8) | 1;
+ /*
+ * (1 << 8) and 1 are interleaving bits to be removed.
+ */
+ Addr output = r.removeIntlvBits(input);
+
+ /*
+ * The bit, formally at position 9, is now at 7.
+ */
+ EXPECT_EQ((1 << 7), output);
+
+ /*
+ * Re-adding the interleaving.
+ */
+ EXPECT_EQ(input, r.addIntlvBits(output));
+}
+
+TEST(AddrRangeTest, AddRemoveInterleavBitsAcrossRange)
+{
+ /*
+ * This purpose of this test is to ensure that removing then adding
+ * interleaving bits has no net effect.
+ * E.g.:
+ * addr_range.addIntlvBits(add_range.removeIntlvBits(an_address)) should
+ * always return an_address.
+ */
+ Addr start = 0x00000;
+ Addr end = 0x10000;
+ std::vector<Addr> masks;
+ masks.push_back(1 << 2);
+ masks.push_back(1 << 3);
+ masks.push_back(1 << 16);
+ masks.push_back(1 << 30);
+ uint8_t intlv_match = 0xF;
+ AddrRange r(start, end, masks, intlv_match);
- int getIndex(Addr addr) override
- {
- return (bits(addr, xorBits0[0]) ^ bits(addr, xorBits0[1])) |
- (bits(addr, xorBits1[0]) ^ bits(addr, xorBits1[1])) << 1;
+ for (Addr i = 0; i < 0xFFF; i++) {
+ Addr removedBits = r.removeIntlvBits(i);
+ /*
+ * As intlv_match = 0xF, all the interleaved bits should be set.
+ */
+ EXPECT_EQ(i | (1 << 2) | (1 << 3) | (1 << 16) | (1 << 30),
+ r.addIntlvBits(removedBits));
}
+}
+
+TEST(AddrRangeTest, InterleavingAddressesGetOffset)
+{
+ Addr start = 0x0002;
+ Addr end = 0xFFFF;
+ std::vector<Addr> masks;
+ masks.push_back((1 << 4) | (1 << 2));
+ uint8_t intlv_match = 0;
+ AddrRange r(start, end, masks, intlv_match);
+
+ Addr value = ((1 << 10) | (1 << 9) | (1 << 8) | (1 << 2) | (1 << 1) | 1);
+ Addr value_interleaving_bits_removed =
+ ((1 << 9) | (1 << 8) | (1 << 7) | (1 << 1) | 1);
- const int xorBits0[2] = {11, 12};
- const int xorBits1[2] = {8, 15};
-};
+ Addr expected_output = value_interleaving_bits_removed - start;
-TEST_F(AddrRangeArb, AddrRangeContains)
+ EXPECT_EQ(expected_output, r.getOffset(value));
+}
+
+TEST(AddrRangeTest, InterleavingLessThanStartEquals)
{
- testContains();
+ Addr start1 = 0x0000FFFF;
+ Addr end1 = 0xFFFF0000;
+ std::vector<Addr> masks1;
+ masks1.push_back((1 << 4) | (1 << 2));
+ uint8_t intlv_match1 = 0;
+ AddrRange r1(start1, end1, masks1, intlv_match1);
+
+ Addr start2 = 0x0000FFFF;
+ Addr end2 = 0x000F0000;
+ std::vector<Addr> masks2;
+ masks2.push_back((1 << 4) | (1 << 2));
+ masks2.push_back((1 << 10));
+ uint8_t intlv_match2 = 2;
+ AddrRange r2(start2, end2, masks2, intlv_match2);
+
+ /*
+ * When The start addresses are equal, the intlv_match values are
+ * compared.
+ */
+ EXPECT_TRUE(r1 < r2);
+ EXPECT_FALSE(r2 < r1);
}
-TEST_F(AddrRangeArb, AddrRangeGetOffset)
+TEST(AddrRangeTest, InterleavingLessThanStartNotEquals)
{
- testGetOffset();
+ Addr start1 = 0x0000FFFF;
+ Addr end1 = 0xFFFF0000;
+ std::vector<Addr> masks1;
+ masks1.push_back((1 << 4) | (1 << 2));
+ uint8_t intlv_match1 = 0;
+ AddrRange r1(start1, end1, masks1, intlv_match1);
+
+ Addr start2 = 0x0000FFFE;
+ Addr end2 = 0x000F0000;
+ std::vector<Addr> masks2;
+ masks2.push_back((1 << 4) | (1 << 2));
+ masks2.push_back((1 << 10));
+ uint8_t intlv_match2 = 2;
+ AddrRange r2(start2, end2, masks2, intlv_match2);
+
+ EXPECT_TRUE(r2 < r1);
+ EXPECT_FALSE(r1 < r2);
}
-TEST_F(AddrRangeArb, AddrRangeAddRemoveIntlvBits)
+TEST(AddrRangeTest, InterleavingEqualTo)
{
- testAddRemoveIntlvBits();
+ Addr start1 = 0x0000FFFF;
+ Addr end1 = 0xFFFF0000;
+ std::vector<Addr> masks1;
+ masks1.push_back((1 << 4) | (1 << 2));
+ uint8_t intlv_match1 = 0;
+ AddrRange r1(start1, end1, masks1, intlv_match1);
+
+ Addr start2 = 0x0000FFFF;
+ Addr end2 = 0xFFFF0000;
+ std::vector<Addr> masks2;
+ masks2.push_back((1 << 4) | (1 << 2));
+ uint8_t intlv_match2 = 0;
+ AddrRange r2(start2, end2, masks2, intlv_match2);
+
+ EXPECT_TRUE(r1 == r2);
+}
+
+TEST(AddrRangeTest, InterleavingNotEqualTo)
+{
+ Addr start1 = 0x0000FFFF;
+ Addr end1 = 0xFFFF0000;
+ std::vector<Addr> masks1;
+ masks1.push_back((1 << 4) | (1 << 2));
+ uint8_t intlv_match1 = 0;
+ AddrRange r1(start1, end1, masks1, intlv_match1);
+
+ Addr start2 = 0x0000FFFF;
+ Addr end2 = 0xFFFF0000;
+ std::vector<Addr> masks2;
+ masks2.push_back((1 << 4) | (1 << 2));
+ masks2.push_back((1 << 10));
+ uint8_t intlv_match2 = 2;
+ AddrRange r2(start2, end2, masks2, intlv_match2);
+
+ /*
+ * These ranges are not equal due to having different masks.
+ */
+ EXPECT_FALSE(r1 == r2);
+}
+
+/*
+ * The AddrRange(std::vector<AddrRange>) constructor "merges" the interleaving
+ * address ranges. It should be noted that this constructor simply checks that
+ * these interleaving addresses can be merged then creates a new address from
+ * the start and end addresses of the first address range in the vector.
+ */
+TEST(AddrRangeTest, MergingInterleavingAddressRanges)
+{
+ Addr start1 = 0x0000;
+ Addr end1 = 0xFFFF;
+ std::vector<Addr> masks1;
+ masks1.push_back((1 << 4) | (1 << 2));
+ uint8_t intlv_match1 = 0;
+ AddrRange r1(start1, end1, masks1, intlv_match1);
+
+ Addr start2 = 0x0000;
+ Addr end2 = 0xFFFF;
+ std::vector<Addr> masks2;
+ masks2.push_back((1 << 4) | (1 << 2));
+ uint8_t intlv_match2 = 1;
+ AddrRange r2(start2, end2, masks2, intlv_match2);
+
+ std::vector<AddrRange> to_merge;
+ to_merge.push_back(r1);
+ to_merge.push_back(r2);
+
+ AddrRange output(to_merge);
+
+ EXPECT_EQ(0x0000, output.start());
+ EXPECT_EQ(0xFFFF, output.end());
+ EXPECT_FALSE(output.interleaved());
+}
+
+TEST(AddrRangeTest, MergingInterleavingAddressRangesOneRange)
+{
+ /*
+ * In the case where there is just one range in the vector, the merged
+ * address range is equal to that range.
+ */
+ Addr start = 0x0000;
+ Addr end = 0xFFFF;
+ std::vector<Addr> masks;
+ masks.push_back((1 << 4) | (1 << 2));
+ uint8_t intlv_match = 0;
+ AddrRange r(start, end, masks, intlv_match);
+
+ std::vector<AddrRange> to_merge;
+ to_merge.push_back(r);
+
+ AddrRange output(to_merge);
+
+ EXPECT_EQ(r, output);
}
+
+/*
+ * The following tests verify the soundness of the "legacy constructor",
+ * AddrRange(Addr, Addr, uint8_t, uint8_t, uint8_t, uint8_t).
+ *
+ * The address is assumed to contain two ranges; the interleaving bits, and
+ * the xor bits. The first two arguments of this constructor specify the
+ * start and end addresses. The third argument specifies the MSB of the
+ * interleaving bits. The fourth argument specifies the MSB of the xor bits.
+ * The firth argument specifies the size (in bits) of the xor and interleaving
+ * bits. These cannot overlap. The sixth argument specifies the value the
+ * XORing of the xor and interleaving bits should equal to be considered in
+ * range.
+ *
+ * This constructor does a lot of complex translation to migrate this
+ * constructor to the masks/intlv_match format.
+ */
+TEST(AddrRangeTest, LegacyConstructorNoInterleaving)
+{
+ /*
+ * This constructor should create a range with no interleaving.
+ */
+ AddrRange range(0x0000, 0xFFFF, 0, 0, 0 ,0);
+ AddrRange expected(0x0000, 0xFFFF);
+
+ EXPECT_EQ(expected, range);
+}
+
+TEST(AddrRangeTest, LegacyConstructorOneBitMask)
+{
+ /*
+ * In this test, the LSB of the address determines whether an address is
+ * in range. If even, it's in range, if not, it's out of range. the XOR
+ * bit range is not used.
+ */
+ AddrRange range(0x00000000, 0xFFFFFFFF, 0, 0, 1, 0);
+
+ std::vector<Addr> masks;
+ masks.push_back(1);
+ AddrRange expected(0x00000000, 0xFFFFFFFF, masks, 0);
+
+ EXPECT_TRUE(expected == range);
+}
+
+TEST(AddrRangeTest, LegacyConstructorTwoBitMask)
+{
+ /*
+ * In this test, the two LSBs of the address determines whether an address
+ * is in range. If the two are set, the address is in range. The XOR bit
+ * range is not used.
+ */
+ AddrRange range(0x00000000, 0xFFFFFFFF, 1, 0, 2, 3);
+
+ std::vector<Addr> masks;
+ masks.push_back(1);
+ masks.push_back((1 << 1));
+ AddrRange expected(0x00000000, 0xFFFFFFFF, masks, 3);
+
+ EXPECT_TRUE(expected == range);
+}
+
+TEST(AddrRangeTest, LegacyConstructorTwoBitMaskWithXOR)
+{
+ /*
+ * In this test, the two LSBs of the address determine wether an address
+ * is in range. They are XORed to the 10th and 11th bits in the address.
+ * If XORed value is equal to 3, then the address is in range.
+ */
+
+ AddrRange range(0x00000000, 0xFFFFFFFF, 1, 11, 2, 3);
+
+ /*
+ * The easiest way to ensure this range is correct is to iterate throguh
+ * the address range and ensure the correct set of addresses are contained
+ * within the range.
+ *
+ * We start with the xor_mask: a mask to select the 10th and 11th bits.
+ */
+ Addr xor_mask = (1 << 11) | (1 << 10);
+ for (Addr i = 0; i < 0x0000FFFF; i++) {
+ // Get xor bits.
+ Addr xor_value = (xor_mask & i) >> 10;
+ /* If the XOR of xor_bits and the intlv bits (the 0th and 1st bits) is
+ * equal to intlv_match (3, i.e., the 0th and 1st bit is set),then the
+ * address is within range.
+ */
+ if (((xor_value ^ i) & 3) == 3) {
+ EXPECT_TRUE(range.contains(i));
+ } else {
+ EXPECT_FALSE(range.contains(i));
+ }
+ }
+}
+
+/*
+ * addr_range.hh contains some convenience constructors. The following tests
+ * verify they construct AddrRange correctly.
+ */
+TEST(AddrRangeTest, RangeExConstruction)
+{
+ AddrRange r = RangeEx(0x6, 0xE);
+ EXPECT_EQ(0x6, r.start());
+ EXPECT_EQ(0xE, r.end());
+}
+
+TEST(AddrRangeTest, RangeInConstruction)
+{
+ AddrRange r = RangeIn(0x6, 0xE);
+ EXPECT_EQ(0x6, r.start());
+ EXPECT_EQ(0xF, r.end());
+}
+
+TEST(AddrRangeTest, RangeSizeConstruction){
+ AddrRange r = RangeSize(0x5, 5);
+ EXPECT_EQ(0x5, r.start());
+ EXPECT_EQ(0xA, r.end());
+} \ No newline at end of file
diff --git a/src/dev/arm/gic_v2.cc b/src/dev/arm/gic_v2.cc
index 20bd01570..df71068d4 100644
--- a/src/dev/arm/gic_v2.cc
+++ b/src/dev/arm/gic_v2.cc
@@ -51,16 +51,16 @@
#include "mem/packet.hh"
#include "mem/packet_access.hh"
-const AddrRange GicV2::GICD_IGROUPR (0x080, 0x0ff);
-const AddrRange GicV2::GICD_ISENABLER (0x100, 0x17f);
-const AddrRange GicV2::GICD_ICENABLER (0x180, 0x1ff);
-const AddrRange GicV2::GICD_ISPENDR (0x200, 0x27f);
-const AddrRange GicV2::GICD_ICPENDR (0x280, 0x2ff);
-const AddrRange GicV2::GICD_ISACTIVER (0x300, 0x37f);
-const AddrRange GicV2::GICD_ICACTIVER (0x380, 0x3ff);
-const AddrRange GicV2::GICD_IPRIORITYR(0x400, 0x7ff);
-const AddrRange GicV2::GICD_ITARGETSR (0x800, 0xbff);
-const AddrRange GicV2::GICD_ICFGR (0xc00, 0xcff);
+const AddrRange GicV2::GICD_IGROUPR (0x080, 0x100);
+const AddrRange GicV2::GICD_ISENABLER (0x100, 0x180);
+const AddrRange GicV2::GICD_ICENABLER (0x180, 0x200);
+const AddrRange GicV2::GICD_ISPENDR (0x200, 0x280);
+const AddrRange GicV2::GICD_ICPENDR (0x280, 0x300);
+const AddrRange GicV2::GICD_ISACTIVER (0x300, 0x380);
+const AddrRange GicV2::GICD_ICACTIVER (0x380, 0x400);
+const AddrRange GicV2::GICD_IPRIORITYR(0x400, 0x800);
+const AddrRange GicV2::GICD_ITARGETSR (0x800, 0xc00);
+const AddrRange GicV2::GICD_ICFGR (0xc00, 0xd00);
GicV2::GicV2(const Params *p)
: BaseGic(p),
diff --git a/src/dev/arm/gic_v3_distributor.cc b/src/dev/arm/gic_v3_distributor.cc
index e38fa185c..77a8392fa 100644
--- a/src/dev/arm/gic_v3_distributor.cc
+++ b/src/dev/arm/gic_v3_distributor.cc
@@ -50,20 +50,20 @@
#include "dev/arm/gic_v3_cpu_interface.hh"
#include "dev/arm/gic_v3_redistributor.hh"
-const AddrRange Gicv3Distributor::GICD_IGROUPR (0x0080, 0x00ff);
-const AddrRange Gicv3Distributor::GICD_ISENABLER (0x0100, 0x017f);
-const AddrRange Gicv3Distributor::GICD_ICENABLER (0x0180, 0x01ff);
-const AddrRange Gicv3Distributor::GICD_ISPENDR (0x0200, 0x027f);
-const AddrRange Gicv3Distributor::GICD_ICPENDR (0x0280, 0x02ff);
-const AddrRange Gicv3Distributor::GICD_ISACTIVER (0x0300, 0x037f);
-const AddrRange Gicv3Distributor::GICD_ICACTIVER (0x0380, 0x03ff);
-const AddrRange Gicv3Distributor::GICD_IPRIORITYR(0x0400, 0x07ff);
-const AddrRange Gicv3Distributor::GICD_ITARGETSR (0x0800, 0x08ff);
-const AddrRange Gicv3Distributor::GICD_ICFGR (0x0c00, 0x0cff);
-const AddrRange Gicv3Distributor::GICD_IGRPMODR (0x0d00, 0x0d7f);
-const AddrRange Gicv3Distributor::GICD_NSACR (0x0e00, 0x0eff);
-const AddrRange Gicv3Distributor::GICD_CPENDSGIR (0x0f10, 0x0f1f);
-const AddrRange Gicv3Distributor::GICD_SPENDSGIR (0x0f20, 0x0f2f);
+const AddrRange Gicv3Distributor::GICD_IGROUPR (0x0080, 0x0100);
+const AddrRange Gicv3Distributor::GICD_ISENABLER (0x0100, 0x0180);
+const AddrRange Gicv3Distributor::GICD_ICENABLER (0x0180, 0x0200);
+const AddrRange Gicv3Distributor::GICD_ISPENDR (0x0200, 0x0280);
+const AddrRange Gicv3Distributor::GICD_ICPENDR (0x0280, 0x0300);
+const AddrRange Gicv3Distributor::GICD_ISACTIVER (0x0300, 0x0380);
+const AddrRange Gicv3Distributor::GICD_ICACTIVER (0x0380, 0x0400);
+const AddrRange Gicv3Distributor::GICD_IPRIORITYR(0x0400, 0x0800);
+const AddrRange Gicv3Distributor::GICD_ITARGETSR (0x0800, 0x0900);
+const AddrRange Gicv3Distributor::GICD_ICFGR (0x0c00, 0x0d00);
+const AddrRange Gicv3Distributor::GICD_IGRPMODR (0x0d00, 0x0d80);
+const AddrRange Gicv3Distributor::GICD_NSACR (0x0e00, 0x0f00);
+const AddrRange Gicv3Distributor::GICD_CPENDSGIR (0x0f10, 0x0f20);
+const AddrRange Gicv3Distributor::GICD_SPENDSGIR (0x0f20, 0x0f30);
const AddrRange Gicv3Distributor::GICD_IROUTER (0x6000, 0x7fe0);
Gicv3Distributor::Gicv3Distributor(Gicv3 * gic, uint32_t it_lines)
diff --git a/src/dev/arm/gic_v3_its.cc b/src/dev/arm/gic_v3_its.cc
index ab0d8c2d0..d25117e30 100644
--- a/src/dev/arm/gic_v3_its.cc
+++ b/src/dev/arm/gic_v3_its.cc
@@ -50,7 +50,7 @@
#define COMMAND(x, method) { x, DispatchEntry(#x, method) }
-const AddrRange Gicv3Its::GITS_BASER(0x0100, 0x0138);
+const AddrRange Gicv3Its::GITS_BASER(0x0100, 0x0140);
const uint32_t Gicv3Its::CTLR_QUIESCENT = 0x80000000;
diff --git a/src/dev/arm/gic_v3_redistributor.cc b/src/dev/arm/gic_v3_redistributor.cc
index 11a1f9d3e..75fd9b326 100644
--- a/src/dev/arm/gic_v3_redistributor.cc
+++ b/src/dev/arm/gic_v3_redistributor.cc
@@ -49,7 +49,7 @@
#include "mem/fs_translating_port_proxy.hh"
const AddrRange Gicv3Redistributor::GICR_IPRIORITYR(SGI_base + 0x0400,
- SGI_base + 0x041f);
+ SGI_base + 0x0420);
Gicv3Redistributor::Gicv3Redistributor(Gicv3 * gic, uint32_t cpu_id)
: gic(gic),
diff --git a/src/python/m5/params.py b/src/python/m5/params.py
index b9afff2a1..9b4198b97 100644
--- a/src/python/m5/params.py
+++ b/src/python/m5/params.py
@@ -768,7 +768,7 @@ class AddrRange(ParamValue):
if 'end' in kwargs:
self.end = Addr(kwargs.pop('end'))
elif 'size' in kwargs:
- self.end = self.start + Addr(kwargs.pop('size')) - 1
+ self.end = self.start + Addr(kwargs.pop('size'))
else:
raise TypeError("Either end or size must be specified")
@@ -810,7 +810,7 @@ class AddrRange(ParamValue):
self.end = Addr(args[0][1])
else:
self.start = Addr(0)
- self.end = Addr(args[0]) - 1
+ self.end = Addr(args[0])
elif len(args) == 2:
self.start = Addr(args[0])
@@ -830,7 +830,7 @@ class AddrRange(ParamValue):
def size(self):
# Divide the size by the size of the interleaving slice
- return (long(self.end) - long(self.start) + 1) >> self.intlvBits
+ return (long(self.end) - long(self.start)) >> self.intlvBits
@classmethod
def cxx_predecls(cls, code):
diff --git a/src/sim/system.cc b/src/sim/system.cc
index f2bbd8cbc..0e7db5964 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -408,7 +408,7 @@ System::allocPhysPages(int npages)
Addr next_return_addr = pagePtr << PageShift;
- AddrRange m5opRange(0xffff0000, 0xffffffff);
+ AddrRange m5opRange(0xffff0000, 0x100000000);
if (m5opRange.contains(next_return_addr)) {
warn("Reached m5ops MMIO region\n");
return_addr = 0xffffffff;