blob: 95e356a0346dce76beebcada99f329702713886b [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 "performance_counters.h"
#include "address_manager.h"
#include "mock/mock_bus_mapper.h"
#include "mock/mock_mmio.h"
#include "gtest/gtest.h"
namespace {
class FakeOwner : public AddressManager::Owner {
public:
FakeOwner(magma::RegisterIo* regs) : register_io_(regs) {}
magma::RegisterIo* register_io() override { return register_io_; }
private:
magma::RegisterIo* register_io_;
};
class TestConnectionOwner : public MsdArmConnection::Owner {
public:
TestConnectionOwner(AddressManager* manager) : manager_(manager) {}
void ScheduleAtom(std::shared_ptr<MsdArmAtom> atom) override {}
void CancelAtoms(std::shared_ptr<MsdArmConnection> connection) override {}
AddressSpaceObserver* GetAddressSpaceObserver() override { return manager_; }
magma::PlatformBusMapper* GetBusMapper() override { return &bus_mapper_; }
private:
AddressManager* manager_;
MockBusMapper bus_mapper_;
};
class TestCounterOwner : public PerformanceCounters::Owner {
public:
TestCounterOwner(magma::RegisterIo* regs)
: register_io_(regs), address_manager_owner_(regs),
address_manager_(&address_manager_owner_, 2), connection_owner_(&address_manager_)
{
}
magma::RegisterIo* register_io() override { return register_io_; }
AddressManager* address_manager() override { return &address_manager_; }
MsdArmConnection::Owner* connection_owner() override { return &connection_owner_; }
private:
magma::RegisterIo* register_io_;
FakeOwner address_manager_owner_;
AddressManager address_manager_;
TestConnectionOwner connection_owner_;
};
} // namespace
class PerformanceCounterTest {
public:
static void TestStateChange()
{
auto mmio = std::make_unique<magma::RegisterIo>(MockMmio::Create(1024 * 1024));
TestCounterOwner owner(mmio.get());
PerformanceCounters perf_counters(&owner);
uint64_t duration_ms;
EXPECT_EQ(PerformanceCounters::PerformanceCounterState::kDisabled,
perf_counters.counter_state_);
EXPECT_FALSE(perf_counters.TriggerRead(false));
EXPECT_EQ(PerformanceCounters::PerformanceCounterState::kDisabled,
perf_counters.counter_state_);
perf_counters.ReadCompleted(&duration_ms);
EXPECT_EQ(PerformanceCounters::PerformanceCounterState::kDisabled,
perf_counters.counter_state_);
EXPECT_TRUE(perf_counters.Enable());
EXPECT_EQ(PerformanceCounters::PerformanceCounterState::kEnabled,
perf_counters.counter_state_);
perf_counters.ReadCompleted(&duration_ms);
EXPECT_EQ(PerformanceCounters::PerformanceCounterState::kEnabled,
perf_counters.counter_state_);
EXPECT_TRUE(perf_counters.TriggerRead(false));
EXPECT_EQ(PerformanceCounters::PerformanceCounterState::kTriggered,
perf_counters.counter_state_);
EXPECT_FALSE(perf_counters.Enable());
EXPECT_EQ(PerformanceCounters::PerformanceCounterState::kTriggered,
perf_counters.counter_state_);
perf_counters.ReadCompleted(&duration_ms);
EXPECT_EQ(PerformanceCounters::PerformanceCounterState::kDisabled,
perf_counters.counter_state_);
}
static void TestEnabled()
{
auto mmio = std::make_unique<magma::RegisterIo>(MockMmio::Create(1024 * 1024));
TestCounterOwner owner(mmio.get());
PerformanceCounters perf_counters(&owner);
uint64_t duration_ms;
EXPECT_EQ(nullptr, owner.address_manager()->GetMappingForSlot(0).get());
EXPECT_TRUE(perf_counters.Enable());
EXPECT_NE(nullptr, perf_counters.address_mapping_.get());
EXPECT_EQ(perf_counters.address_mapping_, owner.address_manager()->GetMappingForSlot(0));
EXPECT_TRUE(perf_counters.TriggerRead(false));
registers::PerformanceCounterBase::Get().FromValue(4096 + 1024).WriteTo(mmio.get());
auto result = perf_counters.ReadCompleted(&duration_ms);
EXPECT_EQ(1024u / 4u, result.size());
EXPECT_EQ(0u, result[0]);
EXPECT_EQ(0u, registers::PerformanceCounterConfig::Get().ReadFrom(mmio.get()).reg_value());
}
static void TestKeepEnabled()
{
auto mmio = std::make_unique<magma::RegisterIo>(MockMmio::Create(1024 * 1024));
TestCounterOwner owner(mmio.get());
PerformanceCounters perf_counters(&owner);
uint64_t duration_ms;
EXPECT_TRUE(perf_counters.Enable());
EXPECT_TRUE(perf_counters.TriggerRead(true));
registers::PerformanceCounterBase::Get().FromValue(4096 + 1024).WriteTo(mmio.get());
auto result = perf_counters.ReadCompleted(&duration_ms);
EXPECT_EQ(1u, registers::PerformanceCounterConfig::Get().ReadFrom(mmio.get()).mode().get());
EXPECT_EQ(4096u, registers::PerformanceCounterBase::Get().ReadFrom(mmio.get()).reg_value());
EXPECT_TRUE(perf_counters.TriggerRead(true));
}
};
TEST(PerfCounters, StateChange) { PerformanceCounterTest::TestStateChange(); }
TEST(PerfCounters, Enabled) { PerformanceCounterTest::TestEnabled(); }
TEST(PerfCounters, KeepEnabled) { PerformanceCounterTest::TestKeepEnabled(); }