113465Sgabeblack@google.com/* 214048Snikos.nikoleris@arm.com * Copyright (c) 2018-2019 ARM Limited 313465Sgabeblack@google.com * All rights reserved 413465Sgabeblack@google.com * 513465Sgabeblack@google.com * The license below extends only to copyright in the software and shall 613465Sgabeblack@google.com * not be construed as granting a license to any other intellectual 713465Sgabeblack@google.com * property including but not limited to intellectual property relating 813465Sgabeblack@google.com * to a hardware implementation of the functionality of the software 913465Sgabeblack@google.com * licensed hereunder. You may use the software subject to the license 1013465Sgabeblack@google.com * terms below provided that you ensure that this notice is replicated 1113465Sgabeblack@google.com * unmodified and in its entirety in all distributions of the software, 1213465Sgabeblack@google.com * modified or unmodified, in source code or in binary form. 1313465Sgabeblack@google.com * 1413465Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 1513465Sgabeblack@google.com * modification, are permitted provided that the following conditions are 1613465Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 1713465Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 1813465Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1913465Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 2013465Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 2113465Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 2213465Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 2313465Sgabeblack@google.com * this software without specific prior written permission. 2413465Sgabeblack@google.com * 2513465Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2613465Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2713465Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2813465Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2913465Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3013465Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3113465Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3213465Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3313465Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3413465Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3513465Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3613465Sgabeblack@google.com * 3713465Sgabeblack@google.com * Authors: Nikos Nikoleris 3813465Sgabeblack@google.com */ 3913465Sgabeblack@google.com 4013465Sgabeblack@google.com#include <gtest/gtest.h> 4113465Sgabeblack@google.com 4213465Sgabeblack@google.com#include "base/addr_range.hh" 4314048Snikos.nikoleris@arm.com#include "base/bitfield.hh" 4413465Sgabeblack@google.com 4513465Sgabeblack@google.comTEST(AddrRangeComp, AddrRangeIsSubset) 4613465Sgabeblack@google.com{ 4713465Sgabeblack@google.com AddrRange r, r1, r2; 4813465Sgabeblack@google.com 4913465Sgabeblack@google.com // Test non-interleaved ranges 5013465Sgabeblack@google.com r1 = AddrRange(0x0, 0x7f); 5113465Sgabeblack@google.com r2 = AddrRange(0x80, 0xff); 5213465Sgabeblack@google.com 5313465Sgabeblack@google.com r = AddrRange(0x0, 0xf); 5413465Sgabeblack@google.com EXPECT_TRUE(r.isSubset(r1)); 5513465Sgabeblack@google.com EXPECT_FALSE(r.isSubset(r2)); 5613465Sgabeblack@google.com 5713465Sgabeblack@google.com r = AddrRange(0x80, 0x8f); 5813465Sgabeblack@google.com EXPECT_FALSE(r.isSubset(r1)); 5913465Sgabeblack@google.com EXPECT_TRUE(r.isSubset(r2)); 6013465Sgabeblack@google.com 6113465Sgabeblack@google.com // Test interleaved ranges 6213465Sgabeblack@google.com r1 = AddrRange(0x0, 0xff, 6, 0, 1, 0); 6313465Sgabeblack@google.com r2 = AddrRange(0x0, 0xff, 6, 0, 1, 1); 6413465Sgabeblack@google.com 6513465Sgabeblack@google.com r = AddrRange(0x0, 0xf); 6613465Sgabeblack@google.com EXPECT_TRUE(r.isSubset(r1)); 6713465Sgabeblack@google.com EXPECT_FALSE(r.isSubset(r2)); 6813465Sgabeblack@google.com 6913465Sgabeblack@google.com r = AddrRange(0x40, 0x4f); 7013465Sgabeblack@google.com EXPECT_FALSE(r.isSubset(r1)); 7113465Sgabeblack@google.com EXPECT_TRUE(r.isSubset(r2)); 7213465Sgabeblack@google.com 7313465Sgabeblack@google.com r = AddrRange(0xbf, 0xc0); 7413465Sgabeblack@google.com EXPECT_FALSE(r.isSubset(r1)); 7513465Sgabeblack@google.com EXPECT_FALSE(r.isSubset(r2)); 7613465Sgabeblack@google.com 7713465Sgabeblack@google.com // Test interleaved ranges with hashing 7813465Sgabeblack@google.com r1 = AddrRange(0x0, 0xff, 6, 7, 1, 0); 7913465Sgabeblack@google.com r2 = AddrRange(0x0, 0xff, 6, 7, 1, 1); 8013465Sgabeblack@google.com 8113465Sgabeblack@google.com r = AddrRange(0x0, 0xf); 8213465Sgabeblack@google.com EXPECT_TRUE(r.isSubset(r1)); 8313465Sgabeblack@google.com EXPECT_FALSE(r.isSubset(r2)); 8413465Sgabeblack@google.com 8513465Sgabeblack@google.com r = AddrRange(0x40, 0x4f); 8613465Sgabeblack@google.com EXPECT_FALSE(r.isSubset(r1)); 8713465Sgabeblack@google.com EXPECT_TRUE(r.isSubset(r2)); 8813465Sgabeblack@google.com 8913465Sgabeblack@google.com r = AddrRange(0xbf, 0xc0); 9013465Sgabeblack@google.com EXPECT_FALSE(r.isSubset(r1)); 9113465Sgabeblack@google.com EXPECT_FALSE(r.isSubset(r2)); 9213465Sgabeblack@google.com} 9314048Snikos.nikoleris@arm.com 9414048Snikos.nikoleris@arm.comclass AddrRangeBase : public testing::Test { 9514048Snikos.nikoleris@arm.com protected: 9614048Snikos.nikoleris@arm.com 9714048Snikos.nikoleris@arm.com virtual int getIndex(Addr addr) = 0; 9814048Snikos.nikoleris@arm.com 9914048Snikos.nikoleris@arm.com void testContains() 10014048Snikos.nikoleris@arm.com { 10114048Snikos.nikoleris@arm.com for (Addr addr = start; addr <= end; addr++) { 10214048Snikos.nikoleris@arm.com int i = getIndex(addr); 10314048Snikos.nikoleris@arm.com ASSERT_TRUE(range[i].contains(addr)); 10414048Snikos.nikoleris@arm.com for (int j = 1; j < intlvSize; j++) { 10514048Snikos.nikoleris@arm.com ASSERT_FALSE(range[(i + j) % intlvSize].contains(addr)); 10614048Snikos.nikoleris@arm.com } 10714048Snikos.nikoleris@arm.com } 10814048Snikos.nikoleris@arm.com } 10914048Snikos.nikoleris@arm.com 11014048Snikos.nikoleris@arm.com void testGetOffset() 11114048Snikos.nikoleris@arm.com { 11214048Snikos.nikoleris@arm.com Addr offsets[intlvSize] = {0, 0, 0, 0}; 11314048Snikos.nikoleris@arm.com for (Addr addr = start; addr <= end; addr++) { 11414048Snikos.nikoleris@arm.com int i = getIndex(addr); 11514048Snikos.nikoleris@arm.com Addr offset = range[i].getOffset(addr); 11614048Snikos.nikoleris@arm.com ASSERT_EQ(offsets[i], offset); 11714048Snikos.nikoleris@arm.com offsets[i]++; 11814048Snikos.nikoleris@arm.com } 11914048Snikos.nikoleris@arm.com for (Addr offset: offsets) { 12014048Snikos.nikoleris@arm.com ASSERT_EQ(offset, (end - start + 1) / intlvSize); 12114048Snikos.nikoleris@arm.com } 12214048Snikos.nikoleris@arm.com } 12314048Snikos.nikoleris@arm.com 12414048Snikos.nikoleris@arm.com static const Addr end = 0x1ffff; 12514048Snikos.nikoleris@arm.com static const Addr start = 0x0; 12614048Snikos.nikoleris@arm.com static const int intlvSize = 4; 12714048Snikos.nikoleris@arm.com 12814048Snikos.nikoleris@arm.com AddrRange range[intlvSize]; 12914048Snikos.nikoleris@arm.com}; 13014048Snikos.nikoleris@arm.com 13114048Snikos.nikoleris@arm.com 13214048Snikos.nikoleris@arm.comclass AddrRangeCont : public AddrRangeBase { 13314048Snikos.nikoleris@arm.com protected: 13414048Snikos.nikoleris@arm.com void SetUp() override 13514048Snikos.nikoleris@arm.com { 13614048Snikos.nikoleris@arm.com std::vector<Addr> masks = { 13714048Snikos.nikoleris@arm.com 1UL << xorBits0[0] | 1UL << xorBits0[1], 13814048Snikos.nikoleris@arm.com 1UL << xorBits1[0] | 1UL << xorBits1[1] 13914048Snikos.nikoleris@arm.com }; 14014048Snikos.nikoleris@arm.com for (auto i = 0; i < intlvSize; i++) { 14114048Snikos.nikoleris@arm.com range[i] = AddrRange(start, end, masks, i); 14214048Snikos.nikoleris@arm.com } 14314048Snikos.nikoleris@arm.com } 14414048Snikos.nikoleris@arm.com 14514048Snikos.nikoleris@arm.com int getIndex(Addr addr) override 14614048Snikos.nikoleris@arm.com { 14714048Snikos.nikoleris@arm.com return bits(addr, xorBits1[1], xorBits0[1]) ^ 14814048Snikos.nikoleris@arm.com bits(addr, xorBits1[0], xorBits0[0]); 14914048Snikos.nikoleris@arm.com } 15014048Snikos.nikoleris@arm.com 15114048Snikos.nikoleris@arm.com const int xorBits0[2] = {8, 14}; 15214048Snikos.nikoleris@arm.com const int xorBits1[2] = {9, 15}; 15314048Snikos.nikoleris@arm.com}; 15414048Snikos.nikoleris@arm.com 15514048Snikos.nikoleris@arm.comTEST_F(AddrRangeCont, AddrRangeContains) 15614048Snikos.nikoleris@arm.com{ 15714048Snikos.nikoleris@arm.com testContains(); 15814048Snikos.nikoleris@arm.com} 15914048Snikos.nikoleris@arm.com 16014048Snikos.nikoleris@arm.comTEST_F(AddrRangeCont, AddrRangeGetOffset) 16114048Snikos.nikoleris@arm.com{ 16214048Snikos.nikoleris@arm.com testGetOffset(); 16314048Snikos.nikoleris@arm.com} 16414048Snikos.nikoleris@arm.com 16514048Snikos.nikoleris@arm.com 16614048Snikos.nikoleris@arm.comclass AddrRangeContLegacy : public AddrRangeCont { 16714048Snikos.nikoleris@arm.com protected: 16814048Snikos.nikoleris@arm.com void SetUp() override 16914048Snikos.nikoleris@arm.com { 17014048Snikos.nikoleris@arm.com // Test interleaved ranges with hashing 17114048Snikos.nikoleris@arm.com for (auto i = 0; i < intlvSize; i++) { 17214048Snikos.nikoleris@arm.com range[i] = AddrRange(start, end, xorBits1[0], xorBits1[1], 17314048Snikos.nikoleris@arm.com 2, i); 17414048Snikos.nikoleris@arm.com } 17514048Snikos.nikoleris@arm.com } 17614048Snikos.nikoleris@arm.com}; 17714048Snikos.nikoleris@arm.com 17814048Snikos.nikoleris@arm.comTEST_F(AddrRangeContLegacy, AddrRangeContains) 17914048Snikos.nikoleris@arm.com{ 18014048Snikos.nikoleris@arm.com testContains(); 18114048Snikos.nikoleris@arm.com} 18214048Snikos.nikoleris@arm.com 18314048Snikos.nikoleris@arm.comTEST_F(AddrRangeContLegacy, AddrRangeGetOffset) 18414048Snikos.nikoleris@arm.com{ 18514048Snikos.nikoleris@arm.com testGetOffset(); 18614048Snikos.nikoleris@arm.com} 18714048Snikos.nikoleris@arm.com 18814048Snikos.nikoleris@arm.com 18914048Snikos.nikoleris@arm.comclass AddrRangeArb : public AddrRangeBase { 19014048Snikos.nikoleris@arm.com protected: 19114048Snikos.nikoleris@arm.com void SetUp() override 19214048Snikos.nikoleris@arm.com { 19314048Snikos.nikoleris@arm.com std::vector<Addr> masks = { 19414048Snikos.nikoleris@arm.com 1UL << xorBits0[0] | 1UL << xorBits0[1], 19514048Snikos.nikoleris@arm.com 1UL << xorBits1[0] | 1UL << xorBits1[1] 19614048Snikos.nikoleris@arm.com }; 19714048Snikos.nikoleris@arm.com for (auto i = 0; i < intlvSize; i++) { 19814048Snikos.nikoleris@arm.com range[i] = AddrRange(start, end, masks, i); 19914048Snikos.nikoleris@arm.com } 20014048Snikos.nikoleris@arm.com } 20114048Snikos.nikoleris@arm.com 20214048Snikos.nikoleris@arm.com int getIndex(Addr addr) override 20314048Snikos.nikoleris@arm.com { 20414048Snikos.nikoleris@arm.com return (bits(addr, xorBits0[0]) ^ bits(addr, xorBits0[1])) | 20514048Snikos.nikoleris@arm.com (bits(addr, xorBits1[0]) ^ bits(addr, xorBits1[1])) << 1; 20614048Snikos.nikoleris@arm.com } 20714048Snikos.nikoleris@arm.com 20814048Snikos.nikoleris@arm.com const int xorBits0[2] = {11, 12}; 20914048Snikos.nikoleris@arm.com const int xorBits1[2] = {8, 15}; 21014048Snikos.nikoleris@arm.com}; 21114048Snikos.nikoleris@arm.com 21214048Snikos.nikoleris@arm.comTEST_F(AddrRangeArb, AddrRangeContains) 21314048Snikos.nikoleris@arm.com{ 21414048Snikos.nikoleris@arm.com testContains(); 21514048Snikos.nikoleris@arm.com} 21614048Snikos.nikoleris@arm.com 21714048Snikos.nikoleris@arm.comTEST_F(AddrRangeArb, AddrRangeGetOffset) 21814048Snikos.nikoleris@arm.com{ 21914048Snikos.nikoleris@arm.com testGetOffset(); 22014048Snikos.nikoleris@arm.com} 221