@@ -23,7 +23,7 @@ use crate::utils::bitmap::Bitmap;
23
23
use crate :: utils:: sync:: Mutex ;
24
24
25
25
use crate :: acpi:: mcfg;
26
- use crate :: mem:: paging:: OffsetPageTable ;
26
+ use crate :: mem:: paging:: { OffsetPageTable , PhysAddr } ;
27
27
use crate :: utils:: VolatileCell ;
28
28
29
29
use crate :: arch:: { apic, io} ;
@@ -116,16 +116,18 @@ impl<'a> Msix<'a> {
116
116
. get_bar ( bar_index)
117
117
. expect ( "msix: table bar not present" ) ;
118
118
119
+ map_bar ( & bar) ;
120
+
119
121
let bar_address = match bar {
120
- Bar :: Memory64 { address, .. } => address,
121
- Bar :: Memory32 { address, .. } => address as u64 ,
122
+ Bar :: Memory64 { address, .. } => PhysAddr :: new ( address) ,
123
+ Bar :: Memory32 { address, .. } => PhysAddr :: new ( address as u64 ) ,
122
124
_ => unreachable ! ( ) ,
123
125
} ;
124
126
125
127
// SAFETY: We have exclusive access to the BAR and the slice is in bounds.
126
128
let messages = unsafe {
127
129
core:: slice:: from_raw_parts_mut (
128
- ( bar_address + bar_offset as u64 ) as * mut Message ,
130
+ ( bar_address. as_hhdm_virt ( ) + bar_offset as u64 ) . as_mut_ptr :: < Message > ( ) ,
129
131
table_length as usize ,
130
132
)
131
133
} ;
@@ -788,6 +790,45 @@ impl PciTable {
788
790
}
789
791
}
790
792
793
+ pub fn map_bar ( bar : & Bar ) {
794
+ use crate :: mem:: paging:: { Mapper , Page , PageTableFlags , PhysFrame , Size4KiB , UnmapError } ;
795
+
796
+ use crate :: mem:: AddressSpace ;
797
+
798
+ let mut address_space = AddressSpace :: this ( ) ;
799
+ let mut offset_table = address_space. offset_page_table ( ) ;
800
+
801
+ let ( addr, size) = match bar {
802
+ Bar :: Memory64 { address, size, .. } => ( PhysAddr :: new ( * address) , * size) ,
803
+ _ => unreachable ! ( ) ,
804
+ } ;
805
+
806
+ for frame in PhysFrame :: range (
807
+ PhysFrame :: < Size4KiB > :: from_start_address ( addr) . unwrap ( ) ,
808
+ PhysFrame :: containing_address ( addr + size) ,
809
+ ) {
810
+ let virt = frame. start_address ( ) . as_hhdm_virt ( ) ;
811
+ let page = Page :: containing_address ( virt) ;
812
+
813
+ // Map will fail if the bar was partially mapped.
814
+ match offset_table. unmap ( page) {
815
+ Ok ( ( _, m) ) => m. ignore ( ) ,
816
+ Err ( UnmapError :: PageNotMapped ) => { }
817
+ Err ( e) => unreachable ! ( "{:?}" , e) ,
818
+ }
819
+
820
+ unsafe {
821
+ offset_table. map_to (
822
+ page,
823
+ frame,
824
+ PageTableFlags :: PRESENT | PageTableFlags :: WRITABLE | PageTableFlags :: NO_EXECUTE ,
825
+ )
826
+ }
827
+ . unwrap ( )
828
+ . flush ( ) ;
829
+ }
830
+ }
831
+
791
832
pub fn register_device_driver ( handle : Arc < dyn PciDeviceHandle > ) {
792
833
PCI_TABLE . lock ( ) . inner . push ( PciDevice { handle } )
793
834
}
0 commit comments