blob: 5c0e2f345dd4ffc5744f23fbcb4d0d9053f39820 [file] [log] [blame]
// Copyright 2019 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 "ddk/phys-iter.h"
#include <utility>
#include <fbl/algorithm.h>
#include <unittest/unittest.h>
namespace {
bool EmptyIteratorTest() {
BEGIN_TEST;
ddk::PhysIter phys_iter(phys_iter_buffer_t{}, 0);
EXPECT_TRUE(phys_iter.begin() == phys_iter.end());
END_TEST;
}
bool SimpleIterationTest() {
BEGIN_TEST;
constexpr zx_paddr_t kPhysList[] = {
2 * ZX_PAGE_SIZE,
};
const phys_iter_buffer_t kIterBuffer = {
.phys = kPhysList,
.phys_count = fbl::count_of(kPhysList),
.length = ZX_PAGE_SIZE,
.vmo_offset = 0,
.sg_list = nullptr,
.sg_count = 0,
};
ddk::PhysIter phys_iter(kIterBuffer, 0);
auto iter = phys_iter.begin();
const auto end = phys_iter.end();
EXPECT_TRUE(iter != end);
auto [paddr, size] = *iter;
EXPECT_EQ(paddr, 2 * ZX_PAGE_SIZE);
EXPECT_EQ(size, ZX_PAGE_SIZE);
++iter;
EXPECT_TRUE(iter == end);
size_t count = 0;
for (auto [paddr, size] : phys_iter) {
++count;
EXPECT_EQ(paddr, 2 * ZX_PAGE_SIZE);
EXPECT_EQ(size, ZX_PAGE_SIZE);
}
EXPECT_EQ(count, 1);
END_TEST;
}
bool ContiguousTest() {
BEGIN_TEST;
constexpr zx_paddr_t kPhysList[] = {
0 * ZX_PAGE_SIZE,
1 * ZX_PAGE_SIZE,
2 * ZX_PAGE_SIZE,
3 * ZX_PAGE_SIZE,
};
const phys_iter_buffer_t kIterBuffer = {
.phys = kPhysList,
.phys_count = fbl::count_of(kPhysList),
.length = 4 * ZX_PAGE_SIZE,
.vmo_offset = 0,
.sg_list = nullptr,
.sg_count = 0,
};
ddk::PhysIter phys_iter(kIterBuffer, 0);
auto iter = phys_iter.begin();
const auto end = phys_iter.end();
EXPECT_TRUE(iter != end);
auto [paddr, size] = *iter;
EXPECT_EQ(paddr, 0);
EXPECT_EQ(size, 4 * ZX_PAGE_SIZE);
++iter;
EXPECT_TRUE(iter == end);
END_TEST;
}
bool DiscontiguousTest() {
BEGIN_TEST;
constexpr zx_paddr_t kPhysList[] = {
1 * ZX_PAGE_SIZE,
3 * ZX_PAGE_SIZE,
4 * ZX_PAGE_SIZE,
7 * ZX_PAGE_SIZE,
};
const phys_iter_buffer_t kIterBuffer = {
.phys = kPhysList,
.phys_count = fbl::count_of(kPhysList),
.length = 4 * ZX_PAGE_SIZE,
.vmo_offset = 0,
.sg_list = nullptr,
.sg_count = 0,
};
ddk::PhysIter phys_iter(kIterBuffer, 0);
auto iter = phys_iter.begin();
const auto end = phys_iter.end();
{
EXPECT_TRUE(iter != end);
auto [paddr, size] = *iter;
EXPECT_EQ(paddr, ZX_PAGE_SIZE);
EXPECT_EQ(size, ZX_PAGE_SIZE);
}
{
++iter;
EXPECT_TRUE(iter != end);
auto [paddr, size] = *iter;
EXPECT_EQ(paddr, 3 * ZX_PAGE_SIZE);
EXPECT_EQ(size, 2 * ZX_PAGE_SIZE);
}
{
++iter;
EXPECT_TRUE(iter != end);
auto [paddr, size] = *iter;
EXPECT_EQ(paddr, 7 * ZX_PAGE_SIZE);
EXPECT_EQ(size, ZX_PAGE_SIZE);
}
++iter;
EXPECT_TRUE(iter == end);
END_TEST;
}
bool UnalignedTest() {
BEGIN_TEST;
constexpr zx_paddr_t kPhysList[] = {
2 * ZX_PAGE_SIZE,
4 * ZX_PAGE_SIZE,
};
const phys_iter_buffer_t kIterBuffer = {
.phys = kPhysList,
.phys_count = fbl::count_of(kPhysList),
.length = 2 * ZX_PAGE_SIZE - 7,
.vmo_offset = 7,
.sg_list = nullptr,
.sg_count = 0,
};
ddk::PhysIter phys_iter(kIterBuffer, 0);
auto iter = phys_iter.begin();
const auto end = phys_iter.end();
{
EXPECT_TRUE(iter != end);
auto [paddr, size] = *iter;
EXPECT_EQ(paddr, 2 * ZX_PAGE_SIZE + 7);
EXPECT_EQ(size, ZX_PAGE_SIZE - 7);
}
{
++iter;
EXPECT_TRUE(iter != end);
auto [paddr, size] = *iter;
EXPECT_EQ(paddr, 4 * ZX_PAGE_SIZE);
EXPECT_EQ(size, ZX_PAGE_SIZE);
}
++iter;
EXPECT_TRUE(iter == end);
END_TEST;
}
bool ScatterGatherTest() {
BEGIN_TEST;
constexpr zx_paddr_t kPhysList[] = {
1 * ZX_PAGE_SIZE,
3 * ZX_PAGE_SIZE,
4 * ZX_PAGE_SIZE,
7 * ZX_PAGE_SIZE,
};
constexpr phys_iter_sg_entry_t kScatterGatherList[] = {
{10, 1024},
// Cross contiguous pages.
{2 * ZX_PAGE_SIZE, ZX_PAGE_SIZE},
// Cross contiguous pages with offset and non-page size.
{ZX_PAGE_SIZE + 10, ZX_PAGE_SIZE + 10},
// Cross nont-contiguous pages and overflow over end.
{2 * ZX_PAGE_SIZE, 2 * ZX_PAGE_SIZE + 15},
};
const phys_iter_buffer_t kIterBuffer = {
.phys = kPhysList,
.phys_count = fbl::count_of(kPhysList),
.length = 0,
.vmo_offset = 0,
.sg_list = kScatterGatherList,
.sg_count = fbl::count_of(kScatterGatherList),
};
ddk::PhysIter phys_iter(kIterBuffer, 0);
auto iter = phys_iter.begin();
const auto end = phys_iter.end();
{
EXPECT_TRUE(iter != end);
auto [paddr, size] = *iter;
EXPECT_EQ(paddr, ZX_PAGE_SIZE + 1024);
EXPECT_EQ(size, 10);
}
{
++iter;
EXPECT_TRUE(iter != end);
auto [paddr, size] = *iter;
EXPECT_EQ(paddr, 3 * ZX_PAGE_SIZE);
EXPECT_EQ(size, 2 * ZX_PAGE_SIZE);
}
{
++iter;
EXPECT_TRUE(iter != end);
auto [paddr, size] = *iter;
EXPECT_EQ(paddr, 3 * ZX_PAGE_SIZE + 10);
EXPECT_EQ(size, ZX_PAGE_SIZE + 10);
}
{
++iter;
EXPECT_TRUE(iter != end);
auto [paddr, size] = *iter;
EXPECT_EQ(paddr, 4 * ZX_PAGE_SIZE + 15);
EXPECT_EQ(size, ZX_PAGE_SIZE - 15);
}
{
++iter;
EXPECT_TRUE(iter != end);
auto [paddr, size] = *iter;
EXPECT_EQ(paddr, 7 * ZX_PAGE_SIZE);
EXPECT_EQ(size, ZX_PAGE_SIZE);
}
++iter;
EXPECT_TRUE(iter == end);
END_TEST;
}
} // namespace
BEGIN_TEST_CASE(PhyIterTests)
RUN_TEST_SMALL(EmptyIteratorTest)
RUN_TEST_SMALL(SimpleIterationTest)
RUN_TEST_SMALL(ContiguousTest)
RUN_TEST_SMALL(DiscontiguousTest)
RUN_TEST_SMALL(UnalignedTest)
RUN_TEST_SMALL(ScatterGatherTest)
END_TEST_CASE(PhyIterTests)