Skip to content

Commit aad3376

Browse files
committed
uefi: Add PciRootBridgeIo memory and I/O space access
1 parent 12509ec commit aad3376

2 files changed

Lines changed: 73 additions & 15 deletions

File tree

uefi/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Added
44
- Added `proto::console::text::InputEx`.
5+
- Added `memory()` and `io()` address space access to `PciRootBridgeIo`
6+
protocol.
57

68
## Changed
79
- MSRV increased from 1.88 to 1.91.

uefi/src/proto/pci/root_bridge.rs

Lines changed: 71 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,30 @@ impl PciRootBridgeIo {
3434
self.0.segment_number
3535
}
3636

37-
/// Access PCI I/O operations on this root bridge.
38-
pub const fn pci(&mut self) -> PciIoAccessPci<'_> {
39-
PciIoAccessPci {
37+
/// Access PCI controller registers in the memory space on this root bridge.
38+
pub const fn memory(&mut self) -> PciIoAccess<'_, PciMemorySpace> {
39+
PciIoAccess {
4040
proto: &mut self.0,
4141
io_access: &mut self.0.pci,
42+
_address_space: PciMemorySpace,
43+
}
44+
}
45+
46+
/// Access PCI controller registers in the I/O space on this root bridge.
47+
pub const fn io(&mut self) -> PciIoAccess<'_, PciIoSpace> {
48+
PciIoAccess {
49+
proto: &mut self.0,
50+
io_access: &mut self.0.pci,
51+
_address_space: PciIoSpace,
52+
}
53+
}
54+
55+
/// Access PCI controller registers in the configuration space on this root bridge.
56+
pub const fn pci(&mut self) -> PciIoAccess<'_, PciConfigurationSpace> {
57+
PciIoAccess {
58+
proto: &mut self.0,
59+
io_access: &mut self.0.pci,
60+
_address_space: PciConfigurationSpace,
4261
}
4362
}
4463

@@ -52,8 +71,6 @@ impl PciRootBridgeIo {
5271
}
5372

5473
// TODO: poll I/O
55-
// TODO: mem I/O access
56-
// TODO: io I/O access
5774
// TODO: map & unmap & copy memory
5875
// TODO: buffer management
5976
// TODO: get/set attributes
@@ -90,7 +107,7 @@ impl PciRootBridgeIo {
90107
/// An ordered list of addresses containing all present devices below this RootBridge.
91108
///
92109
/// # Errors
93-
/// This can basically fail with all the IO errors found in [`PciIoAccessPci`] methods.
110+
/// This can basically fail with all the IO errors found in [`PciIoAccess`] methods.
94111
#[cfg(feature = "alloc")]
95112
pub fn enumerate(&mut self) -> crate::Result<super::enumeration::PciTree> {
96113
use super::enumeration::{self, PciTree};
@@ -118,12 +135,13 @@ impl PciRootBridgeIo {
118135

119136
/// Struct for performing PCI I/O operations on a root bridge.
120137
#[derive(Debug)]
121-
pub struct PciIoAccessPci<'a> {
138+
pub struct PciIoAccess<'a, S: PciIoAddressSpace> {
122139
proto: *mut PciRootBridgeIoProtocol,
123140
io_access: &'a mut PciRootBridgeIoAccess,
141+
_address_space: S,
124142
}
125143

126-
impl PciIoAccessPci<'_> {
144+
impl<S: PciIoAddressSpace> PciIoAccess<'_, S> {
127145
/// Reads a single value of type `U` from the specified PCI address.
128146
///
129147
/// # Arguments
@@ -135,7 +153,7 @@ impl PciIoAccessPci<'_> {
135153
/// # Errors
136154
/// - [`Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
137155
/// - [`Status::OUT_OF_RESOURCES`] The read request could not be completed due to a lack of resources.
138-
pub fn read_one<U: PciIoUnit>(&self, addr: PciIoAddress) -> crate::Result<U> {
156+
pub fn read_one<U: PciIoUnit>(&self, addr: S::Address) -> crate::Result<U> {
139157
let width_mode = encode_io_mode_and_unit::<U>(super::PciIoMode::Normal);
140158
let mut result = U::default();
141159
unsafe {
@@ -159,7 +177,7 @@ impl PciIoAccessPci<'_> {
159177
/// # Errors
160178
/// - [`Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
161179
/// - [`Status::OUT_OF_RESOURCES`] The write request could not be completed due to a lack of resources.
162-
pub fn write_one<U: PciIoUnit>(&self, addr: PciIoAddress, data: U) -> crate::Result<()> {
180+
pub fn write_one<U: PciIoUnit>(&self, addr: S::Address, data: U) -> crate::Result<()> {
163181
let width_mode = encode_io_mode_and_unit::<U>(super::PciIoMode::Normal);
164182
unsafe {
165183
(self.io_access.write)(
@@ -182,7 +200,7 @@ impl PciIoAccessPci<'_> {
182200
/// # Errors
183201
/// - [`Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
184202
/// - [`Status::OUT_OF_RESOURCES`] The read operation could not be completed due to a lack of resources.
185-
pub fn read<U: PciIoUnit>(&self, addr: PciIoAddress, data: &mut [U]) -> crate::Result<()> {
203+
pub fn read<U: PciIoUnit>(&self, addr: S::Address, data: &mut [U]) -> crate::Result<()> {
186204
let width_mode = encode_io_mode_and_unit::<U>(super::PciIoMode::Normal);
187205
unsafe {
188206
(self.io_access.read)(
@@ -205,7 +223,7 @@ impl PciIoAccessPci<'_> {
205223
/// # Errors
206224
/// - [`Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
207225
/// - [`Status::OUT_OF_RESOURCES`] The write operation could not be completed due to a lack of resources.
208-
pub fn write<U: PciIoUnit>(&self, addr: PciIoAddress, data: &[U]) -> crate::Result<()> {
226+
pub fn write<U: PciIoUnit>(&self, addr: S::Address, data: &[U]) -> crate::Result<()> {
209227
let width_mode = encode_io_mode_and_unit::<U>(super::PciIoMode::Normal);
210228
unsafe {
211229
(self.io_access.write)(
@@ -231,7 +249,7 @@ impl PciIoAccessPci<'_> {
231249
/// - [`Status::OUT_OF_RESOURCES`] The operation could not be completed due to a lack of resources.
232250
pub fn fill_write<U: PciIoUnit>(
233251
&self,
234-
addr: PciIoAddress,
252+
addr: S::Address,
235253
count: usize,
236254
data: U,
237255
) -> crate::Result<()> {
@@ -261,7 +279,7 @@ impl PciIoAccessPci<'_> {
261279
/// # Errors
262280
/// - [`Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
263281
/// - [`Status::OUT_OF_RESOURCES`] The read operation could not be completed due to a lack of resources.
264-
pub fn fifo_read<U: PciIoUnit>(&self, addr: PciIoAddress, data: &mut [U]) -> crate::Result<()> {
282+
pub fn fifo_read<U: PciIoUnit>(&self, addr: S::Address, data: &mut [U]) -> crate::Result<()> {
265283
let width_mode = encode_io_mode_and_unit::<U>(super::PciIoMode::Fifo);
266284
unsafe {
267285
(self.io_access.read)(
@@ -288,7 +306,7 @@ impl PciIoAccessPci<'_> {
288306
/// # Errors
289307
/// - [`Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
290308
/// - [`Status::OUT_OF_RESOURCES`] The write operation could not be completed due to a lack of resources.
291-
pub fn fifo_write<U: PciIoUnit>(&self, addr: PciIoAddress, data: &[U]) -> crate::Result<()> {
309+
pub fn fifo_write<U: PciIoUnit>(&self, addr: S::Address, data: &[U]) -> crate::Result<()> {
292310
let width_mode = encode_io_mode_and_unit::<U>(super::PciIoMode::Fifo);
293311
unsafe {
294312
(self.io_access.write)(
@@ -302,3 +320,41 @@ impl PciIoAccessPci<'_> {
302320
}
303321
}
304322
}
323+
324+
/// Marker struct for the PCI memory space.
325+
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
326+
pub struct PciMemorySpace;
327+
328+
impl private::Sealed for PciMemorySpace {}
329+
impl PciIoAddressSpace for PciMemorySpace {
330+
type Address = u64;
331+
}
332+
333+
/// Marker struct for the PCI I/O space.
334+
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
335+
pub struct PciIoSpace;
336+
337+
impl private::Sealed for PciIoSpace {}
338+
impl PciIoAddressSpace for PciIoSpace {
339+
type Address = u64;
340+
}
341+
342+
/// Marker struct for the PCI configuration space.
343+
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
344+
pub struct PciConfigurationSpace;
345+
346+
impl private::Sealed for PciConfigurationSpace {}
347+
impl PciIoAddressSpace for PciConfigurationSpace {
348+
type Address = PciIoAddress;
349+
}
350+
351+
/// Trait representing how to convert from the address type expected for the address space and the
352+
/// raw address space.
353+
pub trait PciIoAddressSpace: private::Sealed {
354+
/// Specifies the type of the address space addresses.
355+
type Address: Into<u64>;
356+
}
357+
358+
mod private {
359+
pub trait Sealed {}
360+
}

0 commit comments

Comments
 (0)