// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "garnet/drivers/gpu/msd-vsl-gc/src/address_space.h"
#include "mock/mock_bus_mapper.h"
#include "gtest/gtest.h"

class TestAddressSpace {
public:
    class MockAddressSpaceOwner : public AddressSpace::Owner {
    public:
        // Put bus addresses close to the 40 bit limit
        MockAddressSpaceOwner() : bus_mapper_((1ul << (40 - 1))) {}

        magma::PlatformBusMapper* bus_mapper() override { return &bus_mapper_; }

    private:
        MockBusMapper bus_mapper_;
    };

    static void check_pte_entries_clear(AddressSpace* address_space, uint64_t gpu_addr,
                                        uint64_t page_count)
    {
        for (unsigned int i = 0; i < page_count; i++) {
            uint64_t addr = gpu_addr + i * PAGE_SIZE;
            uint64_t page_table_index = (addr >>= PAGE_SHIFT) & AddressSpace::kPageTableMask;
            uint64_t page_directory_index =
                (addr >>= AddressSpace::kPageTableShift) & AddressSpace::kPageDirectoryMask;

            auto page_table = address_space->root_->GetPageTable(page_directory_index, false);
            auto* pde = address_space->root_->entry(page_directory_index);

            if (page_table) {
                auto* pte = page_table->entry(page_table_index);
                EXPECT_EQ(*pte, AddressSpace::kInvalidPte);
                EXPECT_NE(*pde, AddressSpace::kInvalidPde);
            } else {
                EXPECT_EQ(*pde, AddressSpace::kInvalidPde);
            }
        }
    }

    static void check_pte_entries(AddressSpace* address_space,
                                  magma::PlatformBusMapper::BusMapping* bus_mapping,
                                  uint64_t gpu_addr, uint64_t mapping_page_count)
    {
        ASSERT_NE(address_space, nullptr);

        std::vector<uint64_t>& bus_addr = bus_mapping->Get();
        ASSERT_LE(mapping_page_count, bus_addr.size());

        for (unsigned int i = 0; i < mapping_page_count; i++) {
            uint64_t addr = gpu_addr + i * PAGE_SIZE;
            uint64_t page_table_index = (addr >>= PAGE_SHIFT) & AddressSpace::kPageTableMask;
            uint64_t page_directory_index =
                (addr >>= AddressSpace::kPageTableShift) & AddressSpace::kPageDirectoryMask;

            auto page_table = address_space->root_->GetPageTable(page_directory_index, false);
            ASSERT_NE(page_table, nullptr);

            auto* pde = address_space->root_->entry(page_directory_index);
            EXPECT_NE(*pde, AddressSpace::kInvalidPde);

            AddressSpace::pte_t expected_pte;
            EXPECT_TRUE(AddressSpace::pte_encode(bus_addr[i], true, true, true, &expected_pte));
            auto* pte = page_table->entry(page_table_index);
            EXPECT_EQ(*pte, expected_pte);
        }
    }

    static void Init()
    {
        MockAddressSpaceOwner owner;
        auto address_space = AddressSpace::Create(&owner);
        ASSERT_NE(nullptr, address_space);

        constexpr uint32_t kPageCount = 1000;
        check_pte_entries_clear(address_space.get(), 0, kPageCount);
        check_pte_entries_clear(address_space.get(), (1 << 31) - kPageCount * PAGE_SIZE,
                                kPageCount);
    }

    static void Insert(AddressSpace::gpu_addr_t gpu_addr, uint32_t size_in_pages,
                       uint32_t mapping_page_count)
    {
        MockAddressSpaceOwner owner;
        auto address_space = AddressSpace::Create(&owner);
        auto buffer = magma::PlatformBuffer::Create(size_in_pages * PAGE_SIZE, "test");
        auto bus_mapping = owner.bus_mapper()->MapPageRangeBus(buffer.get(), 0, size_in_pages);
        EXPECT_TRUE(address_space->Insert(gpu_addr, bus_mapping.get(), mapping_page_count));
        check_pte_entries(address_space.get(), bus_mapping.get(), gpu_addr, mapping_page_count);
    }

    static void Clear(AddressSpace::gpu_addr_t gpu_addr, uint32_t size_in_pages)
    {
        MockAddressSpaceOwner owner;
        auto address_space = AddressSpace::Create(&owner);
        EXPECT_TRUE(address_space->Clear(gpu_addr, size_in_pages));
        check_pte_entries_clear(address_space.get(), gpu_addr, size_in_pages);
    }

    static void InsertAndClear(AddressSpace::gpu_addr_t gpu_addr, uint32_t size_in_pages,
                               uint32_t mapping_page_count)
    {
        MockAddressSpaceOwner owner;
        auto address_space = AddressSpace::Create(&owner);
        auto buffer = magma::PlatformBuffer::Create(size_in_pages * PAGE_SIZE, "test");
        auto bus_mapping = owner.bus_mapper()->MapPageRangeBus(buffer.get(), 0, size_in_pages);
        EXPECT_TRUE(address_space->Insert(gpu_addr, bus_mapping.get(), mapping_page_count));
        EXPECT_TRUE(address_space->Clear(gpu_addr, mapping_page_count));
        check_pte_entries_clear(address_space.get(), gpu_addr, mapping_page_count);
    }

    static void InsertManyClearOnce(AddressSpace::gpu_addr_t gpu_addr)
    {
        MockAddressSpaceOwner owner;
        auto address_space = AddressSpace::Create(&owner);
        auto buffer = magma::PlatformBuffer::Create(PAGE_SIZE, "test");
        auto bus_mapping = owner.bus_mapper()->MapPageRangeBus(buffer.get(), 0, 1);
        EXPECT_TRUE(address_space->Insert(gpu_addr, bus_mapping.get(), 1));
        EXPECT_TRUE(address_space->Insert(gpu_addr + 2 * buffer->size(), bus_mapping.get(), 1));
        EXPECT_TRUE(address_space->Insert(gpu_addr + 5 * buffer->size(), bus_mapping.get(), 1));
        EXPECT_TRUE(address_space->Insert(gpu_addr + 15 * buffer->size(), bus_mapping.get(), 1));
        EXPECT_TRUE(address_space->Clear(gpu_addr, 1024));
        check_pte_entries_clear(address_space.get(), gpu_addr, 1024);
    }

    static void GarbageCollect()
    {
        MockAddressSpaceOwner owner;
        auto address_space = AddressSpace::Create(&owner);

        uint64_t gpu_addr = 0x1000000;
        uint64_t page_directory_index = (gpu_addr >> (PAGE_SHIFT + AddressSpace::kPageTableShift)) &
                                        AddressSpace::kPageDirectoryMask;

        EXPECT_EQ(0u, address_space->root_->valid_count(page_directory_index));

        uint32_t size_in_pages = 1024 + 1;
        auto buffer = magma::PlatformBuffer::Create(size_in_pages * PAGE_SIZE, "test");
        auto bus_mapping = owner.bus_mapper()->MapPageRangeBus(buffer.get(), 0, size_in_pages);

        // Insert 1st
        EXPECT_TRUE(address_space->Insert(gpu_addr, bus_mapping.get(), size_in_pages));
        check_pte_entries(address_space.get(), bus_mapping.get(), gpu_addr, size_in_pages);

        EXPECT_EQ(1024u, address_space->root_->valid_count(page_directory_index));
        EXPECT_NE(nullptr, address_space->root_->GetPageTable(page_directory_index, false));

        EXPECT_EQ(1u, address_space->root_->valid_count(page_directory_index + 1));
        EXPECT_NE(nullptr, address_space->root_->GetPageTable(page_directory_index + 1, false));

        // Insert 2nd
        EXPECT_TRUE(address_space->Insert(gpu_addr + PAGE_SIZE * size_in_pages, bus_mapping.get(),
                                          size_in_pages));
        check_pte_entries(address_space.get(), bus_mapping.get(),
                          gpu_addr + PAGE_SIZE * size_in_pages, size_in_pages);

        EXPECT_EQ(1024u, address_space->root_->valid_count(page_directory_index + 1));
        EXPECT_NE(nullptr, address_space->root_->GetPageTable(page_directory_index + 1, false));

        EXPECT_EQ(2u, address_space->root_->valid_count(page_directory_index + 2));
        EXPECT_NE(nullptr, address_space->root_->GetPageTable(page_directory_index + 2, false));

        // Clear 1st
        EXPECT_TRUE(address_space->Clear(gpu_addr, size_in_pages));
        check_pte_entries_clear(address_space.get(), gpu_addr, size_in_pages);

        EXPECT_EQ(0u, address_space->root_->valid_count(page_directory_index));
        EXPECT_EQ(nullptr, address_space->root_->GetPageTable(page_directory_index, false));

        EXPECT_EQ(1023u, address_space->root_->valid_count(page_directory_index + 1));
        EXPECT_NE(nullptr, address_space->root_->GetPageTable(page_directory_index + 1, false));

        EXPECT_EQ(2u, address_space->root_->valid_count(page_directory_index + 2));
        EXPECT_NE(nullptr, address_space->root_->GetPageTable(page_directory_index + 2, false));

        // Clear 2nd
        EXPECT_TRUE(address_space->Clear(gpu_addr + PAGE_SIZE * size_in_pages, size_in_pages));
        check_pte_entries_clear(address_space.get(), gpu_addr + PAGE_SIZE * size_in_pages,
                                size_in_pages);

        EXPECT_EQ(0u, address_space->root_->valid_count(page_directory_index + 1));
        EXPECT_EQ(nullptr, address_space->root_->GetPageTable(page_directory_index + 1, false));

        EXPECT_EQ(0u, address_space->root_->valid_count(page_directory_index + 2));
        EXPECT_EQ(nullptr, address_space->root_->GetPageTable(page_directory_index + 2, false));
    }
};

TEST(AddressSpace, Init) { TestAddressSpace::Init(); }

TEST(AddressSpace, InsertAtStart) { TestAddressSpace::Insert(0, 10, 10); }

TEST(AddressSpace, InsertAndClearAtStart) { TestAddressSpace::InsertAndClear(0, 10, 10); }

TEST(AddressSpace, InsertAtEnd) { TestAddressSpace::Insert((1ul << 32) - PAGE_SIZE, 1, 1); }

TEST(AddressSpace, InsertAndClearAtEnd)
{
    TestAddressSpace::InsertAndClear((1ul << 32) - PAGE_SIZE, 1, 1);
}

TEST(AddressSpace, Clear) { TestAddressSpace::Clear(0, 10); }

TEST(AddressSpace, InsertShort) { TestAddressSpace::Insert(0, 10, 5); }

TEST(AddressSpace, InsertShortAndClear) { TestAddressSpace::InsertAndClear(0, 10, 5); }

TEST(AddressSpace, InsertManyClearOnce) { TestAddressSpace::InsertManyClearOnce(0); }

TEST(AddressSpace, GarbageCollect) { TestAddressSpace::GarbageCollect(); }
