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