blob: 440095faaac11399af75e3421ccafcd0efdbd485 [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/devices/block/drivers/nvme/queue.h"
#include <lib/ddk/binding_driver.h>
#include <lib/ddk/driver.h>
#include <lib/fake-bti/bti.h>
#include <zircon/syscalls.h>
#include <zxtest/zxtest.h>
namespace nvme {
constexpr uint32_t kQueueMagic = 0xabbacaba;
class QueueTest : public zxtest::Test {
public:
void SetUp() { ASSERT_OK(fake_bti_create(fake_bti_.reset_and_get_address())); }
protected:
zx::bti fake_bti_;
};
TEST_F(QueueTest, CappedToPageSize) {
auto queue = Queue::Create(fake_bti_.borrow(), /*queue_id=*/1, /*max_entries=*/100,
/*entry_size=*/zx_system_get_page_size());
ASSERT_OK(queue.status_value());
ASSERT_EQ(1, queue->entry_count());
}
TEST_F(QueueTest, WrapsAround) {
// Create a queue with two elements.
auto queue = Queue::Create(fake_bti_.borrow(), /*queue_id=*/1, /*max_entries=*/100,
/*entry_size=*/zx_system_get_page_size() / 2);
ASSERT_OK(queue.status_value());
// To start with, the next item in the queue should be the first item in the queue.
ASSERT_EQ(0, queue->NextIndex());
// Set the first item in the queue to |kQueueMagic| and move forward.
*static_cast<uint32_t*>(queue->Next()) = kQueueMagic;
// The next index in the queue should now be 1 (the second item).
ASSERT_EQ(1, queue->NextIndex());
// Set the second item in the queue to 0 and move forward.
*static_cast<uint32_t*>(queue->Next()) = 0;
// We should have wrapped around to the start of the queue.
ASSERT_EQ(0, queue->NextIndex());
// Check that the first item in the queue is still |kQueueMagic|.
ASSERT_EQ(*static_cast<uint32_t*>(queue->Next()), kQueueMagic);
}
TEST_F(QueueTest, CappedToMaxEntries) {
auto queue =
Queue::Create(fake_bti_.borrow(), /*queue_id=*/1, /*max_entries=*/100, /*entry_size=*/1);
ASSERT_OK(queue.status_value());
ASSERT_EQ(100, queue->entry_count());
}
TEST_F(QueueTest, PhysicalAddress) {
auto queue =
Queue::Create(fake_bti_.borrow(), /*queue_id=*/1, /*max_entries=*/100, /*entry_size=*/1);
ASSERT_OK(queue.status_value());
ASSERT_EQ(FAKE_BTI_PHYS_ADDR, queue->GetDeviceAddress());
}
} // namespace nvme
static zx_driver_ops_t stub_driver_ops = []() -> zx_driver_ops_t {
zx_driver_ops_t ops = {};
ops.version = DRIVER_OPS_VERSION;
return ops;
}();
ZIRCON_DRIVER(fake_driver, stub_driver_ops, "zircon", "0.1");