|
5 | 5 | //! functions after exiting boot services; see the "Calling Convention" section
|
6 | 6 | //! of the UEFI specification for details.
|
7 | 7 |
|
| 8 | +use crate::data_types::PhysicalAddress; |
8 | 9 | use crate::table::{self, Revision};
|
9 | 10 | use crate::{CStr16, Error, Result, Status, StatusExt};
|
10 | 11 | use core::mem;
|
|
19 | 20 | use alloc::alloc::Global;
|
20 | 21 |
|
21 | 22 | pub use crate::table::runtime::{
|
22 |
| - Daylight, Time, TimeCapabilities, TimeError, TimeParams, VariableStorageInfo, |
| 23 | + CapsuleInfo, Daylight, Time, TimeCapabilities, TimeError, TimeParams, VariableStorageInfo, |
23 | 24 | };
|
24 | 25 | pub use uefi_raw::capsule::{CapsuleBlockDescriptor, CapsuleFlags, CapsuleHeader};
|
25 | 26 | pub use uefi_raw::table::runtime::{ResetType, VariableAttributes, VariableVendor};
|
@@ -378,3 +379,67 @@ pub fn query_variable_info(attributes: VariableAttributes) -> Result<VariableSto
|
378 | 379 | .to_result_with_val(|| info)
|
379 | 380 | }
|
380 | 381 | }
|
| 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