1 //! UEFI update capsules.
2 //!
3 //! Capsules are used to pass information to the firmware, for example to
4 //! trigger a firmware update.
5 
6 use crate::{Guid, PhysicalAddress};
7 use bitflags::bitflags;
8 
9 /// Descriptor that defines a scatter-gather list for passing a set of capsules
10 /// to the firmware.
11 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
12 #[repr(C)]
13 pub struct CapsuleBlockDescriptor {
14     /// Size in bytes of the data block. If zero, the block is treated as a
15     /// continuation pointer.
16     pub length: u64,
17 
18     /// Either a data block pointer or a continuation pointer.
19     ///
20     /// * If `length` is non-zero, this is the physical address of the data
21     ///   block.
22     /// * If `length` is zero:
23     ///   * If `addr` is non-zero, this is the physical address of another block
24     ///     of `CapsuleBlockDescriptor`.
25     ///   * If `addr` is zero, this entry represents the end of the list.
26     pub address: PhysicalAddress,
27 }
28 
29 bitflags! {
30     /// Capsule update flags.
31     ///
32     /// The meaning of bits `0..=15` are defined by the capsule GUID.
33     #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
34     #[repr(transparent)]
35     pub struct CapsuleFlags: u32 {
36         /// The meaning of this bit depends on the capsule GUID.
37         const TYPE_SPECIFIC_BIT_0 = 1 << 0;
38 
39         /// The meaning of this bit depends on the capsule GUID.
40         const TYPE_SPECIFIC_BIT_1 = 1 << 1;
41 
42         /// The meaning of this bit depends on the capsule GUID.
43         const TYPE_SPECIFIC_BIT_2 = 1 << 2;
44 
45         /// The meaning of this bit depends on the capsule GUID.
46         const TYPE_SPECIFIC_BIT_3 = 1 << 3;
47 
48         /// The meaning of this bit depends on the capsule GUID.
49         const TYPE_SPECIFIC_BIT_4 = 1 << 4;
50 
51         /// The meaning of this bit depends on the capsule GUID.
52         const TYPE_SPECIFIC_BIT_5 = 1 << 5;
53 
54         /// The meaning of this bit depends on the capsule GUID.
55         const TYPE_SPECIFIC_BIT_6 = 1 << 6;
56 
57         /// The meaning of this bit depends on the capsule GUID.
58         const TYPE_SPECIFIC_BIT_7 = 1 << 7;
59 
60         /// The meaning of this bit depends on the capsule GUID.
61         const TYPE_SPECIFIC_BIT_8 = 1 << 8;
62 
63         /// The meaning of this bit depends on the capsule GUID.
64         const TYPE_SPECIFIC_BIT_9 = 1 << 9;
65 
66         /// The meaning of this bit depends on the capsule GUID.
67         const TYPE_SPECIFIC_BIT_10 = 1 << 10;
68 
69         /// The meaning of this bit depends on the capsule GUID.
70         const TYPE_SPECIFIC_BIT_11 = 1 << 11;
71 
72         /// The meaning of this bit depends on the capsule GUID.
73         const TYPE_SPECIFIC_BIT_12 = 1 << 12;
74 
75         /// The meaning of this bit depends on the capsule GUID.
76         const TYPE_SPECIFIC_BIT_13 = 1 << 13;
77 
78         /// The meaning of this bit depends on the capsule GUID.
79         const TYPE_SPECIFIC_BIT_14 = 1 << 14;
80 
81         /// The meaning of this bit depends on the capsule GUID.
82         const TYPE_SPECIFIC_BIT_15 = 1 << 15;
83 
84         /// Indicates the firmware should process the capsule after system reset.
85         const PERSIST_ACROSS_RESET = 1 << 16;
86 
87         /// Causes the contents of the capsule to be coalesced from the
88         /// scatter-gather list into a contiguous buffer, and then a pointer to
89         /// that buffer will be placed in the configuration table after system
90         /// reset.
91         ///
92         /// If this flag is set, [`PERSIST_ACROSS_RESET`] must be set as well.
93         ///
94         /// [`PERSIST_ACROSS_RESET`]: Self::PERSIST_ACROSS_RESET
95         const POPULATE_SYSTEM_TABLE = 1 << 17;
96 
97         /// Trigger a system reset after passing the capsule to the firmware.
98         ///
99         /// If this flag is set, [`PERSIST_ACROSS_RESET`] must be set as well.
100         ///
101         /// [`PERSIST_ACROSS_RESET`]: Self::PERSIST_ACROSS_RESET
102         const INITIATE_RESET = 1 << 18;
103     }
104 }
105 
106 /// Common header at the start of a capsule.
107 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
108 #[repr(C)]
109 pub struct CapsuleHeader {
110     /// GUID that defines the type of data in the capsule.
111     pub capsule_guid: Guid,
112 
113     /// Size in bytes of the capsule header. This may be larger than the size of
114     /// `CapsuleHeader` since the specific capsule type defined by
115     /// [`capsule_guid`] may add additional header fields.
116     ///
117     /// [`capsule_guid`]: Self::capsule_guid
118     pub header_size: u32,
119 
120     /// Capsule update flags.
121     pub flags: CapsuleFlags,
122 
123     /// Size in bytes of the entire capsule, including the header.
124     pub capsule_image_size: u32,
125 }
126