@@ -9,14 +9,18 @@ use uefi::proto::device_path::DevicePath;
99use uefi:: proto:: device_path:: text:: { AllowShortcuts , DisplayOnly } ;
1010use uefi:: proto:: pci:: root_bridge:: PciRootBridgeIo ;
1111use uefi:: proto:: scsi:: pass_thru:: ExtScsiPassThru ;
12+ use uefi_raw:: protocol:: pci:: root_bridge:: {
13+ PciRootBridgeIoProtocolAttribute , PciRootBridgeIoProtocolOperation ,
14+ } ;
15+ use uefi_raw:: table:: boot:: MemoryType ;
1216
1317const RED_HAT_PCI_VENDOR_ID : u16 = 0x1AF4 ;
1418const MASS_STORAGE_CTRL_CLASS_CODE : u8 = 0x1 ;
1519const SATA_CTRL_SUBCLASS_CODE : u8 = 0x6 ;
1620
1721const REG_SIZE : u8 = size_of :: < u32 > ( ) as u8 ;
1822
19- pub fn test ( ) {
23+ pub fn test_io ( ) {
2024 let pci_handles = uefi:: boot:: find_handles :: < PciRootBridgeIo > ( ) . unwrap ( ) ;
2125
2226 let mut sata_ctrl_cnt = 0 ;
@@ -88,6 +92,68 @@ pub fn test() {
8892 }
8993}
9094
95+ pub fn test_buffer ( ) {
96+ let pci_handles = uefi:: boot:: find_handles :: < PciRootBridgeIo > ( ) . unwrap ( ) ;
97+
98+ for pci_handle in pci_handles {
99+ let pci_proto = get_open_protocol :: < PciRootBridgeIo > ( pci_handle) ;
100+
101+ let buffer = pci_proto
102+ . allocate_buffer :: < [ u8 ; 4096 ] > (
103+ MemoryType :: BOOT_SERVICES_DATA ,
104+ None ,
105+ PciRootBridgeIoProtocolAttribute :: PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE ,
106+ )
107+ . unwrap ( ) ;
108+ let buffer = unsafe {
109+ let buffer = buffer. assume_init ( ) ;
110+ buffer. base_ptr ( ) . as_mut ( ) . unwrap ( ) . fill ( 0 ) ;
111+ buffer
112+ } ;
113+ assert_eq ! ( buffer. base_ptr( ) . addr( ) % 4096 , 0 ) ;
114+ unsafe {
115+ assert ! ( buffer. base_ptr( ) . as_mut( ) . unwrap( ) . iter( ) . all( |v| * v == 0 ) ) ;
116+ }
117+ }
118+ }
119+
120+ pub fn test_mapping ( ) {
121+ let pci_handles = uefi:: boot:: find_handles :: < PciRootBridgeIo > ( ) . unwrap ( ) ;
122+ const BUFFER_SIZE : usize = 4096 ;
123+
124+ for pci_handle in pci_handles {
125+ let pci_proto = get_open_protocol :: < PciRootBridgeIo > ( pci_handle) ;
126+
127+ let buffer = pci_proto
128+ . allocate_buffer :: < [ u8 ; BUFFER_SIZE ] > (
129+ MemoryType :: BOOT_SERVICES_DATA ,
130+ None ,
131+ PciRootBridgeIoProtocolAttribute :: PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE ,
132+ )
133+ . unwrap ( ) ;
134+ let buffer = unsafe {
135+ let buffer = buffer. assume_init ( ) ;
136+ buffer. base_ptr ( ) . as_mut ( ) . unwrap ( ) . fill ( 0 ) ;
137+ buffer
138+ } ;
139+ let ( mapped, left_over) = pci_proto
140+ . map (
141+ PciRootBridgeIoProtocolOperation :: BUS_MASTER_COMMON_BUFFER64 ,
142+ & buffer,
143+ )
144+ . unwrap ( ) ;
145+ assert_ne ! ( left_over, BUFFER_SIZE ) ;
146+ if left_over != 0 {
147+ info ! ( "Mapped {} out of {} bytes" , left_over, BUFFER_SIZE ) ;
148+ }
149+ if mapped. region ( ) . device_address == buffer. base_ptr ( ) . addr ( ) {
150+ info ! ( "This PCI device uses identity mapping" ) ;
151+ } else {
152+ info ! ( "This PCI device uses different mapping from CPU" ) ;
153+ }
154+ }
155+ }
156+
91157fn get_open_protocol < P : ProtocolPointer + ?Sized > ( handle : Handle ) -> ScopedProtocol < P > {
92158 let open_opts = OpenProtocolParams {
93159 handle,
0 commit comments