blob: 795546852c555a16f98b29a85d6bff0e2a8329ed [file] [log] [blame]
// 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 "nandpart-utils.h"
#include <zircon/types.h>
#include <memory>
#include <zxtest/zxtest.h>
namespace nand {
namespace {
constexpr uint32_t kPageSize = ZX_PAGE_SIZE;
constexpr uint32_t kPagesPerBlock = 2;
constexpr uint32_t kNumBlocks = 5;
constexpr uint32_t kOobSize = 8;
constexpr fuchsia_hardware_nand_Info kNandInfo = {
.page_size = kPageSize,
.pages_per_block = kPagesPerBlock,
.num_blocks = kNumBlocks,
.ecc_bits = 2,
.oob_size = kOobSize,
.nand_class = fuchsia_hardware_nand_Class_BBS,
.partition_guid = {},
};
zbi_partition_map_t MakePartitionMap(uint32_t partition_count) {
return zbi_partition_map_t{
.block_count = kNumBlocks * kPagesPerBlock,
.block_size = kPageSize,
.partition_count = partition_count,
.reserved = 0,
.guid = {},
};
}
zbi_partition_t MakePartition(uint32_t first_block, uint32_t last_block) {
return zbi_partition_t{
.type_guid = {},
.uniq_guid = {},
.first_block = first_block,
.last_block = last_block,
.flags = 0,
.name = {},
};
}
void ValidatePartition(zbi_partition_map_t* pmap, size_t partition_number, uint32_t first_block,
uint32_t last_block) {
EXPECT_EQ(pmap->partitions[partition_number].first_block, first_block);
EXPECT_EQ(pmap->partitions[partition_number].last_block, last_block);
}
TEST(NandPartUtilsTest, SanitizeEmptyPartitionMapTest) {
auto pmap = MakePartitionMap(0);
ASSERT_NE(SanitizePartitionMap(&pmap, kNandInfo), ZX_OK);
}
TEST(NandPartUtilsTest, SanitizeSinglePartitionMapTest) {
std::unique_ptr<uint8_t[]> pmap_buffer(
new uint8_t[sizeof(zbi_partition_map_t) + sizeof(zbi_partition_t)]);
auto* pmap = reinterpret_cast<zbi_partition_map_t*>(pmap_buffer.get());
*pmap = MakePartitionMap(1);
pmap->partitions[0] = MakePartition(0, 9);
ASSERT_OK(SanitizePartitionMap(pmap, kNandInfo));
ASSERT_NO_FATAL_FAILURES(ValidatePartition(pmap, 0, 0, 4));
}
TEST(NandPartUtilsTest, SanitizeMultiplePartitionMapTest) {
std::unique_ptr<uint8_t[]> pmap_buffer(
new uint8_t[sizeof(zbi_partition_map_t) + 3 * sizeof(zbi_partition_t)]);
auto* pmap = reinterpret_cast<zbi_partition_map_t*>(pmap_buffer.get());
*pmap = MakePartitionMap(3);
pmap->partitions[0] = MakePartition(0, 3);
pmap->partitions[1] = MakePartition(4, 7);
pmap->partitions[2] = MakePartition(8, 9);
ASSERT_OK(SanitizePartitionMap(pmap, kNandInfo));
ASSERT_NO_FATAL_FAILURES(ValidatePartition(pmap, 0, 0, 1));
ASSERT_NO_FATAL_FAILURES(ValidatePartition(pmap, 1, 2, 3));
ASSERT_NO_FATAL_FAILURES(ValidatePartition(pmap, 2, 4, 4));
}
TEST(NandPartUtilsTest, SanitizeMultiplePartitionMapOutOfOrderTest) {
std::unique_ptr<uint8_t[]> pmap_buffer(
new uint8_t[sizeof(zbi_partition_map_t) + 2 * sizeof(zbi_partition_t)]);
auto* pmap = reinterpret_cast<zbi_partition_map_t*>(pmap_buffer.get());
*pmap = MakePartitionMap(2);
pmap->partitions[0] = MakePartition(4, 9);
pmap->partitions[1] = MakePartition(0, 3);
ASSERT_OK(SanitizePartitionMap(pmap, kNandInfo));
ASSERT_NO_FATAL_FAILURES(ValidatePartition(pmap, 0, 0, 1));
ASSERT_NO_FATAL_FAILURES(ValidatePartition(pmap, 1, 2, 4));
}
TEST(NandPartUtilsTest, SanitizeMultiplePartitionMapOverlappingTest) {
std::unique_ptr<uint8_t[]> pmap_buffer(
new uint8_t[sizeof(zbi_partition_map_t) + 3 * sizeof(zbi_partition_t)]);
auto* pmap = reinterpret_cast<zbi_partition_map_t*>(pmap_buffer.get());
*pmap = MakePartitionMap(3);
pmap->partitions[0] = MakePartition(0, 3);
pmap->partitions[1] = MakePartition(8, 9);
pmap->partitions[2] = MakePartition(4, 8);
ASSERT_NE(SanitizePartitionMap(pmap, kNandInfo), ZX_OK);
}
TEST(NandPartUtilsTest, SanitizePartitionMapBadRangeTest) {
std::unique_ptr<uint8_t[]> pmap_buffer(
new uint8_t[sizeof(zbi_partition_map_t) + 2 * sizeof(zbi_partition_t)]);
auto* pmap = reinterpret_cast<zbi_partition_map_t*>(pmap_buffer.get());
*pmap = MakePartitionMap(2);
pmap->partitions[0] = MakePartition(1, 0);
pmap->partitions[1] = MakePartition(1, 9);
ASSERT_NE(SanitizePartitionMap(pmap, kNandInfo), ZX_OK);
}
TEST(NandPartUtilsTest, SanitizePartitionMapUnalignedTest) {
std::unique_ptr<uint8_t[]> pmap_buffer(
new uint8_t[sizeof(zbi_partition_map_t) + 2 * sizeof(zbi_partition_t)]);
auto* pmap = reinterpret_cast<zbi_partition_map_t*>(pmap_buffer.get());
*pmap = MakePartitionMap(2);
pmap->partitions[0] = MakePartition(0, 3);
pmap->partitions[1] = MakePartition(5, 8);
ASSERT_NE(SanitizePartitionMap(pmap, kNandInfo), ZX_OK);
}
TEST(NandPartUtilsTest, SanitizePartitionMapOutofBoundsTest) {
std::unique_ptr<uint8_t[]> pmap_buffer(
new uint8_t[sizeof(zbi_partition_map_t) + 2 * sizeof(zbi_partition_t)]);
auto* pmap = reinterpret_cast<zbi_partition_map_t*>(pmap_buffer.get());
*pmap = MakePartitionMap(2);
pmap->partitions[0] = MakePartition(0, 3);
pmap->partitions[1] = MakePartition(4, 11);
ASSERT_NE(SanitizePartitionMap(pmap, kNandInfo), ZX_OK);
}
} // namespace
} // namespace nand