From 3171ffaa710545473fcb7bb5a1f79f1c55290c2c Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sat, 24 Sep 2022 16:12:47 -0400 Subject: [PATCH] Add PhysicalAddress and VirtualAddress type aliases These correspond to `EFI_PHYSICAL_ADDRESS` and `EFI_VIRTUAL_ADDRESS`. These usually end up being converted to a pointer type, but notably they are always 64-bit regardless of the target platform. This change revealed a bug in the `AllocateType` enum; it was using `usize` for a couple members, but that is not correct for all targets, e.g. `i686-unknown-uefi`. --- CHANGELOG.md | 9 +++++++++ src/data_types/mod.rs | 8 ++++++++ src/proto/security/memory_protection.rs | 18 +++++++++++------- src/table/boot.rs | 22 +++++++++++----------- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 724704403..03bea327d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ ## uefi - [Unreleased] +### Added + +- Added `PhysicalAddress` and `VirtualAddress` type aliases. + +### Changed + +- Fixed the definition of `AllocateType` so that `MaxAddress` and + `Address` always take a 64-bit value, regardless of target platform. + ## uefi-macros - [Unreleased] ## uefi-services - [Unreleased] diff --git a/src/data_types/mod.rs b/src/data_types/mod.rs index f369f25fd..f1f8adb45 100644 --- a/src/data_types/mod.rs +++ b/src/data_types/mod.rs @@ -107,6 +107,14 @@ pub trait Align { } } +/// Physical memory address. This is always a 64-bit value, regardless +/// of target platform. +pub type PhysicalAddress = u64; + +/// Virtual memory address. This is always a 64-bit value, regardless +/// of target platform. +pub type VirtualAddress = u64; + mod guid; pub use self::guid::Guid; pub use self::guid::{unsafe_guid, Identify}; diff --git a/src/proto/security/memory_protection.rs b/src/proto/security/memory_protection.rs index 150d18768..0f548fc6c 100644 --- a/src/proto/security/memory_protection.rs +++ b/src/proto/security/memory_protection.rs @@ -1,3 +1,4 @@ +use crate::data_types::PhysicalAddress; use crate::proto::Protocol; use crate::table::boot::MemoryAttribute; use crate::{unsafe_guid, Result, Status}; @@ -14,21 +15,21 @@ use core::ops::Range; pub struct MemoryProtection { get_memory_attributes: unsafe extern "efiapi" fn( this: *const Self, - base_address: u64, + base_address: PhysicalAddress, length: u64, attributes: *mut MemoryAttribute, ) -> Status, set_memory_attributes: unsafe extern "efiapi" fn( this: *const Self, - base_address: u64, + base_address: PhysicalAddress, length: u64, attributes: MemoryAttribute, ) -> Status, clear_memory_attributes: unsafe extern "efiapi" fn( this: *const Self, - base_address: u64, + base_address: PhysicalAddress, length: u64, attributes: MemoryAttribute, ) -> Status, @@ -46,7 +47,10 @@ impl MemoryProtection { /// [`READ_PROTECT`]: MemoryAttribute::READ_PROTECT /// [`EXECUTE_PROTECT`]: MemoryAttribute::EXECUTE_PROTECT /// [`READ_ONLY`]: MemoryAttribute::READ_ONLY - pub fn get_memory_attributes(&self, byte_region: Range) -> Result { + pub fn get_memory_attributes( + &self, + byte_region: Range, + ) -> Result { let mut attributes = MemoryAttribute::empty(); let (base_address, length) = range_to_base_and_len(byte_region); unsafe { @@ -65,7 +69,7 @@ impl MemoryProtection { /// [`READ_ONLY`]: MemoryAttribute::READ_ONLY pub fn set_memory_attributes( &self, - byte_region: Range, + byte_region: Range, attributes: MemoryAttribute, ) -> Result { let (base_address, length) = range_to_base_and_len(byte_region); @@ -82,7 +86,7 @@ impl MemoryProtection { /// [`READ_ONLY`]: MemoryAttribute::READ_ONLY pub fn clear_memory_attributes( &self, - byte_region: Range, + byte_region: Range, attributes: MemoryAttribute, ) -> Result { let (base_address, length) = range_to_base_and_len(byte_region); @@ -91,7 +95,7 @@ impl MemoryProtection { } /// Convert a byte `Range` to `(base_address, length)`. -fn range_to_base_and_len(r: Range) -> (u64, u64) { +fn range_to_base_and_len(r: Range) -> (PhysicalAddress, PhysicalAddress) { (r.start, r.end.checked_sub(r.start).unwrap()) } diff --git a/src/table/boot.rs b/src/table/boot.rs index 6a81bee82..acfc1d41c 100644 --- a/src/table/boot.rs +++ b/src/table/boot.rs @@ -1,7 +1,7 @@ //! UEFI services available during boot. use super::{Header, Revision}; -use crate::data_types::Align; +use crate::data_types::{Align, PhysicalAddress, VirtualAddress}; use crate::proto::device_path::{DevicePath, FfiDevicePath}; #[cfg(feature = "exts")] use crate::proto::{loaded_image::LoadedImage, media::fs::SimpleFileSystem}; @@ -95,9 +95,9 @@ pub struct BootServices { alloc_ty: u32, mem_ty: MemoryType, count: usize, - addr: &mut u64, + addr: &mut PhysicalAddress, ) -> Status, - free_pages: extern "efiapi" fn(addr: u64, pages: usize) -> Status, + free_pages: extern "efiapi" fn(addr: PhysicalAddress, pages: usize) -> Status, get_memory_map: unsafe extern "efiapi" fn( size: &mut usize, map: *mut MemoryDescriptor, @@ -324,17 +324,17 @@ impl BootServices { ty: AllocateType, mem_ty: MemoryType, count: usize, - ) -> Result { + ) -> Result { let (ty, mut addr) = match ty { AllocateType::AnyPages => (0, 0), - AllocateType::MaxAddress(addr) => (1, addr as u64), - AllocateType::Address(addr) => (2, addr as u64), + AllocateType::MaxAddress(addr) => (1, addr), + AllocateType::Address(addr) => (2, addr), }; (self.allocate_pages)(ty, mem_ty, count, &mut addr).into_with_val(|| addr) } /// Frees memory pages allocated by UEFI. - pub fn free_pages(&self, addr: u64, count: usize) -> Result { + pub fn free_pages(&self, addr: PhysicalAddress, count: usize) -> Result { (self.free_pages)(addr, count).into() } @@ -1522,9 +1522,9 @@ pub enum AllocateType { /// Allocate any possible pages. AnyPages, /// Allocate pages at any address below the given address. - MaxAddress(usize), + MaxAddress(PhysicalAddress), /// Allocate pages at the specified address. - Address(usize), + Address(PhysicalAddress), } newtype_enum! { @@ -1594,9 +1594,9 @@ pub struct MemoryDescriptor { /// Skip 4 bytes as UEFI declares items in structs should be naturally aligned padding: u32, /// Starting physical address. - pub phys_start: u64, + pub phys_start: PhysicalAddress, /// Starting virtual address. - pub virt_start: u64, + pub virt_start: VirtualAddress, /// Number of 4 KiB pages contained in this range. pub page_count: u64, /// The capability attributes of this memory range.