Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
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
33namespace Kernel {
34
35namespace ACPI_RAW {
36
37 struct [[gnu::packed]] RSDPDescriptor
38 {
39 char sig[8];
40 u8 checksum;
41 char oem_id[6];
42 u8 revision;
43 u32 rsdt_ptr;
44 };
45
46 struct [[gnu::packed]] RSDPDescriptor20
47 {
48 RSDPDescriptor base;
49 u32 length;
50 u64 xsdt_ptr;
51 u8 ext_checksum;
52 u8 reserved[3];
53 };
54
55 struct [[gnu::packed]] SDTHeader
56 {
57 char sig[4];
58 u32 length;
59 u8 revision;
60 u8 checksum;
61 char oem_id[6];
62 char oem_table_id[8];
63 u32 oem_revision;
64 u32 creator_id;
65 u32 creator_revision;
66 };
67
68 struct [[gnu::packed]] RSDT
69 {
70 SDTHeader h;
71 u32 table_ptrs[];
72 };
73
74 struct [[gnu::packed]] XSDT
75 {
76 SDTHeader h;
77 u64 table_ptrs[];
78 };
79
80 struct [[gnu::packed]] GenericAddressStructure
81 {
82 u8 address_space;
83 u8 bit_width;
84 u8 bit_offset;
85 u8 access_size;
86 u64 address;
87 };
88
89 struct [[gnu::packed]] TimerStructure
90 {
91 u64 configuration_capability;
92 u64 comparator_value;
93 u64 fsb_interrupt_route;
94 };
95
96 struct [[gnu::packed]] HPET
97 {
98 SDTHeader h;
99 u64 capabilities;
100 u64 reserved;
101 u64 configuration;
102 u64 reserved2;
103 u64 interrupt_status;
104 u64 reserved3;
105 u64 main_counter_value;
106 u64 reserved4;
107 TimerStructure timer0;
108 u64 reserved5;
109 TimerStructure timer1;
110 u64 reserved6;
111 TimerStructure timer2;
112 u64 reserved7;
113 };
114
115 struct [[gnu::packed]] FADT
116 {
117 SDTHeader h;
118 u32 firmware_ctrl;
119 u32 dsdt_ptr;
120 u8 reserved;
121 u8 preferred_pm_profile;
122 u16 sci_int;
123 u32 smi_cmd;
124 u8 acpi_enable_value;
125 u8 acpi_disable_value;
126 u8 s4bios_req;
127 u8 pstate_cnt;
128 u32 PM1a_EVT_BLK;
129 u32 PM1b_EVT_BLK;
130 u32 PM1a_CNT_BLK;
131 u32 PM1b_CNT_BLK;
132 u32 PM2_CNT_BLK;
133 u32 PM_TMR_BLK;
134 u32 GPE0_BLK;
135 u32 GPE1_BLK;
136 u8 PM1_EVT_LEN;
137 u8 PM1_CNT_LEN;
138 u8 PM2_CNT_LEN;
139 u8 PM_TMR_LEN;
140 u8 GPE0_BLK_LEN;
141 u8 GPE1_BLK_LEN;
142 u8 GPE1_BASE;
143 u8 cst_cnt;
144 u16 P_LVL2_LAT;
145 u16 P_LVL3_LAT;
146 u16 flush_size;
147 u16 flush_stride;
148 u8 duty_offset;
149 u8 duty_width;
150 u8 day_alrm;
151 u8 mon_alrm;
152 u8 century;
153 u16 ia_pc_boot_arch_flags;
154 u8 reserved2;
155 u32 flags;
156 GenericAddressStructure reset_reg;
157 u8 reset_value;
158 u16 arm_boot_arch;
159 u8 fadt_minor_version;
160 u64 x_firmware_ctrl;
161 u64 x_dsdt;
162 GenericAddressStructure x_pm1a_evt_blk;
163 GenericAddressStructure x_pm1b_evt_blk;
164 GenericAddressStructure x_pm1a_cnt_blk;
165 GenericAddressStructure x_pm1b_cnt_blk;
166 GenericAddressStructure x_pm2_cnt_blk;
167 GenericAddressStructure x_pm_tmr_blk;
168 GenericAddressStructure x_gpe0_blk;
169 GenericAddressStructure x_gpe1_blk;
170 GenericAddressStructure sleep_control;
171 GenericAddressStructure sleep_status;
172 u64 hypervisor_vendor_identity;
173 };
174 enum class MADTEntryType {
175 LocalAPIC = 0x0,
176 IOAPIC = 0x1,
177 InterruptSourceOverride = 0x2,
178 NMI_Source = 0x3,
179 LocalAPIC_NMI = 0x4,
180 LocalAPIC_Address_Override = 0x5,
181 IO_SAPIC = 0x6,
182 Local_SAPIC = 0x7,
183 Platform_interrupt_Sources = 0x8,
184 Local_x2APIC = 0x9,
185 Local_x2APIC_NMI = 0xA,
186 GIC_CPU = 0xB,
187 GIC_Distributor = 0xC,
188 GIC_MSI = 0xD,
189 GIC_Redistrbutor = 0xE,
190 GIC_Interrupt_Translation = 0xF
191 };
192
193 struct [[gnu::packed]] MADTEntryHeader
194 {
195 u8 type;
196 u8 length;
197 };
198
199 struct [[gnu::packed]] MADT_IOAPIC
200 {
201 MADTEntryHeader h;
202 u8 ioapic_id;
203 u8 reserved;
204 u32 ioapic_address;
205 u32 gsi_base;
206 };
207
208 struct [[gnu::packed]] MADT_InterruptSourceOverride
209 {
210 MADTEntryHeader h;
211 u8 bus;
212 u8 source;
213 u32 global_system_interrupt;
214 u16 flags;
215 };
216
217 struct [[gnu::packed]] MADT
218 {
219 SDTHeader h;
220 u32 lapic_address;
221 u32 flags;
222 MADTEntryHeader entries[];
223 };
224
225 struct [[gnu::packed]] AMLTable
226 {
227 SDTHeader h;
228 char aml_code[];
229 };
230
231 struct [[gnu::packed]] PCI_MMIO_Descriptor
232 {
233 u64 base_addr;
234 u16 seg_group_number;
235 u8 start_pci_bus;
236 u8 end_pci_bus;
237 u32 reserved;
238 };
239
240 struct [[gnu::packed]] MCFG
241 {
242 SDTHeader header;
243 u64 reserved;
244 PCI_MMIO_Descriptor descriptors[];
245 };
246}
247
248class ACPIStaticParser;
249
250namespace ACPI {
251
252 class SDT : public RefCounted<SDT> {
253 };
254
255 struct GenericAddressStructure {
256 u8 address_space;
257 u8 bit_width;
258 u8 bit_offset;
259 u8 access_size;
260 u64 address;
261 GenericAddressStructure& operator=(const GenericAddressStructure& other)
262 {
263 this->address_space = other.address_space;
264 this->bit_width = other.bit_width;
265 this->bit_offset = other.bit_offset;
266 this->access_size = other.access_size;
267 this->address = (uintptr_t)other.address;
268 return *this;
269 }
270 GenericAddressStructure& operator=(const ACPI_RAW::GenericAddressStructure& other)
271 {
272 this->address_space = other.address_space;
273 this->bit_width = other.bit_width;
274 this->bit_offset = other.bit_offset;
275 this->access_size = other.access_size;
276 this->address = (uintptr_t)other.address;
277 return *this;
278 }
279 };
280
281 class FixedACPIData;
282}
283
284class ACPI::FixedACPIData : public ACPI::SDT {
285 friend ACPIStaticParser;
286
287public:
288 explicit FixedACPIData(ACPI_RAW::FADT&);
289 ACPI_RAW::SDTHeader* get_dsdt();
290
291private:
292 u8 m_revision;
293 u32 m_dsdt_ptr;
294 u64 m_x_dsdt_ptr;
295 u8 m_preferred_pm_profile;
296 u16 m_sci_int;
297 u32 m_smi_cmd;
298 u8 m_acpi_enable_value;
299 u8 m_acpi_disable_value;
300 u8 m_s4bios_req;
301 u8 m_pstate_cnt;
302 u32 m_PM1a_EVT_BLK;
303 u32 m_PM1b_EVT_BLK;
304 u32 m_PM1a_CNT_BLK;
305 u32 m_PM1b_CNT_BLK;
306 u32 m_PM2_CNT_BLK;
307 u32 m_PM_TMR_BLK;
308 u32 m_GPE0_BLK;
309 u32 m_GPE1_BLK;
310 u8 m_PM1_EVT_LEN;
311 u8 m_PM1_CNT_LEN;
312 u8 m_PM2_CNT_LEN;
313 u8 m_PM_TMR_LEN;
314 u8 m_GPE0_BLK_LEN;
315 u8 m_GPE1_BLK_LEN;
316 u8 m_GPE1_BASE;
317 u8 m_cst_cnt;
318 u16 m_P_LVL2_LAT;
319 u16 m_P_LVL3_LAT;
320 u16 m_flush_size;
321 u16 m_flush_stride;
322 u8 m_duty_offset;
323 u8 m_duty_width;
324 u8 m_day_alrm;
325 u8 m_mon_alrm;
326 u8 m_century;
327 u16 m_ia_pc_boot_arch_flags;
328 u32 m_flags;
329 ACPI::GenericAddressStructure m_reset_reg;
330 u8 m_reset_value;
331 ACPI::GenericAddressStructure m_x_pm1a_evt_blk;
332 ACPI::GenericAddressStructure m_x_pm1b_evt_blk;
333 ACPI::GenericAddressStructure m_x_pm1a_cnt_blk;
334 ACPI::GenericAddressStructure m_x_pm1b_cnt_blk;
335 ACPI::GenericAddressStructure m_x_pm2_cnt_blk;
336 ACPI::GenericAddressStructure m_x_pm_tmr_blk;
337 ACPI::GenericAddressStructure m_x_gpe0_blk;
338 ACPI::GenericAddressStructure m_x_gpe1_blk;
339 ACPI::GenericAddressStructure m_sleep_control;
340 ACPI::GenericAddressStructure m_sleep_status;
341 u64 m_hypervisor_vendor_identity;
342};
343
344namespace ACPI {
345
346 class MainSystemDescriptionTable : public SDT {
347 public:
348 explicit MainSystemDescriptionTable(Vector<ACPI_RAW::SDTHeader*>&& sdt_pointers);
349 Vector<ACPI_RAW::SDTHeader*>& get_sdt_pointers();
350
351 private:
352 Vector<ACPI_RAW::SDTHeader*> m_sdt_pointers;
353 };
354
355 class MCFG : public SDT {
356 public:
357 MCFG(ACPI_RAW::MCFG&);
358 };
359
360 class FACS : public SDT {
361
362 public:
363 private:
364 u32 hardware_sig;
365 u32 waking_vector;
366 u32 global_lock;
367 u32 flags;
368 u64 x_waking_vector;
369 u32 ospm_flags;
370 };
371
372 class MADT : public SDT {
373 };
374}
375
376}