diff --git a/uefi-raw/CHANGELOG.md b/uefi-raw/CHANGELOG.md index 12304e015..6d78bd559 100644 --- a/uefi-raw/CHANGELOG.md +++ b/uefi-raw/CHANGELOG.md @@ -1,5 +1,9 @@ # uefi-raw - [Unreleased] +## Added +- Added `AllocateType`. +- Added `PciRootBridgeIoProtocol`. + # uefi-raw - 0.11.0 (2025-05-04) diff --git a/uefi-raw/src/protocol/mod.rs b/uefi-raw/src/protocol/mod.rs index 2ee6985e5..dd3558126 100644 --- a/uefi-raw/src/protocol/mod.rs +++ b/uefi-raw/src/protocol/mod.rs @@ -21,6 +21,7 @@ pub mod memory_protection; pub mod misc; pub mod network; pub mod nvme; +pub mod pci; pub mod rng; pub mod scsi; pub mod shell_params; diff --git a/uefi-raw/src/protocol/pci/mod.rs b/uefi-raw/src/protocol/pci/mod.rs new file mode 100644 index 000000000..814d95217 --- /dev/null +++ b/uefi-raw/src/protocol/pci/mod.rs @@ -0,0 +1,3 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 + +pub mod root_bridge; diff --git a/uefi-raw/src/protocol/pci/root_bridge.rs b/uefi-raw/src/protocol/pci/root_bridge.rs new file mode 100644 index 000000000..001be2f9e --- /dev/null +++ b/uefi-raw/src/protocol/pci/root_bridge.rs @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 + +use crate::table::boot::{AllocateType, MemoryType}; +use crate::{Handle, PhysicalAddress, Status}; +use core::ffi::c_void; +use uguid::{guid, Guid}; + +newtype_enum! { + /// Corresponds to the `EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH` enum. + pub enum PciRootBridgeIoProtocolWidth: u32 => { + UINT8 = 0, + UINT16 = 1, + UINT32 = 2, + UINT64 = 3, + FIFO_UINT8 = 4, + FIFO_UINT16 = 5, + FIFO_UINT32 = 6, + FIFO_UINT64 = 7, + FILL_UINT8 = 8, + FILL_UINT16 = 9, + FILL_UINT32 = 10, + FILL_UINT64 = 11, + MAXIMUM = 12, + } +} + +newtype_enum! { + /// Corresponds to the `EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION` enum. + pub enum PciRootBridgeIoProtocolOperation: u32 => { + BUS_MASTER_READ = 0, + BUS_MASTER_WRITE = 1, + BUS_MASTER_COMMON_BUFFER = 2, + BUS_MASTER_READ64 = 3, + BUS_MASTER_WRITE64 = 4, + BUS_MASTER_COMMON_BUFFER64 = 5, + MAXIMUM = 6, + } +} + +/// Structure representing a PCI Address for Pci.Read() and Pci.Write() +#[repr(C, packed)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct PciIoAddress { + pub reg: u8, + pub fun: u8, + pub dev: u8, + pub bus: u8, + pub ext_reg: u32, +} + +impl PciIoAddress { + /// Create address pointing to the device identified by `bus`, `dev` and `fun` ids. + #[must_use] + pub const fn new(bus: u8, dev: u8, fun: u8) -> Self { + Self { + bus, + dev, + fun, + reg: 0, + ext_reg: 0, + } + } + + /// Configure the **byte**-offset of the register to access. + #[must_use] + pub const fn with_register(&self, reg: u8) -> Self { + let mut addr = *self; + addr.reg = reg; + addr.ext_reg = 0; + addr + } + + /// Configure the **byte**-offset of the extended register to access. + #[must_use] + pub const fn with_extended_register(&self, ext_reg: u32) -> Self { + let mut addr = *self; + addr.reg = 0; + addr.ext_reg = ext_reg; + addr + } +} + +impl From for u64 { + fn from(value: PciIoAddress) -> Self { + unsafe { core::mem::transmute(value) } + } +} + +#[derive(Debug)] +#[repr(C)] +pub struct PciRootBridgeIoAccess { + pub read: unsafe extern "efiapi" fn( + this: *mut PciRootBridgeIoProtocol, + width: PciRootBridgeIoProtocolWidth, + address: u64, + count: usize, + buffer: *mut c_void, + ) -> Status, + pub write: unsafe extern "efiapi" fn( + this: *mut PciRootBridgeIoProtocol, + width: PciRootBridgeIoProtocolWidth, + address: u64, + count: usize, + buffer: *const c_void, + ) -> Status, +} + +#[derive(Debug)] +#[repr(C)] +pub struct PciRootBridgeIoProtocol { + pub parent_handle: Handle, + pub poll_mem: unsafe extern "efiapi" fn( + this: *mut Self, + width: PciRootBridgeIoProtocolWidth, + address: u64, + mask: u64, + value: u64, + delay: u64, + result: *mut u64, + ) -> Status, + pub poll_io: unsafe extern "efiapi" fn( + this: *mut Self, + width: PciRootBridgeIoProtocolWidth, + address: u64, + mask: u64, + value: u64, + delay: u64, + result: *mut u64, + ) -> Status, + pub mem: PciRootBridgeIoAccess, + pub io: PciRootBridgeIoAccess, + pub pci: PciRootBridgeIoAccess, + pub copy_mem: unsafe extern "efiapi" fn( + this: *mut Self, + width: PciRootBridgeIoProtocolWidth, + dest_addr: u64, + src_addr: u64, + count: usize, + ) -> Status, + pub map: unsafe extern "efiapi" fn( + this: *const Self, + operation: PciRootBridgeIoProtocolOperation, + host_addr: *const c_void, + num_bytes: *mut usize, + device_addr: *mut PhysicalAddress, + mapping: *mut *mut c_void, + ) -> Status, + pub unmap: unsafe extern "efiapi" fn(this: *const Self, mapping: *const c_void) -> Status, + pub allocate_buffer: unsafe extern "efiapi" fn( + this: *const Self, + alloc_ty: AllocateType, + memory_ty: MemoryType, + pages: usize, + host_addr: *mut *const c_void, + attributes: u64, + ) -> Status, + pub free_buffer: unsafe extern "efiapi" fn( + this: *const Self, + pages: usize, + host_addr: *const c_void, + ) -> Status, + pub flush: unsafe extern "efiapi" fn(this: *mut Self) -> Status, + pub get_attributes: unsafe extern "efiapi" fn( + this: *const Self, + supports: *mut u64, + attributes: *mut u64, + ) -> Status, + pub set_attributes: unsafe extern "efiapi" fn( + this: *mut Self, + attributes: u64, + resource_base: *mut u64, + resource_length: *mut u64, + ) -> Status, + pub configuration: + unsafe extern "efiapi" fn(this: *const Self, resources: *mut *const c_void) -> Status, + pub segment_number: u32, +} + +impl PciRootBridgeIoProtocol { + pub const GUID: Guid = guid!("2f707ebb-4a1a-11d4-9a38-0090273fc14d"); +} diff --git a/uefi-raw/src/table/boot.rs b/uefi-raw/src/table/boot.rs index a2ffb70c4..a9932161c 100644 --- a/uefi-raw/src/table/boot.rs +++ b/uefi-raw/src/table/boot.rs @@ -9,6 +9,15 @@ use bitflags::bitflags; use core::ffi::c_void; use core::ops::RangeInclusive; +newtype_enum! { + pub enum AllocateType: u32 => { + ANY_PAGES = 0, + MAX_ADDRESS = 1, + ADDRESS = 2, + MAX_ALLOCATE_TYPE = 3, + } +} + /// Table of pointers to all the boot services. #[derive(Debug)] #[repr(C)] @@ -21,7 +30,7 @@ pub struct BootServices { // Memory allocation functions pub allocate_pages: unsafe extern "efiapi" fn( - alloc_ty: u32, + alloc_ty: AllocateType, mem_ty: MemoryType, count: usize, addr: *mut PhysicalAddress, diff --git a/uefi/src/boot.rs b/uefi/src/boot.rs index 820389660..3f87ed591 100644 --- a/uefi/src/boot.rs +++ b/uefi/src/boot.rs @@ -45,7 +45,7 @@ use core::ptr::{self, NonNull}; use core::sync::atomic::{AtomicPtr, Ordering}; use core::time::Duration; use core::{mem, slice}; -use uefi_raw::table::boot::{InterfaceType, TimerDelay}; +use uefi_raw::table::boot::{AllocateType as RawAllocateType, InterfaceType, TimerDelay}; #[cfg(feature = "alloc")] use {alloc::vec::Vec, uefi::ResultExt}; @@ -136,9 +136,9 @@ pub fn allocate_pages(ty: AllocateType, mem_ty: MemoryType, count: usize) -> Res let bt = unsafe { bt.as_ref() }; let (ty, initial_addr) = match ty { - AllocateType::AnyPages => (0, 0), - AllocateType::MaxAddress(addr) => (1, addr), - AllocateType::Address(addr) => (2, addr), + AllocateType::AnyPages => (RawAllocateType::ANY_PAGES, 0), + AllocateType::MaxAddress(addr) => (RawAllocateType::MAX_ADDRESS, addr), + AllocateType::Address(addr) => (RawAllocateType::ADDRESS, addr), }; let mut addr1 = initial_addr;