From b4c9996d894118be04cdf4ed793b35a1d5001942 Mon Sep 17 00:00:00 2001 From: Brandon Potter Date: Fri, 18 Oct 2019 14:43:14 -0400 Subject: [PATCH] base,tests: Expanded GTests for addr_range.hh These tests assume the "end address" is not included in the range. This exposed some bugs in addr_range.hh which have been fixed. Where appropriate code comments in addr_range.hh have been extended to improve understanding of the class's behavior. Hard-coded AddrRange values in the project have been updated to take into account that end address is now exclusive. The python params.py interface has been updated to conform to this new standard. Change-Id: Idd1e75d5771d198c4b8142b28de0f3a6e9007a52 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/22427 Maintainer: Bobby R. Bruce Reviewed-by: Nikos Nikoleris Tested-by: kokoro --- src/arch/x86/tlb.cc | 4 +- src/base/addr_range.hh | 24 +- src/base/addr_range.test.cc | 1079 +++++++++++++++++++++++---- src/dev/arm/gic_v2.cc | 20 +- src/dev/arm/gic_v3_distributor.cc | 28 +- src/dev/arm/gic_v3_its.cc | 2 +- src/dev/arm/gic_v3_redistributor.cc | 2 +- src/python/m5/params.py | 6 +- src/sim/system.cc | 2 +- 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 &_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 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 +#include + #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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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) 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 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 masks2; + masks2.push_back((1 << 4) | (1 << 2)); + uint8_t intlv_match2 = 1; + AddrRange r2(start2, end2, masks2, intlv_match2); + + std::vector 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 masks; + masks.push_back((1 << 4) | (1 << 2)); + uint8_t intlv_match = 0; + AddrRange r(start, end, masks, intlv_match); + + std::vector 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 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 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; -- 2.30.2