blob: d4058a3316b38e35ec990fddee94d74dabbae11f [file] [log] [blame]
// Copyright 2022 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 "src/graphics/display/drivers/intel-i915/acpi-memory-region.h"
#include <lib/stdcompat/span.h>
#include <lib/zx/vmar.h>
#include <lib/zx/vmo.h>
#include <zircon/assert.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>
#include <cstdint>
#include <utility>
#include <gtest/gtest.h>
namespace i915 {
namespace {
class AcpiMemoryRegionTest : public ::testing::Test {
public:
void SetUp() override {
std::pair<zx::vmo, cpp20::span<uint8_t>> vmo_and_span = CreateAndMapVmo(kVmoSize);
vmo_ = std::move(vmo_and_span).first;
region_data_ = std::move(vmo_and_span).second;
ASSERT_TRUE(vmo_.is_valid());
ASSERT_FALSE(region_data_.empty());
vmo_unowned_ = vmo_.borrow();
}
// Returns an invalid VMO and empty span on failure.
static std::pair<zx::vmo, cpp20::span<uint8_t>> CreateAndMapVmo(int vmo_size) {
zx::vmo vmo;
zx_status_t status = zx::vmo::create(vmo_size, /*options=*/0, &vmo);
if (status != ZX_OK) {
return {};
}
zx_vaddr_t mapped_address;
status = zx::vmar::root_self()->map(ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, /*vmar_offset=*/0, vmo,
/*vmo_offset=*/0, vmo_size, &mapped_address);
if (status != ZX_OK) {
return {};
}
// NOLINTBEGIN(performance-no-int-to-ptr)
uint8_t* const mapped_base = reinterpret_cast<uint8_t*>(mapped_address);
// NOLINTEND(performance-no-int-to-ptr)
return std::make_pair(std::move(vmo), cpp20::span(mapped_base, kVmoSize));
}
protected:
static constexpr int kVmoSize = 16;
cpp20::span<uint8_t> region_data_;
zx::vmo vmo_;
zx::unowned_vmo vmo_unowned_;
};
TEST_F(AcpiMemoryRegionTest, EmptyConstructor) {
AcpiMemoryRegion memory_region;
EXPECT_FALSE(memory_region.vmo_for_testing()->is_valid());
EXPECT_TRUE(memory_region.is_empty());
EXPECT_TRUE(memory_region.data().empty());
}
TEST_F(AcpiMemoryRegionTest, TestConstructor) {
AcpiMemoryRegion memory_region(std::move(vmo_), region_data_);
EXPECT_EQ(memory_region.vmo_for_testing(), vmo_unowned_);
EXPECT_EQ(memory_region.data().data(), region_data_.data());
EXPECT_EQ(memory_region.data().size(), region_data_.size());
EXPECT_FALSE(memory_region.is_empty());
}
TEST_F(AcpiMemoryRegionTest, MoveConstructorEmptiesRhs) {
AcpiMemoryRegion rhs(std::move(vmo_), region_data_);
AcpiMemoryRegion lhs = std::move(rhs);
EXPECT_FALSE(rhs.vmo_for_testing()->is_valid());
EXPECT_TRUE(rhs.is_empty());
EXPECT_TRUE(rhs.data().empty());
EXPECT_EQ(lhs.vmo_for_testing(), vmo_unowned_);
EXPECT_EQ(lhs.data().data(), region_data_.data());
EXPECT_EQ(lhs.data().size(), region_data_.size());
EXPECT_FALSE(lhs.is_empty());
}
TEST_F(AcpiMemoryRegionTest, MoveAssignmentSwapsRhs) {
AcpiMemoryRegion rhs(std::move(vmo_), region_data_);
std::pair<zx::vmo, cpp20::span<uint8_t>> vmo_and_span = CreateAndMapVmo(kVmoSize);
zx::vmo lhs_vmo = std::move(vmo_and_span).first;
cpp20::span<uint8_t> lhs_region_data = std::move(vmo_and_span).second;
ASSERT_TRUE(lhs_vmo.is_valid());
ASSERT_FALSE(lhs_region_data.empty());
const zx::unowned_vmo lhs_vmo_unowned = lhs_vmo.borrow();
AcpiMemoryRegion lhs(std::move(lhs_vmo), lhs_region_data);
lhs = std::move(rhs);
EXPECT_EQ(rhs.vmo_for_testing(), lhs_vmo_unowned);
EXPECT_EQ(rhs.data().data(), lhs_region_data.data());
EXPECT_EQ(rhs.data().size(), lhs_region_data.size());
EXPECT_FALSE(rhs.is_empty());
EXPECT_EQ(lhs.vmo_for_testing(), vmo_unowned_);
EXPECT_EQ(lhs.data().data(), region_data_.data());
EXPECT_EQ(lhs.data().size(), region_data_.size());
EXPECT_FALSE(lhs.is_empty());
}
} // namespace
} // namespace i915