/** * Copyright (C) 2026 andromeda * * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . **/ module acpi; alias Port = uint; excuse INVALID_DESCRIPTION_HEADER; enum DescriptionHeaderSignature { AEST, AGDI, APIC, APMT, ASPT, BDAT, BERT, BGRT, BOOT, CCEL, CEDT, CPEP, CSRT, DBGP, DBG2, DMAR, DRTM, DSDT, DTPR, ECDT, EINJ, ERST, ETDT, FACP, FACS, FPDT, GTDT, HEST, HPET, IBFT, IERS, IORT, IOVT, IRDT, IVRS, KEYP, LPIT, MCFG, MCHI, MHSP, MISC, MPAM, MPST, MSCT, MSDM, NBFT, NFIT, NHLT, PCCT, PHAT, PMTT, PPTT, PRMT, PSDT, RASF, RAS2, RGRT, RHCT, RIMT, RQSC, RSDT, SBST, SDEI, SDEV, SLIC, SLIT, SPCR, SPMI, SRAT, SSDT, STAO, SVKL, SWFT, TCPA, TPM2, UEFI, WAET, WDAT, WDDT, WDRT, WPBT, WSMT, XENV, XSDT, } enum PMprofile : char { UNSPECIFIED, DESKTOP, MOBILE, WORKSTATION, ENTERPRISE_SERVER, SOHO_SERVER, APPLIANCE_PC, PERFORMANCE_SERVER, TABLET, } enum APICStructureType : char { PROCESSOR_LOCAL_APIC, IO_APIC, INTERRUPT_SOURCE_OVERRIDE, NON_MASKABLE_INTERRUPT_SOURCE, LOCAL_APIC_NMI, LOCAL_APIC_ADDRESS_OVERRIDE, IO_SAPIC, LOCAL_SAPIC, PLATFORM_INTERRUPT_SOURCES, PROCESSOR_LOCAL_X2APIC, LOCAL_X2APIC_NMI, GIC_CPU_INTERFACE, GIC_DISTRIBUTOR, GIC_MSI_FRAME, GIC_REDISTRIBUTOR, GIC_INTERRUPT_TRANSLATION_SERVICE, MULTIPROCESSOR_WAKEUP, CORE_PIC, LEGACY_IO_PIC, HYPERTRANSPORT_PIC, EXTEND_IO_PIC, MSI_PIC, BRIDGE_IO_PIC, LOW_PIN_COUNT_PIC, RISCV_HART_LOCAL_INTERRUPT_CONTROLLER, RISCV_INCOMING_MSI_CONTROLLER, RISCV_ADVANCED_PLIC, RISCV_PLIC, } bitstruct IAPCBootArchFlags : ushort { bool legacy_devices : 0; bool x8042 : 1; bool vga_not_present : 2; bool msi_not_supported : 3; bool pcie_aspm_controls : 4; bool cmos_rtc_not_present : 5; } bitstruct ArmBootArchFlags : ushort { bool psci_compliant : 0; bool psci_use_hvc : 1; } bitstruct FADTFeatureFlags : uint { bool wbinvd : 0; bool wbinvd_flush : 1; bool proc_c1 : 2; bool p_lvl2_up : 3; bool pwr_button : 4; bool slp_button : 5; bool fix_rtc : 6; bool rtc_s4 : 7; bool timer_val_ext : 8; bool dck_cap : 9; bool reset_reg_sup : 10; bool sealed_case : 11; bool headless : 12; bool cpu_sw_slp : 13; bool pci_exp_wak : 14; bool use_platform_clock : 15; bool s4_rtc_sts_valid : 16; bool remote_power_on_capable : 17; bool force_apic_cluster_model : 18; bool force_apic_physical_destination_mode : 19; bool hw_reduced_acpi : 20; bool low_power_s0_idle_capable : 21; PersistentCpuCaches persistent_cpu_caches : 22 .. 23; } bitstruct MultipleAPICFlags : uint { bool pcat_compat : 0; } bitstruct BootGraphicsStatus : char { bool displayed : 0; BootGraphicsOrientation orientation : 1 .. 2; } bitstruct HPETEventTimerBlockId : uint { char hardware_rev_id : 0 .. 7; char timer_block_1_comparator_count : 8 .. 12; bool count_size_cap_counter_size : 13; bool legacy_replacement_irq_routing_capable : 15; ushort timer_block_1_pci_vendor_id : 16 .. 31; } bitstruct HPETPageProtectionAndOEM : char { HPETPageProtectionAttribute page_protection_attribute : 0 .. 3; } constset PersistentCpuCaches : char { NOT_REPORTED = 0b00, NOT_PERSISTENT = 0b01, PERSISTANT = 0b10, } constset AddressSpaceId : char { SYSTEM_MEMORY_SPACE = 0x00, SYSTEM_IO_SPACE = 0x01, PCI_CONFIGURATION_SPACE = 0x02, EMBEDDED_CONTROLLER = 0x03, SMBUS = 0x04, SYSTEM_CMOS = 0x05, PCI_BAR_TARGET = 0x06, IPMI = 0x07, GENERAL_PURPOSE_IO = 0x08, GENERIC_SERIAL_BUS = 0x09, PLATFORM_COMMUNICATIONS_CHANNEL = 0x0A, PLATFORM_RUNTIME_MECHANISM = 0x0B, FUNCTIONAL_FIXED_HARDWARE = 0x7F, } constset BootGraphicsType : char { BITMAP = 0x00, } constset BootGraphicsOrientation : char { NO_OFFSET = 0b00, OFFSET_90 = 0b01, OFFSET_180 = 0b10, OFFSET_270 = 0b11, } constset HPETPageProtectionAttribute : char { NO_GUARANTEE = 0x0, PROTECTED_4KB = 0x1, PROTECTED_64KB = 0x2, } $assert(RootSystemDescriptionPointer::size == 35); struct RootSystemDescriptionPointer @packed { char[8] signature; char checksum; char[6] oemid; char revision; uint rsdtAddress; uint length; ExtendedSystemDescriptionTable* xsdtAddress; char[3] _res; } $assert(GASAddress::size == 12); struct GASAddress @packed { AddressSpaceId id; char width; char offset; char size; ulong addr; } // APIC structures; everything starting with a APICStructureHeader $assert(APICStructureHeader::size == 2); struct APICStructureHeader @packed { APICStructureType type; char length; } // TODO implement a bunch of these structures struct APICStructureDUMMY @packed { inline APICStructureHeader header; } // description tables; everything starting with a DescriptionHeader $assert(DescriptionHeader::size == 36); struct DescriptionHeader @packed { char[4] signature; uint length; char revision; char checksum; char[6] oemid; char[8] oemTableId; uint oemRevision; uint creatorId; uint creatorRevision; } $assert(ExtendedSystemDescriptionTable::size == 36); struct ExtendedSystemDescriptionTable @packed { inline DescriptionHeader header; ulong[*] descriptionHeaders; } $assert(FixedACPIDescriptionTable::size == 276); struct FixedACPIDescriptionTable @packed { inline DescriptionHeader header; uint firmware_control; uint dsdt; char _res0; PMprofile preferred_pm_profile; ushort sci_int; Port smi_cmd; char acpi_enable; char acpi_disable; char s4bios_req; char pstate_cnt; Port pm1a_evt_blk; Port pm1b_evt_blk; Port pm1a_cnt_blk; Port pm1b_cnt_blk; Port pm2_cnt_blk; Port pm_tmr_blk; Port gpe0_blk; Port gpe1_blk; char pm1_evt_len; char pm1_cnt_len; char pm2_cnt_len; char pm_tmr_len; char gpe0_blk_len; char gpe1_blk_len; char gpe1_base; char cst_cnt; ushort p_lvl2_lat; ushort p_lvl3_lat; ushort flush_size; ushort flush_stride; char duty_offset; char duty_width; char day_alrm; char mon_alrm; char century; IAPCBootArchFlags iapc_boot_arch_flags; char _res1; FADTFeatureFlags flags; GASAddress reset_reg; char reset_value; ArmBootArchFlags arm_boot_arch; char minor_revision; ulong x_firmware_ctrl; ulong x_dsdt; GASAddress x_pm1a_evt_blk; GASAddress x_pm1b_evt_blk; GASAddress x_pm1a_cnt_blk; GASAddress x_pm1b_cnt_blk; GASAddress x_pm2_cnt_blk; GASAddress x_pm_tmr_blk; GASAddress x_gpe0_blk; GASAddress x_gpe1_blk; GASAddress sleep_control_reg; GASAddress sleep_status_reg; ulong hypervisor_vendor_id; } $assert(MultipleAPICDescriptionTable::size == 44); struct MultipleAPICDescriptionTable @packed { inline DescriptionHeader header; uint local_interrupt_controller_address; MultipleAPICFlags flags; APICStructureDUMMY[*] interrupt_controller_structures; } $assert(BootGraphicsResourceTable::size == 56); struct BootGraphicsResourceTable @packed { inline DescriptionHeader header; ushort version; BootGraphicsStatus status; BootGraphicsType type; ulong address; uint x_offset; uint y_offset; } $assert(HighPrecisionEventTimersDescriptionTable::size == 56); struct HighPrecisionEventTimersDescriptionTable @packed { inline DescriptionHeader header; HPETEventTimerBlockId event_timer_block_id; GASAddress address; char sequence_number; ushort main_counter_minimum_clock_tick_in_periodic_mode; HPETPageProtectionAndOEM page_protection_attribute_and_oem; }