Skip to main content

raw_acpi/
fadt.rs

1use crate::{GenericAddressStructure, SDTHeader};
2
3#[derive(Copy, Clone)]
4pub enum FADTPersistentCPUCacheFeature {
5    NotReported,
6    NotPersistent,
7    Persistent,
8}
9
10#[derive(Copy, Clone)]
11/// ## Fixed ACPI Description Table Fixed Feature Flags
12pub struct FADTFixedFeatureFlags(u32);
13impl FADTFixedFeatureFlags {
14    /// Processor properly implements a functional equivalent to the WBINVD IA-32 instruction.
15    ///
16    /// If set, signifies that the WBINVD instruction correctly flushes the processor caches, maintains memory coherency,
17    /// and upon completion of the instruction, all caches for the current processor contain no cached data other than what OSPM references and allows to be cached.
18    ///
19    /// If this flag is not set, the ACPI OS is responsible for disabling all ACPI features that need this function.
20    /// This field is maintained for ACPI 1.0 processor compatibility on existing systems. Processors in new ACPI-compatible systems are required to support this function and indicate this to OSPM by setting this field.
21    pub const fn wbinvd(&self) -> bool {
22        self.0 & 0b00000000000000000000000000000001 != 0
23    }
24    /// If set, indicates that the hardware flushes all caches on the WBINVD instruction and maintains memory coherency, but does not guarantee the caches are invalidated.
25    /// This provides the complete semantics of the WBINVD instruction, and provides enough to support the system sleeping states.
26    ///
27    /// If neither of the WBINVD flags is set, the system will require FLUSH_SIZE and FLUSH_STRIDE to support sleeping states.
28    /// If the FLUSH parameters are also not supported, the machine cannot support sleeping states S1, S2, or S3.
29    pub const fn wbinvd_flush(&self) -> bool {
30        self.0 & 0b00000000000000000000000000000010 != 0
31    }
32    /// A one indicates that the C1 power state is supported on all processors.
33    pub const fn proc_c1(&self) -> bool {
34        self.0 & 0b00000000000000000000000000000100 != 0
35    }
36    /// A zero indicates that the C2 power state is configured to only work on a uniprocessor (UP) system.<br>
37    /// A one indicates that the C2 power state is configured to work on a UP or multiprocessor (MP) system.
38    pub const fn p_lvl2_up(&self) -> bool {
39        self.0 & 0b00000000000000000000000000001000 != 0
40    }
41    /// A zero indicates the power button is handled as a fixed feature programming model.<br>
42    /// A one indicates the power button is handled as a control method device.
43    ///
44    /// If the system does not have a power button, this value would be "1" and no power button device would be present.
45    /// Independent of the value of this field, the presence of a power button device in the namespace indicates to OSPM that the power button is handled as a control method device.
46    pub const fn pwr_button(&self) -> bool {
47        self.0 & 0b00000000000000000000000000010000 != 0
48    }
49    /// A zero indicates the sleep button is handled as a fixed feature programming model.<br>
50    /// A one indicates the sleep button is handled as a control method device.
51    ///
52    /// If the system does not have a sleep button, this value would be "1" and no sleep button device would be present.
53    /// Independent of the value of this field, the presence of a sleep button device in the namespace indicates to OSPM that the sleep button is handled as a control method device.
54    pub const fn slp_button(&self) -> bool {
55        self.0 & 0b00000000000000000000000000100000 != 0
56    }
57    /// A zero indicates the RTC wake status is supported in fixed register space.<br>
58    /// A one indicates the RTC wake status is not supported in fixed register space.
59    pub const fn fix_rtc(&self) -> bool {
60        self.0 & 0b00000000000000000000000001000000 != 0
61    }
62    /// Indicates whether the RTC alarm function can wake the system from the S4 state.
63    ///
64    /// The RTC must be able to wake the system from an S1, S2, or S3 sleep state.
65    /// The RTC alarm can optionally support waking the system from the S4 state, as indicated by this value.
66    pub const fn rtc_s4(&self) -> bool {
67        self.0 & 0b00000000000000000000000010000000 != 0
68    }
69    /// A zero indicates TMR_VAL is implemented as a 24-bit value.<br>
70    /// A one indicates TMR_VAL is implemented as a 32-bit value.
71    ///
72    /// The TMR_STS bit is set when the most significant bit of the TMR_VAL toggles.
73    pub const fn tmr_val_ext(&self) -> bool {
74        self.0 & 0b00000000000000000000000100000000 != 0
75    }
76    /// A zero indicates that the system cannot support docking.<br>
77    /// A one indicates that the system can support docking.
78    ///
79    /// Notice that this flag does not indicate whether or not a docking station is currently present; it only indicates that the system is capable of docking.
80    pub const fn dck_cap(&self) -> bool {
81        self.0 & 0b00000000000000000000001000000000 != 0
82    }
83    /// If set, indicates the system supports system reset via the FADT RESET_REG as described in Section 4.8.3.6.
84    pub const fn reset_reg_sup(&self) -> bool {
85        self.0 & 0b00000000000000000000010000000000 != 0
86    }
87    /// System Type Attribute.
88    ///
89    /// If set, indicates that the system has no internal expansion capabilities and the case is sealed.
90    pub const fn sealed_case(&self) -> bool {
91        self.0 & 0b00000000000000000000100000000000 != 0
92    }
93    /// System Type Attribute.
94    ///
95    /// If set, indicates the system cannot detect the monitor or keyboard/mouse devices.
96    pub const fn headless(&self) -> bool {
97        self.0 & 0b00000000000000000001000000000000 != 0
98    }
99    /// If set, indicates to OSPM that a processor native instruction must be executed after writing the SLP_TYPx register.
100    pub const fn cpu_sw_slp(&self) -> bool {
101        self.0 & 0b00000000000000000010000000000000 != 0
102    }
103    /// If set, indicates the platform supports the PCIEXP_WAKE_STS bit in the PM1 Status register and the PCIEXP_WAKE_EN bit in the PM1 Enable register.
104    ///
105    /// This bit must be set on platforms containing chipsets that implement PCI Express and supports PM1 PCIEXP_WAK bits.
106    pub const fn pci_exp_wak(&self) -> bool {
107        self.0 & 0b00000000000000000100000000000000 != 0
108    }
109    /// A value of one indicates that OSPM should use a platform provided timer to drive any monotonically non-decreasing counters, such as OSPM performance counter services.
110    /// Which particular platform timer will be used is OSPM specific; however, it is recommended that the timer used is based on the following algorithm:
111    ///
112    /// - If the HPET is exposed to OSPM, OSPM should use the HPET.
113    /// - Otherwise, OSPM will use the ACPI power management timer.
114    ///
115    /// A value of one indicates that the platform is known to have a correctly implemented ACPI power management timer.
116    /// A platform may choose to set this flag if a internal processor clock (or clocks in a multi-processor configuration) cannot provide consistent monotonically non-decreasing counters.
117    ///
118    /// Note: If a value of zero is present, OSPM may arbitrarily choose to use an internal processor clock or a platform timer clock for these operations.
119    /// That is, a zero does not imply that OSPM will necessarily use the internal processor clock to generate a monotonically non-decreasing counter to the system.
120    pub const fn use_platform_clock(&self) -> bool {
121        self.0 & 0b00000000000000001000000000000000 != 0
122    }
123    /// A one indicates that the contents of the RTC_STS flag is valid when waking the system from S4. See Table 4.11 for more information.
124    ///
125    /// Some existing systems do not reliably set this input today, and this bit allows OSPM to differentiate correctly functioning platforms from platforms with this errata.
126    pub const fn s4_rtc_sts_valid(&self) -> bool {
127        self.0 & 0b00000000000000010000000000000000 != 0
128    }
129    /// A one indicates that the platform is compatible with remote power-on. That is, the platform supports OSPM leaving GPE wake events armed prior to an S5 transition.
130    ///
131    /// Some existing platforms do not reliably transition to S5 with wake events enabled (for example, the platform may immediately generate a spurious wake event after completing the S5 transition).
132    /// This flag allows OSPM to differentiate correctly functioning platforms from platforms with this type of errata.
133    pub const fn remote_power_on_capable(&self) -> bool {
134        self.0 & 0b00000000000000100000000000000000 != 0
135    }
136    /// A one indicates that all local APICs must be configured for the cluster destination model when delivering interrupts in logical mode.
137    ///
138    /// If this bit is set, then logical mode interrupt delivery operation may be undefined until OSPM has moved all local APICs to the cluster model.
139    ///
140    /// Note that the cluster destination model doesn't apply to Itaniumâ„¢ Processor Family (IPF) local SAPICs.
141    /// This bit is intended for xAPIC based machines that require the cluster destination model even when 8 or fewer local APICs are present in the machine.
142    pub const fn force_apic_cluster_model(&self) -> bool {
143        self.0 & 0b00000000000001000000000000000000 != 0
144    }
145    /// A one indicates that all local xAPICs must be configured for physical destination mode.
146    ///
147    /// If this bit is set, interrupt delivery operation in logical destination mode is undefined.
148    /// On machines that contain fewer than 8 local xAPICs or that do not use the xAPIC architecture, this bit is ignored.
149    pub const fn force_apic_physical_destination_mode(&self) -> bool {
150        self.0 & 0b00000000000010000000000000000000 != 0
151    }
152    /// A one indicates that the Hardware-Reduced ACPI (section 4.1) is implemented, therefore software-only alternatives are used for supported fixed-features defined in chapter 4.
153    pub const fn hw_reduced_acpi(&self) -> bool {
154        self.0 & 0b00000000000100000000000000000000 != 0
155    }
156    /// A one informs OSPM that the platform is able to achieve power savings in S0 similar to or better than those typically achieved in S3.
157    ///
158    /// In effect, when this bit is set it indicates that the system will achieve no power benefit by making a sleep transition to S3.
159    pub const fn low_power_s0_idle_capable(&self) -> bool {
160        self.0 & 0b00000000001000000000000000000000 != 0
161    }
162    /// The following values describe whether cpu caches and any other caches that are coherent with them, are considered by the platform to be persistent.
163    /// The platform evaluates the configuration present at system startup to determine this value. System configuration changes after system startup may invalidate this.
164    /// - 00b - Not reported by the platform. Software should reference the NFIT Platform Capabilities
165    /// - 01b - Cpu caches and any other caches that are coherent with them, are not persistent. Software is responsible for flushing data from cpu caches to make stores persistent. Supersedes NFIT Platform Capabilities.
166    /// - 10b - Cpu caches and any other caches that are coherent with them, are persistent. Supersedes NFIT Platform Capabilities.
167    /// When reporting this state, the platform shall provide enough stored energy for ALL of the following:
168    ///   - Time to flush cpu caches and any other caches that are coherent with them
169    ///   - Time of all targets of those flushes to complete flushing stored data
170    ///   - If supporting hot plug, the worst case CXL device topology that can be hot plugged
171    /// - 11b - Reserved
172    ///
173    /// **JJ's note: I made a rust enum just for this 2-bit flag to avoid any sort of confusion when working with this.**
174    pub const fn persistent_cpu_caches(&self) -> FADTPersistentCPUCacheFeature {
175        match (self.0 & 0b00000000110000000000000000000000) >> 22 {
176            0b00 => FADTPersistentCPUCacheFeature::NotReported,
177            0b01 => FADTPersistentCPUCacheFeature::NotPersistent,
178            0b10 => FADTPersistentCPUCacheFeature::Persistent,
179            0b11 => panic!(
180                "FADT Persistent CPU Cache 2-bit flag set to 0b11, which is a reserved value."
181            ),
182            _ => unreachable!(),
183        }
184    }
185    // JJ here, the rest of the bits are reserved; no need to implement.
186}
187
188#[derive(Copy, Clone)]
189/// ## IA-PC Boot Architecture Flags
190///
191/// This set of flags is used by an OS to guide the assumptions it can make in initializing hardware on IA-PC platforms.
192/// These flags are used by an OS at boot time (before the OS is capable of providing an operating environment suitable for parsing the ACPI namespace) to determine the code paths to take during boot.
193///
194/// In IA-PC platforms with reduced legacy hardware, the OS can skip code paths for legacy devices if none are present.
195/// For example, if there are no ISA devices, an OS could skip code that assumes the presence of these devices and their associated resources.
196/// These flags are used independently of the ACPI namespace. The presence of other devices must be described in the ACPI namespace as specified in Section 6 These flags pertain only to IA-PC platforms.
197///
198/// On other system architectures, the entire field should be set to 0.
199pub struct FADTIAPCBootArch(u16);
200impl FADTIAPCBootArch {
201    /// If set, indicates that the motherboard supports user-visible devices on the LPC or ISA bus. User-visible devices are devices that have end-user accessible connectors (for example, LPT port), or devices for which the OS must load a device driver so that an end-user application can use a device.
202    ///
203    /// If clear, the OS may assume there are no such devices and that all devices in the system can be detected exclusively via industry standard device enumeration mechanisms (including the ACPI namespace).
204    pub const fn legacy_devices(&self) -> bool {
205        self.0 & 0b0000000000000001 != 0
206    }
207    /// If set, indicates that the motherboard contains support for a port 60 and 64 based keyboard controller, usually implemented as an 8042 or equivalent micro-controller.
208    pub const fn _8042(&self) -> bool {
209        self.0 & 0b0000000000000010 != 0
210    }
211    /// If set, indicates to OSPM that it must not blindly probe the VGA hardware (that responds to MMIO addresses A0000h-BFFFFh and IO ports 3B0h-3BBh and 3C0h-3DFh) that may cause machine check on this system.
212    ///
213    /// If clear, indicates to OSPM that it is safe to probe the VGA hardware.
214    pub const fn vga_not_present(&self) -> bool {
215        self.0 & 0b0000000000000100 != 0
216    }
217    /// If set, indicates to OSPM that it must not enable Message Signaled Interrupts (MSI) on this platform.
218    pub const fn msi_not_supported(&self) -> bool {
219        self.0 & 0b0000000000001000 != 0
220    }
221    /// If set, indicates to OSPM that it must not enable OSPM ASPM control on this platform.
222    pub const fn pcie_aspm_controls(&self) -> bool {
223        self.0 & 0b0000000000010000 != 0
224    }
225    /// If set, indicates that the CMOS RTC is either not implemented, or does not exist at the legacy addresses.
226    /// OSPM uses the Control Method Time and Alarm Namespace device instead.
227    pub const fn cmos_rtc_not_present(&self) -> bool {
228        self.0 & 0b0000000000100000 != 0
229    }
230    // JJ here, the rest of the bits are reserved; no need to implement.
231}
232
233#[derive(Copy, Clone)]
234/// ## ARM Architecture Boot Flags
235///
236/// These flags are used by an OS at boot time (before the OS is capable of providing an operating environment suitable for parsing the ACPI namespace) to determine the code paths to take during boot.
237///
238/// For the PSCI flags, specifically, the flags describe if the platform is compliant with the PSCI specification.
239///
240/// A link to the PSCI specification can be found at "Links to ACPI-Related Documents" at http://uefi.org/acpi.
241pub struct FADTARMBootArch(u16);
242impl FADTARMBootArch {
243    /// 1 if PSCI is implemented.
244    pub const fn psci_compliant(&self) -> bool {
245        self.0 & 0b01 != 0
246    }
247    /// 1 if HVC must be used as the PSCI conduit.instead of SMC.
248    pub const fn psci_use_hvc(&self) -> bool {
249        self.0 & 0b01 != 0
250    }
251    // JJ here, the rest of the bits are reserved; no need to implement.
252}
253
254#[derive(Copy, Clone)]
255#[repr(C, packed)]
256/// ## Fixed ACPI Description Table
257///
258/// The Fixed ACPI Description Table (FADT) defines various fixed hardware ACPI information vital to an ACPI-compatible OS.
259pub struct FixedACPIDescriptionTable {
260    /// - **Signature** - "FACP"
261    /// - **Revision** - FADT Major Version (see the minor version field of this structure).
262    /// - **OEM Table ID** - For the FADT, the table ID is the manufacture model ID. This field must match the OEM Table ID in the RSDT.
263    pub header: SDTHeader,
264
265    /// Physical memory address of the FACS, where OSPM and Firmware exchange control information.
266    ///
267    /// See <a href="https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html#firmware-acpi-control-structure-facs">Section 5.2.10</a> for more information about the FACS.
268    ///
269    /// If the `x_firmware_ctrl` field contains a non zero value which can be used by the OSPM, then this field must be ignored by the OSPM.<br>
270    /// If the HARDWARE_REDUCED_ACPI flag is set, and both this field and the `x_firmware_ctrl` field are zero, there is no FACS available.
271    pub firmware_ctrl: u32,
272    /// Physical memory address of the DSDT. If the `x_dsdt` field contains a non-zero value which can be used by the OSPM, then this field must be ignored by the OSPM.
273    pub dsdt: u32,
274    /// ACPI 1.0 defined this offset as a field named INT_MODEL, which was eliminated in ACPI 2.0. Platforms should set this field to zero but field values of one are also allowed to maintain compatibility with ACPI 1.0.
275    pub int_model: u8,
276    /// This field is set by the OEM to convey the preferred power management profile to OSPM. OSPM can use this field to set default power management policy parameters during OS installation. Field Values:
277    ///
278    /// - 0 - Unspecified
279    /// - 1 - Desktop
280    /// - 2 - Mobile
281    /// - 3 - Workstation
282    /// - 4 - Enterprise Server
283    /// - 5 - SOHO Server
284    /// - 6 - Appliance PC
285    /// - 7 - Performance Server
286    /// - 8 - Tablet
287    ///
288    /// Other values are reserved.
289    pub preferred_pm_profile: u8,
290
291    /// System vector the SCI interrupt is wired to in 8259 mode.
292    ///
293    /// On systems that do not contain the 8259, this field contains the Global System interrupt number of the SCI interrupt.
294    /// OSPM is required to treat the ACPI SCI interrupt as a shareable, level, active low interrupt.
295    pub sci_int: u16,
296    /// System port address of the SMI Command Port.
297    ///
298    /// During ACPI OS initialization, OSPM can determine that the ACPI hardware registers are owned by SMI (by way of the SCI_EN bit), in which case the ACPI OS issues the ACPI_ENABLE command to the SMI_CMD port.
299    /// The SCI_EN bit effectively tracks the ownership of the ACPI hardware registers. OSPM issues commands to the SMI_CMD port synchronously from the boot processor.
300    /// This field is reserved and must be zero on systems that does not support System Management mode.
301    pub smi_cmd: u32,
302    /// The value to write to SMI_CMD to disable SMI ownership of the ACPI hardware registers.
303    ///
304    /// The last action SMI does to relinquish ownership is to set the SCI_EN bit.
305    /// During the OS initialization process, OSPM will synchronously wait for the ntransfer of SMI ownership to complete, so the ACPI system releases SMI ownership as quickly as possible.
306    /// This field is reserved and must be zero on systems that do not support Legacy Mode.
307    pub acpi_enable: u8,
308    /// The value to write to SMI_CMD to re-enable SMI ownership of the ACPI hardware registers.
309    ///
310    /// This can only be done when ownership was originally acquired from SMI by OSPM using ACPI_ENABLE.
311    /// An OS can hand ownership back to SMI by relinquishing use to the ACPI hardware registers, masking off all SCI interrupts, clearing the SCI_EN bit and then writing ACPI_DISABLE to the SMI_CMD port from the boot processor.
312    /// This field is reserved and must be zero on systems that do not support Legacy Mode.
313    pub acpi_disable: u8,
314    /// The value to write to SMI_CMD to enter the S4BIOS state.
315    ///
316    /// The S4BIOS state provides an alternate way to enter the S4 state where the firmware saves and restores the memory context.
317    /// A value of zero in S4BIOS_F indicates S4BIOS_REQ is not supported.
318    pub s4bios_req: u8,
319    /// If non-zero, this field contains the value OSPM writes to the SMI_CMD register to assume processor performance state control responsibility.
320    pub pstate_cnt: u8,
321
322    /// System port address of the PM1a Event Register Block. See Section 4.8.3.1 for a hardware description layout of this register block.
323    ///
324    /// This is a required field. If the `x_pm1a_evt_blk` field contains a non zero value which can be used by the OSPM, then this field must be ignored by the OSPM.
325    pub pm1a_evt_blk: u32,
326    /// System port address of the PM1b Event Register Block. See Section 4.8.3.1 for a hardware description layout of this register block.
327    ///
328    /// This field is optional; if this register block is not supported, this field contains zero.
329    /// If the `x_pm1b_evt_blk` field contains a non zero value which can be used by the OSPM, then this field must be ignored by the OSPM.
330    pub pm1b_evt_blk: u32,
331    /// System port address of the PM1a Control Register Block. See Section 4.8.3.1 for a hardware description layout of this register block.
332    ///
333    /// This is a required field. If the `x_pm1a_cnt_blk` field contains a non zero value which can be used by the OSPM, then this field must be ignored by the OSPM.
334    pub pm1a_cnt_blk: u32,
335    /// System port address of the PM1b Control Register Block. See Section 4.8.3.1 for a hardware description layout of this register block.
336    ///
337    /// This field is optional; if this register block is not supported, this field contains zero.
338    /// If the `x_pm1b_cnt_blk` field contains a non zero value which can be used by the OSPM, then this field must be ignored by the OSPM.
339    pub pm1b_cnt_blk: u32,
340    /// System port address of the PM2 Control Register Block. See Table 4.4 for a hardware description layout of this register block.
341    ///
342    /// This field is optional; if this register block is not supported, this field contains zero.
343    /// If the `x_pm2_cnt_blk` field contains a non zero value which can be used by the OSPM, then this field must be ignored by the OSPM.
344    pub pm2_cnt_blk: u32,
345    /// System port address of the Power Management Timer Control Register Block. See the Section 4.8.3.3 for a hardware description layout of this register block.
346    ///
347    /// This is an optional field; if this register block is not supported, this field contains zero.
348    /// If the `x_pm_tmr_blk` field contains a non-zero value which can be used by the OSPM, then this field must be ignored by the OSPM.
349    pub pm_tmr_blk: u32,
350    /// System port address of General-Purpose Event 0 Register Block. See Section 4.8.4.1 for more information.
351    ///
352    /// If this register block is not supported, this field contains zero.
353    /// If the `x_gpe0_blk` field contains a nonzero value which can be used by the OSPM, then this field must be ignored by the OSPM.
354    pub gpe0_blk: u32,
355    /// System port address of General-Purpose Event 1 Register Block. See Section 4.8.4.1 for more information.
356    ///
357    /// This is an optional field; if this register block is not supported, this field contains zero.
358    /// If the `x_gpe1_blk` field contains a nonzero value which can be used by the OSPM, then this field must be ignored by the OSPM.
359    pub gpe1_blk: u32,
360
361    /// Number of bytes decoded by `pm1a_evt_blk` and, if supported, `pm1b_evt_blk`. This value is &ge;4.
362    pub pm1_evt_len: u8,
363    /// Number of bytes decoded by `pm1a_cnt_blk` and, if supported, `pm1b_cnt_blk`. This value is &ge;2.
364    pub pm1_cnt_len: u8,
365    /// Number of bytes decoded by `pm2_cnt_blk`. Support for the PM2 register block is optional. If supported, this value is &ge;1. If not supported, this field contains zero.
366    pub pm2_cnt_len: u8,
367    /// Number of bytes decoded by `pm_tmr_blk`. If the PM Timer is supported, this field's value must be 4. If not supported, this field contains zero.
368    pub pm_tmr_len: u8,
369    /// The length of the register whose address is given by `x_gpe0_blk` (if nonzero) or by `gpe0_blk` (otherwise) in bytes. The value is a non-negative multiple of 2.
370    pub gpe0_blk_len: u8,
371    /// The length of the register whose address is given by `x_gpe1_blk` (if nonzero) or by `gpe1_blk` (otherwise) in bytes. The value is a non-negative multiple of 2.
372    pub gpe1_blk_len: u8,
373    /// Offset within the ACPI general-purpose event model where GPE1 based events start.
374    pub gpe1_base: u8,
375    /// If non-zero, this field contains the value OSPM writes to the SMI_CMD register to indicate OS support for the _CST object and C States Changed notification.
376    pub cst_cnt: u8,
377
378    /// The worst-case hardware latency, in microseconds, to enter and exit a C2 state. A value > 100 indicates the system does not support a C2 state.
379    pub p_lvl2_lat: u16,
380    /// The worst-case hardware latency, in microseconds, to enter and exit a C3 state. A value > 1000 indicates the system does not support a C3 state.
381    pub p_lvl3_lat: u16,
382    /// - If WBINVD=0, the value of this field is the number of flush strides that need to be read (using cacheable addresses) to completely flush dirty lines from any processor's memory caches.
383    ///   - Notice that the value in `flush_stride` is typically the smallest cache line width on any of the processor's caches (for more information, see the `flush_stride` field definition).
384    ///
385    /// - If the system does not support a method for flushing the processor's caches, then `flush_size` and WBINVD are set to zero.
386    ///   - Notice that this method of flushing the processor caches has limitations, and WBINVD=1 is the preferred way to flush the processors caches.
387    ///
388    /// - This value is typically at least 2 times the cache size.
389    ///   - The maximum allowed value for `flush_size` multiplied by `flush_stride` is 2 MB for a typical maximum supported cache size of 1 MB.
390    ///   - Larger cache sizes are supported using WBINVD=1.
391    ///
392    /// - This value is ignored if WBINVD=1.
393    ///
394    /// This field is maintained for ACPI 1.0 processor compatibility on existing systems.
395    /// Processors in new ACPI-compatible systems are required to support the WBINVD function and indicate this to OSPM by setting the WBINVD field = 1.
396    pub flush_size: u16,
397    /// - If WBINVD=0, the value of this field is the cache line width, in bytes, of the processor's memory caches.
398    /// - This value is typically the smallest cache line width on any of the processor's caches. For more information, see the description of the `flush_size` field.
399    /// - This value is ignored if WBINVD=1.
400    ///
401    /// This field is maintained for ACPI 1.0 processor compatibility on existing systems.
402    /// Processors in new ACPI-compatible systems are required to support the WBINVD function and indicate this to OSPM by setting the WBINVD field = 1.
403    pub flush_stride: u16,
404
405    /// The zero-based index of where the processor's duty cycle setting is within the processor's P_CNT register.
406    pub duty_offset: u8,
407    /// The bit width of the processor's duty cycle setting value in the P_CNT register.
408    ///
409    /// Each processor's duty cycle setting allows the software to select a nominal processor frequency below its absolute frequency as defined by:
410    ///
411    /// THTL_EN = 1 ⇒ BF * DC / (2 ^ `duty_width`)
412    ///
413    /// Where:
414    /// - BF-Base frequency
415    /// - DC-Duty cycle setting
416    ///
417    /// When THTL_EN is 0, the processor runs at its absolute BF.
418    /// A `duty_width` value of 0 indicates that processor duty cycle is not supported and the processor continuously runs at its base frequency.
419    pub duty_width: u8,
420    /// The RTC CMOS RAM index to the day-of-month alarm value.
421    ///
422    /// If this field contains a zero, then the RTC day of the month alarm feature is not supported.
423    /// If this field has a non-zero value, then this field contains an index into RTC RAM space that OSPM can use to program the day of the month alarm.
424    /// See Section 4.8.2.4 for a description of how this hardware works.
425    pub day_alrm: u8,
426    /// The RTC CMOS RAM index to the month of year alarm value.
427    ///
428    /// If this field contains a zero, then the RTC month of the year alarm feature is not supported.
429    /// If this field has a non-zero value, then this field contains an index into RTC RAM space that OSPM can use to program the month of the year alarm.
430    /// If this feature is supported, then the DAY_ALRM feature must be supported also.
431    pub mon_alrm: u8,
432    /// The RTC CMOS RAM index to the century of data value (hundred and thousand year decimals).
433    ///
434    /// If this field contains a zero, then the RTC centenary feature is not supported.
435    /// If this field has a non-zero value, then this field contains an index into RTC RAM space that OSPM can use to program the centenary field.
436    pub century: u8,
437
438    /// IA-PC Boot Architecture Flags. See Section 5.2.9.3 for a description of this field.
439    pub iapc_boot_arch: FADTIAPCBootArch,
440    /// Must be 0.
441    reserved: u8,
442    /// Fixed feature flags.
443    pub flags: FADTFixedFeatureFlags,
444    /// The address of the reset register represented in Generic Address Structure format (See Section 4.8.3.6 for a description of the reset mechanism).
445    /// Note: Only System I/O space, System Memory space and PCI Configuration space (bus #0) are valid for values for `address_space_id`.
446    /// Also, `reg_bit_width` must be 8 and `reg_bit_offset` must be 0.
447    pub reset_reg: GenericAddressStructure,
448    /// Indicates the value to write to the RESET_REG port to reset the system (See Section 4.8.3.6 for a description of the reset mechanism).
449    pub reset_value: u8,
450    /// ARM Boot Architecture Flags. See Table 5.12 for a description of this field.
451    pub arm_boot_arch: FADTARMBootArch,
452    /// Minor Version of this FADT structure, in "Major.Minor" form, where 'Major' is the value in the Major Version Field (Byte offset 8 in this table).
453    /// - Bits 0-3 - The low order bits correspond to the minor version of the specification version. For instance, ACPI 6.3 has a major version of 6, and a minor version of 3.
454    /// - Bits 4-7 - The high order bits correspond to the version of the ACPI Specification errata this table complies with. A value of 0 means that it complies with the base version of the current specification.
455    /// A value of 1 means this is compatible with Errata A, 2 would be compatible with Errata B, and so on.
456    pub minor_version: u8,
457
458    /// Extended physical address of the FACS.
459    ///
460    /// If this field contains a nonzero value which can be used by the OSPM, then the `firmware_ctrl` field must be ignored by the OSPM.
461    /// If the HARDWARE_REDUCED_ACPI flag is set, and both this field and the `firmware_ctrl` field are zero, there is no FACS available.
462    pub x_firmware_ctrl: u64,
463    /// Extended physical address of the DSDT.
464    ///
465    /// If this field contains a nonzero value which can be used by the OSPM, then the `dsdt` field must be ignored by the OSPM.
466    pub x_dsdt: u64,
467    /// Extended address of the PM1a Event Register Block, represented in Generic Address Structure format. See Section 4.8.3.1 for a hardware description layout of this register block.
468    ///
469    /// This is a required field. If this field contains a nonzero value which can be used by the OSPM, then the `pm1a_evt_blk` field must be ignored by the OSPM.
470    pub x_pm1a_evt_blk: GenericAddressStructure,
471    /// Extended address of the PM1b Event Register Block, represented in Generic Address Structure format. See Section 4.8.3.1 for a hardware description layout of this register block.
472    ///
473    /// This field is optional; if this register block is not supported, this field contains zero. If this field contains a nonzero value which can be used by the OSPM, then the `pm1b_evt_blk` field must be ignored by the OSPM.
474    pub x_pm1b_evt_blk: GenericAddressStructure,
475    /// Extended address of the PM1a Control Register Block, represented in Generic Address Structure format. See Section 4.8.3.2 for a hardware description layout of this register block.
476    ///
477    /// This is a required field. If this field contains a nonzero value which can be used by the OSPM, then the `pm1a_cnt_blk` field must be ignored by the OSPM.
478    pub x_pm1a_cnt_blk: GenericAddressStructure,
479    /// Extended address of the PM1b Control Register Block, represented in Generic Address Structure format. See Section 4.8.3.2 for a hardware description layout of this register block.
480    ///
481    /// This field is optional; if this register block is not supported, this field contains zero. If this field contains a nonzero value which can be used by the OSPM, then the `pm1b_cnt_blk` field must be ignored by the OSPM.
482    pub x_pm1b_cnt_blk: GenericAddressStructure,
483    /// Extended address of the PM2 Control Register Block, represented in Generic Address Structure format. See PM2 Control (PM2_CNT) for a hardware description layout of this register block.
484    ///
485    /// This field is optional; if this register block is not supported, this field contains zero. If this field contains a nonzero value which can be used by the OSPM, then the `pm2_cnt_blk` field must be ignored by the OSPM.
486    pub x_pm2_cnt_blk: GenericAddressStructure,
487    /// Extended address of the Power Management Timer Control Register Block, represented in Generic Address Structure format. See Section 4.8.3.3 for a hardware description layout of this register block.
488    ///
489    /// This field is optional; if this register block is not supported, this field contains zero. If this field contains a nonzero value which can be used by the OSPM, then the `pm_tmr_blk` field must be ignored by the OSPM.
490    pub x_pm_tmr_blk: GenericAddressStructure,
491    /// Extended address of the General-Purpose Event 0 Register Block, represented in Generic Address Structure format. See Section 4.8.4.1 for more information.
492    ///
493    /// This is an optional field; if this register block is not supported, this field contains zero.
494    /// If this field contains a nonzero value which can be used by the OSPM, then the `gpe0_blk` field must be ignored by the OSPM.
495    ///
496    /// Note: Only System I/O space and System Memory space are valid for `address_space_id` values, and the OSPM ignores `reg_bit_width`, `reg_bit_offset` and `access_size`.
497    pub x_gpe0_blk: GenericAddressStructure,
498    /// Extended address of the General-Purpose Event 1 Register Block, represented in Generic Address Structure format. See Section 4.8.4.1 for more information.
499    ///
500    /// This is an optional field; if this register block is not supported, this field contains zero.
501    /// If this field contains a nonzero value which can be used by the OSPM, then the `gpe1_blk` field must be ignored by the OSPM.
502    ///
503    /// Note: Only System I/O space and System Memory space are valid for `address_space_id` values, and the OSPM ignores `reg_bit_width`, `reg_bit_offset` and `access_size`.
504    pub x_gpe1_blk: GenericAddressStructure,
505
506    /// The address of the Sleep register, represented in Generic Address Structure format (see Section 4.8.3.7 for a description of the sleep mechanism).
507    ///
508    /// Note: Only System I/O space, System Memory space and PCI Configuration space (bus #0) are valid for values for `address_space_id`. Also, `reg_bit_width` must be 8 and `reg_bit_offset` must be 0.
509    pub sleep_control_reg: GenericAddressStructure,
510    /// The address of the Sleep status register, represented in Generic Address Structure format (see Section 4.8.3.7 for a description of the sleep mechanism).
511    ///
512    /// Note: Only System I/O space, System Memory space and PCI Configuration space (bus #0) are valid for values for `address_space_id`. Also, `reg_bit_width` must be 8 and `reg_bit_offset` must be 0.
513    pub sleep_status_reg: GenericAddressStructure,
514
515    /// 64-bit identifier of hypervisor vendor.
516    ///
517    /// All bytes in this field are considered part of the vendor identity.
518    /// These identifiers are defined independently by the vendors themselves, usually following the name of the hypervisor product.<br>
519    /// Version information should NOT be included in this field - this shall simply denote the vendor's name or identifier.
520    /// Version information can be communicated through a supplemental vendor-specific hypervisor API.<br>
521    /// Firmware implementers would place zero bytes into this field, denoting that no hypervisor is present in the actual firmware.
522    pub hypervisor_vendor_identity: u64,
523}