I'm a tabs guy. I like tabs, it's an elegant way to represent indentation instead of brute-forcing it. But I have to admit that the world seems to be going towards spaces, and tooling tends not to play nice with tabs. So here we go, changing the whole repo to spaces since I'm getting tired of all the inconsistent formatting.
212 lines
4.4 KiB
C++
212 lines
4.4 KiB
C++
#pragma once
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include "enum_bitfields.h"
|
|
#include "kutil/coord.h"
|
|
#include "kutil/misc.h"
|
|
|
|
struct acpi_table_header
|
|
{
|
|
uint32_t type;
|
|
uint32_t length;
|
|
uint8_t revision;
|
|
uint8_t checksum;
|
|
char oem_id[6];
|
|
char oem_table[8];
|
|
uint32_t oem_revision;
|
|
uint32_t creator_id;
|
|
uint32_t creator_revision;
|
|
|
|
bool validate(uint32_t expected_type = 0) const;
|
|
} __attribute__ ((packed));
|
|
|
|
#define TABLE_HEADER(signature) \
|
|
static constexpr uint32_t type_id = kutil::byteswap(signature); \
|
|
acpi_table_header header;
|
|
|
|
|
|
template <typename T>
|
|
bool acpi_validate(const T *t) { return t->header.validate(T::type_id); }
|
|
|
|
template <typename T>
|
|
size_t acpi_table_entries(const T *t, size_t size)
|
|
{
|
|
return (t->header.length - sizeof(T)) / size;
|
|
}
|
|
|
|
enum class acpi_gas_type : uint8_t
|
|
{
|
|
system_memory,
|
|
system_io,
|
|
pci_config,
|
|
embedded,
|
|
smbus,
|
|
platform_channel = 0x0a,
|
|
functional_fixed = 0x7f
|
|
};
|
|
|
|
struct acpi_gas
|
|
{
|
|
acpi_gas_type type;
|
|
|
|
uint8_t reg_bits;
|
|
uint8_t reg_offset;
|
|
uint8_t access_size;
|
|
|
|
uint64_t address;
|
|
} __attribute__ ((packed));
|
|
|
|
|
|
enum class acpi_fadt_flags : uint32_t
|
|
{
|
|
wbinvd = 0x00000001,
|
|
wbinvd_flush = 0x00000002,
|
|
proc_c1 = 0x00000004,
|
|
p_lvl2_up = 0x00000008,
|
|
pwr_button = 0x00000010,
|
|
slp_button = 0x00000020,
|
|
fix_rtc = 0x00000040,
|
|
rtc_s4 = 0x00000080,
|
|
tmr_val_ext = 0x00000100,
|
|
dck_cap = 0x00000200,
|
|
reset_reg_sup = 0x00000400,
|
|
sealed_case = 0x00000800,
|
|
headless = 0x00001000,
|
|
cpu_sw_slp = 0x00002000,
|
|
pci_exp_wak = 0x00004000,
|
|
use_plat_clock = 0x00008000,
|
|
s4_rtc_sts_val = 0x00010000,
|
|
remote_pwr_cap = 0x00020000,
|
|
apic_cluster = 0x00040000,
|
|
apic_physical = 0x00080000,
|
|
hw_reduced_acpi = 0x00100000,
|
|
low_pwr_s0_idle = 0x00200000
|
|
};
|
|
is_bitfield(acpi_fadt_flags);
|
|
|
|
struct acpi_fadt
|
|
{
|
|
TABLE_HEADER('FACP');
|
|
|
|
uint32_t facs;
|
|
uint32_t dsdt;
|
|
|
|
uint8_t reserved0;
|
|
|
|
uint8_t preferred_pm_profile;
|
|
|
|
uint16_t sci_interrupt;
|
|
uint32_t smi_port;
|
|
uint8_t acpi_enable;
|
|
uint8_t acpi_disable;
|
|
uint8_t s4bios_req;
|
|
uint8_t pstate_control;
|
|
uint32_t pm1a_event_block;
|
|
uint32_t pm1b_event_block;
|
|
uint32_t pm1a_control_block;
|
|
uint32_t pm1b_control_block;
|
|
uint32_t pm2_control_block;
|
|
uint32_t pm_timer_block;
|
|
uint32_t gpe0_block;
|
|
uint32_t gpe1_block;
|
|
uint8_t pm1_event_length;
|
|
uint8_t pm1_control_length;
|
|
uint8_t pm2_control_length;
|
|
uint8_t pm_timer_length;
|
|
uint8_t gpe0_block_length;
|
|
uint8_t gpe1_block_length;
|
|
uint8_t gpe1_base;
|
|
uint8_t cstate_control;
|
|
uint16_t cstate2_latency;
|
|
uint16_t cstate3_latency;
|
|
uint16_t flush_size;
|
|
uint16_t flush_stride;
|
|
uint8_t duty_offset;
|
|
uint8_t duty_width;
|
|
uint8_t day_alarm;
|
|
uint8_t month_alarm;
|
|
uint8_t century;
|
|
|
|
uint16_t iapc_boot_arch;
|
|
uint8_t reserved1;
|
|
acpi_fadt_flags flags;
|
|
|
|
acpi_gas reset_reg;
|
|
uint8_t reset_value;
|
|
|
|
uint16_t arm_boot_arch;
|
|
|
|
uint8_t fadt_minor_version;
|
|
|
|
uint64_t x_facs;
|
|
uint64_t x_dsdt;
|
|
|
|
acpi_gas x_pm1a_event_block;
|
|
acpi_gas x_pm1b_event_block;
|
|
acpi_gas x_pm1a_control_block;
|
|
acpi_gas x_pm1b_control_block;
|
|
acpi_gas x_pm2_control_block;
|
|
acpi_gas x_pm_timer_block;
|
|
acpi_gas x_gpe0_block;
|
|
acpi_gas x_gpe1_block;
|
|
|
|
acpi_gas sleep_control_reg;
|
|
acpi_gas sleep_status_reg;
|
|
|
|
uint64_t hypervisor_vendor_id;
|
|
} __attribute__ ((packed));
|
|
|
|
struct acpi_xsdt
|
|
{
|
|
TABLE_HEADER('XSDT');
|
|
acpi_table_header *headers[0];
|
|
} __attribute__ ((packed));
|
|
|
|
struct acpi_apic
|
|
{
|
|
TABLE_HEADER('APIC');
|
|
uint32_t local_address;
|
|
uint32_t flags;
|
|
uint8_t controller_data[0];
|
|
} __attribute__ ((packed));
|
|
|
|
struct acpi_mcfg_entry
|
|
{
|
|
uint64_t base;
|
|
uint16_t group;
|
|
uint8_t bus_start;
|
|
uint8_t bus_end;
|
|
uint32_t reserved;
|
|
} __attribute__ ((packed));
|
|
|
|
struct acpi_mcfg
|
|
{
|
|
TABLE_HEADER('MCFG');
|
|
uint64_t reserved;
|
|
acpi_mcfg_entry entries[0];
|
|
} __attribute__ ((packed));
|
|
|
|
struct acpi_hpet
|
|
{
|
|
TABLE_HEADER('HPET');
|
|
uint32_t hardware_id;
|
|
acpi_gas base_address;
|
|
uint8_t index;
|
|
uint16_t periodic_min;
|
|
uint8_t attributes;
|
|
} __attribute__ ((packed));
|
|
|
|
struct acpi_bgrt
|
|
{
|
|
TABLE_HEADER('BGRT');
|
|
uint16_t version;
|
|
uint8_t status;
|
|
uint8_t type;
|
|
uintptr_t address;
|
|
uint32_t offset_x;
|
|
uint32_t offset_y;
|
|
} __attribute__ ((packed));
|
|
|