Serenity Operating System
1/*
2 * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#pragma once
28
29#include <AK/RefCounted.h>
30#include <AK/Types.h>
31#include <AK/Vector.h>
32#include <LibBareMetal/Memory/PhysicalAddress.h>
33
34namespace Kernel {
35
36namespace ACPI {
37
38namespace FADTFlags {
39enum class FeatureFlags : u32 {
40 WBINVD = 1 << 0,
41 WBINVD_FLUSH = 1 << 1,
42 PROC_C1 = 1 << 2,
43 P_LVL2_UP = 1 << 3,
44 PWR_BUTTON = 1 << 4,
45 SLP_BUTTON = 1 << 5,
46 FIX_RTC = 1 << 6,
47 RTC_s4 = 1 << 7,
48 TMR_VAL_EXT = 1 << 8,
49 DCK_CAP = 1 << 9,
50 RESET_REG_SUPPORTED = 1 << 10,
51 SEALED_CASE = 1 << 11,
52 HEADLESS = 1 << 12,
53 CPU_SW_SLP = 1 << 13,
54 PCI_EXP_WAK = 1 << 14,
55 USE_PLATFORM_CLOCK = 1 << 15,
56 S4_RTC_STS_VALID = 1 << 16,
57 REMOTE_POWER_ON_CAPABLE = 1 << 17,
58 FORCE_APIC_CLUSTER_MODEL = 1 << 18,
59 FORCE_APIC_PHYSICAL_DESTINATION_MODE = 1 << 19,
60 HW_REDUCED_ACPI = 1 << 20,
61 LOW_POWER_S0_IDLE_CAPABLE = 1 << 21
62};
63
64enum class IA_PC_Flags : u8 {
65 Legacy_Devices = 1 << 0,
66 PS2_8042 = 1 << 1,
67 VGA_Not_Present = 1 << 2,
68 MSI_Not_Supported = 1 << 3,
69 PCIe_ASPM_Controls = 1 << 4,
70 CMOS_RTC_Not_Present = 1 << 5
71};
72
73struct [[gnu::packed]] HardwareFeatures
74{
75 bool wbinvd : 1;
76 bool wbinvd_flush : 1;
77 bool processor_c1 : 1;
78 bool multiprocessor_c2 : 1;
79 bool power_button : 1;
80 bool sleep_button : 1;
81 bool fix_rtc : 1;
82 bool rtc_s4 : 1;
83 bool timer_value_extension : 1;
84 bool docking_capability : 1;
85 bool reset_register_supported : 1;
86 bool sealed_case : 1;
87 bool headless : 1;
88 bool cpu_software_sleep : 1;
89 bool pci_express_wake : 1;
90 bool use_platform_clock : 1;
91 bool s4_rtc_status_valid : 1;
92 bool remote_power_on_capable : 1;
93 bool force_apic_cluster_model : 1;
94 bool force_apic_physical_destination_mode : 1;
95 bool hardware_reduced_acpi : 1;
96 bool low_power_s0_idle_capable : 1;
97};
98struct [[gnu::packed]] x86_Specific_Flags
99{
100 bool legacy_devices : 1;
101 bool keyboard_8042 : 1;
102 bool vga_not_present : 1;
103 bool msi_not_supported : 1;
104 bool cmos_rtc_not_present : 1;
105};
106};
107
108namespace GenericAddressStructure {
109enum class AddressSpace {
110 SystemMemory = 0,
111 SystemIO = 1,
112 PCIConfigurationSpace = 2,
113 EmbeddedController = 3,
114 SMBus = 4,
115 PCC = 0xA,
116 FunctionalFixedHardware = 0x7F
117};
118enum class AccessSize {
119 Undefined = 0,
120 Byte = 1,
121 Word = 2,
122 DWord = 3,
123 QWord = 4
124};
125enum class BitWidth {
126 Undefined = 0,
127 Byte = 8,
128 Word = 16,
129 DWord = 32,
130 QWord = 64
131};
132}
133
134namespace Structures {
135struct [[gnu::packed]] RSDPDescriptor
136{
137 char sig[8];
138 u8 checksum;
139 char oem_id[6];
140 u8 revision;
141 u32 rsdt_ptr;
142};
143
144struct [[gnu::packed]] RSDPDescriptor20
145{
146 RSDPDescriptor base;
147 u32 length;
148 u64 xsdt_ptr;
149 u8 ext_checksum;
150 u8 reserved[3];
151};
152
153struct [[gnu::packed]] SDTHeader
154{
155 char sig[4];
156 u32 length;
157 u8 revision;
158 u8 checksum;
159 char oem_id[6];
160 char oem_table_id[8];
161 u32 oem_revision;
162 u32 creator_id;
163 u32 creator_revision;
164};
165
166struct [[gnu::packed]] RSDT
167{
168 SDTHeader h;
169 u32 table_ptrs[];
170};
171
172struct [[gnu::packed]] XSDT
173{
174 SDTHeader h;
175 u64 table_ptrs[];
176};
177
178struct [[gnu::packed]] GenericAddressStructure
179{
180 u8 address_space;
181 u8 bit_width;
182 u8 bit_offset;
183 u8 access_size;
184 u64 address;
185};
186
187struct [[gnu::packed]] HPET
188{
189 SDTHeader h;
190 u8 hardware_revision_id;
191 u8 attributes;
192 u16 pci_vendor_id;
193 GenericAddressStructure event_timer_block;
194 u8 hpet_number;
195 u16 mininum_clock_tick;
196 u8 page_protection;
197};
198
199struct [[gnu::packed]] FADT
200{
201 SDTHeader h;
202 u32 firmware_ctrl;
203 u32 dsdt_ptr;
204 u8 reserved;
205 u8 preferred_pm_profile;
206 u16 sci_int;
207 u32 smi_cmd;
208 u8 acpi_enable_value;
209 u8 acpi_disable_value;
210 u8 s4bios_req;
211 u8 pstate_cnt;
212 u32 PM1a_EVT_BLK;
213 u32 PM1b_EVT_BLK;
214 u32 PM1a_CNT_BLK;
215 u32 PM1b_CNT_BLK;
216 u32 PM2_CNT_BLK;
217 u32 PM_TMR_BLK;
218 u32 GPE0_BLK;
219 u32 GPE1_BLK;
220 u8 PM1_EVT_LEN;
221 u8 PM1_CNT_LEN;
222 u8 PM2_CNT_LEN;
223 u8 PM_TMR_LEN;
224 u8 GPE0_BLK_LEN;
225 u8 GPE1_BLK_LEN;
226 u8 GPE1_BASE;
227 u8 cst_cnt;
228 u16 P_LVL2_LAT;
229 u16 P_LVL3_LAT;
230 u16 flush_size;
231 u16 flush_stride;
232 u8 duty_offset;
233 u8 duty_width;
234 u8 day_alrm;
235 u8 mon_alrm;
236 u8 century;
237 u16 ia_pc_boot_arch_flags;
238 u8 reserved2;
239 u32 flags;
240 GenericAddressStructure reset_reg;
241 u8 reset_value;
242 u16 arm_boot_arch;
243 u8 fadt_minor_version;
244 u64 x_firmware_ctrl;
245 u64 x_dsdt;
246 GenericAddressStructure x_pm1a_evt_blk;
247 GenericAddressStructure x_pm1b_evt_blk;
248 GenericAddressStructure x_pm1a_cnt_blk;
249 GenericAddressStructure x_pm1b_cnt_blk;
250 GenericAddressStructure x_pm2_cnt_blk;
251 GenericAddressStructure x_pm_tmr_blk;
252 GenericAddressStructure x_gpe0_blk;
253 GenericAddressStructure x_gpe1_blk;
254 GenericAddressStructure sleep_control;
255 GenericAddressStructure sleep_status;
256 u64 hypervisor_vendor_identity;
257};
258enum class MADTEntryType {
259 LocalAPIC = 0x0,
260 IOAPIC = 0x1,
261 InterruptSourceOverride = 0x2,
262 NMI_Source = 0x3,
263 LocalAPIC_NMI = 0x4,
264 LocalAPIC_Address_Override = 0x5,
265 IO_SAPIC = 0x6,
266 Local_SAPIC = 0x7,
267 Platform_interrupt_Sources = 0x8,
268 Local_x2APIC = 0x9,
269 Local_x2APIC_NMI = 0xA,
270 GIC_CPU = 0xB,
271 GIC_Distributor = 0xC,
272 GIC_MSI = 0xD,
273 GIC_Redistrbutor = 0xE,
274 GIC_Interrupt_Translation = 0xF
275};
276
277struct [[gnu::packed]] MADTEntryHeader
278{
279 u8 type;
280 u8 length;
281};
282
283namespace MADTEntries {
284struct [[gnu::packed]] IOAPIC
285{
286 MADTEntryHeader h;
287 u8 ioapic_id;
288 u8 reserved;
289 u32 ioapic_address;
290 u32 gsi_base;
291};
292
293struct [[gnu::packed]] InterruptSourceOverride
294{
295 MADTEntryHeader h;
296 u8 bus;
297 u8 source;
298 u32 global_system_interrupt;
299 u16 flags;
300};
301}
302
303struct [[gnu::packed]] MADT
304{
305 SDTHeader h;
306 u32 lapic_address;
307 u32 flags;
308 MADTEntryHeader entries[];
309};
310
311struct [[gnu::packed]] AMLTable
312{
313 SDTHeader h;
314 char aml_code[];
315};
316
317struct [[gnu::packed]] PCI_MMIO_Descriptor
318{
319 u64 base_addr;
320 u16 seg_group_number;
321 u8 start_pci_bus;
322 u8 end_pci_bus;
323 u32 reserved;
324};
325
326struct [[gnu::packed]] MCFG
327{
328 SDTHeader header;
329 u64 reserved;
330 PCI_MMIO_Descriptor descriptors[];
331};
332}
333
334class StaticParser;
335class DynamicParser;
336class Parser;
337
338namespace StaticParsing {
339PhysicalAddress find_rsdp();
340PhysicalAddress find_table(PhysicalAddress rsdp, const StringView& signature);
341};
342}
343}