Skip to content

Commit 1925c23

Browse files
Add capsule update functions to uefi::freestanding
No tests for these since QEMU+OVMF doesn't support firmware update testing currently.
1 parent b4c9a82 commit 1925c23

File tree

1 file changed

+66
-1
lines changed

1 file changed

+66
-1
lines changed

uefi/src/runtime.rs

+66-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//! functions after exiting boot services; see the "Calling Convention" section
66
//! of the UEFI specification for details.
77
8+
use crate::data_types::PhysicalAddress;
89
use crate::table::{self, Revision};
910
use crate::{CStr16, Error, Result, Status, StatusExt};
1011
use core::mem;
@@ -19,7 +20,7 @@ use {
1920
use alloc::alloc::Global;
2021

2122
pub use crate::table::runtime::{
22-
Daylight, Time, TimeCapabilities, TimeError, TimeParams, VariableStorageInfo,
23+
CapsuleInfo, Daylight, Time, TimeCapabilities, TimeError, TimeParams, VariableStorageInfo,
2324
};
2425
pub use uefi_raw::capsule::{CapsuleBlockDescriptor, CapsuleFlags, CapsuleHeader};
2526
pub use uefi_raw::table::runtime::{ResetType, VariableAttributes, VariableVendor};
@@ -378,3 +379,67 @@ pub fn query_variable_info(attributes: VariableAttributes) -> Result<VariableSto
378379
.to_result_with_val(|| info)
379380
}
380381
}
382+
383+
/// Passes capsules to the firmware.
384+
///
385+
/// Capsules are most commonly used to update system firmware.
386+
///
387+
/// # Errors
388+
///
389+
/// * [`Status::INVALID_PARAMETER`]: zero capsules were provided, or the
390+
/// capsules are invalid.
391+
/// * [`Status::DEVICE_ERROR`]: the capsule update was started but failed to a
392+
/// device error.
393+
/// * [`Status::OUT_OF_RESOURCES`]: before exiting boot services, indicates the
394+
/// capsule is compatible with the platform but there are insufficient
395+
/// resources to complete the update. After exiting boot services, indicates
396+
/// the capsule is compatible with the platform but can only be processed
397+
/// before exiting boot services.
398+
/// * [`Status::UNSUPPORTED`]: this platform does not support capsule updates
399+
/// after exiting boot services.
400+
pub fn update_capsule(
401+
capsule_header_array: &[&CapsuleHeader],
402+
capsule_block_descriptors: &[CapsuleBlockDescriptor],
403+
) -> Result {
404+
let rt = runtime_services_raw_panicking();
405+
let rt = unsafe { rt.as_ref() };
406+
407+
unsafe {
408+
(rt.update_capsule)(
409+
capsule_header_array.as_ptr().cast(),
410+
capsule_header_array.len(),
411+
capsule_block_descriptors.as_ptr() as PhysicalAddress,
412+
)
413+
.to_result()
414+
}
415+
}
416+
417+
/// Tests whether a capsule or capsules can be updated via [`update_capsule`].
418+
///
419+
/// See [`CapsuleInfo`] for details of the information returned.
420+
///
421+
/// # Errors
422+
///
423+
/// * [`Status::OUT_OF_RESOURCES`]: before exiting boot services, indicates the
424+
/// capsule is compatible with the platform but there are insufficient
425+
/// resources to complete the update. After exiting boot services, indicates
426+
/// the capsule is compatible with the platform but can only be processed
427+
/// before exiting boot services.
428+
/// * [`Status::UNSUPPORTED`]: either the capsule type is not supported by this
429+
/// platform, or the platform does not support capsule updates after exiting
430+
/// boot services.
431+
pub fn query_capsule_capabilities(capsule_header_array: &[&CapsuleHeader]) -> Result<CapsuleInfo> {
432+
let rt = runtime_services_raw_panicking();
433+
let rt = unsafe { rt.as_ref() };
434+
435+
let mut info = CapsuleInfo::default();
436+
unsafe {
437+
(rt.query_capsule_capabilities)(
438+
capsule_header_array.as_ptr().cast(),
439+
capsule_header_array.len(),
440+
&mut info.maximum_capsule_size,
441+
&mut info.reset_type,
442+
)
443+
.to_result_with_val(|| info)
444+
}
445+
}

0 commit comments

Comments
 (0)