Skip to content

uefi-raw: Add binding for EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL #1658

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions uefi-raw/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# uefi-raw - [Unreleased]

## Added
- Added `AllocateType`.
- Added `PciRootBridgeIoProtocol`.


# uefi-raw - 0.11.0 (2025-05-04)

Expand Down
1 change: 1 addition & 0 deletions uefi-raw/src/protocol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions uefi-raw/src/protocol/pci/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// SPDX-License-Identifier: MIT OR Apache-2.0

pub mod root_bridge;
132 changes: 132 additions & 0 deletions uefi-raw/src/protocol/pci/root_bridge.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// 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,
}
}

#[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");
}
11 changes: 10 additions & 1 deletion uefi-raw/src/table/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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,
Expand Down
8 changes: 4 additions & 4 deletions uefi/src/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -154,9 +154,9 @@ pub fn allocate_pages(
let bt = unsafe { bt.as_ref() };

let (ty, initial_addr) = match allocation_type {
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;
Expand Down