blob: a78d4ec4228aa90ed6a4394b524b28c35aca592f [file] [log] [blame]
// Copyright 2021 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/acpi_lite/testing/test_data.h>
#include <lib/boot-shim/acpi.h>
#include <lib/boot-shim/boot-shim.h>
#include <lib/boot-shim/test-helper.h>
#include <zxtest/zxtest.h>
namespace {
template <class Item, uint32_t Type, class Parser, typename T>
void AcpiTest(const Parser* parser, const T& expected_payload) {
using TestShim = boot_shim::BootShim<Item>;
boot_shim::testing::TestHelper test;
TestShim shim(__func__, test.log());
if (parser) {
shim.template Get<Item>().Init(*parser);
}
auto [buffer, owner] = test.GetZbiBuffer();
typename TestShim::DataZbi zbi(buffer);
ASSERT_TRUE(zbi.clear().is_ok());
auto result = shim.AppendItems(zbi);
ASSERT_TRUE(result.is_ok());
size_t found_payload_count = 0;
zbitl::ByteView found_payload;
for (auto [header, payload] : zbi) {
if (header->type == Type) {
++found_payload_count;
found_payload = payload;
}
}
EXPECT_TRUE(zbi.take_error().is_ok());
if constexpr (std::is_same_v<T, std::monostate>) {
EXPECT_EQ(0, found_payload_count);
} else {
EXPECT_EQ(1, found_payload_count);
EXPECT_EQ(found_payload.size(), sizeof(expected_payload));
EXPECT_BYTES_EQ(found_payload.data(), &expected_payload, sizeof(expected_payload));
}
}
template <typename T>
void AcpiUartTest(const acpi_lite::AcpiParserInterface* parser, const T& expected_uart) {
AcpiTest<boot_shim::AcpiUartItem, ZBI_TYPE_KERNEL_DRIVER>(parser, expected_uart);
}
TEST(BootShimTests, AcpiUartNone) {
ASSERT_NO_FATAL_FAILURE(AcpiUartTest(nullptr, std::monostate{}));
}
TEST(BootShimTests, AcpiUartAtlas) {
constexpr dcfg_simple_t kAtlasUart = {.mmio_phys = 0xfe03'4000};
auto parser = acpi_lite::testing::PixelbookAtlasAcpiParser();
ASSERT_NO_FATAL_FAILURE(AcpiUartTest(&parser, kAtlasUart));
}
TEST(BootShimTests, AcpiUartNuc) {
constexpr dcfg_simple_pio_t kNucUart = {.base = 0x3f8};
auto reader = acpi_lite::testing::IntelNuc7i5dnPhysMemReader();
auto result = acpi_lite::AcpiParser::Init(reader, reader.rsdp());
ASSERT_TRUE(result.is_ok());
auto& parser = result.value();
ASSERT_NO_FATAL_FAILURE(AcpiUartTest(&parser, kNucUart));
}
void AcpiRsdpTest(acpi_lite::testing::FakePhysMemReader mem_reader, uint64_t expected_rsdp) {
auto result = acpi_lite::AcpiParser::Init(mem_reader, mem_reader.rsdp());
ASSERT_TRUE(result.is_ok());
auto& parser = result.value();
AcpiTest<boot_shim::AcpiRsdpItem, ZBI_TYPE_ACPI_RSDP>(&parser, expected_rsdp);
}
TEST(BootShimTests, AcpiRsdpNone) {
acpi_lite::AcpiParser* parser = nullptr;
AcpiTest<boot_shim::AcpiRsdpItem, ZBI_TYPE_ACPI_RSDP>(parser, std::monostate{});
}
TEST(BootShimTests, AcpiRsdpQemu) {
ASSERT_NO_FATAL_FAILURE(AcpiRsdpTest(acpi_lite::testing::QemuPhysMemReader(), 0xf'5860));
}
TEST(BootShimTests, AcpiRsdpFuchsiaHypervisor) {
ASSERT_NO_FATAL_FAILURE(
AcpiRsdpTest(acpi_lite::testing::FuchsiaHypervisorPhysMemReader(), 0xe'0000));
}
TEST(BootShimTests, AcpiRsdpNuc) {
ASSERT_NO_FATAL_FAILURE(
AcpiRsdpTest(acpi_lite::testing::IntelNuc7i5dnPhysMemReader(), 0x7fa2'9000));
}
} // namespace