55use super :: { PciIoAddress , PciIoUnit , encode_io_mode_and_unit} ;
66use crate :: StatusExt ;
77use crate :: proto:: pci:: buffer:: PciBuffer ;
8- use crate :: proto:: pci:: mapped_region :: PciMappedRegion ;
8+ use crate :: proto:: pci:: region :: { PciMappedRegion , PciRegion } ;
99use core:: ffi:: c_void;
1010use core:: mem:: MaybeUninit ;
1111use core:: num:: NonZeroUsize ;
@@ -14,10 +14,7 @@ use core::ptr::NonNull;
1414use log:: debug;
1515use uefi_macros:: unsafe_protocol;
1616use 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 } ;
2118use uefi_raw:: table:: boot:: { AllocateType , MemoryType , PAGE_SIZE } ;
2219
2320/// Protocol that provides access to the PCI Root Bridge I/O protocol.
@@ -48,7 +45,7 @@ impl PciRootBridgeIo {
4845 /// Flush all PCI posted write transactions from a PCI host bridge to system memory.
4946 ///
5047 /// # 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
5249 /// due to a hardware error.
5350 pub fn flush ( & mut self ) -> crate :: Result < ( ) > {
5451 unsafe { ( self . 0 . flush ) ( & mut self . 0 ) . to_result ( ) }
@@ -57,12 +54,12 @@ impl PciRootBridgeIo {
5754 /// Allocates pages suitable for communicating with PCI devices.
5855 ///
5956 /// # 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:
6259 /// - [`PciRootBridgeIoProtocolAttribute::PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE`]
6360 /// - [`PciRootBridgeIoProtocolAttribute::PCI_ATTRIBUTE_MEMORY_CACHED`]
6461 /// - [`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.
6663 pub fn allocate_buffer < T > (
6764 & self ,
6865 memory_type : MemoryType ,
@@ -101,11 +98,7 @@ impl PciRootBridgeIo {
10198 Status :: SUCCESS => {
10299 let base = NonNull :: new ( address as * mut MaybeUninit < T > ) . unwrap ( ) ;
103100 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 ) )
109102 }
110103 error
111104 @ ( Status :: INVALID_PARAMETER | Status :: UNSUPPORTED | Status :: OUT_OF_RESOURCES ) => {
@@ -155,10 +148,37 @@ impl PciRootBridgeIo {
155148 }
156149 }
157150
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+
158179 // TODO: poll I/O
159180 // TODO: mem I/O access
160181 // TODO: io I/O access
161- // TODO: copy memory
162182 // TODO: get/set attributes
163183 // TODO: configuration / resource settings
164184}
@@ -180,8 +200,8 @@ impl PciIoAccessPci<'_> {
180200 /// - The read value of type `U`.
181201 ///
182202 /// # 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.
185205 pub fn read_one < U : PciIoUnit > ( & self , addr : PciIoAddress ) -> crate :: Result < U > {
186206 let width_mode = encode_io_mode_and_unit :: < U > ( super :: PciIoMode :: Normal ) ;
187207 let mut result = U :: default ( ) ;
@@ -204,8 +224,8 @@ impl PciIoAccessPci<'_> {
204224 /// - `data` - The value to write.
205225 ///
206226 /// # 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.
209229 pub fn write_one < U : PciIoUnit > ( & self , addr : PciIoAddress , data : U ) -> crate :: Result < ( ) > {
210230 let width_mode = encode_io_mode_and_unit :: < U > ( super :: PciIoMode :: Normal ) ;
211231 unsafe {
@@ -227,8 +247,8 @@ impl PciIoAccessPci<'_> {
227247 /// - `data` - A mutable slice to store the read values.
228248 ///
229249 /// # 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.
232252 pub fn read < U : PciIoUnit > ( & self , addr : PciIoAddress , data : & mut [ U ] ) -> crate :: Result < ( ) > {
233253 let width_mode = encode_io_mode_and_unit :: < U > ( super :: PciIoMode :: Normal ) ;
234254 unsafe {
@@ -250,8 +270,8 @@ impl PciIoAccessPci<'_> {
250270 /// - `data` - A slice containing the values to write.
251271 ///
252272 /// # 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.
255275 pub fn write < U : PciIoUnit > ( & self , addr : PciIoAddress , data : & [ U ] ) -> crate :: Result < ( ) > {
256276 let width_mode = encode_io_mode_and_unit :: < U > ( super :: PciIoMode :: Normal ) ;
257277 unsafe {
@@ -274,8 +294,8 @@ impl PciIoAccessPci<'_> {
274294 /// - `data` - The value to fill the address range with.
275295 ///
276296 /// # 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.
279299 pub fn fill_write < U : PciIoUnit > (
280300 & self ,
281301 addr : PciIoAddress ,
@@ -306,8 +326,8 @@ impl PciIoAccessPci<'_> {
306326 /// The resulting `data` buffer will contain the elements returned by reading the same address multiple times sequentially.
307327 ///
308328 /// # 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.
311331 pub fn fifo_read < U : PciIoUnit > ( & self , addr : PciIoAddress , data : & mut [ U ] ) -> crate :: Result < ( ) > {
312332 let width_mode = encode_io_mode_and_unit :: < U > ( super :: PciIoMode :: Fifo ) ;
313333 unsafe {
@@ -333,8 +353,8 @@ impl PciIoAccessPci<'_> {
333353 /// (starting at `addr` and ending at `addr + size_of::<U>()`) sequentially.
334354 ///
335355 /// # 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.
338358 pub fn fifo_write < U : PciIoUnit > ( & self , addr : PciIoAddress , data : & [ U ] ) -> crate :: Result < ( ) > {
339359 let width_mode = encode_io_mode_and_unit :: < U > ( super :: PciIoMode :: Fifo ) ;
340360 unsafe {
0 commit comments