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,
}