//! UEFI update capsules. //! //! Capsules are used to pass information to the firmware, for example to //! trigger a firmware update. use crate::{Guid, PhysicalAddress}; use bitflags::bitflags; /// Descriptor that defines a scatter-gather list for passing a set of capsules /// to the firmware. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(C)] pub struct CapsuleBlockDescriptor { /// Size in bytes of the data block. If zero, the block is treated as a /// continuation pointer. pub length: u64, /// Either a data block pointer or a continuation pointer. /// /// * If `length` is non-zero, this is the physical address of the data /// block. /// * If `length` is zero: /// * If `addr` is non-zero, this is the physical address of another block /// of `CapsuleBlockDescriptor`. /// * If `addr` is zero, this entry represents the end of the list. pub address: PhysicalAddress, } bitflags! { /// Capsule update flags. /// /// The meaning of bits `0..=15` are defined by the capsule GUID. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pub struct CapsuleFlags: u32 { /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_0 = 1 << 0; /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_1 = 1 << 1; /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_2 = 1 << 2; /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_3 = 1 << 3; /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_4 = 1 << 4; /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_5 = 1 << 5; /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_6 = 1 << 6; /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_7 = 1 << 7; /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_8 = 1 << 8; /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_9 = 1 << 9; /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_10 = 1 << 10; /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_11 = 1 << 11; /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_12 = 1 << 12; /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_13 = 1 << 13; /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_14 = 1 << 14; /// The meaning of this bit depends on the capsule GUID. const TYPE_SPECIFIC_BIT_15 = 1 << 15; /// Indicates the firmware should process the capsule after system reset. const PERSIST_ACROSS_RESET = 1 << 16; /// Causes the contents of the capsule to be coalesced from the /// scatter-gather list into a contiguous buffer, and then a pointer to /// that buffer will be placed in the configuration table after system /// reset. /// /// If this flag is set, [`PERSIST_ACROSS_RESET`] must be set as well. /// /// [`PERSIST_ACROSS_RESET`]: Self::PERSIST_ACROSS_RESET const POPULATE_SYSTEM_TABLE = 1 << 17; /// Trigger a system reset after passing the capsule to the firmware. /// /// If this flag is set, [`PERSIST_ACROSS_RESET`] must be set as well. /// /// [`PERSIST_ACROSS_RESET`]: Self::PERSIST_ACROSS_RESET const INITIATE_RESET = 1 << 18; } } /// Common header at the start of a capsule. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(C)] pub struct CapsuleHeader { /// GUID that defines the type of data in the capsule. pub capsule_guid: Guid, /// Size in bytes of the capsule header. This may be larger than the size of /// `CapsuleHeader` since the specific capsule type defined by /// [`capsule_guid`] may add additional header fields. /// /// [`capsule_guid`]: Self::capsule_guid pub header_size: u32, /// Capsule update flags. pub flags: CapsuleFlags, /// Size in bytes of the entire capsule, including the header. pub capsule_image_size: u32, }