5
5
use super :: { PciIoAddress , PciIoUnit , encode_io_mode_and_unit} ;
6
6
use crate :: StatusExt ;
7
7
use crate :: proto:: pci:: buffer:: PciBuffer ;
8
- use crate :: proto:: pci:: mapped_region :: PciMappedRegion ;
8
+ use crate :: proto:: pci:: region :: { PciMappedRegion , PciRegion } ;
9
9
use core:: ffi:: c_void;
10
10
use core:: mem:: MaybeUninit ;
11
11
use core:: num:: NonZeroUsize ;
@@ -14,10 +14,7 @@ use core::ptr::NonNull;
14
14
use log:: debug;
15
15
use uefi_macros:: unsafe_protocol;
16
16
use uefi_raw:: Status ;
17
- use uefi_raw:: protocol:: pci:: root_bridge:: {
18
- PciRootBridgeIoAccess , PciRootBridgeIoProtocol , PciRootBridgeIoProtocolAttribute ,
19
- PciRootBridgeIoProtocolOperation ,
20
- } ;
17
+ use uefi_raw:: protocol:: pci:: root_bridge:: { PciRootBridgeIoAccess , PciRootBridgeIoProtocol , PciRootBridgeIoProtocolAttribute , PciRootBridgeIoProtocolOperation , PciRootBridgeIoProtocolWidth } ;
21
18
use uefi_raw:: table:: boot:: { AllocateType , MemoryType , PAGE_SIZE } ;
22
19
23
20
/// Protocol that provides access to the PCI Root Bridge I/O protocol.
@@ -48,7 +45,7 @@ impl PciRootBridgeIo {
48
45
/// Flush all PCI posted write transactions from a PCI host bridge to system memory.
49
46
///
50
47
/// # Errors
51
- /// - [`crate:: Status::DEVICE_ERROR`] The PCI posted write transactions were not flushed from the PCI host bridge
48
+ /// - [`Status::DEVICE_ERROR`] The PCI posted write transactions were not flushed from the PCI host bridge
52
49
/// due to a hardware error.
53
50
pub fn flush ( & mut self ) -> crate :: Result < ( ) > {
54
51
unsafe { ( self . 0 . flush ) ( & mut self . 0 ) . to_result ( ) }
@@ -57,12 +54,12 @@ impl PciRootBridgeIo {
57
54
/// Allocates pages suitable for communicating with PCI devices.
58
55
///
59
56
/// # Errors
60
- /// - [`crate:: Status::INVALID_PARAMETER`] MemoryType is invalid.
61
- /// - [`crate:: Status::UNSUPPORTED`] Attributes is unsupported. The only legal attribute bits are:
57
+ /// - [`Status::INVALID_PARAMETER`] MemoryType is invalid.
58
+ /// - [`Status::UNSUPPORTED`] Attributes is unsupported. The only legal attribute bits are:
62
59
/// - [`PciRootBridgeIoProtocolAttribute::PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE`]
63
60
/// - [`PciRootBridgeIoProtocolAttribute::PCI_ATTRIBUTE_MEMORY_CACHED`]
64
61
/// - [`PciRootBridgeIoProtocolAttribute::PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE`]
65
- /// - [`crate:: Status::OUT_OF_RESOURCES`] The memory pages could not be allocated.
62
+ /// - [`Status::OUT_OF_RESOURCES`] The memory pages could not be allocated.
66
63
pub fn allocate_buffer < T > (
67
64
& self ,
68
65
memory_type : MemoryType ,
@@ -101,11 +98,7 @@ impl PciRootBridgeIo {
101
98
Status :: SUCCESS => {
102
99
let base = NonNull :: new ( address as * mut MaybeUninit < T > ) . unwrap ( ) ;
103
100
debug ! ( "Allocated {} pages at 0x{:X}" , pages. get( ) , address) ;
104
- Ok ( PciBuffer {
105
- base,
106
- pages,
107
- proto : & self . 0 ,
108
- } )
101
+ Ok ( PciBuffer :: new ( base, pages, & self . 0 ) )
109
102
}
110
103
error
111
104
@ ( Status :: INVALID_PARAMETER | Status :: UNSUPPORTED | Status :: OUT_OF_RESOURCES ) => {
@@ -155,10 +148,37 @@ impl PciRootBridgeIo {
155
148
}
156
149
}
157
150
151
+ /// Copies a region in PCI root bridge memory space onto the other.
152
+ /// Two regions must have same length. Functionally, this is the same as
153
+ /// `<[T]>::copy_from_slice` which is effectively memcpy.
154
+ /// And the same safety requirements as the above method apply.
155
+ pub fn copy (
156
+ & mut self ,
157
+ width : PciRootBridgeIoProtocolWidth ,
158
+ destination : PciRegion ,
159
+ source : PciRegion ,
160
+ ) -> crate :: Result < ( ) > {
161
+ assert_eq ! ( destination. length, source. length) ;
162
+
163
+ let status = unsafe {
164
+ ( self . 0 . copy_mem ) (
165
+ & mut self . 0 ,
166
+ width,
167
+ destination. device_address ,
168
+ source. device_address ,
169
+ destination. length ,
170
+ )
171
+ } ;
172
+
173
+ match status {
174
+ Status :: SUCCESS => Ok ( ( ) ) ,
175
+ error => Err ( error. into ( ) ) ,
176
+ }
177
+ }
178
+
158
179
// TODO: poll I/O
159
180
// TODO: mem I/O access
160
181
// TODO: io I/O access
161
- // TODO: copy memory
162
182
// TODO: get/set attributes
163
183
// TODO: configuration / resource settings
164
184
}
@@ -180,8 +200,8 @@ impl PciIoAccessPci<'_> {
180
200
/// - The read value of type `U`.
181
201
///
182
202
/// # Errors
183
- /// - [`crate:: Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
184
- /// - [`crate:: Status::OUT_OF_RESOURCES`] The read request could not be completed due to a lack of resources.
203
+ /// - [`Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
204
+ /// - [`Status::OUT_OF_RESOURCES`] The read request could not be completed due to a lack of resources.
185
205
pub fn read_one < U : PciIoUnit > ( & self , addr : PciIoAddress ) -> crate :: Result < U > {
186
206
let width_mode = encode_io_mode_and_unit :: < U > ( super :: PciIoMode :: Normal ) ;
187
207
let mut result = U :: default ( ) ;
@@ -204,8 +224,8 @@ impl PciIoAccessPci<'_> {
204
224
/// - `data` - The value to write.
205
225
///
206
226
/// # Errors
207
- /// - [`crate:: Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
208
- /// - [`crate:: Status::OUT_OF_RESOURCES`] The write request could not be completed due to a lack of resources.
227
+ /// - [`Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
228
+ /// - [`Status::OUT_OF_RESOURCES`] The write request could not be completed due to a lack of resources.
209
229
pub fn write_one < U : PciIoUnit > ( & self , addr : PciIoAddress , data : U ) -> crate :: Result < ( ) > {
210
230
let width_mode = encode_io_mode_and_unit :: < U > ( super :: PciIoMode :: Normal ) ;
211
231
unsafe {
@@ -227,8 +247,8 @@ impl PciIoAccessPci<'_> {
227
247
/// - `data` - A mutable slice to store the read values.
228
248
///
229
249
/// # Errors
230
- /// - [`crate:: Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
231
- /// - [`crate:: Status::OUT_OF_RESOURCES`] The read operation could not be completed due to a lack of resources.
250
+ /// - [`Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
251
+ /// - [`Status::OUT_OF_RESOURCES`] The read operation could not be completed due to a lack of resources.
232
252
pub fn read < U : PciIoUnit > ( & self , addr : PciIoAddress , data : & mut [ U ] ) -> crate :: Result < ( ) > {
233
253
let width_mode = encode_io_mode_and_unit :: < U > ( super :: PciIoMode :: Normal ) ;
234
254
unsafe {
@@ -250,8 +270,8 @@ impl PciIoAccessPci<'_> {
250
270
/// - `data` - A slice containing the values to write.
251
271
///
252
272
/// # Errors
253
- /// - [`crate:: Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
254
- /// - [`crate:: Status::OUT_OF_RESOURCES`] The write operation could not be completed due to a lack of resources.
273
+ /// - [`Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
274
+ /// - [`Status::OUT_OF_RESOURCES`] The write operation could not be completed due to a lack of resources.
255
275
pub fn write < U : PciIoUnit > ( & self , addr : PciIoAddress , data : & [ U ] ) -> crate :: Result < ( ) > {
256
276
let width_mode = encode_io_mode_and_unit :: < U > ( super :: PciIoMode :: Normal ) ;
257
277
unsafe {
@@ -274,8 +294,8 @@ impl PciIoAccessPci<'_> {
274
294
/// - `data` - The value to fill the address range with.
275
295
///
276
296
/// # Errors
277
- /// - [`crate:: Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
278
- /// - [`crate:: Status::OUT_OF_RESOURCES`] The operation could not be completed due to a lack of resources.
297
+ /// - [`Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
298
+ /// - [`Status::OUT_OF_RESOURCES`] The operation could not be completed due to a lack of resources.
279
299
pub fn fill_write < U : PciIoUnit > (
280
300
& self ,
281
301
addr : PciIoAddress ,
@@ -306,8 +326,8 @@ impl PciIoAccessPci<'_> {
306
326
/// The resulting `data` buffer will contain the elements returned by reading the same address multiple times sequentially.
307
327
///
308
328
/// # Errors
309
- /// - [`crate:: Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
310
- /// - [`crate:: Status::OUT_OF_RESOURCES`] The read operation could not be completed due to a lack of resources.
329
+ /// - [`Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
330
+ /// - [`Status::OUT_OF_RESOURCES`] The read operation could not be completed due to a lack of resources.
311
331
pub fn fifo_read < U : PciIoUnit > ( & self , addr : PciIoAddress , data : & mut [ U ] ) -> crate :: Result < ( ) > {
312
332
let width_mode = encode_io_mode_and_unit :: < U > ( super :: PciIoMode :: Fifo ) ;
313
333
unsafe {
@@ -333,8 +353,8 @@ impl PciIoAccessPci<'_> {
333
353
/// (starting at `addr` and ending at `addr + size_of::<U>()`) sequentially.
334
354
///
335
355
/// # Errors
336
- /// - [`crate:: Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
337
- /// - [`crate:: Status::OUT_OF_RESOURCES`] The write operation could not be completed due to a lack of resources.
356
+ /// - [`Status::INVALID_PARAMETER`] The requested width is invalid for this PCI root bridge.
357
+ /// - [`Status::OUT_OF_RESOURCES`] The write operation could not be completed due to a lack of resources.
338
358
pub fn fifo_write < U : PciIoUnit > ( & self , addr : PciIoAddress , data : & [ U ] ) -> crate :: Result < ( ) > {
339
359
let width_mode = encode_io_mode_and_unit :: < U > ( super :: PciIoMode :: Fifo ) ;
340
360
unsafe {
0 commit comments