diff --git a/uefi-raw/src/protocol/acpi.rs b/uefi-raw/src/protocol/acpi.rs new file mode 100644 index 000000000..b705d31c7 --- /dev/null +++ b/uefi-raw/src/protocol/acpi.rs @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 + +use crate::{Guid, Status, guid}; +use core::ffi::c_void; + +#[derive(Clone, Copy, Debug)] +#[repr(C)] +pub struct AcpiTableProtocol { + pub install_acpi_table: unsafe extern "efiapi" fn( + this: *const Self, + acpi_table_buffer: *const c_void, + acpi_table_size: usize, + table_key: *mut usize, + ) -> Status, + pub uninstall_acpi_table: + unsafe extern "efiapi" fn(this: *const Self, table_key: usize) -> Status, +} + +impl AcpiTableProtocol { + pub const GUID: Guid = guid!("ffe06bdd-6107-46a6-7bb2-5a9c7ec5275c"); +} diff --git a/uefi-raw/src/protocol/mod.rs b/uefi-raw/src/protocol/mod.rs index e95966275..f634b7ae8 100644 --- a/uefi-raw/src/protocol/mod.rs +++ b/uefi-raw/src/protocol/mod.rs @@ -23,6 +23,7 @@ //! //! [`GUID`]: crate::Guid +pub mod acpi; pub mod ata; pub mod block; pub mod console; diff --git a/uefi/CHANGELOG.md b/uefi/CHANGELOG.md index 397aa4672..c76e7d7d3 100644 --- a/uefi/CHANGELOG.md +++ b/uefi/CHANGELOG.md @@ -7,6 +7,7 @@ - Added `proto::hii::config::ConfigKeywordHandler`. - Added `proto::hii::config::HiiConfigAccess`. - Added `proto::hii::config_str::ConfigurationString`. +- Added `proto::acpi::AcpiTable`. ## Changed - **Breaking:** `boot::stall` now take `core::time::Duration` instead of `usize`. diff --git a/uefi/src/proto/acpi.rs b/uefi/src/proto/acpi.rs new file mode 100644 index 000000000..14b5e2b2f --- /dev/null +++ b/uefi/src/proto/acpi.rs @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 + +//! `AcpiTable` protocol. + +use crate::proto::unsafe_protocol; +use crate::{Result, StatusExt}; +use core::ffi::c_void; +use uefi_raw::protocol::acpi::AcpiTableProtocol; + +/// The AcpiTable protocol. +#[derive(Debug)] +#[repr(transparent)] +#[unsafe_protocol(AcpiTableProtocol::GUID)] +pub struct AcpiTable(AcpiTableProtocol); + +impl AcpiTable { + /// Installs an ACPI table into the RSDT/XSDT. Returns a index + /// that may be used by `uninstall_acpi_table` to remove the ACPI + /// table. + /// + /// # Safety + /// + /// When installing ACPI table, the data pointed to by + /// `acpi_table_ptr` must be a pool allocation of type + /// [`ACPI_RECLAIM`] or other type suitable for data handed off to + /// the OS. + /// + /// [`ACPI_RECLAIM`]: crate::boot::MemoryType::ACPI_RECLAIM + /// + /// # Errors + /// + /// * [`Status::INVALID_PARAMETER`]: `acpi_table_ptr` is null; the + /// `acpi_table_size`, and the size field embedded in the ACPI + /// table are not in sync. + /// + /// * [`Status::OUT_OF_RESOURCES`]: Insufficient resources + /// exist to complete the request. + /// + /// * [`Status::ACCESS_DENIED`]: The table signature matches a + /// table already present in the system and platform policy does + /// not allow duplicate tables of this type. + /// + /// [`Status::INVALID_PARAMETER`]: crate::Status::INVALID_PARAMETER + /// [`Status::OUT_OF_RESOURCES`]: crate::Status::OUT_OF_RESOURCES + /// [`Status::ACCESS_DENIED`]: crate::Status::ACCESS_DENIED + pub unsafe fn install_acpi_table( + &self, + acpi_table_ptr: *const c_void, + acpi_table_size: usize, + ) -> Result { + let mut table_key = 0usize; + let status = unsafe { + (self.0.install_acpi_table)(&self.0, acpi_table_ptr, acpi_table_size, &mut table_key) + }; + status.to_result_with_val(|| table_key) + } + + /// Removes an ACPI table from the RSDT/XSDT. + /// + /// # Errors + /// + /// * [`Status::NOT_FOUND`]: `table_key` does not refer to a + /// valid key for a table entry. + /// + /// * [`Status::OUT_OF_RESOURCES`]: Insufficient resources exist + /// to complete the request. + /// + /// [`Status::NOT_FOUND`]: crate::Status::NOT_FOUND + /// [`Status::OUT_OF_RESOURCES`]: crate::Status::OUT_OF_RESOURCES + pub fn uninstall_acpi_table(&self, table_key: usize) -> Result { + unsafe { (self.0.uninstall_acpi_table)(&self.0, table_key) }.to_result() + } +} diff --git a/uefi/src/proto/mod.rs b/uefi/src/proto/mod.rs index 565f8f73e..4451aa113 100644 --- a/uefi/src/proto/mod.rs +++ b/uefi/src/proto/mod.rs @@ -31,6 +31,7 @@ //! [`boot`]: crate::boot#accessing-protocols //! [UEFI protocols]: uefi_raw::protocol +pub mod acpi; #[cfg(feature = "alloc")] pub mod ata; pub mod console;