blob: cb9d794131c847af3b1397bbb9a4ab3f8a69b574 [file] [edit]
// 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 "platform/pc/acpi.h"
#include <align.h>
#include <lib/acpi_lite.h>
#include <lib/acpi_lite/structures.h>
#include <lib/acpi_lite/zircon.h>
#include <lib/console.h>
#include <lib/fit/defer.h>
#include <lib/lazy_init/lazy_init.h>
#include <lib/zx/result.h>
#include <trace.h>
#include <zircon/types.h>
#include <arch/x86/acpi.h>
#include <arch/x86/bootstrap16.h>
#include <kernel/percpu.h>
#include <ktl/optional.h>
#include <lk/init.h>
#include <phys/handoff.h>
#include <ktl/enforce.h>
extern "C" {
zx_status_t rust_acpi_parser_init(zx_paddr_t rsdp_pa, void* out_parser);
void rust_acpi_parser_dump_tables(const void* parser);
size_t rust_acpi_parser_num_tables(const void* parser);
const acpi_lite::AcpiSdtHeader* rust_acpi_parser_get_table_at_index(const void* parser,
size_t index);
const void* cpp_global_acpi_parser_state();
}
namespace {
// System-wide ACPI parser.
AcpiLiteParser* global_acpi_parser;
lazy_init::LazyInit<AcpiLiteParser, lazy_init::CheckType::None, lazy_init::Destructor::Disabled>
g_parser;
int ConsoleAcpiDump(int argc, const cmd_args* argv, uint32_t flags) {
if (global_acpi_parser == nullptr) {
printf("ACPI not initialized.\n");
return 1;
}
global_acpi_parser->DumpTables();
return 0;
}
} // namespace
AcpiLiteParser& GlobalAcpiLiteParser() {
ASSERT_MSG(global_acpi_parser != nullptr, "PlatformInitAcpi() not called.");
return *global_acpi_parser;
}
extern "C" const void* cpp_global_acpi_parser_state() {
assert(global_acpi_parser);
return &global_acpi_parser->state();
}
void PlatformInitAcpi(zx_paddr_t acpi_rsdp) {
ASSERT(global_acpi_parser == nullptr);
// Create AcpiParser.
RustAcpiLite parser;
zx_status_t status = rust_acpi_parser_init(acpi_rsdp, &parser);
if (status != ZX_OK) {
panic("Could not initialize ACPI. Error code: %d.", status);
}
g_parser.Initialize(parser);
global_acpi_parser = &g_parser.Get();
}
static void platform_init_acpi(uint level) {
PlatformInitAcpi(gPhysHandoff->acpi_rsdp.value_or(0));
}
void AcpiLiteParser::DumpTables() { rust_acpi_parser_dump_tables(&state_); }
size_t AcpiLiteParser::num_tables() const { return rust_acpi_parser_num_tables(&state_); }
const acpi_lite::AcpiSdtHeader* AcpiLiteParser::GetTableAtIndex(size_t index) const {
return rust_acpi_parser_get_table_at_index(&state_, index);
}
LK_INIT_HOOK(platform_init_acpi, platform_init_acpi, LK_INIT_LEVEL_VM)
STATIC_COMMAND_START
STATIC_COMMAND("acpidump", "dump ACPI tables to console", &ConsoleAcpiDump)
STATIC_COMMAND_END(acpi)