@@ -9,6 +9,8 @@ pub mod op_region;
99pub mod pci_routing;
1010pub mod resource;
1111
12+ pub use pci_types:: PciAddress ;
13+
1214use alloc:: {
1315 boxed:: Box ,
1416 collections:: btree_map:: BTreeMap ,
8284 }
8385 }
8486
87+ pub fn invoke_method_if_present (
88+ & self ,
89+ path : AmlName ,
90+ args : Vec < Arc < Object > > ,
91+ ) -> Result < Option < Arc < Object > > , AmlError > {
92+ match self . invoke_method ( path. clone ( ) , args) {
93+ Ok ( result) => Ok ( Some ( result) ) ,
94+ Err ( AmlError :: ObjectDoesNotExist ( not_present) ) => {
95+ if path == not_present {
96+ Ok ( None )
97+ } else {
98+ Err ( AmlError :: ObjectDoesNotExist ( not_present) )
99+ }
100+ }
101+ Err ( other) => Err ( other) ,
102+ }
103+ }
104+
85105 pub fn install_region_handler < RH > ( & self , space : RegionSpace , handler : RH )
86106 where
87107 RH : RegionHandler + ' static ,
@@ -200,14 +220,13 @@ where
200220 else {
201221 panic ! ( )
202222 } ;
203- let region_offset = region_offset. as_integer ( ) ?;
204- let region_length = region_length. as_integer ( ) ?;
205- let region_space = RegionSpace :: from ( * region_space) ;
206223
207224 let region = Object :: OpRegion ( OpRegion {
208- space : region_space,
209- base : region_offset,
210- length : region_length,
225+ space : RegionSpace :: from ( * region_space) ,
226+ base : region_offset. as_integer ( ) ?,
227+ length : region_length. as_integer ( ) ?,
228+ parent_device_path : context. current_scope . clone ( ) ,
229+ } ) ;
211230 } ) ;
212231 self . namespace. lock( ) . insert( name. resolve( & context. current_scope) ?, Arc :: new( region) ) ?;
213232 }
@@ -1493,7 +1512,45 @@ where
14931512 _ => panic ! ( ) ,
14941513 }
14951514 } ) ,
1496- RegionSpace :: PciConfig => todo ! ( ) ,
1515+ RegionSpace :: PciConfig => {
1516+ /*
1517+ * TODO: it's not ideal to do these reads for every native access. See if we can
1518+ * cache them somewhere?
1519+ */
1520+ let seg = match self . invoke_method_if_present (
1521+ AmlName :: from_str ( "_SEG" ) . unwrap ( ) . resolve ( & region. parent_device_path ) ?,
1522+ vec ! [ ] ,
1523+ ) ? {
1524+ Some ( value) => value. as_integer ( ) ?,
1525+ None => 0 ,
1526+ } ;
1527+ let bus = match self . invoke_method_if_present (
1528+ AmlName :: from_str ( "_BBR" ) . unwrap ( ) . resolve ( & region. parent_device_path ) ?,
1529+ vec ! [ ] ,
1530+ ) ? {
1531+ Some ( value) => value. as_integer ( ) ?,
1532+ None => 0 ,
1533+ } ;
1534+ let ( device, function) = {
1535+ let adr = self . invoke_method_if_present (
1536+ AmlName :: from_str ( "_ADR" ) . unwrap ( ) . resolve ( & region. parent_device_path ) ?,
1537+ vec ! [ ] ,
1538+ ) ?;
1539+ let adr = match adr {
1540+ Some ( adr) => adr. as_integer ( ) ?,
1541+ None => 0 ,
1542+ } ;
1543+ ( adr. get_bits ( 16 ..32 ) , adr. get_bits ( 0 ..16 ) )
1544+ } ;
1545+
1546+ let address = PciAddress :: new ( seg as u16 , bus as u8 , device as u8 , function as u8 ) ;
1547+ match length {
1548+ 1 => Ok ( self . handler . read_pci_u8 ( address, offset as u16 ) as u64 ) ,
1549+ 2 => Ok ( self . handler . read_pci_u16 ( address, offset as u16 ) as u64 ) ,
1550+ 4 => Ok ( self . handler . read_pci_u32 ( address, offset as u16 ) as u64 ) ,
1551+ _ => panic ! ( ) ,
1552+ }
1553+ }
14971554
14981555 RegionSpace :: EmbeddedControl
14991556 | RegionSpace :: SmBus
@@ -2086,7 +2143,10 @@ pub enum AmlError {
20862143
20872144/// This trait represents the interface from the `Interpreter` to the hosting kernel, and allows
20882145/// AML to interact with the underlying hardware.
2089- // TODO: maybe use `pci_types::PciAddress` to simplify PCI address passing here
2146+ ///
2147+ /// ### Implementation notes
2148+ /// Reads and writes to PCI devices must succeed for devices that are not detected during
2149+ /// enumeration of the PCI bus / do not exist.
20902150pub trait Handler : Send + Sync {
20912151 fn read_u8 ( & self , address : usize ) -> u8 ;
20922152 fn read_u16 ( & self , address : usize ) -> u16 ;
@@ -2106,13 +2166,13 @@ pub trait Handler: Send + Sync {
21062166 fn write_io_u16 ( & self , port : u16 , value : u16 ) ;
21072167 fn write_io_u32 ( & self , port : u16 , value : u32 ) ;
21082168
2109- fn read_pci_u8 ( & self , segment : u16 , bus : u8 , device : u8 , function : u8 , offset : u16 ) -> u8 ;
2110- fn read_pci_u16 ( & self , segment : u16 , bus : u8 , device : u8 , function : u8 , offset : u16 ) -> u16 ;
2111- fn read_pci_u32 ( & self , segment : u16 , bus : u8 , device : u8 , function : u8 , offset : u16 ) -> u32 ;
2169+ fn read_pci_u8 ( & self , address : PciAddress , offset : u16 ) -> u8 ;
2170+ fn read_pci_u16 ( & self , address : PciAddress , offset : u16 ) -> u16 ;
2171+ fn read_pci_u32 ( & self , address : PciAddress , offset : u16 ) -> u32 ;
21122172
2113- fn write_pci_u8 ( & self , segment : u16 , bus : u8 , device : u8 , function : u8 , offset : u16 , value : u8 ) ;
2114- fn write_pci_u16 ( & self , segment : u16 , bus : u8 , device : u8 , function : u8 , offset : u16 , value : u16 ) ;
2115- fn write_pci_u32 ( & self , segment : u16 , bus : u8 , device : u8 , function : u8 , offset : u16 , value : u32 ) ;
2173+ fn write_pci_u8 ( & self , address : PciAddress , offset : u16 , value : u8 ) ;
2174+ fn write_pci_u16 ( & self , address : PciAddress , offset : u16 , value : u16 ) ;
2175+ fn write_pci_u32 ( & self , address : PciAddress , offset : u16 , value : u32 ) ;
21162176
21172177 /// Returns a monotonically-increasing value of nanoseconds.
21182178 fn nanos_since_boot ( & self ) -> u64 ;
@@ -2160,12 +2220,12 @@ mod tests {
21602220 fn write_io_u8 ( & self , _port : u16 , _value : u8 ) { }
21612221 fn write_io_u16 ( & self , _port : u16 , _value : u16 ) { }
21622222 fn write_io_u32 ( & self , _port : u16 , _value : u32 ) { }
2163- fn read_pci_u8 ( & self , _segment : u16 , _bus : u8 , _device : u8 , _function : u8 , _offset : u16 ) -> u8 { 0 }
2164- fn read_pci_u16 ( & self , _segment : u16 , _bus : u8 , _device : u8 , _function : u8 , _offset : u16 ) -> u16 { 0 }
2165- fn read_pci_u32 ( & self , _segment : u16 , _bus : u8 , _device : u8 , _function : u8 , _offset : u16 ) -> u32 { 0 }
2166- fn write_pci_u8 ( & self , _segment : u16 , _bus : u8 , _device : u8 , _function : u8 , _offset : u16 , _value : u8 ) { }
2167- fn write_pci_u16 ( & self , _segment : u16 , _bus : u8 , _device : u8 , _function : u8 , _offset : u16 , _value : u16 ) { }
2168- fn write_pci_u32 ( & self , _segment : u16 , _bus : u8 , _device : u8 , _function : u8 , _offset : u16 , _value : u32 ) { }
2223+ fn read_pci_u8 ( & self , _address : PciAddress , _offset : u16 ) -> u8 { 0 }
2224+ fn read_pci_u16 ( & self , _address : PciAddress , _offset : u16 ) -> u16 { 0 }
2225+ fn read_pci_u32 ( & self , _address : PciAddress , _offset : u16 ) -> u32 { 0 }
2226+ fn write_pci_u8 ( & self , _address : PciAddress , _offset : u16 , _value : u8 ) { }
2227+ fn write_pci_u16 ( & self , _address : PciAddress , _offset : u16 , _value : u16 ) { }
2228+ fn write_pci_u32 ( & self , _address : PciAddress , _offset : u16 , _value : u32 ) { }
21692229 fn nanos_since_boot ( & self ) -> u64 { 0 }
21702230 fn stall ( & self , _microseconds : u64 ) { }
21712231 fn sleep ( & self , _milliseconds : u64 ) { }
0 commit comments