@@ -9,6 +9,8 @@ pub mod op_region;
9
9
pub mod pci_routing;
10
10
pub mod resource;
11
11
12
+ pub use pci_types:: PciAddress ;
13
+
12
14
use alloc:: {
13
15
boxed:: Box ,
14
16
collections:: btree_map:: BTreeMap ,
82
84
}
83
85
}
84
86
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
+
85
105
pub fn install_region_handler < RH > ( & self , space : RegionSpace , handler : RH )
86
106
where
87
107
RH : RegionHandler + ' static ,
@@ -200,14 +220,13 @@ where
200
220
else {
201
221
panic ! ( )
202
222
} ;
203
- let region_offset = region_offset. as_integer ( ) ?;
204
- let region_length = region_length. as_integer ( ) ?;
205
- let region_space = RegionSpace :: from ( * region_space) ;
206
223
207
224
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
+ } ) ;
211
230
} ) ;
212
231
self . namespace. lock( ) . insert( name. resolve( & context. current_scope) ?, Arc :: new( region) ) ?;
213
232
}
@@ -1493,7 +1512,45 @@ where
1493
1512
_ => panic ! ( ) ,
1494
1513
}
1495
1514
} ) ,
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
+ }
1497
1554
1498
1555
RegionSpace :: EmbeddedControl
1499
1556
| RegionSpace :: SmBus
@@ -2086,7 +2143,10 @@ pub enum AmlError {
2086
2143
2087
2144
/// This trait represents the interface from the `Interpreter` to the hosting kernel, and allows
2088
2145
/// 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.
2090
2150
pub trait Handler : Send + Sync {
2091
2151
fn read_u8 ( & self , address : usize ) -> u8 ;
2092
2152
fn read_u16 ( & self , address : usize ) -> u16 ;
@@ -2106,13 +2166,13 @@ pub trait Handler: Send + Sync {
2106
2166
fn write_io_u16 ( & self , port : u16 , value : u16 ) ;
2107
2167
fn write_io_u32 ( & self , port : u16 , value : u32 ) ;
2108
2168
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 ;
2112
2172
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 ) ;
2116
2176
2117
2177
/// Returns a monotonically-increasing value of nanoseconds.
2118
2178
fn nanos_since_boot ( & self ) -> u64 ;
@@ -2160,12 +2220,12 @@ mod tests {
2160
2220
fn write_io_u8 ( & self , _port : u16 , _value : u8 ) { }
2161
2221
fn write_io_u16 ( & self , _port : u16 , _value : u16 ) { }
2162
2222
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 ) { }
2169
2229
fn nanos_since_boot ( & self ) -> u64 { 0 }
2170
2230
fn stall ( & self , _microseconds : u64 ) { }
2171
2231
fn sleep ( & self , _milliseconds : u64 ) { }
0 commit comments