diff --git a/src/acpi/fadt.rs b/src/acpi/fadt.rs index eada983710..4c55b500bf 100644 --- a/src/acpi/fadt.rs +++ b/src/acpi/fadt.rs @@ -70,19 +70,16 @@ pub fn init(sdt: &Sdt) { if &sdt.signature != &FADT_SIGNATURE { return; } - // SAFETY: We trust the ACPI table discovery code to have - // verified the FADT checksum. The FADT fields are at fixed - // offsets (per the ACPI spec); reading them as u32/u64 is - // safe because all of them are at 4-byte or 8-byte aligned - // offsets on x86_64. - let data = sdt.data_address() as *const u8; + // The FADT fields are at fixed offsets from the start of the + // SDT (including the 36-byte header), not from the data area. + let base = sdt as *const _ as *const u8; unsafe { // PM1a_CNT is at offset 56 in the FADT (ACPI 6.5 ยง5.2.9 // Table 5.6). 32-bit General-Purpose Event Register Block 0 // Address. - let pm1a_cnt = core::ptr::read_unaligned(data.add(offsets::PM1A_CNT) as *const u32); + let pm1a_cnt = core::ptr::read_unaligned(base.add(offsets::PM1A_CNT) as *const u32); // PM1a_STS is at offset 48 in the FADT. - let pm1a_sts = core::ptr::read_unaligned(data.add(offsets::PM1A_STS) as *const u32); + let pm1a_sts = core::ptr::read_unaligned(base.add(offsets::PM1A_STS) as *const u32); // Convert u32 to u16 (port numbers are 16-bit). The low // 16 bits are the IO port; the high 16 bits are the // address-space ID which we ignore (always IO on x86). @@ -98,18 +95,18 @@ pub fn init(sdt: &Sdt) { // Phase II.X.W: 32-bit FACS address (FADT offset 36, // `firmware_ctrl` field). ACPI 1.0+. let firmware_ctrl = core::ptr::read_unaligned( - data.add(offsets::FIRMWARE_CTRL_32) as *const u32, + base.add(offsets::FIRMWARE_CTRL_32) as *const u32, ); FIRMWARE_CTRL.store(firmware_ctrl, core::sync::atomic::Ordering::Release); // Phase II.X.W: 64-bit FACS address (FADT offset 140, - // `x_firmware_ctrl` field). ACPI 2.0+. We require the + // `x_firmware_ctrl` field, ACPI 2.0+). We require the // FADT to be at least 148 bytes to have this field // (the field is at offset 140, which is 8 bytes for the // u64, so the minimum FADT size is 148 bytes). if sdt.length() >= offsets::FADT_MIN_SIZE_ACPI_2_0 as u32 { let x_firmware_ctrl = core::ptr::read_unaligned( - data.add(offsets::X_FIRMWARE_CTRL_64) as *const u64, + base.add(offsets::X_FIRMWARE_CTRL_64) as *const u64, ); X_FIRMWARE_CTRL.store(x_firmware_ctrl, core::sync::atomic::Ordering::Release); }