1 /*
2 * Copyright (C) 2021 Intel Corporation
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 */
7
8 #include "shared/source/memory_manager/memory_banks.h"
9 #include "shared/source/memory_manager/physical_address_allocator.h"
10 #include "shared/test/common/mocks/mock_physical_address_allocator.h"
11 #include "shared/test/common/test_macros/test.h"
12
13 using namespace NEO;
14
15 template <typename GfxFamily>
16 class MockPhysicalAddressAllocatorHw : public PhysicalAddressAllocatorHw<GfxFamily> {
17 public:
18 using PhysicalAddressAllocator::initialPageAddress;
19 using PhysicalAddressAllocator::mainAllocator;
20 using PhysicalAddressAllocatorHw<GfxFamily>::bankAllocators;
21 using PhysicalAddressAllocatorHw<GfxFamily>::memoryBankSize;
22 using PhysicalAddressAllocatorHw<GfxFamily>::numberOfBanks;
23 using PhysicalAddressAllocatorHw<GfxFamily>::PhysicalAddressAllocatorHw;
24
MockPhysicalAddressAllocatorHw()25 MockPhysicalAddressAllocatorHw() : PhysicalAddressAllocatorHw<GfxFamily>(MemoryConstants::gigaByte, 4) {}
26 };
27
28 using PhysicalAddressAllocatorHwTest = ::testing::Test;
29
HWTEST_F(PhysicalAddressAllocatorHwTest,givenZeroBanksWhenPageInBankIsReservedThenMainAllocatorIsUsed)30 HWTEST_F(PhysicalAddressAllocatorHwTest, givenZeroBanksWhenPageInBankIsReservedThenMainAllocatorIsUsed) {
31 size_t bankSize = 1024 * MemoryConstants::pageSize;
32 MockPhysicalAddressAllocatorHw<FamilyType> allocator(bankSize, 0);
33
34 auto physAddress = allocator.reserve4kPage(MemoryBanks::getBankForLocalMemory(1));
35 EXPECT_NE(0u, physAddress);
36 auto address = allocator.mainAllocator.load();
37
38 auto physAddress1 = allocator.reserve4kPage(MemoryBanks::getBankForLocalMemory(1));
39 EXPECT_NE(0u, physAddress1);
40 EXPECT_NE(physAddress, physAddress1);
41
42 auto address1 = allocator.mainAllocator.load();
43
44 EXPECT_NE(address, address1);
45 }
46
HWTEST_F(PhysicalAddressAllocatorHwTest,given4BanksWhenAllocatorIsCreatedThen4AllocatorsAreCreated)47 HWTEST_F(PhysicalAddressAllocatorHwTest, given4BanksWhenAllocatorIsCreatedThen4AllocatorsAreCreated) {
48 MockPhysicalAddressAllocatorHw<FamilyType> allocator(2 * MemoryConstants::megaByte, 4);
49 EXPECT_NE(nullptr, allocator.bankAllocators);
50 EXPECT_EQ(4u, allocator.numberOfBanks);
51 EXPECT_EQ(2 * MemoryConstants::megaByte, allocator.memoryBankSize);
52 }
53
HWTEST_F(PhysicalAddressAllocatorHwTest,given4BanksWhenReservingFirstPageInBanksThenNonZeroAddressIsReturnedAndEachBankAddressIsDifferent)54 HWTEST_F(PhysicalAddressAllocatorHwTest, given4BanksWhenReservingFirstPageInBanksThenNonZeroAddressIsReturnedAndEachBankAddressIsDifferent) {
55 MockPhysicalAddressAllocatorHw<FamilyType> allocator(2 * MemoryConstants::megaByte, 4);
56 auto physAddress0 = allocator.reserve4kPage(MemoryBanks::getBankForLocalMemory(0));
57 EXPECT_NE(0u, physAddress0);
58 auto physAddress1 = allocator.reserve4kPage(MemoryBanks::getBankForLocalMemory(1));
59 EXPECT_NE(0u, physAddress1);
60 auto physAddress2 = allocator.reserve4kPage(MemoryBanks::getBankForLocalMemory(2));
61 EXPECT_NE(0u, physAddress2);
62 auto physAddress3 = allocator.reserve4kPage(MemoryBanks::getBankForLocalMemory(3));
63 EXPECT_NE(0u, physAddress3);
64
65 EXPECT_NE(physAddress0, physAddress1);
66 EXPECT_NE(physAddress0, physAddress2);
67 EXPECT_NE(physAddress0, physAddress3);
68 EXPECT_NE(physAddress1, physAddress2);
69 EXPECT_NE(physAddress1, physAddress3);
70 EXPECT_NE(physAddress2, physAddress3);
71 }
72
HWTEST_F(PhysicalAddressAllocatorHwTest,given4BanksWhenReservingFirstPageInBanksThenEveryNextBankAddressIsOffsetedByBankSize)73 HWTEST_F(PhysicalAddressAllocatorHwTest, given4BanksWhenReservingFirstPageInBanksThenEveryNextBankAddressIsOffsetedByBankSize) {
74 size_t bankSize = 4 * 1024 * MemoryConstants::pageSize;
75 MockPhysicalAddressAllocatorHw<FamilyType> allocator(bankSize, 4);
76 auto physAddress0 = allocator.reserve4kPage(MemoryBanks::getBankForLocalMemory(0));
77 EXPECT_EQ(0x1000u, physAddress0);
78
79 auto physAddress1 = allocator.reserve4kPage(MemoryBanks::getBankForLocalMemory(1));
80 EXPECT_EQ(bankSize, physAddress1);
81
82 auto physAddress2 = allocator.reserve4kPage(MemoryBanks::getBankForLocalMemory(2));
83 EXPECT_EQ(2 * bankSize, physAddress2);
84
85 auto physAddress3 = allocator.reserve4kPage(MemoryBanks::getBankForLocalMemory(3));
86 EXPECT_EQ(3 * bankSize, physAddress3);
87 }
88
HWTEST_F(PhysicalAddressAllocatorHwTest,givenSpecificBankWhenReservingConsecutivePagesThenReturnedAddressesAreDifferent)89 HWTEST_F(PhysicalAddressAllocatorHwTest, givenSpecificBankWhenReservingConsecutivePagesThenReturnedAddressesAreDifferent) {
90 auto bankSize = 4 * 1024 * MemoryConstants::pageSize;
91 MockPhysicalAddressAllocatorHw<FamilyType> allocator(bankSize, 4);
92
93 uint32_t banks[4] = {MemoryBanks::getBankForLocalMemory(0),
94 MemoryBanks::getBankForLocalMemory(1),
95 MemoryBanks::getBankForLocalMemory(2),
96 MemoryBanks::getBankForLocalMemory(3)};
97
98 for (uint32_t bankIndex = 0; bankIndex < 4; bankIndex++) {
99 auto physAddress = allocator.reserve4kPage(banks[bankIndex]);
100 EXPECT_NE(0u, physAddress);
101 auto physAddress1 = allocator.reserve4kPage(banks[bankIndex]);
102 EXPECT_NE(physAddress, physAddress1);
103 auto physAddress2 = allocator.reserve4kPage(banks[bankIndex]);
104 EXPECT_NE(physAddress1, physAddress2);
105 }
106 }
107
HWTEST_F(PhysicalAddressAllocatorHwTest,givenSingleBankWhen4kAnd64kPagesAreAllocatedAlternatelyThenCorrectAlignementIsSatisfied)108 HWTEST_F(PhysicalAddressAllocatorHwTest, givenSingleBankWhen4kAnd64kPagesAreAllocatedAlternatelyThenCorrectAlignementIsSatisfied) {
109 size_t bankSize = 4 * 1024 * MemoryConstants::pageSize;
110 MockPhysicalAddressAllocatorHw<FamilyType> allocator(bankSize, 4);
111 auto physAddress0 = allocator.reserve4kPage(MemoryBanks::getBankForLocalMemory(0));
112 EXPECT_NE(0u, physAddress0);
113 EXPECT_EQ(0u, physAddress0 & MemoryConstants::pageMask);
114
115 auto physAddress1 = allocator.reserve64kPage(MemoryBanks::getBankForLocalMemory(0));
116 EXPECT_NE(0u, physAddress1);
117 EXPECT_EQ(0u, physAddress1 & MemoryConstants::page64kMask);
118
119 auto physAddress2 = allocator.reserve4kPage(MemoryBanks::getBankForLocalMemory(0));
120 EXPECT_NE(0u, physAddress2);
121 EXPECT_EQ(0u, physAddress2 & MemoryConstants::pageMask);
122
123 auto physAddress3 = allocator.reserve64kPage(MemoryBanks::getBankForLocalMemory(0));
124 EXPECT_NE(0u, physAddress3);
125 EXPECT_EQ(0u, physAddress3 & MemoryConstants::page64kMask);
126 }
127
TEST(MemoryBank,givenDifferentDeviceOrdinalsWhenGettingBankThenCorrectBanksAreReturned)128 TEST(MemoryBank, givenDifferentDeviceOrdinalsWhenGettingBankThenCorrectBanksAreReturned) {
129 auto bank = MemoryBanks::getBankForLocalMemory(0);
130 EXPECT_EQ(1u, bank);
131
132 bank = MemoryBanks::getBankForLocalMemory(1);
133 EXPECT_EQ(2u, bank);
134
135 bank = MemoryBanks::getBankForLocalMemory(2);
136 EXPECT_EQ(3u, bank);
137
138 bank = MemoryBanks::getBankForLocalMemory(3);
139 EXPECT_EQ(4u, bank);
140 }
141