blob: e848a7b2f17a60729e2300f3a73d26339c511963 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <lib/arch/testing/x86/fake-cpuid.h>
#include <lib/arch/x86/cpuid.h>
#include <zxtest/zxtest.h>
namespace {
TEST(FakeCpuidIoTests, Get) {
arch::testing::FakeCpuidIo cpuid;
cpuid.Populate(0x0, 0x0, arch::CpuidIo::kEax, 0x0000'0014)
.Populate(0x0, 0x0, arch::CpuidIo::kEbx, 0x756e'6547)
.Populate(0x0, 0x0, arch::CpuidIo::kEcx, 0x6c65'746e)
.Populate(0x0, 0x0, arch::CpuidIo::kEdx, 0x4965'6e69)
.Populate(0x1, 0x0, arch::CpuidIo::kEcx, 0x7ffe'fbff)
.Populate(0x1, 0x0, arch::CpuidIo::kEdx, 0xbfeb'fbff);
// Access by various types corresponding to leaf 0x0 should all yield the
// same CpuidIo* - and its values should coincide with those provided above.
auto* io0A = cpuid.Get<arch::CpuidMaximumLeaf>();
auto* io0B = cpuid.Get<arch::CpuidVendorB>();
auto* io0C = cpuid.Get<arch::CpuidVendorC>();
auto* io0D = cpuid.Get<arch::CpuidVendorD>();
EXPECT_EQ(io0A, io0B);
EXPECT_EQ(io0A, io0C);
EXPECT_EQ(io0A, io0D);
auto* io0 = io0A;
ASSERT_NOT_NULL(io0);
EXPECT_EQ(0x0000'0014, io0->values_[arch::CpuidIo::kEax]);
EXPECT_EQ(0x756e'6547, io0->values_[arch::CpuidIo::kEbx]);
EXPECT_EQ(0x6c65'746e, io0->values_[arch::CpuidIo::kEcx]);
EXPECT_EQ(0x4965'6e69, io0->values_[arch::CpuidIo::kEdx]);
// Ditto for leaf 0x1.
auto* io1C = cpuid.Get<arch::CpuidFeatureFlagsC>();
auto* io1D = cpuid.Get<arch::CpuidFeatureFlagsD>();
EXPECT_EQ(io1C, io1D);
auto* io1 = io1C;
ASSERT_NOT_NULL(io1);
EXPECT_EQ(0, io1->values_[arch::CpuidIo::kEax]); // Unpopulated.
EXPECT_EQ(0, io1->values_[arch::CpuidIo::kEbx]); // Unpopulated.
EXPECT_EQ(0x7ffe'fbff, io1->values_[arch::CpuidIo::kEcx]);
EXPECT_EQ(0xbfeb'fbff, io1->values_[arch::CpuidIo::kEdx]);
}
TEST(FakeCpuidIoTests, Read) {
arch::testing::FakeCpuidIo cpuid;
cpuid.Populate(0x0, 0x0, arch::CpuidIo::kEax, 0x0000'0014);
auto* io = cpuid.Get<arch::CpuidMaximumLeaf>();
ASSERT_NOT_NULL(io);
// Read should be a shortcut to reading our the value type.
EXPECT_EQ(0x0000'0014, io->values_[arch::CpuidIo::kEax]);
EXPECT_EQ(0x0000'0014, cpuid.Read<arch::CpuidMaximumLeaf>().leaf());
}
TEST(FakeCpuidIoTests, PopulateOverwrites) {
arch::testing::FakeCpuidIo cpuid;
cpuid.Populate(0x0, 0x0, arch::CpuidIo::kEax, 0x0000'0014);
auto* io = cpuid.Get<arch::CpuidMaximumLeaf>();
ASSERT_NOT_NULL(io);
EXPECT_EQ(0x0000'0014, io->values_[arch::CpuidIo::kEax]);
cpuid.Populate(0x0, 0x0, arch::CpuidIo::kEax, 0x0000'0020);
EXPECT_EQ(0x0000'0020, io->values_[arch::CpuidIo::kEax]);
}
} // namespace