#pragma once #include #ifndef ACPI_INTERNAL #error "Do not include , only use " #endif struct acpi_header { uint32_t signature; uint32_t length; uint8_t revision; uint8_t checksum; uint8_t oem_id[6]; uint8_t oem_table_id[8]; uint32_t oem_revision; uint32_t creator_id; uint32_t creator_revision; } __attribute__((packed)); // root system descriptor pointer // ACPI 1.0 struct rsdp { uint8_t signature[8]; uint8_t checksum; uint8_t oemid[6]; uint8_t revision; uint32_t rsdt_addr; } __attribute__((packed)); // eXtended system descriptor pointer // ACPI 2.0 struct xsdp { char signature[8]; uint8_t checksum; char oemid[6]; uint8_t revision; uint32_t rsdt_addr; uint32_t length; uint64_t xsdt_addr; uint8_t extendeid_checksum; uint8_t reserved[3]; } __attribute__((packed)); // root system descriptor table // ACPI 1.0 struct rsdt { struct acpi_header h; uint32_t sdt_pointers[]; } __attribute__((packed)); // eXtended system descriptor table // ACPI 2.0 struct xsdt { struct acpi_header h; uint64_t sdt_pointers[]; } __attribute__((packed)); // generic address structure struct gas { uint8_t address_space; uint8_t bit_width; uint8_t bit_offset; uint8_t access_size; uint64_t address; }; // differentiated system description table struct dsdt { struct acpi_header h; char s5_addr[]; } __attribute__((packed)); struct apic { struct acpi_header h; // todo } __attribute__((packed)); struct hept { struct acpi_header h; // todo } __attribute__((packed)); struct waet { struct acpi_header h; // todo } __attribute__((packed)); // fixed acpi description table struct fadt { struct acpi_header h; uint32_t firmware_ctrl; uint32_t dsdt; // field used in ACPI 1.0; no longer in use, for compatibility only uint8_t reserved; uint8_t preferred_power_management_profile; uint16_t sci_interrupt; uint32_t smi_command_port; uint8_t acpi_enable; uint8_t acpi_disable; uint8_t s4bios_req; uint8_t pstate_control; uint32_t pm1_a_event_block; uint32_t pm1_b_event_block; uint32_t pm1_a_control_block; uint32_t pm1_b_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_length; uint8_t gpe1_length; uint8_t gpe1_base; uint8_t cstate_control; uint16_t worst_c2_latency; uint16_t worst_c3_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; // reserved in ACPI 1.0; used since ACPI 2.0+ uint16_t boot_architecture_flags; uint8_t reserved_2; uint32_t flags; // 12 byte structure; see below for details struct gas reset_reg; uint8_t reset_value; uint8_t reserved_3[3]; // 64bit pointers - Available on ACPI 2.0+ uint64_t x_firmware_control; uint64_t x_dsdt; struct gas x_pm1_a_event_block; struct gas x_pm1_b_event_block; struct gas x_pm1_a_control_block; struct gas x_pm1_b_control_block; struct gas x_pm2_control_block; struct gas x_pm_timer_block; struct gas x_gpe0_block; struct gas x_gpe1_block; } __attribute__((packed)); struct acpi_state { union { struct xsdt *xsdt; struct rsdt *rsdt; } sdt; struct fadt *fadt; struct dsdt *dsdt; struct apic *apic; struct hept *hept; struct waet *waet; uint8_t version; uint16_t SLP_TYPa; uint16_t SLP_TYPb; uint16_t SLP_EN; uint16_t SCI_EN; }; void acpi_sys_enable(struct acpi_state *state); int acpi_sys_shutdown(struct acpi_state *state);