blob: c7867dd646857186749743abbb89c570476e9db5 [file] [log] [blame]
// Copyright 2018 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
#pragma once
#include <fbl/function.h>
#include <stdint.h>
#include <zircon/types.h>
// ACPI structures
struct acpi_rsdp {
uint8_t sig[8];
uint8_t checksum;
uint8_t oemid[6];
uint8_t revision;
uint32_t rsdt_address;
// rev 2+
uint32_t length;
uint64_t xsdt_address;
uint8_t extended_checksum;
uint8_t reserved[3];
} __PACKED;
#define ACPI_RSDP_SIG "RSD PTR "
// standard system description table header
struct acpi_sdt_header {
uint8_t sig[4];
uint32_t length;
uint8_t revision;
uint8_t checksum;
uint8_t oemid[6];
uint8_t oem_table_id[8];
uint32_t oem_revision;
uint32_t creator_id;
uint32_t creator_revision;
} __PACKED;
static_assert(sizeof(acpi_sdt_header) == 36, "");
struct acpi_rsdt_xsdt {
acpi_sdt_header header;
// array of uint32s or uint64 addresses are placed immediately afterwards
union {
uint32_t addr32[0];
uint64_t addr64[0];
};
} __PACKED;
struct acpi_generic_address_ {
uint8_t address_space_id;
uint8_t register_bit_width;
uint8_t register_bit_offset;
uint8_t access_size;
uint64_t address;
} __PACKED;
#define ACPI_ADDR_SPACE_MEMORY 0
#define ACPI_ADDR_SPACE_IO 1
#define ACPI_RSDT_SIG "RSDT"
#define ACPI_XSDT_SIG "XSDT"
struct acpi_madt_table {
acpi_sdt_header header;
uint32_t local_int_controller_address;
uint32_t flags;
} __PACKED;
#define ACPI_MADT_SIG "APIC"
struct acpi_sub_table_header {
uint8_t type;
uint8_t length;
} __PACKED;
#define ACPI_HPET_SIG "HPET"
struct acpi_hpet_table {
acpi_sdt_header header;
uint32_t id;
acpi_generic_address_ address;
uint8_t sequence;
uint16_t minimum_tick;
uint8_t flags;
} __PACKED;
zx_status_t acpi_lite_init(zx_paddr_t rsdt);
void acpi_lite_dump_tables();
const acpi_sdt_header *acpi_get_table_by_sig(const char *sig);
const acpi_sdt_header *acpi_get_table_at_index(size_t index);
// MADT table describes processors and interrupt controllers
// type 0: local apic
#define ACPI_MADT_TYPE_LOCAL_APIC 0
struct acpi_madt_local_apic_entry {
acpi_sub_table_header header;
uint8_t processor_id;
uint8_t apic_id;
uint32_t flags;
} __PACKED;
#define ACPI_MADT_FLAG_ENABLED 0x1
// type 1: io apic
#define ACPI_MADT_TYPE_IO_APIC 1
struct acpi_madt_io_apic_entry {
acpi_sub_table_header header;
uint8_t io_apic_id;
uint8_t reserved;
uint32_t io_apic_address;
uint32_t global_system_interrupt_base;
} __PACKED;
// type 2: interrupt source override
#define ACPI_MADT_TYPE_INT_SOURCE_OVERRIDE 2
struct acpi_madt_int_source_override_entry {
acpi_sub_table_header header;
uint8_t bus;
uint8_t source;
uint32_t global_sys_interrupt;
uint16_t flags;
} __PACKED;
#define ACPI_MADT_FLAG_POLARITY_CONFORMS 0b00
#define ACPI_MADT_FLAG_POLARITY_HIGH 0b01
#define ACPI_MADT_FLAG_POLARITY_LOW 0b11
#define ACPI_MADT_FLAG_POLARITY_MASK 0b11
#define ACPI_MADT_FLAG_TRIGGER_CONFORMS 0b0000
#define ACPI_MADT_FLAG_TRIGGER_EDGE 0b0100
#define ACPI_MADT_FLAG_TRIGGER_LEVEL 0b1100
#define ACPI_MADT_FLAG_TRIGGER_MASK 0b1100
// A routine to iterate over all the MADT entries of a particular type via a callback
using MadtEntryCallback = fbl::Function<void(const void* entry, size_t entry_len)>;
zx_status_t acpi_process_madt_entries_etc(const uint8_t search_type, const MadtEntryCallback&);