diff --git a/uefi-test-runner/src/runtime/vars.rs b/uefi-test-runner/src/runtime/vars.rs index 32b5c0ec2..ebd57e08f 100644 --- a/uefi-test-runner/src/runtime/vars.rs +++ b/uefi-test-runner/src/runtime/vars.rs @@ -117,20 +117,15 @@ fn test_variables_freestanding() { } fn test_variable_info(rt: &RuntimeServices) { - info!( - "Storage for non-volatile boot-services variables: {:?}", - rt.query_variable_info( - VariableAttributes::BOOTSERVICE_ACCESS | VariableAttributes::NON_VOLATILE - ) - .unwrap(), - ); - info!( - "Storage for volatile runtime variables: {:?}", - rt.query_variable_info( - VariableAttributes::BOOTSERVICE_ACCESS | VariableAttributes::RUNTIME_ACCESS - ) - .unwrap(), - ); + let attr = VariableAttributes::BOOTSERVICE_ACCESS | VariableAttributes::NON_VOLATILE; + let info = rt.query_variable_info(attr).unwrap(); + info!("Storage for non-volatile boot-services variables: {info:?}"); + assert_eq!(info, runtime::query_variable_info(attr).unwrap()); + + let attr = VariableAttributes::BOOTSERVICE_ACCESS | VariableAttributes::RUNTIME_ACCESS; + let info = rt.query_variable_info(attr).unwrap(); + info!("Storage for volatile runtime variables: {info:?}"); + assert_eq!(info, runtime::query_variable_info(attr).unwrap()); } pub fn test(rt: &RuntimeServices) { diff --git a/uefi/src/runtime.rs b/uefi/src/runtime.rs index b1f187294..7f62b991b 100644 --- a/uefi/src/runtime.rs +++ b/uefi/src/runtime.rs @@ -5,7 +5,8 @@ //! functions after exiting boot services; see the "Calling Convention" section //! of the UEFI specification for details. -use crate::{table, CStr16, Error, Result, Status, StatusExt}; +use crate::table::{self, Revision}; +use crate::{CStr16, Error, Result, Status, StatusExt}; use core::mem; use core::ptr::{self, NonNull}; @@ -17,7 +18,9 @@ use { #[cfg(all(feature = "unstable", feature = "alloc"))] use alloc::alloc::Global; -pub use crate::table::runtime::{Daylight, Time, TimeCapabilities, TimeError, TimeParams}; +pub use crate::table::runtime::{ + Daylight, Time, TimeCapabilities, TimeError, TimeParams, VariableStorageInfo, +}; pub use uefi_raw::capsule::{CapsuleBlockDescriptor, CapsuleFlags, CapsuleHeader}; pub use uefi_raw::table::runtime::{ResetType, VariableAttributes, VariableVendor}; @@ -343,3 +346,35 @@ pub fn set_variable( pub fn delete_variable(name: &CStr16, vendor: &VariableVendor) -> Result { set_variable(name, vendor, VariableAttributes::empty(), &[]) } + +/// Get information about UEFI variable storage space for the type +/// of variable specified in `attributes`. +/// +/// This operation is only supported starting with UEFI 2.0. +/// +/// See [`VariableStorageInfo`] for details of the information returned. +/// +/// # Errors +/// +/// * [`Status::INVALID_PARAMETER`]: invalid combination of variable attributes. +/// * [`Status::UNSUPPORTED`]: the combination of variable attributes is not +/// supported on this platform, or the UEFI version is less than 2.0. +pub fn query_variable_info(attributes: VariableAttributes) -> Result { + let rt = runtime_services_raw_panicking(); + let rt = unsafe { rt.as_ref() }; + + if rt.header.revision < Revision::EFI_2_00 { + return Err(Status::UNSUPPORTED.into()); + } + + let mut info = VariableStorageInfo::default(); + unsafe { + (rt.query_variable_info)( + attributes, + &mut info.maximum_variable_storage_size, + &mut info.remaining_variable_storage_size, + &mut info.maximum_variable_size, + ) + .to_result_with_val(|| info) + } +}