1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
//! 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,
}