Serenity Operating System
1/*
2 * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#pragma once
8
9#include <AK/Types.h>
10#include <Kernel/PhysicalAddress.h>
11
12namespace Kernel::ACPI {
13
14namespace FADTFlags {
15
16// https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#fixed-acpi-description-table-fixed-feature-flags
17enum class FeatureFlags : u32 {
18 WBINVD = 1 << 0,
19 WBINVD_FLUSH = 1 << 1,
20 PROC_C1 = 1 << 2,
21 P_LVL2_UP = 1 << 3,
22 PWR_BUTTON = 1 << 4,
23 SLP_BUTTON = 1 << 5,
24 FIX_RTC = 1 << 6,
25 RTC_s4 = 1 << 7,
26 TMR_VAL_EXT = 1 << 8,
27 DCK_CAP = 1 << 9,
28 RESET_REG_SUPPORTED = 1 << 10,
29 SEALED_CASE = 1 << 11,
30 HEADLESS = 1 << 12,
31 CPU_SW_SLP = 1 << 13,
32 PCI_EXP_WAK = 1 << 14,
33 USE_PLATFORM_CLOCK = 1 << 15,
34 S4_RTC_STS_VALID = 1 << 16,
35 REMOTE_POWER_ON_CAPABLE = 1 << 17,
36 FORCE_APIC_CLUSTER_MODEL = 1 << 18,
37 FORCE_APIC_PHYSICAL_DESTINATION_MODE = 1 << 19,
38 HW_REDUCED_ACPI = 1 << 20,
39 LOW_POWER_S0_IDLE_CAPABLE = 1 << 21
40};
41
42// https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#fixed-acpi-description-table-boot-ia-pc-boot-architecture-flags
43enum class IA_PC_Flags : u8 {
44 Legacy_Devices = 1 << 0,
45 PS2_8042 = 1 << 1,
46 VGA_Not_Present = 1 << 2,
47 MSI_Not_Supported = 1 << 3,
48 PCIe_ASPM_Controls = 1 << 4,
49 CMOS_RTC_Not_Present = 1 << 5
50};
51
52struct [[gnu::packed]] HardwareFeatures {
53 bool wbinvd : 1;
54 bool wbinvd_flush : 1;
55 bool processor_c1 : 1;
56 bool multiprocessor_c2 : 1;
57 bool power_button : 1;
58 bool sleep_button : 1;
59 bool fix_rtc : 1;
60 bool rtc_s4 : 1;
61 bool timer_value_extension : 1;
62 bool docking_capability : 1;
63 bool reset_register_supported : 1;
64 bool sealed_case : 1;
65 bool headless : 1;
66 bool cpu_software_sleep : 1;
67 bool pci_express_wake : 1;
68 bool use_platform_clock : 1;
69 bool s4_rtc_status_valid : 1;
70 bool remote_power_on_capable : 1;
71 bool force_apic_cluster_model : 1;
72 bool force_apic_physical_destination_mode : 1;
73 bool hardware_reduced_acpi : 1;
74 bool low_power_s0_idle_capable : 1;
75};
76struct [[gnu::packed]] x86_Specific_Flags {
77 bool legacy_devices : 1;
78 bool keyboard_8042 : 1;
79 bool vga_not_present : 1;
80 bool msi_not_supported : 1;
81 bool cmos_rtc_not_present : 1;
82};
83};
84
85namespace GenericAddressStructure {
86enum class AddressSpace {
87 SystemMemory = 0,
88 SystemIO = 1,
89 PCIConfigurationSpace = 2,
90 EmbeddedController = 3,
91 SMBus = 4,
92 PCC = 0xA,
93 FunctionalFixedHardware = 0x7F
94};
95enum class AccessSize {
96 Undefined = 0,
97 Byte = 1,
98 Word = 2,
99 DWord = 3,
100 QWord = 4
101};
102enum class BitWidth {
103 Undefined = 0,
104 Byte = 8,
105 Word = 16,
106 DWord = 32,
107 QWord = 64
108};
109}
110
111namespace Structures {
112
113// https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#root-system-description-pointer-rsdp-structure
114struct [[gnu::packed]] RSDPDescriptor {
115 char sig[8];
116 u8 checksum;
117 char oem_id[6];
118 u8 revision;
119 u32 rsdt_ptr;
120};
121
122struct [[gnu::packed]] RSDPDescriptor20 {
123 RSDPDescriptor base;
124 u32 length;
125 u64 xsdt_ptr;
126 u8 ext_checksum;
127 u8 reserved[3];
128};
129
130// https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#system-description-table-header
131struct [[gnu::packed]] SDTHeader {
132 char sig[4];
133 u32 length;
134 u8 revision;
135 u8 checksum;
136 char oem_id[6];
137 char oem_table_id[8];
138 u32 oem_revision;
139 u32 creator_id;
140 u32 creator_revision;
141};
142
143// https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#root-system-description-table-rsdt
144struct [[gnu::packed]] RSDT {
145 SDTHeader h;
146 u32 table_ptrs[];
147};
148
149// https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#extended-system-description-table-xsdt
150struct [[gnu::packed]] XSDT {
151 SDTHeader h;
152 u64 table_ptrs[];
153};
154
155struct [[gnu::packed]] GenericAddressStructure {
156 u8 address_space;
157 u8 bit_width;
158 u8 bit_offset;
159 u8 access_size;
160 u64 address;
161};
162
163struct [[gnu::packed]] HPET {
164 SDTHeader h;
165 u8 hardware_revision_id;
166 u8 attributes;
167 u16 pci_vendor_id;
168 GenericAddressStructure event_timer_block;
169 u8 hpet_number;
170 u16 mininum_clock_tick;
171 u8 page_protection;
172};
173
174// https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#fixed-acpi-description-table-fadt
175struct [[gnu::packed]] FADT {
176 SDTHeader h;
177 u32 firmware_ctrl;
178 u32 dsdt_ptr;
179 u8 reserved;
180 u8 preferred_pm_profile;
181 u16 sci_int;
182 u32 smi_cmd;
183 u8 acpi_enable_value;
184 u8 acpi_disable_value;
185 u8 s4bios_req;
186 u8 pstate_cnt;
187 u32 PM1a_EVT_BLK;
188 u32 PM1b_EVT_BLK;
189 u32 PM1a_CNT_BLK;
190 u32 PM1b_CNT_BLK;
191 u32 PM2_CNT_BLK;
192 u32 PM_TMR_BLK;
193 u32 GPE0_BLK;
194 u32 GPE1_BLK;
195 u8 PM1_EVT_LEN;
196 u8 PM1_CNT_LEN;
197 u8 PM2_CNT_LEN;
198 u8 PM_TMR_LEN;
199 u8 GPE0_BLK_LEN;
200 u8 GPE1_BLK_LEN;
201 u8 GPE1_BASE;
202 u8 cst_cnt;
203 u16 P_LVL2_LAT;
204 u16 P_LVL3_LAT;
205 u16 flush_size;
206 u16 flush_stride;
207 u8 duty_offset;
208 u8 duty_width;
209 u8 day_alrm;
210 u8 mon_alrm;
211 u8 century;
212 u16 ia_pc_boot_arch_flags;
213 u8 reserved2;
214 u32 flags;
215 GenericAddressStructure reset_reg;
216 u8 reset_value;
217 u16 arm_boot_arch;
218 u8 fadt_minor_version;
219 u64 x_firmware_ctrl;
220 u64 x_dsdt;
221 GenericAddressStructure x_pm1a_evt_blk;
222 GenericAddressStructure x_pm1b_evt_blk;
223 GenericAddressStructure x_pm1a_cnt_blk;
224 GenericAddressStructure x_pm1b_cnt_blk;
225 GenericAddressStructure x_pm2_cnt_blk;
226 GenericAddressStructure x_pm_tmr_blk;
227 GenericAddressStructure x_gpe0_blk;
228 GenericAddressStructure x_gpe1_blk;
229 GenericAddressStructure sleep_control;
230 GenericAddressStructure sleep_status;
231 u64 hypervisor_vendor_identity;
232};
233
234// https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#interrupt-controller-structure-types
235enum class MADTEntryType {
236 LocalAPIC = 0x0,
237 IOAPIC = 0x1,
238 InterruptSourceOverride = 0x2,
239 NMI_Source = 0x3,
240 LocalAPIC_NMI = 0x4,
241 LocalAPIC_Address_Override = 0x5,
242 IO_SAPIC = 0x6,
243 Local_SAPIC = 0x7,
244 Platform_interrupt_Sources = 0x8,
245 Local_x2APIC = 0x9,
246 Local_x2APIC_NMI = 0xA,
247 GIC_CPU = 0xB,
248 GIC_Distributor = 0xC,
249 GIC_MSI = 0xD,
250 GIC_Redistrbutor = 0xE,
251 GIC_Interrupt_Translation = 0xF
252};
253
254struct [[gnu::packed]] MADTEntryHeader {
255 u8 type;
256 u8 length;
257};
258
259namespace MADTEntries {
260
261// https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#i-o-apic-structure
262struct [[gnu::packed]] IOAPIC {
263 MADTEntryHeader h;
264 u8 ioapic_id;
265 u8 reserved;
266 u32 ioapic_address;
267 u32 gsi_base;
268};
269
270// https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#processor-local-apic-structure
271struct [[gnu::packed]] ProcessorLocalAPIC {
272 MADTEntryHeader h;
273 u8 acpi_processor_id;
274 u8 apic_id;
275 u32 flags;
276};
277
278// https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#processor-local-x2apic-structure
279struct [[gnu::packed]] ProcessorLocalX2APIC {
280 MADTEntryHeader h;
281 u16 reserved;
282 u32 apic_id;
283 u32 flags;
284 u32 acpi_processor_id;
285};
286
287// https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#interrupt-source-override-structure
288struct [[gnu::packed]] InterruptSourceOverride {
289 MADTEntryHeader h;
290 u8 bus;
291 u8 source;
292 u32 global_system_interrupt;
293 u16 flags;
294};
295}
296
297// https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#multiple-apic-description-table-madt-format
298struct [[gnu::packed]] MADT {
299 SDTHeader h;
300 u32 lapic_address;
301 u32 flags;
302 MADTEntryHeader entries[];
303};
304
305struct [[gnu::packed]] AMLTable {
306 SDTHeader h;
307 char aml_code[];
308};
309
310struct [[gnu::packed]] PCI_MMIO_Descriptor {
311 u64 base_addr;
312 u16 seg_group_number;
313 u8 start_pci_bus;
314 u8 end_pci_bus;
315 u32 reserved;
316};
317
318struct [[gnu::packed]] MCFG {
319 SDTHeader header;
320 u64 reserved;
321 PCI_MMIO_Descriptor descriptors[];
322};
323
324struct [[gnu::packed]] DSDT {
325 SDTHeader h;
326 unsigned char definition_block[];
327};
328}
329
330class Parser;
331
332namespace StaticParsing {
333Optional<PhysicalAddress> find_rsdp();
334Optional<PhysicalAddress> find_table(PhysicalAddress rsdp, StringView signature);
335}
336
337}