blob: 9f70f9d76e0813d38ac7f5be9f6f55d0caa0ceb7 [file] [log] [blame] [edit]
// Copyright 2024 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 <lib/driver/mmio/cpp/mmio.h>
#include <lib/driver/mock-mmio/cpp/globally-ordered-region.h>
#include <gtest/gtest.h>
namespace mock_mmio {
namespace {
class GloballyOrderedRegionTest : public ::testing::Test {
public:
void TearDown() override { mmio_range_.CheckAllAccessesReplayed(); }
protected:
GloballyOrderedRegion mmio_range_{0x4000, GloballyOrderedRegion::Size::k32};
fdf::MmioBuffer mmio_buffer_{mmio_range_.GetMmioBuffer()};
};
TEST_F(GloballyOrderedRegionTest, NoOperations) {
GloballyOrderedRegion mmio_range(0x1000, GloballyOrderedRegion::Size::k32);
mmio_range_.CheckAllAccessesReplayed();
SUCCEED();
}
TEST_F(GloballyOrderedRegionTest, ConstructorRangeSize) {
GloballyOrderedRegion mmio_range1(0x1000, GloballyOrderedRegion::Size::k32);
GloballyOrderedRegion mmio_range2(0x4000, GloballyOrderedRegion::Size::k32);
fdf::MmioBuffer mmio_range1_buffer = mmio_range1.GetMmioBuffer();
fdf::MmioBuffer mmio_range2_buffer = mmio_range2.GetMmioBuffer();
EXPECT_EQ(0x1000u, mmio_range1_buffer.get_size());
EXPECT_EQ(0x4000u, mmio_range2_buffer.get_size());
}
TEST_F(GloballyOrderedRegionTest, ConstructorDefaultOperationSize) {
GloballyOrderedRegion mmio_range1(0x1000, GloballyOrderedRegion::Size::k32);
GloballyOrderedRegion mmio_range2(0x1000, GloballyOrderedRegion::Size::k16);
fdf::MmioBuffer mmio_range1_buffer = mmio_range1.GetMmioBuffer();
fdf::MmioBuffer mmio_range2_buffer = mmio_range2.GetMmioBuffer();
mmio_range1.Expect({.address = 0x100, .value = 0x01});
mmio_range2.Expect({.address = 0x100, .value = 0x01});
EXPECT_EQ(0x01u, mmio_range1_buffer.Read32(0x100));
EXPECT_EQ(0x01u, mmio_range2_buffer.Read16(0x100));
}
TEST_F(GloballyOrderedRegionTest, ReadOnce) {
mmio_range_.Expect({.address = 0x100, .value = 0x42434445});
EXPECT_EQ(0x42434445u, mmio_buffer_.Read32(0x100));
}
TEST_F(GloballyOrderedRegionTest, ReadOnceNonDefaultSize) {
mmio_range_.Expect(
{.address = 0x100, .value = 0x42434445, .size = GloballyOrderedRegion::Size::k64});
EXPECT_EQ(0x42434445u, mmio_buffer_.Read64(0x100));
}
TEST_F(GloballyOrderedRegionTest, ReadOnceExplicitSize) {
mmio_range_.Expect(
{.address = 0x100, .value = 0x42434445, .size = GloballyOrderedRegion::Size::k32});
EXPECT_EQ(0x42434445u, mmio_buffer_.Read32(0x100));
}
TEST_F(GloballyOrderedRegionTest, ReadRepeated) {
mmio_range_.Expect({.address = 0x100, .value = 0x42});
mmio_range_.Expect({.address = 0x100, .value = 0x43});
mmio_range_.Expect({.address = 0x100, .value = 0x44});
mmio_range_.Expect({.address = 0x100, .value = 0x45});
EXPECT_EQ(0x42u, mmio_buffer_.Read32(0x100));
EXPECT_EQ(0x43u, mmio_buffer_.Read32(0x100));
EXPECT_EQ(0x44u, mmio_buffer_.Read32(0x100));
EXPECT_EQ(0x45u, mmio_buffer_.Read32(0x100));
}
TEST_F(GloballyOrderedRegionTest, ReadRepeatedFromAccessList) {
mmio_range_.Expect(GloballyOrderedRegion::AccessList({
{.address = 0x100, .value = 0x42},
{.address = 0x100, .value = 0x43},
{.address = 0x100, .value = 0x44},
{.address = 0x100, .value = 0x45},
}));
EXPECT_EQ(0x42u, mmio_buffer_.Read32(0x100));
EXPECT_EQ(0x43u, mmio_buffer_.Read32(0x100));
EXPECT_EQ(0x44u, mmio_buffer_.Read32(0x100));
EXPECT_EQ(0x45u, mmio_buffer_.Read32(0x100));
}
TEST_F(GloballyOrderedRegionTest, ReadVaryingAddressSize) {
mmio_range_.Expect({.address = 0x100, .value = 0x42});
mmio_range_.Expect({.address = 0x104, .value = 0x43, .size = GloballyOrderedRegion::Size::k16});
mmio_range_.Expect({.address = 0x106, .value = 0x44, .size = GloballyOrderedRegion::Size::k8});
mmio_range_.Expect({.address = 0x108, .value = 0x45, .size = GloballyOrderedRegion::Size::k64});
EXPECT_EQ(0x42u, mmio_buffer_.Read32(0x100));
EXPECT_EQ(0x43u, mmio_buffer_.Read16(0x104));
EXPECT_EQ(0x44u, mmio_buffer_.Read8(0x106));
EXPECT_EQ(0x45u, mmio_buffer_.Read64(0x108));
}
TEST_F(GloballyOrderedRegionTest, ReadVaryingAddressSizeFromAccessLists) {
mmio_range_.Expect(GloballyOrderedRegion::AccessList({
{.address = 0x100, .value = 0x42},
{.address = 0x104, .value = 0x43, .size = GloballyOrderedRegion::Size::k16},
}));
mmio_range_.Expect(GloballyOrderedRegion::AccessList({
{.address = 0x106, .value = 0x44, .size = GloballyOrderedRegion::Size::k8},
{.address = 0x108, .value = 0x45, .size = GloballyOrderedRegion::Size::k64},
}));
EXPECT_EQ(0x42u, mmio_buffer_.Read32(0x100));
EXPECT_EQ(0x43u, mmio_buffer_.Read16(0x104));
EXPECT_EQ(0x44u, mmio_buffer_.Read8(0x106));
EXPECT_EQ(0x45u, mmio_buffer_.Read64(0x108));
}
TEST_F(GloballyOrderedRegionTest, WriteOnce) {
mmio_range_.Expect({.address = 0x100, .value = 0x42434445, .write = true});
mmio_buffer_.Write32(0x42434445, 0x100);
mmio_range_.CheckAllAccessesReplayed();
SUCCEED();
}
TEST_F(GloballyOrderedRegionTest, WriteOnceNonDefaultSize) {
mmio_range_.Expect(
{.address = 0x100, .value = 0x42434445, .size = GloballyOrderedRegion::Size::k64});
EXPECT_EQ(0x42434445u, mmio_buffer_.Read64(0x100));
}
TEST_F(GloballyOrderedRegionTest, WriteOnceExplicitSize) {
mmio_range_.Expect(
{.address = 0x100, .value = 0x42434445, .size = GloballyOrderedRegion::Size::k32});
EXPECT_EQ(0x42434445u, mmio_buffer_.Read32(0x100));
}
TEST_F(GloballyOrderedRegionTest, WriteRepeated) {
mmio_range_.Expect({.address = 0x100, .value = 0x42, .write = true});
mmio_range_.Expect({.address = 0x100, .value = 0x43, .write = true});
mmio_range_.Expect({.address = 0x100, .value = 0x44, .write = true});
mmio_range_.Expect({.address = 0x100, .value = 0x45, .write = true});
mmio_buffer_.Write32(0x42, 0x100);
mmio_buffer_.Write32(0x43, 0x100);
mmio_buffer_.Write32(0x44, 0x100);
mmio_buffer_.Write32(0x45, 0x100);
}
TEST_F(GloballyOrderedRegionTest, WriteRepeatedFromAccessList) {
mmio_range_.Expect(
GloballyOrderedRegion::AccessList({{.address = 0x100, .value = 0x42, .write = true},
{.address = 0x100, .value = 0x43, .write = true},
{.address = 0x100, .value = 0x44, .write = true},
{.address = 0x100, .value = 0x45, .write = true}}));
mmio_buffer_.Write32(0x42, 0x100);
mmio_buffer_.Write32(0x43, 0x100);
mmio_buffer_.Write32(0x44, 0x100);
mmio_buffer_.Write32(0x45, 0x100);
}
TEST_F(GloballyOrderedRegionTest, WriteVaryingAddressSize) {
mmio_range_.Expect({.address = 0x100, .value = 0x42, .write = true});
mmio_range_.Expect(
{.address = 0x104, .value = 0x43, .write = true, .size = GloballyOrderedRegion::Size::k16});
mmio_range_.Expect(
{.address = 0x106, .value = 0x44, .write = true, .size = GloballyOrderedRegion::Size::k8});
mmio_range_.Expect(
{.address = 0x108, .value = 0x45, .write = true, .size = GloballyOrderedRegion::Size::k64});
mmio_buffer_.Write32(0x42, 0x100);
mmio_buffer_.Write16(0x43, 0x104);
mmio_buffer_.Write8(0x44, 0x106);
mmio_buffer_.Write64(0x45, 0x108);
}
TEST_F(GloballyOrderedRegionTest, WriteVaryingAddressSizeFromAccessLists) {
mmio_range_.Expect(GloballyOrderedRegion::AccessList({
{.address = 0x100, .value = 0x42, .write = true},
{.address = 0x104, .value = 0x43, .write = true, .size = GloballyOrderedRegion::Size::k16},
}));
mmio_range_.Expect(GloballyOrderedRegion::AccessList({
{.address = 0x106, .value = 0x44, .write = true, .size = GloballyOrderedRegion::Size::k8},
{.address = 0x108, .value = 0x45, .write = true, .size = GloballyOrderedRegion::Size::k64},
}));
mmio_buffer_.Write32(0x42, 0x100);
mmio_buffer_.Write16(0x43, 0x104);
mmio_buffer_.Write8(0x44, 0x106);
mmio_buffer_.Write64(0x45, 0x108);
}
TEST_F(GloballyOrderedRegionTest, InterleavedReadAndWrite) {
mmio_range_.Expect({.address = 0x100, .value = 0x42, .write = true});
mmio_range_.Expect({.address = 0x104, .value = 0x43, .size = GloballyOrderedRegion::Size::k16});
mmio_range_.Expect(
{.address = 0x106, .value = 0x44, .write = true, .size = GloballyOrderedRegion::Size::k8});
mmio_range_.Expect({.address = 0x108, .value = 0x45, .size = GloballyOrderedRegion::Size::k64});
mmio_buffer_.Write32(0x42, 0x100);
EXPECT_EQ(0x43u, mmio_buffer_.Read16(0x104));
mmio_buffer_.Write8(0x44, 0x106);
EXPECT_EQ(0x45u, mmio_buffer_.Read64(0x108));
}
TEST_F(GloballyOrderedRegionTest, InterleavedReadAndWriteFromAccessList) {
mmio_range_.Expect(GloballyOrderedRegion::AccessList({
{.address = 0x100, .value = 0x42, .write = true},
{.address = 0x104, .value = 0x43, .size = GloballyOrderedRegion::Size::k16},
{.address = 0x106, .value = 0x44, .write = true, .size = GloballyOrderedRegion::Size::k8},
{.address = 0x108, .value = 0x45, .size = GloballyOrderedRegion::Size::k64},
}));
mmio_buffer_.Write32(0x42, 0x100);
EXPECT_EQ(0x43u, mmio_buffer_.Read16(0x104));
mmio_buffer_.Write8(0x44, 0x106);
EXPECT_EQ(0x45u, mmio_buffer_.Read64(0x108));
}
} // namespace
} // namespace mock_mmio