diff --git a/uefi-raw/src/table/boot.rs b/uefi-raw/src/table/boot.rs index e3a10ff6b..9de16cd4e 100644 --- a/uefi-raw/src/table/boot.rs +++ b/uefi-raw/src/table/boot.rs @@ -1,5 +1,147 @@ //! UEFI services available during boot. +use crate::{PhysicalAddress, VirtualAddress}; +use bitflags::bitflags; + +bitflags! { + /// Flags describing the capabilities of a memory range. + #[repr(transparent)] + pub struct MemoryAttribute: u64 { + /// Supports marking as uncacheable. + const UNCACHEABLE = 0x1; + /// Supports write-combining. + const WRITE_COMBINE = 0x2; + /// Supports write-through. + const WRITE_THROUGH = 0x4; + /// Support write-back. + const WRITE_BACK = 0x8; + /// Supports marking as uncacheable, exported and + /// supports the "fetch and add" semaphore mechanism. + const UNCACHABLE_EXPORTED = 0x10; + /// Supports write-protection. + const WRITE_PROTECT = 0x1000; + /// Supports read-protection. + const READ_PROTECT = 0x2000; + /// Supports disabling code execution. + const EXECUTE_PROTECT = 0x4000; + /// Persistent memory. + const NON_VOLATILE = 0x8000; + /// This memory region is more reliable than other memory. + const MORE_RELIABLE = 0x10000; + /// This memory range can be set as read-only. + const READ_ONLY = 0x20000; + /// This memory is earmarked for specific purposes such as for specific + /// device drivers or applications. This serves as a hint to the OS to + /// avoid this memory for core OS data or code that cannot be relocated. + const SPECIAL_PURPOSE = 0x4_0000; + /// This memory region is capable of being protected with the CPU's memory + /// cryptography capabilities. + const CPU_CRYPTO = 0x8_0000; + /// This memory must be mapped by the OS when a runtime service is called. + const RUNTIME = 0x8000_0000_0000_0000; + /// This memory region is described with additional ISA-specific memory + /// attributes as specified in `MemoryAttribute::ISA_MASK`. + const ISA_VALID = 0x4000_0000_0000_0000; + /// These bits are reserved for describing optional ISA-specific cache- + /// ability attributes that are not covered by the standard UEFI Memory + /// Attribute cacheability bits such as `UNCACHEABLE`, `WRITE_COMBINE`, + /// `WRITE_THROUGH`, `WRITE_BACK`, and `UNCACHEABLE_EXPORTED`. + /// + /// See Section 2.3 "Calling Conventions" in the UEFI Specification + /// for further information on each ISA that takes advantage of this. + const ISA_MASK = 0x0FFF_F000_0000_0000; + } +} + +/// A structure describing a region of memory. +#[derive(Debug, Copy, Clone)] +#[repr(C)] +pub struct MemoryDescriptor { + /// Type of memory occupying this range. + pub ty: MemoryType, + /// Starting physical address. + pub phys_start: PhysicalAddress, + /// Starting virtual address. + pub virt_start: VirtualAddress, + /// Number of 4 KiB pages contained in this range. + pub page_count: u64, + /// The capability attributes of this memory range. + pub att: MemoryAttribute, +} + +impl MemoryDescriptor { + /// Memory descriptor version number. + pub const VERSION: u32 = 1; +} + +impl Default for MemoryDescriptor { + fn default() -> MemoryDescriptor { + MemoryDescriptor { + ty: MemoryType::RESERVED, + phys_start: 0, + virt_start: 0, + page_count: 0, + att: MemoryAttribute::empty(), + } + } +} + +newtype_enum! { +/// The type of a memory range. +/// +/// UEFI allows firmwares and operating systems to introduce new memory types +/// in the 0x70000000..0xFFFFFFFF range. Therefore, we don't know the full set +/// of memory types at compile time, and it is _not_ safe to model this C enum +/// as a Rust enum. +pub enum MemoryType: u32 => { + /// This enum variant is not used. + RESERVED = 0, + /// The code portions of a loaded UEFI application. + LOADER_CODE = 1, + /// The data portions of a loaded UEFI applications, + /// as well as any memory allocated by it. + LOADER_DATA = 2, + /// Code of the boot drivers. + /// + /// Can be reused after OS is loaded. + BOOT_SERVICES_CODE = 3, + /// Memory used to store boot drivers' data. + /// + /// Can be reused after OS is loaded. + BOOT_SERVICES_DATA = 4, + /// Runtime drivers' code. + RUNTIME_SERVICES_CODE = 5, + /// Runtime services' code. + RUNTIME_SERVICES_DATA = 6, + /// Free usable memory. + CONVENTIONAL = 7, + /// Memory in which errors have been detected. + UNUSABLE = 8, + /// Memory that holds ACPI tables. + /// Can be reclaimed after they are parsed. + ACPI_RECLAIM = 9, + /// Firmware-reserved addresses. + ACPI_NON_VOLATILE = 10, + /// A region used for memory-mapped I/O. + MMIO = 11, + /// Address space used for memory-mapped port I/O. + MMIO_PORT_SPACE = 12, + /// Address space which is part of the processor. + PAL_CODE = 13, + /// Memory region which is usable and is also non-volatile. + PERSISTENT_MEMORY = 14, +}} + +impl MemoryType { + /// Construct a custom `MemoryType`. Values in the range `0x80000000..=0xffffffff` are free for use if you are + /// an OS loader. + #[must_use] + pub const fn custom(value: u32) -> MemoryType { + assert!(value >= 0x80000000); + MemoryType(value) + } +} + newtype_enum! { /// Task priority level. /// diff --git a/uefi/src/table/boot.rs b/uefi/src/table/boot.rs index d3efa7b0a..aa5d5871d 100644 --- a/uefi/src/table/boot.rs +++ b/uefi/src/table/boot.rs @@ -1,7 +1,7 @@ //! UEFI services available during boot. use super::{Header, Revision}; -use crate::data_types::{Align, PhysicalAddress, VirtualAddress}; +use crate::data_types::{Align, PhysicalAddress}; use crate::proto::device_path::{DevicePath, FfiDevicePath}; use crate::proto::{Protocol, ProtocolPointer}; use crate::{Char16, Event, Guid, Handle, Result, Status, StatusExt}; @@ -20,7 +20,7 @@ use { ::alloc::vec::Vec, }; -pub use uefi_raw::table::boot::Tpl; +pub use uefi_raw::table::boot::{MemoryAttribute, MemoryDescriptor, MemoryType, Tpl}; // TODO: this similar to `SyncUnsafeCell`. Once that is stabilized we // can use it instead. @@ -1814,151 +1814,12 @@ pub enum AllocateType { Address(PhysicalAddress), } -newtype_enum! { -/// The type of a memory range. -/// -/// UEFI allows firmwares and operating systems to introduce new memory types -/// in the 0x70000000..0xFFFFFFFF range. Therefore, we don't know the full set -/// of memory types at compile time, and it is _not_ safe to model this C enum -/// as a Rust enum. -pub enum MemoryType: u32 => { - /// This enum variant is not used. - RESERVED = 0, - /// The code portions of a loaded UEFI application. - LOADER_CODE = 1, - /// The data portions of a loaded UEFI applications, - /// as well as any memory allocated by it. - LOADER_DATA = 2, - /// Code of the boot drivers. - /// - /// Can be reused after OS is loaded. - BOOT_SERVICES_CODE = 3, - /// Memory used to store boot drivers' data. - /// - /// Can be reused after OS is loaded. - BOOT_SERVICES_DATA = 4, - /// Runtime drivers' code. - RUNTIME_SERVICES_CODE = 5, - /// Runtime services' code. - RUNTIME_SERVICES_DATA = 6, - /// Free usable memory. - CONVENTIONAL = 7, - /// Memory in which errors have been detected. - UNUSABLE = 8, - /// Memory that holds ACPI tables. - /// Can be reclaimed after they are parsed. - ACPI_RECLAIM = 9, - /// Firmware-reserved addresses. - ACPI_NON_VOLATILE = 10, - /// A region used for memory-mapped I/O. - MMIO = 11, - /// Address space used for memory-mapped port I/O. - MMIO_PORT_SPACE = 12, - /// Address space which is part of the processor. - PAL_CODE = 13, - /// Memory region which is usable and is also non-volatile. - PERSISTENT_MEMORY = 14, -}} - -impl MemoryType { - /// Construct a custom `MemoryType`. Values in the range `0x80000000..=0xffffffff` are free for use if you are - /// an OS loader. - #[must_use] - pub const fn custom(value: u32) -> MemoryType { - assert!(value >= 0x80000000); - MemoryType(value) - } -} - -/// A structure describing a region of memory. -#[derive(Debug, Copy, Clone)] -#[repr(C)] -pub struct MemoryDescriptor { - /// Type of memory occupying this range. - pub ty: MemoryType, - /// Starting physical address. - pub phys_start: PhysicalAddress, - /// Starting virtual address. - pub virt_start: VirtualAddress, - /// Number of 4 KiB pages contained in this range. - pub page_count: u64, - /// The capability attributes of this memory range. - pub att: MemoryAttribute, -} - -impl MemoryDescriptor { - /// Memory descriptor version number. - pub const VERSION: u32 = 1; -} - -impl Default for MemoryDescriptor { - fn default() -> MemoryDescriptor { - MemoryDescriptor { - ty: MemoryType::RESERVED, - phys_start: 0, - virt_start: 0, - page_count: 0, - att: MemoryAttribute::empty(), - } - } -} - impl Align for MemoryDescriptor { fn alignment() -> usize { mem::align_of::() } } -bitflags! { - /// Flags describing the capabilities of a memory range. - #[repr(transparent)] - pub struct MemoryAttribute: u64 { - /// Supports marking as uncacheable. - const UNCACHEABLE = 0x1; - /// Supports write-combining. - const WRITE_COMBINE = 0x2; - /// Supports write-through. - const WRITE_THROUGH = 0x4; - /// Support write-back. - const WRITE_BACK = 0x8; - /// Supports marking as uncacheable, exported and - /// supports the "fetch and add" semaphore mechanism. - const UNCACHABLE_EXPORTED = 0x10; - /// Supports write-protection. - const WRITE_PROTECT = 0x1000; - /// Supports read-protection. - const READ_PROTECT = 0x2000; - /// Supports disabling code execution. - const EXECUTE_PROTECT = 0x4000; - /// Persistent memory. - const NON_VOLATILE = 0x8000; - /// This memory region is more reliable than other memory. - const MORE_RELIABLE = 0x10000; - /// This memory range can be set as read-only. - const READ_ONLY = 0x20000; - /// This memory is earmarked for specific purposes such as for specific - /// device drivers or applications. This serves as a hint to the OS to - /// avoid this memory for core OS data or code that cannot be relocated. - const SPECIAL_PURPOSE = 0x4_0000; - /// This memory region is capable of being protected with the CPU's memory - /// cryptography capabilities. - const CPU_CRYPTO = 0x8_0000; - /// This memory must be mapped by the OS when a runtime service is called. - const RUNTIME = 0x8000_0000_0000_0000; - /// This memory region is described with additional ISA-specific memory - /// attributes as specified in `MemoryAttribute::ISA_MASK`. - const ISA_VALID = 0x4000_0000_0000_0000; - /// These bits are reserved for describing optional ISA-specific cache- - /// ability attributes that are not covered by the standard UEFI Memory - /// Attribute cacheability bits such as `UNCACHEABLE`, `WRITE_COMBINE`, - /// `WRITE_THROUGH`, `WRITE_BACK`, and `UNCACHEABLE_EXPORTED`. - /// - /// See Section 2.3 "Calling Conventions" in the UEFI Specification - /// for further information on each ISA that takes advantage of this. - const ISA_MASK = 0x0FFF_F000_0000_0000; - } -} - /// A unique identifier of a memory map. /// /// If the memory map changes, this value is no longer valid.