Skip to main content

intelflash/
file.rs

1// SPDX-License-Identifier: MIT
2
3use bitflags::bitflags;
4use plain::Plain;
5use uefi::guid::Guid;
6
7#[derive(Debug)]
8pub enum HeaderKind {
9    Raw,
10    Freeform,
11    SecurityCore,
12    PeiCore,
13    DxeCore,
14    Peim,
15    Driver,
16    CombinedPeimDriver,
17    Application,
18    Mm,
19    VolumeImage,
20    CombinedMmDxe,
21    MmCore,
22    MmStandalone,
23    MmCoreStandalone,
24    Oem(u8),
25    Debug(u8),
26    Ffs(u8),
27    Unknown(u8)
28}
29
30bitflags! {
31    pub struct Attributes: u8 {
32        const ATTRIB_TAIL_PRESENT = 0x01;
33        const ATTRIB_RECOVERY = 0x02;
34        const ATTRIB_HEADER_EXTENSION = 0x04;
35        const ATTRIB_CHECKSUM = 0x40;
36    }
37}
38
39bitflags! {
40    pub struct State: u8 {
41        const STATE_HEADER_CONSTRUCTION = 0x01;
42        const STATE_HEADER_VALID = 0x02;
43        const STATE_DATA_VALID = 0x04;
44        const STATE_MARKED_FOR_UPDATE = 0x08;
45        const STATE_DELETED = 0x10;
46        const STATE_HEADER_INVALID = 0x20;
47    }
48}
49
50#[repr(packed)]
51pub struct Header {
52    pub guid: Guid,
53    pub integrity_check: u16,
54    kind: u8,
55    attributes: u8,
56    size: [u8; 3],
57    state: u8,
58}
59
60impl Header {
61    pub fn kind(&self) -> HeaderKind {
62        match self.kind {
63            0x01 => HeaderKind::Raw,
64            0x02 => HeaderKind::Freeform,
65            0x03 => HeaderKind::SecurityCore,
66            0x04 => HeaderKind::PeiCore,
67            0x05 => HeaderKind::DxeCore,
68            0x06 => HeaderKind::Peim,
69            0x07 => HeaderKind::Driver,
70            0x08 => HeaderKind::CombinedPeimDriver,
71            0x09 => HeaderKind::Application,
72            0x0A => HeaderKind::Mm,
73            0x0B => HeaderKind::VolumeImage,
74            0x0C => HeaderKind::CombinedMmDxe,
75            0x0D => HeaderKind::MmCore,
76            0x0E => HeaderKind::MmStandalone,
77            0x0F => HeaderKind::MmCoreStandalone,
78            oem @ 0xC0..=0xDF => HeaderKind::Oem(oem),
79            debug @ 0xE0..=0xEF => HeaderKind::Debug(debug),
80            ffs @ 0xF0..=0xFF => HeaderKind::Ffs(ffs),
81            unknown => HeaderKind::Unknown(unknown)
82        }
83    }
84
85    pub fn size(&self) -> usize {
86        self.size[0] as usize | (self.size[1] as usize) << 8 | (self.size[2] as usize) << 16
87    }
88
89    pub fn attributes(&self) -> Attributes {
90        Attributes::from_bits_truncate(self.attributes)
91    }
92
93    pub fn alignment(&self) -> u8 {
94        (self.attributes & 0x38) >> 3
95    }
96
97    pub fn state(&self, polarity: bool) -> State {
98        State::from_bits_truncate(if polarity {
99            ! self.state
100        } else {
101            self.state
102        })
103    }
104
105    pub fn sectioned(&self) -> bool {
106        match self.kind() {
107            HeaderKind::Raw => false,
108            HeaderKind::Freeform => true,
109            HeaderKind::SecurityCore => false,
110            HeaderKind::PeiCore => true,
111            HeaderKind::DxeCore => true,
112            HeaderKind::Peim => true,
113            HeaderKind::Driver => true,
114            HeaderKind::CombinedPeimDriver => true,
115            HeaderKind::Application => true,
116            HeaderKind::Mm => true,
117            HeaderKind::VolumeImage => true,
118            HeaderKind::CombinedMmDxe => true,
119            HeaderKind::MmCore => true,
120            HeaderKind::MmStandalone => true,
121            HeaderKind::MmCoreStandalone => false,
122            HeaderKind::Oem(_oem) => false,
123            HeaderKind::Debug(_debug) => false,
124            HeaderKind::Ffs(_ffs) => false,
125            HeaderKind::Unknown(_unknown) => false
126        }
127    }
128}
129
130unsafe impl Plain for Header {}