td_shim_interface/td_uefi_pi/pi/
hob.rs

1// Copyright © 2019 Intel Corporation
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use core::mem::size_of;
16use core::ptr::slice_from_raw_parts;
17use r_efi::efi::{Guid, PhysicalAddress};
18use scroll::{Pread, Pwrite};
19
20use super::boot_mode::BootMode;
21
22/// GUID for HOB list, defined in [UEFI-PI Spec], section "B.2 HOB List GUID".
23pub const HOB_LIST_GUID: Guid = Guid::from_fields(
24    0x7739F24C,
25    0x93D7,
26    0x11D4,
27    0x9A,
28    0x3A,
29    &[0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D],
30);
31
32/// HOB Generic Header, defined in [UEFI-PI Spec], section 5.2
33///
34/// Describes the format and size of the data inside the HOB. All HOBs must contain this generic
35/// HOB header.
36#[repr(C)]
37#[derive(Copy, Clone, Debug, Pread, Pwrite)]
38pub struct Header {
39    pub r#type: u16,
40    pub length: u16,
41    pub reserved: u32,
42}
43
44impl Header {
45    pub fn dump(&self) {
46        log::info!("Hob:\n");
47        log::info!("  header.type            - 0x{:x}\n", self.r#type);
48        log::info!("  header.length          - 0x{:x}\n", self.length);
49    }
50
51    pub fn as_bytes(&self) -> &[u8] {
52        unsafe { &*slice_from_raw_parts(self as *const Self as *const u8, size_of::<Self>()) }
53    }
54}
55
56pub const HOB_TYPE_HANDOFF: u16 = 0x0001;
57pub const HOB_TYPE_MEMORY_ALLOCATION: u16 = 0x0002;
58pub const HOB_TYPE_RESOURCE_DESCRIPTOR: u16 = 0x0003;
59pub const HOB_TYPE_GUID_EXTENSION: u16 = 0x0004;
60pub const HOB_TYPE_FV: u16 = 0x0005;
61pub const HOB_TYPE_CPU: u16 = 0x0006;
62pub const HOB_TYPE_MEMORY_POOL: u16 = 0x0007;
63pub const HOB_TYPE_FV2: u16 = 0x0009;
64pub const HOB_TYPE_LOAD_PEIM_UNUSED: u16 = 0x000A;
65pub const HOB_TYPE_UEFI_CAPSULE: u16 = 0x000B;
66pub const HOB_TYPE_FV3: u16 = 0x000C;
67pub const HOB_TYPE_UNUSED: u16 = 0xfffe;
68pub const HOB_TYPE_END_OF_HOB_LIST: u16 = 0xffff;
69
70/// HOB Hand Off Information Table, defined in [UEFI-PI Spec], section 5.3
71///
72/// Contains general state information used by the HOB producer phase. This HOB must be the first
73/// one in the HOB list.
74#[repr(C)]
75#[derive(Copy, Clone, Debug, Pread, Pwrite)]
76pub struct HandoffInfoTable {
77    pub header: Header,
78    pub version: u32,
79    pub boot_mode: BootMode,
80    pub efi_memory_top: PhysicalAddress,
81    pub efi_memory_bottom: PhysicalAddress,
82    pub efi_free_memory_top: PhysicalAddress,
83    pub efi_free_memory_bottom: PhysicalAddress,
84    pub efi_end_of_hob_list: PhysicalAddress,
85}
86
87impl HandoffInfoTable {
88    pub fn dump(&self) {
89        log::info!("PhitHob:\n");
90        log::info!("  version                - 0x{:x}\n", self.version);
91        log::info!("  boot_mode              - 0x{:x}\n", self.boot_mode);
92        log::info!(
93            "  efi_memory_top         - 0x{:016x}\n",
94            self.efi_memory_top
95        );
96        log::info!(
97            "  efi_memory_bottom      - 0x{:016x}\n",
98            self.efi_memory_bottom
99        );
100        log::info!(
101            "  efi_free_memory_top    - 0x{:016x}\n",
102            self.efi_free_memory_top
103        );
104        log::info!(
105            "  efi_free_memory_bottom - 0x{:016x}\n",
106            self.efi_free_memory_bottom
107        );
108        log::info!(
109            "  efi_end_of_hob_list    - 0x{:016x}\n",
110            self.efi_end_of_hob_list
111        );
112    }
113
114    pub fn as_bytes(&self) -> &[u8] {
115        unsafe { &*slice_from_raw_parts(self as *const Self as *const u8, size_of::<Self>()) }
116    }
117}
118
119/// Memory Allocation Hob Header, defined in [UEFI-PI Spec], section 5.4
120///
121/// Describes all memory ranges used during the HOB producer phase that exist outside the HOB list.
122/// This HOB type describes how memory is used, not the physical attributes of memory.
123#[repr(C)]
124#[derive(Copy, Clone, Debug, Pread, Pwrite)]
125pub struct MemoryAllocationHeader {
126    pub name: [u8; 16], // Guid
127    pub memory_base_address: PhysicalAddress,
128    pub memory_length: u64,
129    pub memory_type: u32, // MemoryType,
130    pub reserved: [u8; 4],
131}
132
133impl MemoryAllocationHeader {
134    pub fn as_bytes(&self) -> &[u8] {
135        unsafe { &*slice_from_raw_parts(self as *const Self as *const u8, size_of::<Self>()) }
136    }
137}
138
139/// Memory Allocation Hob Entry, defined in [UEFI-PI Spec], section 5.4
140///
141///
142#[repr(C)]
143#[derive(Copy, Clone, Debug, Pread, Pwrite)]
144pub struct MemoryAllocation {
145    pub header: Header,
146    pub alloc_descriptor: MemoryAllocationHeader,
147}
148
149impl MemoryAllocation {
150    pub fn dump(&self) {
151        log::info!(
152            "MemoryAllocation type: 0x{:08x} base: 0x{:016x} length: 0x{:016x}\n",
153            self.alloc_descriptor.memory_type,
154            self.alloc_descriptor.memory_base_address,
155            self.alloc_descriptor.memory_length
156        );
157    }
158
159    pub fn as_bytes(&self) -> &[u8] {
160        unsafe { &*slice_from_raw_parts(self as *const Self as *const u8, size_of::<Self>()) }
161    }
162}
163
164/// Resource Descriptor HOB, defined in [UEFI-PI Spec] section 5.5.
165///
166/// The resource descriptor HOB describes the resource properties of all fixed, nonrelocatable
167/// resource ranges found on the processor host bus during the HOB producer phase. This HOB type
168/// does not describe how memory is used but instead describes the attributes of the physical
169/// memory present.
170#[repr(C)]
171#[derive(Copy, Clone, Debug, Pread, Pwrite)]
172pub struct ResourceDescription {
173    pub header: Header,
174    pub owner: [u8; 16], // Guid
175    pub resource_type: ResourceType,
176    pub resource_attribute: ResourceAttributeType,
177    pub physical_start: PhysicalAddress,
178    pub resource_length: u64,
179}
180
181impl ResourceDescription {
182    pub fn dump(&self) {
183        log::info!(
184            "ResourceDescription type: 0x{:08x} start: 0x{:016x} length: 0x{:016x} attribute: (0x{:08x})\n",
185            self.resource_type,
186            self.physical_start,
187            self.resource_length,
188            self.resource_attribute
189        );
190    }
191
192    pub fn as_bytes(&self) -> &[u8] {
193        unsafe { &*slice_from_raw_parts(self as *const Self as *const u8, size_of::<Self>()) }
194    }
195}
196
197/// Resource Type, defined in [UEFI-PI Spec] section 5.5.
198pub type ResourceType = u32;
199
200pub const RESOURCE_SYSTEM_MEMORY: u32 = 0x00;
201pub const RESOURCE_MEMORY_MAPPED_IO: u32 = 0x01;
202pub const RESOURCE_IO: u32 = 0x02;
203pub const RESOURCE_FIRMWARE_DEVICE: u32 = 0x03;
204pub const RESOURCE_MEMORY_MAPPED_IO_PORT: u32 = 0x04;
205pub const RESOURCE_MEMORY_RESERVED: u32 = 0x05;
206pub const RESOURCE_IO_RESERVED: u32 = 0x06;
207pub const RESOURCE_MEMORY_UNACCEPTED: u32 = 0x00000007;
208pub const RESOURCE_MAX_MEMORY_TYPE: u32 = 0x00000008;
209
210/// Resource Attribute, defined in [UEFI-PI Spec] section 5.5.
211pub type ResourceAttributeType = u32;
212
213pub const RESOURCE_ATTRIBUTE_PRESENT: u32 = 0x00000001;
214pub const RESOURCE_ATTRIBUTE_INITIALIZED: u32 = 0x00000002;
215pub const RESOURCE_ATTRIBUTE_TESTED: u32 = 0x00000004;
216
217pub const RESOURCE_ATTRIBUTE_READ_PROTECTED: u32 = 0x00000080;
218pub const RESOURCE_ATTRIBUTE_WRITE_PROTECTED: u32 = 0x00000100;
219pub const RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED: u32 = 0x00000200;
220
221pub const RESOURCE_ATTRIBUTE_PERSISTENT: u32 = 0x00800000;
222pub const RESOURCE_ATTRIBUTE_MORE_RELIABLE: u32 = 0x02000000;
223
224pub const RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC: u32 = 0x00000008;
225pub const RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC: u32 = 0x00000010;
226pub const RESOURCE_ATTRIBUTE_ECC_RESERVED_1: u32 = 0x00000020;
227pub const RESOURCE_ATTRIBUTE_ECC_RESERVED_2: u32 = 0x00000040;
228
229pub const RESOURCE_ATTRIBUTE_UNCACHEABLE: u32 = 0x00000400;
230pub const RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE: u32 = 0x00000800;
231pub const RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE: u32 = 0x00001000;
232pub const RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE: u32 = 0x00002000;
233
234pub const RESOURCE_ATTRIBUTE_16_BIT_IO: u32 = 0x00004000;
235pub const RESOURCE_ATTRIBUTE_32_BIT_IO: u32 = 0x00008000;
236pub const RESOURCE_ATTRIBUTE_64_BIT_IO: u32 = 0x00010000;
237
238pub const RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED: u32 = 0x00020000;
239pub const RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED: u32 = 0x00040000;
240
241pub const RESOURCE_ATTRIBUTE_READ_PROTECTABLE: u32 = 0x00100000;
242pub const RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE: u32 = 0x00200000;
243pub const RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE: u32 = 0x00400000;
244
245pub const RESOURCE_ATTRIBUTE_PERSISTABLE: u32 = 0x01000000;
246pub const RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE: u32 = 0x00080000;
247
248// Physical memory encrypted attribute.
249pub const EFI_RESOURCE_ATTRIBUTE_ENCRYPTED: u32 = 0x04000000;
250
251// All the attributes above
252pub const RESOURCE_ATTRIBUTE_ALL: u32 = 0x07ffffff;
253
254/// Firmware Volume HOB, defined in [UEFI-PI Spec], section 5.7
255///
256/// Details the location of firmware volumes that contain firmware files.
257#[repr(C)]
258#[derive(Copy, Clone, Debug, Pread, Pwrite)]
259pub struct FirmwareVolume {
260    pub header: Header,
261    pub base_address: PhysicalAddress,
262    pub length: u64,
263}
264
265impl FirmwareVolume {
266    pub fn dump(&self) {
267        log::info!(
268            "FirmwareVolume base: 0x{:016x} length: 0x{:016x}\n",
269            self.base_address,
270            self.length
271        );
272    }
273
274    pub fn as_bytes(&self) -> &[u8] {
275        unsafe { &*slice_from_raw_parts(self as *const Self as *const u8, size_of::<Self>()) }
276    }
277}
278
279/// Firmware Volume 2 HOB, defined in [UEFI-PI Spec], section 5.7
280///
281/// Details the location of a firmware volume which was extracted from a file within another
282/// firmware volume.
283#[repr(C)]
284#[derive(Copy, Clone, Debug, Pread, Pwrite)]
285pub struct FirmwareVolume2 {
286    pub header: Header,
287    pub base_address: PhysicalAddress,
288    pub length: u64,
289    pub fv_name: [u8; 16],   // Guid
290    pub file_name: [u8; 16], // Guid
291}
292
293impl FirmwareVolume2 {
294    pub fn as_bytes(&self) -> &[u8] {
295        unsafe { &*slice_from_raw_parts(self as *const Self as *const u8, size_of::<Self>()) }
296    }
297}
298
299/// Firmware Volume 3 HOB, defined in [UEFI-PI Spec], section 5.7
300///
301/// Details the location of a firmware volume including authentication information, for both
302/// standalone and extracted firmware volumes.
303#[repr(C)]
304#[derive(Copy, Clone, Debug, Pread, Pwrite)]
305pub struct FirmwareVolume3 {
306    pub header: Header,
307    pub base_address: PhysicalAddress,
308    pub length: u64,
309    pub authentication_status: u32,
310    pub extracted_fv: u8,    // Boolean
311    pub fv_name: [u8; 16],   // Guid
312    pub file_name: [u8; 16], // Guid
313}
314
315impl FirmwareVolume3 {
316    pub fn as_bytes(&self) -> &[u8] {
317        unsafe { &*slice_from_raw_parts(self as *const Self as *const u8, size_of::<Self>()) }
318    }
319}
320
321/// CPU HOB, defined in [UEFI-PI Spec], section 5.8
322///
323///
324/// Describes processor information, such as address space and I/O space capabilities.
325#[repr(C)]
326#[derive(Copy, Clone, Debug, Pread, Pwrite)]
327pub struct Cpu {
328    pub header: Header,
329    pub size_of_memory_space: u8,
330    pub size_of_io_space: u8,
331    pub reserved: [u8; 6],
332}
333
334impl Cpu {
335    pub fn dump(&self) {
336        log::info!(
337            "Cpu : mem size {} , io size {}\n",
338            self.size_of_memory_space,
339            self.size_of_io_space
340        );
341    }
342
343    pub fn as_bytes(&self) -> &[u8] {
344        unsafe { &*slice_from_raw_parts(self as *const Self as *const u8, size_of::<Self>()) }
345    }
346}
347
348/// GUID Extension HOB, defined in [UEFI-PI Spec], section 5.6
349///
350/// Allows writers of executable content in the HOB producer phase to maintain and manage HOBs
351/// whose types are not included in this specification. Specifically, writers of executable content
352/// in the HOB producer phase can generate a GUID and name their own HOB entries using this
353/// module specific value.
354#[repr(C)]
355#[derive(Copy, Clone, Debug, Pread, Pwrite)]
356pub struct GuidExtension {
357    pub header: Header,
358    pub name: [u8; 16], // Guid
359}
360
361impl GuidExtension {
362    pub fn as_bytes(&self) -> &[u8] {
363        unsafe { &*slice_from_raw_parts(self as *const Self as *const u8, size_of::<Self>()) }
364    }
365}
366
367#[cfg(test)]
368mod tests {
369    use core::mem::size_of;
370
371    use super::*;
372
373    #[test]
374    fn test_size_of_struct() {
375        assert_eq!(size_of::<Header>(), 8);
376        assert_eq!(size_of::<HandoffInfoTable>(), 56);
377        assert_eq!(size_of::<MemoryAllocation>(), 48);
378        assert_eq!(size_of::<ResourceDescription>(), 48);
379        assert_eq!(size_of::<FirmwareVolume>(), 24);
380        assert_eq!(size_of::<FirmwareVolume2>(), 56);
381        assert_eq!(size_of::<FirmwareVolume3>(), 64);
382        assert_eq!(size_of::<Cpu>(), 16);
383        assert_eq!(size_of::<GuidExtension>(), 24);
384    }
385}